Factorization of syms class objects

2 views (last 30 days)
I create Syms class matrices with elements taking a similar structure to this,
a11*(a1*a4*a7 + a2*a5*a9) + a3*a7*a11
I wish to factor each cell in such a way that there is no reptition of variables. In cases such as the above using 'factor' or 'simplify' only removes the common factor 'a11' from the term yielding,
a11*(a3*a7 + a1*a4*a7 + a2*a5*a9).
However, i am looking for 'a7' to also be factored out; thus yielding,
a11*( a7*(a3 + a1*a4) + a2*a5*a9).
I am interested to hear if anyone has an approach for dealing with such a problem.
Regards
Ross
Note: The methods applied to reach the original matrix would never return solutions which could not be factored in such a way that every variable occurs only once in the term.
  2 Comments
Sean de Wolski
Sean de Wolski on 16 Dec 2011
Just a note: Naming a variable a11 is very hard to understand since it looks like all, a very useful builtin function.
ross montgomery
ross montgomery on 16 Dec 2011
Hi Sean,
Yeah, sorry, in hindsight 'a11' is a bad choice to use as an example. Didn't even think about that. My procedure utilises automated variables all (as in A L L ;) ) named 'a' followed by a number. The numbers can often be in the hundreds/thousands, 'a11' was just the first result at hand which displayed the problems simply using simplify/collect brought about.
Thanks for your response Sean.

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 16 Dec 2011
You get the "low-lying fruit" with using factor(), but after that it gets more messy for sure.
The approximate route I can think of at the moment is:
Create a MuPad procedure. In the procedure, if op(0) of the result is _mult then map() the procedure recursively over the expression. When the expression is not _mult then factor() the expression; if the result of that has op(0) of _mult then map() the procedure recursively over the factored expression.
Now if the expression type was not _mult and factor() did not result in a _mult, then use indets() to find the variable names in the expression. If there were no variables then return (this takes care of numeric constants and constants such as Pi and symbolic constants such as tan(Pi/17)). If there were variables, loop over the variables and coeff the current expression with regards to each variable in turn. If the result of the coeff is an expression sequence then nops([TheSequence]) to get the number of items; if the result of the coeff has op(0) of _plus then nops() to get the number of subexpressions; otherwise the count is 1. If all the counts were 1, return -- each variable occurs uniquely. Otherwise, determine the variable that had the largest count out of all the variables (i.e., the variable that occurred most frequently) and collect() the expression with regards to that variable, and then map() the function over the collected expression.
I didn't say it was easy!
  2 Comments
ross montgomery
ross montgomery on 16 Dec 2011
Hi Walter,
Yeah I was hoping there would be an easier solution to this but somewhat knew it would require building quite a complicated procedure. Still, by outlining the method you would adopt you've saved me a good amount of time wandering down fruitless paths (to continue the metaphor).
Thanks for your response.
Regards
Ross
Walter Roberson
Walter Roberson on 16 Dec 2011
I do not have the Symbolic Toolbox myself, so I have not had a chance to work through the "standard tricks" in analyzing expressions. I use Maple, and in Maple I suspect I would probably write this using Maple's subsindets() or evalindets() and use more pattern matching and less recursion; and the counting would be made easier by using Maple's coeffs().
The symbolic packages are pretty big; there is often some obscure way to do things.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!