# Loosen tolerances to get a solution from NSolve for trig system

This is more an exercise in learning Mathematica than a real issue because the solution for me is just to solve half of the system.

I have a simple system of trig equations and can't solve the angle, presumably because it can't find a solution with the numerical precision available.

m = Quantity[6, "Kilograms"];
θ = 38 Degree;
v1 = Quantity[13, ("Meters")/("Seconds")] {-1, 0};
v2 = Quantity[25, ("Meters")/("Seconds")] {Cos[θ],
Sin[θ]};
t = Quantity[3, "Seconds"];
L1 = m v1;
L2 = m v2;
ΔL = L2 - L1;
F = Norm[ΔL]/t // UnitSimplify // N
i = t F {Cos[ϕ], Sin[ϕ]};
L1 + i == L2 // UnitSimplify // Reduce // NSolve[#, ϕ] & (* no solution *)


This definitely could find a solution if I knew how to let it relax

L1 + i == L2 // Reduce
Cos[ϕ] == 0.904785 && Sin[ϕ] == 0.425869

ArcCos[0.9047848529545457] // Sin
0.425869


I tried fiddling with the WorkingPrecision in NSolve to no avail. I also tried adding an inequality to constrain the angle and constrained it to Reals.

If it's not possible to get an answer straight out like this, how do I separate the output from Reduce and run NSolve on only one of the equations (as I've done manually here)? I know how to do this when Solve gives a list of solutions, but not with the boolean equation from Reduce.

Cheers

Clear["Global*"]

m = Quantity[6, "Kilograms"];
θ = 38 Degree;
v1 = Quantity[13, ("Meters")/("Seconds")] {-1, 0};
v2 = Quantity[25, ("Meters")/("Seconds")] AngleVector[θ];
t = Quantity[3, "Seconds"];
L1 = m v1;
L2 = m v2;
ΔL = L2 - L1;
F = Norm[ΔL]/t // UnitSimplify;
i = t F AngleVector[θ];

sol = (L1 + i == L2 // UnitSimplify // Reduce) && 0 <= ϕ < 2 Pi //
Solve[#, ϕ][] & // Simplify

(* {ϕ ->
ArcCos[(13 + 25 Cos[38 °])/Sqrt[794 + 650 Cos[38 °]]]} *)

soln = sol // N

(* {ϕ -> 0.439922} *)


Edit:

Another answer introduced me to AngleVector[θ] in place of {Cos[θ],Sin[θ]} so I'm including that here.

• Yes! All I needed to do is remove the numeric conversion before Solve, and now using the domain restriction works. Thank you! – Matt Murphy May 2 at 3:42

This is yet another case where the Weierstrass substitution is useful:

With[{m = Quantity[6, "Kilograms"], θ = 38 °,
v1 = Quantity[13, ("Meters")/("Seconds")] {-1, 0},
t = Quantity[3, "Seconds"]},
v2 = Quantity[25, ("Meters")/("Seconds")] AngleVector[θ];
L1 = m v1; L2 = m v2; ΔL = L2 - L1;
F = Norm[ΔL]/t // UnitSimplify // N;
i = t F AngleVector[ϕ] /. ϕ -> 2 ArcTan[ff] // TrigExpand;
2 ArcTan[ff] /. First[NSolve[UnitSimplify /@ L1 + i == L2, ff]]]

0.4399220723025391


eq = L1 + i - L2 == 0 // UnitSimplify // Reduce;
(* Cos[\[Phi]] == 0.904785 && Sin[\[Phi]] == 0.425869 *)


Transform the equation into a minimization problem:

cost = (eq[[#, 2]] - eq[[#, 1]])^2 & /@ {1, 2} // Total
(* (0.904785 - Cos[\[Phi]])^2 + (0.425869 - Sin[\[Phi]])^2 *)


Note that eq[[i]] returns the $$i$$-th equation, and eq[[i,1]] its LHS.

Solve it:

NMinimize[cost, \[Phi]]
(* {0., {\[Phi] -> 0.439922}} *)