# Pure Function passed as an option to a function, which uses other options of the same function as arguments

I am editing my original question, as I have figured out a method of doing what I want.

Now my question is if there is a more elegant, efficient way to do the following:

Options[f] = {
Energy -> energy,
Temperature -> Func[Energy*Frequency, {Energy, Frequency}],
Frequency -> freq
};
f[OptionsPattern[]] := Module[{energy, temperature, frequency},
energy = OptionValue[Energy];
frequency = OptionValue[Frequency];
temperature = If[
OptionValue[Temperature][[1]] /. Map[# -> OptionValue[#] &,
Flatten[{OptionValue[Temperature][[2]]}]],
OptionValue[Temperature]
];
{
Energy -> energy,
Frequency -> frequency,
Temperature -> temperature
}]


Please note that this has the needed generalization to change what options are used as arguments to the passed function or if desired a value (or variable) can be directly inserted as an option.

For this application I have >70 Options (parameters) and I would like to be able to insert (if desired) a function with arguments based on any of the other options, or directly insert a value (if a function "Func" isn't desired.)

Is this more clear?

Thanks again!

• Hi and welcome! To make the most of Mma.SE start by taking the tour now. As you receive give back, vote and answer questions, keep the site useful, be kind, correct mistakes and share what you have learned. Jun 3, 2018 at 21:04
• You shouldn't use fas a function name and as a paramter as well. Use another symbol for the f inside your function. I would also suggest that using strings for your option names may be safer (i.e. "TemperatureFunction" instead of the plain TemperatureFunction) (see e.g. Why are some option values symbols, other strings?. Jun 3, 2018 at 21:17
• Thanks for the response. Please re-read my original question as I have completely changed it. Hopefully, it is more clear now. Jun 4, 2018 at 0:18
• @M.Decker I have proposed a solution in an answer below. Is that more along the lines of what you seek? Jun 4, 2018 at 21:14

Apparently, the only problem was that you scoped f by Module so that OptionValue had a hard time to find the default values for f. (Option stores Option[f] within f, not as DownValue of Option.)

The following should work without any problems.

Options[f] = {
Energy -> 25,
Frequency -> 60,
TemperatureFunction ->
Function[{Energy, Frequency}, Energy*Frequency^2]
};

f[x_, OptionsPattern[]] := Module[{en, freq, tempFunction},
en = OptionValue[Energy];
freq = OptionValue[Frequency];
tempFunction = OptionValue[TemperatureFunction];
(* **Missing Necessary Code***)
x*tempFunction[en, freq]
]

• Thanks for the response. I have edited my question to be more clear on the desired capability I am seeking. I now have a solution, but I am wondering if there is a more elegant (straight forward and efficient) solution. Thanks again. Jun 4, 2018 at 0:19

I mentioned in the comments that I find it advantageous to use strings as the names of my user-defined options. In this case, I think it may work for your problem as well. Here is a sample idea:

ClearAll[f]

Options[f] = {
"Energy" -> energy,
"Temperature" -> "Energy" "Frequency",
"Frequency" -> freq
};

f[OptionsPattern[]] := Module[
{energy, temperature, frequency},
energy = OptionValue["Energy"];
frequency = OptionValue["Frequency"];
temperature = With[{tempopt = OptionValue["Temperature"]},
If[NumberQ@tempopt,
tempopt,
tempopt /. Cases[tempopt, a_String :> (a -> OptionValue[a]), Infinity]
]
]
]


So now you can pass a "template" to your function, using the names of the other options / parameters as placeholders for their values (you will just have to be careful not to generate recursive definitions upon function call). For instance:

f["Energy" -> aNumber, "Temperature" -> 2 Exp["Energy"] + Log["Frequency"]]

(* Out: 2 E^aNumber + Log[freq] *)


or:

f["Energy" -> 4, "Temperature" -> "Energy" "Frequency"^2]

(* Out: 4 freq^2 *)

• I will take a look at this. I would rather not require quotes, but if it end up speeding up calculated results, I'll go with it. Thanks. Jun 6, 2018 at 22:03