4

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}
florin
  • 1,798
  • 7
  • 12
  • 4
    "Chop did not do his job" - why not adjust the second argument of Chop[], then? Chop[expr, 1.*^-12]. – J. M.'s missing motivation May 21 '20 at 11:31
  • 2
    "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. – MarcoB May 21 '20 at 15:52

1 Answers1

6

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 *)
John Doty
  • 13,712
  • 1
  • 22
  • 42
  • 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}]] – florin May 21 '20 at 12:55
  • 1
    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. – John Doty May 21 '20 at 13:05
  • 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 :) – florin May 21 '20 at 16:31