feat: equality on Vector elementwise
This commit is contained in:
parent
7b799f7183
commit
c3c2bbbf78
3 changed files with 107 additions and 12 deletions
|
@ -1,8 +1,14 @@
|
|||
import {TypeOfTypes, Undefined} from '#core/Type.js'
|
||||
import {match} from '#core/TypePatterns.js'
|
||||
import {Any, Multiple, match} from '#core/TypePatterns.js'
|
||||
import {boolnum} from '#number/helpers.js'
|
||||
|
||||
export const indistinguishable = [
|
||||
match([Undefined, Undefined], boolnum(() => true)),
|
||||
match([TypeOfTypes, TypeOfTypes], boolnum((t, u) => t === u))
|
||||
// I don't think there's any other type that should be indistinguishable
|
||||
// from undefined:
|
||||
match([Undefined, Any, Multiple(Any)], boolnum(() => false)),
|
||||
match([Any, Undefined, Multiple(Any)], boolnum(() => false)),
|
||||
match([Undefined, Undefined, Multiple(Any)], boolnum(() => true)),
|
||||
match(
|
||||
[TypeOfTypes, TypeOfTypes, Multiple(Any)],
|
||||
boolnum((t, u) => t === u))
|
||||
]
|
||||
|
|
|
@ -1,16 +1,34 @@
|
|||
import assert from 'assert'
|
||||
import math from '#nanomath'
|
||||
|
||||
const t = true
|
||||
const f = false
|
||||
describe('Vector relational functions', () => {
|
||||
it('can test two vectors for deep equality', () => {
|
||||
const dEq = math.deepEqual
|
||||
const pyth = [3, 4, 5]
|
||||
assert.strictEqual(dEq(pyth, [3, 4, 5]), true)
|
||||
assert.strictEqual(dEq(pyth, [3, 4, 6]), false)
|
||||
assert.strictEqual(dEq(pyth, [3, 4, [5]]), false)
|
||||
assert.strictEqual(dEq(3, 3 + 1e-13), true)
|
||||
assert.strictEqual(dEq(pyth, [3+1e-13, 4-1e-13, 5]), true)
|
||||
assert.strictEqual(dEq([pyth, pyth], [pyth, [3, 4, 5]]), true)
|
||||
assert.strictEqual(dEq([3], 3), false)
|
||||
assert.strictEqual(dEq(pyth, [3, 4, 5]), t)
|
||||
assert.strictEqual(dEq(pyth, [3, 4, 6]), f)
|
||||
assert.strictEqual(dEq(pyth, [3, 4, [5]]), f)
|
||||
assert.strictEqual(dEq(3, 3 + 1e-13), t)
|
||||
assert.strictEqual(dEq(pyth, [3+1e-13, 4-1e-13, 5]), t)
|
||||
assert.strictEqual(dEq([pyth, pyth], [pyth, [3, 4, 5]]), t)
|
||||
assert.strictEqual(dEq([3], 3), f)
|
||||
})
|
||||
it('performs equal elementwise', () => {
|
||||
const eq = math.equal
|
||||
const pyth = [3, 4, 5]
|
||||
assert.deepStrictEqual(eq(pyth, 4), [f, t, f])
|
||||
assert.deepStrictEqual(eq(5, pyth), [f, f, t])
|
||||
assert.deepStrictEqual(eq(pyth, pyth), [t, t, t])
|
||||
assert.deepStrictEqual(eq(pyth, [3]), [t, f, f])
|
||||
assert.deepStrictEqual(eq([4 + 1e-14], pyth), [f, t, f])
|
||||
assert.deepStrictEqual(eq(pyth, [3, 4]), [t, t, f])
|
||||
assert.deepStrictEqual(eq([3, 2], pyth), [t, f, f])
|
||||
assert.deepStrictEqual(eq([pyth, pyth], [3, 4]), [[t, f, f], [f, t, f]])
|
||||
assert.deepStrictEqual(
|
||||
eq([pyth, pyth], [[5], pyth]), [[f, f, t], [t, t, t]])
|
||||
assert.deepStrictEqual(
|
||||
eq([[1, 2], [3, 4]], [[1, 3], [2, 4]]), [[t, f], [f, t]])
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {Vector} from './Vector.js'
|
||||
import {NotAType, Returns} from '#core/Type.js'
|
||||
import {Any, match} from '#core/TypePatterns.js'
|
||||
import {NotAType, Returns, Undefined} from '#core/Type.js'
|
||||
import {Any, Optional, match} from '#core/TypePatterns.js'
|
||||
import {BooleanT} from '#boolean/BooleanT.js'
|
||||
|
||||
export const deepEqual = [
|
||||
|
@ -18,3 +18,74 @@ export const deepEqual = [
|
|||
&& v.every((e, i) => compDeep(e, w[i]))))
|
||||
})
|
||||
]
|
||||
|
||||
export const indistinguishable = [
|
||||
match([Vector, Any, Optional([Any, Any])], (math, [V, E, T]) => {
|
||||
const VComp = V.Component
|
||||
if (T.length === 0) { // no tolerances
|
||||
const same = math.indistinguishable.resolve([VComp, E])
|
||||
return Returns(
|
||||
Vector(same.returns), (v, e) => v.map(f => same(f, e)))
|
||||
}
|
||||
const [[RT, AT]] = T
|
||||
const same = math.indistinguishable.resolve([VComp, E, RT, AT])
|
||||
return Returns(
|
||||
Vector(same.returns),
|
||||
(v, e, [[rT, aT]]) => v.map(f => same(f, e, rT, aT)))
|
||||
}),
|
||||
match([Any, Vector, Optional([Any, Any])], (math, [E, V, T]) => {
|
||||
// reimplement to get other order in same so as not to assume
|
||||
// same is symmetric, even though it probably is
|
||||
const VComp = V.Component
|
||||
if (T.length === 0) { // no tolerances
|
||||
const same = math.indistinguishable.resolve([E, VComp])
|
||||
return Returns(
|
||||
Vector(same.returns), (e, v) => v.map(f => same(e, f)))
|
||||
}
|
||||
const [[RT, AT]] = T
|
||||
const same = math.indistinguishable.resolve([E, VComp, RT, AT])
|
||||
return Returns(
|
||||
Vector(same.returns),
|
||||
(e, v, [[rT, aT]]) => v.map(f => same(e, f, rT, aT)))
|
||||
}),
|
||||
match([Vector, Vector, Optional([Any, Any])], (math, [V, W, T]) => {
|
||||
const VComp = V.Component
|
||||
const WComp = W.Component
|
||||
let same
|
||||
let sameNoV
|
||||
let sameNoW
|
||||
if (T.length === 0) { // no tolerances
|
||||
same = math.indistinguishable.resolve([VComp, WComp])
|
||||
sameNoV = math.indistinguishable.resolve([Undefined, WComp])
|
||||
sameNoW = math.indistinguishable.resolve([VComp, Undefined])
|
||||
} else {
|
||||
const [[RT, AT]] = T
|
||||
same = math.indistinguishable.resolve([VComp, WComp, RT, AT])
|
||||
sameNoV = math.indistinguishable.resolve([Undefined, WComp, RT, AT])
|
||||
sameNoW = math.indistinguishable.resolve([VComp, Undefined, RT, AT])
|
||||
}
|
||||
return Returns(
|
||||
Vector(same.returns),
|
||||
(v, w, [tol = [0, 0]]) => {
|
||||
const [rT, aT] = tol
|
||||
const vInc = Number(v.length > 1)
|
||||
const wInc = Number(w.length >= v.length || w.length > 1)
|
||||
const retval = []
|
||||
let vIx = 0
|
||||
let wIx = 0
|
||||
let remainder = vIx < v.length || wIx < w.length
|
||||
while ((vInc && vIx < v.length)
|
||||
|| (wInc && wIx < w.length)
|
||||
) {
|
||||
if (vIx >= v.length) {
|
||||
retval.push(sameNoV(undefined, w[wIx], rT, aT))
|
||||
} else if (wIx >= w.length) {
|
||||
retval.push(sameNoW(v[vIx], undefined, rT, aT))
|
||||
} else retval.push(same(v[vIx], w[wIx], rT, aT))
|
||||
vIx += vInc
|
||||
wIx += wInc
|
||||
}
|
||||
return retval
|
||||
})
|
||||
})
|
||||
]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue