Merge pull request 'fix(Types): Move distinct types into distinct identifiers' (#28) from bigint_sqrt into main
Reviewed-on: #28
This commit is contained in:
commit
58fa661a2d
@ -1,8 +1,7 @@
|
|||||||
{
|
{
|
||||||
name: 'pocomath',
|
name: 'pocomath',
|
||||||
version: '0.0.0',
|
version: '0.0.0',
|
||||||
description: 'A little proof-of-concept for organizing mathjs by module\
|
description: 'A little proof-of-concept for organizing mathjs by module inclusion, avoiding factory functions.',
|
||||||
inclusion, avoiding factory functions.',
|
|
||||||
main: 'index.js',
|
main: 'index.js',
|
||||||
scripts: {
|
scripts: {
|
||||||
'test:filecase': '!(find . | sort -f | uniq -i -c | grep -v " 1 ")',
|
'test:filecase': '!(find . | sort -f | uniq -i -c | grep -v " 1 ")',
|
||||||
@ -24,6 +23,7 @@
|
|||||||
mocha: '^10.0.0',
|
mocha: '^10.0.0',
|
||||||
},
|
},
|
||||||
dependencies: {
|
dependencies: {
|
||||||
|
'bigint-isqrt': '^0.2.1',
|
||||||
'typed-function': '^3.0.0',
|
'typed-function': '^3.0.0',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
lockfileVersion: 5.4
|
lockfileVersion: 5.4
|
||||||
|
|
||||||
specifiers:
|
specifiers:
|
||||||
|
bigint-isqrt: ^0.2.1
|
||||||
mocha: ^10.0.0
|
mocha: ^10.0.0
|
||||||
typed-function: ^3.0.0
|
typed-function: ^3.0.0
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
|
bigint-isqrt: 0.2.1
|
||||||
typed-function: 3.0.0
|
typed-function: 3.0.0
|
||||||
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
@ -49,6 +51,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/bigint-isqrt/0.2.1:
|
||||||
|
resolution: {integrity: sha512-x43s2Qx5l5ShFZFA5xejJfPtV1vXISyWUXlrZeJTx9F6D2ex3BR6AwWnIz4ITAu5nTy3hp+d+ClGu7qUGcgY8g==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/binary-extensions/2.2.0:
|
/binary-extensions/2.2.0:
|
||||||
resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
|
resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
export const Types = {
|
export const Type_bigint = {
|
||||||
bigint: {
|
before: ['Complex'],
|
||||||
before: ['Complex'],
|
test: b => typeof b === 'bigint'
|
||||||
test: b => typeof b === 'bigint'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export {Types} from './Types/bigint.mjs'
|
export * from './Types/bigint.mjs'
|
||||||
|
|
||||||
export const add = {
|
export const add = {
|
||||||
'...bigint': () => addends => addends.reduce((x,y) => x+y, 0n)
|
'...bigint': () => addends => addends.reduce((x,y) => x+y, 0n)
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
export {Types} from './Types/bigint.mjs'
|
export * from './native.mjs'
|
||||||
export {add} from './add.mjs'
|
export * from '../generic/arithmetic.mjs'
|
||||||
export {negate} from './negate.mjs'
|
|
||||||
export {subtract} from '../generic/subtract.mjs'
|
// resolve the conflicts
|
||||||
|
export {divide} from './divide.mjs'
|
||||||
|
export {multiply} from './multiply.mjs'
|
||||||
|
export {sign} from './sign.mjs'
|
||||||
|
export {sqrt} from './sqrt.mjs'
|
||||||
|
20
src/bigint/divide.mjs
Normal file
20
src/bigint/divide.mjs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
export * from './Types/bigint.mjs'
|
||||||
|
|
||||||
|
export const divide = {
|
||||||
|
'bigint,bigint': ({config, 'sign(bigint)': sgn}) => {
|
||||||
|
if (config.predictable) {
|
||||||
|
return (n, d) => {
|
||||||
|
if (sgn(n) === sgn(d)) return n/d
|
||||||
|
const quot = n/d
|
||||||
|
if (quot * d == n) return quot
|
||||||
|
return quot - 1n
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return (n, d) => {
|
||||||
|
const quot = n/d
|
||||||
|
if (quot * d == n) return quot
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
5
src/bigint/multiply.mjs
Normal file
5
src/bigint/multiply.mjs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export * from './Types/bigint.mjs'
|
||||||
|
|
||||||
|
export const multiply = {
|
||||||
|
'...bigint': () => multiplicands => multiplicands.reduce((x,y) => x*y, 1n)
|
||||||
|
}
|
9
src/bigint/native.mjs
Normal file
9
src/bigint/native.mjs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
export * from './Types/bigint.mjs'
|
||||||
|
export {add} from './add.mjs'
|
||||||
|
export {divide} from './divide.mjs'
|
||||||
|
export {multiply} from './multiply.mjs'
|
||||||
|
export {negate} from './negate.mjs'
|
||||||
|
export {one} from './one.mjs'
|
||||||
|
export {sign} from './sign.mjs'
|
||||||
|
export {sqrt} from './sqrt.mjs'
|
||||||
|
export {zero} from './zero.mjs'
|
@ -1,3 +1,3 @@
|
|||||||
export {Types} from './Types/bigint.mjs'
|
export * from './Types/bigint.mjs'
|
||||||
|
|
||||||
export const negate = {bigint: () => b => -b}
|
export const negate = {bigint: () => b => -b}
|
||||||
|
3
src/bigint/one.mjs
Normal file
3
src/bigint/one.mjs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export * from './Types/bigint.mjs'
|
||||||
|
|
||||||
|
export const one = {bigint: () => () => 1n}
|
9
src/bigint/sign.mjs
Normal file
9
src/bigint/sign.mjs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
export * from './Types/bigint.mjs'
|
||||||
|
|
||||||
|
export const sign = {
|
||||||
|
bigint: () => b => {
|
||||||
|
if (b === 0n) return 0n
|
||||||
|
if (b > 0n) return 1n
|
||||||
|
return -1n
|
||||||
|
}
|
||||||
|
}
|
30
src/bigint/sqrt.mjs
Normal file
30
src/bigint/sqrt.mjs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
export * from './Types/bigint.mjs'
|
||||||
|
import isqrt from 'bigint-isqrt'
|
||||||
|
|
||||||
|
export const sqrt = {
|
||||||
|
bigint: ({config, complex, 'self(Complex)': complexSqrt}) => {
|
||||||
|
if (config.predictable) {
|
||||||
|
// Don't just return the constant isqrt here because the object
|
||||||
|
// gets decorated with info that might need to be different
|
||||||
|
// for different PocomathInstancss
|
||||||
|
return b => isqrt(b)
|
||||||
|
}
|
||||||
|
if (!complexSqrt) {
|
||||||
|
return b => {
|
||||||
|
if (b >= 0n) {
|
||||||
|
const trial = isqrt(b)
|
||||||
|
if (trial * trial === b) return trial
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b => {
|
||||||
|
if (b >= 0n) {
|
||||||
|
const trial = isqrt(b)
|
||||||
|
if (trial * trial === b) return trial
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
return complexSqrt(complex(b))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
src/bigint/zero.mjs
Normal file
3
src/bigint/zero.mjs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export * from './Types/bigint.mjs'
|
||||||
|
|
||||||
|
export const zero = {bigint: () => () => 0n}
|
@ -2,21 +2,15 @@
|
|||||||
* can be any type (for this proof-of-concept; in reality we'd want to
|
* can be any type (for this proof-of-concept; in reality we'd want to
|
||||||
* insist on some numeric or scalar supertype).
|
* insist on some numeric or scalar supertype).
|
||||||
*/
|
*/
|
||||||
export function isComplex(z) {
|
function isComplex(z) {
|
||||||
return z && typeof z === 'object' && 're' in z && 'im' in z
|
return z && typeof z === 'object' && 're' in z && 'im' in z
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Types = {
|
export const Type_Complex = {
|
||||||
Complex: {
|
test: isComplex,
|
||||||
test: isComplex,
|
from: {
|
||||||
from: {
|
number: x => ({re: x, im: 0}),
|
||||||
number: x => ({re: x, im: 0}),
|
bigint: x => ({re: x, im: 0n})
|
||||||
bigint: x => ({re: x, im: 0n})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* test if an entity is Complex<number>, so to speak: */
|
|
||||||
export function numComplex(z) {
|
|
||||||
return isComplex(z) && typeof z.re === 'number' && typeof z.im === 'number'
|
|
||||||
}
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export {Types} from './Types/Complex.mjs'
|
export * from './Types/Complex.mjs'
|
||||||
|
|
||||||
export const abs = {Complex: ({sqrt, add, multiply}) => z => {
|
export const abs = {Complex: ({sqrt, add, multiply}) => z => {
|
||||||
return sqrt(add(multiply(z.re, z.re), multiply(z.im, z.im)))
|
return sqrt(add(multiply(z.re, z.re), multiply(z.im, z.im)))
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export {Types} from './Types/Complex.mjs'
|
export * from './Types/Complex.mjs'
|
||||||
|
|
||||||
export const add = {
|
export const add = {
|
||||||
'...Complex': ({self}) => addends => {
|
'...Complex': ({self}) => addends => {
|
||||||
|
@ -1,2 +1,5 @@
|
|||||||
export * from './native.mjs'
|
|
||||||
export * from '../generic/arithmetic.mjs'
|
export * from '../generic/arithmetic.mjs'
|
||||||
|
export * from './native.mjs'
|
||||||
|
|
||||||
|
// resolve the conflicts
|
||||||
|
export {sqrt} from './sqrt.mjs'
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
export {Types} from './Types/Complex.mjs'
|
export * from './Types/Complex.mjs'
|
||||||
|
export * from '../generic/Types/generic.mjs'
|
||||||
|
|
||||||
export const complex = {
|
export const complex = {
|
||||||
/* Very permissive for sake of proof-of-concept; would be better to
|
/* Very permissive for sake of proof-of-concept; would be better to
|
||||||
* have a numeric/scalar type, e.g. by implementing subtypes in
|
* have a numeric/scalar type, e.g. by implementing subtypes in
|
||||||
* typed-function
|
* typed-function
|
||||||
*/
|
*/
|
||||||
'any, any': () => (x, y) => ({re: x, im: y}),
|
'undefined': () => u => u,
|
||||||
|
'undefined,any': () => (u, y) => u,
|
||||||
|
'any,undefined': () => (x, u) => u,
|
||||||
|
'any,any': () => (x, y) => ({re: x, im: y}),
|
||||||
/* Take advantage of conversions in typed-function */
|
/* Take advantage of conversions in typed-function */
|
||||||
Complex: () => z => z
|
Complex: () => z => z
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export {Types} from './Types/Complex.mjs'
|
export * from './Types/Complex.mjs'
|
||||||
|
|
||||||
export {abs} from './abs.mjs'
|
export {abs} from './abs.mjs'
|
||||||
export {add} from './add.mjs'
|
export {add} from './add.mjs'
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export {Types} from './Types/Complex.mjs'
|
export * from './Types/Complex.mjs'
|
||||||
|
|
||||||
export const negate = {
|
export const negate = {
|
||||||
Complex: ({self}) => z => ({re: self(z.re), im: self(z.im)})
|
Complex: ({self}) => z => ({re: self(z.re), im: self(z.im)})
|
||||||
|
@ -1,35 +1,44 @@
|
|||||||
export { Types } from './Types/Complex.mjs'
|
export * from './Types/Complex.mjs'
|
||||||
|
|
||||||
export const sqrt = {
|
export const sqrt = {
|
||||||
Complex: ({
|
Complex: ({
|
||||||
config,
|
config,
|
||||||
|
zero,
|
||||||
|
sign,
|
||||||
|
one,
|
||||||
|
add,
|
||||||
complex,
|
complex,
|
||||||
multiply,
|
multiply,
|
||||||
sign,
|
|
||||||
self,
|
self,
|
||||||
divide,
|
divide,
|
||||||
add,
|
|
||||||
'abs(Complex)': abs,
|
'abs(Complex)': abs,
|
||||||
subtract
|
subtract
|
||||||
}) => {
|
}) => {
|
||||||
if (config.predictable) {
|
if (config.predictable) {
|
||||||
return z => {
|
return z => {
|
||||||
|
const imZero = zero(z.im)
|
||||||
const imSign = sign(z.im)
|
const imSign = sign(z.im)
|
||||||
|
const reOne = one(z.re)
|
||||||
const reSign = sign(z.re)
|
const reSign = sign(z.re)
|
||||||
if (imSign === 0 && reSign === 1) return complex(self(z.re))
|
if (imSign === imZero && reSign === reOne) return complex(self(z.re))
|
||||||
|
const reTwo = add(reOne, reOne)
|
||||||
return complex(
|
return complex(
|
||||||
multiply(sign(z.im), self(divide(add(abs(z),z.re), 2))),
|
multiply(sign(z.im), self(divide(add(abs(z),z.re), reTwo))),
|
||||||
self(divide(subtract(abs(z),z.re), 2))
|
self(divide(subtract(abs(z),z.re), reTwo))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return z => {
|
return z => {
|
||||||
|
const imZero = zero(z.im)
|
||||||
const imSign = sign(z.im)
|
const imSign = sign(z.im)
|
||||||
|
const reOne = one(z.re)
|
||||||
const reSign = sign(z.re)
|
const reSign = sign(z.re)
|
||||||
if (imSign === 0 && reSign === 1) return self(z.re)
|
if (imSign === imZero && reSign === reOne) return self(z.re)
|
||||||
|
const reTwo = add(reOne, reOne)
|
||||||
|
const partial = add(abs(z), z.re)
|
||||||
return complex(
|
return complex(
|
||||||
multiply(sign(z.im), self(divide(add(abs(z),z.re), 2))),
|
multiply(sign(z.im), self(divide(add(abs(z),z.re), reTwo))),
|
||||||
self(divide(subtract(abs(z),z.re), 2))
|
self(divide(subtract(abs(z),z.re), reTwo))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,8 @@ export default class PocomathInstance {
|
|||||||
* in that if a new top-level PocomathInstance method is added, its name
|
* in that if a new top-level PocomathInstance method is added, its name
|
||||||
* must be added to this list.
|
* must be added to this list.
|
||||||
*/
|
*/
|
||||||
static reserved = new Set(['config', 'importDependencies', 'install', 'name'])
|
static reserved = new Set([
|
||||||
|
'config', 'importDependencies', 'install', 'name', 'Types'])
|
||||||
|
|
||||||
constructor(name) {
|
constructor(name) {
|
||||||
this.name = name
|
this.name = name
|
||||||
@ -65,10 +66,11 @@ export default class PocomathInstance {
|
|||||||
* operation in the body of the implementation. [NOTE: this signature-
|
* operation in the body of the implementation. [NOTE: this signature-
|
||||||
* specific reference is not yet implemented.]
|
* specific reference is not yet implemented.]
|
||||||
*
|
*
|
||||||
* Note that the "operation" named `Types` is special: it gives
|
* Note that any "operation" whose name begins with `Type_` is special:
|
||||||
* types that must be installed in the instance. In this case, the keys
|
* it defines a types that must be installed in the instance.
|
||||||
* are type names, and the values are plain objects with the following
|
* The remainder of the "operation" name following the `_` is the
|
||||||
* properties:
|
* name of the type. The value of the "operation" should be a plain
|
||||||
|
* object with the following properties:
|
||||||
*
|
*
|
||||||
* - test: the predicate for the type
|
* - test: the predicate for the type
|
||||||
* - from: a plain object mapping the names of types that can be converted
|
* - from: a plain object mapping the names of types that can be converted
|
||||||
@ -78,8 +80,8 @@ export default class PocomathInstance {
|
|||||||
*/
|
*/
|
||||||
install(ops) {
|
install(ops) {
|
||||||
for (const [item, spec] of Object.entries(ops)) {
|
for (const [item, spec] of Object.entries(ops)) {
|
||||||
if (item === 'Types') {
|
if (item.slice(0,5) === 'Type_') {
|
||||||
this._installTypes(spec)
|
this._installType(item.slice(5), spec)
|
||||||
} else {
|
} else {
|
||||||
this._installOp(item, spec)
|
this._installOp(item, spec)
|
||||||
}
|
}
|
||||||
@ -128,43 +130,40 @@ export default class PocomathInstance {
|
|||||||
/* Used internally by install, see the documentation there.
|
/* Used internally by install, see the documentation there.
|
||||||
* Note that unlike _installOp below, we can do this immediately
|
* Note that unlike _installOp below, we can do this immediately
|
||||||
*/
|
*/
|
||||||
_installTypes(typeSpecs) {
|
_installType(type, spec) {
|
||||||
for (const [type, spec] of Object.entries(typeSpecs)) {
|
if (type in this.Types) {
|
||||||
if (type in this.Types) {
|
if (spec !== this.Types[type]) {
|
||||||
if (spec !== this.Types[type]) {
|
throw new SyntaxError(`Conflicting definitions of type ${type}`)
|
||||||
throw new SyntaxError(
|
|
||||||
`Conflicting definitions of type ${type}`)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
let beforeType = 'any'
|
return
|
||||||
for (const other of spec.before || []) {
|
|
||||||
if (other in this.Types) {
|
|
||||||
beforeType = other
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this._typed.addTypes([{name: type, test: spec.test}], beforeType)
|
|
||||||
/* Now add conversions to this type */
|
|
||||||
for (const from in (spec.from || {})) {
|
|
||||||
if (from in this.Types) {
|
|
||||||
this._typed.addConversion(
|
|
||||||
{from, to: type, convert: spec.from[from]})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* And add conversions from this type */
|
|
||||||
for (const to in this.Types) {
|
|
||||||
if (type in (this.Types[to].from || {})) {
|
|
||||||
this._typed.addConversion(
|
|
||||||
{from: type, to, convert: this.Types[to].from[type]})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.Types[type] = spec
|
|
||||||
// rebundle anything that uses the new type:
|
|
||||||
this._invalidateDependents(':' + type)
|
|
||||||
}
|
}
|
||||||
|
let beforeType = 'any'
|
||||||
|
for (const other of spec.before || []) {
|
||||||
|
if (other in this.Types) {
|
||||||
|
beforeType = other
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._typed.addTypes([{name: type, test: spec.test}], beforeType)
|
||||||
|
/* Now add conversions to this type */
|
||||||
|
for (const from in (spec.from || {})) {
|
||||||
|
if (from in this.Types) {
|
||||||
|
this._typed.addConversion(
|
||||||
|
{from, to: type, convert: spec.from[from]})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* And add conversions from this type */
|
||||||
|
for (const to in this.Types) {
|
||||||
|
if (type in (this.Types[to].from || {})) {
|
||||||
|
this._typed.addConversion(
|
||||||
|
{from: type, to, convert: this.Types[to].from[type]})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.Types[type] = spec
|
||||||
|
// rebundle anything that uses the new type:
|
||||||
|
this._invalidateDependents(':' + type)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Used internally by install, see the documentation there */
|
/* Used internally by install, see the documentation there */
|
||||||
_installOp(name, implementations) {
|
_installOp(name, implementations) {
|
||||||
if (name.charAt(0) === '_') {
|
if (name.charAt(0) === '_') {
|
||||||
|
2
src/generic/Types/generic.mjs
Normal file
2
src/generic/Types/generic.mjs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export const Type_undefined = {test: u => u === undefined}
|
||||||
|
|
@ -1,3 +1,7 @@
|
|||||||
|
export * from './Types/generic.mjs'
|
||||||
|
|
||||||
|
export {multiply} from './multiply.mjs'
|
||||||
export {divide} from './divide.mjs'
|
export {divide} from './divide.mjs'
|
||||||
export {sign} from './sign.mjs'
|
export {sign} from './sign.mjs'
|
||||||
|
export {sqrt} from './sqrt.mjs'
|
||||||
export {subtract} from './subtract.mjs'
|
export {subtract} from './subtract.mjs'
|
||||||
|
12
src/generic/multiply.mjs
Normal file
12
src/generic/multiply.mjs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
export * from './Types/generic.mjs'
|
||||||
|
|
||||||
|
export const multiply = {
|
||||||
|
'undefined': () => u => u,
|
||||||
|
'undefined,...any': () => (u, rest) => u,
|
||||||
|
'any,undefined': () => (x, u) => u,
|
||||||
|
'any,undefined,...any': () => (x, u, rest) => u,
|
||||||
|
'any,any,undefined': () => (x, y, u) => u,
|
||||||
|
'any,any,undefined,...any': () => (x, y, u, rest) => u
|
||||||
|
// Bit of a hack since this should go on indefinitely...
|
||||||
|
}
|
||||||
|
|
3
src/generic/sqrt.mjs
Normal file
3
src/generic/sqrt.mjs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export * from './Types/generic.mjs'
|
||||||
|
|
||||||
|
export const sqrt = {undefined: () => () => undefined}
|
@ -1,8 +1,6 @@
|
|||||||
export const Types = {
|
export const Type_number = {
|
||||||
number: {
|
before: ['Complex'],
|
||||||
before: ['Complex'],
|
test: n => typeof n === 'number',
|
||||||
test: n => typeof n === 'number',
|
from: {string: s => +s}
|
||||||
from: {string: s => +s}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
export {Types} from './Types/number.mjs'
|
export * from './Types/number.mjs'
|
||||||
|
|
||||||
export const abs = {number: () => n => Math.abs(n)}
|
export const abs = {number: () => n => Math.abs(n)}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export {Types} from './Types/number.mjs'
|
export * from './Types/number.mjs'
|
||||||
|
|
||||||
export const add = {
|
export const add = {
|
||||||
'...number': () => addends => addends.reduce((x,y) => x+y, 0),
|
'...number': () => addends => addends.reduce((x,y) => x+y, 0),
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
export {Types} from './Types/number.mjs'
|
|
||||||
|
|
||||||
export * from './native.mjs'
|
|
||||||
export * from '../generic/arithmetic.mjs'
|
export * from '../generic/arithmetic.mjs'
|
||||||
|
export * from './native.mjs'
|
||||||
|
|
||||||
|
// resolve the conflicts
|
||||||
|
export {sqrt} from './sqrt.mjs'
|
||||||
|
export {multiply} from './multiply.mjs'
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
export {Types} from './Types/number.mjs'
|
export * from './Types/number.mjs'
|
||||||
|
|
||||||
export const invert = {number: () => n => 1/n}
|
export const invert = {number: () => n => 1/n}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export {Types} from './Types/number.mjs'
|
export * from './Types/number.mjs'
|
||||||
|
|
||||||
export const multiply = {
|
export const multiply = {
|
||||||
'...number': () => multiplicands => multiplicands.reduce((x,y) => x*y, 1),
|
'...number': () => multiplicands => multiplicands.reduce((x,y) => x*y, 1),
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
export {Types} from './Types/number.mjs'
|
|
||||||
export {add} from './add.mjs'
|
|
||||||
export {negate} from './negate.mjs'
|
|
||||||
export {sqrt} from './sqrt.mjs'
|
|
@ -1,8 +1,10 @@
|
|||||||
export {Types} from './Types/number.mjs'
|
export * from './Types/number.mjs'
|
||||||
|
|
||||||
export {abs} from './abs.mjs'
|
export {abs} from './abs.mjs'
|
||||||
export {add} from './add.mjs'
|
export {add} from './add.mjs'
|
||||||
export {invert} from './invert.mjs'
|
export {invert} from './invert.mjs'
|
||||||
export {multiply} from './multiply.mjs'
|
export {multiply} from './multiply.mjs'
|
||||||
export {negate} from './negate.mjs'
|
export {negate} from './negate.mjs'
|
||||||
|
export {one} from './one.mjs'
|
||||||
export {sqrt} from './sqrt.mjs'
|
export {sqrt} from './sqrt.mjs'
|
||||||
|
export {zero} from './zero.mjs'
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
export { Types } from './Types/number.mjs'
|
export * from './Types/number.mjs'
|
||||||
|
|
||||||
export const negate = {number: () => n => -n}
|
export const negate = {number: () => n => -n}
|
||||||
|
3
src/number/one.mjs
Normal file
3
src/number/one.mjs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export * from './Types/number.mjs'
|
||||||
|
|
||||||
|
export const one = {number: () => () => 1}
|
@ -1,4 +1,4 @@
|
|||||||
export { Types } from './Types/number.mjs'
|
export * from './Types/number.mjs'
|
||||||
|
|
||||||
export const sqrt = {
|
export const sqrt = {
|
||||||
number: ({config, complex, 'self(Complex)': complexSqrt}) => {
|
number: ({config, complex, 'self(Complex)': complexSqrt}) => {
|
||||||
|
3
src/number/zero.mjs
Normal file
3
src/number/zero.mjs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export * from './Types/number.mjs'
|
||||||
|
|
||||||
|
export const zero = {number: () => () => 0}
|
@ -1,7 +1,7 @@
|
|||||||
/* Core of pocomath: generates the default instance */
|
/* Core of pocomath: generates the default instance */
|
||||||
import PocomathInstance from './core/PocomathInstance.mjs'
|
import PocomathInstance from './core/PocomathInstance.mjs'
|
||||||
import * as numbers from './number/native.mjs'
|
import * as numbers from './number/native.mjs'
|
||||||
import * as bigints from './bigint/all.mjs'
|
import * as bigints from './bigint/native.mjs'
|
||||||
import * as complex from './complex/native.mjs'
|
import * as complex from './complex/native.mjs'
|
||||||
import * as generic from './generic/all.mjs'
|
import * as generic from './generic/all.mjs'
|
||||||
|
|
||||||
|
@ -22,11 +22,9 @@ describe('The default full pocomath instance "math"', () => {
|
|||||||
add: {
|
add: {
|
||||||
'...stringK': () => addends => addends.reduce((x,y) => x+y, '')
|
'...stringK': () => addends => addends.reduce((x,y) => x+y, '')
|
||||||
},
|
},
|
||||||
Types: {
|
Type_stringK: {
|
||||||
stringK: {
|
test: s => typeof s === 'string' && s.charAt(0) === 'K',
|
||||||
test: s => typeof s === 'string' && s.charAt(0) === 'K',
|
before: ['string']
|
||||||
before: ['string']
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
assert.strictEqual(math.add('Kilroy','K is here'), 'KilroyK is here')
|
assert.strictEqual(math.add('Kilroy','K is here'), 'KilroyK is here')
|
||||||
|
55
test/bigint/_all.mjs
Normal file
55
test/bigint/_all.mjs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import assert from 'assert'
|
||||||
|
import math from '../../src/pocomath.mjs'
|
||||||
|
import PocomathInstance from '../../src/core/PocomathInstance.mjs'
|
||||||
|
import * as bigintSqrt from '../../src/bigint/sqrt.mjs'
|
||||||
|
import * as complex from '../../src/complex/all.mjs'
|
||||||
|
import * as bigints from '../../src/bigint/all.mjs'
|
||||||
|
|
||||||
|
describe('bigint', () => {
|
||||||
|
it('can divide', () => {
|
||||||
|
assert.strictEqual(math.divide(15n, 5n), 3n)
|
||||||
|
assert.strictEqual(math.divide(14n, 5n), undefined)
|
||||||
|
math.config.predictable = true
|
||||||
|
assert.strictEqual(math.divide(14n, 5n), 2n)
|
||||||
|
assert.strictEqual(math.divide(-14n, 5n), -3n)
|
||||||
|
assert.strictEqual(math.divide(14n, -5n), -3n)
|
||||||
|
assert.strictEqual(math.divide(-14n, -5n), 2n)
|
||||||
|
math.config.predictable = false
|
||||||
|
})
|
||||||
|
|
||||||
|
it('supports sqrt', () => {
|
||||||
|
assert.strictEqual(math.sqrt(0n), 0n)
|
||||||
|
assert.strictEqual(math.sqrt(4n), 2n)
|
||||||
|
assert.strictEqual(math.sqrt(5n), undefined)
|
||||||
|
assert.strictEqual(
|
||||||
|
math.sqrt(82120471531550314555681345949499512621827274120673745141541602816614526075010755373654280259022317599142038423759320355177481886719814621305828811322920076213800348341464996337890625n),
|
||||||
|
9062034624274524065844376014975805577107171799890766992670739972241112960081909332275390625n)
|
||||||
|
assert.deepStrictEqual(math.sqrt(-9n), math.complex(0n, 3n))
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
math.sqrt(math.complex(5n, 12n)),
|
||||||
|
math.complex(3n, 2n))
|
||||||
|
assert.deepStrictEqual(math.sqrt(math.complex(1n, 0n)), 1n)
|
||||||
|
assert.deepStrictEqual(math.sqrt(math.complex(0n, 1n)), undefined)
|
||||||
|
math.config.predictable = true
|
||||||
|
assert.strictEqual(math.sqrt(-9n), -9n)
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
math.sqrt(math.complex(1n, 0n)), math.complex(1n, 0n))
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
math.sqrt(math.complex(0n, 1n)), math.complex(0n, 0n))
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
math.sqrt(math.complex(0n, 2n)), math.complex(1n, 1n))
|
||||||
|
math.config.predictable = false
|
||||||
|
assert.deepStrictEqual(math.sqrt(-1024n), math.complex(0n, 32n))
|
||||||
|
})
|
||||||
|
|
||||||
|
it('supports sqrt by itself', () => {
|
||||||
|
const bo = new PocomathInstance('BigInts Only')
|
||||||
|
bo.install(bigintSqrt)
|
||||||
|
assert.strictEqual(bo.sqrt(256n), 16n)
|
||||||
|
assert.strictEqual(bo.sqrt(-17n), undefined)
|
||||||
|
bo.install(complex)
|
||||||
|
bo.install(bigints)
|
||||||
|
assert.deepStrictEqual(bo.sqrt(-3249n), bo.complex(0n, 57n))
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
@ -9,6 +9,9 @@ describe('complex', () => {
|
|||||||
assert.deepStrictEqual(
|
assert.deepStrictEqual(
|
||||||
math.sqrt(math.complex(0,1)),
|
math.sqrt(math.complex(0,1)),
|
||||||
math.complex(math.sqrt(0.5), math.sqrt(0.5)))
|
math.complex(math.sqrt(0.5), math.sqrt(0.5)))
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
math.sqrt(math.complex(5, 12)),
|
||||||
|
math.complex(3, 2))
|
||||||
math.config.predictable = true
|
math.config.predictable = true
|
||||||
assert.deepStrictEqual(math.sqrt(math.complex(1,0)), math.complex(1,0))
|
assert.deepStrictEqual(math.sqrt(math.complex(1,0)), math.complex(1,0))
|
||||||
assert.deepStrictEqual(
|
assert.deepStrictEqual(
|
||||||
|
@ -23,7 +23,7 @@ describe('A custom instance', () => {
|
|||||||
|
|
||||||
it("can be assembled in any order", () => {
|
it("can be assembled in any order", () => {
|
||||||
bw.install(numbers)
|
bw.install(numbers)
|
||||||
bw.install({Types: {string: {test: s => typeof s === 'string'}}})
|
bw.install({Type_string: {test: s => typeof s === 'string'}})
|
||||||
assert.strictEqual(bw.subtract(16, bw.add(3,4,2)), 7)
|
assert.strictEqual(bw.subtract(16, bw.add(3,4,2)), 7)
|
||||||
assert.strictEqual(bw.negate('8'), -8)
|
assert.strictEqual(bw.negate('8'), -8)
|
||||||
assert.deepStrictEqual(bw.add(bw.complex(1,3), 1), {re: 2, im: 3})
|
assert.deepStrictEqual(bw.add(bw.complex(1,3), 1), {re: 2, im: 3})
|
||||||
|
@ -4,6 +4,7 @@ import PocomathInstance from '../../src/core/PocomathInstance.mjs'
|
|||||||
import * as numberSqrt from '../../src/number/sqrt.mjs'
|
import * as numberSqrt from '../../src/number/sqrt.mjs'
|
||||||
import * as complex from '../../src/complex/all.mjs'
|
import * as complex from '../../src/complex/all.mjs'
|
||||||
import * as numbers from '../../src/number/all.mjs'
|
import * as numbers from '../../src/number/all.mjs'
|
||||||
|
|
||||||
describe('number', () => {
|
describe('number', () => {
|
||||||
it('supports sqrt', () => {
|
it('supports sqrt', () => {
|
||||||
assert.strictEqual(math.sqrt(4), 2)
|
assert.strictEqual(math.sqrt(4), 2)
|
||||||
|
Loading…
Reference in New Issue
Block a user