Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 581875
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 13, 20262026-05-13T14:37:36+00:00 2026-05-13T14:37:36+00:00

I need small lists of gaussian random numbers for a simulation and so I

  • 0

I need small lists of gaussian random numbers for a simulation and so I tried the following:

import System.Random

seed = 10101
gen = mkStdGen seed

boxMuller mu sigma (r1,r2) =  mu + sigma * sqrt (-2 * log r1) * cos (2 * pi * r2) 

This is just the Box-Muller algorithm – given r1, r2 uniform random numbers in the [0,1] interval it returns a gaussian random number.

normals 0 g = [] 
normals n g = take n $ map (boxMuller 0 1) $ pairs $ randoms g
    where pairs (x:y:zs) = (x,y):(pairs zs)

So I used this normals function everytime I needed my list of random numbers.

The problem with that must be apparent: it generates always the same sequence cause I’m using always the same seed! I’m not getting new sequences, I’m only getting the first n values of the sequence all the time.

What I was pretending clearly was that, when I type:

x = normal 10 
y = normal 50

I’d have x to be the first 10 values of map (boxMuller 0 1) $ pairs $ randoms g and y to be the next 50 values on this list, and so on.

Of course this is impossible, cause a function must always return the same values given the same input. How do I escape this trap?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-13T14:37:36+00:00Added an answer on May 13, 2026 at 2:37 pm

    I think that doing your computations that require random numbers inside a monad that abstracts away the generator is the cleanest thing. Here is what that code would look like:

    We are going to put the StdGen instance in a state monad, then provide some sugar over the state monad’s get and set method to give us random numbers.

    First, load the modules:

    import Control.Monad.State (State, evalState, get, put)
    import System.Random (StdGen, mkStdGen, random)
    import Control.Applicative ((<$>))
    

    (Normally I would probably not specify the imports, but this makes it easy to understand where each function is coming from.)

    Then we will define our “computations requiring random numbers” monad; in this case, an alias for State StdGen called R. (Because “Random” and “Rand” already mean something else.)

    type R a = State StdGen a
    

    The way R works is: you define a computation that requires a stream of random numbers (the monadic “action”), and then you “run it” with runRandom:

    runRandom :: R a -> Int -> a
    runRandom action seed = evalState action $ mkStdGen seed
    

    This takes an action and a seed, and returns the results of the action. Just like the usual evalState, runReader, etc.

    Now we just need sugar around the State monad. We use get to get the StdGen, and we use put to install a new state. This means, to get one random number, we would write:

    rand :: R Double
    rand = do
      gen <- get
      let (r, gen') = random gen
      put gen'
      return r
    

    We get the current state of the random number generator, use it to get a new random number and a new generator, save the random number, install the new generator state, and return the random number.

    This is an “action” that can be run with runRandom, so let’s try it:

    ghci> runRandom rand 42
    0.11040701265689151                           
    it :: Double     
    

    This is a pure function, so if you run it again with the same arguments, you will get the same result. The impurity stays inside the “action” that you pass to runRandom.

    Anyway, your function wants pairs of random numbers, so let’s write an action to produce a pair of random numbers:

    randPair :: R (Double, Double)
    randPair = do
      x <- rand
      y <- rand
      return (x,y)
    

    Run this with runRandom, and you’ll see two different numbers in the pair, as you’d expect. But notice that you didn’t have to supply “rand” with an argument; that’s because functions are pure, but “rand” is an action, which need not be pure.

    Now we can implement your normals function. boxMuller is as you defined it above, I just added a type signature so I can understand what’s going on without having to read the whole function:

    boxMuller :: Double -> Double -> (Double, Double) -> Double
    boxMuller mu sigma (r1,r2) =  mu + sigma * sqrt (-2 * log r1) * cos (2 * pi * r2)
    

    With all the helper functions/actions implemented, we can finally write normals, an action of 0 arguments that returns a (lazily-generated) infinite list of normally-distributed Doubles:

    normals :: R [Double]
    normals = mapM (\_ -> boxMuller 0 1 <$> randPair) $ repeat ()
    

    You could also write this less concisely if you want:

    oneNormal :: R Double
    oneNormal = do
        pair <- randPair
        return $ boxMuller 0 1 pair
    
    normals :: R [Double]
    normals = mapM (\_ -> oneNormal) $ repeat ()
    

    repeat () gives the monadic action an infinite stream of nothing to invoke the function with (and is what makes the result of normals infinitely long). I had initially written [1..], but I rewrote it to remove the meaningless 1 from the program text. We are not operating on integers, we just want an infinite list.

    Anyway, that’s it. To use this in a real program, you just do your work requiring random normals inside an R action:

    someNormals :: Int -> R [Double]
    someNormals x = liftM (take x) normals
    
    myAlgorithm :: R [Bool]
    myAlgorithm = do
       xs <- someNormals 10
       ys <- someNormals 10
       let xys = zip xs ys
       return $ uncurry (<) <$> xys
    
    runRandom myAlgorithm 42
    

    The usual techniques for programming monadic actions apply; keep as little of your application in R as possible, and things won’t be too messy.

    Oh, and on other thing: laziness can “leak” outside of the monad boundary cleanly. This means you can write:

    take 10 $ runRandom normals 42
    

    and it will work.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I need small help. I have 2 lists( say A and B) which have
I am using SDL Tridion 2011 SP1. I need small clarification regarding multimedia schema
I often need relatively small (<10000 entries <1kb) caches for speeding up calculations. My
I need to read small sequences of data from a 3.7 GB file. The
I need to develop small AIR extension for iOS. here's the question: is it
In my project I need to write small WYSIWYG editor (just let users make
I need to write a small console app (patch) that turns off the print
I need to write a small application to read a configuration file and generate
I need to edit XML files on a small Linux box that we have
I need to allow multiple downloading of small documents in Rails, preferably using Paperclip

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.