feat: Add complex numbers
With just the operations we have for numbers, and overall tests.
This commit is contained in:
parent
536656bfe8
commit
32bc9ca515
16
complex/add.js
Normal file
16
complex/add.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { anyComplex } from './complex.js'
|
||||||
|
|
||||||
|
export default function create(pmath) {
|
||||||
|
const complex = pmath('complex')
|
||||||
|
return pmath('add', [anyComplex, // naive, but this is just a P-o-C
|
||||||
|
(...addends) => {
|
||||||
|
let sum = complex(addends[0])
|
||||||
|
for (let i = 1; i < addends.length; ++i) {
|
||||||
|
const addend = complex(addends[i])
|
||||||
|
sum.re += addend.re
|
||||||
|
sum.im += addend.im
|
||||||
|
}
|
||||||
|
return sum
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
|
12
complex/all.js
Normal file
12
complex/all.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import createComplex from './complex.js'
|
||||||
|
import createAdd from './add.js'
|
||||||
|
import createNegate from './negate.js'
|
||||||
|
import createSubtract from '../generic/subtract.js'
|
||||||
|
|
||||||
|
export default function create(pmath) {
|
||||||
|
createComplex(pmath)
|
||||||
|
createAdd(pmath)
|
||||||
|
createNegate(pmath)
|
||||||
|
createSubtract(pmath)
|
||||||
|
// not sure if there's anything reasonable to return here
|
||||||
|
}
|
21
complex/complex.js
Normal file
21
complex/complex.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/* Use a plain object with keys re and im for a complex */
|
||||||
|
export function isComplex(z) {
|
||||||
|
return z && typeof z === 'object' && 're' in z && 'im' in z
|
||||||
|
}
|
||||||
|
|
||||||
|
export function anyComplex(args) {
|
||||||
|
for (let i = 0; i < args.length; ++i) {
|
||||||
|
if (isComplex(args[i])) return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function create(pmath) {
|
||||||
|
const number = pmath('number')
|
||||||
|
return pmath('complex', [
|
||||||
|
[args => args.length == 2, (x,y) => ({re: number(x), im: number(y)})],
|
||||||
|
[args => args.length == 1 && isComplex(args[0]), z => z],
|
||||||
|
[args => args.length == 1, x => ({re: number(x), im: 0})]
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
6
complex/negate.js
Normal file
6
complex/negate.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { isComplex } from './complex.js'
|
||||||
|
|
||||||
|
export default function create(pmath) {
|
||||||
|
return pmath('negate', [args => args.length == 1 && isComplex(args[0]),
|
||||||
|
z => ({re: -z.re, im: -z.im})])
|
||||||
|
}
|
@ -1,14 +1,18 @@
|
|||||||
|
export function isNumber(x) {
|
||||||
|
return typeof x === 'number'
|
||||||
|
}
|
||||||
|
|
||||||
export function allNumbers(args) {
|
export function allNumbers(args) {
|
||||||
for (let i = 0; i < args.length; ++i) {
|
for (let i = 0; i < args.length; ++i) {
|
||||||
if (typeof args[i] !== 'number') return false
|
if (!isNumber(args[i])) return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
export function oneNumber(args) {
|
export function oneNumber(args) {
|
||||||
return args.length === 1 && typeof args[0] === 'number'
|
return args.length === 1 && isNumber(args[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function create(pmath) {
|
export default function create(pmath) {
|
||||||
return pmath('number', [() => true, x => Number(x)])
|
return pmath('number', [() => true, x => Number(x)])
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
/* Core of picomath: generates an instance */
|
/* Core of picomath: generates an instance */
|
||||||
import picomathInstance from './picomathInstance.js'
|
import picomathInstance from './picomathInstance.js'
|
||||||
import createNumbers from './number/all.js'
|
import createNumbers from './number/all.js'
|
||||||
|
import createComplex from './complex/all.js'
|
||||||
|
|
||||||
const math = picomathInstance('math')
|
const math = picomathInstance('math')
|
||||||
createNumbers(math)
|
createNumbers(math)
|
||||||
|
createComplex(math)
|
||||||
|
|
||||||
export default math
|
export default math
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
import poortf from './poortf.js'
|
import poortf from './poortf.js'
|
||||||
|
|
||||||
export default function picomathInstance (instName) {
|
export default function picomathInstance (instName) {
|
||||||
|
/* Since we have to do it all the time, when we call a picomath instance
|
||||||
|
* as a function, it takes a name and 0 or more implementations add adds
|
||||||
|
* them to its poortf property named name, returning that property value.
|
||||||
|
*/
|
||||||
function fn (name, imps) {
|
function fn (name, imps) {
|
||||||
if (name in fn) {
|
if (name in fn) {
|
||||||
fn[name].addImps(imps)
|
fn[name].addImps(imps)
|
||||||
|
@ -12,4 +12,12 @@ describe('The default full picomath instance "math"', () => {
|
|||||||
(...addends) => addends.reduce((x,y) => x+y, '')])
|
(...addends) => addends.reduce((x,y) => x+y, '')])
|
||||||
assert.strictEqual(math.add('Kilroy',' is here'), 'Kilroy is here')
|
assert.strictEqual(math.add('Kilroy',' is here'), 'Kilroy is here')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('handles complex numbers', () => {
|
||||||
|
assert.deepStrictEqual(math.complex(2,3), {re: 2, im: 3})
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
math.subtract(16, math.add(3, math.complex(0,4), 2)),
|
||||||
|
math.complex(11, -4))
|
||||||
|
assert.deepStrictEqual(math.negate(math.complex(3, '8')).im, -8)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user