Skip to content

A compiled product of real numbers is real at an infinity - #2226

Merged
Rafael-SOWNet merged 1 commit into
masterfrom
a-real-product-stays-real
Oct 30, 2026
Merged

Rafael-SOWNet merged 1 commit into
masterfrom
a-real-product-stays-real

Conversation

@Rafael-SOWNet

Copy link
Copy Markdown
Member

Fixes #2222.

Over System.Numerics.Complex, in FastExpression and in the LINQ compiler, a product's imaginary part is a.Re b.Im + a.Im b.Re. With a real infinity that is ∞ · 0, which is NaN. So -x at +oo was (-∞, NaN), and so were 2 * x, x / 2 and x * x. That is a value with no imaginary part at all: a comparison of it had no truth value, and a piecewise passed over it. Evaluation gives -oo, and so does the compiler over double.

RealProducts.Product and RealProducts.Quotient take two numbers whose imaginary parts are both 0 as reals, and anything else as before. FastExpression's CALL_MUL and CALL_DIV call them, and so do the LINQ compiler's Multiply and Divide over Complex.

A division by 0 is left to Complex, whose NaN is evaluation's. A real quotient would have made 1/x at 0 equal +∞, where evaluation has no value for 1/0.

2.6.0 and master now
"-x".ToEntity().Compile("x").Call(double.PositiveInfinity) (-Infinity, NaN) (-Infinity, 0)
"x / 2".ToEntity().Compile<Complex, Complex>("x")(double.PositiveInfinity) (Infinity, NaN) (Infinity, 0)

#2223's MembershipCompilationTest kept its piecewise case away from the infinities because of this. That case now runs at +oo and -oo too.

Tests: RealProductCompilationTest has 8 expressions at +oo or -oo, all failing on master. It also has 6 cases elsewhere that keep their values: a division by 0, and complex products and quotients. Full suite 18025/0, interactive trio, AOT smoke 73/0, all frameworks build.

A power at a real infinity comes out NaN in both parts. That is a different mechanism, Complex.Pow, filed as #2225.

🤖 Generated with Claude Code

Over System.Numerics.Complex, in FastExpression and in the LINQ compiler,
a product's imaginary part is a.Re b.Im + a.Im b.Re. With a real
infinity that is inf * 0, which is NaN. So -x at +oo was (-inf, NaN),
and so were 2 * x, x / 2 and x * x. That is a value with no imaginary
part at all, so a comparison of it had no truth value and a piecewise
passed over it. Evaluation gives -oo, and so does the compiler over
double.

RealProducts.Product and Quotient take two numbers whose imaginary parts
are both 0 as reals, and anything else as before. FastExpression's
CALL_MUL and CALL_DIV call them, and so does the LINQ compiler's
Multiply and Divide over Complex. A division by 0 is left to Complex,
whose NaN is evaluation's. A real Quotient would have made 1/x at 0
+inf, where evaluation has no value for 1/0.

MembershipCompilationTest's piecewise case, which #2223 kept away from
the infinities for this, now runs at +oo and -oo as well.

RealProductCompilationTest: 8 expressions at +oo or -oo, all failing on
master, and 6 elsewhere that keep their values: a division by 0, and
complex products and quotients.

A power at a real infinity is NaN in both parts, which is a different
mechanism, Complex.Pow. It is #2225.

Fixes #2222.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Rafael-SOWNet Rafael-SOWNet moved this from Todo to In review in AngouriMath Oct 30, 2026
@codecov

codecov Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.66%. Comparing base (5c6a13f) to head (4b17696).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2226      +/-   ##
==========================================
- Coverage   86.67%   86.66%   -0.02%     
==========================================
  Files         308      309       +1     
  Lines       67639    67644       +5     
  Branches    19610    19612       +2     
==========================================
- Hits        58628    58625       -3     
- Misses       4895     4899       +4     
- Partials     4116     4120       +4     
Flag Coverage Δ
cpp 37.77% <ø> (ø)
csharp 87.21% <100.00%> (-0.02%) ⬇️
fsharp 32.97% <ø> (ø)
interactive 40.72% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...ath/Functions/Compilation/IntoFE/FastExpression.cs 96.72% <100.00%> (ø)
...ctions/Compilation/IntoLinq/CompilationProtocol.cs 91.36% <100.00%> (+0.06%) ⬆️
.../AngouriMath/Functions/Compilation/RealProducts.cs 100.00% <100.00%> (ø)

... and 10 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Rafael-SOWNet
Rafael-SOWNet merged commit c50b9ff into master Oct 30, 2026
36 checks passed
@github-project-automation github-project-automation Bot moved this from In review to Done in AngouriMath Oct 30, 2026
@Rafael-SOWNet
Rafael-SOWNet deleted the a-real-product-stays-real branch October 30, 2026 05:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

A compiled product with a real infinity has a NaN imaginary part: -x at +oo is (-inf, NaN)

1 participant