# How in Fortran 77 or in the next standards to do a multi-column out put in a simple calculation, having a Nested loop?

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}$.

• Welcome to scicomp -- Nice question - only your formatting is a bit off the standards :)
– Jan
Dec 26 '14 at 16:45
• Thank You @Jan. You are right. I am not the best, but try to be better :) Dec 27 '14 at 16:54
• 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. Dec 27 '14 at 17:05

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)
k=1
do  while(k<10)
f=sin(k*x)
k=k+4
enddo
x=x+dx
write(11,*) ' '
enddo
1001  format(' ',e12.3)
endprogram

• Thank you @A-R-M. What a pitty that I could not realize that first I have to do a loop for $\mathbf{x}$ Dec 27 '14 at 16:55
• @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. Dec 27 '14 at 20:39

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