# Best way to write a function that randomly takes definition from list of functions?

I want to define a function based on a random choice from a list of possible functions.

For example, suppose the possible functions are {Sqrt,Log}. Then I want to define f[x] to be a (randomly chosen) one of f[x_]=Sqrt[x] and f[x_]:=Log[x]

What is a good way to do this? (and have it work with user defined functions in the list, like {Sqrt,Log,x^2+x}

My feeling is that I should make a function that takes a list of functions as an input, and randomly chooses one of them. I have an example of this below, but I have three concerns/issues with the below code:

1. using ?fun1 gives fun1=Log, not fun1=Log[x]
• I don't know how(/whether) this matters, but something nags at me that it does
2. If I want a function that is either f[x_]:=Sqrt[x] f[x_]:=Log[x+1], I don't know how to incorporate this "+1" part
3. I should probably be using := not = in the example code below

I imagine 1 and 3 can likely be corrected by some small tweak to the code, whereas for 2 all I can think of is using Which, but this seem unwieldy for long lists of possible functions.

I don't know how to go about correcting this hence my question.

Example code:

SeedRandom[10];
chooseFun[listFun_] :=
Module[{randVal}, randVal = RandomInteger[{1, Length[listFun]}];
listFun[[randVal]]
];
fun1 = chooseFun[{Sqrt, Log}];
fun2 = chooseFun[{Sqrt, Log}];


Edit: Note: Its not a requirement that the function take a list of functions as an input. I would be okay, say, defining ListOfFunctions before calling SeedRandom in the below code.

Also, an additional concern/question: Normally when we do something like f[x_]:=x^2 it assigns the RHS to the LHS. But in the case here I dont want to assign the LHS to the RHS, but the something based on the output of the RHS. (Sorry if I have not explained this well)

Edit 2: Heres another attempt I have made. This one uses a function that defines another function (based on a name that is the input).

• Is this a good approach?
• Note here ?test gives test[x$_] := listFun[x$][[randNum\$61000]]

.

Clear["Global*"]

SeedRandom[10];
listFun[x_] := {Sqrt[x], Log[x + 1]};
chooseRandFunc[name_] := Module[{randNum},
randNum = RandomInteger[{1, Length[listFun[x]]}];
name[x_] := listFun[x][[randNum]]
];
chooseRandFunc[test]


Edit 3: It seems the question was not clear, so I went back to try to clarify. Sorry to the existing answers

• why not simply ClearAll[chooseFun]; chooseFun=RandomChoice?
– kglr
Commented May 22, 2021 at 14:06
• @kglr Honestly, I was not aware of that function. Does chooseFun[x] evaluate properly though, in particular if one of the options is a user defined function like Log[x+1] or x^2_x as opposed to a system one like Log or Sqrt? (I ask because I usually think about f[x_]:=x^2 as saying "take x^2 and replace x by whatever is given", but chooseFun=RandomChoice doesn't take an input which confuses me.) Commented May 22, 2021 at 14:12
• you need to use it as chooseFunb[{Sqrt, Log}]@xx or as fa =chooseFunb[{Sqrt, Log}]; fa@x
– kglr
Commented May 22, 2021 at 14:15
• alternatively, you can define choseFun as ClearAll[chooseFun]; chooseFun := RandomChoice[{Sqrt, Log}]; Then chooseFun[t] gives Sqrt[t] or Log[t] at each invocation.
– kglr
Commented May 22, 2021 at 14:20
• @kglr Sorry I am not understanding stuff, and/or I have not explained my question well. First, why chooseFunb in the earlier comment (i.e. why is there a "b" there?). Second, with ClearAll[chooseFun] chooseFun := RandomChoice[{Sqrt, Log}];, chooseFun[t] would (potentially) switch from Sqrt to Log on different evaluations, wouldn't it? Commented May 22, 2021 at 14:24

Clear["Global*"]

SeedRandom[10];


Use pure functions and RandomChoice

listFun = {E^# - 1 &, Sqrt, Log[# + 1] &, #^2 &, Sin, Cos};

func[x_] := RandomChoice[listFun][x]

Plot[Evaluate[f = func[x]], {x, 0, 2}, PlotLabel -> f]


Plot[Evaluate@DeleteDuplicates@Table[func[x], 3], {x, 0, 2},
PlotLegends -> "Expressions"]


• This looks really nice, however I have an issue (sorry if I didn't explain my question well), func[x] can change from being Cos to Sin from one evaluation to the next. I don't want that to be possible. Specifically, I want a function, func[x_]:=, that becomes one of the functions in listFun, and once it becomes one of those functions it no longer changes. Does that make sense? (I think changing := to = might fix this though?) Commented May 22, 2021 at 14:38
• Perhaps another way of saying this is as follows: With the code you have provided ?func gives func[x_] := RandomChoice[listFun][x]. What I want it to be is func[x_]:=Cos[x], or an equivalent version of that (not need to be Cos, I just use Cos as example since that is the first thing you func evaluate to). Then, if I have func1[x_] := RandomChoice[listFun][x], func2[x_] := RandomChoice[listFun][x], func1 might be Sin,Cos, etc, and func2 can possibly be a different one, and so on Commented May 22, 2021 at 14:40
• Yes Set would give a fixed result. That is what Evaluate does in the plots. Commented May 22, 2021 at 14:49