For Programmers: Free Programming Magazines  


Home > Archive > Fortran > March 2007 > Print statement within If-Then block changes output!!!????









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Print statement within If-Then block changes output!!!????
watsteel

2007-03-18, 7:07 pm

Hello,
I'm new to fortran, and I'm having a problem tracking a bug in my
code.

I have a pair of If-then blocks to store a minimum residual.
While debugging, I noticed that a 'Print' statement placed within the
second block would change the program's output. I've tried 'Print *',
Write(both to * and to unit=2, which was opened.), and I've changed
the location of the 'Print' statement within the block, but all to no
avail. If the 'Print' statement is in the block, the output changes.
There are two sets of output, depending on whether the 'Print'
statement exists in the block or not.

The program is only 195 lines of code. The input file if 15 lines of
code.
I will happily e-mail them to anyone who can spare the time to look
this over--I'm stumped.

I'm using GNU G77, on a Dell laptop, running XP Home.

And my forehead is getting bruised from banging it on my desk, so any
help would be greatly appreciated.

Thanks
Vic
watsteel@hotmail.com

Dan Nagle

2007-03-18, 7:07 pm

Hello,

watsteel wrote:
> Hello,
> I'm new to fortran, and I'm having a problem tracking a bug in my
> code.
>
> I have a pair of If-then blocks to store a minimum residual.
> While debugging, I noticed that a 'Print' statement placed within the
> second block would change the program's output.


That's a compiler bug.

> I've tried 'Print *',
> Write(both to * and to unit=2, which was opened.), and I've changed
> the location of the 'Print' statement within the block, but all to no
> avail. If the 'Print' statement is in the block, the output changes.
> There are two sets of output, depending on whether the 'Print'
> statement exists in the block or not.
>
> The program is only 195 lines of code. The input file if 15 lines of
> code.
> I will happily e-mail them to anyone who can spare the time to look
> this over--I'm stumped.
>
> I'm using GNU G77, on a Dell laptop, running XP Home.


g77 is old and no longer supported.
Try using g95 or gfortran. Any f95 compiler will compile f77.

> And my forehead is getting bruised from banging it on my desk, so any
> help would be greatly appreciated.


--
Cheers!

Dan Nagle
Purple Sage Computing Solutions, Inc.
Beliavsky

2007-03-18, 7:07 pm

On Mar 18, 10:05 am, Dan Nagle <danna...@verizon.net> wrote:
> Hello,
>
> watsteel wrote:
>
>
> That's a compiler bug.


Probably there is a bug in watsteel's PROGRAM, which may be trying to
access an out-of-bounds array element. When a program does that,
inserting a PRINT statement can lead to strange changes in how the
program works.
[color=darkred]
> g77 is old and no longer supported.
> Try using g95 or gfortran. Any f95 compiler will compile f77.
>

The first thing to do is to turn on all the debugging options of the
compiler you are using. You can type g77 -v --help to get a list of
compiler options. Try compiling and running your code with the -
fbounds-check option.

As Dan Nagle suggested, you can try another compiler, such as g95 or
gfortran, which are both free and which support Fortran 95. Why don't
you use Fortran 95, which is a more modern version of the language?
Because of features such as modules, which help to catch errors at
compile time, I bang my head less often than I used to.


Ron Shepard

2007-03-18, 7:07 pm

In article <1174229428.021401.45400@e65g2000hsc.googlegroups.com>,
"watsteel" <avlewis@gmail.com> wrote:

> I have a pair of If-then blocks to store a minimum residual.
> While debugging, I noticed that a 'Print' statement placed within the
> second block would change the program's output.


I assume you mean that it changes the computed results.

This is typical of an out-of-bounds array reference error. It can
also be caused by an argument mismatch in a subprogram call, or
inconsistent common block definitions. Try turning on some runtime
bounds checking options in your compiler and run your f77 code
through ftnchk. I would also suggest that you use a newer compiler,
such a gfortran or a commercial f90 compiler.

$.02 -Ron Shepard
Steven G. Kargl

2007-03-18, 7:07 pm

In article <GycLh.3453$YD.2877@trnddc06>,
Dan Nagle <dannagle@verizon.net> writes:
> Hello,
>
> watsteel wrote:
>
> That's a compiler bug.
>


There isn't enough information to make the above conclusion.
Without seeing the code, I'd guess that it is programming
error (e.g., using an unintialized variable or an array
index out of bounds).

Since OP is using g77, he can run his code through fntchek
and use -Wall to find the bug.

--
Steve
http://troutmask.apl.washington.edu/~kargl/
Colin Watters

2007-03-18, 7:07 pm


"Colin Watters" <qolin.see_signature@nowhere.co.uk> wrote in message
news:etjp3g$97c$1$8300dec7@news.demon.co.uk...
> "Dan Nagle" <dannagle@verizon.net> wrote in message
> news:GycLh.3453$YD.2877@trnddc06...
>
> Bet you a beer it isn't.
>
>


....Well I've had a look at the OP's code and played around with it under
CVF, and I can't see a good reason for the symptoms he is seeing. But then
again, nither can I reproduce his problem.

The is no array over- or under- indexing going on. The only 'questionable'
aspect of the code is the use of double-precision do-loop indices. Maybe G77
has a problem with these? Feels like I'm clutching at straws.

So, Dan, I think I owe you a beer.

--
Qolin

Email: my qname at domain
Domain: qomputing dot demon dot co dot uk --


Dan Nagle

2007-03-18, 10:09 pm

Hello,

