0

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.

RFS
  • 211
  • 2
  • 9
  • 1
    I'm sorry, but I fail to understand the question. Can you make the question a bit more specific? – xzczd Apr 18 '19 at 03:08
  • 1
    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. – m_goldberg Apr 18 '19 at 04:12
  • 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 – m_goldberg Apr 18 '19 at 04:18
  • 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: https://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. – xzczd Apr 18 '19 at 11:37
  • I have read it, as I've mentioned in my last comment. – xzczd May 31 '19 at 00:20
  • 1
    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. – m_goldberg May 31 '19 at 00:36
  • @m_goldberg I rewrote the question and the answer that I provided. I used the verbiage " the internal form of any symbolic expression" from https://www.wolfram.com/language/elementary-introduction/2nd-ed/33-expressions-and-their-structure.html – RFS May 31 '19 at 01:21

2 Answers2

0

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}} *)

```
MelaGo
  • 8,586
  • 1
  • 11
  • 24
  • 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. – RFS Apr 18 '19 at 07:46
0

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];
   ];
RFS
  • 211
  • 2
  • 9
  • 1
    Try With[{cf = PolynomialGCD @@ f}, Print["f = ", cf," ", f/cf // MatrixForm]] instead. – Somos Apr 18 '19 at 15:56
  • @Somos. Thank you! – RFS May 30 '19 at 20:02
  • @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])} – RFS May 30 '19 at 20:48