I'm running a Fortran code that should write from 1 to 2000000 on the left column and in the range 1 - 0.001 on the right column, the main code body is below:
program signal
implicit none
integer dt_start, dtq, dtb, dtt, mdotb, i, mdot, t_start, n, dt, t
real*8 mdotq, mdott, nmdott
mdotb = 1 !burst phase
mdotq = 0.001 !quiescent phase
dtb = 100 !time for burst phase
dtq = 1080 !time for quiescent phase
dtt = 200 !transition time
t = 0 !initial time
dt = 10 !time step
n = 2000000 !interval
t_start = 0 !start of the range
open(unit=1, file='accretion.txt', status='unknown')
do i = 1, n
t = t + dt
dt_start = t-t_start
mdott = ((0.999/200)*t) + 0.505
nmdott = ((-0.999/200)*t) + 0.505
if (dt_start .le. dtb) then
if (dt_start .eq. dtb) then
t_start = i*dtb
endif
write(1,*) t, mdotb
else if (dt_start .le. dtt) then
if (dt_start .eq. dtt) then
t_start = i*dtt
endif
write(1,*) t, nmdott
else if (dt_start .le. dtq) then
if (dt_start .eq. dtq) then
t_start = i*dtq
endif
write(1,*) t, mdotq
else if (dt_start .le. dtt) then
if (dt_start .eq. dtt) then
t_start = i*dtt
endif
write(1,*) t, mdott
endif
enddo
close(1)
end
This outputs the following results:
10 1
20 1
30 1
40 1
50 1
60 1
70 1
80 1
90 1
100 1
110 1
120 1
130 1
140 1
150 1
160 1
170 1
180 1
190 1
200 1
210 1
220 1
230 1
240 1
250 1
260 1
270 1
280 1
290 1
300 1
and continues like that up to 2000000. I don't understand what I've done wrong with the code I think I might need to just restart at certain times or something?
Look at your through this perspective:
integer t = 0
integer t_start = 0
integer dt = 10
integer dtb = 100
integer n = 2000000
integer mdotb = 1
! (...)
do i = 1, n
t = t + dt
dt_start = t-t_start ! <- (*)
! (...)
if (dt_start .le. dtb) then ! <- condition (A)
if (dt_start .eq. dtb) then ! <- condition (A.1)
t_start = I*dtb. ! <- (**)
endif
write(1,*) t, mdotb ! <- output for branch (A)
else if ! <- other conditions
! (...)
end if
end do
For the first iterations i = 1, 9, you have condition (A) true and (A.1) is false, then the output for branch (A) is executed and the code prints t = 10, 90 in the first column and mdotb = 1 in the second column.
For iteration i = 10, you have finally dt_start == dtb, so condition (A) is true and (A.1) is also true. From inside the branch (A.1), you get the assignment t_start = 1000 in the line marked as (**). Then, the output for branch (A) is executed again and the code prints t = 100 in the first column and mdotb = 1 in the second.
For the following iterations i = 11, 109, remember that t_start == 1000 now, so in the line marked as (*) you will have dt_start = -890, dt_start = -880... until dt_start = 90, where all the time condition (A) holds true, (A.1) holds false, and you keep printing t and mdotb all the time.
By reaching iteration i = 110, finally dt_start = 100 again, then both conditions (A) and (A.1) are true again, then the line (**) is executed again, then t_start = 11000 now, and the output for branch (A) is executed again, printing t and mdotb again.
For the following iterations i = 111, 1109, you repeat the cycle where dt_start has negative/low values, still making condition (A) be true all the time, printing always the same output...
Then i = 1110 makes dt_start = 100 again, then t_start = 111000 now, same output...
And this pattern repeats again and again, while your output for branch (A) is always executed, and the remaining conditions won't ever be reached.
Obviously, there the logic of your program is flawed (well, technically it is in range 0.001 ~ 1, as it is always 1... but you don't seem to like it). But I don't know what are your trying to manage to print on the second column of the output. What I know for sure is that if you want from 1 to 2000000 on the first column, you should print I instead of t.
Or the op wants to...
"write(,) t, mdott"
Or
"Write(,) t, mdotb !But first set mdotb so it is not 1"
Or
"Write(,) I, t !?
Related
I want to double a number till 256, and when the program gets 256 make stop but the program that I created not giving me a double from 1 till 256
`````````````````````````````````````````````````````````````````
Fortran code
program exercise1
implicit none
real, external :: f
real :: h,a,b,prod,integration,summ,p
integer :: i,j,n
print*, 'Welcome, This program using Composite trapezoid method to calculate the integer'
print*, ' -------- '
prod=1
summ=0
print*,'Number of intervals ',' The integer value'
do i=1,258
n=(prod*i*i) ! Getting number of interval till 256
a=-1 ! The Lower limit of the integration
b=1 ! The Upper limit of the integration
h=(b-a)/n ! Calculate the delta X
p=(h/2.)*(f(a)+f(b)) ! Here as we have the whole equation is (h/2)*[f(a)+f(b)+2*sum(Xi) ! So we calculate the first part (h/2)*[f(a)+f(b) and then calculate the anoter part
summ=summ+h*f(a+i*h) !h/2 *2* sum[f(Xi)
integration = p+summ !Here the sum the both parts
if(n == 256) then !put a limit for the number of interval
Stop
end if
print*,n,' -', integration
enddo
end
real function f(x) !the function of the integer
f=sin(x+1)
end`
``````````````````````
the output
``````````````````
1 2.72789216
4 2.46665454
9 2.47777867
16 2.49350500
25 2.50419927
36 2.51126313
49 2.51606560
64 2.51944780
81 2.52190781
100 2.52374840
121 2.52515912
144 2.52626276
169 2.52714205
196 2.52785373
225 2.52843738
I think you want powers of: 2**i not squares: i**2. For example:
do i = 0,8
print*, 2**i
enddo
gives
1
2
4
8
16
32
64
128
256
I was originally voting to close as a typo, but your code maybe indeed does something different.
Your codes makes n to be a sequence if integer squares. 1^2, 2^2, 3^2 ... 16^2=256
But you wanted doubling the number, in that case just multiply n by 2.
n = 1
do i = 1, 10
do what you need
print *, n
n = n * 2
end do
I want to double a number till 256, and when the program gets 256 make stop but the program that I created not giving me a double from 1 till 256
`````````````````````````````````````````````````````````````````
Fortran code
program exercise1
implicit none
real, external :: f
real :: h,a,b,prod,integration,summ,p
integer :: i,j,n
print*, 'Welcome, This program using Composite trapezoid method to calculate the integer'
print*, ' -------- '
prod=1
summ=0
print*,'Number of intervals ',' The integer value'
do i=1,258
n=(prod*i*i) ! Getting number of interval till 256
a=-1 ! The Lower limit of the integration
b=1 ! The Upper limit of the integration
h=(b-a)/n ! Calculate the delta X
p=(h/2.)*(f(a)+f(b)) ! Here as we have the whole equation is (h/2)*[f(a)+f(b)+2*sum(Xi) ! So we calculate the first part (h/2)*[f(a)+f(b) and then calculate the anoter part
summ=summ+h*f(a+i*h) !h/2 *2* sum[f(Xi)
integration = p+summ !Here the sum the both parts
if(n == 256) then !put a limit for the number of interval
Stop
end if
print*,n,' -', integration
enddo
end
real function f(x) !the function of the integer
f=sin(x+1)
end`
``````````````````````
the output
``````````````````
1 2.72789216
4 2.46665454
9 2.47777867
16 2.49350500
25 2.50419927
36 2.51126313
49 2.51606560
64 2.51944780
81 2.52190781
100 2.52374840
121 2.52515912
144 2.52626276
169 2.52714205
196 2.52785373
225 2.52843738
I think you want powers of: 2**i not squares: i**2. For example:
do i = 0,8
print*, 2**i
enddo
gives
1
2
4
8
16
32
64
128
256
I was originally voting to close as a typo, but your code maybe indeed does something different.
Your codes makes n to be a sequence if integer squares. 1^2, 2^2, 3^2 ... 16^2=256
But you wanted doubling the number, in that case just multiply n by 2.
n = 1
do i = 1, 10
do what you need
print *, n
n = n * 2
end do
I want to write the time in a txt file but I have a problem. The problem is if the Sec is 14.999 or sec is 10^-6 so that it will be wrong. How can I write this conditions? where am I doing wrong? The result is for second case is 0.000 but I need 00.000.
The first one result is : 14.999
The second one result is : 0. 0
First condition Milisec = 999
Second condition Milisec = 0
-------------------------
Result should be if sec is 14.999 : 14.999
Result should be if sec is 10^-6 : 00.000
---------------------Code --------------------
program test
Real :: Sec,Sec2
integer :: milisec, Milisec2
Sec=14.999
milisec = 999
Sec2=0
milisec2 = 0
Write(*, 400) int(sec), '.', milisec
Write(*, 400) int(Sec2), '.', milisec2
400 Format (I2,A1,I3.3)
end program test
I have the following data
X Y INFTIME
1 1 0
1 2 4
1 3 4
1 4 3
2 1 3
2 2 1
2 3 3
2 4 4
3 1 2
3 2 2
3 3 0
3 4 2
4 1 4
4 2 3
4 3 3
4 4 0
X and Y represent he X and Y components in the square grid of 4 by 4.
Here I want to sample randomly 10% from the population which are infected i.e, whose INFTIME is non zero. I did not get any idea of coding so could not start it.
Any suggestions and idea will be great for me.
Thanks
EDIT:
DO T = 1,10
DO i = 1, 625
IF(INFTIME(i)/=0 .AND. INFTIME(i) .LE. T)THEN
CALL RANDOM_NUMBER(u(i))
u(i) = 1+aint(u(i)*25)
CALL RANDOM_NUMBER(v(i))
v(i) = 1+aint(v(i)*25)
CALL RANDOM_NUMBER(w(i))
w(i) = 1+aint(w(i)*10)
ENDIF
ENDDO
ENDDO
do p = 1,625
WRITE(*,*) u(p),v(p),w(p)
enddo
This is my code what I tried but it only gives the random numbers, not the connection to the data. I used the data of 25 by 25 grids i.e, 625 individuals and time of infection 1 to 10
Follow what ja72 said. You have three 1D arrays of the same size (16). All you need to do is pick a number between 1 and 16, check to see if INFTIME is zero and accept the value as needed, then repeat until you've taken 10% of the samples (which would be 1.6 values, so I presume you'd just take 2? Or do you have more data than this 4x4 you presented?)
Edit You need to call the random number generator before the if statement:
do t=1,10
do i=1,625
ind = 1+int(624*rand(seed))
if(inftime(ind).neq.0 .and. inftime(ind).le.t) then
stuff
endif
enddo
enddo
The call ind=1+int(625*rand(seed)) will pick a random integer between 1 (when rand(seed)=0) and 625 (when rand(seed)=1). Then you can do what you need if the if statement is satisfied.
EDIT: program epimatrix
IMPLICIT NONE
INTEGER ::l, i,T,K
REAL, DIMENSION(1:625):: X,y,inftime
INTEGER::seed,my_cnt
INTEGER,DIMENSION(8) :: time1
CALL DATE_AND_TIME(values=time1)
seed = 1000*time1(7)+time1(8)
call srand(seed)
OPEN(10, FILE = 'epidemicSIR.txt', FORM = 'FORMATTED')
DO l = 1,625
READ(10,*,END = 200) X(l), Y(l), INFTIME(l)
! WRITE(*,*) X(l),Y(l), INFTIME(l)
! if you know how it was formatted, you should use
! read(10,20) X(l), Y(l), INFTIME(l)
! where 20 is the format
ENDDO
200 CONTINUE
CLOSE(10)
DO T = 1,10
my_cnt=0
write(*,*) "T=",T
DO while (my_cnt.le.63)
K = 1+int(624*rand())
IF(INFTIME(K)/=0 .AND. INFTIME(K) .LE. T)THEN
write(*,*) X(k),Y(k),INFTIME(k)
my_cnt=my_cnt+1
ENDIF
enddo
write(*,*) " "
ENDDO
end program
EDIT 2
I've adjusted the program to fix some of the issues. I've tried keeping my edits in lowercase so that you can see the difference. The do-while loop allows the code to continue running until the condition my_cnt.le.63 has been met (which means you have 63 lines of X, Y, inftime per T). I've added a line to output T and another line to add a space so that the data might be more clear when looking at the output.
This should take care of all the issues you've been running into. If not, I'll keep checking this page.
Here is my code:
program change
integer:: amount, remainder, q, d, n, p
amount = 47
remainder = amount
print*,remainder
q = 0
d = 0
n = 0
p = 0
do while (remainder >= 25)
remainder = remainder - 25
print*,remainder
q = q + 1
end do
do while (remainder >= 10)
remainder = remainder - 25
print*,remainder
d = d + 1
end do
do while (remainder >= 5)
remainder = remainder - 25
print*,remainder
n = n + 1
end do
do while (remainder >= 1)
remainder = remainder - 25
print*,remainder
p = p + 1
end do
print*, "# Quarters:", q
print*, "# Dimes:", d
print*, "# Nickels:", n
print*, "# Pennies:", p
end program change
Output:
47
22
-3
# Quarters: 1
# Dimes: 1
# Nickels: 0
# Pennies: 0
The first loop (>=25) should exit once the remainder becomes 22, but it runs through once more and yields a negative number. Why is this not exiting even though the condition is false? I'm using IDEone.com's Fortran "compiler" which appears to be Fortran 95-like.
Your DO loops are fine. You simply need to subtract the correct denomination from remainder in each loop. For instance change your second DO loop to:
do while (remainder >= 10)
remainder = remainder - 10
print*,remainder
d = d + 1
end do
and change the rest in a similar manner.