Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I am running symbolic calculations with Mathematica. Simplification of algebraic expressions is an important part of them as very often final results can be simplified considerably. Typically my expressions involve many variables that can be categorised into few groups. I use to denote a group by a letter, variables within the group are distinguished by an index, e.g. $A_1$, $B_2$, etc. At some point I found out (and tried to discuss it here Simplifying using assumptions) that FullSimplify command best works with variables without any subscripts. In the example below the result of the simplification is cardinally different depending whether I am using plain letters

$-\frac{p}{a+x}+\frac{q}{x-a}+\frac{P}{b+x}+\frac{Q}{b-x}$

or letters with subscripts

$\frac{B_1 \left(a_1+x\right) \left(A_2 \left(a_2-x\right) \left(-a_1+a_2+2 x\right)-\left(a_1-a_2\right) B_2 \left(a_2+x\right)\right)-A_1 \left(a_1-x\right) \left(\left(a_1-a_2\right) A_2 \left(a_2-x\right)+B_2 \left(a_1-a_2+2 x\right) \left(a_2+x\right)\right)}{\left(x-a_1\right) \left(a_1+x\right) \left(a_2-x\right) \left(a_2+x\right)}$.

Clearly, I prefer the first form. Therefore I am using rules to replace indexed variables with plain letters, perform a simplification, and using the rules again to replace plain letters by the original indexed variables. However, it is not very convenient method, also in view of the fact that the number of letters is finite...

Therefore I have a question, is there a way to teach FullSimplify to work as efficiently with indexed variables as it does with the normal ones?

Below are two equivalent expressions. The first one contains only letters

f2 = (-p (a - x) ((a - b) P (b - x) + Q (b + x) (a - b + 2 x)) + q (a + x) (-(a - b) Q (b + x) + P (b - x) (-a + b + 2 x)))/((b - x) (-a + x) (a + x) (b + x));
rule2 = {(p + q) -> 1, (P + Q) -> 1};
FullSimplify[f2] /. rule2

It leads to the first equation. The second one

f1 = ((x + Subscript[a,1]) Subscript[B,1]((-x + Subscript[a, 2])(2 x - Subscript[a,1] + Subscript[a,2]) Subscript[A,2]-(Subscript[a,1]-Subscript[a, 2]) (x + Subscript[a,2]) Subscript[B,2]) - (-x + Subscript[a,1]) Subscript[A,1] ((Subscript[a, 1] - Subscript[a,2]) (-x + Subscript[a,2]) Subscript[A,2] + (2 x + Subscript[a, 1] - Subscript[a, 2]) (x + Subscript[a,2]) Subscript[B,2]))/((x - Subscript[a,1]) (x + Subscript[a,1]) (-x + Subscript[a, 2]) (x + Subscript[a, 2]));
rule1 = {Subscript[A,1] + Subscript[B,1] -> 1, Subscript[A,2] + Subscript[B,2] -> 1};
FullSimplify[f1] /. rule1

Is equivalent to the first one, however, it is returned unsimplified (at least with my version of Mathematica: 9.0.1 for Mac OS X). Two expressions are equivalent as the following command shows

FullSimplify[f1 - f2 /. {Subscript[a,1] -> a, Subscript[a,2] -> b, Subscript[A,1] -> p, Subscript[A,2] -> P, Subscript[B,1] -> q,Subscript[B,2] -> Q}]

Returns 0.

Thank you in advance.

share|improve this question
3  
Why can't you use a1, a2, a3... b1, b2, ..., z1, z2, ... aa1,... ab1...? You have an infinite pool of symbols! –  rm -rf Feb 3 at 16:34
    
How to define an order relation on your set? –  yarchik Feb 4 at 9:23
    
There seems to be a sort of side-question (which @rm-rf may want to weigh in on) where you want to use subscripts in "looping constructs" and to make things "visually appealing". For the latter, you can convert at the end to whatever presentation you want. For the former, it might be better to use things like a[1], a[2],... but maybe this is worthy of a search and possibly a separate question about the best way to handle indices for the looping constructs you have in mind. –  Mark S. Feb 5 at 4:15
    
