Error while calculating arc length of curve in Fortran

Click For Summary
SUMMARY

The discussion centers on a Fortran program designed to calculate the arc length of the curve defined by the function ƒ=3.1*x^2-5.3/x between x=1/2 and x=3/2. The original code incorrectly computes the length, yielding a result of 104.3853 instead of the expected 13, as verified by WolframAlpha. Key issues identified include the use of hard-coded constants, the need for a function to calculate f(x), and the inappropriate use of 'x' as a loop variable. Suggestions include implementing a user-defined function for f(x) and using a more descriptive loop control variable.

PREREQUISITES
  • Understanding of Fortran programming language
  • Familiarity with numerical methods for calculating arc length
  • Knowledge of function definitions in programming
  • Ability to debug and optimize code
NEXT STEPS
  • Implement a user-defined function in Fortran for f(x)
  • Learn about dynamic memory allocation in Fortran to handle variable subintervals
  • Explore numerical integration techniques for arc length calculations
  • Investigate debugging tools available for Fortran to improve code accuracy
USEFUL FOR

Fortran developers, mathematicians working on numerical methods, and anyone interested in optimizing arc length calculations in programming.

NicolasPan
Messages
21
Reaction score
2
The program must calculate the length of the curve of ƒ=3.1*x^2-5.3/x between x=1/2 and x=3/2.The legth should be calculated as the sum of n line segments starting with n=1 and ending with n=20.

I really can't find why the result I'm getting is wrong.Thanks in advance
I am giving you the code below:

Fortran:
program pr2_ex2
implicit none
integer::x
double precision::dy,dx !dy=the height of the linear part & dx=the length of the linear part
double precision::x1,x2,s !f=f(x) the function,x=the values which can be given to f
double precision::length 
  print*,"Please enter the function's starting point"
  read*,x1
  print*,"Please enter the function's ending  point"
  read*,x2
length=0
  s=0
do x=2,21
   dx=((x*abs(x2-x1)-(x-1)*abs(x2-x1))/(20))
   dy=(3.1*(x*abs(x2-x1)/20)**2-(5.3*20/x*abs(x2-x1)))-(3.1*((x-1)*abs(x2-x1)/20)**2-(5.3*20/(x-1)*abs(x2-x1)))
   length=sqrt((dx**2)+(dy**2))
   s=length+s
   end do
   print*,s
end program
 
Last edited:
Physics news on Phys.org
What is the result you're getting that you say is wrong?

"Lenght" being a misspelling of "length"?
 
Well if for x1=0.5 and for x2=1.5 I am getting 104.3853... That can't be right since I've checked it in wolframalpha and it says 13
 
The program must calculate the length of the curve of ƒ=3.1*x^2-5.3/x between x=1/2 and x=3/2.The leght should be calculated as the sum of n line segments starting with n=1 and ending with n=20.
EDIT: My reading of this is that it needs a program to print out 20 answers, one answer for each value of n.

I can see your program prints only one answer, right at the end, so that might be where you are going wrong?

How would you explain to someone what n is in this situation, to show you understand what this calculation is about?
 
Last edited:
NascentOxygen said:
My reading of this is that your program will print out 20 answers, one answer for each value of n.

I can see your program prints only one answer, right at the end, so that might be where you are going wrong?

How would you explain to someone what n is in this situation, to show you understand what this calculation is about?
Well I think the curve's x's from x1 to x2 can be divided to 20 equidistant x's with every n to be used to get to the next x.Xn=abs(x2-x1)*x/20 and X(n-1)=(x-1)*(abs(x2-x1)/20).Therefore if I subtract Xn,X(n-1),I will be getting the distance between consecutive X's.
 
NicolasPan said:
Well I think the curve's x's from x1 to x2 can be divided to 20 equidistant x's with every n to be used to get to the next x.Xn=abs(x2-x1)*x/20 and X(n-1)=(x-1)*(abs(x2-x1)/20).Therefore if I subtract Xn,X(n-1),I will be getting the distance between consecutive X's.
That would be the case for n=20. But, for example, when n=16 then there would be 16 segments spanning the path between those same two endpoints. That's what I think. The greater the value of n, the closer to the true length will be your approximation.
 
I am aware of that,although that can't be the problem the bigger the n the more my sum goes up.And the problem states that it should be able to work with just n=20,which doesn't in my case.Therefore I assume the problem is associated with my code.Nevermind thanks for your suggestion
 
NicolasPan said:
dy=(3.1*(x*abs(x2-x1)/20)**2-(5.3*20/x*abs(x2-x1)))-(3.1*((x-1)*abs(x2-x1)/20)**2-(5.3*20/(x-1)*abs(x2-x1)))
When you write 5.3*20/x*abs(x2-x1), it means
$$
5.3 \times \frac{20}{x} \times \left| x_2 - x_1 \right|
$$
which is not what you want.

You should create a function that given x, returns f(x), instead of hard-coding it many times. Also, do not use x as an integer index for the loop. It looks too much like the mathematical variable x. Use something like i instead.
 
NicolasPan said:
The program must calculate the length of the curve of ƒ=3.1*x^2-5.3/x between x=1/2 and x=3/2.The legth should be calculated as the sum of n line segments starting with n=1 and ending with n=20.

I really can't find why the result I'm getting is wrong.Thanks in advance
I am giving you the code below:

Fortran:
program pr2_ex2
implicit none
integer::x
double precision::dy,dx !dy=the height of the linear part & dx=the length of the linear part
double precision::x1,x2,s !f=f(x) the function,x=the values which can be given to f
double precision::length
  print*,"Please enter the function's starting point"
  read*,x1
  print*,"Please enter the function's ending  point"
  read*,x2
length=0
  s=0
do x=2,21
   dx=((x*abs(x2-x1)-(x-1)*abs(x2-x1))/(20))
   dy=(3.1*(x*abs(x2-x1)/20)**2-(5.3*20/x*abs(x2-x1)))-(3.1*((x-1)*abs(x2-x1)/20)**2-(5.3*20/(x-1)*abs(x2-x1)))
   length=sqrt((dx**2)+(dy**2))
   s=length+s
   end do
   print*,s
end program
Nicholas, your code is chock full of what are disparagingly called "magic" numbers, constants that are hard-coded. The number of subintervals should be a variable that the user enters, and not sprinkled throughout in your loop ending value and your assignment statements for dx and dy.

As already suggested, your code would be a lot more readable if you used a function to calculate the y values.

Fortran:
function f(x)
   double precision :: f
   double precision ::x
 
   f = 3.1 * x**2 - 5.3/x
   return
end function

The only change to your main program would be to insert a declaration for the function up near the top:
Fortran:
program pr2_ex2
implicit none
double precision:: f

To use the function, write an expression of the form f(x1).

One more thing -- you really shouldn't use x as your loop control variable. Use i or j for that.
 
Last edited:
  • #10
Thank you for your answers! I will be using your advice for sure in my code and see how it goes
 
  • #11
I put together some Python code to do this calculation. With n = 20 and n = 100 subintervals, I got 13.3059 in the first four decimal places.
 

Similar threads

  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 7 ·
Replies
7
Views
2K
  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 6 ·
Replies
6
Views
5K
Replies
4
Views
3K
  • · Replies 6 ·
Replies
6
Views
2K
  • · Replies 14 ·
Replies
14
Views
4K
  • · Replies 11 ·
Replies
11
Views
6K
  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 1 ·
Replies
1
Views
2K