含平方根、sin、cos的四元非线性方程组求解及NumPy适配难题
Hey there! Let's sort out why your original NumPy approach didn't work, then walk through a solid solution for your system of equations.
First, Why NumPy's linalg.solve Isn't Working
The key issue here is that your system is nonlinear, while numpy.linalg.solve only handles linear systems (where all variables appear to the first power, no trigonometric functions, squares, or products of variables). Your equations include cos(b), sin(d), and a² + c²—these nonlinear terms mean we need a different approach.
Step 1: Simplify by Solving for a and c First
Your last two equations are purely about a and c, so we can solve these separately to reduce variables:
13 = a² + c²
5 = a + c
Substitute c = 5 - a into the first equation:
a² + (5 - a)² = 13 2a² - 10a + 12 = 0 a² - 5a + 6 = 0
This factors to (a-2)(a-3)=0, giving two valid pairs:
a=2, c=3a=3, c=2
These are exactly the pairs in your GeoGebra solution—nice, that's a great starting point!
Step 2: Solve for b and d Using Nonlinear Solvers
With a and c fixed, we're left with a 2-variable nonlinear system for b and d. We can use SciPy's nonlinear equation solvers (like scipy.optimize.root) to find these angles.
Full Code Example
Here's how to implement this in Python:
import numpy as np from scipy.optimize import root # Define the residual function: returns the difference between left and right sides of each equation def equations(x): a, b, c, d = x # Convert angles from degrees to radians (since NumPy uses radians for trig functions) b_rad = np.deg2rad(b) d_rad = np.deg2rad(d) eq1 = a * np.cos(b_rad) + c * np.cos(d_rad) - (np.sqrt(2) + (3/2)*np.sqrt(3)) eq2 = a * np.sin(b_rad) + c * np.sin(d_rad) - (-np.sqrt(2) + 3/2) eq3 = a**2 + c**2 - 13 eq4 = a + c - 5 return [eq1, eq2, eq3, eq4] # Test with initial guesses matching your GeoGebra solutions # Guess 1: a=2, b=-45, c=3, d=30 x0_1 = [2, -45, 3, 30] result_1 = root(equations, x0_1) if result_1.success: a, b, c, d = result_1.x print(f"Solution 1: a={a:.2f}, b={b:.2f}°, c={c:.2f}, d={d:.2f}°") # Guess 2: a=2, b=47.45, c=3, d=-27.55 x0_2 = [2, 47.45, 3, -27.55] result_2 = root(equations, x0_2) if result_2.success: a, b, c, d = result_2.x print(f"Solution 2: a={a:.2f}, b={b:.2f}°, c={c:.2f}, d={d:.2f}°") # Guess 3: a=3, b=30, c=2, d=-45 x0_3 = [3, 30, 2, -45] result_3 = root(equations, x0_3) if result_3.success: a, b, c, d = result_3.x print(f"Solution 3: a={a:.2f}, b={b:.2f}°, c={c:.2f}, d={d:.2f}°") # Guess 4: a=3, b=-27.55, c=2, d=47.45 x0_4 = [3, -27.55, 2, 47.45] result_4 = root(equations, x0_4) if result_4.success: a, b, c, d = result_4.x print(f"Solution 4: a={a:.2f}, b={b:.2f}°, c={c:.2f}, d={d:.2f}°")
Key Notes
- Multiple Solutions: Nonlinear systems often have multiple valid solutions, so you need to test different initial guesses (like the ones from GeoGebra) to find all of them.
- Angle Units: Remember to convert degrees to radians for NumPy's trigonometric functions, then convert back to degrees for the final output if needed.
- Alternative: Simplify Further: You could also split the problem into two separate steps: first solve for
aandcalgebraically (as we did), then write a residual function just forbanddfor eacha/cpair. This makes the solver's job easier and more stable.
内容的提问来源于stack exchange,提问作者KrissKloss

