2
$\begingroup$

I am trying to convert a user defined function that takes two or more variables into a user defined function that takes a list of variables. However, it seems Mathematica treats variables and variables in a list differently to one another in a way I don't understand.

An example of a user defined function taking x1 and x2 that works as intended.

fun1[x1_, x2_] := x1 + x2^2
D[fun1[x1, x2], x2]
ContourPlot[fun1[x1, x2] == 10, {x1, -10, 10}, {x2, -10, 10}]

Now I want to condense the variables to a list x.

fun2[x_] := x[[1]] + x[[2]]^2
D[fun2[x], x[[2]]]
ContourPlot[fun2[x] == 10, {x[[1]], -10, 10}, {x[[2]], -10, 10}]

The differentiation step on fun2 outputs the expected 2 x[[2]] but with warnings Part::partd: Part specification x[[1]] is longer than depth of object., Part::partd: Part specification x[[2]] is longer than depth of object., Part::partd: Part specification x[[2]] is longer than depth of object. and General::stop: Further output of Part::partd will be suppressed during this calculation..

The ContourPlot does not render and outputs warnings Part::partd: Part specification x[[1]] is longer than depth of object. and ContourPlot::itraw: Raw object x[[1]] cannot be used as an iterator..

What am I doing incorrectly in specifying a function that takes a list of variables? Are there alternate ways of writing functions that will take a large vector of inputs?

$\endgroup$
  • 1
    $\begingroup$ Except for the last line, you can: xs = Array [x, 2]; fun2 [x__]: = x [[1]] + x [[2]] ^ 2 D [fun2 @ xs, xs [[2]]] $\endgroup$ – Xminer Dec 29 '19 at 17:06
  • $\begingroup$ And maybe you find xs = Table[Indexed[x, i], {i, 1, 2}]; more attractive... But ContourPlot just does not like vector inputs. The closest you can get to it is ContourPlot[ fun2[{x, y}] == 10, {x, y} \[Element] Rectangle[{-10, -10}, {10, 10}]]. $\endgroup$ – Henrik Schumacher Dec 29 '19 at 17:08
  • $\begingroup$ Dummy variables in functions like D, ContourPlot should be a plain symbol like 'x1' 'x[[1]]' is in a full form 'Part[x,1]' which is not a plain symbol. You have to use them like this ; D[fun2[{x1, x2}], x2] ContourPlot[fun2[{x1, x2}] == 10, {x1, -10, 10}, {x2, -10, 10}] $\endgroup$ – Hayashi Yoshiaki Dec 29 '19 at 17:09
3
$\begingroup$

You can eliminate your problem by defining your function so that it takes both multiple arguments and a list of arguments.

fun[x1_, x2_] := x1 + x2^2
fun[{x1_, x2_}] := fun[x1, x2]

Now when you have a list of arguments, you simply give fun the list. Like so:

D[fun[{x1, x2}], x2]
ContourPlot[fun[{x1, x2}] == 10, {x1, -10, 10}, {x2, -10, 10}]

The results are:

2 x2

and

plot

| improve this answer | |
$\endgroup$

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