From 3b882f3d531c2c1d5ab686cd0dd24919a2760b1b Mon Sep 17 00:00:00 2001 From: Glen Whitney Date: Mon, 28 Apr 2025 19:32:12 -0700 Subject: [PATCH] feat: extend all utils to vectors elementwise & fix parameter match grouping --- src/core/TypePatterns.js | 7 ++++--- src/core/__test__/TypePatterns.spec.js | 4 ++++ src/generic/utils.js | 2 +- src/vector/__test__/utils.spec.js | 17 +++++++++++++++++ src/vector/utils.js | 7 +++++++ 5 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/core/TypePatterns.js b/src/core/TypePatterns.js index 0705894..b3cb566 100644 --- a/src/core/TypePatterns.js +++ b/src/core/TypePatterns.js @@ -51,7 +51,8 @@ class SequencePattern extends TypePattern { const [newPos, newMatch] = pat.match(typeSequence, options) if (newPos < 0) return [-1, Undefined] options.position = newPos - matches.push(newMatch) + if (Array.isArray(newMatch)) matches.push(...newMatch) + else matches.push(newMatch) } return [options.position, matches] } @@ -125,7 +126,7 @@ class OptionalPattern extends TypePattern { options.position = newPos matches.push(newMatch) } - return [options.position, matches] + return [options.position, [matches]] } sampleTypes() {return []} equal(other) { @@ -148,7 +149,7 @@ class MultiPattern extends TypePattern { const matches = [] while (true) { const [newPos, newMatch] = this.pattern.match(typeSequence, options) - if (newPos < 0) return [options.position, matches] + if (newPos < 0) return [options.position, [matches]] options.position = newPos matches.push(newMatch) } diff --git a/src/core/__test__/TypePatterns.spec.js b/src/core/__test__/TypePatterns.spec.js index 5aefc3a..b2750be 100644 --- a/src/core/__test__/TypePatterns.spec.js +++ b/src/core/__test__/TypePatterns.spec.js @@ -53,6 +53,10 @@ describe('Type patterns', () => { midOpt.match([Undefined, TypeOfTypes, TypeOfTypes]), [-1, Undefined]) assert.deepStrictEqual(midOpt.sampleTypes(), [Undefined, Undefined]) + const justMulti = pattern(Multiple(Undefined)) + assert.deepStrictEqual( + justMulti.match([Undefined, Undefined]), + [2, [[Undefined, Undefined]]]) const midMulti = pattern([Undefined, Multiple(TypeOfTypes), Undefined]) assert.deepStrictEqual( midMulti.match([Undefined, Undefined]), diff --git a/src/generic/utils.js b/src/generic/utils.js index 716609e..9a17f52 100644 --- a/src/generic/utils.js +++ b/src/generic/utils.js @@ -18,7 +18,7 @@ export const isZero = match(Passthru, (math, [T]) => { const eq = math.equal.resolve([T, T]) return ReturnsAs(eq, x => eq(z, x)) }) -export const nonImaginary = match(Passthru, boolnum(() => true)) +export const nonImaginary = match(Any, boolnum(() => true)) export const re = match(Any, (_math, T) => Returns(T, t => t)) export const im = match(Any, (math, T) => { const z = math.zero(T) diff --git a/src/vector/__test__/utils.spec.js b/src/vector/__test__/utils.spec.js index 0e1a56e..eb1f0cc 100644 --- a/src/vector/__test__/utils.spec.js +++ b/src/vector/__test__/utils.spec.js @@ -18,6 +18,23 @@ describe('Vector utility functions', () => { assert(clone3[0] !== subj3[0]) assert(clone3[1] !== subj3[1]) }) + it('performs utilities elementwise', () => { + const cplx = math.complex + const sink = math.vector( + NaN, -Infinity, 7, + cplx(3, 4), cplx(3.5, -2.5), cplx(2.2), cplx(cplx(3, 4)) + ) + const t = true, f = false + assert.deepStrictEqual(math.isnan(sink), [t, f, f, f, f, f, f]) + assert.deepStrictEqual(math.isfinite(sink), [f, f, t, t, t, t, t]) + assert.deepStrictEqual(math.isInteger(sink), [f, f, t, t, f, f, t]) + assert.deepStrictEqual(math.isReal(sink), [t, t, t, f, f, t, f]) + assert.deepStrictEqual(math.nonImaginary(sink), [t, t, t, f, f, t, t]) + assert.deepStrictEqual(math.re(sink), [NaN, -Infinity, 7, 3, 3.5, 2.2, 3]) + assert.deepStrictEqual( + math.im(sink), + [0, 0, 0, cplx(0, 4), cplx(0, -2.5), cplx(0, 0), cplx(cplx(0, 4))]) + }) }) diff --git a/src/vector/utils.js b/src/vector/utils.js index c717a96..54c6fa9 100644 --- a/src/vector/utils.js +++ b/src/vector/utils.js @@ -1,3 +1,10 @@ import {promoteUnary} from './helpers.js' export const clone = promoteUnary('clone') +export const isnan = promoteUnary('isnan') +export const isfinite = promoteUnary('isfinite') +export const isInteger = promoteUnary('isInteger') +export const isReal = promoteUnary('isReal') +export const nonImaginary = promoteUnary('nonImaginary') +export const re = promoteUnary('re') +export const im = promoteUnary('im')