Colin Watters wrote:
> "Colin Watters" <qolin.see_signature@nowhere.co.uk> wrote in message
> news:etjp3g$97c$1$8300dec7@news.demon.co.uk...
>
> ...Well I've had a look at the OP's code and played around with it under
> CVF, and I can't see a good reason for the symptoms he is seeing. But then
> again, nither can I reproduce his problem.
>
> The is no array over- or under- indexing going on. The only 'questionable'
> aspect of the code is the use of double-precision do-loop indices. Maybe G77
> has a problem with these? Feels like I'm clutching at straws.
>
> So, Dan, I think I owe you a beer.


I spent some time today moving my email and news from my Linux box
to my Mac. So I could use a beer. :-)

My guess that it was a compiler bug was based on the idea
that an if-block with a print statement is usually
a rather small block, and should only force a few variables
to be stored. It was hard for me to see how that changes
the ill effects of an out-of-bounds index.

OTOH, out-of-bounds is a good first guess, too.

Drat. Now I must fix the .sig file. There's no end to this. :-(

Brooks Moses

2007-03-18, 10:09 pm

watsteel wrote:
> I have a pair of If-then blocks to store a minimum residual.
> While debugging, I noticed that a 'Print' statement placed within the
> second block would change the program's output. I've tried 'Print *',
> Write(both to * and to unit=2, which was opened.), and I've changed
> the location of the 'Print' statement within the block, but all to no
> avail. If the 'Print' statement is in the block, the output changes.
> There are two sets of output, depending on whether the 'Print'
> statement exists in the block or not.
>
> The program is only 195 lines of code. The input file if 15 lines of
> code.
> I will happily e-mail them to anyone who can spare the time to look
> this over--I'm stumped.
>
> I'm using GNU G77, on a Dell laptop, running XP Home.
>
> And my forehead is getting bruised from banging it on my desk, so any
> help would be greatly appreciated.


Presuming that Colin's conclusion that this isn't the usual sort of
out-of-bounds error causing that problem, and that it is in fact a
compiler bug, I think I've got a fair guess which exactly compiler bug
it is, because I've run into it in exactly this situation:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=323.

The short version is of the bug this: The Intel floating-point system
has 80-bit floating-point registers, but has only 64-bit floating-point
storage. Thus, there are cases where, if a value is stored in memory,
its value will be slightly different (due to removing the last 16 bits)
than if its kept in a register.

How this hit me is that I had two numbers where A was supposed to be
greater than or equal to B, but when the comparison was done, one of
them had been stored in memory and the other was still in the register
where it had been calculated, and as a result A.GE.B was false.
Printing out something in the middle of this caused all of the variables
to be shunted out of registers into 64-bit memory slots, and thus made
the bug go away.

One recommended fix for this in GCC/g77/gfortran is the -ffloat-store
option, which forces all floating-point values to go through a memory
store before being used, thereby assuring that they're consistently
truncated to 64 bits. It's worth a try to see if using that flag causes
your problem to disappear. (It does slow down the program a bit, though.)

- Brooks


--
The "bmoses-nospam" address is valid; no unmunging needed.
watsteel

2007-03-20, 7:09 pm

<snip>

Hello all,

Many thanks for all the comments.

I took Qolin's advice and tried compiling using gfortran, and the
little bug seems to have been squashed. So that's good. He also
suggested I re-write the code to get rid to the Real-type DO loop
indexes, and I will do that for sure.

As a note to other comments, when I compile using G77, I use 'g77 -
Wall name.f -O -o name', but no message re this error/bug.
I have read of, but not used ftnchk. That will change.
I did 'g77 --help', and didn't spend enough time trying to find out
what all the options did. Yeah, rtfm...That too will change.

And possibly my biggest brain-fart--I assumed that while f77 was less
feature-rich than newer options such as f95, it would be stable since
it had been around for so long. Maybe I should have banged my forehead
on the desk a little earlier.

I just tried Brooks' suggestion of compiling with the -ffloat-store
switch, and hey, no buggy output, it seems.

You guys are the best!

I'll follow this post with the code, and the input file, in case
anyone else what's to have a look.

Cheers,

Vic

watsteel

2007-03-21, 5:42 am

On Mar 20, 4:47 pm, "Beliavsky" <beliav...@aol.com> wrote:
> Would you mind if I made some constructive stylistic comments on the
> code?


I'd appreciate any constructive comments, stylistic or otherwise.

Thanks,


Beliavsky

2007-03-21, 5:42 am

On Mar 20, 3:33 pm, "watsteel" <avle...@gmail.com> wrote:

<snip>

"Magic numbers" are bad. Write

INTEGER N
PARAMETER (N = 150)

and use N in the declarations below.

In Fortran 90 you can write

INTEGER, PARAMETER :: N = 150

> DOUBLE PRECISION Fy(150), t(150), Pt(150)
> DOUBLE PRECISION R(150), N(150), h(150)


<snip>

> OPEN(1,FILE="bdata_d.txt")


One should specify the ACTION in an OPEN statement and use a PARAMETER
for file units. You could write

OPEN(in_unit,file="bdata_d.txt",action="read",status="old")

where in_unit would be a PARAMETER defined earlier.

>
> DO WHILE (.TRUE.)

Instead of the line above, just write "DO"

> READ (1,*, end=200) t(I), Fy(I), R(I), N(I), h(I), Pt(I)
>
> WRITE(*,20) t(I), Fy(I), R(I), N(I), h(I), Pt(I), CNT, I
> CNT = CNT + 1
> I = I + 1
> END DO


<snip>

>
> 510 CONTINUE
> 520 CONTINUE
> 530 CONTINUE
> 540 CONTINUE


Use ENDDO. A compiler supporting DO WHILE will support ENDDO.

<snip>

e p chandler

2007-03-21, 7:05 pm

