Skip to main content
added 22 characters in body
Source Link
march
  • 24.2k
  • 2
  • 46
  • 102

In my calculations I often end up with large expressions that contain a lot of terms like $\sqrt{a^2}$, where I know that $a>0$ is always satisfied.

I know that Mathematica won't simplify such expressions by default (which is good), since $a$ could be complex. I also know that one can use Simplify with Assumptions or PowerExpand to get rid of the square roots.

The issue is that my expressions can be potentially very large, so applying Simplify or PowerExpand in the intermediate steps is not really an option. It just costs too much time...

Consider for example

exp = Sum[coeff[i] Sqrt[ab^2], {i, 1, 20000}];
AbsoluteTiming[PowerExpand[exp];]

On my machine PowerExpand requires 7.7 seconds to get rid of the square roots, which is painfully slow.

Now I can use the dirty trick

Unprotect[Power];
Power[Power[ab, 2], Rational[1, 2]] = ab;
Protect[Power];

and with

AbsoluteTiming[exp2 = exp;]
exp2[[1 ;; 10]]

the square roots are all gone in less than 0.05 seconds.

Of course, I know that it is almost always a bad idea to redefine system functions, but in this particular case I just cannot come up with any good alternative.

One possible solution is to do something like

AbsoluteTiming[
 sqrts = Cases[exp, Power[_, _Rational], Infinity] //DeleteDuplicates // Sort;
 sqrtsSimp = PowerExpand /@ sqrts;
 repRule = Thread[Rule[sqrts, sqrtsSimp]];
 exp2 = exp /. repRule;
]

This seems to be almost as fast as the dirty trick, but the disadvantage is that I have to explicitly apply it to my expressions (possibly after each subsequent evaluation). With redefined Power, however, the simplification is done automatically, so I know that I don't have to bother about square roots at all.

I wonder if there are better solutions to my problem? It may well be that I'm missing some obvious tricks to deal with such things.

In my calculations I often end up with large expressions that contain a lot of terms like $\sqrt{a^2}$, where I know that $a>0$ is always satisfied.

I know that Mathematica won't simplify such expressions by default (which is good), since $a$ could be complex. I also know that one can use Simplify with Assumptions or PowerExpand to get rid of the square roots.

The issue is that my expressions can be potentially very large, so applying Simplify or PowerExpand in the intermediate steps is not really an option. It just costs too much time...

Consider for example

exp = Sum[coeff[i] Sqrt[ab^2], {i, 1, 20000}];
AbsoluteTiming[PowerExpand[exp];]

On my machine PowerExpand requires 7.7 seconds to get rid of the square roots, which is painfully slow.

Now I can use the dirty trick

Unprotect[Power];
Power[Power[ab, 2], Rational[1, 2]] = ab;
Protect[Power];

and with

AbsoluteTiming[exp2 = exp;]
exp2[[1 ;; 10]]

the square roots are all gone in less than 0.05 seconds.

Of course, I know that it is almost always a bad idea to redefine system functions, but in this particular case I just cannot come up with any good alternative.

One possible solution is to do something like

AbsoluteTiming[
 sqrts = Cases[exp, Power[_, _Rational], Infinity] //DeleteDuplicates // Sort;
 sqrtsSimp = PowerExpand /@ sqrts;
 repRule = Thread[Rule[sqrts, sqrtsSimp]];
 exp2 = exp /. repRule;
]

This seems to be almost as fast as the dirty trick, but the disadvantage is that I have to explicitly apply it to my expressions (possibly after each subsequent evaluation). With redefined Power, however, the simplification is done automatically, so I know that I don't have to bother about square roots at all.

I wonder if there are better solutions to my problem? It may well be that I'm missing some obvious tricks to deal with such things.

In my calculations I often end up with large expressions that contain a lot of terms like $\sqrt{a^2}$, where I know that $a>0$ is always satisfied.

I know that Mathematica won't simplify such expressions by default (which is good), since $a$ could be complex. I also know that one can use Simplify with Assumptions or PowerExpand to get rid of the square roots.

The issue is that my expressions can be potentially very large, so applying Simplify or PowerExpand in the intermediate steps is not really an option. It just costs too much time...

Consider for example

exp = Sum[coeff[i] Sqrt[ab^2], {i, 1, 20000}];
AbsoluteTiming[PowerExpand[exp];]

On my machine PowerExpand requires 7.7 seconds to get rid of the square roots, which is painfully slow.

Now I can use the dirty trick

Unprotect[Power];
Power[Power[ab, 2], Rational[1, 2]] = ab;
Protect[Power];

and with

AbsoluteTiming[exp2 = exp;]
exp2[[1 ;; 10]]

the square roots are all gone in less than 0.05 seconds.

Of course, I know that it is almost always a bad idea to redefine system functions, but in this particular case I just cannot come up with any good alternative.

One possible solution is to do something like

AbsoluteTiming[
 sqrts = Cases[exp, Power[_, _Rational], Infinity] //DeleteDuplicates // Sort;
 sqrtsSimp = PowerExpand /@ sqrts;
 repRule = Thread[Rule[sqrts, sqrtsSimp]];
 exp2 = exp /. repRule;
]

This seems to be almost as fast as the dirty trick, but the disadvantage is that I have to explicitly apply it to my expressions (possibly after each subsequent evaluation). With redefined Power, however, the simplification is done automatically, so I know that I don't have to bother about square roots at all.

I wonder if there are better solutions to my problem? It may well be that I'm missing some obvious tricks to deal with such things.

Source Link
vsht
  • 3.6k
  • 14
  • 23

What is the fastest way to simplify $\sqrt{a^2}$ for $a>0$

In my calculations I often end up with large expressions that contain a lot of terms like $\sqrt{a^2}$, where I know that $a>0$ is always satisfied.

I know that Mathematica won't simplify such expressions by default (which is good), since $a$ could be complex. I also know that one can use Simplify with Assumptions or PowerExpand to get rid of the square roots.

The issue is that my expressions can be potentially very large, so applying Simplify or PowerExpand in the intermediate steps is not really an option. It just costs too much time...

Consider for example

exp = Sum[coeff[i] Sqrt[ab^2], {i, 1, 20000}];
AbsoluteTiming[PowerExpand[exp];]

On my machine PowerExpand requires 7.7 seconds to get rid of the square roots, which is painfully slow.

Now I can use the dirty trick

Unprotect[Power];
Power[Power[ab, 2], Rational[1, 2]] = ab;
Protect[Power];

and with

AbsoluteTiming[exp2 = exp;]
exp2[[1 ;; 10]]

the square roots are all gone in less than 0.05 seconds.

Of course, I know that it is almost always a bad idea to redefine system functions, but in this particular case I just cannot come up with any good alternative.

One possible solution is to do something like

AbsoluteTiming[
 sqrts = Cases[exp, Power[_, _Rational], Infinity] //DeleteDuplicates // Sort;
 sqrtsSimp = PowerExpand /@ sqrts;
 repRule = Thread[Rule[sqrts, sqrtsSimp]];
 exp2 = exp /. repRule;
]

This seems to be almost as fast as the dirty trick, but the disadvantage is that I have to explicitly apply it to my expressions (possibly after each subsequent evaluation). With redefined Power, however, the simplification is done automatically, so I know that I don't have to bother about square roots at all.

I wonder if there are better solutions to my problem? It may well be that I'm missing some obvious tricks to deal with such things.