Skip to content

Commit

Permalink
feat(vectors): add vector ops codegen, update basic vec2/3/4 ops (#51)
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Sep 28, 2018
1 parent d964865 commit b5ed254
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 249 deletions.
12 changes: 12 additions & 0 deletions packages/vectors/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,24 @@ export type VecOp1<T> = (v: Vec, i?: number, s?: number) => T;
*/
export type VecOp2<T> = (a: Vec, b: ReadonlyVec, ia?: number, ib?: number, sa?: number, sb?: number) => T;

/**
* A vector operation involving a vector and a scalar. The vector might
* be modified.
*/
export type VecOpN2<T> = (a: Vec, n: number, ia?: number, sa?: number) => T;

/**
* A vector operation involving input readonly two vectors and writing
* result to an output vector `out`.
*/
export type VecOp2o<T> = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, io?: number, ia?: number, ib?: number, so?: number, sa?: number, sb?: number) => T;

/**
* A vector operation involving input readonly two vectors and writing
* result to an output vector `out`.
*/
export type VecOpN2o<T> = (out: Vec, a: ReadonlyVec, n: number, io?: number, ia?: number, so?: number, sa?: number) => T;

/**
* A readonly vector operation involving only a single vector.
*/
Expand Down
70 changes: 70 additions & 0 deletions packages/vectors/src/codegen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import {
Vec,
VecOp1,
VecOp2,
VecOp2o,
VecOpN2,
VecOpN2o
} from "@thi.ng/vectors/src/api";

const compile = (args: string, src: string[]) =>
new Function(args, src.join(""));

const assemble = (fn: (op: string, i: number) => string, dim: number, op: string, ret = "a") => {
const src = [];
for (let i = 0; i < dim; i++) {
src.push(fn(op, i));
}
src.push(`return ${ret};`);
return src;
}

const uniop = (op: string, i: number) =>
i > 1 ?
`a[ia+${i}*sa]=${op}(a[ia+${i}*sa]);` :
i == 1 ?
`a[ia+sa]=${op}(a[ia+sa]);` :
`a[ia]=${op}(a[ia]);`;

const binop = (op: string, i: number) =>
i > 1 ?
`a[ia+${i}*sa]${op}=b[ib+${i}*sb];` :
i == 1 ?
`a[ia+sa]${op}=b[ib+sb];` :
`a[ia]${op}=b[ib];`;

const binopN = (op: string, i: number) =>
i > 1 ?
`a[ia+${i}*sa]${op}=n;` :
i == 1 ?
`a[ia+sa]${op}=n;` :
`a[ia]${op}=n;`;

const binopO = (op: string, i: number) =>
i > 1 ?
`o[io+${i}*so]=a[ia+${i}*sa]${op}b[ib+${i}*sb];` :
i == 1 ?
`o[io+so]=a[ia+sa]${op}b[ib+sb];` :
`o[io]=a[ia]${op}b[ib];`;

const binopON = (op: string, i: number) =>
i > 1 ?
`o[io+${i}*so]=a[ia+${i}*sa]${op}n;` :
i == 1 ?
`o[io+so]=a[ia+sa]${op}n;` :
`o[io]=a[ia]${op}n;`;

export const vuniop = (dim: number, op: string): VecOp1<Vec> =>
<any>compile("a,ia=0,sa=1", assemble(uniop, dim, op));

export const vbinop = (dim: number, op: string): VecOp2<Vec> =>
<any>compile("a,b,ia=0,ib=0,sa=1,sb=1", assemble(binop, dim, op));

export const vbinopN = (dim: number, op: string): VecOpN2<Vec> =>
<any>compile("a,n,ia=0,sa=1", assemble(binopN, dim, op));

export const vbinopO = (dim: number, op: string): VecOp2o<Vec> =>
<any>compile("o,a,b,io=0,ia=0,ib=0,so=1,sa=1,sb=1", assemble(binopO, dim, op, "o"));

export const vbinopON = (dim: number, op: string): VecOpN2o<Vec> =>
<any>compile("o,a,n,io=0,ia=0,so=1,sa=1", assemble(binopON, dim, op, "o"));
2 changes: 2 additions & 0 deletions packages/vectors/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ export * from "./gvec";
export * from "./vec2";
export * from "./vec3";
export * from "./vec4";

export * from "./codegen";
72 changes: 25 additions & 47 deletions packages/vectors/src/vec2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ import {
Vec,
ZERO4
} from "./api";
import {
vbinop,
vbinopN,
vbinopO,
vbinopON
} from "./codegen";
import { $iter, declareIndices } from "./common";
import {
atan2Abs1,
Expand Down Expand Up @@ -91,53 +97,25 @@ export const eqDelta2 = (a: ReadonlyVec, b: ReadonlyVec, eps = EPS, ia = 0, ib =
eqDelta1(a[ia], b[ib], eps) &&
eqDelta1(a[ia + sa], b[ib + sb], eps);

export const add2 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) =>
(a[ia] += b[ib], a[ia + sa] += b[ib + sb], a);

export const sub2 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) =>
(a[ia] -= b[ib], a[ia + sa] -= b[ib + sb], a);

