Compare commits
No commits in common. "bd05dc926776db4e49f107c8d27922e488a207e2" and "a0b21181e6906cc17ae38965873587513ed35841" have entirely different histories.
bd05dc9267
...
a0b21181e6
6 changed files with 52 additions and 52 deletions
|
@ -1,6 +1,6 @@
|
||||||
import {Complex} from './type.js'
|
import {Complex} from './type.js'
|
||||||
import type {
|
import type {
|
||||||
Dependencies, Signature, Returns, RealType, AliasOf
|
Dependencies, Signature, Returns, RealType, ZeroType
|
||||||
} from '../interfaces/type.js'
|
} from '../interfaces/type.js'
|
||||||
|
|
||||||
declare module "../interfaces/type" {
|
declare module "../interfaces/type" {
|
||||||
|
@ -9,8 +9,8 @@ declare module "../interfaces/type" {
|
||||||
// after removing any `_...` suffixes; the following should be
|
// after removing any `_...` suffixes; the following should be
|
||||||
// additional dispatches for add and divide, not separate
|
// additional dispatches for add and divide, not separate
|
||||||
// operations, in the final mathjs bundle.
|
// operations, in the final mathjs bundle.
|
||||||
addReal: AliasOf<'add', (a: T, b: RealType<T>) => T>
|
add_real: {params: [T, RealType<T>], returns: T}
|
||||||
divideReal: AliasOf<'divide', (a: T, b: RealType<T>) => T>
|
divide_real: {params: [T, RealType<T>], returns: T}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,9 +19,9 @@ export const add =
|
||||||
(w, z) => dep.complex(dep.add(w.re, z.re), dep.add(w.im, z.im))
|
(w, z) => dep.complex(dep.add(w.re, z.re), dep.add(w.im, z.im))
|
||||||
|
|
||||||
export const add_real =
|
export const add_real =
|
||||||
<T>(dep: Dependencies<'addReal' | 'complex', T>):
|
<T>(dep: Dependencies<'add_real' | 'complex', T>):
|
||||||
Signature<'addReal', Complex<T>> =>
|
Signature<'add_real', Complex<T>> =>
|
||||||
(z, r) => dep.complex(dep.addReal(z.re, r), z.im)
|
(z, r) => dep.complex(dep.add_real(z.re, r), z.im)
|
||||||
|
|
||||||
export const unaryMinus =
|
export const unaryMinus =
|
||||||
<T>(dep: Dependencies<'unaryMinus' | 'complex', T>):
|
<T>(dep: Dependencies<'unaryMinus' | 'complex', T>):
|
||||||
|
@ -58,14 +58,14 @@ export const absquare =
|
||||||
z => dep.add(dep.absquare(z.re), dep.absquare(z.im))
|
z => dep.add(dep.absquare(z.re), dep.absquare(z.im))
|
||||||
|
|
||||||
export const divideByReal =
|
export const divideByReal =
|
||||||
<T>(dep: Dependencies<'divideReal' | 'complex', T>):
|
<T>(dep: Dependencies<'divide_real' | 'complex', T>):
|
||||||
Signature<'divideReal', Complex<T>> =>
|
Signature<'divide_real', Complex<T>> =>
|
||||||
(z, r) => dep.complex(dep.divideReal(z.re, r), dep.divideReal(z.im, r))
|
(z, r) => dep.complex(dep.divide_real(z.re, r), dep.divide_real(z.im, r))
|
||||||
|
|
||||||
export const reciprocal =
|
export const reciprocal =
|
||||||
<T>(dep: Dependencies<'conj' | 'absquare' | 'divideReal', Complex<T>>):
|
<T>(dep: Dependencies<'conj' | 'absquare' | 'divide_real', Complex<T>>):
|
||||||
Signature<'reciprocal', Complex<T>> =>
|
Signature<'reciprocal', Complex<T>> =>
|
||||||
z => dep.divideReal(dep.conj(z), dep.absquare(z))
|
z => dep.divide_real(dep.conj(z), dep.absquare(z))
|
||||||
|
|
||||||
export const divide =
|
export const divide =
|
||||||
<T>(dep: Dependencies<'multiply' | 'reciprocal', Complex<T>>):
|
<T>(dep: Dependencies<'multiply' | 'reciprocal', Complex<T>>):
|
||||||
|
@ -78,14 +78,11 @@ export const divide =
|
||||||
// in fact, we need `add_real` on both T and Complex<T>, hence the dependency
|
// in fact, we need `add_real` on both T and Complex<T>, hence the dependency
|
||||||
// with a custom name, not generated via Dependencies<...>
|
// with a custom name, not generated via Dependencies<...>
|
||||||
export const sqrt =
|
export const sqrt =
|
||||||
<T>(dep: Dependencies<'equal' | 'conservativeSqrt' | 'unaryMinus', RealType<T>>
|
<T>(dep: Dependencies<'add' | 'equal' | 'conservativeSqrt' | 'unaryMinus',
|
||||||
& Dependencies<'zero' | 'complex', T>
|
RealType<T>>
|
||||||
& Dependencies<'absquare' | 're' | 'divideReal', Complex<T>>
|
& Dependencies<'zero' | 'add_real' | 'complex', T>
|
||||||
& {
|
& Dependencies<'absquare' | 're' | 'divide_real', Complex<T>>
|
||||||
addNumber: Signature<'addReal', T>, // TODO: should use Signature<'add'> here
|
& {add_complex_real: Signature<'add_real', Complex<T>>}):
|
||||||
addReal: Signature<'add', RealType<T>>,
|
|
||||||
addComplex: Signature<'addReal', Complex<T>> // TODO: should use Signature<'add'> here
|
|
||||||
}):
|
|
||||||
Signature<'sqrt', Complex<T>> =>
|
Signature<'sqrt', Complex<T>> =>
|
||||||
z => {
|
z => {
|
||||||
const myabs = dep.conservativeSqrt(dep.absquare(z))
|
const myabs = dep.conservativeSqrt(dep.absquare(z))
|
||||||
|
@ -94,12 +91,12 @@ export const sqrt =
|
||||||
if (dep.equal(myabs, negr)) {
|
if (dep.equal(myabs, negr)) {
|
||||||
// pure imaginary square root; z.im already zero
|
// pure imaginary square root; z.im already zero
|
||||||
return dep.complex(
|
return dep.complex(
|
||||||
dep.zero(z.re), dep.addNumber(z.im, dep.conservativeSqrt(negr)))
|
dep.zero(z.re), dep.add_real(z.im, dep.conservativeSqrt(negr)))
|
||||||
}
|
}
|
||||||
const num = dep.addComplex(z, myabs)
|
const num = dep.add_complex_real(z, myabs)
|
||||||
const denomsq = dep.addReal(dep.addReal(myabs, myabs), dep.addReal(r, r))
|
const denomsq = dep.add(dep.add(myabs, myabs), dep.add(r, r))
|
||||||
const denom = dep.conservativeSqrt(denomsq)
|
const denom = dep.conservativeSqrt(denomsq)
|
||||||
return dep.divideReal(num, denom)
|
return dep.divide_real(num, denom)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const conservativeSqrt = sqrt
|
export const conservativeSqrt = sqrt
|
||||||
|
|
|
@ -32,7 +32,7 @@ declare module "../interfaces/type" {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Signatures<T> {
|
interface Signatures<T> {
|
||||||
complex: ((re: T) => Complex<T>) | ((re: T, im: T) => Complex<T>)
|
complex: {params: [T] | [T,T], returns: Complex<T>}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,23 @@
|
||||||
import type {Complex} from '../Complex/type.js'
|
import type {Complex} from '../Complex/type.js'
|
||||||
import type {RealType} from './type.js'
|
import type {RealType} from './type.js'
|
||||||
|
|
||||||
|
type UnaryOperator<T> = {params: [T], returns: T}
|
||||||
|
type BinaryOperator<T> = {params: [T, T], returns: T}
|
||||||
declare module "./type" {
|
declare module "./type" {
|
||||||
interface Signatures<T> {
|
interface Signatures<T> {
|
||||||
add: (a: T, b: T) => T
|
add: BinaryOperator<T>
|
||||||
unaryMinus: (a: T) => T
|
unaryMinus: UnaryOperator<T>
|
||||||
conj: (a: T) => T
|
conj: UnaryOperator<T>
|
||||||
subtract: (a: T, b: T) => T
|
subtract: BinaryOperator<T>
|
||||||
multiply: (a: T, b: T) => T
|
multiply: BinaryOperator<T>
|
||||||
square: (a: T) => T
|
square: UnaryOperator<T>
|
||||||
absquare: (a: T) => RealType<T>
|
absquare: {params: [T], returns: RealType<T>}
|
||||||
reciprocal: (a: T) => T
|
reciprocal: UnaryOperator<T>
|
||||||
divide: (a: T, b: T) => T
|
divide: BinaryOperator<T>
|
||||||
conservativeSqrt: (a: T) => T
|
conservativeSqrt: UnaryOperator<T>
|
||||||
sqrt: (a: T)=> T extends Complex<unknown> ? T : T | Complex<T>
|
sqrt: {
|
||||||
|
params: [T],
|
||||||
|
returns: T extends Complex<any> ? T : T | Complex<T>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
// Warning: a module must have something besides just a "declare module"
|
// Warning: a module must have something besides just a "declare module"
|
||||||
// section; otherwise it is ignored.
|
// section; otherwise it is ignored.
|
||||||
export type UnaryPredicate<T> = (a: T) => boolean
|
export type UnaryPredicate<T> = {params: [T], returns: boolean}
|
||||||
|
|
||||||
declare module "./type" {
|
declare module "./type" {
|
||||||
interface Signatures<T> {
|
interface Signatures<T> {
|
||||||
isReal: (a: T) => boolean
|
isReal: UnaryPredicate<T>
|
||||||
isSquare: (a: T) => boolean
|
isSquare: UnaryPredicate<T>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
// Warning: a module must have something besides just a "declare module"
|
// Warning: a module must have something besides just a "declare module"
|
||||||
// section; otherwise it is ignored.
|
// section; otherwise it is ignored.
|
||||||
export type BinaryPredicate<T> = (a: T, b: T) => T
|
export type BinaryPredicate<T> = {params: [T, T], returns: boolean}
|
||||||
declare module "./type" {
|
declare module "./type" {
|
||||||
interface Signatures<T> {
|
interface Signatures<T> {
|
||||||
equal: (a: T, b: T) => boolean
|
equal: BinaryPredicate<T>
|
||||||
unequal: (a: T, b: T) => boolean
|
unequal: BinaryPredicate<T>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,18 +58,17 @@ export type RealType<T> = ALookup<T, 'real'>
|
||||||
* key 're' in the interface.
|
* key 're' in the interface.
|
||||||
****/
|
****/
|
||||||
export interface Signatures<T> {
|
export interface Signatures<T> {
|
||||||
zero: (a: T) => ZeroType<T>
|
zero: {params: [T], returns: ZeroType<T>}
|
||||||
one: (a: T) => OneType<T>
|
one: {params: [T], returns: OneType<T>}
|
||||||
// nan needs to be able to operate on its own output for everything
|
// nan needs to be able to operate on its own output for everything
|
||||||
// else to compile. That's why its parameter type is widened:
|
// else to compile. That's why its parameter type is widened:
|
||||||
nan: (a: T | NaNType<T>) => NaNType<T>
|
nan: {params: [T | NaNType<T>], returns: NaNType<T>}
|
||||||
re: (a: T) => RealType<T>
|
re: {params: [T], returns: RealType<T>}
|
||||||
}
|
}
|
||||||
|
|
||||||
type SignatureKey<T> = keyof Signatures<T>
|
type SignatureKey = keyof Signatures<unknown>
|
||||||
|
|
||||||
export type Signature<Name extends SignatureKey<T>, T> = Signatures<T>[Name]
|
export type Returns<Name extends SignatureKey, T> = Signatures<T>[Name]['returns']
|
||||||
export type Returns<Name extends SignatureKey<T>, T> = ReturnType<Signatures<T>[Name]>
|
export type Signature<Name extends SignatureKey, T> =
|
||||||
export type Dependencies<Name extends SignatureKey<T>, T> = {[K in Name]: Signature<K, T>}
|
(...args: Signatures<T>[Name]['params']) => Returns<Name, T>
|
||||||
|
export type Dependencies<Name extends SignatureKey, T> = {[K in Name]: Signature<K, T>}
|
||||||
export type AliasOf<Name extends string, T> = T & {aliasOf?: Name}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue