Repository navigation
Description
limit answers 1 for z / abs(z) and z ^ 2 / abs(z) ^ 2 whatever the phase of z, and the
answer is wrong wherever that phase is not real and positive.
limit((i/x)/abs(i/x), x, +oo) -> 1 true value: i
limit((i/x)^2/abs(i/x)^2, x, +oo) -> 1 true value: -1
limit(((1+i)/x)^2/abs((1+i)/x)^2, x, +oo) -> 1 true value: i
Checking the first by hand: for real x → +oo, i/x is a positive imaginary number and
abs(i/x) = 1/x, so the quotient is i at every x and its limit is i. The second: (i/x)^2 is
-1/x^2 while abs(i/x)^2 is 1/x^2, so the quotient is -1 everywhere. The third: (1+i)^2 = 2i
and abs(1+i)^2 = 2, so the quotient is i everywhere. None of the three is a limit that needs
taking — the expression is constant in x.
Simplify is not at fault
"x ^ 2 / abs(x) ^ 2".Simplify() -> (x / abs(x)) ^ 2 at x = i: -1, correctly
"abs(x) ^ 2".Simplify() -> abs(x) ^ 2 at x = i: 1, correctly
So the simplifier keeps the phase and evaluates correctly. It is the limit machinery that discards
it — Absf's limit is computed as abs(<limit of the argument>), which is true for a real path and
loses the argument's direction otherwise.
The same cause, without an i in the input
limit(x ^ 2 / abs(x) ^ 2, x, 0) -> 1
The default codomain is Complex, and along the imaginary axis x = it the quotient is
-t^2 / t^2 = -1, so no complex limit exists and 1 is a wrong answer rather than an
unqualified one. Under Codomain = Real the same query answers 1, which is right — so the defect
is specifically that the complex reading is being answered with the real one.
limit(x / abs(x), x, 0) already answers NaN, which is correct, so the machinery is not uniformly
wrong — it is wrong where the quotient's phase is constant and non-real, which is exactly where it
looks like it can cancel.
Not the same as #720
#720 asks for ApproachFrom to be able to
name a direction in the complex plane. This needs no direction named: every case above is reachable
today with the ordinary two-argument limit, and three of them return a wrong value rather than
declining. Worth fixing first and separately — a direction parameter on a machinery that mishandles
abs off the real line would inherit this.
Found while measuring #720 rather than from a report, so no user is known to have hit it.
Activity
Rafael-SOWNet commentedon Sep 7, 2026
Fix in #1208, with the cause traced stage by stage: the derivative of a modulus was
sgn(f) * f'whether or notfwas real-valued, and l'Hôpital's rule read it — for|i/x| = 1/|x|the formula gives+sgn(x)/x^2where the derivative is-sgn(x)/x^2, and1follows. Three things behind it agreed with the wrong answer and are fixed with it:0 * (i * +oo)evaluated to0, a complex infinity did not count as infinite, and an unread0 / abs(0)was reported asNaN.Measured on the PR's build:
(i/x)/abs(i/x)→iat+oo(and-iat-oo),(i/x)^2/abs(i/x)^2→-1at+ooand at0,((1+i)/x)^2/abs((1+i)/x)^2→ left unevaluated (it isi;|1 + i|is not a rational number, so the factor stays inside the modulus and nothing reads the quotient — declining rather than1), and theSimplify()case → left unevaluated rather than0.One input stays as it was, deliberately:
limit(x^2/abs(x)^2, x, 0)is still1.Limitcomputes a limit along the real line, andxis real on its way to0, where the quotient is1throughout; the two-dimensional approach the issue has in mind, on which there is no limit, is not the questionLimitanswers.The limit of z / |z| carries the phase of z (ASC-Community#1208)
Compiled arithmetic of a complex number is evaluation's at a whole po…