Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Using Mathematica, I need to define a function of one integer variable that generates the same real number in the range 0 to 1, if it is called with the same argument, but gives a different real number if its argument is changed. For example :

Func[1] = 0.12675,
Func[2] = 0.11213,
Func[2] = 0.11213,
Func[1] = 0.12675,
Func[3] = 0.02561,

and so on.

How can I define such a function?

Edit

A more precise statement of the pseudo-random nature of the function Func.

The function should generate new numbers for each Mathematica session. So after thousands of sessions, the values Func[1] are uniformly distributed on the intervall 0 to 1. For a given session, Func[1] generates the same number again and again. But in the next session, Func[1] would be a different number. Otherwise, the generated numbers couldn't be considered as "random" if they are always the same.

share|improve this question
    
Can give a precise definition of "random" here? Since the function is deterministic, this is a very relevant and non-trivial question. –  Szabolcs Mar 8 '13 at 2:13
    
I mean uniformly distributed real numbers in the interval 0 to 1. –  Cham Mar 8 '13 at 2:17
    
I'd still like to know what you need this for and why a pre-generated list of numbers won't do. –  Szabolcs Mar 8 '13 at 3:51
    
@Szabolcs, I'm trying to generate a random distribution of points in 3D space to simulate the Crab nebula, with its filaments structure. Currently, I'm still unable to generate the filaments, and the random function is an experiment to generate several small lines. There's probably a better way to do this, though. I may ask a question on this subject with another topic. –  Cham Mar 8 '13 at 4:38
add comment

3 Answers

This one will be the same in a single session. However, it will be different each time the kernel is (re)started, or if func is cleared and the definition re-executed.

func[x_] := func[x] = RandomReal[];

If you wish func to give the same values every time you run Mathematica, then you could use RandomSeed[1], or whatever seed appeals to you, in a session before func is used. The values will be the same provided func[x] is always evaluated in the same order for each x. (If the order cannot be guaranteed, then another answer will be better.)

Here is a related answer on the use of the above trick in similar circumstances, called memoization.

share|improve this answer
    
I was just going to post the same, +1. –  Szabolcs Mar 8 '13 at 2:39
    
@Szabolcs I was just pondering, is there any worry, if RandomReal is called elsewhere? Or if func[x] is called, with x in a constructed order, such that func[1], func[2], etc. would not be a random sequence? I can't figure out if that is possible. –  Michael E2 Mar 8 '13 at 2:45
2  
FWIW, this can be written more tersely as: m : func[x_] := m = RandomReal[]; –  Mr.Wizard Mar 8 '13 at 3:09
    
@Mr.Wizard Hey, that's cute. I hadn't seen that before. I wonder, though, if you think that's a good way to write it? It's terser, but the traditional(?) way seems easier to read. Well, it would since I'm used to it. –  Michael E2 Mar 8 '13 at 3:24
    
Well, you know I love terse coding. In practice I often use mem : f[. . .] := mem = . . . as that is both terse and (IMHO) clear. This is assuming of course that it is for the purpose memoization and not something else. Using the Pattern is actually less prone to typos because you do not need to rewrite the entire function definition a second time. –  Mr.Wizard Mar 8 '13 at 3:33
show 1 more comment

You can simply create a big list of numbers, list = RandomReal[1, 1000000], and take those numbers one by one.

The elements of this list will be uniformly distributed and uncorrelated. I was assuming that this is what you meant by "random", which is the most important part of the question here. Perhaps you could clarify this.

share|improve this answer
    
Yes, I need uniformly distributed random numbers, in the interval 0 to 1. Apparently, the solution from belisarius : f[x_] := (SeedRandom[x]; RandomReal[]), is doing this, but I'm not sure yet. –  Cham Mar 8 '13 at 2:15
    
@Martin Uniformly distributed and "random" are not the same thing. Table[Mod[i, 10], {i, 10000000}] are uniformly distributed integers. Do you consider them random? –  Szabolcs Mar 8 '13 at 2:17
    
Hmm, then I'm not sure how to define "random" here. For all practical purposes, I need the function to generate any real number (in the interval 0 to 1) like the usual Random[Real, {0, 1}] command, but must give the same number again if I call the function with the same integer argument. –  Cham Mar 8 '13 at 2:22
    
I have to go with Szabolcs here. If the Mathematica developers have done their job right then this will do what the OP is asking for. If they haven't, the other approaches may not be curing that problem either (or may even be worse). –  sebhofer Mar 8 '13 at 9:16
add comment

I believe ...

f[x_] := (SeedRandom[x]; RandomReal[])
share|improve this answer
2  
I expected something better from you :P There's no guarantee that these will be uniformly distributed or that they will be uncorrelated if you take Table[f[i], {i, bigNumber}]. But of course the question is what does the OP really mean by "random"? –  Szabolcs Mar 8 '13 at 2:08
    
@Szabolcs I needed to save a few chars just to beat Leonid :P –  belisarius Mar 8 '13 at 2:09
    
This solution appears to be working great. The numbers should be uniformly distributed in the interval 0 to 1 –  Cham Mar 8 '13 at 2:09
    
So I now have two solutions which apparently are working great for what I need to do : func1[x_] := func[x] = RandomReal[]; and func2[x_] := (SeedRandom[x]; RandomReal[]). Which one should I use ? Which is "better" (I know, this question may be stupid, but I'm asking it anyway!). –  Cham Mar 8 '13 at 2:39
2  
@Szabolcs I just did a quick test for whiteness using Ljung-Box test (and another test using periodograms whos name I don't know) on a 50k sample created by this method and it looks good. (I did the test in Matlab so I can't post the code.) Didn't test for uniformity though. –  sebhofer Mar 8 '13 at 9:58
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.