feat: Start adding vector arithmetic
So far, abs, add, norm, normsq, and sum are supported. To get them to work, also implements the following: * refactor: Use ReturnType function rather than just accessing .returns * feat: distinguish marking a function as a behavior from its return type * refactor: Rename `NotAType` to `Unknown` because it must be made closer to a bona fide type for the sake of inhomogeneous vectors * feat: make resolving a TypeDispatcher method on a type vector including `Unknown` into a no-op; that simplifies a number of generic behaviors * feat: add `haszero` method parallel to `hasnan` * feat: track the Vector nesting depth of Vector specializations
This commit is contained in:
parent
ec97b0e20a
commit
cb3a93dd1c
26 changed files with 238 additions and 171 deletions
33
src/vector/arithmetic.js
Normal file
33
src/vector/arithmetic.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
import {promoteBinary, promoteUnary} from './helpers.js'
|
||||
import {Vector} from './Vector.js'
|
||||
|
||||
import {ReturnType} from '#core/Type.js'
|
||||
import {match} from '#core/TypePatterns.js'
|
||||
import {ReturnsAs} from '#generic/helpers.js'
|
||||
|
||||
export const normsq = match(Vector, (math, V) => {
|
||||
const compNormsq = math.normsq.resolve(V.Component)
|
||||
const sum = math.sum.resolve(Vector(ReturnType(compNormsq)))
|
||||
return ReturnsAs(sum, v => sum(v.map(compNormsq)))
|
||||
})
|
||||
// abs and norm differ only on Vector (and perhaps other collections) --
|
||||
// norm computes overall by the generic formula, whereas abs distributes
|
||||
// elementwise:
|
||||
export const abs = promoteUnary('abs')
|
||||
export const add = promoteBinary('add')
|
||||
|
||||
export const sum = match(Vector, (math, V) => {
|
||||
const add = math.add.resolve([V.Component, V.Component])
|
||||
const haszero = math.haszero(V.Component)
|
||||
const zero = haszero ? math.zero(V.Component) : undefined
|
||||
return ReturnsAs(add, v => {
|
||||
if (v.length === 0) {
|
||||
if (haszero) return zero
|
||||
throw new TypeError(`Can't sum empty ${V}: no zero element`)
|
||||
}
|
||||
let ix = 0
|
||||
let retval = v[ix]
|
||||
while (++ix < v.length) retval = add(retval, v[ix])
|
||||
return retval
|
||||
})
|
||||
})
|
Loading…
Add table
Add a link
Reference in a new issue