Jump to content
Sign in to follow this  
EAIP

Posting seed value

Recommended Posts

Here is a suggestion for posting the random seed value used by a function.

When using Open Music way back in time I remember that you could "lock" a random function if you liked the result, which IMO was a great workflow feature.

Perhaps a similar thing could be achived in Opusmodus if the random seed used for a function was posted to the post window in addition to the result of the evaluation.

If you like the result of a particular seed you could then manually "lock" the randomization using the :seed keyword for the function:

 

; first try different randomizations
(setf bin-rhythm (gen-binary-rnd 5 5 2 1))
=> gen-binary-rnd :seed 752

(setf bin-rhythm (gen-binary-rnd 5 5 2 1))
=> gen-binary-rnd :seed 234

; then lock seed if you like the result
(setf bin-rhythm (gen-binary-rnd 5 5 2 1) :seed 234)

 

Perhaps if possible also with the variable name as a label to keep track of things when using several random functions in complex code:

 

(setf bin-rhythm (gen-binary-rnd 5 5 2 1))
=> bin-rhytm gen-binary-rnd :seed 37

 

I think that this or a similar approach would be a really powerful way of trying different results when working with randomization in Opusmodus.

 

Share this post


Link to post
Share on other sites

INIT-SEED can be used at the start of algorithmic compositions employing high degrees of randomness in order to create consisted results, without having to worry about supplying seed N values to all the other functions which may also use random generation.


Example:

(setf init-seed (init-seed (rnd1 :low 1 :high 99999)))

init-seed
=> 3467

This way you can recover the initial seed if needed.

Share this post


Link to post
Share on other sites

Yes, I know about init-seed, it's great for setting the overall seed in a complete score context, I guess you mean something like this:

 

(setf seed (rnd-range 1 999999))
(init-seed seed)

