feat: Add isReal and isZero, and fix specializing a generic type
All checks were successful
/ test (pull_request) Successful in 17s
All checks were successful
/ test (pull_request) Successful in 17s
This commit is contained in:
parent
627c1c3d7f
commit
f9b723b882
5 changed files with 28 additions and 4 deletions
|
@ -2,3 +2,4 @@ export * as typeDefinition from './Complex.js'
|
||||||
export * as arithmetic from './arithmetic.js'
|
export * as arithmetic from './arithmetic.js'
|
||||||
export * as relational from './relational.js'
|
export * as relational from './relational.js'
|
||||||
export * as type from './type.js'
|
export * as type from './type.js'
|
||||||
|
export * as utilities from './utils.js'
|
||||||
|
|
9
src/complex/utils.js
Normal file
9
src/complex/utils.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import {Complex} from './Complex.js'
|
||||||
|
import {match} from '#core/TypePatterns.js'
|
||||||
|
import {ReturnsAs} from '#generic/helpers.js'
|
||||||
|
|
||||||
|
export const isReal = match(Complex, (math, C) => {
|
||||||
|
const eq = math.equal.resolve([C.Component, C.Component])
|
||||||
|
const add = math.add.resolve([C.Component, C.Component])
|
||||||
|
return ReturnsAs(eq, z => eq(z.re, add(z.re, z.im)))
|
||||||
|
})
|
|
@ -10,9 +10,8 @@ export class Type extends Function {
|
||||||
// let the proxy out of this function, never `this`.
|
// let the proxy out of this function, never `this`.
|
||||||
const rewired = new Proxy(this, {
|
const rewired = new Proxy(this, {
|
||||||
apply: (target, thisForCall, args) => {
|
apply: (target, thisForCall, args) => {
|
||||||
const callThrough = thisForCall ?? target
|
if (target.specialize) return target.specialize(...args)
|
||||||
if (callThrough.specialize) return callThrough.specialize(...args)
|
throw new TypeError(`Type ${target} is not generic`)
|
||||||
throw new TypeError(`Type ${callThrough} is not generic`)
|
|
||||||
},
|
},
|
||||||
get: (target, prop, receiver) => {
|
get: (target, prop, receiver) => {
|
||||||
if (prop === 'isAproxy') return true
|
if (prop === 'isAproxy') return true
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import assert from 'assert'
|
import assert from 'assert'
|
||||||
import math from '#nanomath'
|
import math from '#nanomath'
|
||||||
|
import {NumberT} from '#number/NumberT.js'
|
||||||
|
|
||||||
describe('generic utility functions', () => {
|
describe('generic utility functions', () => {
|
||||||
it('tests whether an element is zero', () => {
|
it('tests whether an element is zero', () => {
|
||||||
|
@ -9,5 +10,16 @@ describe('generic utility functions', () => {
|
||||||
assert(isZero(false))
|
assert(isZero(false))
|
||||||
assert(!isZero(true))
|
assert(!isZero(true))
|
||||||
assert(isZero(undefined))
|
assert(isZero(undefined))
|
||||||
|
assert(isZero(math.types.Complex(NumberT).zero))
|
||||||
|
assert(isZero(math.complex(-2e-16, 4e-17)))
|
||||||
|
assert(!isZero(math.complex(true)))
|
||||||
|
})
|
||||||
|
it('tests whether an element is real', () => {
|
||||||
|
const {isReal} = math
|
||||||
|
assert(isReal(Infinity))
|
||||||
|
assert(isReal(false))
|
||||||
|
assert(isReal(math.types.Complex(NumberT).one))
|
||||||
|
assert(isReal(math.complex(-3.25, 4e-16)))
|
||||||
|
assert(!isReal(math.complex(3, 4)))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
import {ReturnsAs} from './helpers.js'
|
import {ReturnsAs} from './helpers.js'
|
||||||
import {ResolutionError} from '#core/helpers.js'
|
import {ResolutionError} from '#core/helpers.js'
|
||||||
import {Passthru, match} from "#core/TypePatterns.js"
|
import {Passthru, match} from '#core/TypePatterns.js'
|
||||||
|
import {boolnum} from '#number/helpers.js'
|
||||||
|
|
||||||
|
// Most types are real. Have to make sure to redefine on all non-real types
|
||||||
|
export const isReal = match(Passthru, boolnum(() => true))
|
||||||
export const isZero = match(Passthru, (math, [T]) => {
|
export const isZero = match(Passthru, (math, [T]) => {
|
||||||
if (!T) { // called with no arguments
|
if (!T) { // called with no arguments
|
||||||
throw new ResolutionError('isZero() requires one argument')
|
throw new ResolutionError('isZero() requires one argument')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue