UNPKG

molstar

Version:

A comprehensive macromolecular library.

325 lines 15.5 kB
"use strict"; 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