Re: Normal distribution random numbers

2020-05-31 Thread tantalum
surely not the ideal way to generate numbers with a normal distribution, 
but there is a way to use custom probabilities from a list, which i 
think is nice to know.

it works like this:

have a list of probabilities. can be as long as you want. i think that 
is called probability density.

->
(1 0 3 1)

create the cumulative sums for this list. that is, sums like this
  (a b c ...) -> (a (+ a b) (+ a b c) ...)
i think that is called cumulative distribution.
->
(1 1 4 5)

create a random number up to the largest sum
->
(random 5)

return the first index of the list of cumulative sums that is greater 
than the random number.
given the distribution above, you would see index 2 a lot, never index 
1, and index 0 and 3 rarely.


~~~
(use-modules ((srfi srfi-1) #:select (last)))

(define (cusum a . b)
  "calculate cumulative sums from the given numbers.
   (a b c ...) -> (a (+ a b) (+ a b c) ...)"
  (cons a (if (null? b) (list) (apply cusum (+ a (car b)) (cdr b)

(define* (random-discrete-f probabilities #:optional (state 
*random-state*))

  "(real ...) [random-state] -> procedure:{-> integer}"
  (let* ((cuprob (apply cusum probabilities)) (sum (last cuprob)))
(lambda ()
  (let ((deviate (random sum state)))
(let loop ((a 0) (b cuprob))
  (if (null? b) a (if (< deviate (car b)) a (loop (+ 1 a) (cdr 
b)


(define random* (random-discrete-f (list 1 0 3 1) 
(random-state-from-platform)))

(display (random*))
~~~




Re: C programs in Scheme syntax

2020-05-31 Thread tantalum
ive started https://github.com/sph-mn/sph-sc and have been using it a 
lot over the years and worked through several c edge cases. i enjoy 
using it, more and more even. the git repository page contains several 
hints and ideas on the general topic. i you have any questions, i'd be 
happy to answer them.


a few key points about sc:
* it uses scheme read to parse code but that discards scheme comments 
and other ways to insert c comments are needed. using guile-reader 
instead works, but it is a c library to be compiled by the user and i 
often faced autotools issues with it
* i guess it would be possible to do the whole generation process via 
scheme macros. it might be better than the approach currently 
implemented in sc, as the scheme macro system and scheme comments are 
immediately available. syntax checks with hints on error would be nice. 
the translation process of sc calls procedures for all elements of the 
nested list of expressions returned by scheme read. first going through 
the tree top to bottom - possibly translating whole subtrees to c 
strings or returning sc to be parsed again, then bottom to top to handle 
remaining elements - elements which might be lists with arguments that 
have been previously translated. sescript, the javascript variant of sc, 
uses hashtables that map s-expression prefixes to replacer functions, 
which is easier to extend than the case statements used by sc
* the reason why i havent implemented a scheme style macro system for sc 
yet is that the task of implementing something like syntax-rules or 
syntax-case seems quite daunting. a good pattern matcher and preserving 
hygiene seem to be the top issues. simpler macro systems are possible, 
quickly implemented even, but all in all i havent hit a clear need for 
it yet (still thinking what i would do with it) and fear that it might 
create hard to read c code. then again, it might simplify c code because 
of a reduced dependence on the preprocessor
* sc has automated tests with input/output listed, this could be helpful 
for finding edge cases even in other projects
* with s-expressions, automated code documentation for c becomes easier 
than ever before




Re: Normal distribution random numbers

2020-05-31 Thread Zelphir Kaltstahl
Hi!

Interesting technique, that when thinking about it, intuitively makes
sense to me. Thanks for sharing!

Regards,
Zelphir   

On 31.05.20 17:12, tantalum wrote:
> surely not the ideal way to generate numbers with a normal
> distribution, but there is a way to use custom probabilities from a
> list, which i think is nice to know.
> it works like this:
>
> have a list of probabilities. can be as long as you want. i think that
> is called probability density.
> ->
> (1 0 3 1)
>
> create the cumulative sums for this list. that is, sums like this
>   (a b c ...) -> (a (+ a b) (+ a b c) ...)
> i think that is called cumulative distribution.
> ->
> (1 1 4 5)
>
> create a random number up to the largest sum
> ->
> (random 5)
>
> return the first index of the list of cumulative sums that is greater
> than the random number.
> given the distribution above, you would see index 2 a lot, never index
> 1, and index 0 and 3 rarely.
>
> ~~~
> (use-modules ((srfi srfi-1) #:select (last)))
>
> (define (cusum a . b)
>   "calculate cumulative sums from the given numbers.
>    (a b c ...) -> (a (+ a b) (+ a b c) ...)"
>   (cons a (if (null? b) (list) (apply cusum (+ a (car b)) (cdr b)
>
> (define* (random-discrete-f probabilities #:optional (state
> *random-state*))
>   "(real ...) [random-state] -> procedure:{-> integer}"
>   (let* ((cuprob (apply cusum probabilities)) (sum (last cuprob)))
>     (lambda ()
>   (let ((deviate (random sum state)))
>     (let loop ((a 0) (b cuprob))
>   (if (null? b) a (if (< deviate (car b)) a (loop (+ 1 a) (cdr
> b)
>
> (define random* (random-discrete-f (list 1 0 3 1)
> (random-state-from-platform)))
> (display (random*))
> ~~~
>
>