0
$\begingroup$

I'm trying to create a simple function that generates a transformation matrix from the partial derivatives of two coordinate systems. It currently works when I have it written like this:

x[r_, theta_] = r*Cos[theta]; 
y[r_, theta_] = r*Sin[theta]; 

transformationMatrix[r_, theta_] = 
   {{D[x[r, theta], r], D[x[r, theta], theta]}, 
    {D[y[r, theta], r], D[y[r, theta], theta]}}; 

In[123]:= transformationMatrix[0.3, 0.5]    
Out[123]= {{0.877583, -0.143828}, {0.479426, 0.263275}}

But I want the function to work with vectors, not scalars, so I change it to this:

x[xPrime_] = xPrime[[1]]*Cos[xPrime[[2]]]; 
y[xPrime_] = xPrime[[1]]*Sin[xPrime[[2]]]; 

transformationMatrix[xPrime_] = 
   {{D[x[xPrime], xPrime[[1]]], D[x[xPrime], xPrime[[2]]]}, 
    {D[y[xPrime], xPrime[[1]]], D[y[xPrime], xPrime[[2]]]}}; 

transformationMatrix[{0.3, 0.5}]

and I get a bunch of errors that say:

Part::partd: Part specification xPrime[[1]] is longer than depth of object. >>
Part::partd: Part specification xPrime[[2]] is longer than depth of object. >>
Part::partd: Part specification xPrime[[1]] is longer than depth of object. >>
Part::partd: Part specification xPrime[[2]] is longer than depth of object. >>

Fine, so I'll try deferring the evaluation with this:

x[xPrime_] := xPrime[[1]]*Cos[xPrime[[2]]]; 
y[xPrime_] := xPrime[[1]]*Sin[xPrime[[2]]]; 
transformationMatrix[xPrime_] := 
   {{D[x[xPrime], xPrime[[1]]], D[x[xPrime], xPrime[[2]]]}, 
    {D[y[xPrime], xPrime[[1]]], D[y[xPrime], xPrime[[2]]]}}; 
transformationMatrix[{0.3, 0.5}]

And I get this:

General::ivar: 0.3` is not a valid variable. >>
General::ivar: 0.5` is not a valid variable. >>
General::ivar: 0.3` is not a valid variable. >>

I need some help. How should I be constructing this function to work with vectors? Is there a more natural way in Mathematica to accomplish this?

$\endgroup$

1 Answer 1

1
$\begingroup$

Just add a 2nd definition for transformationMatrix

x[r_, theta_] := r*Cos[theta]
y[r_, theta_] := r*Sin[theta]

transformationMatrix[r_, theta_] = 
  {{D[x[r, theta], r], D[x[r, theta], theta]}, 
   {D[y[r, theta], r], D[y[r, theta], theta]}};

transformationMatrix[{r_, theta_}] := transformationMatrix[r, theta]

Then

transformationMatrix[{0.3, 0.5}]

gives the same answer as

transformationMatrix[0.3, 0.5]

Note: transformationMatrix[Sequence @@ {0.3, 0.5}] will give the results you want with your original code.

$\endgroup$
4
  • $\begingroup$ Is there a way to tell the function that the parameters are a sequence? Similar to what you did with the caller there. $\endgroup$
    – Quark Soup
    Commented Nov 11, 2019 at 23:28
  • $\begingroup$ @Quarkly. The parameters of are always a sequence; you don't have to tell a function that they are. That's why Sequence @@ {0.3, 0.5} works. $\endgroup$
    – m_goldberg
    Commented Nov 12, 2019 at 1:10
  • $\begingroup$ The function x[vector_] = vector[[1]]*Cos[vector[[2]]] most definitely needs to be told that vector is an array, otherwise it spits out those messages "Part specification vector[[1]] is longer than depth of object.". $\endgroup$
    – Quark Soup
    Commented Nov 12, 2019 at 1:12
  • 1
    $\begingroup$ @Quarkly, use :=, as in x[vector_] := vector[[1]]*Cos[vector[[2]]]. That way it won't try to do anything until it knows what vector is. $\endgroup$
    – MelaGo
    Commented Nov 12, 2019 at 1:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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