3

Consider

ArcTan[3, -3]  
(* out: *) -Pi/4  

ArcTan[3 a Sin[t/2], -3 a Sin[t/2]]
(* out: *) ArcTan[3 a Sin[t/2], -3 a Sin[t/2]]  

However, we can fix the second one with some assumptions (where applicable)

$Assumptions = a > 0 && Pi > t > 0  
Refine@ArcTan[3 a Sin[t/2], -3 a Sin[t/2]]
(* out: *) -Pi/4  

I need a way to force mathematica to similarly realize it can cancel units in the ArcTan (which is basically a ratio, except for the sign consideration for the quadrant).

For example, say I now have

$Assumptions = a > 0 && Pi > t > 0   
aa=(4 Pi/(3 Sqrt[3]))(Quantity[1.42, "Angstroms"])^(-1)  
b=(Quantity[5, "Angstroms"])^(-1)
ArcTan[b+3 aa Sin[t/2],-b-3 aa Sin[t/2]]

How can I force Mathematica to recognize that these arguments are just +c and -c and thus the ArcTan significantly reduces?

I wish to avoid removing the units here artificially with QuantityMagnitude[] because elswhere in these expressions the units appear outside of these ArcTan[]s. However, a last ditch solution would be one that simply searched for these ArcTan[] and applied QuantityMagnitude[] to their arguments, I suppose.

Steve
  • 1,153
  • 7
  • 17

4 Answers4

2

This preserves the two argument ArcTan form feature of returning a result in the correct quadrant, as well as handling the x=0 case..

    arctan[x_, y_] /; QuantityUnit[x] == QuantityUnit[y] := 
          ArcTan[ x ,   y] /. QuantityUnit[x] -> 1 ;
    arctan[x_,y_]:=ArcTan[x,y];

    x = Quantity[-2, "Angstrom"];
    y = Quantity[2 Sqrt[3], "Angstrom"];

    arctan[ x ,   y] 

2 Pi/3

    arctan[ 1 ,   1] 

Pi/4

I'm not a fan of modifying intrinsics but you can do it like this:

 newatan = True;
 Unprotect[ArcTan];
 ArcTan[x_, y_] /; newatan && ((quantityunit=QuantityUnit[x]) == 
                                             QuantityUnit[y]) := 
        Block[{newatan = False}, ArcTan[ x ,   y] /. quantityunit -> 1 ];
 Protect[ArcTan];

I notice by the way that Sign recognizes the unit to be positive:

 Sign[x]

-1

It seems an oversight that the built in ArcTan does not..

generalization

I suppose we ought to handle mixed units..

 newatan = True;
 Unprotect[ArcTan];
 ArcTan[x_, y_] /; 
   newatan && ((commonunit = QuantityUnit[UnitConvert[x]]) == 
                             QuantityUnit[UnitConvert[y]]) := 
           Block[{newatan = False}, 
           ArcTan[ UnitConvert[x] , UnitConvert[  y ]] /. commonunit -> 1];
 Protect[ArcTan];
 x = Quantity[2 , "Inches"];
 y = Quantity[2 Sqrt[3] 254/10, "Millimeter"];
 ArcTan[x, y]

Pi/3

george2079
  • 38,913
  • 1
  • 43
  • 110
2

I solved the problem with help and ideas from answers here, primarily inspiration from george2079's answer, by introducing a new function (so as not to alter the underlying definition of ArcTan). In the context of my research, this was actually quite natural, but might be a slight extra step for some.

The solution works for arguments of the same dimension type (length, or time, etc.) and also accounts for the different scales within units of those types (mm vs. m, etc.) Also, the quadrant-sign aspect of the two-argument ArcTan is preserved correctly. Finally, I have written it so that if incommensurate units are attempted, the function returns itself (and the user should be wary that something else is wrong, as such a statement is meaningless).

j[x_, y] /; QuantityUnit@UnitConvert[x] == QuantityUnit@UnitConvert[y] := 
ArcTan[QuantityMagnitude@UnitConvert[x], QuantityMagnitude@UnitConvert[y]]  

then

p = Quantity[3000, "mm"]
q = Quantity[-3, "m"]
z = Quantity[14, "eV"]
j[{3, -3}]
j[{p, q}]
j[{p, z}]  

gives the desired outputs

(* out: *) 3000 mm
(* out: *) -3 m
(* out: *) 14 eV
(* out: *) -Pi/4
(* out: *) -Pi/4
(* out: *) ArcTan[3000 m, 14 eV]
Steve
  • 1,153
  • 7
  • 17
1

You can get this to work by unprotecting ArcTan (or alternately making a wrapper for ArcTan). But, for example:

Unprotect[ArcTan]
ArcTan[common_, y_ common_] := ArcTan[1, y]
ArcTan[x_ common_, common_] := ArcTan[x, 1]
ArcTan[x_ common_, y_ common_] := ArcTan[x, y]
ArcTan[x_ /common_, y_ /common_] := ArcTan[x, y]
ArcTan[Quantity[x_, units_], Quantity[y_, units_]] := ArcTan[x, y]

ArcTan[3 foo, 1 foo]
(* ArcTan[1/3] *)
ArcTan[3/foo, -2 /foo]
(* -ArcTan[2/3] *)
ArcTan[Quantity[-7, "Angstroms"], Quantity[5, "Angstroms"]]
(* \[Pi] - ArcTan[5/7] *)

This doesn't quite get you all the way to evaluating the quantities you're after, because the implemented patterns don't match

FullForm[b + 3 aa Sin[t/2]] (* =  Plus[
    Quantity[Rational[1,5],Power["Angstroms",-1]],
    Times[Quantity[5.10929398375836`, Power["Angstroms",-1]], Sin[Times[Rational[1,2],t]]]] *)

but it's almost there...

evanb
  • 6,026
  • 18
  • 30
1

One simple enough way is to use a rule. For example, like this:

rule = ArcTan[a_, b_] -> ArcTan[b/a];

Then your example is automatically done:

 ArcTan[3 a Sin[t/2], -3 a Sin[t/2]] /. rule

(* -([Pi]/4) *)

This might be combined with something else to transform the resulting ArcTan argument. Compare this:

ArcTan[Log[x^2], -Log[x]] /. rule
(*  -ArcTan[Log[x^2]/Log[x]]  *)

with this:

  ArcTan[Log[x^2], -Log[x]] /. rule // Simplify[#, x > 0] &
(*  -ArcTan[2]  *)

Another example is here:

    ArcTan[Gamma[x + 1], x*Gamma[x]] /. rule

(* ArcTan[Gamma[1 + x]/(x Gamma[x])] *)

which can also be subjected to a simplification:

    ArcTan[Gamma[x + 1], x*Gamma[x]] /. rule // FullSimplify[#, x > 0] &
(*   \[Pi]/4   *)
Alexei Boulbitch
  • 39,397
  • 2
  • 47
  • 96