4
$\begingroup$

Hi Consider the following expression which contains multiplication by inexact 0

E^(-0.400000000000000 a - 
  4.45401233327988 b) (1.000000000000 E^(
    0.400000000000000 a + 4.45401233327988 b) + 
   0.*10^-13 E^(0.400000000000000 a + 0.172989402425367 b)
     k + (0.*10^-13 + 0.*10^-13 a) E^(0.172989402425367 b)
     k + (0.*10^-13 + 0.*10^-13 a) E^(4.28102293085451 b)
     k + (0.*10^-13 + 0.*10^-13 a) E^(4.50802466655976 b) k + 
   0.*10^-13 E^(0.400000000000000 a + 4.28102293085451 b) k + 
   0.*10^-13 E^(0.400000000000000 a + 4.50802466655976 b) k)

It was produced by

Chop[D[Jf[x, a, b], x] /. x -> b] /. {x_Real /; x == 0 -> 0}

It's hard to give a complete and simple definition of Jf, but I hope that may not be necessary. Suffice to say Chop did not do his job; it would be nice to have some pattern replacement fixup, like /. {x_Real /; x == 0 -> 0} (this did not work, of course, since 0.*10^-13 is not 0). I tried also without success

(D[Jf[x, a, b], x] /. x -> b) /. {0.*10^-13 -> 0}
$\endgroup$
2
  • 4
    $\begingroup$ "Chop did not do his job" - why not adjust the second argument of Chop[], then? Chop[expr, 1.*^-12]. $\endgroup$ Commented May 21, 2020 at 11:31
  • 2
    $\begingroup$ "Chop did not do his job" - nah, you just did not use it correctly; as @J.M said, there is a reason for the second argument of Chop. Note also that Chop will work on your final expression to return 1. Since you did not give us the expression for Jf, we cannot check the original computation. Also, your pattern replacement comparison {x_Real /; x == 0 -> 0} relies on Equal's internal tolerance for numerical expressions: you may need to adjust that to your needs, or at least be aware of that. You could also use PossibleZeroQ. $\endgroup$
    – MarcoB
    Commented May 21, 2020 at 15:52

1 Answer 1

6
$\begingroup$

Check numbers for zero precision and replace with 0.

foo = x + 1234567`3 - 1234567`3
(* 0.*10^3 + x *)
foo /. x_Real /; Precision[x] <= 0. -> 0
(* x *)

Edit:

Another way is to use SetPrecision instead of Chop. That sets zero precision numbers in the expression to exactly zero.

SetPrecision[foo, Infinity]
(* x *)
$\endgroup$
3
  • $\begingroup$ I had already tried Chop[ , ] for some reason, it doesn't work. l will add eventually a simplified complete example :) @John Doty since I do not fully understand "Check numbers for zero precision" I played this by the ear for a while, but unsuccessfully. Last attempt: Assuming[{Element[a, Integers], Element[k, Integers], Element[b, Integers]}, FullSimplify[ D[Jf[x, a, b], x] /. x -> b /. {y_Real /; Precision[y] <= (-12) -> 0}]] $\endgroup$
    – florin
    Commented May 21, 2020 at 12:55
  • 1
    $\begingroup$ A number with zero precision displays as something like 0.*10^3. Its FullForm looks like 0``-3.3925446597502456. Zero precision means that no digits of the number are known. I don't think Precision will ever yield a negative number, so your Precision[y] <= (-12) will never be satisfied. For your problem, Precision[x] <= 0 should work. $\endgroup$
    – John Doty
    Commented May 21, 2020 at 13:05
  • $\begingroup$ Thanks!!!!! SetPrecision[foo, Infinity] has done the job. @MarcoB, for Chop, I had kind of improvement :) switching first the order with FullSimplify mi = Chop[FullSimplify[D[Jf[x, a, b], x] /. x -> b], 1.*^-12] improved the answer to 1.000000000000 E^(0.*10^-16 a + 0.*10^-15 b) and rechopping Chop[mi, 1.*^-12] got it. It's interesting that chopping twice may be needed. Anyway, I'm glad I got your help without needing to explain my function Jf :) $\endgroup$
    – florin
    Commented May 21, 2020 at 16:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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