nanomath/src/complex/type.js
Glen Whitney 7903a46118
All checks were successful
/ test (pull_request) Successful in 16s
feat: add cis and fix indistinguishable
2025-04-24 20:52:43 -07:00

55 lines
1.9 KiB
JavaScript

import {Complex} from './Complex.js'
import {Returns} from "#core/Type.js"
import {Any, match} from "#core/TypePatterns.js"
import {BooleanT} from '#boolean/BooleanT.js'
import {NumberT} from '#number/NumberT.js'
export const complex = [
match(Any, (math, T) => {
const z = math.zero(T)
if (math.hasnan(T)) {
const isnan = math.isnan.resolve([T])
const compnan = math.nan(Complex(T))
return Returns(Complex(T), r => {
if (isnan(r)) return compnan
return {re: r, im: z}
})
}
return Returns(Complex(T), r => ({re: r, im: z}))
}),
match([Any, Any], (math, [T, U]) => {
if (T !== U) {
throw new RangeError(
'mixed complex types disallowed '
+ `(real ${T}, imaginary ${U})`)
}
return Returns(Complex(T), (r, m) => ({re: r, im: m}))
})
]
export const arg = match(
Complex(NumberT), Returns(NumberT, z => Math.atan2(z.im, z.re)))
/* Returns true if w is z multiplied by a complex unit */
export const associate = match([Complex, Complex], (math, [W, Z]) => {
if (Z.Component.complex) {
throw new Error(
`The group of units of type ${Z} is not yet implemented`)
}
const eq = math.equal.resolve([W, Z])
const neg = math.negate.resolve(Z)
const eqN = math.equal.resolve([W, neg.returns])
const mult = math.multiply.resolve([Z, Z])
const eqM = math.equal.resolve([W, mult.returns])
const negM = math.negate.resolve(mult.returns)
const eqNM = math.equal.resolve([W, negM.returns])
const iZ = math.complex(math.zero(Z.Component), math.one(Z.Component))
return Returns(BooleanT, (w, z) => {
if (eq(w, z) || eqN(w, neg(z))) return true
const iz = mult(iZ, z)
return eqM(w, iz) || eqNM(w, negM(iz))
})
})
export const cis = match(NumberT, Returns(Complex(NumberT), t => ({
re: Math.cos(t), im: Math.sin(t)})))