feat: add divide and invert and fix PredicatePattern match
All checks were successful
/ test (pull_request) Successful in 17s

This commit is contained in:
Glen Whitney 2025-04-24 21:41:09 -07:00
parent 7903a46118
commit 627c1c3d7f
3 changed files with 41 additions and 0 deletions

View file

@ -32,6 +32,21 @@ describe('complex arithmetic operations', () => {
assert.deepStrictEqual(conj(z), cplx(3, -4))
assert.deepStrictEqual(conj(cplx(z,z)), cplx(cplx(3, -4), cplx(-3, -4)))
})
it('divides complex numbers', () => {
const div = math.divide
const z = cplx(3, 4)
assert.deepStrictEqual(div(z, cplx(0, 1)), cplx(4, -3))
assert(math.equal(div(z, z), 1))
// should probably have a quaternion example, but it's intricate
})
it('inverts complex numbers', () => {
const inv = math.invert
assert.deepStrictEqual(inv(cplx(0, 1)), cplx(0, -1))
assert.deepStrictEqual(inv(cplx(3, 4)), cplx(3/25, -4/25))
assert.deepStrictEqual(
inv(cplx(cplx(1, 2), cplx(4, 2))),
cplx(cplx(1/25, -2/25), cplx(-4/25, -2/25)))
})
it('multiplies complex numbers', () => {
const mult = math.multiply
const z = cplx(3, 4)

View file

@ -20,6 +20,31 @@ export const conj = match(Complex, (math, C) => {
return ReturnsAs(cplx, z => cplx(compConj(z.re), neg(z.im)))
})
export const divide = [
match([Complex, T => !T.complex], (math, [C, R]) => {
const div = math.divide.resolve([C.Component, R])
const cplx = math.complex.resolve([div.returns, div.returns])
return ReturnsAs(cplx, (z, r) => cplx(div(z.re, r), div(z.im, r)))
}),
match([Complex, Complex], (math, [W, Z]) => {
const inv = math.invert.resolve(Z)
const mult = math.multiply.resolve([W, inv.returns])
return ReturnsAs(mult, (w, z) => mult(w, inv(z)))
})
]
export const invert = match(Complex, (math, C) => {
const conj = math.conj.resolve(C)
const norm = math.absquare.resolve(C)
const div = math.divide.resolve([C.Component, norm.returns])
const cplx = math.complex.resolve([div.returns, div.returns])
return ReturnsAs(cplx, z => {
const c = conj(z)
const d = norm(z)
return cplx(div(c.re, d), div(c.im, d))
})
})
// We want this to work for complex numbers, quaternions, octonions, etc
// See https://math.ucr.edu/home/baez/octonions/node5.html
export const multiply = match([Complex, Complex], (math, [W, Z]) => {

View file

@ -72,6 +72,7 @@ class PredicatePattern extends TypePattern {
}
match(typeSequence, options={}) {
const position = options.position ?? 0
if (position >= typeSequence.length) return [-1, undefined]
const actual = typeSequence[position]
if (this.predicate(actual)) return [position + 1, actual]
return [-1, Undefined]