(setf pitch (rnd-sample 5 '(c4 e4 g4 b4)))
(setf len (rnd-sample 5 '(s e)))

(setf phrase (make-omn
              :pitch pitch
              :length len
              ))

(def-score flute
           (
            :key-signature 'chromatic
            :time-signature '(4 4)
            :tempo 112
            :layout (flute-layout 'flt)
            )

(flt
 :omn phrase
 :channel 1
 :sound 'gm
 :program 'flute
 )
)

 

If you are happy with the result you can then evaluate the seed variable and paste the posted number into the :seed keyword in one or both of the forms including random functions and thus achieve locking one or several parameters.

 

However, if you just want to evaluate for example the 3rd line over and over again untill you find a pitch line you like, this is quite a cumbersome method.

It would be great to somehow get a report of the current internal state of a single random function, or at least be able to after evaluation get the current random state or seed used. Perhaps I'm misunderstanding something crucial regarding the way the seed functionality is implemented in OM.

Share this post


Link to post
Share on other sites

Also you can't use the method above for a single line if you want to evaluate OMN Notation (cmd + 3 or ctrl + cmd + N) at the same time (or at least I don't know how to do that).

 

(setf seed (rnd-range 1 999999))
(init-seed seed)
(setf pitch (rnd-sample 5 '(c4 e4 g4 b4)))

; Select all then Evaluate and Notation (ctrl + 3)
=> Error: The value 793536 is not of the expected type list.

 

Share this post


Link to post
Share on other sites

With snippet:

(setf pitch (rnd-sample 5 '(c4 e4 g4 b4) :seed (setf seed (rnd-range 1 999999))))
=> (g4 e4 c4 b4 b4)

Test:

(rnd-sample 5 '(c4 e4 g4 b4) :seed 675029)
=> (g4 e4 c4 b4 b4)

 

Note: ctrl-3 is not for displaying numbers.

 

Share this post


Link to post
Share on other sites

Yes, of course, but in terms of workflow it isn't very practical, I think you would like to keep things separated when trying out individual lines of a score.

Is there a way of somehow getting the seed or random state used under the hood when not providing one yourself?

 

(Sorry about the typo, I meant to write Cmd + 3 in the code example, as in "OMN notation")

Share this post


Link to post
Share on other sites

If we use random function without a seed then there is nothing to retrieve because there is no seed of any kind in random pick at any stage. 

Share this post


Link to post
Share on other sites
(defun doseed (&key seed)
        (setf seed (init-seed (rnd-range 1 999999)))
        (print seed))


(rnd-sample 5 '(c4 e4 g4 b4) :seed (doseed))

This works for me.

 

/Lasse

Share this post


Link to post
Share on other sites

Thanks for the patience and clarification Janusz, and thanks also to Lasse for the useful lisp function.

Share this post


Link to post
Share on other sites

> Perhaps if possible also with the variable name as a label to keep track of things when using several random functions in complex code:

(setf bin-rhythm (gen-binary-rnd 5 5 2 1))
=> bin-rhytm gen-binary-rnd :seed 37

This should be easy to do with a revision of the macro do-verbose, but as users, we have no access to its definition to change it. (The macro would check the value of the variable seed in its environment.)

Side remark: If anyone revises do-verbose, it would be highly welcome to be able to switch off its effect altogether, because Common Lisp offers much better builtin debugging facilities than what this macro does. 

 

Anyway, here is an easy workaround for your particular situation. 

 

(setf bin-rhythm (gen-binary-rnd 5 5 2 1 :seed (print 123)))
; printed: 123 gen-binary-rnd
=> ((0 0 1 0 0) (1 0 1 0 1) (0 1 1 0 1) (1 1 0 1 1) (0 1 0 1 1))


See also the discussion in the thread linked below.

 

Best,

Torsten

 

 

Share this post


Link to post
Share on other sites
On 3/31/2018 at 7:40 PM, lviklund said:

(defun doseed (&key seed)
        (setf seed (init-seed (rnd-range 1 999999)))
        (print seed))


(rnd-sample 5 '(c4 e4 g4 b4) :seed (doseed))

This works for me.

 

/Lasse

 

Below is a more secure variant of that function, which does not overwrite the seeds of all other functions. Calling init-seed is not needed here... 

 

I avoided using do in the function name, as functions/macros named such are by convention looping constructs. 

 

Best,

Torsten

 

(defun mk-seed (&optional seed)
  "Generates a random seed value, prints and returns it. Useful for exploring different results of random processes, but then keeping a found solution.

  Args:
  - seed (int): optionally fixes generated seed.

  Examples:

  (rnd-sample 3 '(c4 d4 e4) :seed (mk-seed))
  ; 405621 rnd-sample
  => (c4 e4 d4) 

  (rnd-sample 3 '(c4 d4 e4) :seed (mk-seed 13))
  ; 13 rnd-sample
  => (e4 d4 e4) 
  "
  (print (if seed seed (rnd-range 1 999999))))

 

Share this post


Link to post
Share on other sites
On 4/6/2018 at 1:38 PM, torstenanders said:

Calling init-seed is not needed here... 

 

I guess it is, if you want to see what value init-seed gives you... Or...?

That was anyway why I did it this way.

 

Anyway, thank you again for your interesting knowledge.

 

/lasse

Share this post


Link to post
Share on other sites

Citing the documentation: "INIT-SEED can be used at the start of algorithmic compositions employing high degrees of randomness in order to create consisted results, without having to worry about supplying seed N values to all the other functions which may also use random generation."

 

The function init-seed does not give you any new value actually (it just returns its argument), but in the background as a side-effect initialises the random generation of all Opusmodus random functions, so that their results are consistent on re-evaluation. 

 

Just try removing it in your function :)

 

Besides, programs that reduce any changes to global states and side effects to the absolute minimum (which is most often using no stateful programming at all) are more easy to maintain and expand. Your little function introduces two stateful operations that are not needed here: setf (better use a local let) and init-seed. (This is even more important when writing concurrent code, which can be necessary when doing real-time stuff, e.g., when you have multiple processes running in parallel changing the same global variables without further precaution.)   

 

Best,

Torsten

Share this post


Link to post
Share on other sites

I found a way to display an internal seed if seed is nil (random process).

 

Example without a seed (each time different result):

(rnd-number 12 1 10)
? rnd-number :seed 678732
=> (10 6 10 6 1 9 5 6 10 2 4 2)

 

Now the same function with a manually "lock" using the :seed

(rnd-number 12 1 10 :seed 678732)
? rnd-number :seed 678732
=> (10 6 10 6 1 9 5 6 10 2 4 2)

 

(rnd-pick '((q c4 p d4 ff s a4 stacc) (s e4 app q c5 d5 pp)))
? rnd-pick :seed 598336
=> (q c4 p d4 ff s a4 stacc)

 

Screen Shot 2018-04-07 at 10.30.22.png

 

I hope everybody will be happy with the solution  :-)

To add this functionality to all the functions using random seed will take some time to do.

Hopefully tomorrow :-)

 

Best,

Janusz

Share this post


Link to post
Share on other sites

Thanks Janusz, this was exactly was what I was wishing for, really useful I think!

Share this post


Link to post
Share on other sites
Quote

Is it possible to implement the same when doing audition-omn-snippet?

That would be very complicated. The snippet (section) is rewritten from all kind of selections into DEF-SCORE.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

  • Similar Topics

    • By Andy
      Hello
      I'm new here.
      I'm on the demo and doing fine but for the life of me I can't figure out what the n integer does after :seed?
      I know seed fixes a random function so it is repeatable but what does that number do? I tried changing it in Tutorial 5 but I can't make sense of it!
      Thanks
      Andy
       
    • By Andy
      Hi
      I'm starting to loose the will to progress.
      So I just spent an hour trying to evaluate this and getting errors and thinking I'd got the wrong number of brackets and yet it looks fine.
       
      (setf motifx12 (rnd-order (gen-repeat 12 (list motif)))) :seed3) 
       
      And then I realise that I have to place the cursor not on the final bracket but on the one before :seed3)
      Nowhere does it say this in the manual as far as I can tell.
      And why?
      I think it's something to do with the : colon that I don't understand in the language. And I still don't understand seed.
      I'm really trying to get to grips with lisp but my hair is on fire. 😞
    • By PatrickMimran
      I try to put a seed as an option in this function with a default value of nil or no seed , how may i add it as optional 
       
      Thanks  Patrick  
       
      (defun patkaos ( seed lambda long )
       (let ((res (cons seed nil)) (xn seed))
          (dotimes (n long res) (setf res (cons (setf xn (* lambda xn (- 1 xn))) res)))
          (reverse res)))
×
×
  • Create New...