On Mar 18, 9:53 pm, Brooks Moses <bmoses-nos...@cits1.stanford.edu>
wrote:
> watsteel wrote:
>
>
>
>
> Presuming that Colin's conclusion that this isn't the usual sort of
> out-of-bounds error causing that problem, and that it is in fact a
> compiler bug, I think I've got a fair guess which exactly compiler bug
> it is, because I've run into it in exactly this situation:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=323.
>
> The short version is of the bug this: The Intel floating-point system
> has 80-bit floating-point registers, but has only 64-bit floating-point
> storage. Thus, there are cases where, if a value is stored in memory,
> its value will be slightly different (due to removing the last 16 bits)
> than if its kept in a register.
>
> How this hit me is that I had two numbers where A was supposed to be
> greater than or equal to B, but when the comparison was done, one of
> them had been stored in memory and the other was still in the register
> where it had been calculated, and as a result A.GE.B was false.
> Printing out something in the middle of this caused all of the variables
> to be shunted out of registers into 64-bit memory slots, and thus made
> the bug go away.
>
> One recommended fix for this in GCC/g77/gfortran is the -ffloat-store
> option, which forces all floating-point values to go through a memory
> store before being used, thereby assuring that they're consistently
> truncated to 64 bits. It's worth a try to see if using that flag causes
> your problem to disappear. (It does slow down the program a bit, though.)
>
> - Brooks


IMO the real solution is for the OP to fix his program and for him to
take a good look at his input data.

Here is the OPs input data with the changes in the predicted values
and the estimated "parameters" induced by using both an "-O" switch
and inserting a Print in the inner loop:

t(I) Fy(I) R(I) N(I) h(I) Pt(I) Pn

.7910 335.58 3.368 25.0 66.193 2.11 3.13 ->
3.27
.7910 335.58 3.368 25.0 66.193 2.16 3.13 ->
3.27
.7910 335.58 3.368 25.0 66.193 2.20 3.13 ->
3.27

.7910 335.58 3.368 25.0 83.682 1.86 3.58 ->
3.73
.7910 335.58 3.368 25.0 83.682 2.12 3.58 ->
3.73

1.078 307.72 3.175 25.0 83.494 3.57 3.44 ->
3.55
1.078 307.72 3.175 25.0 83.494 4.04 3.44 ->
3.55

1.078 307.72 3.175 25.0 90.007 3.96 3.59 ->
3.70
1.078 307.72 3.175 25.0 90.007 4.25 3.59 ->
3.70
1.078 307.72 3.175 25.0 90.007 4.38 3.59 ->
3.70
1.078 307.72 3.175 25.0 90.007 4.46 3.59 ->
3.70

1.547 391.01 3.186 25.0 127.68 7.10 5.66 ->
5.71
1.547 391.01 3.186 25.0 127.68 7.32 5.66 ->
5.71

1.874 453.80 3.195 25.0 153.41 5.75 6.75 ->
6.62
1.874 453.80 3.195 25.0 153.41 6.46 6.75 ->
6.62

iCf = 2.
iCRf = 1.0001 -> 0.9751
iCNf = 0.0001
iChf = 0.8751 -> 0.9501

I've grouped and moved the input data to show that there are multiple
Pt() values for the same set of other input values. This seems odd in
a regression program. Also note that the fitted data is not that close
to the observed data. Note that the step size in the inner loops is
relatively large = .025. Adding a Print statement to the inner loop
changes CR by 1 step and CH by 3 steps when compiled with "-O".

I don't understand why the OP used a "-O" switch anyway. He could have
reduced the run time considerably without resorting to "optimization"
by noting that he is re-computing quantities that are constant for a
particular value of I each time through the inner-most loop.

Instead of

Pn=iC*(t(I)**2)*(Fy(I)/1.d3)*(1-iCR*SQRT(R(I)/t(I)))*
& (1+iCN*SQRT(N(I)/t(I)))*(1-iCh*SQRT(h(I)/t(I)))


Why not pre-compute

x1(i)=(t(I)**2)*(Fy(I)/1.d3)
x2(i)=SQRT(R(I)/t(I)))
x3(i)=SQRT(N(I)/t(I)))
x4(i)=SQRT(h(I)/t(I)))

?

I would also read in M, the number of data points before reading the
data, but that's my preference.

Changing some variable names and using INTEGER DO loops, the core of
the program becomes

msres=1e39 ! a large number
do i1=0,40
C = 0 + i1*.5 ! 0 to 20 step .5
do i2=0,40
CR = .0001 + i2*.025 ! .0001 to 1.0001 step .025
do i3=0,40
CN = .0001 + i3*.025
do i4=0,40
CH = .0001 + i4*.025
sres=0
do i=1,M
Pn=C*x1(i)*(1-CR*x2(i))*(1+CN*x3(i))*(1-CH*x4(i))
sres=(Pn-Pt(i))**2
end do
if (sres < msres) then
msres = sres
CF = C
CRF = CR
CNF = CN
CHF = CH
end if
end do
end do
end do
end do
[blah, blah, blah]

[flame on]

Whether the OP uses G77 or G95 or Gfortran or whether he uses the
latest F95+ syntax or whether hs uses DOUBLE PRECISION instead of REAL
is of little relevance given the numerical instability of his program
and data (IMO).

[flame off]

-- elliot



watsteel

2007-03-21, 7:05 pm

