-1
$\begingroup$

I have the following problem. I current can automatically create the variable positionPayload, for instance:

positionPayload=2.x+3.t^2

I need, however, to automatically make positionPayload a function of x and t, i.e. do something like positionPayload[x_,t_]. To identify the variables present in positionPayload, I do:

variableList=DeleteDuplicates[Variables[positionPayload]]

However, how do I now write something to the effect of positionPayload[variableList] such that Mathematica now understands that positionPayload is a function of those variables?

Update

My question really is: how can I convert positionPayload into positionPayload[x_,t_] using the list variableList.

$\endgroup$
  • 1
    $\begingroup$ perhaps you're after SetDelayed : positionPayload := 2.x+3.t^2 $\endgroup$ – Dr. belisarius Aug 4 '15 at 1:37
  • $\begingroup$ @belisarius I am just looking for a way how I can write f[a_,b_] knowing the list {a,b}. Apply[] is not working.... $\endgroup$ – space_voyager Aug 4 '15 at 1:59
  • $\begingroup$ Related: (10067), (31985) $\endgroup$ – Michael E2 Aug 4 '15 at 14:30
4
$\begingroup$

Not that I would recommend this, but anyway:

positionPayload = 2. x + 3. t^2;
variableList = Variables[positionPayload];
positionPayload = Function[Evaluate@variableList, Evaluate@positionPayload];
positionPayload[q, r]
(* 3. q^2 + 2. r *)

Edit

positionPayload = 2. x[1] + 3. t[3]^2;
variableList = Variables[positionPayload];
ul = Unique[ConstantArray[\[FormalT], Length@variableList]];
positionPayload = Function @@ {ul, positionPayload /. Thread[variableList -> ul]};
positionPayload[q, r]
(*3. q^2+2. r*)
$\endgroup$
  • $\begingroup$ It still doesn't quite work. This gives my positionPayload[x,t] while I need positionPayload[x_,t_] $\endgroup$ – space_voyager Aug 4 '15 at 2:24
  • $\begingroup$ @space_voyager It gives you positionPayload = Function[{t,x},3. t^2+2. x] which is exactly the same as positionPayload[ t_, x_] := 3. t^2+2. x $\endgroup$ – Dr. belisarius Aug 4 '15 at 2:31
  • $\begingroup$ @space_voyager I have no idea what you mean. It gives Function[{t, x}, 3. t^2 + 2. x], which is a "pure function" instead of a transformation rule. What is the practical difference in your use-case? (BTW, my idiomatic way to do the same thing would be positionPayload = Function @@ {Variables[positionPayload], positionPayload}. I don't believe DeleteDuplicates is necessary.) $\endgroup$ – Michael E2 Aug 4 '15 at 2:31
  • $\begingroup$ @MichaelE2 You're right about DeleteDuplicates. I copied it in BM (Brainless Mode) $\endgroup$ – Dr. belisarius Aug 4 '15 at 2:33
  • 1
    $\begingroup$ @space_voyager The difference is quite fundamental in Mathematica: x is a Symbol, while x[1] isn't. $\endgroup$ – Dr. belisarius Aug 4 '15 at 2:57
3
$\begingroup$

You might try something like this, which makes pure functions, which means the variables used int the expression to converted only have to be clear at time expToF is called.

expToF[exp_, vars : {_Symbol ..}] :=
  With[{body = exp /. Thread[Rule[vars, Slot /@ Range @ Length[vars]]]},
    Function[body]]

Clear[x,t]
f = expToF[2. x + 3. t^2, {x, t}];
f[x,t]
3. t^2 + 2. x

Not limited to two variables.

Clear[x, y, z]
g = expToF[Sin[2 x] (1 - Cos[y]) E^z, {x, y, z}];
g[a, b, c]
(E^c)(1 - Cos[b]) Sin[2 a]

It can even be used for somewhat weird things, like

Clear[x]
h = expToF[Style[x, 24, Bold, Red, "SR"], {x}]
h[1 + Sin[x]]

which produces

funny

Despite Mathematica's funny formatting of the pure function returned by expToF, the returned function, as can be seen, works perfectly well.

Update

To handle the OP's revised question, I revise my definition definition of expToF to

expToF[exp_, vars : {(_Symbol | h_Symbol[_Integer]) ..}] :=
  With[{body = exp /. Thread[Rule[vars, Slot /@ Range @ Length[vars]]]},
    Function[body]]

then

Clear[x]
positionPayload = 2. x[1] + 3. x[2]^2;
positionPayload = expToF[positionPayload, {x[1], x[2]}];
positionPayload[q, r]
2. q + 3. r^2
$\endgroup$
2
$\begingroup$
positionPayload = 2. x + 3. t^2
(* 3. t^2 + 2. x *)

variableList = DeleteDuplicates[Variables[positionPayload]]
(* {t, x} *)

temp = positionPayload;
positionPayload =.
Evaluate[positionPayload @@ (Pattern[#, Blank[]] & /@ variableList)] := Evaluate@temp

Definition@positionPayload
(* positionPayload[t_, x_] := 3. t^2 + 2. x *)

positionPayload[q, r]
(* 3. q^2 + 2. r *)
$\endgroup$
2
$\begingroup$

My one shot at answering this question:

Attributes[convert] = {HoldFirst};

convert[def_Symbol?ValueQ] :=
  With[{old = def, pats = Quiet[Sequence @@ Cases[Variables @ def, s_Symbol :> s_]]},
    ClearAll[def];
    def[pats] := old;
  ]

Test:

positionPayload = 2. x + 3. t^2;

convert[positionPayload]

?? positionPayload

Global`positionPayload

positionPayload[t_, x_] := 3. t^2 + 2. x
positionPayload[5, 7]
89.

I hope it helps.

$\endgroup$

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