Logo
⚠️ Unsaved
[M]:

Matrix and Vector Operations with Mathjs

Linear algebra operations are essential for many applications including machine learning, computer graphics, physics simulations, and data analysis. Math.js offers powerful capabilities for working with matrices and vectors in JavaScript. This notebook provides a comprehensive guide to performing matrix and vector operations using the math.js library.

We'll explore everything from creating matrices and basic operations to advanced techniques like eigenvalue decomposition and solving linear systems.

[1]:
// Install math.js
!npm install mathjs
$ npm install mathjs

added 9 packages in 7s

30 packages are looking for funding
  run `npm fund` for details
[2]:
// Import math.js
const math = require('mathjs');

console.log('Math.js version:', math.version, '\n');
Math.js version: 14.3.1 
[M]:

1. Creating Matrices and Vectors

Let's start by exploring different ways to create matrices and vectors in math.js.

[3]:
// Creating matrices from arrays
console.log('Creating matrices from arrays:\n');

// Create a 2x3 matrix
const matrix1 = math.matrix([[1, 2, 3], [4, 5, 6]]);
console.log('2x3 matrix:\n', matrix1.toString(), '\n');

// Create a 3x3 matrix
const matrix2 = math.matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]);
console.log('3x3 matrix:\n', matrix2.toString(), '\n');

// Create a vector (can be represented as a matrix with one row or one column)
const rowVector = math.matrix([[1, 2, 3, 4]]);
const columnVector = math.matrix([[1], [2], [3], [4]]);

console.log('Row vector:\n', rowVector.toString(), '\n');
console.log('Column vector:\n', columnVector.toString(), '\n');
Creating matrices from arrays:
2x3 matrix:
 [[1, 2, 3], [4, 5, 6]] 
3x3 matrix:
 [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 
Row vector:
 [[1, 2, 3, 4]] 
Column vector:
 [[1], [2], [3], [4]] 
[4]:
// Creating special matrices
console.log('Creating special matrices:\n');

// Identity matrix (3x3)
const identity3 = math.identity(3);
console.log('3x3 identity matrix:\n', identity3.toString(), '\n');

// Zero matrix (2x4)
const zeros = math.zeros(2, 4);
console.log('2x4 zero matrix:\n', zeros.toString(), '\n');

// Ones matrix (3x2)
const ones = math.ones(3, 2);
console.log('3x2 ones matrix:\n', ones.toString(), '\n');

// Diagonal matrix
const diag = math.diag([1, 2, 3]);
console.log('Diagonal matrix from vector [1, 2, 3]:\n', diag.toString(), '\n');

// Extract diagonal from matrix
const extractedDiag = math.diag(matrix2);
console.log('Diagonal extracted from 3x3 matrix:\n', extractedDiag.toString(), '\n');
Creating special matrices:
3x3 identity matrix:
 [[1, 0, 0], [0, 1, 0], [0, 0, 1]] 
2x4 zero matrix:
 [[0, 0, 0, 0], [0, 0, 0, 0]] 
3x2 ones matrix:
 [[1, 1], [1, 1], [1, 1]] 
Diagonal matrix from vector [1, 2, 3]:
 1,0,0,0,2,0,0,0,3 
Diagonal extracted from 3x3 matrix:
 [1, 5, 9] 
[5]:
// Other ways to create matrices
console.log('Other matrix creation methods:\n');

// Create a matrix from a range
const range = math.range(1, 10); // Creates [1, 2, ..., 9]
const rangeMatrix = math.reshape(range, [3, 3]);
console.log('Matrix from range 1-9 reshaped to 3x3:\n', rangeMatrix.toString(), '\n');

// Create a random matrix
const random = math.random([2, 3]);
console.log('2x3 random matrix (values between 0-1):\n', random.toString(), '\n');

// Create a matrix with repeated values
const repeated = math.matrix(Array(3).fill(Array(3).fill(5)));
console.log('3x3 matrix filled with 5s:\n', repeated.toString(), '\n');
Other matrix creation methods:
Matrix from range 1-9 reshaped to 3x3:
 [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 
2x3 random matrix (values between 0-1):
 0.7886473348025803,0.24767441870923387,0.16474275628797758,0.5158762351334484,0.6405172826627917,0.6645898070793942 
3x3 matrix filled with 5s:
 [[5, 5, 5], [5, 5, 5], [5, 5, 5]] 
[M]:

2. Basic Matrix Operations

Now let's look at the fundamental matrix operations: addition, subtraction, and multiplication.

[6]:
// Matrix addition and subtraction
console.log('Matrix addition and subtraction:\n');

const A = math.matrix([[1, 2], [3, 4]]);
const B = math.matrix([[5, 6], [7, 8]]);

console.log('Matrix A:\n', A.toString(), '\n');
console.log('Matrix B:\n', B.toString(), '\n');

// Addition
const sum = math.add(A, B);
console.log('A + B:\n', sum.toString(), '\n');

// Subtraction
const difference = math.subtract(A, B);
console.log('A - B:\n', difference.toString(), '\n');

// Scalar multiplication
const scaledA = math.multiply(2, A);
console.log('2 * A:\n', scaledA.toString(), '\n');
Matrix addition and subtraction:
Matrix A:
 [[1, 2], [3, 4]] 
Matrix B:
 [[5, 6], [7, 8]] 
A + B:
 [[6, 8], [10, 12]] 
A - B:
 [[-4, -4], [-4, -4]] 
2 * A:
 [[2, 4], [6, 8]] 
[7]:
// Matrix multiplication
console.log('Matrix multiplication:\n');

const C = math.matrix([[1, 2, 3], [4, 5, 6]]);
const D = math.matrix([[7, 8], [9, 10], [11, 12]]);

console.log('Matrix C (2x3):\n', C.toString(), '\n');
console.log('Matrix D (3x2):\n', D.toString(), '\n');

// Matrix product
const product = math.multiply(C, D);
console.log('C * D (2x2):\n', product.toString(), '\n');

// Element-wise multiplication (Hadamard product)
const hadamard = math.dotMultiply(A, B); // Only works when matrices have same dimensions
console.log('A .* B (element-wise):\n', hadamard.toString(), '\n');

// Power of a matrix
const squared = math.pow(A, 2); // A^2 = A * A
console.log('A^2:\n', squared.toString(), '\n');
Matrix multiplication:
Matrix C (2x3):
 [[1, 2, 3], [4, 5, 6]] 
Matrix D (3x2):
 [[7, 8], [9, 10], [11, 12]] 
C * D (2x2):
 [[58, 64], [139, 154]] 
A .* B (element-wise):
 [[5, 12], [21, 32]] 
A^2:
 [[7, 10], [15, 22]] 
[M]:

3. Matrix Transformations

Let's explore common matrix transformations such as transpose, inverse, and determinant calculations.

[8]:
// Matrix transpose
console.log('Matrix transpose:\n');

const E = math.matrix([[1, 2, 3], [4, 5, 6]]);
console.log('Matrix E (2x3):\n', E.toString(), '\n');

const transposed = math.transpose(E);
console.log('E transposed (3x2):\n', transposed.toString(), '\n');

// Verify that (E^T)^T = E
const doubleTranspose = math.transpose(transposed);
console.log('Transpose of transpose (2x3):\n', doubleTranspose.toString(), '\n');
Matrix transpose:
Matrix E (2x3):
 [[1, 2, 3], [4, 5, 6]] 
E transposed (3x2):
 [[1, 4], [2, 5], [3, 6]] 
Transpose of transpose (2x3):
 [[1, 2, 3], [4, 5, 6]] 
[9]:
// Matrix inverse and determinant
console.log('Matrix inverse and determinant:\n');

// Square matrix (required for inverse and determinant)
const F = math.matrix([[4, 7], [2, 6]]);
console.log('Matrix F:\n', F.toString(), '\n');

// Calculate determinant
const det = math.det(F);
console.log(`Determinant of F: ${det}\n`);

// Calculate inverse
const inverse = math.inv(F);
console.log('Inverse of F:\n', inverse.toString(), '\n');

// Verify that F * F^(-1) = I
const identity = math.multiply(F, inverse);
console.log('F * F^(-1) (should be identity):\n', identity.toString(), '\n');

// Example of a singular matrix (determinant = 0, not invertible)
const singular = math.matrix([[1, 2], [2, 4]]);
console.log('Singular matrix:\n', singular.toString(), '\n');
console.log(`Determinant: ${math.det(singular)}\n`);

try {
const singularInverse = math.inv(singular);
console.log('Inverse (should not happen):', singularInverse.toString(), '\n');
} catch (error) {
console.log('Error computing inverse: ', error.message, '\n');
}
Matrix inverse and determinant:
Matrix F:
 [[4, 7], [2, 6]] 
Determinant of F: 10
Inverse of F:
 [[0.6, -0.7], [-0.2, 0.4]] 
F * F^(-1) (should be identity):
 [[0.9999999999999998, 4.440892098500626e-16], [-2.220446049250313e-16, 1.0000000000000004]] 
Singular matrix:
 [[1, 2], [2, 4]] 
Determinant: 0
Error computing inverse:  Cannot calculate inverse, determinant is zero 
[10]:
// Trace and norm
console.log('Matrix trace and norm:\n');

const G = math.matrix([[3, 1, 4], [1, 5, 9], [2, 6, 5]]);
console.log('Matrix G:\n', G.toString(), '\n');

// Calculate trace (sum of diagonal elements)
const trace = math.trace(G);
console.log(`Trace of G: ${trace}\n`); // 3 + 5 + 5 = 13

// Calculate Frobenius norm (square root of sum of squares of all elements)
const fnorm = math.norm(G, 'fro');
console.log(`Frobenius norm of G: ${fnorm}\n`);

// Other norms
try {
// 1-norm (maximum absolute column sum)
const norm1 = math.norm(G, 1);
console.log(`1-norm of G: ${norm1}\n`);
// Infinity-norm (maximum absolute row sum)
const normInf = math.norm(G, 'inf');
console.log(`Infinity-norm of G: ${normInf}\n`);
} catch (error) {
console.log('Note: Some norm types may not be implemented in this version of math.js\n');
}
Matrix trace and norm:
Matrix G:
 [[3, 1, 4], [1, 5, 9], [2, 6, 5]] 
Trace of G: 13
Frobenius norm of G: 14.071247279470288
1-norm of G: 18
Infinity-norm of G: 15
[M]:

4. Matrix Decompositions

Math.js provides several matrix decomposition methods that are useful for solving linear systems, eigenvalue problems, and other applications.

[22]:
// LU Decomposition
console.log('LU Decomposition:\n');

const H = math.matrix([[2, 1, 1], [4, -6, 0], [-2, 7, 2]]);
console.log('Matrix H:\n', H.toString(), '\n');

try {
// Perform LU decomposition
const { L, U, p } = math.lup(H);
console.log('L (Lower triangular):\n', L.toString(), '\n');
console.log('U (Upper triangular):\n', U.toString(), '\n');
console.log('P (Permutation vector):', p, '\n');
const LU = math.multiply(L, U);
console.log('L*U:\n', LU.toString(), '\n');
} catch (error) {
console.log('Error performing LU decomposition: ', error.message, '\n');
}
LU Decomposition:
Matrix H:
 [[2, 1, 1], [4, -6, 0], [-2, 7, 2]] 
L (Lower triangular):
 [[1, 0, 0], [0.5, 1, 0], [-0.5, 1, 1]] 
U (Upper triangular):
 [[4, -6, 0], [0, 4, 1], [0, 0, 1]] 
P (Permutation vector): [ 1, 0, 2 ] 
L*U:
 [[4, -6, 0], [2, 1, 1], [-2, 7, 2]] 
[M]:

5. Solving Linear Systems

Math.js provides methods to solve systems of linear equations.

[13]:
// Solving linear equations
console.log('Solving linear equations:\n');

// System: 2x + y = 5
// 3x + 2y = 8

const coefficients = math.matrix([
[2, 1],
[3, 2]
]);

const constants = math.matrix([
[5],
[8]
]);

console.log('Coefficient matrix A:\n', coefficients.toString(), '\n');
console.log('Constants vector b:\n', constants.toString(), '\n');

// Solve Ax = b
const solution = math.lusolve(coefficients, constants);
console.log('Solution x:\n', solution.toString(), '\n');

// Verify: A*x should equal b
const verification = math.multiply(coefficients, solution);
console.log('Verification (A*x):\n', verification.toString(), '\n');

// Alternative method using inverse: x = A^(-1) * b
const solutionWithInverse = math.multiply(math.inv(coefficients), constants);
console.log('Solution using inverse:\n', solutionWithInverse.toString(), '\n');
Solving linear equations:
Coefficient matrix A:
 [[2, 1], [3, 2]] 
Constants vector b:
 [[5], [8]] 
Solution x:
 [[2.0000000000000004], [0.9999999999999993]] 
Verification (A*x):
 [[5], [8]] 
Solution using inverse:
 [[2], [1]] 
[14]:
// Solving larger linear systems
console.log('Solving a larger system of equations:\n');

// System with 3 equations and 3 unknowns
const A = math.matrix([
[3, 2, -1],
[2, -2, 4],
[-1, 0.5, -1]
]);

const b = math.matrix([
[1],
[-2],
[0]
]);

console.log('Matrix A:\n', A.toString(), '\n');
console.log('Vector b:\n', b.toString(), '\n');

// Solve using LU decomposition
const x = math.lusolve(A, b);
console.log('Solution x:\n', x.toString(), '\n');

// Verify the solution
const Ax = math.multiply(A, x);
console.log('A*x (should equal b):\n', Ax.toString(), '\n');

// Try with an inconsistent system
console.log('Attempting to solve an inconsistent system:\n');
try {
const singular = math.matrix([
[1, 2, 3],
[2, 4, 6], // This row is 2 times the first row (linearly dependent)
[3, 6, 9] // This row is 3 times the first row (linearly dependent)
]);
Solving a larger system of equations:
Matrix A:
 [[3, 2, -1], [2, -2, 4], [-1, 0.5, -1]] 
Vector b:
 [[1], [-2], [0]] 
Solution x:
 [[1], [-1.9999999999999996], [-1.9999999999999993]] 
A*x (should equal b):
 [[1.0000000000000002], [-1.9999999999999982], [-4.440892098500626e-16]] 
Attempting to solve an inconsistent system:
Singular matrix:
 [[1, 2, 3], [2, 4, 6], [3, 6, 9]] 
Inconsistent b:
 [[1], [3], [3]] 
Error solving inconsistent system:  Linear system cannot be solved since matrix is singular 
[M]:

6. Vector Operations

Let's explore operations specific to vectors.

[15]:
// Vector operations
console.log('Vector operations:\n');

// Create two vectors
const v1 = math.matrix([1, 2, 3]);
const v2 = math.matrix([4, 5, 6]);

console.log('Vector v1:', v1.toArray(), '\n');
console.log('Vector v2:', v2.toArray(), '\n');

// Vector addition and subtraction
const vSum = math.add(v1, v2);
const vDiff = math.subtract(v1, v2);

console.log('v1 + v2:', vSum.toArray(), '\n');
console.log('v1 - v2:', vDiff.toArray(), '\n');

// Scalar multiplication
const vScaled = math.multiply(2, v1);
console.log('2 * v1:', vScaled.toArray(), '\n');

// Dot product
const dotProduct = math.dot(v1, v2);
console.log(`v1 · v2 = ${dotProduct}\n`); // 1*4 + 2*5 + 3*6 = 32

// Vector magnitude (norm)
const magnitude1 = math.norm(v1, 2);
console.log(`|v1| = ${magnitude1}\n`); // sqrt(1^2 + 2^2 + 3^2) = sqrt(14)

// Normalize vector (unit vector in same direction)
const unitV1 = math.divide(v1, magnitude1);
console.log('Unit vector of v1:', unitV1.toArray(), '\n');
console.log(`Magnitude of unit vector: ${math.norm(unitV1, 2)}\n`); // Should be 1
Vector operations:
Vector v1: [ 1, 2, 3 ] 
Vector v2: [ 4, 5, 6 ] 
v1 + v2: [ 5, 7, 9 ] 
v1 - v2: [ -3, -3, -3 ] 
2 * v1: [ 2, 4, 6 ] 
v1 · v2 = 32
|v1| = 3.7416573867739413
Unit vector of v1: [ 0.2672612419124244, 0.5345224838248488, 0.8017837257372732 ] 
Magnitude of unit vector: 1
[16]:
// Cross product (only defined for 3D vectors)
console.log('Cross product:\n');

const a = math.matrix([1, 0, 0]); // Unit vector in x direction
const b = math.matrix([0, 1, 0]); // Unit vector in y direction

console.log('Vector a:', a.toArray(), '\n');
console.log('Vector b:', b.toArray(), '\n');

const crossProduct = math.cross(a, b);
console.log('a × b:', crossProduct.toArray(), '\n'); // Should be [0, 0, 1] (z direction)

// Verify properties of cross product
const crossBA = math.cross(b, a);
console.log('b × a:', crossBA.toArray(), '\n'); // Should be [0, 0, -1] (negative z direction)

// Area of parallelogram formed by vectors
const area = math.norm(crossProduct);
console.log(`Area of parallelogram: ${area}\n`); // |a|*|b|*sin(θ) = 1*1*sin(90°) = 1

// Angle between vectors
function angleBetweenVectors(u, v) {
const dotProd = math.dot(u, v);
const normU = math.norm(u);
const normV = math.norm(v);
const cosTheta = dotProd / (normU * normV);
return math.acos(cosTheta);
}

const angle = angleBetweenVectors(a, b);
console.log(`Angle between a and b: ${angle} radians (${math.multiply(angle, 180/math.pi)} degrees)\n`);
Cross product:
Vector a: [ 1, 0, 0 ] 
Vector b: [ 0, 1, 0 ] 
a × b: [ 0, 0, 1 ] 
b × a: [ 0, 0, -1 ] 
Area of parallelogram: 1
Angle between a and b: 1.5707963267948966 radians (90 degrees)
[M]:

7. Practical Applications

Let's explore some practical applications of matrix and vector operations.

[17]:
// Linear regression using matrix operations
console.log('Linear regression using matrices:\n');

// Sample data points (x, y)
const x = [1, 2, 3, 4, 5];
const y = [2, 3.9, 6.1, 7.8, 9.9];

console.log('Data points:\n');
for (let i = 0; i < x.length; i++) {
console.log(`(${x[i]}, ${y[i]})\n`);
}

// For linear regression y = mx + b, we solve the normal equations
// X^T * X * β = X^T * y
// where β = [b, m]^T and X is the design matrix

// Create the design matrix [1, x_i]
const X = [];
for (let i = 0; i < x.length; i++) {
X.push([1, x[i]]);
}

const Xmat = math.matrix(X);
const yVec = math.matrix(y);

console.log('Design matrix X:\n', Xmat.toString(), '\n');
console.log('Target vector y:\n', yVec.toString(), '\n');

// Calculate X^T * X
const XtX = math.multiply(math.transpose(Xmat), Xmat);
console.log('X^T * X:\n', XtX.toString(), '\n');

// Calculate X^T * y
const Xty = math.multiply(math.transpose(Xmat), yVec);
console.log('X^T * y:\n', Xty.toString(), '\n');

Linear regression using matrices:
Data points:
(1, 2)
(2, 3.9)
(3, 6.1)
(4, 7.8)
(5, 9.9)
Design matrix X:
 [[1, 1], [1, 2], [1, 3], [1, 4], [1, 5]] 
Target vector y:
 [2, 3.9, 6.1, 7.8, 9.9] 
X^T * X:
 [[5, 15], [15, 55]] 
X^T * y:
 [29.700000000000003, 108.8] 
Beta coefficients [b, m]:
 [[0.030000000000001137], [1.9699999999999995]] 
Regression line: y = 1.9700x + 0.0300
Predictions using the regression model:
x = 1.5, predicted y = 2.9850
x = 3.5, predicted y = 6.9250
x = 6, predicted y = 11.8500
[18]:
// 2D transformation matrices
console.log('2D transformations with matrices:\n');

// Define a point in homogeneous coordinates
const point = math.matrix([[3], [2], [1]]);
console.log('Original point (x, y, 1):\n', point.toString(), '\n');

// Define transformations

// Translation by (2, 3)
const translation = math.matrix([
[1, 0, 2],
[0, 1, 3],
[0, 0, 1]
]);
console.log('Translation matrix:\n', translation.toString(), '\n');

// Rotation by 45 degrees counter-clockwise
const angle = math.pi / 4; // 45 degrees in radians
const rotation = math.matrix([
[math.cos(angle), -math.sin(angle), 0],
[math.sin(angle), math.cos(angle), 0],
[0, 0, 1]
]);
console.log('Rotation matrix (45°):\n', rotation.toString(), '\n');

// Scaling by factor of 2 in x and 0.5 in y
const scaling = math.matrix([
[2, 0, 0],
[0, 0.5, 0],
[0, 0, 1]
]);
console.log('Scaling matrix:\n', scaling.toString(), '\n');

// Apply transformations
const translated = math.multiply(translation, point);
2D transformations with matrices:
Original point (x, y, 1):
 [[3], [2], [1]] 
Translation matrix:
 [[1, 0, 2], [0, 1, 3], [0, 0, 1]] 
Rotation matrix (45°):
 [[0.7071067811865476, -0.7071067811865475, 0], [0.7071067811865475, 0.7071067811865476, 0], [0, 0, 1]] 
Scaling matrix:
 [[2, 0, 0], [0, 0.5, 0], [0, 0, 1]] 
Translated point:
 [[5], [5], [1]] 
Rotated point:
 [[0.7071067811865479], [3.5355339059327378], [1]] 
Scaled point:
 [[6], [1], [1]] 
Combined transformation matrix:
 [[1.4142135623730951, -1.414213562373095, -1.4142135623730945], [0.35355339059327373, 0.3535533905932738, 1.7677669529663689], [0, 0, 1]] 
Point after all transformations:
 [[1.3322676295501878e-15], [3.5355339059327378], [1]] 
[M]:

8. Performance Tips

Here are some tips for optimizing matrix operations in math.js.

[19]:
// Performance comparison
console.log('Performance tips for matrix operations:\n');

// Create a large matrix for testing
const size = 200;
const largeMatrix = math.ones(size, size);
const vector = math.ones(size);

console.log(`Created a ${size}x${size} matrix for testing\n`);

// Function to measure execution time
function timeExecution(fn, name) {
const start = Date.now();
fn();
const end = Date.now();
console.log(`${name}: ${end - start} ms\n`);
}

// Test different approaches
console.log('Comparing performance of different approaches:\n');

// Using math.js matrices
timeExecution(() => {
const result = math.multiply(largeMatrix, vector);
}, 'Matrix-vector multiplication with math.js matrices');

// Using JavaScript arrays
const arrayMatrix = largeMatrix.toArray();
const arrayVector = vector.toArray();

timeExecution(() => {
const result = [];
for (let i = 0; i < size; i++) {
let sum = 0;
for (let j = 0; j < size; j++) {
sum += arrayMatrix[i][j] * arrayVector[j];
Error during execution: Factory, Object, or Array expectedPerformance tips for matrix operations: Created a 200x200 matrix for testing Comparing performance of different approaches: Matrix-vector multiplication with math.js matrices: 2 ms Matrix-vector multiplication with JavaScript arrays: 1 ms
[20]:
// Performance tips summary
console.log('Performance optimization tips:\n');

console.log('1. For large matrices, consider using typed arrays\n');
console.log('2. Configure math.js to use arrays instead of matrix objects when performance is critical:\n');
console.log(' math.create({ matrix: \'Array\' })\n');
console.log('3. For very large matrices, consider specialized libraries like numeric.js or GPGPU libraries\n');
console.log('4. When possible, avoid creating intermediate matrices in calculations\n');
console.log('5. Use specialized functions (like math.det) instead of general-purpose ones when available\n');
console.log('6. For repeated calculations, reuse matrix objects rather than recreating them\n');
console.log('7. Consider sparse matrices for large matrices with many zero elements:\n');
console.log(' math.sparse([[1, 0, 0], [0, 1, 0], [0, 0, 1]])\n');

// Demonstrating sparse matrices
const denseMatrix = math.matrix([
[1, 0, 0, 0, 0],
[0, 2, 0, 0, 0],
[0, 0, 3, 0, 0],
[0, 0, 0, 4, 0],
[0, 0, 0, 0, 5]
]);

const sparseMatrix = math.sparse([
[1, 0, 0, 0, 0],
[0, 2, 0, 0, 0],
[0, 0, 3, 0, 0],
[0, 0, 0, 4, 0],
[0, 0, 0, 0, 5]
]);

console.log('\nDense vs Sparse representation:\n');
console.log(`Dense matrix size: approximately ${JSON.stringify(denseMatrix).length} bytes\n`);
console.log(`Sparse matrix size: approximately ${JSON.stringify(sparseMatrix).length} bytes\n`);
Performance optimization tips:
1. For large matrices, consider using typed arrays
2. Configure math.js to use arrays instead of matrix objects when performance is critical:
   math.create({ matrix: 'Array' })
3. For very large matrices, consider specialized libraries like numeric.js or GPGPU libraries
4. When possible, avoid creating intermediate matrices in calculations
5. Use specialized functions (like math.det) instead of general-purpose ones when available
6. For repeated calculations, reuse matrix objects rather than recreating them
7. Consider sparse matrices for large matrices with many zero elements:
   math.sparse([[1, 0, 0], [0, 1, 0], [0, 0, 1]])

Dense vs Sparse representation:
Dense matrix size: approximately 106 bytes
Sparse matrix size: approximately 99 bytes
[M]:

9. Best Practices and Common Pitfalls

Here are some best practices and common pitfalls to avoid when working with matrices in math.js.

[M]:

Best Practices

  1. Choose the right matrix type

    • Use dense matrices for general-purpose calculations
    • Use sparse matrices for large matrices with many zeros
    • Configure math.js to use arrays when performance is critical
  2. Matrix creation

    • Use specialized functions like identity(), zeros(), ones() when appropriate
    • For larger matrices, create them programmatically rather than typing out all elements
  3. Matrix access and modification

    • Use subset() for efficient access and modification
    • Remember that math.js uses zero-based indexing, unlike some mathematical conventions
  4. Error handling

    • Check matrix dimensions before operations
    • Wrap operations that could fail (like inverse or decomposition) in try-catch blocks

Common Pitfalls

  1. Mixing matrix types

    • Mixing sparse and dense matrices may lead to unexpected results
    • Mixing math.js matrices with regular JavaScript arrays requires explicit conversion
  2. Matrix dimensions

    • Not checking dimensions before multiplication
    • Not transposing matrices when needed
  3. Performance issues

    • Using matrix operations in tight loops without optimization
    • Creating many intermediate matrices
  4. Numerical stability

    • Not considering numerical stability for operations like inverse
    • Using direct inverse instead of decomposition methods for solving equations
[21]:
// Example of a common pitfall: Dimensions mismatch
console.log('Example of a common pitfall: Dimensions mismatch\n');

const matrix1 = math.matrix([[1, 2], [3, 4]]);
const matrix2 = math.matrix([[5, 6, 7], [8, 9, 10]]);

console.log('Matrix 1 (2x2):\n', matrix1.toString(), '\n');
console.log('Matrix 2 (2x3):\n', matrix2.toString(), '\n');

try {
// This will fail because dimensions don't match for multiplication
const result = math.multiply(matrix1, matrix2);
console.log('Result:\n', result.toString(), '\n');
} catch (error) {
console.log(`Error: ${error.message}\n`);
console.log('Correct approach: Check dimensions before multiplying\n');
// M1 is 2x2, M2 is 2x3, so M1 * M2 is not possible but M2 * M1 is
try {
const transposedM1 = math.transpose(matrix1); // Now 2x2
console.log('Transposed Matrix 1:\n', transposedM1.toString(), '\n');
// Now dimensions match for multiplication
const correctResult = math.multiply(matrix2, transposedM1); // (2x3) * (2x2) = 2x2
console.log('Correct result (M2 * M1ᵀ):\n', correctResult.toString(), '\n');
} catch (error2) {
console.log(`Still error: ${error2.message}\n`);
}
}
Example of a common pitfall: Dimensions mismatch
Matrix 1 (2x2):
 [[1, 2], [3, 4]] 
Matrix 2 (2x3):
 [[5, 6, 7], [8, 9, 10]] 
Result:
 [[21, 24, 27], [47, 54, 61]] 
Sign in to save your work and access it from anywhere