On Mar 21, 10:20 am, "e p chandler" <e...@juno.com> wrote:
> On Mar 18, 9:53 pm, Brooks Moses <bmoses-nos...@cits1.stanford.edu>
> wrote:
>
>
>
[color=darkred]
>
>
>
>
>
>
>
>
>
> IMO the real solution is for the OP to fix his program and for him to
> take a good look at his input data.
>
> Here is the OPs input data with the changes in the predicted values
> and the estimated "parameters" induced by using both an "-O" switch
> and inserting a Print in the inner loop:
>
> t(I) Fy(I) R(I) N(I) h(I) Pt(I) Pn
>
> .7910 335.58 3.368 25.0 66.193 2.11 3.13 ->
> 3.27
> .7910 335.58 3.368 25.0 66.193 2.16 3.13 ->
> 3.27
> .7910 335.58 3.368 25.0 66.193 2.20 3.13 ->
> 3.27
>
> .7910 335.58 3.368 25.0 83.682 1.86 3.58 ->
> 3.73
> .7910 335.58 3.368 25.0 83.682 2.12 3.58 ->
> 3.73
>
> 1.078 307.72 3.175 25.0 83.494 3.57 3.44 ->
> 3.55
> 1.078 307.72 3.175 25.0 83.494 4.04 3.44 ->
> 3.55
>
> 1.078 307.72 3.175 25.0 90.007 3.96 3.59 ->
> 3.70
> 1.078 307.72 3.175 25.0 90.007 4.25 3.59 ->
> 3.70
> 1.078 307.72 3.175 25.0 90.007 4.38 3.59 ->
> 3.70
> 1.078 307.72 3.175 25.0 90.007 4.46 3.59 ->
> 3.70
>
> 1.547 391.01 3.186 25.0 127.68 7.10 5.66 ->
> 5.71
> 1.547 391.01 3.186 25.0 127.68 7.32 5.66 ->
> 5.71
>
> 1.874 453.80 3.195 25.0 153.41 5.75 6.75 ->
> 6.62
> 1.874 453.80 3.195 25.0 153.41 6.46 6.75 ->
> 6.62
>
> iCf = 2.
> iCRf = 1.0001 -> 0.9751
> iCNf = 0.0001
> iChf = 0.8751 -> 0.9501
>
> I've grouped and moved the input data to show that there are multiple
> Pt() values for the same set of other input values. This seems odd in
> a regression program. Also note that the fitted data is not that close
> to the observed data. Note that the step size in the inner loops is
> relatively large = .025. Adding a Print statement to the inner loop
> changes CR by 1 step and CH by 3 steps when compiled with "-O".
>
> I don't understand why the OP used a "-O" switch anyway. He could have
> reduced the run time considerably without resorting to "optimization"
> by noting that he is re-computing quantities that are constant for a
> particular value of I each time through the inner-most loop.
>
> Instead of
>
> Pn=iC*(t(I)**2)*(Fy(I)/1.d3)*(1-iCR*SQRT(R(I)/t(I)))*
> & (1+iCN*SQRT(N(I)/t(I)))*(1-iCh*SQRT(h(I)/t(I)))
>
> Why not pre-compute
>
> x1(i)=(t(I)**2)*(Fy(I)/1.d3)
> x2(i)=SQRT(R(I)/t(I)))
> x3(i)=SQRT(N(I)/t(I)))
> x4(i)=SQRT(h(I)/t(I)))
>
> ?
>
> I would also read in M, the number of data points before reading the
> data, but that's my preference.
>
> Changing some variable names and using INTEGER DO loops, the core of
> the program becomes
>
> msres=1e39 ! a large number
> do i1=0,40
> C = 0 + i1*.5 ! 0 to 20 step .5
> do i2=0,40
> CR = .0001 + i2*.025 ! .0001 to 1.0001 step .025
> do i3=0,40
> CN = .0001 + i3*.025
> do i4=0,40
> CH = .0001 + i4*.025
> sres=0
> do i=1,M
> Pn=C*x1(i)*(1-CR*x2(i))*(1+CN*x3(i))*(1-CH*x4(i))
> sres=(Pn-Pt(i))**2
> end do
> if (sres < msres) then
> msres = sres
> CF = C
> CRF = CR
> CNF = CN
> CHF = CH
> end if
> end do
> end do
> end do
> end do
> [blah, blah, blah]
>
> [flame on]
>
> Whether the OP uses G77 or G95 or Gfortran or whether he uses the
> latest F95+ syntax or whether hs uses DOUBLE PRECISION instead of REAL
> is of little relevance given the numerical instability of his program
> and data (IMO).
>
> [flame off]
>
> -- elliot


What does 'OP' mean?
Also, each line in the data file presents the results of a particular
test, and some of the test parameters. This may make the reason for
the "multiple Pt() values for the same set of other input values" a
little more clear.

> sres=0
> do i=1,M
> Pn=C*x1(i)*(1-CR*x2(i))*(1+CN*x3(i))*(1-CH*x4(i))
> sres=(Pn-Pt(i))**2
> end do
> if (sres < msres) then
> msres = sres



watsteel

2007-03-21, 7:05 pm

On Mar 21, 11:24 am, "watsteel" <avle...@gmail.com> wrote:[color=darkred]
> On Mar 21, 10:20 am, "e p chandler" <e...@juno.com> wrote:
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> What does 'OP' mean?
> Also, each line in the data file presents the results of a particular
> test, and some of the test parameters. This may make the reason for
> the "multiple Pt() values for the same set of other input values" a
> little more clear.
>

Oops, hit <Enter> to soon!

I like the msres=1e39 ! a large number plus the rest of that. A lot
cleaner.
Like I said, I'm a newbie. In my blind ignorance, the -O seemed like a
good idea at the time.
[color=darkred]
I had originally done this, but it seemed to me that 'DO WHILE
(.TRUE.) ' would suffice. My bad.

Thanks for the comments. I'll look the rest over.

Cheers,

Vic

Paul van Delst

2007-03-21, 7:05 pm

