55 lines
1.9 KiB
JavaScript
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)})))
|