0
$\begingroup$

Could someone provide code for looping through the internal form for a symbolic expression?

Specifically I am looking to write my own code for simplifying expressions (such as removing a common factor from a vector or matrix) by parsing the internal form of the expression. I am not satisfied with the results that PolynomialGCD gives.

$\endgroup$
7
  • 1
    $\begingroup$ I'm sorry, but I fail to understand the question. Can you make the question a bit more specific? $\endgroup$
    – xzczd
    Commented Apr 18, 2019 at 3:08
  • 1
    $\begingroup$ Any looping you do on an expression is done in a kernel, which always works with the full form of the expression. Any other form is strictly for display. $\endgroup$
    – m_goldberg
    Commented Apr 18, 2019 at 4:12
  • $\begingroup$ I'm voting to close this question as off-topic because the OP is does not understand the simple fact that a Mathematica kernel only works on the full form of a Mathematica expression $\endgroup$
    – m_goldberg
    Commented Apr 18, 2019 at 4:18
  • $\begingroup$ According to the answer below, you do misunderstand the usage of FullForm in Mathematica. In short, there's just no need to use FullForm in your code. You may want to read the following post: mathematica.stackexchange.com/q/3098/1871 Notice the behaviors of FullForm and MatrixForm are similar here: they just influence the appearance of expression in the notebook. $\endgroup$
    – xzczd
    Commented Apr 18, 2019 at 11:37
  • 1
    $\begingroup$ I also have read your answer and I agree with @xzczd that it shows you fail to be aware that looping over any expression is looping over its full form because that the only form the kernel doing the looping receives from the front-end. $\endgroup$
    – m_goldberg
    Commented May 31, 2019 at 0:36

2 Answers 2

0
$\begingroup$

Something like this might be fun for looking at the FullForm structure:

ff = FullForm[x/Sqrt[5] + y^2 + 1/z] (* example from MMA help *)

(* Plus[1,Times[Power[5,Rational[-1,2]],x],Power[y,2]] *)

t[f_, tree_] := Module[{},
  If[Length[f] == 0, Return[tree],
   Table[(f[[0]] // FullForm) ->
     If[Length[f[[n]]] == 0, f[[n]] // FullForm, t[f[[n]], tree]],
    {n, 1, Length[f]}]]]

t[ff[[1]], {}]

(* {Plus->1,Plus->{Times->{Power->5,Power->Rational[-1,2]},Times->x},Plus->{Power->y,Power->2}} *)

```
$\endgroup$
1
  • $\begingroup$ Thank you for the code. I will look it over. I would uptick your answer but my score is too low and I am not yet allowed to do so. $\endgroup$
    – RFS
    Commented Apr 18, 2019 at 7:46
0
$\begingroup$

Here is what I came up with to remove a common factor from a vector/list/matrix. It works better than PolynomialGCD.

First I give an example of usage.

f = {((1 + g)*r^(-1 + g))/E^(r*\[Kappa]), 
   0, (I*r^(-2 + g)*z*\[Alpha])/
    E^(r*\[Kappa]), (I*r^(-2 + g)*(x + I*y)*\[Alpha])/E^(r*\[Kappa])};
Print["ORIGINAL f = ", f // MatrixForm];
With[{cf = PolynomialGCD @@ f}, 
  Print["SIMPLIFIED WITH PolynomialGCD: ", cf, " ", 
   f/cf // MatrixForm]];
PrintRCF["SIMPLIFIED WITH BESPOKE CODE BELOW = ", 
  RemoveCommonFactor[f], ""];

HERE IS THE OUTPUT enter image description here

Here is the code

RemoveCommonFactor[myexpr_] :=
  Module [{leafcount, atoms, factor, newExpr, Nfactors, depth},
   factor = 1;
   Nfactors = 0;
   newExpr = Simplify[myexpr];
   depth = Depth[newExpr];
   leafcount = LeafCount[newExpr];
   atoms = Union[Flatten[Level[newExpr, 3]]];
   Do[
    Module[ {atom, temp, lc},
     atom = atoms[[i]];
     If[! (atom === 0), (
       temp = Simplify[newExpr/atom];
       lc = LeafCount[temp] +  LeafCount[atom] ;
       If[lc < LeafCount[newExpr] + 1, (
         factor = factor * atom;
         Nfactors = Nfactors + 1;
         newExpr = temp;
         ),
        null
        ];
       )
      ];
     ],
    {i, 1, Length[atoms]}
    ];
   {Nfactors, factor, newExpr}
   ];


PrintRCF[headstr_, rcf_, footstr_] :=
  Module[{Nfactors, myfactor, expr},
   Nfactors = rcf[[1]];
   myfactor = rcf[[2]];
   expr = rcf[[3]];
   If[Nfactors > 0,
    (
     Print[headstr, myfactor, " ", expr // MatrixForm, footstr]
     ),
    (
     Print[headstr, expr // MatrixForm, footstr];
     )
    ];
   Return[null];
   ];
$\endgroup$
3
  • 1
    $\begingroup$ Try With[{cf = PolynomialGCD @@ f}, Print["f = ", cf," ", f/cf // MatrixForm]] instead. $\endgroup$
    – Somos
    Commented Apr 18, 2019 at 15:56
  • $\begingroup$ @Somos. Thank you! $\endgroup$
    – RFS
    Commented May 30, 2019 at 20:02
  • $\begingroup$ @Somos Although your code is immensely simpler, my code gives nicer results for a lot of expressions. An example to try is {((1 + g)*r^(-1 + g))/E^(r*\[Kappa]), 0, (I*r^(-2 + g)*z*\[Alpha])/E^(r*\[Kappa]), (I*r^(-2 + g)*(x + I*y)*\[Alpha])/E^(r*\[Kappa])} $\endgroup$
    – RFS
    Commented May 30, 2019 at 20:48

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