0
$\begingroup$

I have a simple question concerning the management of the output after running a Fortran code, having a NESTED LOOP..
I want to calculate for different k=1,5,9 the value $\mathbf{Sin(kx)}$ in the range $\mathbf{x=0:2\pi}$ with the step $\mathbf{h=0.01}$. As the range of $\mathbf{x}$ for all $\mathbf{k}$ is the same, I would like to do an output in a cal.dat file as the following (of course without the functions and just number):

$x$ $\quad\qquad\sin(x)$ $\qquad\sin(5x)$ $\qquad\sin(9x)$
$0.0$ $\quad\qquad0$ $\qquad\qquad0$ $\quad\qquad\qquad0$
$...$ $\quad\qquad...$ $\qquad\qquad...$ $\quad\qquad\qquad...$


My code is:

         program test3
         real dx,f,x
         k=1
         pi=4.0*atan(1.0)
         open(11,file='sinkx.dat',status='unknown',form='formatted')
         do  while(k<10)
         x=0.0
         dx=0.01
         do while(x<2*pi)
         f=sin(k*x) 
         write(11,1001) x,f
1001     format(' ',f9.3,' ',e12.3)
         x=x+dx
         enddo
         k=k+4
         enddo
         end



The questions is that when you run this code, you get the output not in a multi-column out put as desired, but in a two column out put in which first come numbers for the $\mathbf{x}$ range and in the second column the values of $\mathbf{Sin(kx)}$ for different $\mathbf{k=1}$, then $\mathbf{k=5}$ and then $\mathbf{k=9}$.
How to write results in a multi-column out put, as I have indicated in the above?
I think that the question is in write operator rather than in the calculations?
Of course, I could write the results in thre different cal.dat, but I prefer to write it in a one dat file, since the range of $\mathbf{x}$ is the same for all $\mathbf{k}$.

$\endgroup$
  • $\begingroup$ Welcome to scicomp -- Nice question - only your formatting is a bit off the standards :) $\endgroup$ – Jan Dec 26 '14 at 16:45
  • $\begingroup$ Thank You @Jan. You are right. I am not the best, but try to be better :) $\endgroup$ – Shariel Dec 27 '14 at 16:54
  • $\begingroup$ Thank you @A-R-M. <br/>What a pitty that I could not realize that first I have to do a loop for $\mathbf{x}$, write it and then do the loop for $\mathbf{k}$ and again write it. Nevertheless, thank you for your help. <br/>But there is a moment I can not understand. If with advanced='no' option in the write operator, one can do a multiple column, then why did you add the statement write(11,*) at the end of the code? I can not understand the role of this line. Could you in 2 or 3 words explain it? Thank you. $\endgroup$ – Shariel Dec 27 '14 at 17:05
1
$\begingroup$

There are multiple issues with your program. I am not sure why you are expecting it to produce multiple column output in the way that you want. You are looping over x for each k. You need to switch this nesting first.

As you rightly guessed there is a specifier for the write statement, advance='no', which you can use to not advance to the next line when using formatted output. I have made the changes that would give you the desired formatting. It is slightly hacky but it works.

program test3
  real dx,f,x
  pi=4.0*atan(1.0)
  open(11,file='sinkx.dat',status='unknown',form='formatted')
  x=0.0
  dx=0.01
  do while(x<2*pi)
    write(11,'(f9.3)',advance='no') x
    k=1
    do  while(k<10)
      f=sin(k*x) 
      write(11,1001,advance='no') f
      k=k+4
    enddo
    x=x+dx
    write(11,*) ' '
  enddo
  1001  format(' ',e12.3)
endprogram
$\endgroup$
  • $\begingroup$ Thank you @A-R-M. What a pitty that I could not realize that first I have to do a loop for $\mathbf{x}$ $\endgroup$ – Shariel Dec 27 '14 at 16:55
  • $\begingroup$ @Shariel You are welcome! The statement write(11,*)' ' is there to print the next x and f(x) on a new line. As the first two write statements have advance=no,all the output would have been printed on the first line itself (one very long line), if this statement were not present. $\endgroup$ – A R M Dec 27 '14 at 20:39
0
$\begingroup$

I would suggest moving to Fortran 90 and using an implied do loop inside the write statement:

program test3
    real, parameter :: dx=0.01
    real :: x
    integer :: k
    pi=4.0*atan(1.0)
    open(unit=11,file='sinkx.dat',status='replace',form='formatted')
    x=0.0
    do while(x < 2.0*pi)
        write(unit=11,fmt='(X,F9.3,10(X,E12.3))') &
            x, (SIN(REAL(k)*x),k=1,10,4)
        x=x+dx
    end do
    close(unit=11)
end program test3

Edit: Note that this would also work if we replaced the 10 in fmt='(X,F9.3,10(X,E12.3))' with any number greater or equal to 3. We could also calculate the number during runtime:

program test3
    ...
    integer, parameter :: k_max=10
    character(len=64) :: my_format
    write(my_format,'(A,I0,A)') "(X,F9.3,", 1+(k_max-1)/4, "(X,E12.3))"
    ...
    do while(x < 2.0*pi)
        write(unit=11,fmt=my_format) &
            x, (SIN(REAL(k)*x),k=1,k_max,4)
        x=x+dx
    end do
    ...
end program test3
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.