- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This program was written as a test bed to test the algortihm in the subroutine delay_alg_int. The idea of the subroutine is that it takes the initial failure value, u. It then divides this u value by t to give a value, a. I then use INT(a) to give me an integer value which tells me the lower bound of the interval in which u lies. For example when u=12.5 and t=2, a=6.25. Converting using INT() gives me six, so i know now that the value lies betwen the sixth and seventh inspections. Using the upper bound of the inspection interval, in the example the seventh inspection, i now test to see if u is greater than or equal to (t-h) if it is the the system undergoes inspection if not the system breaksdown. The inspection and breakdown have different values an inspection takes 1 hr and a breakdown is 10 hrs. All the testbed does is return the value of DTSUM which is the downtime.
The algoritm works fine when change the variables to force a breakdown e.g. u=12.5,t=2 and h=1 and the testbed returns a downtime of 10 hrs. However when i force it to result in an inspection e.g. u=12.5,t=2 and h=1.5 the testbed returns the inspection downtime of 1 hr. I have spent alot of time trying to figure out why it doesent work for the inspection and im at a loss! If anyone could have a read through the code below and spot something i would be eternally gratefull! Its been really fustrating me as ive debugged much larger algoritms than this!
program delay_alg
IMPLICIT NONE
REAL ::U=12.5 !initial failure point
REAL ::H=1.5 !dealy time value
REAL ::DTSUM
CALL DELAY_ALG_INT(DTSUM)
WRITE (*,*) DTSUM
END PROGRAM
SUBROUTINE DELAY_ALG_INT(DTSUM)
IMPLICIT NONE
REAL, INTENT(OUT) ::DTSUM
REAL ::U !initial failure point
REAL ::H !delay time value
REAL ::a !variable which indicates inspection interval of interest
REAL ::INS=1.0 !downtime caused by inspection
REAL ::BK=10.0 !downtime caused by breakdown
INTEGER ::T=2 !inspection time, in this case every two hours
INTEGER ::aINT !integer result of a conversion
INTEGER ::REL_INT !upper bound of relavant inspection
NO_1:IF(U.LT.1.0)THEN
NO_2:IF(U.GE.(T-H))THEN
!INSPECTION BREAKDOWN
DTSUM=DTSUM+INS
ELSE !(U.LT.(T-H))
!BREAKDOWN
DTSUM=DTSUM+BK
END IF NO_2
ELSE !(U.GE.1)
a=U/T !a IS AN INTERMEDIATE VALUE WHICH INDICATES THE INSPECTION INTERVAL OF INTEREST
aINT=INT(a)
REL_INT=(aINT*T)+T
NO_3:IF(U.GE.(REL_INT-H))THEN
!INSPECTION BREAKDOWN
DTSUM=DTSUM+INS
ELSE !(U.LT.(T-H))
!BREAKDOWN
DTSUM=DTSUM+BK
END IF NO_3
END IF NO_1
END SUBROUTINE
The algoritm works fine when change the variables to force a breakdown e.g. u=12.5,t=2 and h=1 and the testbed returns a downtime of 10 hrs. However when i force it to result in an inspection e.g. u=12.5,t=2 and h=1.5 the testbed returns the inspection downtime of 1 hr. I have spent alot of time trying to figure out why it doesent work for the inspection and im at a loss! If anyone could have a read through the code below and spot something i would be eternally gratefull! Its been really fustrating me as ive debugged much larger algoritms than this!
program delay_alg
IMPLICIT NONE
REAL ::U=12.5 !initial failure point
REAL ::H=1.5 !dealy time value
REAL ::DTSUM
CALL DELAY_ALG_INT(DTSUM)
WRITE (*,*) DTSUM
END PROGRAM
SUBROUTINE DELAY_ALG_INT(DTSUM)
IMPLICIT NONE
REAL, INTENT(OUT) ::DTSUM
REAL ::U !initial failure point
REAL ::H !delay time value
REAL ::a !variable which indicates inspection interval of interest
REAL ::INS=1.0 !downtime caused by inspection
REAL ::BK=10.0 !downtime caused by breakdown
INTEGER ::T=2 !inspection time, in this case every two hours
INTEGER ::aINT !integer result of a conversion
INTEGER ::REL_INT !upper bound of relavant inspection
NO_1:IF(U.LT.1.0)THEN
NO_2:IF(U.GE.(T-H))THEN
!INSPECTION BREAKDOWN
DTSUM=DTSUM+INS
ELSE !(U.LT.(T-H))
!BREAKDOWN
DTSUM=DTSUM+BK
END IF NO_2
ELSE !(U.GE.1)
a=U/T !a IS AN INTERMEDIATE VALUE WHICH INDICATES THE INSPECTION INTERVAL OF INTEREST
aINT=INT(a)
REL_INT=(aINT*T)+T
NO_3:IF(U.GE.(REL_INT-H))THEN
!INSPECTION BREAKDOWN
DTSUM=DTSUM+INS
ELSE !(U.LT.(T-H))
!BREAKDOWN
DTSUM=DTSUM+BK
END IF NO_3
END IF NO_1
END SUBROUTINE
Link Copied
8 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - andibrains
This program was written as a test bed to test the algortihm in the subroutine delay_alg_int. The idea of the subroutine is that it takes the initial failure value, u. It then divides this u value by t to give a value, a. I then use INT(a) to give me an integer value which tells me the lower bound of the interval in which u lies. For example when u=12.5 and t=2, a=6.25. Converting using INT() gives me six, so i know now that the value lies betwen the sixth and seventh inspections. Using the upper bound of the inspection interval, in the example the seventh inspection, i now test to see if u is greater than or equal to (t-h) if it is the the system undergoes inspection if not the system breaksdown. The inspection and breakdown have different values an inspection takes 1 hr and a breakdown is 10 hrs. All the testbed does is return the value of DTSUM which is the downtime.
The algoritm works fine when change the variables to force a breakdown e.g. u=12.5,t=2 and h=1 and the testbed returns a downtime of 10 hrs. However when i force it to result in an inspection e.g. u=12.5,t=2 and h=1.5 the testbed returns the inspection downtime of 1 hr. I have spent alot of time trying to figure out why it doesent work for the inspection and im at a loss! If anyone could have a read through the code below and spot something i would be eternally gratefull! Its been really fustrating me as ive debugged much larger algoritms than this!
program delay_alg
IMPLICIT NONE
REAL ::U=12.5 !initial failure point
REAL ::H=1.5 !dealy time value
REAL ::DTSUM
CALL DELAY_ALG_INT(DTSUM)
WRITE (*,*) DTSUM
END PROGRAM
SUBROUTINE DELAY_ALG_INT(DTSUM)
IMPLICIT NONE
REAL, INTENT(OUT) ::DTSUM
REAL ::U !initial failure point
REAL ::H !delay time value
REAL ::a !variable which indicates inspection interval of interest
REAL ::INS=1.0 !downtime caused by inspection
REAL ::BK=10.0 !downtime caused by breakdown
INTEGER ::T=2 !inspection time, in this case every two hours
INTEGER ::aINT !integer result of a conversion
INTEGER ::REL_INT !upper bound of relavant inspection
NO_1:IF(U.LT.1.0)THEN
NO_2:IF(U.GE.(T-H))THEN
!INSPECTION BREAKDOWN
DTSUM=DTSUM+INS
ELSE !(U.LT.(T-H))
!BREAKDOWN
DTSUM=DTSUM+BK
END IF NO_2
ELSE !(U.GE.1)
a=U/T !a IS AN INTERMEDIATE VALUE WHICH INDICATES THE INSPECTION INTERVAL OF INTEREST
aINT=INT(a)
REL_INT=(aINT*T)+T
NO_3:IF(U.GE.(REL_INT-H))THEN
!INSPECTION BREAKDOWN
DTSUM=DTSUM+INS
ELSE !(U.LT.(T-H))
!BREAKDOWN
DTSUM=DTSUM+BK
END IF NO_3
END IF NO_1
END SUBROUTINE
The algoritm works fine when change the variables to force a breakdown e.g. u=12.5,t=2 and h=1 and the testbed returns a downtime of 10 hrs. However when i force it to result in an inspection e.g. u=12.5,t=2 and h=1.5 the testbed returns the inspection downtime of 1 hr. I have spent alot of time trying to figure out why it doesent work for the inspection and im at a loss! If anyone could have a read through the code below and spot something i would be eternally gratefull! Its been really fustrating me as ive debugged much larger algoritms than this!
program delay_alg
IMPLICIT NONE
REAL ::U=12.5 !initial failure point
REAL ::H=1.5 !dealy time value
REAL ::DTSUM
CALL DELAY_ALG_INT(DTSUM)
WRITE (*,*) DTSUM
END PROGRAM
SUBROUTINE DELAY_ALG_INT(DTSUM)
IMPLICIT NONE
REAL, INTENT(OUT) ::DTSUM
REAL ::U !initial failure point
REAL ::H !delay time value
REAL ::a !variable which indicates inspection interval of interest
REAL ::INS=1.0 !downtime caused by inspection
REAL ::BK=10.0 !downtime caused by breakdown
INTEGER ::T=2 !inspection time, in this case every two hours
INTEGER ::aINT !integer result of a conversion
INTEGER ::REL_INT !upper bound of relavant inspection
NO_1:IF(U.LT.1.0)THEN
NO_2:IF(U.GE.(T-H))THEN
!INSPECTION BREAKDOWN
DTSUM=DTSUM+INS
ELSE !(U.LT.(T-H))
!BREAKDOWN
DTSUM=DTSUM+BK
END IF NO_2
ELSE !(U.GE.1)
a=U/T !a IS AN INTERMEDIATE VALUE WHICH INDICATES THE INSPECTION INTERVAL OF INTEREST
aINT=INT(a)
REL_INT=(aINT*T)+T
NO_3:IF(U.GE.(REL_INT-H))THEN
!INSPECTION BREAKDOWN
DTSUM=DTSUM+INS
ELSE !(U.LT.(T-H))
!BREAKDOWN
DTSUM=DTSUM+BK
END IF NO_3
END IF NO_1
END SUBROUTINE
sorry made typo, when trying to force the inspection it returns the downtime for a breakdown
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The program as written prints 10.0, however, that's because the initial values for U and H are undefined within the scope of the subroutine.
The subroutine has no visibility of the initial values for U or H that are assigned in the main program. There aredifferent ways to get those initial values into the scope of the subroutine. One quick way isto modifythe call to DELAY_ALG_INT and pass in U and H and add the corresponding dummy arguments to the subroutine (see below). When done, the program prints the value of 1.0. I gather that's is the result you are after.
Make the following changes:
CALL DELAY_ALG_INT(DTSUM,U,H)
and
SUBROUTINE DELAY_ALG_INT(DTSUM,U,H)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
should i then us then INTENT(IN) statement for U and Hin the declaration section of the subroutine?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That's not required, but you can if you wish.Thisis amatter of programming style. Doing so helps guard against redefining the dummy argument within the procedure.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Excellent, that has solved the problem, i cant believe it was so simple i was doubting my logic! just out of interest if U and H were not visible to the subroutine how did they aquireany values in the first place?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - andibrains
Excellent, that has solved the problem, i cant believe it was so simple i was doubting my logic! just out of interest if U and H were not visible to the subroutine how did they aquireany values in the first place?
They were visible. They were *local* variables, and their values were whatever happened to be in memory at the time (unless your compiler options specify that local variables are initialized to zero.)
It is usually a good idea to turn on all compile and run time diagnostic warnings when developing code - check uninitialized variables could have caught this.
Les
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - andibrains
Excellent, that has solved the problem, i cant believe it was so simple i was doubting my logic! just out of interest if U and H were not visible to the subroutine how did they aquireany values in the first place?
You declared the variables in the subroutine, so the compiler set aside memory, local to the subroutine, to
store the variables. Some compilers will assign an initial value to this memory, but this is not required by the standard. If an initial value is not assigned, then you get whatever happened to be in that memory location
at the time your program runs.
Many people assume (mistakenly) that memory gets initialized to 0, probably because they've used compilers
that did this by default. They write programs assuming this behavior and are then mystified when they switch to
another compiler and their program doesn't work correctly.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As the others said, every variable has an initial value. The question really is, is the variables initial value defined or undefined?
I suspect you might have also been tripped up here by overlooking the scope of the variables U and H within the main and the subroutine scopes. As others said, as originally written, you declared U and H local to both the subroutine and the main; those were unique instances of the variables with no sharing of that initial value assigned in the main.
Given all that you have learned here, you should be able to find and fix the one remaining issue with your program that could still potentially lead to incorrect results. You can determine what that is and how to fix it if you ask yourself this question:
What is the initial value of DTSUM?
Then ask yourself, what is the value of DTSUM after either of these statements from your subroutine executes?
DTSUM=DTSUM+INS
DTSUM=DTSUM+BK
I suspect you might have also been tripped up here by overlooking the scope of the variables U and H within the main and the subroutine scopes. As others said, as originally written, you declared U and H local to both the subroutine and the main; those were unique instances of the variables with no sharing of that initial value assigned in the main.
Given all that you have learned here, you should be able to find and fix the one remaining issue with your program that could still potentially lead to incorrect results. You can determine what that is and how to fix it if you ask yourself this question:
What is the initial value of DTSUM?
Then ask yourself, what is the value of DTSUM after either of these statements from your subroutine executes?
DTSUM=DTSUM+INS
DTSUM=DTSUM+BK

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page