From: Antonio De Juárez on
Thanks for your responses. I see now that I was too succint in posing
the problem. The specific situation is a follows. I have written a
module for emulating the behavior of an object that collects the
values of a random variable, and then is able to produce simple
statistics. The code is the following,

statObserver :=
Module[{s1 = \[Infinity], s2 = \[Infinity], nTrials = 0, out},
SetAttributes[out, HoldFirst];
out[AddObs, d_] := (If[nTrials == 0,
s1 = d;
s2 = d^2,
s1 += d;
s2 += d^2;
]; nTrials++;);

out[stat] := Module[{m, dev, rms},
m = s1/nTrials;
dev = (s2 - s1^2/nTrials)/(nTrials - 1) // Sqrt;
rms = m^2 + dev^2 // Sqrt;
{nTrials, m, dev, rms}];

out[reset] := (nTrials = 0);
out[delete] := Remove[s1, s2, nTrials, out];
out
];

Once loaded, this line defines the object

Ob= StatObserver[];

If a is a new trial of the random variable, then Ob[AddObs,a] updates
the module variables s1 and s2, and Ob[stat] returns the number of
trials, mean, deviation, and RMS.

This is an execution example:

Ob = statObserver;
For[k = 1, k <= 1000, k++, Ob[AddObs, RandomReal[]]];
Ob[stat] // Print;
Ob[delete]

The printed value is the desired statistics

{1000 , 0.503057 , 0.286419 , 0.57888}

My question is whether I could link symbols a and Ob, so that
Ob[AddObs,a] is automatically executed every time variable a changes.
I know this can be done using Dynamic, but Dynamic must be displayed
in some Notebook cell, in order to work, and I do not think this is a
neat solution. Any idea?

Thanks, I really appreciate your answers,

Antonio






From: David Bailey on
On 13/06/10 23:52, Antonio De Ju=E1rez wrote:
> Thanks for your responses. I see now that I was too succint in posing
> the problem. The specific situation is a follows. I have written a
> module for emulating the behavior of an object that collects the
> values of a random variable, and then is able to produce simple
> statistics. The code is the following,
>
> statObserver :=
> Module[{s1 = \[Infinity], s2 = \[Infinity], nTrials = 0, out},
> SetAttributes[out, HoldFirst];
> out[AddObs, d_] := (If[nTrials == 0,
> s1 = d;
> s2 = d^2,
> s1 += d;
> s2 += d^2;
> ]; nTrials++;);
>
> out[stat] := Module[{m, dev, rms},
> m = s1/nTrials;
> dev = (s2 - s1^2/nTrials)/(nTrials - 1) // Sqrt;
> rms = m^2 + dev^2 // Sqrt;
> {nTrials, m, dev, rms}];
>
> out[reset] := (nTrials = 0);
> out[delete] := Remove[s1, s2, nTrials, out];
> out
> ];
>
> Once loaded, this line defines the object
>
> Ob= StatObserver[];
>
> If a is a new trial of the random variable, then Ob[AddObs,a] updates
> the module variables s1 and s2, and Ob[stat] returns the number of
> trials, mean, deviation, and RMS.
>
> This is an execution example:
>
> Ob = statObserver;
> For[k = 1, k<= 1000, k++, Ob[AddObs, RandomReal[]]];
> Ob[stat] // Print;
> Ob[delete]
>
> The printed value is the desired statistics
>
> {1000 , 0.503057 , 0.286419 , 0.57888}
>
> My question is whether I could link symbols a and Ob, so that
> Ob[AddObs,a] is automatically executed every time variable a changes.
> I know this can be done using Dynamic, but Dynamic must be displayed
> in some Notebook cell, in order to work, and I do not think this is a
> neat solution. Any idea?
>
> Thanks, I really appreciate your answers,
>
> Antonio
>

Your coding style seems rather obscure, and is possibly an attempt to
adapt your knowledge of some other language - maybe something object
oriented. It also contains errors - fo example, you have not defined the
function StatObserver, yet you use it in the line

Ob= StatObserver[];

My advice would be to learn Mathematica from the tutorial - or even go
on a short course. Copy examples of the tutorial code into your own
notebooks, and explore what they do.

It is far better to spend a bit of time really learning Mathematica,
before you start designing serious code and making decisions that will
be hard to change later.

Dynamic is really useful for building GUI applications (fancy
interfaces, if you like), forget it for now.

Although it is possible to define variables (as opposed to functions)
using SetDelayed (:=), this is usually not a good idea because it makes
code hard to read.

David Bailey

http://www.dbaileyconsultancy.co.uk