RE : crazy run-time fluctuations (mostly super-slow) -- a bit more data
Subject: RE : crazy run-time fluctuations (mostly super-slow) -- a bit more data
From: Oliver Kullmann
Date: Sun, 23 Oct 2011 13:52:28 +0100
Hi Bill,
thanks a lot! That became clear now. (As explained in my other e-mail,
I assumed Lisp would be based on copy-semantics. Again, I just top-post
here, since the examples are clear now.)
1. What seems the nicest way to store a state of the
random generator and to re-install that state (several times) is
perhaps the following:
:lisp (defvar s (make-random-state))
for storing it, and
:lisp (setq *random-state* (make-random-state s))
for setting it (using the copy-mode of make-random-state).
2. Now back to the original problem: Tested in that way, ifactors
behaves stable over several consecutive invocation (using the same
random "seed"). So no "crazy fluctuation" here.
So, actually unfortunately, that wasn't a nice-and-easy examples
of the problems we encounter with Maximal slowing down (drastically).
But perhaps the fluctuation for ifactors are too much (between 6 seconds
and 10 minutes!), and one might be able to improve the implementation.
3. Regarding the thoughts on the general design of Maxima: From my point
of view, I don't have principle problems with Maxima (except that namespaces
would be really nice, and having *additionally* statically scoped variables
would likely remove quite some problems). I think what is needed is a section
on the general principles of Maxima and Lisp in the documention, which
emphasises general issues like copy- versus reference-semantics.
I think it's mainly a documentation issue. One should spend some time
on programming issues and their documentation, while most Maxima documentation
efforts seem to go into the mathematical side. This also has the side-effect
of making examples sometimes too complicated. I don't think the Maxima examples
in the documentation are as bad as the R-examples (I believe I never ever
could use any example in the R-documentation --- to just see how simplest
programming-parameters are involved, always complicated examples from
statistics are used), but there is also the tendency to use differentiation,
integration, solution of equations and so on at places where the topic
is just general programming techniques and data structures.
Thanks a lot for all the help!
Oliver
On Sun, Oct 23, 2011 at 12:22:33AM -0500, Bill Wood wrote:
> On Sun, 2011-10-23 at 03:13 +0100, Oliver Kullmann wrote:
> . . .
> > However, with each invocation of :lisp seems to start a fresh
> environment,
> > unrelated to the invocation before, so that between two Maxima-calls
> apparently
> > no relation can be established between the calls of random??:
>
> > (%i447) :lisp (setq ss *random-state*)
> > #<random-state 000000000143b000>
> > (%i447) :lisp (setq ss2 *random-state*)
> > #<random-state 000000000143b000>
> > (%i447) :lisp (equal ss ss2)
> > T
> > (%i447) :lisp (random 1000 ss)
> > 808
> > (%i447) :lisp (random 1000 ss2)
> > 57
> > (%i447) :lisp (equal ss ss2)
> > T
>
> Lisp doesn't copy structured objects unless asked. The two SETQ forms
> created two references to the same structured object, the one bound to
> *random-state*. When RANDOM is called on SS the side-effect change to
> the state object will be visible to SS2. You can use the lisp predicate
> EQ to test if two variables reference the same object. Here is the
> example on my system:
>
> (%i1) :lisp (defvar ss *random-state*)
>
> SS
> (%i1) :lisp (defvar ss2 *random-state*)
>
> SS2
> (%i1) :lisp (eq ss ss2)
>
> T
> (%i1) :lisp (random 1000 ss)
>
> 308
> (%i1) :lisp (random 1000 ss2)
>
> 465
> (%i1) :lisp (eq ss ss2)
>
> T
>
> Again the calls to RANDOM using SS and SS2 yield different values, but
> the applications of EQ show the two variables reference the same object
> both before and after the two calls. Here is another example of
> sharing, this time with a simple list:
>
> (%i1) :lisp (defvar x (list 1 2))
>
> X
> (%i1) :lisp (defvar y x)
>
> Y
> (%i1) :lisp (list x y)
>
> ((1 2) (1 2))
> (%i1) :lisp (setf (first x) 99)
>
> 99
> (%i1) :lisp (list x y)
>
> ((99 2) (99 2))
>
> The form "(setf (first x) 99)" reaches into the list x and sets its
> first element to 99. As you can see, after that statement both x and y
> see the list with its first element equal to 99.
>
> You are correct, the way to get two copies of *random-state* is to use
> MAKE-RANDOM-STATE:
>
> (%i1) :lisp (defvar s (make-random-state))
>
> S
> (%i1) :lisp (defvar s2 (make-random-state))
>
> S2
> (%i1) :lisp (eq s s2)
>
> NIL
> (%i1) :lisp (equalp s s2)
>
> T
> (%i1) :lisp (random 1000 s2)
>
> 669
> (%i1) :lisp (random 1000 s)
>
> 669
> (%i1) :lisp (equalp s s2)
>
> T
>
> Now EQ returns NIL, indicating that S and S2 are bound to two different
> objects, but the predicate EQUALP, which is used to test whether two
> values are structurally equivalent, shows the two states are equivalent.
> Now the two calls to RANDOM return the same values, as desired, and
> again EQUALP shows the two states are equivalent after each has been
> side-effected once.
>
> Hope this helps.
>
> --
> Bill Wood