[Thread Prev][Thread Next][Index]

Re: [ferret_users] strange summarizing



Hi Peter,

| when i am trying to have the results of mann-kendall test, i found
| something strange: i want to sum a calculated variable it just dont
| work. A bug or i am messing up something?

I think so.  In Ferret, a variable is defined but not evaluated
until its value is demanded.  To illustrate your problem, let's
consider a very simple example:

  yes? let a = 1        !!(1)
  yes? let b = a + 2    !!(2)
  yes? let a = 10       !!(3)redefinition
  yes? list/nohead a, b !!(4)
  I / *:     10.00  12.00
  yes? let a = 100      !!(5)redefinition
  yes? list/nohead a, b !!(6)
  I / *:     100.0  102.0

At line (2), b is defined to be "a + 2" not "3".
Then, at line (3), the definition of a is changed.
At line (4), the values of a and b are demanded,
so they are computed.  Since "b = a + 2" and "a = 10"
b is "evaluated" as 12.

This doesn't change the definition of b.  So, after
the definition of a is again changed at line (5),
b evaluates to yet a different value.

| let ka=1
| let szum`ka`=0
| repeat/range=`ka+1`:40:1/name=ja (let signpreX=if (pret=`ja`]-pre[t=`ka`])
| ge 1 then 1 else signproba; let signproba=if (pret=`ja`]-pre[t=`ka`]) le -1
| then (-1) else 0; let szum`ja`=signpreX+szum`ja-1`; list/nohead
| szum`ja`,signpreX)

So, let's consider the first two steps of this loop:

ja=2

     SZUM1 = 0
     SZUM2 = SIGNPREX + SZUM1

ja=3

     SZUM1 = 0
     SZUM2 = SIGNPREX + SZUM1
     SZUM3 = SIGNPREX + SZUM2

As you see, 

  SZUM3 = SIGNPREX + SZUM2
        = SIGNPREX + SIGNPREX + SZUM1
        = 2 * SIGNPREX + SZUM1

which isn't what you want.

To fix the problem, you have to force the evaluation of signpreX
at each iteration of the loop.

   let szum`ja` = `signpreX` + szum`ja-1`

The operator `` means "evaluate it right now".

Having said all this, I don't think you need such a complex
program.  In your loop, you are computing a running sum of
signpreX.  So, I think you'd be better off with

 let ka=1
 let signpreX = if (pre - pre[t=`ka`]) ge 1  then 1 else signproba
 let signproba= if (pre - pre[t=`ka`]) le -1 then (-1) else 0
 let szum = signpreX[t=1:40@rsum]
 list szum

where "@rsum" operator computes the running sum.

Hope this helps,
Ryo


[Thread Prev][Thread Next][Index]

Contact Us
Dept of Commerce / NOAA / OAR / PMEL / TMAP

Privacy Policy | Disclaimer | Accessibility Statement