# Transform a Matrix as an expression

If I have a matrix that I know it can be written as (xi.xi)*KroneckerProduct(H,xi), where xi and H are vectors. Is there a way to obtain this expression from a given matrix?

You can find $$H$$ as the only right eigenvector that is not in the nullspace, and $$\xi$$ as the only left eigenvector that is not in the nullspace:

SeedRandom[1234];
n = 5;
H = RandomVariate[NormalDistribution[], n];
ξ = RandomVariate[NormalDistribution[], n];
M = (ξ.ξ) * KroneckerProduct[H, ξ];


Find the right-eigenvector $$H_n$$ associated with the largest (the only non-zero) eigenvalue:

Hn = MaximalBy[Transpose[Eigensystem[M]], Abs@*First][[1, 2]]
(*    {0.144727, 0.0201009, 0.453794, -0.43748, -0.762452}    *)


Find the left-eigenvector $$\xi_n$$ associated with the largest (the only non-zero) eigenvalue:

ξn = MaximalBy[Transpose[Eigensystem[Transpose[M]]], Abs@*First][[1, 2]]
(*    {-0.545246, 0.071208, 0.051889, -0.833442, 0.0178092}    *)


$$H_n$$ is proportional to $$H$$, and $$\xi_n$$ is proportional to $$\xi$$:

Hn/H
(*    {-0.284707, -0.284707, -0.284707, -0.284707, -0.284707}    *)

ξn/ξ
(*    {0.49814, 0.49814, 0.49814, 0.49814, 0.49814}    *)


Scale $$\xi_n$$ so that the original equation is satisfied:

ξξ = ξn * Surd[Tr[M]/Tr[KroneckerProduct[Hn, ξn]], 3];


Now $$\xi\xi$$ and $$H_n$$ are solutions to your problem:

M == (ξξ.ξξ) * KroneckerProduct[Hn, ξξ]
(*    True    *)


There are many other ways of scaling these vectors. I've chosen the one where $$H_n$$ is normalized and $$\xi\xi$$ is scaled to match; other choices are possible, for example keeping $$\xi_n$$ normalized and scaling $$H_n$$ to match:

HH = Hn * Tr[M]/Tr[KroneckerProduct[Hn, ξn]];
M == (ξn.ξn) * KroneckerProduct[HH, ξn]
(*    True    *)

Clear["Global*"]


Generate a test matrix mat

n = 5;

SeedRandom[1234];

HH = RandomReal[10, n];

X = RandomReal[1, n];

mat = (X . X)*KroneckerProduct[HH, X];


For a given mat, solve for xi and H

xi = Array[x, n];

H = Array[h, n];

sol = NMinimize[
Total[(Flatten[(xi . xi)*KroneckerProduct[H, xi]] -
Flatten[Rationalize[mat, 0]])^2], Flatten[{xi, H}],
WorkingPrecision -> 20][[2]] /. v_Real :> N[v]

(*{x[1] -> 2.05585, x[2] -> 1.20557, x[3] -> 1.06273, x[4] -> 0.543965,
x[5] -> 1.68477, h[1] -> 0.804353, h[2] -> 0.478941, h[3] -> 0.0791164,
h[4] -> 0.346763, h[5] -> 0.0106848} *)


Verifying,

mat == ((xi . xi)*KroneckerProduct[H, xi] /. sol)

(* True *)


Then

xi /. sol

(* {2.05585, 1.20557, 1.06273, 0.543965, 1.68477} *)

H /. sol

(* {0.804353, 0.478941, 0.0791164, 0.346763, 0.0106848} *)
`