laplace-determinant.js
function determinant (data, scalar, order) {
  // Recursion will stop here:
  // the determinant of a 1x1 matrix is its only element.
  if (data.length === 1) return data[0]

  if (no(order)) order = Math.sqrt(data.length)

  if (order % 1 !== 0) {
    throw new TypeError('data.lenght must be a square')
  }

  // Default to common real number field.
  if (no(scalar)) {
    scalar = {
      addition: function (a, b) { return a + b },
      multiplication: function (a, b) { return a * b },
      negation: function (a) { return -a }
    }
  }

  var det

  // TODO choose best row or column to start from, i.e. the one with more zeros
  // by now we start from first row, and walk by column
  // needs scalar.isZero
  //
  // is scalar.isZero is a function will be used, but should remain optional
  var startingRow = 0

  for (var col = 0; col < order; col++) {
    var subData = subMatrix(data, order, order, startingRow, col)

    //             +-- Recursion here.
    //             ↓
    var cofactor = determinant(subData, scalar, order - 1)

    if ((startingRow + col) % 2 === 1) {
      cofactor = scalar.negation(cofactor)
    }

    var index = matrixToArrayIndex(startingRow, col, order)

    if (no(det)) {
      det = scalar.multiplication(data[index], cofactor) // first iteration
    } else {
      det = scalar.addition(det, scalar.multiplication(data[index], cofactor))
    }
  }

  return det
}
function determinant (data, scalar, order) {
  // Recursion will stop here:
  // the determinant of a 1x1 matrix is its only element.
  if (data.length === 1) return data[0]

  if (no(order)) order = Math.sqrt(data.length)

  if (order % 1 !== 0) {
    throw new TypeError('data.lenght must be a square')
  }

  // Default to common real number field.
  if (no(scalar)) {
    scalar = {
      addition: function (a, b) { return a + b },
      multiplication: function (a, b) { return a * b },
      negation: function (a) { return -a }
    }
  }

  var det

  // TODO choose best row or column to start from, i.e. the one with more zeros
  // by now we start from first row, and walk by column
  // needs scalar.isZero
  //
  // is scalar.isZero is a function will be used, but should remain optional
  var startingRow = 0

  for (var col = 0; col < order; col++) {
    var subData = subMatrix(data, order, order, startingRow, col)

    //             +-- Recursion here.
    //             ↓
    var cofactor = determinant(subData, scalar, order - 1)

    if ((startingRow + col) % 2 === 1) {
      cofactor = scalar.negation(cofactor)
    }

    var index = matrixToArrayIndex(startingRow, col, order)

    if (no(det)) {
      det = scalar.multiplication(data[index], cofactor) // first iteration
    } else {
      det = scalar.addition(det, scalar.multiplication(data[index], cofactor))
    }
  }

  return det
}
function determinant ( data , scalar , order ) { // Recursion will stop here: // the determinant of a 1x1 matrix is its only element. if ( data . length === 1 ) return data [ 0 ] if ( no ( order ) ) order = Math . sqrt ( data . length ) if ( order % 1 !== 0 ) { throw new TypeError ( 'data.lenght must be a square' ) } // Default to common real number field. if ( no ( scalar ) ) { scalar = { addition : function ( a , b ) { return a + b } , multiplication : function ( a , b ) { return a * b } , negation : function ( a ) { return - a } } } var det // TODO choose best row or column to start from, i.e. the one with more zeros // by now we start from first row, and walk by column // needs scalar.isZero // // is scalar.isZero is a function will be used, but should remain optional var startingRow = 0 for ( var col = 0 ; col < order ; col ++ ) { var subData = subMatrix ( data , order , order , startingRow , col ) //             +-- Recursion here. //             ↓ var cofactor = determinant ( subData , scalar , order - 1 ) if ( ( startingRow + col ) % 2 === 1 ) { cofactor = scalar . negation ( cofactor ) } var index = matrixToArrayIndex ( startingRow , col , order ) if ( no ( det ) ) { det = scalar . multiplication ( data [ index ] , cofactor ) // first iteration } else { det = scalar . addition ( det , scalar . multiplication ( data [ index ] , cofactor ) ) } } return det }
Computes the determinant of a matrix using Laplace's formula

See https://en.wikipedia.org/wiki/Laplace_expansion

@function

@param {Array} data, lenght must be a square.
@param {Object} [scalar]
@param {Function} [scalar.addition       = (a, b) -> a + b ]
@param {Function} [scalar.multiplication = (a, b) -> a * b ]
@param {Function} [scalar.negation       = (a)    -> -a    ]
@param {Number} [order], defaults to Math.sqrt(data.length)

@returns {*} det
Computes the determinant of a matrix using Laplace s formula