Thanks everyone for the info and examination. I'll go and digest.
Some notes:
@nophead. yes all this is so I can force the children(0) to be the same
when its evaluated twice. So @kintel indicates it probbaly a bug. If that
bug is fixed my problem would go away. which is great :)
However in the meantime it has raised this usse about rands() concept... and
until its fixed(maybe not) I need to move ahead.
@nophead the $seed varible seems like the right fix for that problem.
looking into it now. Thanks for the info.
Maybe $seed could be added to the cheatsheet ?
rands() seems to me like its ok for OpenSCAD because its really designed
to produce a list of numbers.
E.g. rands(0,100,50); gives a list of 50 random numbers back.
Its just that usually we want only one, and so we go:
rands(0,100,1)[0]
and just ask for one and pick it off the list.
So rands() itself seems quite openscaddy(?)... but picking a specific value
out of rands in a deterministic way becomes tricky because of the way
openSCAD is really a scene description language with a different evaluation
criteria than a general purpose language (as doug points out).
--
View this message in context: http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16311.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
Neon22 wrote
$seed is not special it is just an example of $special_variables
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features#Special_variables
which have special scope.
He could have used $hiccups.
Admin - PM me if you need anything, or if I've done something stupid...
Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. Obviously inclusion of works of previous authors is not included in the above.
View this message in context: http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16312.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
@MichaelAtOz - yeah - I worked that out eventually :)
So I tried @nophead's approach and while it works, it means all random
numbers are the same number which unfortunately also means some boring
results :)
Like this if symmetry (and therefore only 1 value used everywhere):
http://i68.tinypic.com/n5o29w.jpg
http://forum.openscad.org/file/n16313/n5o29w.jpg
or like this when non-symmetrical - and with a random sequence of values:
http://forum.openscad.org/file/n16313/icofo0.jpg
I guess I'll hope for a bugfix and an incremental release :)
Cheers...
--
View this message in context: http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16313.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
Did you try the version where I did $seed+n for the nth call? Another
possibility is rands(a,b,n,$seed)[n - 1] for the nth call.
I think it is possible to code Doug's hash system in user space with the
current OpenScad. I have used hashes for pseudo random but repeatable
results before.
On 7 March 2016 at 07:10, Neon22 mschafer@wireframe.biz wrote:
@MichaelAtOz - yeah - I worked that out eventually :)
So I tried @nophead's approach and while it works, it means all random
numbers are the same number which unfortunately also means some boring
results :)
Like this if symmetry (and therefore only 1 value used everywhere):
http://i68.tinypic.com/n5o29w.jpg
http://forum.openscad.org/file/n16313/n5o29w.jpg
or like this when non-symmetrical - and with a random sequence of values:
http://forum.openscad.org/file/n16313/icofo0.jpg
I guess I'll hope for a bugfix and an incremental release :)
Cheers...
--
View this message in context:
http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16313.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
As I mentioned before, if you use the same seed each time you call rands
you get the same sequence. That is the seed is for.
In both codes, the original Neon 22's code and in the nop head's code, the
rands in randcyl is called with the same seed every time and it will
return the very same result. Try this:
echo(rands(0,1,1,seed_value=10)[0]);
echo(rands(0,1,1,seed_value=10)[0]);
echo(rands(0,1,1,seed_value=10)[0]);
echo(rands(0,1,1,seed_value=10)[0]);
and then this:
echo(rands(0,1,4,seed_value=10));
2016-03-07 7:09 GMT-03:00 nop head nop.head@gmail.com:
Did you try the version where I did $seed+n for the nth call? Another
possibility is rands(a,b,n,$seed)[n - 1] for the nth call.
I think it is possible to code Doug's hash system in user space with the
current OpenScad. I have used hashes for pseudo random but repeatable
results before.
On 7 March 2016 at 07:10, Neon22 mschafer@wireframe.biz wrote:
@MichaelAtOz - yeah - I worked that out eventually :)
So I tried @nophead's approach and while it works, it means all random
numbers are the same number which unfortunately also means some boring
results :)
Like this if symmetry (and therefore only 1 value used everywhere):
http://i68.tinypic.com/n5o29w.jpg
http://forum.openscad.org/file/n16313/n5o29w.jpg
or like this when non-symmetrical - and with a random sequence of values:
http://forum.openscad.org/file/n16313/icofo0.jpg
I guess I'll hope for a bugfix and an incremental release :)
Cheers...
--
View this message in context:
http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16313.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Doug,
I don't believe your proposal would solve the Neon22's question. I
understood that he would like to have distinct results for every call to
randcyl(). And that module m_mirror() calls randcyl() just once.
This latter issue is supposed to be a bug by kintel. And the former is not
solved by your proposal of random().
I would have a similar proposal but with other behaviour. The signature you
suggest would identify a whole series of random numbers starting from the
seed resulting from hashing $seed together the signature. However, each time
random() is called with the same signature it will return the next random
number in the series identified by the signature.
As an example, suppose you have two places in the code where random numbers
are needed and you create two functions to generate them:
sign1 = ["randcyl"];
sign2 = ["randcube"];
function random1() = random(sign1) * 77;
function random2() = random(sign2) * 55;
Each of those function would generate a new random number at each call. The
whole series generated by the first function random1() would change if the
signature sign1 is changed: the signature is part of the seed of that
series. If you want the same series for all the runs it is enough to add as
first line:
$seed = 10: // or any other number
If you want that just the random2() function generates new series at each
run, change sign2 to something like:
sign2 = random(["sign2"]);
I don't know if this proposal is either an imperative or a declarative
solution but it would solve a lot issues in a flexible way.
--
View this message in context: http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16316.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
On 7 March 2016 at 14:31, Ronaldo Persiano rcmpersiano@gmail.com wrote:
As I mentioned before, if you use the same seed each time you call rands
you get the same sequence. That is the seed is for.
In both codes, the original Neon 22's code and in the nop head's code, the
rands in randcyl is called with the same seed every time and it will
return the very same result. Try this:
echo(rands(0,1,1,seed_value=10)[0]);
echo(rands(0,1,1,seed_value=10)[0]);
echo(rands(0,1,1,seed_value=10)[0]);
echo(rands(0,1,1,seed_value=10)[0]);
and then this:
echo(rands(0,1,4,seed_value=10));
In my example I generated a new random $seed in m_mirror that is then
passed to its children to use as a seed so each child generates the same
random numbers. If the child wants say three then can used rands(a,b,1,
$seed)[0], rands(c,d,2,$seed)[1] and rands(e,f,3,$seed)[2]. That seems to
work fine in this example
$fn = 32;
module m_mirror() {
$seed = rands(0,1000000,1)[0];
children(0);
mirror([1,0,0])
children(0);
}
module cut_in_half(size) {
intersection() {
translate([0, -size/2.0, -size/2.0])
cube(size=size, center=false);
children(0);
}
}
module randcyl() {
// use of rands in here shows this object being called twice
echo("randcyl called");
rotate([rands(0,77,1, $seed)[0],45,0])
cylinder(h=rands(4,8,2, $seed)[1], d = rands(.1,5,3,
$seed)[2], center=true);
}
m_mirror() cut_in_half(100) render() randcyl();
translate([0, 5, 0])
m_mirror() cut_in_half(100) render() randcyl();
unless I misunderstand the problem. It isn't very efficient as it is
generating the same sub-sequences over and over again, but I doubt it is a
significant overhead compared to geometry evaluation.
There is still an issue between F5 and F6. I think OpenScad should generate
a new seed each time F5 is run but should save it so F6 always generates
the same sequence as the last F5.
2016-03-07 7:09 GMT-03:00 nop head nop.head@gmail.com:
Did you try the version where I did $seed+n for the nth call? Another
possibility is rands(a,b,n,$seed)[n - 1] for the nth call.
I think it is possible to code Doug's hash system in user space with the
current OpenScad. I have used hashes for pseudo random but repeatable
results before.
On 7 March 2016 at 07:10, Neon22 mschafer@wireframe.biz wrote:
@MichaelAtOz - yeah - I worked that out eventually :)
So I tried @nophead's approach and while it works, it means all random
numbers are the same number which unfortunately also means some boring
results :)
Like this if symmetry (and therefore only 1 value used everywhere):
http://i68.tinypic.com/n5o29w.jpg
http://forum.openscad.org/file/n16313/n5o29w.jpg
or like this when non-symmetrical - and with a random sequence of values:
http://forum.openscad.org/file/n16313/icofo0.jpg
I guess I'll hope for a bugfix and an incremental release :)
Cheers...
--
View this message in context:
http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16313.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
@Ronaldo, my proposed random() function is a declarative interface which
provides the following guarantees: it doesn't matter if your function or
module is called more times than you expect, and it doesn't matter if they
are called in a different order than you expect, the results will be the
same. Those guarantees are necessary if we want to keep OpenSCAD as a pure
declarative language. The "bug" where modules are called a different number
of times than expected will not affect the behaviour of random().
But this means you have to write your code differently. The existing
rands() function relies on hidden state, so that successive calls to
rands() with the same arguments will return different results. That kind of
behaviour can only exist in an imperative language, and random() doesn't
work that way. With random(), you have to explicitly construct a signature
argument that is different for each unique random number you want to
generate.
In the example code that I gave, randcyl() will always return the same
results, unless the dynamically scoped $seed variable is different for
different calls.
Let's say you want to call randcyl() 6 times, with a different random
number generated for each call. Then you could do this:
for (i=[1:6])
translate([i*10,0,0]) randcyl($seed=random(["row of randcyl", i]));
Each seed value passed to randcyl is different because they are generated
from different signature lists passed to random().
Once you wrap your head around the coding style, this interface is actually
more powerful, since it gives you precise control over when random number
sequences are different, and when they are the same.
@Ronaldo wrote:
I would have a similar proposal but with other behaviour. The signature you
suggest would identify a whole series of random numbers starting from the
seed resulting from hashing $seed together the signature. However, each
time random() is called with the same signature it will return the next
random number in the series identified by the signature.
This is still an imperative interface, because it relies on a hidden
mutable global variable that keeps track of the state of each random number
sequence.
The imperative interface is more convenient, especially for simple
examples, because you don't need to construct unique signatures for each
distinct random number.
But the imperative interface also creates more problems, in the context of
a declarative language.
An imperative random number interface can lead to fragile code that breaks
when you try to change it. For example, suppose there is a model that uses
random() to generate an entire family of randomly generated shapes, based
on the $seed. You've experimentally explored this family of shapes by
hitting F5 repeatedly until you got a shape you like. Then you select this
specific shape by fixing the value of $seed. At this point, if the code
relies on an imperative random number generator, then the code is fragile
and hard to change, because moving code around, adding or removing code may
change the random numbers generated in other code that you didn't want to
change, and then you lose the specific shape that you had chosen. With a
declarative random number generator, the code isn't fragile: each random
number is chosen deterministically based on a signature and seed.
The other problem is that an imperative random number generator prevents
OpenSCAD from using standard optimization techniques that work for
declarative languages. Here are two techniques that Marius and I would like
to try out. One is lazy evaluation, where we delay evaluating expressions
and module calls until the result is needed: this is a win if the result is
never needed. This makes the evaluation order hard to predict. Another is
parallel evaluation, where expressions and module calls are evaluated in an
unpredictable order, using multiple cores.
nop head,
It seems I disregarded the $seed assignment in the beginning of module
m_mirror() of your code. Sorry.
But that code solves just one of Neon22's issue: randcyl() will generate the
same two solids by m_mirror(). However, I don't see anyway to reproduce the
same result twice which is the random function seed is meant to. If you
comment the $seed assignment in m_mirror(), all m_mirror() calls will
produce the very same solid.
--
View this message in context: http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16320.html
Sent from the OpenSCAD mailing list archive at Nabble.com.