Kara-Moon Forum
March 28, 2024, 11:25:17 AM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: You can go back to the main site here: Kara-Moon site
 
   Home   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: Random seed  (Read 3926 times)
sciurius
Sr. Member
****
Posts: 443



« on: August 02, 2019, 06:57:15 AM »

To aid in developing regression tests it is necessary to control de random number generator that MMA uses for e.g. RTime and RVolume.

The attached patch to the mma main program adds support for environment variable MMA_RSEED to initialize the random generator.


* mma-rseed.patch.txt (0.64 KB - downloaded 200 times.)
Logged
bvdp
Kara-Moon Master
****
Posts: 1436


WWW
« Reply #1 on: August 02, 2019, 03:57:20 PM »

MMA already has an RNDSEED command.
Logged

My online life: http://www.mellowood.ca
sciurius
Sr. Member
****
Posts: 443



« Reply #2 on: August 02, 2019, 06:22:14 PM »

Yes, but this command must be stored in the .mma files.
Hmm. I could use this in a dedicated mmarc specific for testing... Good!
Logged
sciurius
Sr. Member
****
Posts: 443



« Reply #3 on: August 02, 2019, 08:13:55 PM »

However, RndSeed uses internally stof, which returns a float. For larger values random.seed() then uses the hash of the value instead. And the hash value is not guranteed to be the same across runs, architectures,and so on...
Logged
bvdp
Kara-Moon Master
****
Posts: 1436


WWW
« Reply #4 on: August 02, 2019, 11:43:19 PM »

2 suggestions on this for you to think about:

1. for rndseed we could add an optional argument: type. So, it could be INT or FLOAT and default to the existing FLOAT. We end up with a line like:

     rndseed 123 type=int

and not break any existing code.

2. instead of a dedicated env variable could we have a MMA_ENVSTARTCMD (or something less verbose) which mma would interpret as a normal line. Not sure what to do with multiple line lines? Most likely buffer the line and call it around line 145 in main.py. It would (might) need a bit of clobbering to make the parser happy ... don't have time to try just now Smiley 
Logged

My online life: http://www.mellowood.ca
sciurius
Sr. Member
****
Posts: 443



« Reply #5 on: August 03, 2019, 08:37:42 AM »

Some points:

  • In the current implementation results will break when switching from python2 to python3 for non-int values.
  • The documentation unfortunately shows using a non-int as first example.
  • In the libraries and examples, there is no occurrence of using RndSeed.

Personally, I can see ony two uses of RndSeed. One is the example from the docs, to obtain identical repeat sections. For this it doesn't matter at all what is under the hood, since this will work for ints, floats, python2 and python3. No breaking of existing code.

The other use is to get reproducible results for regression tests (what I'm currently working on). For this it still doesn't matter what is under the hood, as long as it is reproducible. It turns out that due to the changed python2 to python3 behaviour this is only possible when using int values.

So I would suggest to use int conversion for the random seed (instead of stof) and adjust the first example in the documentation. Adding a type argument is overkill for this issue.

There is, actually, a third use for RndSeed: When I have a nice midi and I want to do it again (with a different chord or something). This is currently not possible since that would require keeping track of the seed value used to generate this midi.

Having an environment variable to set initial lines? Cute, but I think .mmarc can already handle that. For the regression tests I use a dedicated .mmarc but I could of course Include ~/.mmarc or something similar if needed.
Logged
bvdp
Kara-Moon Master
****
Posts: 1436


WWW
« Reply #6 on: August 04, 2019, 11:41:12 PM »

Changed the command to use an INT or no argument. When using an INT the results will be the same between py2/3. All I've done in change line  617 in parse.py to:

    random.seed(stoi(ln[0]))  # predicable results.

Also, changed the docs to reflect the same.

Committed (unless there is a problem!).
Logged

My online life: http://www.mellowood.ca
sciurius
Sr. Member
****
Posts: 443



« Reply #7 on: August 05, 2019, 11:59:14 AM »

The regression tests 19.07 -> 19.08 succeeded with integer values.
Python2 -> Python3 yields a lot of discrepancies, some due to different handling of formatted numbers. For example:

P2: Overwriting existing midi file (8 bars, 0.27 min / :16 m:s)
P3: Overwriting existing midi file (8 bars, 0.27 min / 0:16 m:s)

MMA uses "%.0d" format in main.py. Shouldn't this be just "%d"?

More serious is that I get different MIDI from python 2 versus 3 runs. It turns out that Python3 uses a different random implementation. This does not affect calls to random(), but it does affect often used methods like randrange() and choice(). So runs are consistent when using python2, and when using python3, but not from python2 to python3 and vice versa.
I am afraid that is something we have to live with. Alternatives like migrating MMA to use NumPy do not seem worth the effort to me.
Logged
bvdp
Kara-Moon Master
****
Posts: 1436


WWW
« Reply #8 on: August 05, 2019, 04:16:38 PM »

I'm glad when MMA works with both py2 and 3 Smiley I'm going to have to wean myself off of 2.x one of these days ... but there are concepts in 3.x that I just don't get. Hint, don't get old ... makes life to complicated.

I would be surprised if the same random results happened between py2 and 3.
Logged

My online life: http://www.mellowood.ca
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.123 seconds with 19 queries.