2
$\begingroup$

Consider the following expression:

a1 b1 c1 + a4 b2 c1 + a7 b3 c1 + a2 b1 c2 + a5 b2 c2 + a8 b3 c2 + 
 a3 b1 c3 + a6 b2 c3 + a9 b3 c3

Can Mathematica convert it smarter into the product of a row vector, a 3*3 matrix, and a column vector?

Edited:

ex = a1^2 w1 + a1 a2 w2 + a1 a3 w3 + a1 a4 w4 + a1 a2 x1 + a2^2 x2 + 
   a2 a3 x3^2 + a2 a4 x4^3 + a1 a3 y1 + a2 a3 y2 + a3^2 y3^4 + 
   a3 a4 y4 + a1 a4 z1 + a2 a4 z2 + a3 a4 z3^2 + a4^2 z5;

Now, the matrices should be 4*4.

$\endgroup$
2
  • $\begingroup$ putting higher powers terms like a^2 and y3^4 and so on might make it not possible to solve as there will be many different possibilities now. I mean a a^2 a gives a^4 and a a^3 and so on. I mean there is now many different ways to generate possible solutions (if there is any) because of this. $\endgroup$
    – Nasser
    Commented May 25 at 0:22
  • $\begingroup$ @Nasser: I don't think the higher powers are any issue. The code even does not work for the linear power of a's for the 4*4 arrays. Please try without power terms. $\endgroup$
    – SciJewel
    Commented May 25 at 9:35

3 Answers 3

4
$\begingroup$

I think CoefficientArrays is what you are after.

I start by putting in your expression and defining two vectors of coefficients.

ex = a1  b1  c1 + a4  b2  c1 + a7  b3  c1 + a2  b1  c2 + a5  b2  c2 + 
a8  b3  c2 + a3  b1  c3 + a6  b2  c3 + a9  b3  c3;
vec1 = {b1, b2, b3};
vec2 = {c1, c2, c3};

Next we apply CoefficientArrays. You could include a right hand side in your expression which in this case will turn out to be zero.

{rhs1, mat1} = CoefficientArrays[ex, vec1] // Normal;
 mat1 // MatrixForm

enter image description here

This has pulled out the b vector. Now to pull out the c vector we go again.

{rhs2, mat2} = CoefficientArrays[mat, vec2] // Normal;

enter image description here

Finally we check that the matrices formed are the same as the original expressioin.

ex2 = (mat2 . vec2) . vec1;
 ex == ex2 // Simplify

True

So I hope this is what you wanted.

$\endgroup$
1
  • $\begingroup$ Please check the edited. Your answer works for the 3*3 case, but not for the 4*4 or any general case. $\endgroup$
    – SciJewel
    Commented May 24 at 14:28
2
$\begingroup$
expr = a1  b1  c1 + a4  b2  c1 + a7  b3  c1 + a2  b1  c2 + 
  a5  b2  c2 + a8  b3  c2 + a3  b1  c3 + a6  b2  c3 + a9  b3  c3

n = 3; (*number of symbols in each term*)
expr2 = List @@ expr
A = expr2[[1 ;; 3, 2]]
B = Union@expr2[[;; , 3]]
M = ArrayReshape[expr2[[;; , 1]], {n, n}]
(MatrixForm[M] . MatrixForm[A]) . MatrixForm[B]

enter image description here

 Expand[(M . A) . B]
 a1 b1 c1 + a4 b2 c1 + a7 b3 c1 + a2 b1 c2 + a5 b2 c2 + a8 b3 c2 + 
  a3 b1 c3 + a6 b2 c3 + a9 b3 c3

Check

Expand[(M . A) . B] === expr
(*True*)
$\endgroup$
4
  • $\begingroup$ First, please explain each step, eg List@@, ;;, Array Reshape. 2nd, vector A should be in a row on the left, looking like: A.M.B. $\endgroup$
    – SciJewel
    Commented May 24 at 13:32
  • $\begingroup$ Could you try the edited example? You answer does not work for the 4*4 operation with different symbols in each term. $\endgroup$
    – SciJewel
    Commented May 24 at 14:33
  • $\begingroup$ @SciJewel I used the same format as Hugh to reduce confusion. He used (mat2 . vec2) . vec1; and that is what I used. Other permutation might not lead to an answer. Will check. The way I did this is by reverse engineering. I made generic matrix and generic two vectors and multiplied them as above, and by looking at result, found the what each should be given the input you had. i.e. found mapping between the input and the generic output. $\endgroup$
    – Nasser
    Commented May 24 at 21:19
  • $\begingroup$ Ok thanks! Could you also try the edited example? Your code doesn't work on this example. $\endgroup$
    – SciJewel
    Commented May 24 at 22:06
1
$\begingroup$

In your case solution seems don't exist. One could try it as follows.

input = a1  b1  c1 + a4  b2  c1 + a7  b3  c1 + a2  b1  c2 + 
   a5  b2  c2 + a8  b3  c2 + a3  b1  c3 + a6  b2  c3 + a9  b3  c3;

formalExpression = (a /@ Range[3]) . 
   Partition[c /@ Range[3*3], 3] . (b /@ Range[3]) // Expand

vars = Variables[input]
SolveAlways[formalExpression == input, vars]
(* {} *)

With some of variables omitted solution can be found. For example,

SolveAlways[formalExpression == input, 
 Flatten[{vars[[1 ;; 2]], vars[[4 ;; 8]], vars[[10 ;; 12]], 
   vars[[14 ;; 15]]}]]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.