watsteel wrote:
> What does 'OP' mean?


Original poster. I.e. the person that initiated the thread (in this case, you).

cheers,

paulv

--
Paul van Delst Ride lots.
CIMSS @ NOAA/NCEP/EMC Eddy Merckx
Jugoslav Dujic

2007-03-22, 7:04 pm

Beliavsky wrote:
| On Mar 20, 3:33 pm, "watsteel" <avle...@gmail.com> wrote:
|| DO WHILE (.TRUE.)
| Instead of the line above, just write "DO"

On the same stylistic nitpicking wavelength, I prefer the original
verbose version. It's slightly more obvious, but, more importantly,
it's far easier to grep your sources for "while (.true.)" once
your 100,000 lines program gets stuck in an unknown location. Not
that it ever happened to me... :o)

--
Jugoslav
___________
www.xeffort.com

Please reply to the newsgroup.
You can find my real e-mail on my home page above.
FX

2007-03-22, 7:04 pm

> it's far easier to grep your sources for "while (.true.)"

Far easier than what? Than grepping for "do\s*$"?

--
FX
Dan Nagle

2007-03-22, 7:04 pm

Hello,

Jugoslav Dujic wrote:
> Beliavsky wrote:
> | On Mar 20, 3:33 pm, "watsteel" <avle...@gmail.com> wrote:
> || DO WHILE (.TRUE.)
> | Instead of the line above, just write "DO"
>
> On the same stylistic nitpicking wavelength, I prefer the original
> verbose version. It's slightly more obvious, but, more importantly,
> it's far easier to grep your sources for "while (.true.)" once
> your 100,000 lines program gets stuck in an unknown location. Not
> that it ever happened to me... :o)


If grepping is a concern, try using a label for the block.

--

Dan Nagle
Purple Sage Computing Solutions, Inc.
Richard Maine

2007-03-22, 7:04 pm

Dan Nagle <dannagle@verizon.net> wrote:

> Jugoslav Dujic wrote:
>
> If grepping is a concern, try using a label for the block.


Or even putting a comment on the line.

As for "obvious", well I guess that's in the eye of the beholder. I
suspect you are just used to the practice and so recognize it. I find it
cryptic, about along the line of simillar do-nothing constructs I've
seen such as

x = x

and

if (something) continue

or

goto 100
100 continue

(Note the lack of ellipses in the last one. Nothing between those
lines). There can be valid reasons for all these constructs. I've even
written at least the last two. But they confuse readers into wondering
whether they are actually supposed to do something or not.

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
e p chandler

2007-03-22, 7:04 pm

> > watsteel wrote:
[color=darkred]
> Changing some variable names and using INTEGER DO loops, the core of
> the program becomes
>
> msres=1e39 ! a large number
> do i1=0,40
> C = 0 + i1*.5 ! 0 to 20 step .5
> do i2=0,40
> CR = .0001 + i2*.025 ! .0001 to 1.0001 step .025
> do i3=0,40
> CN = .0001 + i3*.025
> do i4=0,40
> CH = .0001 + i4*.025
> sres=0
> do i=1,M
> Pn=C*x1(i)*(1-CR*x2(i))*(1+CN*x3(i))*(1-CH*x4(i))
> sres=(Pn-Pt(i))**2


OOPS it should of course be

sres=sres+(Pn-Pt(i))**2

> end do
> if (sres < msres) then
> msres = sres
> CF = C
> CRF = CR
> CNF = CN
> CHF = CH
> end if
> end do
> end do
> end do
> end do


Excuse the previous mini flame fest :-). Along with all of the other
worthwhile suggestions, I do think it is worth the OP's time to
investigate the numerical stability of his program. Storing the "x"
arrays allows decreasing the step size and increasing the number of
steps while keeping a reasonable run time.

As for the different Pt() values for the same test conditions, I would
combine these data points by taking the average of the corresponding
Pt() values. This reduces the number of input data points and also
decreases the run time without changing the output much.

As a check on the "goodness of fit" of the regression, I would suggest
computing a standard error (of the mean) for each set of measurements,
then computing for each "fit" (actual - fitted)/standard_error.
Since there are now only 6 data points, this is easy enough to do by
hand.

-- elliot



e p chandler

2007-03-22, 7:04 pm

On Mar 22, 12:12 pm, nos...@see.signature (Richard Maine) wrote:
> Dan Nagle <danna...@verizon.net> wrote:
>
>
>
> Or even putting a comment on the line.
>
> As for "obvious", well I guess that's in the eye of the beholder. I
> suspect you are just used to the practice and so recognize it. I find it
> cryptic, about along the line of simillar do-nothing constructs I've
> seen such as
>
> x = x
>
> and
>
> if (something) continue
>
> or
>
> goto 100
> 100 continue
>
> (Note the lack of ellipses in the last one. Nothing between those
> lines). There can be valid reasons for all these constructs. I've even
> written at least the last two. But they confuse readers into wondering
> whether they are actually supposed to do something or not.
>
> --
> Richard Maine | Good judgement comes from experience;
> email: last name at domain . net | experience comes from bad judgement.
> domain: summertriangle | -- Mark Twain


Thanks for giving me an excuse to dig out some old and nasty code that
does *exactly* what you describe. Bear in mind that I wrote it just
for fun as an exercise in using old computer hardware and software. I
would *never* (well, hardly ever) do something as crufty as this in
real production code. :-). Or as James Van Buskirk might say, it's
about knowing what you want the object code to be and fooling your
assembler/compiler into producing it.

