Files
tuneinsight-lattigo/utils/bignum/complex_test.go
T
dualfroz 351ba05ff4 fix(bignum): ComplexMultiplier.Quo wrong result and panic for real / non-real
The a-real / b-non-real branch of Quo divided the real numerator by each
component of b independently, which is not complex division: (1+0i)/(1+i)
returned 1+1i instead of 0.5-0.5i, (1+0i)/i returned +Inf+1i, and (0+0i)/i
divided 0/0 and panicked. Use the full a*conj(b)/|b|^2 formula (the same
one the general branch uses), which reduces correctly when a is real.

Closes #577
2026-09-02 05:04:22 +02:00

40 lines
1.2 KiB
Go

package bignum
import (
"math/big"
"testing"
"github.com/stretchr/testify/require"
)
func TestComplexMultiplierQuo(t *testing.T) {
const prec = 128
newComplex := func(re, im float64) *Complex {
return &Complex{
new(big.Float).SetPrec(prec).SetFloat64(re),
new(big.Float).SetPrec(prec).SetFloat64(im),
}
}
f := func(v float64) *big.Float { return new(big.Float).SetPrec(prec).SetFloat64(v) }
cm := NewComplexMultiplier()
for _, tc := range []struct {
name string
a, b *Complex
wantRe, wantIm float64
}{
// Real numerator, non-real denominator: the previously broken branch.
{"1/(1+i)", newComplex(1, 0), newComplex(1, 1), 0.5, -0.5},
{"1/i", newComplex(1, 0), newComplex(0, 1), 0, -1},
{"0/i", newComplex(0, 0), newComplex(0, 1), 0, 0}, // must not panic
// General complex division (regression guard for the other branch).
{"(2+3i)/(1+i)", newComplex(2, 3), newComplex(1, 1), 2.5, 0.5},
} {
c := newComplex(0, 0)
cm.Quo(tc.a, tc.b, c)
require.Zerof(t, c[0].Cmp(f(tc.wantRe)), "%s real: got %v, want %v", tc.name, c[0], tc.wantRe)
require.Zerof(t, c[1].Cmp(f(tc.wantIm)), "%s imag: got %v, want %v", tc.name, c[1], tc.wantIm)
}
}