@ Mark S. Well, have you tried before suggesting? "Things like a[1], a[2], ... " do not work either ... A suggestion of rm -rf does work, but, as I said, additional work must be invested in implementing looping with these variables. I do not say that suggestion rm -rf is not a plausible solution: It is just preaching instead of answering a precisely formulated question. –  yarchik Feb 5 at 10:03

3 Answers 3

up vote 1 down vote accepted

I agree with point 5 of Verbeia's answer to the canonical Q&A, i.e. you should avoid subscripted variables. One solution here might be to automatically convert "subscript Symbols" to regular symbols and to convert them back after having using FullSimplify. The function below does this.

fullSimplify[expr_] :=
 Module[
  {uqString, counter, definedQ, toMapper, backRules, symb, simpExpr, 
   bla},

  backRules = {};
  definedQ[x__] := False;
  uqString = ToString[Unique[bla]];
  counter = 0;
  Block[
   {Subscript},

   Subscript[x__] := 
    (
     If[
      definedQ[x]
      ,
      toMapper[x]
      ,
      definedQ[x] = True;
      symb = Symbol[uqString <> ToString[counter]];
      counter++;
      AppendTo[
       backRules,
       symb :> Subscript[x]
       ];
      toMapper[x] = symb
      ]
     );
   simpExpr =
    FullSimplify[
     expr
     ];
   ];
  Remove[toMapper, definedQ];
  simpExpr /. backRules

  ]

Now

fullSimplify[f1] /. rule1

gives

enter image description here

Notes

It is better to use a linkedlist than to use a regular list with AppendTo

The variables from Module will leak unless they are removed.

share|improve this answer
    
This answers my question although it does not improve my understanding of inner mechanisms of Mathematica. I am not making any assignments to the subscripted variables. Should not they have all the properties of complex numbers? It is hard for me to accept your recommendation of completely avoiding subscripted variables: they are very useful in looping constructs. –  yarchik Feb 4 at 9:20
    
@yarchik I am not sure why the same simplification is not made. You should know the measure for simplicity used by FullSimplify is LeafCount. The LeafCount of a subscripted variable is different than that of a normal Symbol, so this may cause different behaviour. I do not really understand your comment about looking constructs, could you elaborate? –  Jacob Akkerboom Feb 4 at 11:13
    
@yarchik If you think this is bad, have you seen Variable naming changes everything? Even a choice of a different letter changes behavior in other contexts. –  Mark S. Feb 5 at 4:10
    
@Mark S. I haven't seen this discussion before, but now I am amazed... –  yarchik Feb 5 at 9:11
    
@Jacob Akkerboom I have tried to follow your suggestion and used a different complexity function that disregards Subscripts: comp[e_] := -2 Count[e, _Subscript, {0,Infinity}] + LeafCount[e] However, it does not help. –  yarchik Feb 5 at 10:33

If you follow rm -rf advice, everything goes smoothly:

expr = 
  (-A1 (a1 - x) ((a1 - a2) A2 (a2 - x) + B2 (a2 + x) (a1 - a2 + 2 x)) + 
    B1 (a1 + x) (-(a1 - a2) B2 (a2 + x) + A2 (a2 - x) (-a1 + a2 + 2 x))) /
  ((a2 - x) (-a1 + x) (a1 + x) (a2 + x));
rule = {A1 + B1 -> 1, A2 + B2 -> 1};
FullSimplify[expr] /. rule

result.png

share|improve this answer
    
Well, I cannot accept this answer simply because it does not answer the question: there are many cases when subscripts are useful and to work with your variables is pretty inconvenient. Second, visually it is less appealing. –  yarchik Feb 4 at 9:15
1  
@yarchik As with everything, there's a trade off and you need to make a decision — do you want to obtain the solution (without additional effort) or do you want something that is simply visually appealing? You might find a solution to this problem, but using subscripts heavily is almost sure to end in tears. –  rm -rf Feb 4 at 15:07

Symbolizing subscripts before running your code also works.

<< Notation`
Symbolize[
ParsedBoxWrapper[
SubscriptBox["_", "_"]]]
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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