34 lines
1.2 KiB
JavaScript
34 lines
1.2 KiB
JavaScript
|
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
|
||
|
})
|
||
|
})
|