enable variance() and std() to use arrays with units (#1959)

This commit is contained in:
rnd-debug 2020-09-06 09:29:25 +02:00 committed by GitHub
parent 77ca248c39
commit d08f2bc893
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 89 additions and 10 deletions

View File

@ -97,7 +97,7 @@ export const createVariance = /* #__PURE__ */ factory(name, dependencies, ({ typ
* @private
*/
function _var (array, normalization) {
let sum = 0
let sum
let num = 0
if (array.length === 0) {
@ -107,7 +107,7 @@ export const createVariance = /* #__PURE__ */ factory(name, dependencies, ({ typ
// calculate the mean and number of elements
deepForEach(array, function (value) {
try {
sum = add(sum, value)
sum = sum === undefined ? value : add(sum, value)
num++
} catch (err) {
throw improveErrorMessage(err, 'variance', value)
@ -118,10 +118,10 @@ export const createVariance = /* #__PURE__ */ factory(name, dependencies, ({ typ
const mean = divide(sum, num)
// calculate the variance
sum = 0
sum = undefined
deepForEach(array, function (value) {
const diff = subtract(value, mean)
sum = add(sum, multiply(diff, diff))
sum = sum === undefined ? multiply(diff, diff) : add(sum, multiply(diff, diff))
})
if (isNaN(sum)) {

View File

@ -1,4 +1,5 @@
import assert from 'assert'
import approx from '../../../../tools/approx'
import math from '../../../../src/bundleAny'
const Unit = math.Unit
@ -34,7 +35,6 @@ describe('std', function () {
it('should throw an error if called with invalid type of arguments', function () {
assert.throws(function () { std(new Date(), 2) }, /Cannot calculate std, unexpected type of argument/)
assert.throws(function () { std(new Unit(5, 'cm'), new Unit(10, 'cm')) }, /Cannot calculate std, unexpected type of argument/)
assert.throws(function () { std(2, 3, null) }, /Cannot calculate std, unexpected type of argument/)
assert.throws(function () { std([2, 3, null]) }, /Cannot calculate std, unexpected type of argument/)
assert.throws(function () { std([[2, 4, 6], [1, 3, 5]], 'biased', 0) }, /Cannot convert "biased" to a number/)
@ -49,4 +49,25 @@ describe('std', function () {
const expression = math.parse('std(1,2,3)')
assert.strictEqual(expression.toTex(), '\\mathrm{std}\\left(1,2,3\\right)')
})
it('should compute the standard deviation value of quantities with units', function () {
const a = new Unit(2, 'cm')
const b = new Unit(5, 'cm')
const c = new Unit(8, 'cm')
const res = math.unit(3, 'cm')
approx.equal(std([a, b, c]).toNumber('cm'), res.toNumber('cm'))
})
it('should compute the standard deviation value of quantities with compatible units', function () {
const a = math.unit(1, 'm')
const b = math.unit(50, 'cm')
const c = math.unit(math.sqrt(1250), 'cm')
approx.equal(std([a, b]).toNumber('cm'), c.toNumber('cm'))
})
it('should not compute the standard deviation value of quantities with incompatible units', function () {
const a = math.unit(1, 'm')
const b = math.unit(50, 'kg')
assert.throws(function () { std([a, b]) }, /Units do not match/)
})
})

View File

@ -1,7 +1,7 @@
import assert from 'assert'
import approx from '../../../../tools/approx'
import math from '../../../../src/bundleAny'
const Unit = math.Unit
const variance = math.expression.transform.variance
describe('variance', function () {
@ -34,7 +34,6 @@ describe('variance', function () {
it('should throw an error if called with invalid type of arguments', function () {
assert.throws(function () { variance(new Date(), 2) }, /Cannot calculate variance, unexpected type of argument/)
assert.throws(function () { variance(new Unit(5, 'cm'), new Unit(10, 'cm')) }, /Cannot calculate variance, unexpected type of argument/)
assert.throws(function () { variance(2, 3, null) }, /Cannot calculate variance, unexpected type of argument/)
assert.throws(function () { variance([2, 3, null]) }, /Cannot calculate variance, unexpected type of argument/)
assert.throws(function () { variance([[2, 4, 6], [1, 3, 5]], 'biased', 0) }, /Cannot convert "biased" to a number/)
@ -49,4 +48,24 @@ describe('variance', function () {
const expression = math.parse('variance(1,2,3)')
assert.strictEqual(expression.toTex(), '\\mathrm{Var}\\left(1,2,3\\right)')
})
it('should compute the variance of quantities with units', function () {
const a = math.unit(10, 'cm')
const b = math.unit(20, 'cm')
const c = math.unit(50, 'cm^2')
approx.equal(variance([a, b]).toNumber('cm^2'), c.toNumber('cm^2'))
})
it('should compute the variance of quantities with compatible units', function () {
const a = math.unit(1, 'm')
const b = math.unit(50, 'cm')
const c = math.unit(1250, 'cm^2')
approx.equal(variance([a, b]).toNumber('cm^2'), c.toNumber('cm^2'))
})
it('should not compute the variance of quantities with incompatible units', function () {
const a = math.unit(1, 'm')
const b = math.unit(50, 'kg')
assert.throws(function () { variance([a, b]) }, /Units do not match/)
})
})

View File

@ -106,7 +106,6 @@ describe('std', function () {
it('should throw an error if called with invalid type of arguments', function () {
assert.throws(function () { std(new Date(), 2) }, /Cannot calculate std, unexpected type of argument/)
assert.throws(function () { std(new Unit(5, 'cm'), new Unit(10, 'cm')) }, /Cannot calculate std, unexpected type of argument/)
assert.throws(function () { std(2, 3, null) }, /Cannot calculate std, unexpected type of argument/)
assert.throws(function () { std([2, 3, null]) }, /Cannot calculate std, unexpected type of argument/)
assert.throws(function () { std([[2, 4, 6], [1, 3, 5]], 'biased', 0) }, /Cannot convert "biased" to a number/)
@ -121,4 +120,25 @@ describe('std', function () {
const expression = math.parse('std(1,2,3)')
assert.strictEqual(expression.toTex(), '\\mathrm{std}\\left(1,2,3\\right)')
})
it('should compute the standard deviation value of quantities with units', function () {
const a = new Unit(2, 'cm')
const b = new Unit(5, 'cm')
const c = new Unit(8, 'cm')
const res = math.unit(3, 'cm')
approx.equal(std([a, b, c]).toNumber('cm'), res.toNumber('cm'))
})
it('should compute the standard deviation value of quantities with compatible units', function () {
const a = math.unit(1, 'm')
const b = math.unit(50, 'cm')
const c = math.unit(math.sqrt(1250), 'cm')
approx.equal(std([a, b]).toNumber('cm'), c.toNumber('cm'))
})
it('should not compute the standard deviation value of quantities with incompatible units', function () {
const a = math.unit(1, 'm')
const b = math.unit(50, 'kg')
assert.throws(function () { std([a, b]) }, /Units do not match/)
})
})

View File

@ -1,9 +1,9 @@
import assert from 'assert'
import approx from '../../../../tools/approx'
import math from '../../../../src/bundleAny'
const BigNumber = math.BigNumber
const Complex = math.Complex
const DenseMatrix = math.DenseMatrix
const Unit = math.Unit
const variance = math.variance
describe('variance', function () {
@ -109,7 +109,6 @@ describe('variance', function () {
it('should throw an error if called with invalid type of arguments', function () {
assert.throws(function () { variance(new Date(), 2) }, /Cannot calculate variance, unexpected type of argument/)
assert.throws(function () { variance(new Unit(5, 'cm'), new Unit(10, 'cm')) }, /Cannot calculate variance, unexpected type of argument/)
assert.throws(function () { variance(2, 3, null) }, /Cannot calculate variance, unexpected type of argument/)
assert.throws(function () { variance([2, 3, null]) }, /Cannot calculate variance, unexpected type of argument/)
assert.throws(function () { variance([[2, 4, 6], [1, 3, 5]], 'biased', 0) }, /Cannot convert "biased" to a number/)
@ -128,4 +127,24 @@ describe('variance', function () {
const expression = math.parse('variance(1,2,3)')
assert.strictEqual(expression.toTex(), '\\mathrm{Var}\\left(1,2,3\\right)')
})
it('should compute the variance of quantities with units', function () {
const a = math.unit(10, 'cm')
const b = math.unit(20, 'cm')
const c = math.unit(50, 'cm^2')
approx.equal(variance([a, b]).toNumber('cm^2'), c.toNumber('cm^2'))
})
it('should compute the variance of quantities with compatible units', function () {
const a = math.unit(1, 'm')
const b = math.unit(50, 'cm')
const c = math.unit(1250, 'cm^2')
approx.equal(variance([a, b]).toNumber('cm^2'), c.toNumber('cm^2'))
})
it('should not compute the variance of quantities with incompatible units', function () {
const a = math.unit(1, 'm')
const b = math.unit(50, 'kg')
assert.throws(function () { variance([a, b]) }, /Units do not match/)
})
})