Skip to content

Commit

Permalink
added implemenation for signature Matrix, Matrix and support for BigN…
Browse files Browse the repository at this point in the history
…umbers
  • Loading branch information
vrushaket committed Aug 23, 2023
1 parent 96ed00a commit d6a403a
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 46 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 <[email protected]>
Aly Khaled <[email protected]>
BuildTools <[email protected]>
Anik Patel <[email protected]>
vrushaket <[email protected]>

# Generated by tools/update-authors.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ export const correlationDocs = {
syntax: [
'corr(A,B)'
],
description: 'Compute the colleration of a two list with values',
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([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',
Expand Down
69 changes: 33 additions & 36 deletions src/function/statistics/correlation.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { factory } from '../../utils/factory.js'

const name = 'corr'
const dependencies = ['typed']
const dependencies = ['typed', 'matrix', 'mean', 'sqrt', 'sum', 'add', 'subtract', 'multiply', 'pow', 'divide']

export const createCorrelation = /* #__PURE__ */ factory(name, dependencies, ({ typed }) => {
export const createCorrelation = /* #__PURE__ */ factory(name, dependencies, ({ typed, matrix, sqrt, sum, add, subtract, multiply, pow, divide }) => {
/**
* Compute the colleration of a two list with values.
* Compute the correlation coefficient of a two list with values, For matrices, the matrix correlation coefficient is calculated.
*
* Syntax:
*
Expand All @@ -15,46 +14,44 @@ export const createCorrelation = /* #__PURE__ */ factory(name, dependencies, ({
*
* 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(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]])) // returns [0.9569941688503644, 1])
*
*/
return typed(name, {
// correlation(xArray, yArray)
'Array, Array': function (xArray, yArray) {
return _corr(xArray, yArray)
'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.
* @param {Array} xArray
* @param {Array} yArray
* @return {number | BigNumber} correlation coefficient
* Calculate the correlation coefficient between two arrays or matrices.
* @param {Array | Matrix} A
* @param {Array | Matrix} B
* @return {*} correlation coefficient
* @private
*/
function _corr (xArray, yArray, normalization) {
if (xArray.length !== yArray.length) {
throw new SyntaxError('Input arrays must have the same length')
}
if (xArray.length < 2) {
throw new SyntaxError('Function corr requires two or more parameters (' + xArray.length + ' provided) in first input array')
}
if (yArray.length < 2) {
throw new SyntaxError('Function corr requires two or more parameters (' + yArray.length + ' provided) in second input array')
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)
}

const n = xArray.length

const sumX = xArray.reduce((acc, x) => acc + x, 0)
const sumY = yArray.reduce((acc, y) => acc + y, 0)

const sumXY = xArray.reduce((acc, x, index) => acc + x * yArray[index], 0)
const sumXSquare = xArray.reduce((acc, x) => acc + x ** 2, 0)
const sumYSquare = yArray.reduce((acc, y) => acc + y ** 2, 0)

const numerator = n * sumXY - sumX * sumY
const denominator = Math.sqrt((n * sumXSquare - sumX ** 2) * (n * sumYSquare - sumY ** 2))

const correlation = numerator / denominator

return correlation
}
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)
}
})
3 changes: 3 additions & 0 deletions test/unit-tests/function/statistics/correlation.test.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
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 () {
Expand Down
13 changes: 5 additions & 8 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2915,8 +2915,8 @@ declare namespace math {
cumsum(...args: MathType[]): MathType[]
/**
* @param array A single matrix
* @p corr(xArray: MathCollection, yArray: MathCollection): MathNumericType
ms along the given dimension
* @param dim The dimension along which to sum (defaults to 0)
* @returns The cumulative sums along the given dimension
*/
cumsum(array: MathCollection, dim?: number): MathCollection

Expand Down Expand Up @@ -2972,14 +2972,11 @@ ms along the given dimension

/**
* Calculate the correlation coefficient between two matrix.
* @param {Array} xArray A matrix to compute correlation coefficient
* @param {Array} yArray A matrix to compute correlation coefficient
* @param {Array} x The first matrix to compute correlation coefficient
* @param {Array} y The second matrix to compute correlation coefficient
* @returns correlation coefficient
*/
corr(
xArray: MathCollection,
yArray: MathCollection
): MathNumericType
corr(xArray: MathCollection, yArray: MathCollection): MathType

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

0 comments on commit d6a403a

Please sign in to comment.