UNPKG

data-structure-typed

Version:
378 lines (321 loc) 9.65 kB
import { Matrix } from '../../../../src'; describe('Matrix', () => { let matrix: Matrix; beforeEach(() => { // Initialize a 3x3 matrix with zeros matrix = new Matrix([ [0, 0, 0], [0, 0, 0], [0, 0, 0] ]); }); it('should create a matrix with the correct dimensions and initial values', () => { expect(matrix.rows).toBe(3); expect(matrix.cols).toBe(3); expect(matrix.data).toEqual([ [0, 0, 0], [0, 0, 0], [0, 0, 0] ]); }); it('should initiate with empty', () => { matrix = new Matrix([], { rows: 2, cols: 2 }); expect(matrix.data).toEqual([ [0, 0], [0, 0] ]); }); it('should get a value at a specific position', () => { expect(matrix.get(1, 1)).toBe(0); expect(matrix.get(2, 2)).toBe(0); }); it('should set a value at a specific position', () => { matrix.set(1, 1, 42); expect(matrix.get(1, 1)).toBe(42); }); it('should not allow getting or setting values at invalid positions', () => { expect(matrix.get(-1, 0)).toBeUndefined(); expect(matrix.get(0, 10)).toBeUndefined(); const originalValue = matrix.get(1, 1); matrix.set(-1, 1, 42); matrix.set(1, 10, 42); expect(matrix.get(1, 1)).toBe(originalValue); }); describe('add', () => { it('should add two matrices correctly', () => { const matrixA = new Matrix([ [1, 2], [3, 4] ]); const matrixB = new Matrix([ [5, 6], [7, 8] ]); const expectedResult = new Matrix([ [6, 8], [10, 12] ]); const result = matrixA.add(matrixB); expect(result?.data).toEqual(expectedResult.data); }); it('should throw an error for matrices with mismatched dimensions', () => { const matrixA = new Matrix([ [1, 2], [3, 4] ]); const matrixB = new Matrix([ [5, 6, 7], [8, 9, 10] ]); expect(() => matrixA.add(matrixB)).toThrowError('Matrix dimensions must match for addition.'); }); it('should throw an error for matrices with mismatched dimensions', () => { const matrixA = new Matrix([ [1, 2], [3, 4] ]); const matrixB = new Matrix([ [5, 6, 7], [8, 9, 10] ]); expect(() => matrixA.add(matrixB)).toThrowError('Matrix dimensions must match for addition.'); }); }); describe('subtract', () => { it('should subtract two matrices with numbers correctly', () => { const matrixA = new Matrix([ [5, 6], [7, 8] ]); const matrixB = new Matrix([ [1, 2], [3, 4] ]); const expectedResult = new Matrix([ [4, 4], [4, 4] ]); const result = matrixA.subtract(matrixB); expect(result?.data).toEqual(expectedResult.data); }); it('should subtract two matrices with custom subtract function correctly', () => { const customSubtractFn = (a: number, b: number) => a * 10 - b; // Custom subtraction for arrays const matrixA = new Matrix( [ [5, 6], [7, 8] ], { subtractFn: customSubtractFn } ); const matrixB = new Matrix( [ [1, 2], [3, 4] ], { subtractFn: customSubtractFn } ); const expectedResult = new Matrix( [ [49, 58], [67, 76] ], { subtractFn: customSubtractFn } ); const result = matrixA.subtract(matrixB); expect(result?.data).toEqual(expectedResult.data); }); it('should throw an error for matrices with mismatched dimensions', () => { const matrixA = new Matrix([ [1, 2], [3, 4] ]); const matrixB = new Matrix([ [5, 6, 7], [8, 9, 10] ]); expect(() => matrixA.subtract(matrixB)).toThrowError('Matrix dimensions must match for subtraction.'); }); }); describe('multiply', () => { it('should multiply two matrices with numbers correctly', () => { const matrixA = new Matrix([ [1, 2], [3, 4] ]); const matrixB = new Matrix([ [5, 6], [7, 8] ]); const expectedResult = new Matrix([ [19, 22], [43, 50] ]); const result = matrixA.multiply(matrixB); expect(result?.data).toEqual(expectedResult.data); }); it('should multiply two matrices with custom multiply function correctly', () => { const customMultiplyFn = (a: number, b: number) => a * 10 * b; // Custom multiplication for arrays const matrixA = new Matrix( [ [1, 2], [3, 4] ], { multiplyFn: customMultiplyFn } ); const matrixB = new Matrix( [ [5, 6], [7, 8] ], { multiplyFn: customMultiplyFn } ); const result = matrixA.multiply(matrixB); expect(result?.data).toEqual([ [190, 220], [430, 500] ]); }); it('should throw an error for matrices with mismatched dimensions', () => { const matrixA = new Matrix([ [1, 2, 3], [3, 4, 5] ]); const matrixB = new Matrix([ [5, 6, 7], [8, 9, 1] ]); expect(() => matrixA.multiply(matrixB)).toThrowError( 'Matrix dimensions must be compatible for multiplication (A.cols = B.rows).' ); }); }); describe('transpose', () => { it('should transpose a matrix with numeric values correctly', () => { const originalMatrix = new Matrix([ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]); const transposedMatrix = originalMatrix.transpose(); expect(transposedMatrix.rows).toBe(originalMatrix.cols); expect(transposedMatrix.cols).toBe(originalMatrix.rows); expect(transposedMatrix.data).toEqual([ [1, 4, 7], [2, 5, 8], [3, 6, 9] ]); }); it('should transpose an empty matrix correctly', () => { const originalMatrix = new Matrix([]); const transposedMatrix = originalMatrix.transpose(); expect(transposedMatrix.rows).toBe(0); expect(transposedMatrix.cols).toBe(0); expect(transposedMatrix.data).toEqual([]); }); it('should throw an error when transposing a non-rectangular matrix', () => { const originalMatrix = new Matrix([ [1, 2, 3], [4, 5] ]); // Using a lambda to call transpose because Jest expects the error to be thrown within a function expect(() => originalMatrix.transpose()).toThrowError('Matrix must be rectangular for transposition.'); }); }); describe('inverse', () => { it('should calculate the inverse of a 2x2 matrix', () => { const data: number[][] = [ [1, 2], [3, 4] ]; const matrix = new Matrix(data); const inverseMatrix = matrix.inverse(); const expectedInverse: number[][] = [ [-2, 1], [1.5, -0.5] ]; expect(inverseMatrix?.data).toEqual(expectedInverse); }); it('should calculate the inverse of a 3x3 matrix', () => { const data: number[][] = [ [4, 7, 2], [2, 6, 3], [1, 2, 5] ]; const matrix = new Matrix(data); const inverseMatrix = matrix.inverse(); // const expectedInverse: number[][] = [ // [24 / 43, -31 / 43, 9 / 43], // [-7 / 43, 18 / 43, -8 / 43], // [-2 / 43, -1 / 43, 10 / 43], // ]; expect(inverseMatrix?.data).toEqual([ [0.558139534883721, -0.7209302325581396, 0.2093023255813954], [-0.16279069767441862, 0.4186046511627907, -0.18604651162790697], [-0.046511627906976744, -0.023255813953488372, 0.23255813953488372] ]); }); it('should throw error when cols does not equal to rows', () => { const data: number[][] = [ [4, 7, 2], [2, 6, 3] ]; const matrix = new Matrix(data); expect(() => matrix.inverse()).toThrow('Matrix must be square for inversion.'); }); it('should clone', () => { const data: number[][] = [ [4, 7, 2], [2, 6, 3] ]; const matrix = new Matrix(data); const cloned = matrix.clone(); expect(cloned instanceof Matrix).toBe(true); expect(cloned.data).toEqual(data); }); }); describe('dot', () => { it('should calculate the dot product of two matrices', () => { const matrix1 = new Matrix([ [1, 2], [3, 4] ]); const matrix2 = new Matrix([ [5, 6], [7, 8] ]); const resultMatrix = matrix1.dot(matrix2); expect(resultMatrix?.data).toEqual([ [19, 22], [43, 50] ]); }); it('should throw an error for incompatible matrices', () => { const matrix1 = new Matrix([ [1, 2], [3, 4] ]); const matrix2 = new Matrix([ [5, 6, 7], [8, 9, 10], [18, 19, 110] ]); expect(() => matrix1.dot(matrix2)).toThrowError( 'Number of columns in the first matrix must be equal to the number of rows in the second matrix for dot product.' ); }); it('should throw an error for incompatible matrices', () => { const matrixA = new Matrix([ [1, 2], [3, 4] ]); const matrixB = new Matrix([ [5, 6], [7, 8], [9, 10] ]); expect(() => matrixA.dot(matrixB)).toThrowError( 'Number of columns in the first matrix must be equal to the number of rows in the second matrix for dot product.' ); }); }); });