Skip to content

Commit

Permalink
added correlation function to statistics (#3015)
Browse files Browse the repository at this point in the history
* added correlation function to statistics

* added implemenation for signature Matrix, Matrix and support for BigNumbers

* reverted changes to default for version numbers of devDepenencies

* reverted changes to default for version numbers of devDepenencies in package-lock.json

* change variable name from xArray, yArray to x and y

* added Matrix as param in index.d.ts

* corrected the file and function names for correlation function

* renamed createCorrelation to createCorr in factoriesNumber.js

* fixed failing test case for matrix and added params and return in corr
  • Loading branch information
vrushaket authored Sep 1, 2023
1 parent 2a3c99d commit 1ee8733
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 0 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -231,5 +231,6 @@ MaybePixem <47889538+MaybePixem@users.noreply.github.com>
Aly Khaled <alykhaled2001@live.com>
BuildTools <anikpatel1322@gmail.com>
Anik Patel <74193405+Bobingstern@users.noreply.github.com>
vrushaket <vrushu00@gmail.com>

# Generated by tools/update-authors.js
2 changes: 2 additions & 0 deletions src/expression/embeddedDocs/embeddedDocs.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ import { stdDocs } from './function/statistics/std.js'
import { cumSumDocs } from './function/statistics/cumsum.js'
import { sumDocs } from './function/statistics/sum.js'
import { varianceDocs } from './function/statistics/variance.js'
import { corrDocs } from './function/statistics/corr.js'
import { acosDocs } from './function/trigonometry/acos.js'
import { acoshDocs } from './function/trigonometry/acosh.js'
import { acotDocs } from './function/trigonometry/acot.js'
Expand Down Expand Up @@ -543,6 +544,7 @@ export const embeddedDocs = {
std: stdDocs,
sum: sumDocs,
variance: varianceDocs,
corr: corrDocs,

// functions - trigonometry
acos: acosDocs,
Expand Down
22 changes: 22 additions & 0 deletions src/expression/embeddedDocs/function/statistics/corr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export const corrDocs = {
name: 'corr',
category: 'Statistics',
syntax: [
'corr(A,B)'
],
description: 'Compute the correlation coefficient of a two list with values, For matrices, the matrix correlation coefficient is calculated.',
examples: [
'corr([2, 4, 6, 8],[1, 2, 3, 6])',
'corr(matrix([[1, 2.2, 3, 4.8, 5], [1, 2, 3, 4, 5]]), matrix([[4, 5.3, 6.6, 7, 8], [1, 2, 3, 4, 5]]))'
],
seealso: [
'max',
'mean',
'min',
'median',
'min',
'prod',
'std',
'sum'
]
}
1 change: 1 addition & 0 deletions src/factoriesAny.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ export { createMad } from './function/statistics/mad.js'
export { createVariance } from './function/statistics/variance.js'
export { createQuantileSeq } from './function/statistics/quantileSeq.js'
export { createStd } from './function/statistics/std.js'
export { createCorr } from './function/statistics/corr.js'
export { createCombinations } from './function/probability/combinations.js'
export { createCombinationsWithRep } from './function/probability/combinationsWithRep.js'
export { createGamma } from './function/probability/gamma.js'
Expand Down
1 change: 1 addition & 0 deletions src/factoriesNumber.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ export { createMad } from './function/statistics/mad.js'
export { createVariance } from './function/statistics/variance.js'
export { createQuantileSeq } from './function/statistics/quantileSeq.js'
export { createStd } from './function/statistics/std.js'
export { createCorr } from './function/statistics/corr.js'

// string
export { createFormat } from './function/string/format.js'
Expand Down
64 changes: 64 additions & 0 deletions src/function/statistics/corr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { factory } from '../../utils/factory.js'
const name = 'corr'
const dependencies = ['typed', 'matrix', 'mean', 'sqrt', 'sum', 'add', 'subtract', 'multiply', 'pow', 'divide']

export const createCorr = /* #__PURE__ */ factory(name, dependencies, ({ typed, matrix, sqrt, sum, add, subtract, multiply, pow, divide }) => {
/**
* Compute the correlation coefficient of a two list with values, For matrices, the matrix correlation coefficient is calculated.
*
* Syntax:
*
* math.corr(A, B)
*
* Examples:
*
* math.corr([1, 2, 3, 4, 5], [4, 5, 6, 7, 8]) // returns 1
* math.corr([1, 2.2, 3, 4.8, 5], [4, 5.3, 6.6, 7, 8]) // returns 0.9569941688503644
* math.corr(math.matrix([[1, 2.2, 3, 4.8, 5], [1, 2, 3, 4, 5]]), math.matrix([[4, 5.3, 6.6, 7, 8], [1, 2, 3, 4, 5]])) // returns DenseMatrix [0.9569941688503644, 1]
*
* See also:
*
* median, mean, min, max, sum, prod, std, variance
*
* @param {Array | Matrix} A The first array or matrix to compute correlation coefficient
* @param {Array | Matrix} B The second array or matrix to compute correlation coefficient
* @return {*} The correlation coefficient
*/
return typed(name, {
'Array, Array': function (A, B) {
return _corr(A, B)
},
'Matrix, Matrix': function (xMatrix, yMatrix) {
return matrix(_corr(xMatrix.toArray(), yMatrix.toArray()))
}
})
/**
* Calculate the correlation coefficient between two arrays or matrices.
* @param {Array | Matrix} A
* @param {Array | Matrix} B
* @return {*} correlation coefficient
* @private
*/
function _corr (A, B) {
if (Array.isArray(A[0]) && Array.isArray(B[0])) {
const correlations = []
for (let i = 0; i < A.length; i++) {
correlations.push(correlation(A[i], B[i]))
}
return correlations
} else {
return correlation(A, B)
}
}
function correlation (A, B) {
const n = A.length
const sumX = sum(A)
const sumY = sum(B)
const sumXY = A.reduce((acc, x, index) => add(acc, multiply(x, B[index])), 0)
const sumXSquare = sum(A.map(x => pow(x, 2)))
const sumYSquare = sum(B.map(y => pow(y, 2)))
const numerator = subtract(multiply(n, sumXY), multiply(sumX, sumY))
const denominator = sqrt(multiply(subtract(multiply(n, sumXSquare), pow(sumX, 2)), subtract(multiply(n, sumYSquare), pow(sumY, 2))))
return divide(numerator, denominator)
}
})
21 changes: 21 additions & 0 deletions test/unit-tests/function/statistics/corr.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
const corr = math.corr
const BigNumber = math.BigNumber

describe('correlation', function () {
it('should return the correlation coefficient from an array', function () {
assert.strictEqual(corr([new BigNumber(1), new BigNumber(2.2), new BigNumber(3), new BigNumber(4.8), new BigNumber(5)], [new BigNumber(4), new BigNumber(5.3), new BigNumber(6.6), new BigNumber(7), new BigNumber(8)]).toNumber(), 0.9569941688503653)
assert.strictEqual(corr([1, 2, 3, 4, 5], [4, 5, 6, 7, 8]), 1)
assert.strictEqual(corr([1, 2.2, 3, 4.8, 5], [4, 5.3, 6.6, 7, 8]), 0.9569941688503644)
assert.deepStrictEqual(corr(math.matrix([[1, 2.2, 3, 4.8, 5], [1, 2, 3, 4, 5]]), math.matrix([[4, 5.3, 6.6, 7, 8], [1, 2, 3, 4, 5]]))._data, [0.9569941688503644, 1])
})

it('should throw an error if called with invalid number of arguments', function () {
assert.throws(function () { corr() })
})

it('should throw an error if called with an empty array', function () {
assert.throws(function () { corr([]) })
})
})
8 changes: 8 additions & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2970,6 +2970,14 @@ declare namespace math {
normalization: 'unbiased' | 'uncorrected' | 'biased'
): MathNumericType

/**
* Calculate the correlation coefficient between two matrix.
* @param {Array | Matrix} x The first array or matrix to compute correlation coefficient
* @param {Array | Matrix} y The second array or matrix to compute correlation coefficient
* @returns correlation coefficient
*/
corr(x: MathCollection, y: MathCollection): MathType

/*************************************************************************
* String functions
************************************************************************/
Expand Down

0 comments on commit 1ee8733

Please sign in to comment.