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 }) })