molstar
Version:
A comprehensive macromolecular library.
325 lines • 15.5 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.Tensor = void 0;
var mat3_1 = require("./3d/mat3");
/**
* Copyright (c) 2017-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
var mat4_1 = require("./3d/mat4");
var Tensor;
(function (Tensor) {
function Layout(dimensions, axisOrderSlowToFast, ctor) {
// need to reverse the axis order for better access.
var axisOrderFastToSlow = [];
for (var i = 0; i < axisOrderSlowToFast.length; i++)
axisOrderFastToSlow[i] = axisOrderSlowToFast[axisOrderSlowToFast.length - i - 1];
var accessDimensions = [1];
for (var i = 1; i < dimensions.length; i++)
accessDimensions[i] = dimensions[axisOrderFastToSlow[i - 1]];
return { dimensions: dimensions, axisOrderFastToSlow: axisOrderFastToSlow, axisOrderSlowToFast: axisOrderSlowToFast, accessDimensions: accessDimensions, defaultCtor: ctor || Float64Array };
}
function create(space, data) { return { space: space, data: data }; }
Tensor.create = create;
function Space(dimensions, axisOrderSlowToFast, ctor) {
var layout = Layout(dimensions, axisOrderSlowToFast, ctor);
var _a = accessors(layout), get = _a.get, set = _a.set, add = _a.add, dataOffset = _a.dataOffset, getCoords = _a.getCoords;
return { rank: dimensions.length, dimensions: dimensions, axisOrderSlowToFast: axisOrderSlowToFast, create: creator(layout), get: get, set: set, add: add, dataOffset: dataOffset, getCoords: getCoords };
}
Tensor.Space = Space;
function Data1(values) { return values; }
Tensor.Data1 = Data1;
function Vector(d, ctor) { return Space([d], [0], ctor); }
Tensor.Vector = Vector;
function ColumnMajorMatrix(rows, cols, ctor) { return Space([rows, cols], [1, 0], ctor); }
Tensor.ColumnMajorMatrix = ColumnMajorMatrix;
function RowMajorMatrix(rows, cols, ctor) { return Space([rows, cols], [0, 1], ctor); }
Tensor.RowMajorMatrix = RowMajorMatrix;
function toMat4(out, space, data) {
if (space.rank !== 2)
throw new Error('Invalid tensor rank');
var d0 = Math.min(4, space.dimensions[0]), d1 = Math.min(4, space.dimensions[1]);
for (var i = 0; i < d0; i++) {
for (var j = 0; j < d1; j++)
mat4_1.Mat4.setValue(out, i, j, space.get(data, i, j));
}
return out;
}
Tensor.toMat4 = toMat4;
function toMat3(out, space, data) {
if (space.rank !== 2)
throw new Error('Invalid tensor rank');
var d0 = Math.min(3, space.dimensions[0]), d1 = Math.min(3, space.dimensions[1]);
for (var i = 0; i < d0; i++) {
for (var j = 0; j < d1; j++)
mat3_1.Mat3.setValue(out, i, j, space.get(data, i, j));
}
return out;
}
Tensor.toMat3 = toMat3;
function toVec3(out, space, data) {
if (space.rank !== 1)
throw new Error('Invalid tensor rank');
var d0 = Math.min(3, space.dimensions[0]);
for (var i = 0; i < d0; i++)
out[i] = data[i];
return out;
}
Tensor.toVec3 = toVec3;
function toVec4(out, space, data) {
if (space.rank !== 1)
throw new Error('Invalid tensor rank');
var d0 = Math.min(4, space.dimensions[0]);
for (var i = 0; i < d0; i++)
out[i] = data[i];
return out;
}
Tensor.toVec4 = toVec4;
function areEqualExact(a, b) {
var len = a.length;
if (len !== b.length)
return false;
for (var i = 0; i < len; i++)
if (a[i] !== b[i])
return false;
return true;
}
Tensor.areEqualExact = areEqualExact;
function accessors(layout) {
var dimensions = layout.dimensions, ao = layout.axisOrderFastToSlow;
switch (dimensions.length) {
case 1: return {
get: function (t, d) { return t[d]; },
set: function (t, d, x) { return t[d] = x; },
add: function (t, d, x) { return t[d] += x; },
dataOffset: function (d) { return d; },
getCoords: function (o, c) {
c[0] = o;
return c;
}
};
case 2: {
// column major
if (ao[0] === 0 && ao[1] === 1) {
var rows_1 = dimensions[0];
return {
get: function (t, i, j) { return t[j * rows_1 + i]; },
set: function (t, i, j, x) { return t[j * rows_1 + i] = x; },
add: function (t, i, j, x) { return t[j * rows_1 + i] += x; },
dataOffset: function (i, j) { return j * rows_1 + i; },
getCoords: function (o, c) {
c[0] = o % rows_1;
c[1] = Math.floor(o / rows_1);
return c;
}
};
}
if (ao[0] === 1 && ao[1] === 0) {
var cols_1 = dimensions[1];
return {
get: function (t, i, j) { return t[i * cols_1 + j]; },
set: function (t, i, j, x) { return t[i * cols_1 + j] = x; },
add: function (t, i, j, x) { return t[i * cols_1 + j] += x; },
dataOffset: function (i, j) { return i * cols_1 + j; },
getCoords: function (o, c) {
c[0] = Math.floor(o / cols_1);
c[1] = o % cols_1;
return c;
}
};
}
throw new Error('bad axis order');
}
case 3: {
if (ao[0] === 0 && ao[1] === 1 && ao[2] === 2) { // 012 ijk
var u_1 = dimensions[0], v_1 = dimensions[1], uv_1 = u_1 * v_1;
return {
get: function (t, i, j, k) { return t[i + j * u_1 + k * uv_1]; },
set: function (t, i, j, k, x) { return t[i + j * u_1 + k * uv_1] = x; },
add: function (t, i, j, k, x) { return t[i + j * u_1 + k * uv_1] += x; },
dataOffset: function (i, j, k) { return i + j * u_1 + k * uv_1; },
getCoords: function (o, c) {
var p = Math.floor(o / u_1);
c[0] = o % u_1;
c[1] = p % v_1;
c[2] = Math.floor(p / v_1);
return c;
}
};
}
if (ao[0] === 0 && ao[1] === 2 && ao[2] === 1) { // 021 ikj
var u_2 = dimensions[0], v_2 = dimensions[2], uv_2 = u_2 * v_2;
return {
get: function (t, i, j, k) { return t[i + k * u_2 + j * uv_2]; },
set: function (t, i, j, k, x) { return t[i + k * u_2 + j * uv_2] = x; },
add: function (t, i, j, k, x) { return t[i + k * u_2 + j * uv_2] += x; },
dataOffset: function (i, j, k) { return i + k * u_2 + j * uv_2; },
getCoords: function (o, c) {
var p = Math.floor(o / u_2);
c[0] = o % u_2;
c[1] = Math.floor(p / v_2);
c[2] = p % v_2;
return c;
}
};
}
if (ao[0] === 1 && ao[1] === 0 && ao[2] === 2) { // 102 jik
var u_3 = dimensions[1], v_3 = dimensions[0], uv_3 = u_3 * v_3;
return {
get: function (t, i, j, k) { return t[j + i * u_3 + k * uv_3]; },
set: function (t, i, j, k, x) { return t[j + i * u_3 + k * uv_3] = x; },
add: function (t, i, j, k, x) { return t[j + i * u_3 + k * uv_3] += x; },
dataOffset: function (i, j, k) { return j + i * u_3 + k * uv_3; },
getCoords: function (o, c) {
var p = Math.floor(o / u_3);
c[0] = p % v_3;
c[1] = o % u_3;
c[2] = Math.floor(p / v_3);
return c;
}
};
}
if (ao[0] === 1 && ao[1] === 2 && ao[2] === 0) { // 120 jki
var u_4 = dimensions[1], v_4 = dimensions[2], uv_4 = u_4 * v_4;
return {
get: function (t, i, j, k) { return t[j + k * u_4 + i * uv_4]; },
set: function (t, i, j, k, x) { return t[j + k * u_4 + i * uv_4] = x; },
add: function (t, i, j, k, x) { return t[j + k * u_4 + i * uv_4] += x; },
dataOffset: function (i, j, k) { return j + k * u_4 + i * uv_4; },
getCoords: function (o, c) {
var p = Math.floor(o / u_4);
c[0] = Math.floor(p / v_4);
c[1] = o % u_4;
c[2] = p % v_4;
return c;
}
};
}
if (ao[0] === 2 && ao[1] === 0 && ao[2] === 1) { // 201 kij
var u_5 = dimensions[2], v_5 = dimensions[0], uv_5 = u_5 * v_5;
return {
get: function (t, i, j, k) { return t[k + i * u_5 + j * uv_5]; },
set: function (t, i, j, k, x) { return t[k + i * u_5 + j * uv_5] = x; },
add: function (t, i, j, k, x) { return t[k + i * u_5 + j * uv_5] += x; },
dataOffset: function (i, j, k) { return k + i * u_5 + j * uv_5; },
getCoords: function (o, c) {
var p = Math.floor(o / u_5);
c[0] = p % v_5;
c[1] = Math.floor(p / v_5);
c[2] = o % u_5;
return c;
}
};
}
if (ao[0] === 2 && ao[1] === 1 && ao[2] === 0) { // 210 kji
var u_6 = dimensions[2], v_6 = dimensions[1], uv_6 = u_6 * v_6;
return {
get: function (t, i, j, k) { return t[k + j * u_6 + i * uv_6]; },
set: function (t, i, j, k, x) { return t[k + j * u_6 + i * uv_6] = x; },
add: function (t, i, j, k, x) { return t[k + j * u_6 + i * uv_6] += x; },
dataOffset: function (i, j, k) { return k + j * u_6 + i * uv_6; },
getCoords: function (o, c) {
var p = Math.floor(o / u_6);
c[0] = Math.floor(p / v_6);
c[1] = p % v_6;
c[2] = o % u_6;
return c;
}
};
}
throw new Error('bad axis order');
}
default: return {
get: function (t) {
var c = [];
for (var _a = 1; _a < arguments.length; _a++) {
c[_a - 1] = arguments[_a];
}
return t[dataOffset(layout, c)];
},
set: function (t) {
var c = [];
for (var _a = 1; _a < arguments.length; _a++) {
c[_a - 1] = arguments[_a];
}
return t[dataOffset(layout, c)] = c[c.length - 1];
},
add: function (t) {
var c = [];
for (var _a = 1; _a < arguments.length; _a++) {
c[_a - 1] = arguments[_a];
}
return t[dataOffset(layout, c)] += c[c.length - 1];
},
dataOffset: function () {
var c = [];
for (var _a = 0; _a < arguments.length; _a++) {
c[_a] = arguments[_a];
}
return dataOffset(layout, c);
},
getCoords: function (o, c) { return getCoords(layout, o, c); },
};
}
}
function creator(layout) {
var ds = layout.dimensions;
var size = 1;
for (var i = 0, _i = ds.length; i < _i; i++)
size *= ds[i];
return function (ctor) { return new (ctor || layout.defaultCtor)(size); };
}
function dataOffset(layout, coord) {
var acc = layout.accessDimensions, ao = layout.axisOrderFastToSlow;
var d = acc.length - 1;
var o = acc[d] * coord[ao[d]];
for (var i = d - 1; i >= 0; i--) {
o = (o + coord[ao[i]]) * acc[i];
}
return o;
}
function getCoords(layout, o, coords) {
var dim = layout.dimensions, ao = layout.axisOrderFastToSlow;
var d = dim.length;
var c = o;
for (var i = 0; i < d; i++) {
var d_1 = dim[ao[i]];
coords[ao[i]] = c % d_1;
c = Math.floor(c / d_1);
}
coords[ao[d + 1]] = c;
return coords;
}
// Convers "slow to fast" axis order to "fast to slow" and vice versa.
function invertAxisOrder(v) {
var ret = [];
for (var i = 0; i < v.length; i++) {
ret[i] = v[v.length - i - 1];
}
return ret;
}
Tensor.invertAxisOrder = invertAxisOrder;
function reorder(xs, indices) {
var ret = [];
for (var i = 0; i < xs.length; i++)
ret[i] = xs[indices[i]];
return ret;
}
function convertToCanonicalAxisIndicesFastToSlow(order) {
var indices = new Int32Array(order.length);
for (var i = 0; i < order.length; i++)
indices[order[i]] = i;
return function (xs) { return reorder(xs, indices); };
}
Tensor.convertToCanonicalAxisIndicesFastToSlow = convertToCanonicalAxisIndicesFastToSlow;
function convertToCanonicalAxisIndicesSlowToFast(order) {
var indices = new Int32Array(order.length);
for (var i = 0; i < order.length; i++)
indices[order[order.length - i - 1]] = i;
return function (xs) { return reorder(xs, indices); };
}
Tensor.convertToCanonicalAxisIndicesSlowToFast = convertToCanonicalAxisIndicesSlowToFast;
})(Tensor = exports.Tensor || (exports.Tensor = {}));
//# sourceMappingURL=tensor.js.map
;