On Mon, 2 Jun 2025 at 14:26, Leon Deligny via NumPy-Discussion
<numpy-discussion@python.org> wrote:
>
> ### Proposed new feature or change:
>
> Motivations: This is specific to 3D vector algebra. In Fluid Dynamics, we 
> have access to the moment of a force at a specific point (M_P = OP \cross F). 
> This calculation is crucial when determining the center of pressure (CoP), a 
> pivotal concept for understanding the distribution of forces on an object 
> submerged in a fluid. To accurately pinpoint the CoP, we often need to 
> "reverse" this process, effectively requiring an inverse functionality for 
> the cross product.
>
> How to compute the right-inverse: Given two real numbers a and c we want to 
> find b such that c = a \cross b . If we write this equation in matrix format 
> then we need to define:
>
> ```latex
> A = \begin{pmatrix}
> 0 & -a_3 & a_2 \\
> a_3 & 0 & -a_1 \\
> -a_2 & a_1 & 0
> \end{pmatrix}
> ```
>
> to get $c = A \cdot b$ (where $\cdot$ is the matrix multiplication). In real 
> case scenarios there does not exist a vector b such that $c = A \cdot b$. So 
> we can always find a vector b such that $|c - A \cdot b|_2^2$ is minimal 
> (i.e. b is the best approximation $c \approx A \cdot b$).

The pseudo inverse of a skew symmetric 3x3 matrix like this is
proportional to itself. Here is a demonstration using sympy:

In [129]: x, y, z = symbols('x, y, z', real=True)

In [130]: M = Matrix([[0, -z, y], [z, 0, -x], [-y, x, 0]])

In [131]: print(M)
Matrix([[0, -z, y], [z, 0, -x], [-y, x, 0]])

In [132]: print(simplify(M.pinv()*(-x**2 - y**2 - z**2)))
Matrix([[0, -z, y], [z, 0, -x], [-y, x, 0]])

Given the matrix A then your least squares solution computed using numpy is:

In [133]: (A @ c) / ((A**2).sum() / -2)
Out[133]: array([-0.93244529,  0.74775365,  1.09117371])

That matches what Robert showed with lstsq:

In [134]: np.linalg.lstsq(A, c)[0]
Out[134]: array([-0.93244529,  0.74775365,  1.09117371])

Note that ((A**2).sum() / -2) is just -|a|^2 so if a is a unit vector
then this part can be simplified.

In vectors the minimum norm solution for b in a x b = c is just bhat =
(c x a) / |a|^2 so the cross product computes its own "inverse":

In [135]: np.cross(c, a) / (a**2).sum()
Out[135]: array([-0.93244529,  0.74775365,  1.09117371])

--
Oscar
_______________________________________________
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3//lists/numpy-discussion.python.org
Member address: arch...@mail-archive.com

Reply via email to