export const mul2 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) =>
(a[ia] *= b[ib], a[ia + sa] *= b[ib + sb], a);

export const div2 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) =>
(a[ia] /= b[ib], a[ia + sa] /= b[ib + sb], a);

export const add2o = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, io = 0, ia = 0, ib = 0, so = 1, sa = 1, sb = 1) =>
(out[io] = a[ia] + b[ib], out[io + so] = a[ia + sa] + b[ib + sb], out);

export const sub2o = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, io = 0, ia = 0, ib = 0, so = 1, sa = 1, sb = 1) =>
(out[io] = a[ia] - b[ib], out[io + so] = a[ia + sa] - b[ib + sb], out);

export const mul2o = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, io = 0, ia = 0, ib = 0, so = 1, sa = 1, sb = 1) =>
(out[io] = a[ia] * b[ib], out[io + so] = a[ia + sa] * b[ib + sb], out);

export const div2o = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, io = 0, ia = 0, ib = 0, so = 1, sa = 1, sb = 1) =>
(out[io] = a[ia] / b[ib], out[io + so] = a[ia + sa] / b[ib + sb], out);

export const addN2 = (a: Vec, n: number, ia = 0, sa = 1) =>
(a[ia] += n, a[ia + sa] += n, a);

export const subN2 = (a: Vec, n: number, ia = 0, sa = 1) =>
(a[ia] -= n, a[ia + sa] -= n, a);

export const mulN2 = (a: Vec, n: number, ia = 0, sa = 1) =>
(a[ia] *= n, a[ia + sa] *= n, a);

export const divN2 = (a: Vec, n: number, ia = 0, sa = 1) =>
(a[ia] /= n, a[ia + sa] /= n, a);

export const addN2o = (out: Vec, a: ReadonlyVec, n: number, io = 0, ia = 0, so = 1, sa = 1) =>
(out[io] = a[ia] + n, out[io + so] = a[ia + sa] + n, out);

export const subN2o = (out: Vec, a: ReadonlyVec, n: number, io = 0, ia = 0, so = 1, sa = 1) =>
(out[io] = a[ia] - n, out[io + so] = a[ia + sa] - n, out);

export const mulN2o = (out: Vec, a: ReadonlyVec, n: number, io = 0, ia = 0, so = 1, sa = 1) =>
(out[io] = a[ia] * n, out[io + so] = a[ia + sa] * n, out);

export const divN2o = (out: Vec, a: ReadonlyVec, n: number, io = 0, ia = 0, so = 1, sa = 1) =>
(out[io] = a[ia] / n, out[io + so] = a[ia + sa] / n, out);
export const add2 = vbinop(2, "+");
export const sub2 = vbinop(2, "-");
export const mul2 = vbinop(2, "*");
export const div2 = vbinop(2, "/");

export const add2o = vbinopO(2, "+");
export const sub2o = vbinopO(2, "-");
export const mul2o = vbinopO(2, "*");
export const div2o = vbinopO(2, "/");

export const addN2 = vbinopN(2, "+");
export const subN2 = vbinopN(2, "-");
export const mulN2 = vbinopN(2, "*");
export const divN2 = vbinopN(2, "/");

export const addN2o = vbinopON(2, "+");
export const subN2o = vbinopON(2, "-");
export const mulN2o = vbinopON(2, "*");
export const divN2o = vbinopON(2, "/");

