# Evaluate a parametric function dependent on a random number of parameters

This is a question related to the evaluation of a parametric function dependent on a random number of parameters.

Consider a "blackBox" that returns a parametric function dependent on time (t) and, randomly, on N parameters: $$\{p_1, ..., p_N\}$$. At the outset, we don't know what N is. The only way to measure N is to call the blackBox. If the blackBox is called again, N might change.

How to evaluate the box at $$t = 1$$, $$p_1=1$$, $$p_2=2$$ , ...., $$p_N=N$$?

For concreteness, consider the following "little-black-box":

littleblackBox := Module[{parameters},
parameters = If[RandomReal[] < 0.5, {p1}, {p1, p2}];
Return[ParametricNDSolveValue[{f'[t] + f[t] == 0,
f[0] == Total[parameters]}, f, {t, 0, 1}, parameters]]
]


It returns a parametric function dependent on time and, randomly, dependent on either one parameter: $$\{p_1\}$$, or two: $$\{p_1, p_2\}$$.

Clearly,

Evaluate[littleblackBox[##] &[1][t]] /. t -> 1


or

Evaluate[littleblackBox[##] &[1, 2][t]] /. t -> 1


could fail. On the other hand, one might think that

evaluatelittleBlackBox := Module[{Np, localBox},
localBox = littleblackBox;
Np = Length[localBox[[-2]][[1]]];(*get number of parameters*)
If[ Np == 1, Evaluate[localBox[##] &[1][t]] /. t -> 1 ,
Evaluate[localBox[##] &[1, 2][t]] /. t -> 1]
]


does the work; however, I was able to define this function using as prior knowledge that the little-black-box depends on two parameters at most. This doesn't constitute a satisfactory answer.

Aim: rewrite "evaluatelittleBlackBox" without looking inside the little-black-box!

• Do you know that the "black box" is always a ParametricFunction[...] object? Or could it be any type of function-like expression? – Lukas Lang Sep 17 '19 at 14:08
• It is always a ParametricFunction[...] object. – user10181864 Sep 17 '19 at 14:31
• And how should the parameter values be chosen? Randomly? From a long enough list? From 1 to n? – Lukas Lang Sep 17 '19 at 16:48
• In principle from 1 to N. But I wrote the problem in this way for the sake of being concrete. Choosing them randomly or from a long enough list works for me as well. – user10181864 Sep 17 '19 at 17:06

For ParametricFunction, you can get the parameters using the following code:

littleblackBox@"Parameters"
(* {p1, p2} *)


It is then straightforward to construct a list of appropriate length and to pass it to the function using Apply:

func = littleblackBox
(* ParametricFunction[ <> ] *)

nParams = Length@func@"Parameters"
(* 1 *)

args = Range@nParams
(* {1} *)

func @@ args
(* InterpolatingFunction[ <> ] *)

(func @@ args)[1]
(* 0.367879 *)