Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot solve Ax=b for A using python if there is no unique solution

I am trying to solve a linear system of equations of the form Ax=b where A is a square matrix which is unknown, while the vectors x and b are known. I am interested in a physics problem where my A is a unitary matrix, which rotates a random unit vector x to b which is of the form [1,0,0...0]. One cannot find a unique solution to A. I just need one of the many possible solutions. Since I want to scale it to larger dimensions, I want the computer to solve it.

I tried following the answer to the question in this link , but by A was not unitary.

I am thinking of using cvxpy to give me a solution, and I wrote a code taking the dimension to be three for a start. I don't know if cvxpy is suitable when there is no unique solution. The code is below. It gives an error in the constraint part saying "0-dimensional array given. Array must be at least two-dimensional". I think what I have is a valid representation of a matrix in cvxpy. I am happy to be corrected.

Can someone help me with this problem? If you have another way of doing it, that is also fine.

import numpy as np
import cvxpy as cp
n = 3
alpha=0.01
np.random.seed(1)
b= [1,0,0]
x = np.random.randn(n)+1j*np.random.randn(n)
x=x/np.linalg.norm(x)


#Construct the problem.
A = cp.Variable((n,n),complex=True)
objective = cp.Minimize(cp.sum_squares(A @ x - b))
constraints = [A.H==np.linalg.inv(A)]
prob = cp.Problem(objective, constraints)

# The optimal objective value is returned by `prob.solve()`.
result = prob.solve()
print(A.value)

Traceback:

Traceback (most recent call last):
    File "/Users/sreerampg/untitled1.py", line 22, in <module>     constraints = [A.H==np.linalg.inv(A)]
    File "<__array_function__ internals>", line 6, in inv    File "/Applications/anaconda3/lib/python3.7/site-packages/numpy/linalg/linalg.py", line 539, in inv     _assert_stacked_2d(a)
    File "/Applications/anaconda3/lib/python3.7/site-packages/numpy/linalg/linalg.py", line 197, in _assert_stacked_2d     
    'at least two-dimensional' % a.ndim)  LinAlgError: 0-dimensional array given. Array must be at least two-dimensional
like image 342
sreeram pg Avatar asked Mar 27 '26 22:03

sreeram pg


1 Answers

It seems like you could approach this analytically, since you're looking for a rotation. In 3 dimensions, you could directly construct the rotation matrix by computing the angle between x and b, and the vector perpendicular to both:

import numpy as np
from scipy.spatial.transform import Rotation

def find_rot(a, b):
    a /= np.linalg.norm(a)
    b /= np.linalg.norm(b)
    angle = np.arccos(np.dot(a, b))
    vec = np.cross(a, b)
    return Rotation.from_rotvec(vec * angle / np.linalg.norm(vec))

x = np.random.rand(3)
b = np.array([1., 0., 0.])
A = find_rot(x, b)
print(x, b, A.apply(x), A.as_matrix(), sep='\n')

In higher dimensions it's not as direct since you can't just use the cross product, although there's probably a way to generalize the above using exterior product for which I'd need to brush up on my linear algebra skills more.

Barring that, you can construct a series of "higher dimensional rotation matrices" that successively zero out each dimension, of the form:

[1 . . . . 
 . 1 
 .   1
 .     . 
 .       cosT -sinT
 .       sinT cosT]

Where T is the angle theta between your vector x and the unit vector [0, 0, ...., 1, 0], then repeat moving down one dim at a time. Essentially you "rotate out" your vector from each dimension, then multiply them all together to get your final unitary matrix.

like image 116
tzaman Avatar answered Mar 29 '26 11:03

tzaman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!