feat(Complex): Define return types of all operations
This commit is contained in:
parent
de42c22ab4
commit
23b3ef4fdd
@ -1,9 +1,11 @@
|
|||||||
|
import Returns from '../core/Returns.mjs'
|
||||||
export * from './Types/Complex.mjs'
|
export * from './Types/Complex.mjs'
|
||||||
|
|
||||||
export const conjugate = {
|
export const conjugate = {
|
||||||
'Complex<T>': ({
|
'Complex<T>': ({
|
||||||
|
T,
|
||||||
'negate(T)': neg,
|
'negate(T)': neg,
|
||||||
'complex(T,T)': cplx
|
'complex(T,T)': cplx
|
||||||
}) => z => cplx(z.re, neg(z.im))
|
}) => Returns(`Complex<${T}>`, z => cplx(z.re, neg(z.im)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
|
import Returns from '../core/Returns.mjs'
|
||||||
export * from './Types/Complex.mjs'
|
export * from './Types/Complex.mjs'
|
||||||
|
|
||||||
export const equalTT = {
|
export const equalTT = {
|
||||||
'Complex<T>,Complex<T>': ({
|
'Complex<T>,Complex<T>': ({
|
||||||
'self(T,T)': me
|
'self(T,T)': me
|
||||||
}) => (w,z) => me(w.re, z.re) && me(w.im, z.im),
|
}) => Returns('boolean', (w, z) => me(w.re, z.re) && me(w.im, z.im)),
|
||||||
// NOTE: Although I do not understand exactly why, with typed-function@3.0's
|
// NOTE: Although I do not understand exactly why, with typed-function@3.0's
|
||||||
// matching algorithm, the above template must come first to ensure the
|
// matching algorithm, the above template must come first to ensure the
|
||||||
// most specific match to a template call. I.e, if one of the below
|
// most specific match to a template call. I.e, if one of the below
|
||||||
@ -11,16 +12,16 @@ export const equalTT = {
|
|||||||
// with (Complex<Complex<number>>, Complex<number>) (!, hopefully in some
|
// with (Complex<Complex<number>>, Complex<number>) (!, hopefully in some
|
||||||
// future iteration typed-function will be smart enough to prefer
|
// future iteration typed-function will be smart enough to prefer
|
||||||
// Complex<T>, Complex<T>. Possibly the problem is in Pocomath's bolted-on
|
// Complex<T>, Complex<T>. Possibly the problem is in Pocomath's bolted-on
|
||||||
// type resolution and the difficulty will go away when features are moved into
|
// type resolution and the difficulty will go away when features are moved
|
||||||
// typed-function.
|
// into typed-function.
|
||||||
'Complex<T>,T': ({
|
'Complex<T>,T': ({
|
||||||
'isZero(T)': isZ,
|
'isZero(T)': isZ,
|
||||||
'self(T,T)': eqReal
|
'self(T,T)': eqReal
|
||||||
}) => (z, x) => eqReal(z.re, x) && isZ(z.im),
|
}) => Returns('boolean', (z, x) => eqReal(z.re, x) && isZ(z.im)),
|
||||||
|
|
||||||
'T,Complex<T>': ({
|
'T,Complex<T>': ({
|
||||||
'isZero(T)': isZ,
|
'isZero(T)': isZ,
|
||||||
'self(T,T)': eqReal
|
'self(T,T)': eqReal
|
||||||
}) => (b, z) => eqReal(z.re, b) && isZ(z.im),
|
}) => Returns('boolean', (b, z) => eqReal(z.re, b) && isZ(z.im)),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import PocomathInstance from '../core/PocomathInstance.mjs'
|
import PocomathInstance from '../core/PocomathInstance.mjs'
|
||||||
import * as Complex from './Types/Complex.mjs'
|
import Returns from '../core/Returns.mjs'
|
||||||
|
import * as Complex from './Types/Complex.mjs'
|
||||||
import gcdType from '../generic/gcdType.mjs'
|
import gcdType from '../generic/gcdType.mjs'
|
||||||
|
|
||||||
const gcdComplexRaw = {}
|
const gcdComplexRaw = {}
|
||||||
@ -9,15 +10,16 @@ const imps = {
|
|||||||
gcdComplexRaw,
|
gcdComplexRaw,
|
||||||
gcd: { // Only return gcds with positive real part
|
gcd: { // Only return gcds with positive real part
|
||||||
'Complex<T>,Complex<T>': ({
|
'Complex<T>,Complex<T>': ({
|
||||||
|
T,
|
||||||
'gcdComplexRaw(Complex<T>,Complex<T>)': gcdRaw,
|
'gcdComplexRaw(Complex<T>,Complex<T>)': gcdRaw,
|
||||||
'sign(T)': sgn,
|
'sign(T)': sgn,
|
||||||
'one(T)': uno,
|
'one(T)': uno,
|
||||||
'negate(Complex<T>)': neg
|
'negate(Complex<T>)': neg
|
||||||
}) => (z,m) => {
|
}) => Returns(`Complex<${T}>`, (z,m) => {
|
||||||
const raw = gcdRaw(z, m)
|
const raw = gcdRaw(z, m)
|
||||||
if (sgn(raw.re) === uno(raw.re)) return raw
|
if (sgn(raw.re) === uno(raw.re)) return raw
|
||||||
return neg(raw)
|
return neg(raw)
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
|
import Returns from '../core/Returns.mjs'
|
||||||
export * from './Types/Complex.mjs'
|
export * from './Types/Complex.mjs'
|
||||||
|
|
||||||
export const invert = {
|
export const invert = {
|
||||||
'Complex<T>': ({
|
'Complex<T>': ({
|
||||||
|
T,
|
||||||
'conjugate(Complex<T>)': conj,
|
'conjugate(Complex<T>)': conj,
|
||||||
'absquare(Complex<T>)': asq,
|
'absquare(Complex<T>)': asq,
|
||||||
'complex(T,T)': cplx,
|
'complex(T,T)': cplx,
|
||||||
'divide(T,T)': div
|
'divide(T,T)': div
|
||||||
}) => z => {
|
}) => Returns(`Complex<${T}>`, z => {
|
||||||
const c = conj(z)
|
const c = conj(z)
|
||||||
const d = asq(z)
|
const d = asq(z)
|
||||||
return cplx(div(c.re, d), div(c.im, d))
|
return cplx(div(c.re, d), div(c.im, d))
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
import Returns from '../core/Returns.mjs'
|
||||||
export * from './Types/Complex.mjs'
|
export * from './Types/Complex.mjs'
|
||||||
|
|
||||||
export const isZero = {
|
export const isZero = {
|
||||||
'Complex<T>': ({'self(T)': me}) => z => me(z.re) && me(z.im)
|
'Complex<T>': ({'self(T)': me}) => Returns(
|
||||||
|
'boolean', z => me(z.re) && me(z.im))
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
|
import Returns from '../core/Returns.mjs'
|
||||||
export * from './Types/Complex.mjs'
|
export * from './Types/Complex.mjs'
|
||||||
|
|
||||||
|
// Might be nice to have type aliases!
|
||||||
export const quaternion = {
|
export const quaternion = {
|
||||||
'T,T,T,T': ({complex}) => (r,i,j,k) => complex(complex(r,j), complex(i,k))
|
'T,T,T,T': ({
|
||||||
|
T,
|
||||||
|
'complex(T,T)': cplxT,
|
||||||
|
'complex(Complex<T>,Complex<T>)': quat
|
||||||
|
}) => Returns(
|
||||||
|
`Complex<Complex<${T}>>`,
|
||||||
|
(r,i,j,k) => quat(cplxT(r,j), cplxT(i,k))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
|
import Returns from '../core/Returns.mjs'
|
||||||
export * from './roundquotient.mjs'
|
export * from './roundquotient.mjs'
|
||||||
|
|
||||||
export const quotient = {
|
export const quotient = {
|
||||||
'Complex<T>,Complex<T>': ({
|
'Complex<T>,Complex<T>': ({
|
||||||
|
T,
|
||||||
'roundquotient(Complex<T>,Complex<T>)': rq
|
'roundquotient(Complex<T>,Complex<T>)': rq
|
||||||
}) => (w,z) => rq(w,z)
|
}) => Returns(`Complex<${T}>`, (w,z) => rq(w,z))
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,19 @@
|
|||||||
|
import Returns from '../core/Returns.mjs'
|
||||||
export * from './Types/Complex.mjs'
|
export * from './Types/Complex.mjs'
|
||||||
|
|
||||||
export const roundquotient = {
|
export const roundquotient = {
|
||||||
'Complex<T>,Complex<T>': ({
|
'Complex<T>,Complex<T>': ({
|
||||||
|
T,
|
||||||
'isZero(Complex<T>)': isZ,
|
'isZero(Complex<T>)': isZ,
|
||||||
'conjugate(Complex<T>)': conj,
|
'conjugate(Complex<T>)': conj,
|
||||||
'multiply(Complex<T>,Complex<T>)': mult,
|
'multiply(Complex<T>,Complex<T>)': mult,
|
||||||
'absquare(Complex<T>)': asq,
|
'absquare(Complex<T>)': asq,
|
||||||
'self(T,T)': me,
|
'self(T,T)': me,
|
||||||
'complex(T,T)': cplx
|
'complex(T,T)': cplx
|
||||||
}) => (n,d) => {
|
}) => Returns(`Complex<${T}>`, (n,d) => {
|
||||||
if (isZ(d)) return d
|
if (isZ(d)) return d
|
||||||
const cnum = mult(n, conj(d))
|
const cnum = mult(n, conj(d))
|
||||||
const dreal = asq(d)
|
const dreal = asq(d)
|
||||||
return cplx(me(cnum.re, dreal), me(cnum.im, dreal))
|
return cplx(me(cnum.re, dreal), me(cnum.im, dreal))
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,12 @@ describe('The default full pocomath instance "math"', () => {
|
|||||||
math.abs(math.complex(2,1)) //TODO: ditto
|
math.abs(math.complex(2,1)) //TODO: ditto
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
math.returnTypeOf('abs','Complex<NumInt>'), 'number')
|
math.returnTypeOf('abs','Complex<NumInt>'), 'number')
|
||||||
|
math.multiply(math.quaternion(1,1,1,1), math.quaternion(1,-1,1,-1)) // dit
|
||||||
|
const quatType = math.returnTypeOf(
|
||||||
|
'quaternion', 'NumInt,NumInt,NumInt,NumInt')
|
||||||
|
assert.strictEqual(quatType, 'Complex<Complex<NumInt>>')
|
||||||
|
assert.strictEqual(
|
||||||
|
math.returnTypeOf('multiply', quatType + ',' + quatType), quatType)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('can subtract numbers', () => {
|
it('can subtract numbers', () => {
|
||||||
|
Loading…
Reference in New Issue
Block a user