New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Diff function #1812
Closed
Closed
Diff function #1812
Changes from 14 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
4cd2704
Prefix the cli test with 'node' so it works on windows
Veeloxfire 268b594
Revert "Prefix the cli test with 'node' so it works on windows"
Veeloxfire 6bff420
Revert "Revert "Prefix the cli test with 'node' so it works on windows""
Veeloxfire 76a9506
Merge branch 'develop' into Undo
josdejong bc3cbbc
Diff function
Veeloxfire 49a6521
Included createDiff in factoriesAny
Veeloxfire b94a346
Diff docs
Veeloxfire 9a66b80
Finalized Diff function
Veeloxfire 79066f1
Merge branch 'develop' into Undo
Veeloxfire c2c3f73
Merge branch 'develop' into Undo
josdejong 12395f2
Merge branch 'develop' into Undo
josdejong 6a50291
Merge branch 'develop' into Undo
josdejong 1348d67
Updated diff function to allow selecting a dimension
Veeloxfire d026dad
Merge branch 'develop' into Undo
josdejong bd641d2
Merge branch 'develop' into Undo
josdejong File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
export const diffDocs = { | ||
name: 'diff', | ||
category: 'Matrix', | ||
syntax: [ | ||
'diff(arr)', | ||
'diff(arr, dim)' | ||
], | ||
description: [ | ||
'Create a new matrix or array with the difference of the passed matrix or array.', | ||
'Dim parameter is optional and used to indicant the dimension of the array/matrix to apply the diffrence (if not used it is assumed as 0)' | ||
], | ||
examples: [ | ||
'diff([1, 2, 4, 7, 0])', | ||
'diff([1, 2, 4, 7, 0], 0)', | ||
'diff(matrix([1, 2, 4, 7, 0]))' | ||
], | ||
seealso: ['subtract'] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
import { factory } from '../../utils/factory' | ||
import { isMatrix } from '../../utils/is' | ||
|
||
const name = 'diff' | ||
const dependencies = ['typed', 'matrix', 'subtract'] | ||
|
||
export const createDiff = /* #__PURE__ */ factory(name, dependencies, ({ typed, matrix, subtract }) => { | ||
/** | ||
* Create a new matrix or array of the difference between elements of the given array | ||
* The optional dim parameter lets you specify the dimension to evaluate the difference of | ||
* If no dimension parameter is passed it is assumed as dimension 0 | ||
* | ||
* Syntax: | ||
* | ||
* math.diff(arr) | ||
* math.diff(arr, dim) | ||
* | ||
* Examples: | ||
* | ||
* const arr = [1, 2, 4, 7, 0] | ||
* math.diff(arr) // returns [1, 2, 3, -7] (no dimension passed so 0 is assumed) | ||
* math.diff(math.matrix(arr)) // returns [1, 2, 3, -7] as matrix | ||
* | ||
* const arr = [1] | ||
* math.diff(arr) // returns [1] | ||
* | ||
* const arr = [[1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [9, 8, 7, 6, 4]] | ||
* math.diff(arr) // returns [[0, 0, 0, 0, 0], [8, 6, 4, 2, -1]] | ||
* math.diff(arr) // returns [[1, 1, 1, 1], [1, 1, 1, 1], [-1, -1, -1, -2]] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think here the dimension should be specified, like |
||
* | ||
* See Also: | ||
* | ||
* Subtract | ||
* | ||
* @param {Array | Matrix} arr An array or matrix | ||
* @param {number} dim Dimension | ||
* @return {Array | Matrix} Difference between array elements in given dimension | ||
*/ | ||
return typed(name, { | ||
'Array | Matrix': function (arr) { // No dimension specified => assume dimension 1 | ||
if (isMatrix(arr)) { | ||
return matrix(_diff(arr.toArray())) | ||
} else { | ||
return _diff(arr) | ||
} | ||
}, | ||
'Array | Matrix, number': function (arr, dim) { | ||
if (isMatrix(arr)) { | ||
return matrix(_recursive(arr.toArray(), dim)) | ||
} else { | ||
return _recursive(arr, dim) | ||
} | ||
} | ||
}) | ||
|
||
/** | ||
* Recursively find the correct dimension in the array/matrix | ||
* Then Apply _diff to that dimension | ||
* | ||
* @param {Array} arr The array | ||
* @param {number} dim Dimension | ||
* @return {Array} resulting array | ||
*/ | ||
function _recursive (arr, dim) { | ||
if (!Array.isArray(arr)) { | ||
throw RangeError('Array/Matrix does not have that many dimensions') | ||
} | ||
if (dim > 0) { | ||
const result = [] | ||
arr.forEach(element => { | ||
result.push(_recursive(element, dim - 1)) | ||
}) | ||
return result | ||
} | ||
return _diff(arr) | ||
} | ||
|
||
/** | ||
* Difference between elements in the array | ||
* | ||
* @param {Array} arr An array | ||
* @return {Array} resulting array | ||
*/ | ||
function _diff (arr) { | ||
const result = [] | ||
const size = arr.length | ||
if (size < 2) { | ||
return arr | ||
} | ||
for (let i = 1; i < size; i++) { | ||
result.push(_ElementDiff(arr[i - 1], arr[i])) | ||
} | ||
return result | ||
} | ||
|
||
/** | ||
* Difference between 2 objects | ||
* | ||
* @param {Object} obj1 First object | ||
* @param {Object} obj2 Second object | ||
* @return {Array} resulting array | ||
*/ | ||
function _ElementDiff (obj1, obj2) { | ||
const obj1IsArray = Array.isArray(obj1) | ||
const obj2IsArray = Array.isArray(obj2) | ||
if (obj1IsArray && obj2IsArray) { | ||
return _ArrayDiff(obj1, obj2) | ||
} | ||
if (!obj1IsArray && !obj2IsArray) { | ||
return subtract(obj2, obj1) // Difference is (second - first) NOT (first - second) | ||
} | ||
throw Error('Cannot calculate difference between 1 array and 1 non-array') | ||
} | ||
|
||
/** | ||
* Difference of elements in 2 arrays | ||
* | ||
* @param {Array} arr1 Array 1 | ||
* @param {Array} arr2 Array 2 | ||
* @return {Array} resulting array | ||
*/ | ||
function _ArrayDiff (arr1, arr2) { | ||
if (arr1.length !== arr2.length) { | ||
throw RangeError('Not all arrays have the same length') | ||
} | ||
const result = [] | ||
const size = arr1.length | ||
for (let i = 0; i < size; i++) { | ||
result.push(_ElementDiff(arr1[i], arr2[i])) | ||
} | ||
return result | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import assert from 'assert' | ||
import math from '../../../../src/bundleAny' | ||
|
||
const matrix = math.matrix | ||
|
||
const smallTestArray = [[1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [9, 8, 7, 6, 4]] | ||
|
||
const smallTestArrayDimension0 = [[0, 0, 0, 0, 0], [8, 6, 4, 2, -1]] | ||
const smallTestArrayDimension1 = [[1, 1, 1, 1], [1, 1, 1, 1], [-1, -1, -1, -2]] | ||
|
||
// largeTestArrayDimension0-3 were generated from largeTestArray using numpy.diff() for consistency. Please dont change them because they are a pain to get linted correctly | ||
const largeTestArray = [[[[1, 2, 3], [2, 3, 4], [3, 4, 5]], [[3, 2, 1], [2, 3, 4], [5, 4, 3]], [[5, 2, 1], [5, 2, 1], [5, 2, 1]]], [[[8, 12, 345], [23, 35, 23], [123, 234, 12]], [[1, 2, 3], [1, 3, 5], [5, 6, 7]], [[66, 55, 44], [32, 32, 1], [0, 1, 2]]], [[[1, 64, 3], [2, 34, 61], [128, 92, 64]], [[12, 2, 1], [6, 8, 9], [2, 7, 3]], [[52, 22, 21], [55, 52, 51], [111, 12, 11]]]] | ||
|
||
const largeTestArrayDimension0 = [[[[7, 10, 342], [21, 32, 19], [120, 230, 7]], [[-2, 0, 2], [-1, 0, 1], [0, 2, 4]], [[61, 53, 43], [27, 30, 0], [-5, -1, 1]]], [[[-7, 52, -342], [-21, -1, 38], [5, -142, 52]], [[11, 0, -2], [5, 5, 4], [-3, 1, -4]], [[-14, -33, -23], [23, 20, 50], [111, 11, 9]]]] | ||
const largeTestArrayDimension1 = [[[[2, 0, -2], [0, 0, 0], [2, 0, -2]], [[2, 0, 0], [3, -1, -3], [0, -2, -2]]], [[[-7, -10, -342], [-22, -32, -18], [-118, -228, -5]], [[65, 53, 41], [31, 29, -4], [-5, -5, -5]]], [[[11, -62, -2], [4, -26, -52], [-126, -85, -61]], [[40, 20, 20], [49, 44, 42], [109, 5, 8]]]] | ||
const largeTestArrayDimension2 = [[[[1, 1, 1], [1, 1, 1]], [[-1, 1, 3], [3, 1, -1]], [[0, 0, 0], [0, 0, 0]]], [[[15, 23, -322], [100, 199, -11]], [[0, 1, 2], [4, 3, 2]], [[-34, -23, -43], [-32, -31, 1]]], [[[1, -30, 58], [126, 58, 3]], [[-6, 6, 8], [-4, -1, -6]], [[3, 30, 30], [56, -40, -40]]]] | ||
const largeTestArrayDimension3 = [[[[1, 1], [1, 1], [1, 1]], [[-1, -1], [1, 1], [-1, -1]], [[-3, -1], [-3, -1], [-3, -1]]], [[[4, 333], [12, -12], [111, -222]], [[1, 1], [2, 2], [1, 1]], [[-11, -11], [0, -31], [1, 1]]], [[[63, -61], [32, 27], [-36, -28]], [[-10, -1], [2, 1], [5, -4]], [[-30, -1], [-3, -1], [-99, -1]]]] | ||
|
||
describe('diff', function () { | ||
it('should return original array/matrix for less than 2 elements, with and without specified dimension', function () { | ||
// With Dim = 0 specified | ||
assert.deepStrictEqual(math.diff([], 0), []) | ||
assert.deepStrictEqual(math.diff(matrix([]), 0), matrix([])) | ||
assert.deepStrictEqual(math.diff([2], 0), [2]) | ||
assert.deepStrictEqual(math.diff(matrix([2]), 0), matrix([2])) | ||
|
||
// Without Dim = 0 specified | ||
assert.deepStrictEqual(math.diff([]), []) | ||
assert.deepStrictEqual(math.diff(matrix([])), matrix([])) | ||
assert.deepStrictEqual(math.diff([2]), [2]) | ||
assert.deepStrictEqual(math.diff(matrix([2])), matrix([2])) | ||
}) | ||
|
||
it('should return difference between elements of a 1-dimensional array, with and without specified dimension', function () { | ||
// With Dim = 0 | ||
assert.deepStrictEqual(math.diff([1, 2, 4, 7, 0], 0), [1, 2, 3, -7]) | ||
|
||
// Without Dim = 0 | ||
assert.deepStrictEqual(math.diff([1, 2, 4, 7, 0]), [1, 2, 3, -7]) | ||
}) | ||
|
||
it('should return difference between elements of a 1-dimensional matrix, with and without specified dimension', function () { | ||
// With Dim = 0 | ||
assert.deepStrictEqual(math.diff(matrix([1, 2, 4, 7, 0]), 0), matrix([1, 2, 3, -7])) | ||
|
||
// Without Dim = 0 | ||
assert.deepStrictEqual(math.diff(matrix([1, 2, 4, 7, 0])), matrix([1, 2, 3, -7])) | ||
}) | ||
|
||
it('should return difference between elements of a 2-dimensional array, with and without specified dimension', function () { | ||
// With Dim specified | ||
assert.deepStrictEqual(math.diff(smallTestArray, 0), smallTestArrayDimension0) | ||
assert.deepStrictEqual(math.diff(smallTestArray, 1), smallTestArrayDimension1) | ||
|
||
// Without Dim specified | ||
assert.deepStrictEqual(math.diff(smallTestArray), smallTestArrayDimension0) | ||
}) | ||
|
||
it('should return difference between elements of a 2-dimensional matrix, with and without specified dimension', function () { | ||
// With Dim specified | ||
assert.deepStrictEqual(math.diff(matrix(smallTestArray), 0), matrix(smallTestArrayDimension0)) | ||
assert.deepStrictEqual(math.diff(matrix(smallTestArray), 1), matrix(smallTestArrayDimension1)) | ||
|
||
// Without Dim specified | ||
assert.deepStrictEqual(math.diff(matrix(smallTestArray)), matrix(smallTestArrayDimension0)) | ||
}) | ||
|
||
it('should return difference between elements of a 4-dimensional array, with and without specified dimension', function () { | ||
// With Dim specified | ||
assert.deepStrictEqual(math.diff(largeTestArray, 0), largeTestArrayDimension0) | ||
assert.deepStrictEqual(math.diff(largeTestArray, 1), largeTestArrayDimension1) | ||
assert.deepStrictEqual(math.diff(largeTestArray, 2), largeTestArrayDimension2) | ||
assert.deepStrictEqual(math.diff(largeTestArray, 3), largeTestArrayDimension3) | ||
|
||
// Without Dim specified | ||
assert.deepStrictEqual(math.diff(largeTestArray), largeTestArrayDimension0) | ||
}) | ||
|
||
it('should return difference between elements of a 4-dimensional matrix, with and without specified dimension', function () { | ||
// With Dim specified | ||
assert.deepStrictEqual(math.diff(matrix(largeTestArray), 0), matrix(largeTestArrayDimension0)) | ||
assert.deepStrictEqual(math.diff(matrix(largeTestArray), 1), matrix(largeTestArrayDimension1)) | ||
assert.deepStrictEqual(math.diff(matrix(largeTestArray), 2), matrix(largeTestArrayDimension2)) | ||
assert.deepStrictEqual(math.diff(matrix(largeTestArray), 3), matrix(largeTestArrayDimension3)) | ||
|
||
// Without Dim specified | ||
assert.deepStrictEqual(math.diff(matrix(largeTestArray)), matrix(largeTestArrayDimension0)) | ||
}) | ||
}) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this example should be a 2d array so you can actually see what the dimension does, like
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, I think I did this because it was just a copy and paste but yes should definitely have more comprehensive examples