Skip to content

Instantly share code, notes, and snippets.

@mayakraft
Last active February 15, 2021 16:51
Show Gist options
  • Save mayakraft/1ac95aa1e9f63b98fd0312b0f09e6039 to your computer and use it in GitHub Desktop.
Save mayakraft/1ac95aa1e9f63b98fd0312b0f09e6039 to your computer and use it in GitHub Desktop.
(a,b,c) ring algebra
class Ring {
a: number;
b: number;
c: number;
constructor(a: number, b: number, c:number) {
this.a = a;
this.b = b;
this.c = c;
}
};
// interface Ring { };
class Vector {
x: Ring;
y: Ring;
constructor(x: Ring, y: Ring) {
this.x = x;
this.y = y;
}
};
class Line {
u: Vector;
d: Ring;
// ξ²
xi_sq: Ring;
// normalized meaning true if length is 1. false if length is ξ
constructor(u: Vector, d: Ring, normalized: boolean) {
this.u = u;
this.d = d;
this.xi_sq = normalized
? new Ring(1, 0, 1)
: new Ring(2, 1, 2);
}
};
/**
*
* methods on ring elements
*
*/
const to_float = (r: Ring): number => (r.a / r.c) + ((r.b / r.c) * Math.sqrt(2));
/**
* make the C components match
* this method modifies the arguments in place!
* return boolean, was a match successful? (should succeed if power of 2)
*/
const match_denominator = (r: Ring, s: Ring): boolean => {
if (r.c === s.c) { return true; }
while (s.c < r.c) {
s.a *= 2;
s.b *= 2;
s.c *= 2;
}
while (r.c < s.c) {
r.a *= 2;
r.b *= 2;
r.c *= 2;
}
return (r.c === s.c);
};
const add = (r: Ring, s: Ring): Ring => {
if (!match_denominator(r, s)) { throw "cannot add, no common denominator"; }
return new Ring(r.a + s.a, r.b + s.b, r.c);
};
const subtract = (r: Ring, s: Ring): Ring => {
if (!match_denominator(r, s)) { throw "cannot subtract, no common denominator"; }
return new Ring(r.a - s.a, r.b - s.b, r.c);
};
/**
* @param {ring element}
* @param {number}
*/
const scale = (r: Ring, n: number): Ring => new Ring(n * r.a, n * r.b, r.c);
// todo:
const invert = (r) => r;
/** multiply two ring elements */
const multiply = (r: Ring, s: Ring): Ring => new Ring(
(r.a * s.a) + 2 * (s.a * s.b),
r.a * s.b + r.b * s.a,
r.c * s.c,
);
/** divide two ring elements: r/s */
const divide = (r: Ring, s: Ring): Ring => multiply(r, invert(s));
const simplify = (r: Ring): Ring => {
if (r.c <= 1) { return r; }
return (Number.isInteger(r.a / 2) && Number.isInteger(r.b / 2))
? simplify(new Ring(r.a/2, r.b/2, r.c/2))
: r;
};
/**
*
* methods on vectors / points, and lines
*
*/
const dot = (u: Vector, v: Vector): Ring => add(multiply(u.x, v.x), multiply(u.y, v.y));
/** (u.x * v.y - u.y * v.x) */
const determinant = (u: Vector, v: Vector): Ring => {
return subtract(multiply(u.x, v.y), multiply(u.y, v.x));
};
// unsure how this works
// const square_root = (r) => r;
// const magnitude_squared = (u: Vector): Ring => add(multiply(u.x, u.x), multiply(u.y, u.y));
// const magnitude = (u: Vector): Ring => square_root(magnitude_squared(u));
// const normalize = (u: Vector): Vector => {
// const m = magnitude(u);
// return new Vector(
// divide(u.x, m),
// divide(u.y, m),
// );
// };
const intersection = (l1: Line, l2: Line): Vector => {
const denomA = multiply(l1.u.x, l2.u.y);
const denomB = multiply(l1.u.y, l2.u.x);
const denominator = subtract(denomA, denomB);
const numerA = multiply(multiply(l1.d, l2.u.y), l1.xi_sq);
const numerB = multiply(multiply(l2.d, l1.u.y), l2.xi_sq);
const numerC = multiply(multiply(l2.d, l1.u.x), l2.xi_sq);
const numerD = multiply(multiply(l1.d, l2.u.x), l1.xi_sq);
const xNumerator = subtract(numerA, numerB);
const yNumerator = subtract(numerC, numerD);
return new Vector(
divide(xNumerator, denominator),
divide(yNumerator, denominator),
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment