src/color/kmeans/index.js
function fillMatrices(data, matrix, backtrackMatrix) {
  let nValues = matrix[0].length;

  // Shift values by the median to improve numeric stability
  let shift = data[Math.floor(nValues / 2)];

  // Cumulative sum and cumulative sum of squares for all values in data array
  let sums = [];
  let sumsOfSquares = [];

  // Initialize first column in matrix & backtrackMatrix
  for (let i = 0, shiftedValue; i < nValues; ++i) {
    shiftedValue = data[i] - shift;
    if (i === 0) {
      sums.push(shiftedValue);
      sumsOfSquares.push(shiftedValue * shiftedValue);
    } else {
      sums.push(sums[i - 1] + shiftedValue);
      sumsOfSquares.push(sumsOfSquares[i - 1] + shiftedValue * shiftedValue);
    }

    // Initialize for cluster = 0
    matrix[0][i] = ssq(0, i, sums, sumsOfSquares);
    backtrackMatrix[0][i] = 0;
  }

  // Initialize the rest of the columns
  let iMin;
  for (let cluster = 1; cluster < matrix.length; ++cluster) {
    if (cluster < matrix.length - 1) {
      iMin = cluster;
    } else {
      // No need to compute matrix[K-1][0] ... matrix[K-1][N-2]
      iMin = nValues - 1;
    }

    fillMatrixColumn(
      iMin,
      nValues - 1,
      cluster,
      matrix,
      backtrackMatrix,
      sums,
      sumsOfSquares
    );
  }
}
function fillMatrices(data, matrix, backtrackMatrix) {
  let nValues = matrix[0].length;

  // Shift values by the median to improve numeric stability
  let shift = data[Math.floor(nValues / 2)];

  // Cumulative sum and cumulative sum of squares for all values in data array
  let sums = [];
  let sumsOfSquares = [];

  // Initialize first column in matrix & backtrackMatrix
  for (let i = 0, shiftedValue; i < nValues; ++i) {
    shiftedValue = data[i] - shift;
    if (i === 0) {
      sums.push(shiftedValue);
      sumsOfSquares.push(shiftedValue * shiftedValue);
    } else {
      sums.push(sums[i - 1] + shiftedValue);
      sumsOfSquares.push(sumsOfSquares[i - 1] + shiftedValue * shiftedValue);
    }

    // Initialize for cluster = 0
    matrix[0][i] = ssq(0, i, sums, sumsOfSquares);
    backtrackMatrix[0][i] = 0;
  }

  // Initialize the rest of the columns
  let iMin;
  for (let cluster = 1; cluster < matrix.length; ++cluster) {
    if (cluster < matrix.length - 1) {
      iMin = cluster;
    } else {
      // No need to compute matrix[K-1][0] ... matrix[K-1][N-2]
      iMin = nValues - 1;
    }

    fillMatrixColumn(
      iMin,
      nValues - 1,
      cluster,
      matrix,
      backtrackMatrix,
      sums,
      sumsOfSquares
    );
  }
}
function fillMatrices ( data , matrix , backtrackMatrix ) { let nValues = matrix [ 0 ] . length ; // Shift values by the median to improve numeric stability let shift = data [ Math . floor ( nValues / 2 ) ] ; // Cumulative sum and cumulative sum of squares for all values in data array let sums = [ ] ; let sumsOfSquares = [ ] ; // Initialize first column in matrix & backtrackMatrix for ( let i = 0 , shiftedValue ; i < nValues ; ++ i ) { shiftedValue = data [ i ] - shift ; if ( i === 0 ) { sums . push ( shiftedValue ) ; sumsOfSquares . push ( shiftedValue * shiftedValue ) ; } else { sums . push ( sums [ i - 1 ] + shiftedValue ) ; sumsOfSquares . push ( sumsOfSquares [ i - 1 ] + shiftedValue * shiftedValue ) ; } // Initialize for cluster = 0 matrix [ 0 ] [ i ] = ssq ( 0 , i , sums , sumsOfSquares ) ; backtrackMatrix [ 0 ] [ i ] = 0 ; } // Initialize the rest of the columns let iMin ; for ( let cluster = 1 ; cluster < matrix . length ; ++ cluster ) { if ( cluster < matrix . length - 1 ) { iMin = cluster ; } else { // No need to compute matrix[K-1][0] ... matrix[K-1][N-2] iMin = nValues - 1 ; } fillMatrixColumn ( iMin , nValues - 1 , cluster , matrix , backtrackMatrix , sums , sumsOfSquares ) ; } }
Initializes the main matrices used in Ckmeans and kicks
off the divide and conquer cluster computation strategy

@private
@param {Array<number>} data sorted array of values
@param {Array<Array<number>>} matrix
@param {Array<Array<number>>} backtrackMatrix
Initializes the main matrices used in Ckmeans and kicks off the divide and conquer cluster computation strategy