feat: Homogeneous typed Tuple class using templates

This commit is contained in:
Glen Whitney 2022-08-05 05:44:28 -07:00
parent b0fb004224
commit 7ec9686019
20 changed files with 291 additions and 136 deletions

View file

@ -18,9 +18,10 @@ describe('A custom instance', () => {
it("works when partially assembled", () => {
bw.install(complex)
// Not much we can call without any number types:
const i3 = {re: 0, im: 3}
assert.deepStrictEqual(bw.complex(0, 3), i3)
assert.deepStrictEqual(bw.chain(0).complex(3).value, i3)
assert.deepStrictEqual(bw.complex(undefined, undefined), undefined)
assert.deepStrictEqual(
bw.chain(undefined).complex(undefined).value,
undefined)
// Don't have a way to negate things, for example:
assert.throws(() => bw.negate(2), TypeError)
})
@ -34,7 +35,7 @@ describe('A custom instance', () => {
assert.deepStrictEqual(
bw.subtract(16, bw.add(3, bw.complex(0,4), 2)),
math.complex(11, -4)) // note both instances coexist
assert.deepStrictEqual(bw.negate(math.complex(3, '8')).im, -8)
assert.deepStrictEqual(bw.negate(bw.complex(3, '8')).im, -8)
})
it("can be assembled piecemeal", () => {
@ -130,12 +131,9 @@ describe('A custom instance', () => {
inst.typeMerge(3, inst.complex(4.5,2.1)),
'Merge to Complex')
// The following is the current behavior, since 3 converts to 3+0i
// and 3n converts to 3n+0ni, both of which are technically Complex.
// This will remain the case even with templated Complex, because
// both Complex<bigint> and Complex<NumInt> will refine Complex (for the
// sake of catching new specializations). Not sure whether that will be
// OK or a problem that will have to be dealt with.
assert.strictEqual(inst.typeMerge(3, 3n), 'Merge to Complex')
// which is technically the same Complex type as 3n+0ni.
// This should clear up when Complex is templatized
assert.strictEqual(inst.typeMerge(3, inst.complex(3n)), 'Merge to Complex')
// But types that truly cannot be merged should throw a TypeError
// Should add a variation of this with a more usual type once there is
// one not interconvertible with others...

View file

@ -18,11 +18,97 @@ describe('tuple', () => {
{elts: [math.complex(3), math.complex(2n), math.complex(5.2)]})
})
it('can be tested for zero', () => {
it('can be tested for zero and equality', () => {
assert.strictEqual(math.isZero(math.tuple(0,1)), false)
assert.strictEqual(math.isZero(math.tuple(0n,0n,0n,0n)), true)
assert.strictEqual(math.isZero(math.tuple(0,0.001,0)), false)
assert.deepStrictEqual(math.complex(0,0), {re: 0, im:0})
assert.strictEqual(math.isZero(math.tuple(0,math.complex(0,0))), true)
assert.strictEqual(
math.equal(
math.tuple(0,math.complex(0,0.1)),
math.complex(math.tuple(0,0), math.tuple(0,0.1))),
true)
assert.strictEqual(
math.equal(math.tuple(3n,2n), math.tuple(3,2)),
false)
})
it('supports addition', () => {
assert.deepStrictEqual(
math.add(math.tuple(3,4,5), math.tuple(2,1,0)),
math.tuple(5,5,5))
assert.deepStrictEqual(
math.add(math.tuple(3.25,4.5,5), math.tuple(3,3)),
math.tuple(6.25,7.5,5))
assert.deepStrictEqual(
math.add(math.tuple(math.complex(2,3), 7), math.tuple(4, 5, 6)),
math.tuple(math.complex(6,3), math.complex(12), math.complex(6)))
assert.deepStrictEqual(
math.add(math.tuple(5,6), 7),
math.tuple(12,6))
assert.deepStrictEqual(
math.add(math.tuple(math.complex(5,4),6), 7),
math.tuple(math.complex(12,4),math.complex(6)))
})
it('supports subtraction', () => {
assert.deepStrictEqual(
math.subtract(math.tuple(3n,4n,5n), math.tuple(2n,1n,0n)),
math.tuple(1n,3n,5n))
assert.throws(
() => math.subtract(math.tuple(5,6), math.tuple(7)),
/RangeError/)
})
it('makes a tuple of complex and conjugates it', () => {
const complexTuple = math.tuple(
math.complex(3,1), math.complex(4,2.2), math.complex(5,3))
assert.deepStrictEqual(
math.complex(math.tuple(3,4,5), math.tuple(1,2.2,3)),
complexTuple)
assert.deepStrictEqual(
math.conjugate(complexTuple),
math.tuple(math.complex(3,-1), math.complex(4,-2.2), math.complex(5,-3)))
})
it('supports division', () => {
assert.deepStrictEqual(
math.divide(math.tuple(3,4,5),math.tuple(1,2,2)),
math.tuple(3,2,2.5))
})
it('supports multiplication', () => {
assert.deepStrictEqual(
math.multiply(math.tuple(3,4,5), math.tuple(1,2,2)),
math.tuple(3,8,10))
})
it('supports one and zero', () => {
assert.deepStrictEqual(
math.one(math.tuple(2n,3n,0n)),
math.tuple(1n,1n,1n))
assert.deepStrictEqual(
math.zero(math.tuple(math.complex(5,2), 3.4)),
math.tuple(math.complex(0), math.complex(0)))
})
it('supports quotient and roundquotient', () => {
const bigTuple = math.tuple(1n,2n,3n,4n,5n)
const bigOnes = math.one(bigTuple)
const threes = math.add(bigOnes, bigOnes, bigOnes)
assert.deepStrictEqual(
math.quotient(bigTuple, threes),
math.tuple(0n, 0n, 1n, 1n, 1n))
assert.deepStrictEqual(
math.roundquotient(bigTuple, threes),
math.tuple(0n, 1n, 1n, 1n, 2n))
})
it('supports sqrt', () => {
assert.deepStrictEqual(
math.sqrt(math.tuple(4,-4,2.25)),
math.tuple(2, math.complex(0,2), 1.5))
})
})