I'm using Nevada Fortran on CP/M in these programs. This old and
strange compiler compiled to 8080 code. It did all calculations in its
own form of Binary Coded Decimal (BCD) Floating point. It's an
extended FORTRAN IV without character variables. One "feature" was the
ability to "in-line" 8080 assembly language statements. Here I want to
create a version of the ACHAR function which sets the first byte of a
string to a certain BINARY value. I can't simply manipulate an
ordinary variable because all of them are BCD floating point. I can
POKE a value into memory, once I know its address.
All variables are 48 bits (6 bytes) long.

Here is the first program:

do 20 i=65,70
t=ichr(i)
write(1,10)i,t,t
10 format(i2,1x,a1,1x,k12)
20 continue
call exit
end

function getadr(x)
x=x
continue
* shld 254
getadr=p(254)+256*p(255)-5
return
end

function ichr(x)
ichr=' '
call poke(getadr(ichr),x)
return
end

In function getadr(),

x=x

leaves a pointer to the last byte of x in the HL register. (Don't ask
how I found this out.:-))

continue

is required to align the generated in-line assembly code

shld 254

stuffs the address contained in HL into a known pair of memory
locations

getdr=....

converts the binary to a floating point value suitable for POKE.

Note that locations 254 and 255 are the end of the default DTA under
CP/M and are probably safe to use in this fashion.

The second program is a bit simpler:

do 20 i=65,70
t=ichr(i)
write(1,10)i,t,t
10 format(i2,1x,a1,1x,k12)
20 continue
call exit
end

function ichr(x)
ichr=' '
call poke(255,x)
call move(1,255,-1,ichr,0)
return
end

MOVE is a library routine that does a memory move either from an
absolute address or from a variable (plus offset) to a variable plus
offset. This is only slightly less obscure. :-).
K12 format dumps a variable as the text representation of memory bytes
(in hex).

So there you are. A "real" reason to put a "useless"

x=x

and

continue

into a program.

-- elliot [It's only a hobby.]


Gordon Sande

2007-03-22, 7:04 pm



> I'm using Nevada Fortran on CP/M in these programs. This old and
> strange compiler compiled to 8080 code. It did all calculations in its
> own form of Binary Coded Decimal (BCD) Floating point.


An example of a decimal arithmetic Fortran. No need for folks to
say "it might be possible" to have other than binary (or oct or hex).

> It's an
> extended FORTRAN IV without character variables.




Dick Hendrickson

2007-03-22, 7:04 pm

Gordon Sande wrote:
>
>
>
> An example of a decimal arithmetic Fortran. No need for folks to
> say "it might be possible" to have other than binary (or oct or hex).


Also, literally as we speak, the IEEE folk are in the process of
standardizing two (count-em, two) 32 bit representations for a packed
decimal format. (As near as I can recall, at least two different
hardware vendors had at least two different favorite representations.)

Fortunately, the much maligned Fortran KIND and SELECTED_*_KIND
mechanism was easily adapted in F2008 to accommodate both of
them. Basically, tweak something minor in I/O and add a "radix"
argument (and a host of associated error returns) to the
SELECTED_*_KIND routines.

Dick Hendrickson
>
>
>
>

Lane Straatman

2007-03-22, 7:04 pm


"e p chandler" <epc8@juno.com> wrote in message
news:1174583992.734587.271570@p15g2000hsd.googlegroups.com...
> On Mar 22, 12:12 pm, nos...@see.signature (Richard Maine) wrote:
[color=darkred]
> Thanks for giving me an excuse to dig out some old and nasty code that
> does *exactly* what you describe. Bear in mind that I wrote it just
> for fun as an exercise in using old computer hardware and software. I
> would *never* (well, hardly ever) do something as crufty as this in
> real production code. :-). Or as James Van Buskirk might say, it's
> about knowing what you want the object code to be and fooling your
> assembler/compiler into producing it.
>
> I'm using Nevada Fortran on CP/M in these programs. This old and
> strange compiler compiled to 8080 code. It did all calculations in its
> own form of Binary Coded Decimal (BCD) Floating point. It's an
> extended FORTRAN IV without character variables. One "feature" was the
> ability to "in-line" 8080 assembly language statements. Here I want to
> create a version of the ACHAR function which sets the first byte of a
> string to a certain BINARY value. I can't simply manipulate an
> ordinary variable because all of them are BCD floating point. I can
> POKE a value into memory, once I know its address.
> All variables are 48 bits (6 bytes) long.
>
> Here is the first program:
>
> do 20 i=65,70
> t=ichr(i)
> write(1,10)i,t,t
> 10 format(i2,1x,a1,1x,k12)
> 20 continue
> call exit
> end
>
> function getadr(x)
> x=x
> continue
> * shld 254
> getadr=p(254)+256*p(255)-5
> return
> end
>
> function ichr(x)
> ichr=' '
> call poke(getadr(ichr),x)
> return
> end
>
> In function getadr(),
>
> x=x
>
> leaves a pointer to the last byte of x in the HL register. (Don't ask
> how I found this out.:-))
>
> continue
>
> is required to align the generated in-line assembly code
>
> shld 254
>
> stuffs the address contained in HL into a known pair of memory
> locations
>
> getdr=....
>
> converts the binary to a floating point value suitable for POKE.
>
> Note that locations 254 and 255 are the end of the default DTA under
> CP/M and are probably safe to use in this fashion.
>
> The second program is a bit simpler:
>
> do 20 i=65,70
> t=ichr(i)
> write(1,10)i,t,t
> 10 format(i2,1x,a1,1x,k12)
> 20 continue
> call exit
> end
>
> function ichr(x)
> ichr=' '
> call poke(255,x)
> call move(1,255,-1,ichr,0)
> return
> end
>
> MOVE is a library routine that does a memory move either from an
> absolute address or from a variable (plus offset) to a variable plus
> offset. This is only slightly less obscure. :-).
> K12 format dumps a variable as the text representation of memory bytes
> (in hex).
>
> So there you are. A "real" reason to put a "useless"
>
> x=x
>
> and
>
> continue
>
> into a program.
>

