2
$\begingroup$

In physics (I'm thinking of Taylor's Classical Mechanics or Griffith's Classical Electrodynamics) it is common to use "hat" vectors to denote unit vectors like $\hat{x}$ or $\hat{r}$. If I wanted to write in Mathematica (and still be able to use all the vector analysis functionality) using this notation I could evaluate

Overhat[x,^] = {1, 0};
Overhat[y,^] = {0, 1};

and then just let it sit in the background while I type equations in "unit vector" notation and Mathematica doesn't have any trouble. And if I wanted to make something more complicated, like with coordinate systems whose unit vectors change with position (such as polar) I could do this

Overhat[r][r_, θ_] = Cos[θ]Overhat[x] + Sin[θ]Overhat[y]
Overhat[θ][r_, θ_] = -Sin[θ]Overhat[x] + Cos[θ]Overhat[y]

And type in equations and Mathematica will reduce them down to the standard list form it uses for vectors.

Just to be clear, if you wanted to do this you would also need to write simple substitutions for $r$ and $\theta$ in terms of x and y (because you would likely be using those variables if you were using $\hat{r}$ and $\hat{\theta}$ otherwise the built vector analysis functions wouldn't work as expected). One could even write a function that would take a list like $\{x,y\}$ and write it in terms of such unit vectors, either as $x \hat{x} + y \hat{y}$ or as $r \hat{r}$.

But doing all this in a document would be an awful lot of effort for every computation in say polar coordinates: Write in the nice hat notation, convert to a list, compute say the vector Laplacian (or some other vector related operation), get the output as a list and convert it back to unit vector notation (knowing which coordinate system the output is in).

After that long introduction, what I'm asking is if there is a way to automate all of this. I've been trying to make a function called Vect (or something along those lines) that could store a vector internally and output it in any coordinate system (using the nice unit vector notation) which ones could also use to do vector derivatives and other operations. In Java we would call this a wrapper class for a list, because it is basically just a list but with added functionality wrapped around it. I'm envisioning something like Quanity (which is basically just a wrapper class for a number) or Around (which is basically just a wrapper class for probability distributions).

The thing that is tricky is that Mathematica uses lists to represent vectors, but lists themselves have no notion of coordinate system. If I evaluate $\{r,0,0\}$ for $r=5, \theta=\Pi/2$ I get a very different vector than $\{x,y\}$ with $x->5, y->0$ even though Mathematica sees them both as $\{5,0\}$. To use the vector analysis functions you pretty much need to keep track yourself what expression should be interpreted as being "in" what coordinate system and apply options accordingly.

So how would one automate this. You would need to use Holds on expression to get them to output using the unit vectors. And you would either need a function to output lists that the built in functions can use or you would need to create wrappers for all the built in functions.

I guess what I'm asking is, is this possible? What would be the general best approach? Am I way over complicating this?

I should point out that I have scored the Internet looking for packages that do this already and haven't been able to find any. None of the tensor calculus packages accomplish this (and are probably overkill anyway). VECT and Symbolic Computing looked at first to be promising but no cigar (as far as I can tell). And most other implementation of these sorts of things tend to be for coordinate free vectors which is clearly not what I'm going for :)

Sorry for the long question, I just wanted to remove any confusion as to what I'm kinda going for here. Any feedback is appreciated, even if it is just a little :)

$\endgroup$
  • $\begingroup$ "I have scored the Internet looking for packages that do this already and haven't been able to find any." And that's probably for some good reason. What you seek for is basically utter pain. I'd suggest to just stick with one coordinate system at a time and do the math. $\endgroup$ – Henrik Schumacher Dec 17 '19 at 9:15
  • $\begingroup$ Focus on mathematics, not notations. The overhead to implement all the notations will be large. $\endgroup$ – yarchik Dec 17 '19 at 10:39
  • $\begingroup$ MMA provides OverHat[ ]. It allows you to make the $\hat{x}$ "symbol". The "symbol" can be made using a 3-key sequence: x Ctrl-7 Shft-6, then hit the spacebar. But OverHat[x] is not exactly a symbol. You can assign values to it like a symbol, and even use it in calculations like a symbol, at least sometimes. You can't Clear it, though, but you can Remove[ x ]. It's good for comments and documentation, but the experts do not advocate using it in calculation. $\endgroup$ – LouisB Dec 17 '19 at 11:09
  • 1
    $\begingroup$ Sorry for all the negative feedback. One problem is that natural language notations for mathematics don't make for a good programming language. For instance, Overhat[x] depends formally on x in the same way f[x] depends formally on x. But I take it that $\hat x$ is the vector $(1,0)$ or $(1,0,0)$ and should be treated formally as independent of $x$. Note also the ambiguity in the definition of $\hat x$, which humans handle with no trouble after they learn the conventions.. $\endgroup$ – Michael E2 Dec 17 '19 at 12:03
  • $\begingroup$ Ok, I understand what y'all are saying. But one question is: what sort of expression may get affected by this. I can't get OverHat[r] to evaluate to anything but what I set using OverHat[r] = 5;. For example OverHat[r] /. r -> 3 still returns 5. Is there a page where I can read more about the details of this sort of thing, I like using underscores and other symbols in MMA to make it look more like math on paper. I can see how this sort of thing could be dangerous. The Notations tutorials don't seem like they're about this sort of thing... but they might be? $\endgroup$ – Tanner Legvold Dec 17 '19 at 20:54
2
$\begingroup$

If you want just work in one coordinate system, then you can do something like this:

enter image description here

If you want to use multiple coordinate charts, then it really depends on what how you want things to behave. But maybe you can find inspiration from this code:

enter image description here

$Assumptions = {{x, y, r, \[Theta]} \[Element] Reals, r > 0};
ForceChart[v_, 1] := 
  v /. {r -> Sqrt[x^2 + y^2], \[Theta] -> ArcTan[x, y]};
ForceChart[v_, 2] := v /. {x -> r Cos[\[Theta]], y -> r Sin[\[Theta]]};
Cartesian[Vector[v_, chart_]] := Vector[ForceChart[v, 1], 1];
Polar[Vector[v_, chart_]] := Vector[ForceChart[v, 2], 2];
Unprotect[Times, Plus, Dot];
Times[a_, Vector[v_, chart_]] := Vector[a v, chart];
Plus[Vector[v1_, chart1_], Vector[v2_, chart2_]] := 
  Module[{ch = Min[chart1, chart2]}, 
   Vector[ForceChart[v1, ch] + ForceChart[v2, ch], ch]];
Dot[Vector[v1_, _], Vector[v2_, _]] := 
  ForceChart[v1, 1].ForceChart[v2, 1];
Protect[Times, Plus, Dot];

\!\(\*OverscriptBox[\(x\), \(^\)]\) = Vector[{ 1, 0}, 1]; 
\!\(\*OverscriptBox[\(y\), \(^\)]\) = Vector[{0, 1}, 1];

\!\(\*OverscriptBox[\(r\), \(^\)]\) = 
 Vector[{ Cos[\[Theta]], Sin[\[Theta]]}, 2]; 
\!\(\*OverscriptBox[\(\[Theta]\), \(^\)]\) = 
 Vector[{-(1/r) Sin[\[Theta]], 1/r Cos[\[Theta]]}, 2];
Format[Vector[v_, 1]] := 
 DisplayForm[
  v[[1]] OverscriptBox["x", "^"] + v[[2]] OverscriptBox["y", "^"]]
Format[Vector[v_, 2]] := 
 Module[{u = ForceChart[v, 2]}, 
  DisplayForm[
   Simplify[u.{Cos[\[Theta]], Sin[\[Theta]]}] OverscriptBox["r", 
      "^"] + Simplify[
      r^2 u.{-(1/r) Sin[\[Theta]], 1/r Cos[\[Theta]]}] OverscriptBox[
      "\[Theta]", "^"]]]
$\endgroup$
  • 1
    $\begingroup$ Please look at the instructions provided here: How to copy code from Mathematica so it looks good on this site and replace your box expressions with readable code. $\endgroup$ – MarcoB Dec 17 '19 at 16:29
  • $\begingroup$ This is great! Thanks so much. I'm still tying to understand it and I have yet to test it myself, but I think I can get by. This is pretty much exactly what I was looking for. I do have one question, in the second block of code you set $\hat{\theta}$ using OverHat[\[Theta]] = Vector[{(-1/r) Sin[\[Theta]] + (1/r) Cos[\[Theta]]}, 2]. What are the (1/r)'s for, I would think that now the unit vector may not have a magnitude of 1. Is there a reason that has to be there for it all to work that I don't understand? $\endgroup$ – Tanner Legvold Dec 17 '19 at 21:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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