From: Rune Allnor on 25 May 2010 08:12 On 25 Mai, 12:50, "Baalzamon " <baalzamon_mori...(a)yahoo.com> wrote: > Howdy there, once again. With regards to a few of the points brought up by various people. > 1) The main code has several subroutine calls and by my quick flowchart-check the calls go five deep at a max. That is to say once calls another, which calls another, which calls another etc. These are the key points one would look for in a procedural language: Isolate what goes on inside each subroutine (the same as 'function' in matlab), make sure one understands what each function is supposed to do, then test it independently. Once you have done all that, you can be *reasonably* sure (but by no means certain) you have a good building block for what follows. > 2) There are goto jumps, including the much tricksome (for a complete newcomer such as myself) 'computed?' goto. I have never heard of it before, and there is no reason why you should have to deal with it. This was obsolete 40 years ago. > 3) The maths behind the routine are currently beyond me. Though largely this wouldn't be a problem if the source code was filled with comments explaining what is the point of lines x to y etc. Exactly. The author likely used all kinds of tricks *both* with the implementation *and* the algorithm. The job is hard enough if one only wants to derive the algorithm - there is no need to have to deal with 40-year-old tricks no one have had to deal with after Neal Armstrong walked the moon. Which is why you would want to derive the algorithm from scratch and record the algorithm. As for comments, that's the main problem with computer programming: The comments and the code are two different accounts for the same algorithm. The problem is to keep them synced up: It is enough work to maintain the *code*, that makes the program do its job. Keeping an independent comments base updated effectively doubles the amount of work required, eventually causing that code and comments slip out of sync. The trend these days is to write lots of small, trivial functions, that do very little and that have descriptive names that explain to the human reader what they do. Some program I wrote a few years back have a main routine that goes something like [*]: function coeffs = computeIIRfilterCoefficients(spec) if (specificationIsValid(spec)) Nspec = normalizeSpec(spec); PWSpec = preWarpSpec(Nspec); Order = FindOrder(PWspec); SDcoeffs = ComputeSDomainCoeffs(PWspec,Order); ZDcoeffs = BilinearTransform(SDcoeffs); coeffs = DenormalizeFilter(ZDcoeffs,spec); end Somebody who knows a little about the filter design procedure in question immediately understands what is going on here, merely by reading the names of the subroutines. Each of the functions contain similarly self-documenting code, and this goes on until the contents of a function can be described by a single formula. [*] (I wrote C++ rather than matlab, as matlab has way to high run-time penalty at function calls for this style of coding. C++ also allows me, the coder, to delegate a number of tests and conditionals to the compiler. For instance, there are mo tests in the code snippet above to determine if the filter in question is a low pass, high pass or other filter. This information is encoded in the type of the filter specification, and it is the compiler's responsibility, not the coder's, to ensure that the low-pass versions of the routines are called when a low-pass spec is issued to the routine.) Coding in this way might seem a bit demanding up front, as one clearly needs to understand *exactly* what is going on and what the program is going to do, to pull off something like this. But on the other hand, only a fool would think one can get a working program up and running *without* that kind of understanding of the problem domain.... > Er there were some more points, however, I got lost during the reading of this topic. > Currently I have translated some of it...until i found that I had to set x=y where y is not established until a subroutine call later on. Which means that either - You have missed something. - The code you use works with relies on uninitialized variables - The code you work with relies on stuff going on one or more levels above the one you have access to (that y belongs in the scope of the program that calls the routine you work with) - The variable y is implicitly initialized by the compiler. You can *hope* for the latter, but don't rely on it. > Some specfic questions: > excerpt from code > if (a .eq. 1) goto 85 > Now does this mean that if a does not equal 1 then execute code immeadiately after the if statement... Yes. > then when we arrive at '85' do we ignore it or execture also? Yes, unless a branch has been reached in between. > Go to (15,25), L > DOes this mean depending upon the values of 'L' jump to 15 or 25? If so Is the argument governed by 'L' in ascending order? Such that, say 'L' could be 1 or 2 then if L=1 go to 15 and if L=2 go to 25? Who knows? These are the kinds of things that would be handled by literal if-then-else tests or case-switch tests in C and later languages. The main difference is that literal statements are immediately understandable to the human reader of the code. They don't mean much to the compiler, as it will be able to translate the literal statements more or less 1:1 to gibberish like the above. The point is that you, the user, should have to deal with *what* the routine does, not *how* it does it. This lack of focus on the human user is *the* main drawback of fortran (along with that stuff that is trivial in later languages is at least cumbersome, maybe even difficult, to pull off with fortran) and is the main reason why you would want to have as little as possible to do with it. Depending on where you got the code from, find any companion reports, published articles, or other documents, and use them to derive the algorithm from scratch. Rune
From: dpb on 25 May 2010 10:07 Baalzamon wrote: .... > 1) The main code has several subroutine calls and by my quick > flowchart-check the calls go five deep at a max. That is to say one > calls another, which calls another, which calls another etc. Yes, Rune's got this part right w/o editorializing... > 2) There are goto jumps, including the much tricksome (for a complete > newcomer such as myself) 'computed?' goto. Only because it's a construct you're not familiar with...it has a specific syntax > 3) The maths behind the routine are currently beyond me. Though largely > this wouldn't be a problem if the source code was filled with comments > explaining what is the point of lines x to y etc. That is a potential problem w/ any code no matter what the language, of course...that's a function of the coder, not the language. .... > Currently I have translated some of it...until i found that I had to set > x=y where y is not established until a subroutine call later on. It's possible there's a code bug; more likely you missed the previous definition/assignment of y. Perhaps it's in COMMON? > Some specfic questions: excerpt from code > if (a .eq. 1) goto 85 > Now does this mean that if a does not equal 1 then execute code > immediately after the if statement...then when we arrive at '85' do we > ignore it or execute also? Yes, if the branch is not taken, code sequence "falls through" to the next statement in sequence. Rune's "unless" is, while true, sort of a red herring -- the rules are the same as you continue irregardless. The target branch is the statement w/ the target label (85 in your example here) and that statement is the next one executed if the branch is taken; that is, the labeled statement is the target, not the line succeeding the label. if(a. eq. 1) go to 85 some code 85 continue more code is the same as if(a .ne. 1) then some code endif more code If the line "more code" had the label instead of a CONTINUE, the result would be the same; that is you can always insert a CONTINUE line w/ the label in front of the code line to aid in visualization if desired. An IF...THEN...ELSE...ENDIF is constructed in a similar fashion as the above IF...ENDIF by the use of a GOTO a second label beyond the desired code of the ELSE block. With a little time, you'll begin to recognize these idioms as you see them. > Go to (15,25), L > DOes this mean depending upon the values of 'L' jump to 15 or 25? If so > Is the argument governed by 'L' in ascending order? Such that, say 'L' > could be 1 or 2 then if L=1 go to 15 and if L=2 go to 25? Yes, that's correct. The only missing action is that if L is outside the range of [1,2] then execution will continue w/ the statement following the GOTO statement From a Fortran language syntax manual... > When the computed GO TO statement is executed, the expression is evaluated first. The value of the expression represents the ordinal position of a label in the associated list of labels. Control is transferred to the statement identified by the label. For example, if the list contains (30,20,30,40) and the value of the expression is 2, control is transferred to the statement identified with label 20. > > If the value of the expression is less than 1 or greater than the > number of labels in the list, control is transferred to the next > executable statement or construct following the computed GO TO > statement Just to make Rune's day, I'll note that the computed GOTO was made obsolescent by the F95 Standard. I'm not sure whether F2003 actually then moved it to the deleted features list or not... But, you'll not find a current compiler that doesn't support it although it can be flagged by a compiler switch that checks for a given level of Standard conformance. I'll ask again...did you look at the tools (specifically Understand for Fortran) at <www.scitools.com> for the trial download to aid in the task? If not it or some of the open source tools of a similar nature you're shortchanging yourself and making it more difficult than it needs be. I'll also reiterate the suggestion to bring the Fortran-specific questions to the Fortran group instead of cs-sm. That would be comp.lang.fortran accessible from any newsreader pointing at one of the free usenet mirror sites or via the Google Groups interface. --
From: Walter Roberson on 25 May 2010 10:11 Baalzamon wrote: > Some > specfic questions: excerpt from code > if (a .eq. 1) goto 85 > Now does this mean that if a does not equal 1 then execute code > immeadiately after the if statement...then when we arrive at '85' do we > ignore it or execture also? Yes, if a is not 1 then the flow continues with the next executable line. If 85 is ever reached then it will be executed. There is no internal record kept of which branches have occurred. > Go to (15,25), L > DOes this mean depending upon the values of 'L' jump to 15 or 25? Yes. > If so > Is the argument governed by 'L' in ascending order? Such that, say 'L' > could be 1 or 2 then if L=1 go to 15 and if L=2 go to 25? Yes. Computed GOTOs were discouraged in Fortran starting with Fortran77. None the less, in most languages that support some sort of switch statement, the switch cases must be constants, and in the case where the values are sequential, the program will end up internally executing something like a computed GOTO. The _functionality_ of computed GOTOs is thus still very much alive, but the _syntax_ of computed GOTOs is not.
From: Walter Roberson on 25 May 2010 10:16 Baalzamon wrote: > Some > specfic questions: excerpt from code > if (a .eq. 1) goto 85 > Now does this mean that if a does not equal 1 then execute code > immeadiately after the if statement...then when we arrive at '85' do we > ignore it or execture also? Yes, if a is not 1 then the flow continues with the next executable line. If 85 is ever reached then it will be executed. There is no internal record kept of which branches have occurred. > Go to (15,25), L > DOes this mean depending upon the values of 'L' jump to 15 or 25? Yes. > If so > Is the argument governed by 'L' in ascending order? Such that, say 'L' > could be 1 or 2 then if L=1 go to 15 and if L=2 go to 25? Yes. Computed GOTOs were discouraged in Fortran starting with Fortran77. None the less, in most languages that support some sort of switch statement, the switch cases must be constants, and in the case where the values are sequential, the program will end up internally executing something like a computed GOTO. The _functionality_ of computed GOTOs is thus still very much alive, but the _syntax_ of computed GOTOs is not.
From: Steve Amphlett on 25 May 2010 10:36
Walter Roberson <roberson(a)hushmail.com> wrote in message <eZQKn.10565$%u7.5758(a)newsfe14.iad>... > > Computed GOTOs were discouraged in Fortran starting with Fortran77. None > the less, in most languages that support some sort of switch statement, > the switch cases must be constants, and in the case where the values are > sequential, the program will end up internally executing something like > a computed GOTO. The _functionality_ of computed GOTOs is thus still > very much alive, but the _syntax_ of computed GOTOs is not. Computed GOTO is horrible. I once did something similar in assembler (my code modified the jump address on the fly, so the program changed its own flow). Unfortunately the program that puts my meals on the table is still based on one large computed GOTO. |