export const neg2 = (a: Vec, ia = 0, sa = 1) =>
mulN2(a, -1, ia, sa);
Expand Down
120 changes: 25 additions & 95 deletions packages/vectors/src/vec3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ import {
Vec,
ZERO4
} from "./api";
import {
vbinop,
vbinopN,
vbinopO,
vbinopON
} from "./codegen";
import { $iter, declareIndices } from "./common";
import {
atan2Abs1,
Expand Down Expand Up @@ -115,101 +121,25 @@ export const eqDelta3 = (a: ReadonlyVec, b: ReadonlyVec, eps = EPS, ia = 0, ib =
eqDelta1(a[ia + sa], b[ib + sb], eps) &&
eqDelta1(a[ia + 2 * sa], b[ib + 2 * sb], eps);

export const add3 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => (
a[ia] += b[ib],
a[ia + sa] += b[ib + sb],
a[ia + 2 * sa] += b[ib + 2 * sb],
a
);

export const mul3 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => (
a[ia] *= b[ib],
a[ia + sa] *= b[ib + sb],
a[ia + 2 * sa] *= b[ib + 2 * sb],
a
);

export const sub3 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => (
a[ia] -= b[ib],
a[ia + sa] -= b[ib + sb],
a[ia + 2 * sa] -= b[ib + 2 * sb],
a
);

export const div3 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => (
a[ia] /= b[ib],
a[ia + sa] /= b[ib + sb],
a[ia + 2 * sa] /= b[ib + 2 * sb],
a
);

export const add3o = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, io = 0, ia = 0, ib = 0, so = 1, sa = 1, sb = 1) => (
out[io] = a[ia] + b[ib],
out[io + so] = a[ia + sa] + b[ib + sb],
out[io + 2 * so] = a[ia + 2 * sa] + b[ib + 2 * sb],
out
);

export const sub3o = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, io = 0, ia = 0, ib = 0, so = 1, sa = 1, sb = 1) => (
out[io] = a[ia] - b[ib],
out[io + so] = a[ia + sa] - b[ib + sb],
out[io + 2 * so] = a[ia + 2 * sa] - b[ib + 2 * sb],
out
);

export const mul3o = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, io = 0, ia = 0, ib = 0, so = 1, sa = 1, sb = 1) => (
out[io] = a[ia] * b[ib],
out[io + so] = a[ia + sa] * b[ib + sb],
out[io + 2 * so] = a[ia + 2 * sa] * b[ib + 2 * sb],
out
);

export const div3o = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, io = 0, ia = 0, ib = 0, so = 1, sa = 1, sb = 1) => (
out[io] = a[ia] / b[ib],
out[io + so] = a[ia + sa] / b[ib + sb],
out[io + 2 * so] = a[ia + 2 * sa] / b[ib + 2 * sb],
out
);

export const addN3 = (a: Vec, n: number, ia = 0, sa = 1) =>
(a[ia] += n, a[ia + sa] += n, a[ia + 2 * sa] += n, a);

export const subN3 = (a: Vec, n: number, ia = 0, sa = 1) =>
(a[ia] -= n, a[ia + sa] -= n, a[ia + 2 * sa] -= n, a);

export const mulN3 = (a: Vec, n: number, ia = 0, sa = 1) =>
(a[ia] *= n, a[ia + sa] *= n, a[ia + 2 * sa] *= n, a);

export const divN3 = (a: Vec, n: number, ia = 0, sa = 1) =>
(a[ia] /= n, a[ia + sa] /= n, a[ia + 2 * sa] /= n, a);

export const addN3o = (out: Vec, a: ReadonlyVec, n: number, io = 0, ia = 0, so = 1, sa = 1) => (
out[io] = a[ia] + n,
out[io + so] = a[ia + sa] + n,
out[io + 2 * so] = a[ia + 2 * sa] + n,
out
);

export const subN3o = (out: Vec, a: ReadonlyVec, n: number, io = 0, ia = 0, so = 1, sa = 1) => (
out[io] = a[ia] - n,
out[io + so] = a[ia + sa] - n,
out[io + 2 * so] = a[ia + 2 * sa] - n,
out
);

export const mulN3o = (out: Vec, a: ReadonlyVec, n: number, io = 0, ia = 0, so = 1, sa = 1) => (
out[io] = a[ia] * n,
out[io + so] = a[ia + sa] * n,
out[io + 2 * so] = a[ia + 2 * sa] * n,
out
);

export const divN3o = (out: Vec, a: ReadonlyVec, n: number, io = 0, ia = 0, so = 1, sa = 1) => (
out[io] = a[ia] / n,
out[io + so] = a[ia + sa] / n,
out[io + 2 * so] = a[ia + 2 * sa] / n,
out
);
export const add3 = vbinop(3, "+");
export const sub3 = vbinop(3, "-");
export const mul3 = vbinop(3, "*");
export const div3 = vbinop(3, "/");

export const add3o = vbinopO(3, "+");
export const sub3o = vbinopO(3, "-");
export const mul3o = vbinopO(3, "*");
export const div3o = vbinopO(3, "/");

export const addN3 = vbinopN(3, "+");
export const subN3 = vbinopN(3, "-");
export const mulN3 = vbinopN(3, "*");
export const divN3 = vbinopN(3, "/");

export const addN3o = vbinopON(3, "+");
export const subN3o = vbinopON(3, "-");
export const mulN3o = vbinopON(3, "*");
export const divN3o = vbinopON(3, "/");

export const neg3 = (a: Vec, ia = 0, sa = 1) =>
mulN3(a, -1, ia, sa);
Expand Down
Loading

0 comments on commit b5ed254

Please sign in to comment.