Skip to content

Instantly share code, notes, and snippets.

@tylerneylon
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tylerneylon/5c5f89cf3be14c898026 to your computer and use it in GitHub Desktop.
Save tylerneylon/5c5f89cf3be14c898026 to your computer and use it in GitHub Desktop.
A page to try out elementary row operations on a matrix.
<!DOCTYPE html>
<!--
# matrix.html
*An interactive tool to perform elementary row operations on a matrix.*
I built this tool so I could speed up some hand calculations I was performing
while learning linear programming algorithms.
I thought it might be helpful for others learning or working with linear
algebra.
-->
<html>
<head>
<meta charset="UTF-8">
<title>matrix</title>
<style>
body { font-family: Helvetica, "sans serif" }
#t {
border-spacing: 0;
margin-top: 50px;
}
#t td {
padding: 10px;
}
.unselectable {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
cursor: default;
}
</style>
<script src="jquery-2.1.1.min.js"></script>
<script>
// All cells.
var cells = [];
// The selected cell.
var currCell = null;
var currRow = null;
var currCol = null;
var editCell = null;
var stopEditTimer = null;
var savedValue = null;
function val(row, col, newVal) {
if (newVal === undefined) return Number($(cells[row][col]).html())
$(cells[row][col]).html(newVal);
}
// Scales a row so that a given entry has value 1.
// If the entry is zero, this does nothing.
function normalizeCell(row, col) {
row = Number(row);
col = Number(col);
var cellVal = val(row, col);
if (cellVal === 0) {
console.log('Warning: attempt to normalize a zero cell at (row, col) %d, %d', row + 1, col + 1);
return;
}
var scale = 1 / cellVal;
for (var c = 0; c < cells[row].length; c++) {
val(row, c, scale * val(row, c));
}
}
function zeroCellWithRow(zeroRow, col, withRow) {
zeroRow = Number(zeroRow);
col = Number(col);
withRow = Number(withRow);
var srcVal = val(withRow, col);
var dstVal = val(zeroRow, col);
if (dstVal !== 0 && srcVal === 0) {
console.log('Warning: bad attempt to zero the cell %d, %d using %d, %d',
zeroRow + 1, col + 1, withRow + 1, col + 1);
return;
}
var withScale = -dstVal / srcVal;
for (var c = 0; c < cells[zeroRow].length; c++) {
val(zeroRow, c, val(withRow, c) * withScale + val(zeroRow, c));
}
}
function makeEditable(row, col, isEditable) {
editCell = null;
var c = cells[row][col];
$(c).attr('contenteditable', isEditable);
if (isEditable) {
$(c).removeClass('unselectable');
stopEditTimer = setTimeout(function () {
makeEditable(row, col, false);
}, 300);
} else {
$(c).addClass('unselectable');
}
}
// Returns a jquery wrapped <td> item ready to be added.
function makeCell(row, col, initData) {
var cell = $('<td>');
// Add the cell to the cells array, as cells[row][col].
if (!cells[row]) cells[row] = [];
cells[row][col] = cell[0];
cell.hover(function() {
$(this).css('background-color', '#aff');
}, function () {
var exitColor = (this == currCell ? '#ff7' : '');
$(this).css('background-color', exitColor);
});
cell.attr('class', 'unselectable');
cell.attr({row: row, col: col});
if (initData !== undefined) cell.html(initData);
cell.click(function() {
var r = $(this).attr('row');
var c = $(this).attr('col');
if (currCell && c === currCol && r !== currRow) {
// Zero out the destination cell, but if it's already zero
// then the user can select this cell instead.
if (Number($(this).html()) !== 0) {
zeroCellWithRow($(this).attr('row'), currCol, currRow);
return;
}
}
if (this === editCell) {
return;
}
makeEditable(r, c, true);
if (this === currCell) {
// It was already selected; normalize the cell.
normalizeCell(currRow, currCol);
return;
}
// Deselect the old cell, if any.
if (currCell) {
$(currCell).css('background-color', '');
}
$(this).css('background-color', '#ff7');
currCell = this;
currRow = r;
currCol = c;
});
cell.focus(function () {
editCell = this;
savedValue = $(this).html();
$(this).html('');
if (stopEditTimer) clearTimeout(stopEditTimer);
});
cell.keydown(function (event) {
var row = $(this).attr('row');
var col = $(this).attr('col');
if (event.which === 13) { // Return.
$(this).blur();
makeEditable(row, col, false);
}
if (event.which === 27) { // Esc.
$(this).html(savedValue);
$(this).blur();
makeEditable(row, col, false);
}
if (event.which === 9) { // Tab.
event.preventDefault();
if ($(this).html().length === 0) {
$(this).html(savedValue);
}
$(this).blur();
makeEditable(row, col, false);
var numRows = cells.length;
var numCols = cells[0].length;
col++;
if (col === numCols) {
col = 0;
row++;
if (row === numRows) return;
}
var next = cells[row][col];
$(next).click();
next.focus();
}
});
return cell;
}
$(document).ready(function() {
var numRows = 3;
var numCols = 7;
var rowElt = null;
var row = -1, col = 0;
for (var i = 0; i < numRows * numCols; i++) {
if (i % numCols === 0) {
rowElt = $('<tr>').appendTo('#t');
row++;
col = 0;
}
makeCell(row, col, 0).appendTo(rowElt);
col++;
}
});
</script>
</head>
<body>
<center>
<table id="t"></table>
</center>
</body>
</html>
@tylerneylon
Copy link
Author

matrix.html

An interactive tool to perform elementary row operations on a matrix.

I built this tool so I could speed up some hand calculations I was performing while learning linear programming algorithms. I thought it might be helpful for others learning or working with linear
algebra.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment