import * as utils from "./utils.js";
import * as wasm from "./wasm.js";
/**
* Apply delayed arithmetic to a {@linkplain ScranMatrix} object.
*
* @param {ScranMatrix} x - A ScranMatrix object.
* @param {string} operation - The operation to perform, one of `"+"`, `"*"`, `"/"` or `"-"`.
* @param {number|Array|WasmArray|TypedArray} value - The other operand in the arithmetic operation.
* If a scalar, this is applied element-wise to each entry of `x`.
* If a vector, it is assumed to map to either the rows or columns of `x` (see `along`) and each entry is applied to all values of the corresponding row/column.
* @param {object} [options={}] - Optional parameters.
* @param {boolean} [options.right=true] - Whether `value` is applied to the right of `x`.
* Only relevant for subtraction or division.
* @param {string} [options.along="row"] - Whether an array-like `value` maps to the rows (`"row"`) or columns (`"column"`).
* If rows, `value` should have length equal to `x.numberOfRows()`.
* If columns, `value` should have length equal to `x.numberOfColumns()`.
* @param {boolean} [options.inPlace=false] - Whether to modify `x` in place.
* If `false`, a new ScranMatrix is returned.
*
* @return {ScranMatrix} A ScranMatrix containing the delayed arithmetic operation on `x`.
* If `inPlace = true`, this is a reference to `x`, otherwise it is a new ScranMatrix.
*/
export function delayedArithmetic(x, operation, value, options = {}) {
const { right = true, along = "row", inPlace = false, ...others } = options;
utils.checkOtherOptions(others);
let xcopy;
let vbuffer;
let target;
try {
if (inPlace) {
target = x;
} else {
xcopy = x.clone();
target = xcopy;
}
let margin = (along == "row" ? 0 : 1);
if (typeof value == "number") {
wasm.call(module => module.delayed_arithmetic_scalar(target.matrix, operation, right, value));
} else {
vbuffer = utils.wasmifyArray(value, "Float64WasmArray")
wasm.call(module => module.delayed_arithmetic_vector(target.matrix, operation, right, margin, vbuffer.offset, vbuffer.length));
}
} catch (e) {
utils.free(xcopy);
throw e;
} finally {
utils.free(vbuffer);
}
return target;
}
/**
* Apply delayed math to a {@linkplain ScranMatrix} object.
*
* @param {ScranMatrix} x - A ScranMatrix object.
* @param {string} operation - The operation to perform, one of `"log"`, `"sqrt"`, `"abs"`, `"log1p"`, `"round"` or `"exp"`.
* @param {object} [options={}] - Optional parameters.
* @param {number} [options.logBase=null] - Base of the logarithm to use when `operation = "log"`.
* Defaults to the natural base.
* @param {boolean} [options.inPlace=false] - Whether to modify `x` in place.
* If `false`, a new ScranMatrix is returned.
*
* @return {ScranMatrix} A ScranMatrix containing the delayed math operation on `x`.
* If `inPlace = true`, this is a reference to `x`, otherwise it is a new ScranMatrix.
*/
export function delayedMath(x, operation, options = {}) {
let { logBase = null, inPlace = false, ...others } = options;
utils.checkOtherOptions(others);
let xcopy;
let target;
try {
if (inPlace) {
target = x;
} else {
xcopy = x.clone();
target = xcopy;
}
if (logBase === null) {
logBase = -1;
}
wasm.call(module => module.delayed_math(target.matrix, operation, logBase));
} catch (e) {
utils.free(xcopy);
throw e;
}
return target;
}
/**
* Transpose a {@linkplain ScranMatrix} object.
*
* @param {ScranMatrix} x - A ScranMatrix object.
* @param {object} [options={}] - Optional parameters.
* @param {boolean} [options.inPlace=false] - Whether to modify `x` in place.
* If `false`, a new ScranMatrix is returned.
*
* @return {ScranMatrix} A ScranMatrix containing the transposition of `x`.
* If `inPlace = true`, this is a reference to `x`, otherwise it is a new ScranMatrix.
*/
export function transpose(x, options = {}) {
const { inPlace = false, ...others } = options;
utils.checkOtherOptions(others);
let xcopy;
let target;
try {
if (inPlace) {
target = x;
} else {
xcopy = x.clone();
target = xcopy;
}
wasm.call(module => module.transpose(target.matrix));
} catch (e) {
utils.free(xcopy);
throw e;
}
return target;
}