I'm trying to see what you guys are getting at. When I try to compile
either of the above I get:
error 274 - Unknown edit descriptor 'K', or missing comma
for the line labelled 10. It sounds like they're supposed to compile. What
gives?
--
LS


e p chandler

2007-03-22, 7:04 pm

On Mar 22, 2:17 pm, "Lane Straatman" <inva...@invalid.net> wrote:
> "e p chandler" <e...@juno.com> wrote in messagenews:1174583992.734587.271570@p15g2000hsd.googlegroups.com...
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> I'm trying to see what you guys are getting at. When I try to compile
> either of the above I get:
> error 274 - Unknown edit descriptor 'K', or missing comma
> for the line labelled 10. It sounds like they're supposed to compile. What
> gives?
> --
> LS- Hide quoted text -
>
> - Show quoted text -


the K edit descriptor is one of the non-standard features of Nevada
Fortran.

I posted the programs to illustrate seemingly "do-nothing" code. If
you want to actually compile and run them you need either a CP/M
machine (with an 8080 or Z80 processor) or CP/M emulation software
(Simeon Cran's MyZ80 is best here) plus Nevada Fortran. :-). [Perhaps
my sense of humor was not obvious enough. :-(.]

-- elliot [Running old computer software is a great hobby. It keeps me
from filling my basement with expensive model trains!]





Richard Maine

2007-03-22, 7:04 pm

Lane Straatman <invalid@invalid.net> wrote:

> "e p chandler" <epc8@juno.com> wrote in message
> news:1174583992.734587.271570@p15g2000hsd.googlegroups.com...


> I'm trying to see what you guys are getting at. When I try to compile
> either of the above I get:
> error 274 - Unknown edit descriptor 'K', or missing comma
> for the line labelled 10. It sounds like they're supposed to compile. What
> gives?


No, this isn't "supposed to compile." EP explained that this is *HIGHLY*
compiler specific. The odds of you happening to have the compiler that
it was written for (along with an appropriate system) are pretty much
zero. He posted it as an amusing example - not as something anyone else
would take and use as is. (And I did find it an interesting example.)

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
glen herrmannsfeldt

2007-03-22, 7:04 pm

e p chandler wrote:
(snip)

> I posted the programs to illustrate seemingly "do-nothing" code. If
> you want to actually compile and run them you need either a CP/M
> machine (with an 8080 or Z80 processor) or CP/M emulation software
> (Simeon Cran's MyZ80 is best here) plus Nevada Fortran. :-). [Perhaps
> my sense of humor was not obvious enough. :-(.]


> -- elliot [Running old computer software is a great hobby. It keeps me
> from filling my basement with expensive model trains!]


You could fill it with expensive old computers.

Real Altair 8800's are pretty expensive, other S100 bus machines
aren't quite as expensive. There are now new IMSAI machines,

http://www.imsai.net/products/imsai_series_two.htm

(Note: I don't own one, know anyone who does, know anyone
in the company producing them, etc.)

-- glen

Lane Straatman

2007-03-22, 10:03 pm


"e p chandler" <epc8@juno.com> wrote in message
news:1174589022.033780.162160@n76g2000hsh.googlegroups.com...
> On Mar 22, 2:17 pm, "Lane Straatman" <inva...@invalid.net> wrote:
>
> the K edit descriptor is one of the non-standard features of Nevada
> Fortran.
>
> I posted the programs to illustrate seemingly "do-nothing" code. If
> you want to actually compile and run them you need either a CP/M
> machine (with an 8080 or Z80 processor) or CP/M emulation software
> (Simeon Cran's MyZ80 is best here) plus Nevada Fortran. :-). [Perhaps
> my sense of humor was not obvious enough. :-(.]

Having a pet project on a cpm machine sounds like fun to me. I thought what
Richard was talking about was stuff that compiles but doesn't do a whole
lot. Assigning x to itself. If true. Goto the next statement. What is a
K descriptor that my compiler knows enough about it to have it in an error
message but not have it?

> -- elliot [Running old computer software is a great hobby. It keeps me
> from filling my basement with expensive model trains!]

Does it have a floppy disk drive that is actually floppy?
--
LS


glen herrmannsfeldt

2007-03-22, 10:03 pm

Lane Straatman wrote:

(snip)

> Having a pet project on a cpm machine sounds like fun to me. I thought what
> Richard was talking about was stuff that compiles but doesn't do a whole
> lot. Assigning x to itself. If true. Goto the next statement. What is a
> K descriptor that my compiler knows enough about it to have it in an error
> message but not have it?


It might be that if you put any letter in the compiler will recognize
it enough to issue an error message. It might be that some don't
check them until execution, but most check at compile time for
valid format descriptors.

[color=darkred]
> Does it have a floppy disk drive that is actually floppy?


There are emulators available for many old machines: Apple II,
Z80/CPM, many of the old game consoles, VAX/VMS, IBM S/370,
7090/IBSYS. I think there are some working on the 704, though
I am not sure about the status of the Fortran I compiler.

I have an 8 inch floppy drive, but it isn't connected to any
machine right now.

-- glen

e p chandler

2007-03-23, 4:05 am

On Mar 22, 11:13 pm, glen herrmannsfeldt <g...@ugcs.caltech.edu>
wrote:
> Lane Straatman wrote:
>
> (snip)
>
>
> It might be that if you put any letter in the compiler will recognize
> it enough to issue an error message. It might be that some don't
> check them until execution, but most check at compile time for
> valid format descriptors.
>
>
> There are emulators available for many old machines: Apple II,
> Z80/CPM, many of the old game consoles, VAX/VMS, IBM S/370,
> 7090/IBSYS. I think there are some working on the 704, though
> I am not sure about the status of the Fortran I compiler.
>
> I have an 8 inch floppy drive, but it isn't connected to any
> machine right now.
>
> -- glen


[taking this thread OT] I usually run (pre MS-DOS) software on an
emulator rather than on real hardware. There are advantages when
playing with "antique" programs.

1. The emulator is often many times faster than the original hardware.
2. Very large (or almost unlimited) disk space.
3. File import and export from the host.
4. Ability to use the host's editing, file decompression/un-archiving
facilities, etc.
5. If the emulator runs in a window instead of full screen, I've got
mark, cut, paste, the clipboard, etc.
6. No more running NULL modem cables, firing up X-Modem for file
transfers, etc.
7. Changing "pseudo" floppy disks instead of real disks. (I would have
worn out the drive doors on my Apple II long ago...)

It's sort of fun to do things with old programs that were not possible
on the original hardware because of limited time or disk.

One emulator that old Fortraners might enjoy playing with is one for
the IBM 1130.
see http://ibm1130.org/

-- elliot




Richard Maine

2007-03-23, 4:05 am

e p chandler <epc8@juno.com> wrote:

> [taking this thread OT] I usually run (pre MS-DOS) software on an
> emulator rather than on real hardware. There are advantages when
> playing with "antique" programs.


I've got a real Apple 2e. Still works - or anyway it did the last time I
tried, which was within the last year. But I bought a piece of emulator
software anyway, as I'd rather run the emulator than my real machine.
Besides the reasons you mentioned, advantages of the emulator are:

1. It's handy. Right here on the machine I'm using anyway (24" iMac)
instead of having to drag the 2e out of where I have it stashed.

2. It's more reliable - particularly the floppies. No floppy read
errors.

3. I'm not putting wear on my old hardware - mostly the floppy drives
and the floppy media, both of which are definitely subject to physical
wear.

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
Gary Scott

2007-03-23, 8:04 am

e p chandler wrote:
> On Mar 22, 11:13 pm, glen herrmannsfeldt <g...@ugcs.caltech.edu>
> wrote:
>
>
>
> [taking this thread OT] I usually run (pre MS-DOS) software on an
> emulator rather than on real hardware. There are advantages when
> playing with "antique" programs.
>
> 1. The emulator is often many times faster than the original hardware.
> 2. Very large (or almost unlimited) disk space.
> 3. File import and export from the host.
> 4. Ability to use the host's editing, file decompression/un-archiving
> facilities, etc.
> 5. If the emulator runs in a window instead of full screen, I've got
> mark, cut, paste, the clipboard, etc.
> 6. No more running NULL modem cables, firing up X-Modem for file
> transfers, etc.
> 7. Changing "pseudo" floppy disks instead of real disks. (I would have
> worn out the drive doors on my Apple II long ago...)
>
> It's sort of fun to do things with old programs that were not possible
> on the original hardware because of limited time or disk.
>
> One emulator that old Fortraners might enjoy playing with is one for
> the IBM 1130.
> see http://ibm1130.org/


I want to emulate a 32 way parallel sysplex 390 on my 2Ghz PC.

>
> -- elliot
>
>
>
>



--

Gary Scott
mailto:garylscott@sbcglobal dot net

Fortran Library: http://www.fortranlib.com

Support the Original G95 Project: http://www.g95.org
-OR-
Support the GNU GFortran Project: http://gcc.gnu.org/fortran/index.html

If you want to do the impossible, don't hire an expert because he knows
it can't be done.

-- Henry Ford
glen herrmannsfeldt

2007-03-23, 8:04 am

Gary Scott wrote:

(snip)

> I want to emulate a 32 way parallel sysplex 390 on my 2Ghz PC.


I don't believe that Hercules implements sysplex, but it
does implement multi-CPU machines up through z/Architecture.
(z/Linux being the legal OS to run on it for most people.)

The suggestion is to have as many real processors as virtual
processors, but that isn't required.

-- glen

Kevin G. Rhoads

2007-03-28, 7:09 pm

>There can be valid reasons for all these constructs. I've even
>written at least the last two. But they confuse readers into wondering
>whether they are actually supposed to do something or not.


Isn't that one of the things comments are for?

I sometimes find myself writing things like
IF (condition) THEN
* we aren't doing anything here, yet
ELSE
...
ENDIF
because I expect to fill in the do nothing blocks later. So I put in a comment
to show that, however unreasonable it might seem, it was intentional. I will
admit that sometimes the comments can be cryptic, because they reflect my
state of mind at the time of writing. An example would be your snippet,
modified to include comment

goto 100
* Can we flush the instruction pre-fetch queue? Or will the optimizer win?
100 continue

Such are not intentionally obscure, just accidentally. But at least they indicate
intention and not accident in the coding.
Richard Maine

2007-03-28, 7:09 pm

Kevin G. Rhoads <kgrhoads@alum.mit.edu> wrote:

>
> Isn't that one of the things comments are for?


Well. In some cases. But look at the context of the thread that lead to
this. The two suggestions as to why the coding practice in question was
nice were:

1. It was "obvious" what it was doing

and

2. It provided something handy to grep for.

I'd say that

1. If the code needs a comment to explain it, then it must not be all
that obvious.

2. If the purpose is to put something handily grepable, and you need a
comment to explain that, then one might as well put the grepable
material in the comment in the first place and dispense with the
do-nothing code.

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com