From: Rune Allnor on
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
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
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
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
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.