<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="style.css" />
    <title>Linear Algebra for computing</title>
  </head>
  <body>
    <div class="ERO" id="editor">
      <div class="explain">
        <h2>Gaussian Elimination</h2>
        <p>
          *Edit the initial Augmented Matrix below to try different values
        </p>
        <button id="updateMatrix">UPDATE</button>
      </div>
    </div>
    <script src="index.js"></script>
  </body>
</html>
body {
  display: flex;
  justify-content: center;
  align-items: center;
  color: beige;
}
table {
  border-collapse: collapse;
  color: beige;
}
div.ERO {
  border-radius: 10px;
  background-color: black;
  width: fit-content;
  color: beige;
  display: grid;
  grid-template-columns: 400px;
  grid-template-rows: repeat(5, 110px);
  grid-auto-flow: column;
}

div.step {
  width: fit-content;
  border-radius: 5px;
  border-left: 1px solid beige;
  border-right: 1px solid beige;
  justify-self: center;
  align-self: center;
  position: relative;
}

div.step:nth-child(2) table:hover {
  background-color: rgb(58, 89, 117);
}
div.step:nth-child(2) table {
  background-color: black;
}
div.step:nth-child(2) table::before {
  content: "INITIAL";
  position: absolute;
  left: 30%;
  top: -30%;
}

div.step:last-child table::after {
  content: "RESULT";
  position: absolute;
  left: 30%;
}
div.step:not(:last-child) table::after {
  content: "=>";
  position: absolute;
  left: 40%;
  transform: rotate(90deg);
  animation: appear 1s;
}
@keyframes appear {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
div div.explain {
  grid-row: 1;
  grid-column-start: span 5;
  justify-self: center;
  margin-top: -15px;
  text-align: center;
}
div div.explain p {
  font-size: 15px;
  font-style: italic;
}
td:nth-last-child(1) {
  border-left: 1px solid beige;
}

td {
  min-width: 20px;
  text-align: right;
}
// main flow
var og = [
  // example
  [0, 0, 2, 4, 2, 8],
  [1, 2, 4, 5, 3, -9],
  [-2, -4, -5, -4, 3, 6],
];

addMatrix(og, 3, 6, "step");
var ogMatrix = document.querySelector("div.ERO div.step");
ogMatrix.setAttribute("contentEditable", "true");
gaussianElimination(og, 3, 6);
document.getElementById("updateMatrix").addEventListener(
  "click",
  function () {
    console.log("input event fired");
    var thatTable = document.querySelector("table");
    var containerERO = document.querySelector("div.ERO");
    var oldstuff = document.querySelectorAll("div.step");
    oldstuff.forEach((x) => x.parentNode.removeChild(x));

    var newMatrix = tableToArray(thatTable);
    addMatrix(newMatrix, 3, 6, "step");
    var ogMatrix = document.querySelector("div.ERO div.step");
    ogMatrix.setAttribute("contentEditable", "true");
    gaussianElimination(newMatrix, 3, 6);
  },
  false
);

function tableToArray(table) {
  // for retrieving new array from html
  var result = [];
  var rows = table.rows;
  var cells, t;

  // Iterate over rows
  for (var i = 0, iLen = rows.length; i < iLen; i++) {
    cells = rows[i].cells;
    t = [];

    // Iterate over cells
    for (var j = 0, jLen = cells.length; j < jLen; j++) {
      t.push(parseInt(cells[j].textContent));
    }
    result.push(t);
  }
  return result;
}
function gaussianElimination(matrix, row, col) {
  var nonzeroFlag;
  var currRow = 0;
  var factor;
  // step 1 locate the leftmost column that does not consist entirely of zero
  for (var i = 0; i < col; i++) {
    nonzeroFlag = false;
    for (let j = currRow; j < row; j++) {
      var curr = matrix[j][i];
      if (curr != 0) {
        nonzeroFlag = true;
      }
    }

    if (!nonzeroFlag) {
      // if entire column is zero, move to next column
      continue;
    } else {
      // step 2 interchange top row with another row to get top row to nonzero
      for (let k = currRow; k < row; k++) {
        if (matrix[currRow][i] != 0) {
          // if top row is already nonzero, do nothing
          break;
        }
        if (matrix[k][i] == 0) {
          // if current row is zero, do nothing
          continue;
        }
        let temp = matrix[k];
        matrix[k] = matrix[currRow];
        matrix[currRow] = temp;
        addMatrix(matrix, 3, 6, "step");
        break;
      }
      // console.log(JSON.parse(JSON.stringify(matrix)));
      // step 3 for each row below the top row, add a suitable multiple of the top row to it,
      // so that the entry below the leading entry of the top row becomes zero
      for (var a = currRow + 1; a < row; a++) {
        if (matrix[a][i] == 0) {
          // leading column is already zero, do nothing
          continue;
        }
        if (
          (matrix[a][i] < 0 && matrix[currRow][i] > 0) ||
          (matrix[a][i] > 0 && matrix[currRow][i] < 0)
        ) {
          factor = Math.abs(matrix[a][i] / matrix[currRow][i]);
        } else {
          factor = matrix[a][i] / matrix[currRow][i];
          factor = -factor;
        }
        for (var u = i; u < col; u++) {
          matrix[a][u] = matrix[a][u] + matrix[currRow][u] * factor;
        }
        addMatrix(matrix, 3, 6, "step");
      }
      currRow++;

      // console.log(JSON.parse(JSON.stringify(matrix)));
    }
  }
}

function createAugmentedMatrix(row, column) {
  const reducer = (accumulator, currentValue) => accumulator + currentValue;
  var items = Array(row);
  for (var i = 0; i < row; i++) {
    var temp = Array(column);
    for (var j = 0; j < column - 1; j++) {
      temp[j] = getRandomInt(-10, 10);
    }
    temp[column - 1] = 0;
    temp[column - 1] = temp.reduce(reducer);
    items[i] = temp;
  }
  return items;
}

function addMatrix(items, row, col, which) {
  // add matrix into dom
  var table = document.createElement("div");
  table.setAttribute("class", which);
  var innerTable = document.createElement("table");
  for (var i = 0; i < row; i++) {
    var innerRow = document.createElement("tr");
    for (var j = 0; j < col; j++) {
      var innerCell = document.createElement("td");
      var temp = items[i][j];
      innerCell.innerHTML = temp;
      innerRow.appendChild(innerCell);
    }
    innerTable.appendChild(innerRow);
  }
  table.appendChild(innerTable);
  var containerERO = document.querySelector("div.ERO");
  containerERO.appendChild(table);
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.