Topic: Sine, cosine error

Hi,

I am working with sin(x) and cos(x) instrinsic functions, and this x depends on the timestep for my code.
I need to run this code up to 100.000 maybe 200.000 iterations, and I have noticed that near 38.000 iterations, cos (x) returns a number beyond [1,-1], and sin(x) returned 0 value over 38.000 iterations.

I would like to know if there is any limitation on the input of these functions.
My code lines are the following:

...
y1 = 1
dx = x1 / mp
kn=pi/x1
w1 = sqrt(9.81*kn*tanh(kn*y1))
wh = 0.7*w1
ah = 0.05*y1
xt(itimestep) = ah*cos(wh*(itimestep)*dt)
vt(itimestep) = -wh*ah*sin(wh*(itimestep)*dt)
...
in this case xt(38,000) is a big number over the range of the function results [ah;-ah]
and vt (>38.000) = 0.

I would be very grateful if anyone could help me please.

Best,
Emilio

Re: Sine, cosine error

Hi,

Would someone tell me please how to share an image here?, as I can show you the behavior of the sine and cosine functions.

Thank you,
EMilio

Re: Sine, cosine error

Emelio,

To post an image, you need to host it first somewhere (imgur.com is a pretty good option) and then provide the link in an "img" tag (check the BBCode documentation).

I don't see a problem with your code, but could you simplify it somewhat?  There are a lot of parameters present, including dt, x1, and mp, that don't have any associated values.  Are they changing as well?  If not, could you provide the values of everything else?

Depending on the algorithm used internally to compute cos and sin, I suppose they could fail at large values, but I doubt it.  Could you also provide the actual values being fed into cos and sin after your equations are calculated?  I'd be interested to see the values of wh*(itimestep)*dt for each iteration.

Jeff Armstrong
Approximatrix, LLC

Re: Sine, cosine error

Jeff,

Thanks for your answer,
sorry, I have not included all of the variables values in my post. In the parenthesis the only value changing is itimestep, which I consider would be up to 500.000 or even more.

The values of the variables are the following.

nvirt = 0
mp = 40
x1 = 2
y1 = 1
dx = x1 / mp
kn=pi/x1
w1 = 3.76! sqrt(9.81*kn*tanh(kn*y1))
wh = 0.7*w1
ah = 0.05*y1
! DO temp=1, 100000
  xt(itimestep) = 0.05*cos(0.7*3.76*(itimestep)*5e-5)
  vt(itimestep) = -0.7*3.76*0.05*sin(0.7*3.76*(itimestep)*5e-5)
  !write(*,*) 'iter',temp,'xt',xt(temp),'vt',vt(temp)
!ENDDO

I was thinking it was a problem on the "tanh" function in the w1 calculation so I tried with a constant value (3.76) to avoid errors, but the function keep un continuous for some values.

I also tried with the next loop to calculate all values for one iteration:

DO temp=1, 100000
  xt(temp) = 0.05*cos(0.7*3.76*(temp)*5e-5)
  vt(temp) = -0.7*3.76*0.05*sin(0.7*3.76*(temp)*5e-5)
  !write(*,*) 'iter',temp,'xt',xt(temp),'vt',vt(temp)
ENDDO

And the results were correct, but when I link the temp to the actual itimestep, the function became un-continuous.

Now I am trying do this but for each iteration the code will have to calculate the 100000 values and getting information of xt and vt for each iteration (itimestep), which will be expensive for computing resources.

Excuse me I can´t upload images to show the issue because my office connection blocked the imgur page.

I will try calculating for each step all the values of xt and vt for 100000 iterations and get the actual step value from these values and post the result of this.

Thanks,
Emilio

Re: Sine, cosine error

Emilio,

I've run the loop with your inputs, and I'm not seeing the discontinuity (I don't believe).  Are the arrays xt and vt being dimensioned properly?

Could you also try enabling runtime diagnostics on your software?  It's available in the Project Options window under the Fortran tab.

EDIT: My code is:

program iter
implicit none
integer, parameter::n=5000000
integer::temp
real(kind=8), dimension(:), allocatable::xt, vt

allocate(xt(n), vt(n))
open(file='out.txt', unit=100)
DO temp=4500000, n
  xt(temp) = 0.05*cos(0.7*3.76*(temp)*5e-5)
  vt(temp) = -0.7*3.76*0.05*sin(0.7*3.76*(temp)*5e-5)

  write(100,*) temp, 0.7*3.76*(temp)*5e-5, xt(temp),vt(temp)
ENDDO
close(100)
end program iter
Jeff Armstrong
Approximatrix, LLC

Re: Sine, cosine error

I don't have time to re-write Emilios loop (or Jeff's version), but I thought it may be helpful (to Emilio) to point out there is a much better way to code it (I know this a bit off topic)

Remember the equations from school:

cos(A+B)=cos(A)cos(B) - sin(A)sin(B)
sin(A+B)=sin(A)cos(B) + sin(B)cos(A)

These can be used such that cos and sin dont need to be calculated inside the loop at all.

Consider the loop:

integer: i
double precision: Tcos, Tsin, angle

theta_increment = (2*PI) / number

do i=1, number

   angle = i * theta_increment

   Tcos = cos (angle)
   Tsin = sin (angle)

   ! ... Use Tcos and Tsin
end do

You can re-write this as:

integer: i
double precision: Tcos, Tsin, angle, sa, ca, tmp

theta_increment = (2*PI) / number

! These are the only places where sin and cos are called.
sa = sin(theta_increment)
ca = cos(theta_increment)

angle = 0.0d0
Tcos = 1.0d0 ! cos(0.0d0)
Tsin = 0.0d0 ! sin(0.0d0)

do i=1, number

   tmp = Tcos
   Tcos = Tcos*ca - Tsin*sa
   Tsin = Tsin*ca + tmp*sa

   angle = angle + theta_increment

    ! ... Use Tcos and Tsin
end do

This loop should be at least 10 times faster then the first one.

You can also do this more elegantly using complex variables.

--
David

Re: Sine, cosine error

Thank you guys for your replies (Jeff and Davidb).

In your reply Jeff, I did that as a test to avoid error calculating for each step the whole matrix of numbers (xt (temp), vt (temp)), and get the values for each timestep: xt (itimestep), vt (itimestep). I think this solve the problem.

Davidb, I appreciate your proposal, I will review If this would help me.

Regards,
Emilio