Skip to content

Commit

Permalink
feat(bitfield): add and/or/xor/not() methods, add IClear, ICopy impls
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Mar 6, 2020
1 parent c07cf04 commit 52d3005
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 6 deletions.
50 changes: 47 additions & 3 deletions packages/bitfield/src/bitfield.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import { align } from "@thi.ng/binary";
import { toString } from "./util";
import { assert } from "@thi.ng/api";
import {
align,
bitAnd,
bitNot,
bitOr,
bitXor
} from "@thi.ng/binary";
import { binOp, toString } from "./util";
import type { Fn2, IClear, ICopy } from "@thi.ng/api";

/**
* 1D bit field, backed by a Uint32Array. Hence size is always rounded
* up to a multiple of 32.
*/
export class BitField {
export class BitField implements IClear, ICopy<BitField> {
data: Uint32Array;
n: number;

Expand All @@ -16,6 +24,16 @@ export class BitField {
!isNumber && this.setRange(0, <any>bits);
}

clear() {
this.data.fill(0);
}

copy() {
const dest = new BitField(this.n);
dest.data.set(this.data);
return dest;
}

/**
* Resizes bitfield to new size given (rounded up to multiples of
* 32).
Expand Down Expand Up @@ -98,9 +116,35 @@ export class BitField {
return r;
}

and(field: BitField) {
return this.binOp(field, bitAnd);
}

or(field: BitField) {
return this.binOp(field, bitOr);
}

xor(field: BitField) {
return this.binOp(field, bitXor);
}

not() {
return this.binOp(this, bitNot);
}

toString() {
return toString(this.data);
}

protected binOp(field: BitField, op: Fn2<number, number, number>) {
this.ensureSize(field);
binOp(this.data, field.data, op);
return this;
}

protected ensureSize(field: BitField) {
assert(field.n === this.n, `fields must be same size`);
}
}

export const bitField = (bits: number | string | ArrayLike<boolean>) =>
Expand Down
53 changes: 50 additions & 3 deletions packages/bitfield/src/bitmatrix.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import { align } from "@thi.ng/binary";
import { toString } from "./util";
import { assert } from "@thi.ng/api";
import {
align,
bitAnd,
bitNot,
bitOr,
bitXor
} from "@thi.ng/binary";
import { binOp, toString } from "./util";
import type { Fn2, IClear, ICopy } from "@thi.ng/api";

/**
* MxN row-major 2D bit matrix, backed by a Uint32Array. Hence the width
* (number of columns) is always rounded up to a multiple of 32.
*/
export class BitMatrix {
export class BitMatrix implements IClear, ICopy<BitMatrix> {
data: Uint32Array;
stride: number;
m: number;
Expand All @@ -18,6 +26,16 @@ export class BitMatrix {
this.data = new Uint32Array(rows * this.stride);
}

clear() {
this.data.fill(0);
}

copy() {
const dest = new BitMatrix(this.m, this.n);
dest.data.set(this.data);
return dest;
}

/**
* Resizes matrix to new size given (width always rounded up to
* multiples of 32).
Expand Down Expand Up @@ -99,13 +117,42 @@ export class BitMatrix {
return r;
}

and(mat: BitMatrix) {
return this.binOp(mat, bitAnd);
}

or(mat: BitMatrix) {
return this.binOp(mat, bitOr);
}

xor(mat: BitMatrix) {
return this.binOp(mat, bitXor);
}

not() {
return this.binOp(this, bitNot);
}

toString() {
const res: string[] = [];
for (let i = 0, j = 0, s = this.stride; i < this.m; i++, j += s) {
res.push(toString(this.data.subarray(j, j + s)));
}
return res.join("\n");
}

protected binOp(field: BitMatrix, op: Fn2<number, number, number>) {
this.ensureSize(field);
binOp(this.data, field.data, op);
return this;
}

protected ensureSize(field: BitMatrix) {
assert(
field.m === this.m && field.n === this.n,
`matrices must be same size`
);
}
}

export const bitMatrix = (rows: number, cols = rows) =>
Expand Down
16 changes: 16 additions & 0 deletions packages/bitfield/src/util.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { B32 } from "@thi.ng/strings";
import type { Fn2 } from "@thi.ng/api";

/**
* Converts 1D bitfield to binary string.
Expand All @@ -8,3 +9,18 @@ import { B32 } from "@thi.ng/strings";
* @internal
*/
export const toString = (data: Uint32Array) => [...data].map(B32).join("");

/**
* @param dest -
* @param src -
* @param op -
*
* @internal
*/
export const binOp = (
dest: Uint32Array,
src: Uint32Array,
op: Fn2<number, number, number>
) => {
for (let i = src.length; --i >= 0; ) dest[i] = op(src[i], dest[i]);
};

0 comments on commit 52d3005

Please sign in to comment.