Comparing version 1.1.15 to 1.1.16
@@ -104,2 +104,4 @@ # Contributing to MathJSLab | ||
* [MATLAB® grammar from Grammar Zoo](https://slebok.github.io/zoo/markup/scientific/matlab/srour/extracted/index.html) | ||
* [Wikipedia - Row- and column-major order](https://en.wikipedia.org/wiki/Row-_and_column-major_order) | ||
* [Scratchapixel 3.0 - Geometry - Row Major vs Column Major Vector](https://www.scratchapixel.com/lessons/mathematics-physics-for-computer-graphics/geometry/row-major-vs-column-major-vector.html) | ||
@@ -57,3 +57,3 @@ /** | ||
*/ | ||
export type NodeExpr = NodeName | NodeArgExpr | NodeOperation | NodeList | NodeRange | NodeReturnList; | ||
export type NodeExpr = NodeName | NodeArgExpr | NodeOperation | NodeList | NodeRange | NodeReturnList | MultiArray | ComplexDecimal; | ||
/** | ||
@@ -234,3 +234,3 @@ * Reserved node. | ||
readonly linearize: typeof MultiArray.linearize; | ||
readonly toTensor: typeof MultiArray.number2matrix1x1; | ||
readonly toTensor: typeof MultiArray.numberToMatrix; | ||
private readonly unparseMLFunctions; | ||
@@ -340,2 +340,3 @@ /** | ||
nodeReturnList(selector: ReturnSelector): NodeReturnList; | ||
reduceIfReturnList(value: any): any; | ||
/** | ||
@@ -385,6 +386,6 @@ * Validate left hand side of assignment node. | ||
* Expression tree recursive evaluator. | ||
* @param tree | ||
* @param local | ||
* @param fname | ||
* @returns | ||
* @param tree Expression to evaluate. | ||
* @param local Set `true` if evaluating function. | ||
* @param fname Function name. | ||
* @returns Expression tree evaluated. | ||
*/ | ||
@@ -391,0 +392,0 @@ Evaluator(tree: any, local?: boolean, fname?: string): any; |
@@ -29,2 +29,11 @@ import { ComplexDecimal } from './complex-decimal'; | ||
/** | ||
* Linearized functions | ||
*/ | ||
static linearizedFunctions: { | ||
[name: string]: { | ||
func: Function; | ||
lin: boolean[]; | ||
}; | ||
}; | ||
/** | ||
* Dimension property. | ||
@@ -122,3 +131,4 @@ */ | ||
*/ | ||
static number2matrix1x1(value: ComplexDecimal | MultiArray): MultiArray; | ||
static numberToMatrix(value: ComplexDecimal | MultiArray): MultiArray; | ||
static matrixToNumber(value: ComplexDecimal | MultiArray): MultiArray | ComplexDecimal; | ||
/** | ||
@@ -203,14 +213,14 @@ * Copy of MultiArray. | ||
* Set selected items from MultiArray by linear index or subscripts. | ||
* @param nameTable | ||
* @param id | ||
* @param args | ||
* @param right | ||
* @param nameTable Name Table | ||
* @param id Identifier | ||
* @param args linear indices or subscripts | ||
* @param right Value to assign. | ||
*/ | ||
static setItems(nameTable: TNameTable, id: string, args: any[], right: MultiArray): void; | ||
/** | ||
* Get selected items from MultiArray by linear index or subscripts. | ||
* @param M | ||
* @param id | ||
* Get selected items from MultiArray by linear indices or subscripts. | ||
* @param M Matrix | ||
* @param id Identifier | ||
* @param indexList | ||
* @returns | ||
* @returns MultiArray of selected items | ||
*/ | ||
@@ -444,2 +454,23 @@ static getItems(M: MultiArray, id: string, indexList: (ComplexDecimal | MultiArray)[]): MultiArray | ComplexDecimal; | ||
static qr(M: MultiArray): any; | ||
/** | ||
* Convert subscripts to linear indices. | ||
* @param DIMS | ||
* @param S | ||
* @returns | ||
*/ | ||
static sub2ind(DIMS: any, ...S: any): ComplexDecimal; | ||
/** | ||
* Convert linear indices to subscripts. | ||
* @param DIMS | ||
* @param IND | ||
* @returns | ||
*/ | ||
static ind2sub(DIMS: any, IND: any): any; | ||
/** | ||
* Array size. | ||
* @param M Matrix | ||
* @param DIM | ||
* @returns | ||
*/ | ||
static size(M: MultiArray, ...DIM: ComplexDecimal[] | ComplexDecimal[][]): MultiArray | ComplexDecimal; | ||
} |
@@ -1,7 +0,2 @@ | ||
import { ComplexDecimal } from './complex-decimal'; | ||
import { MultiArray } from './multi-array'; | ||
/** | ||
* External reference for Evaluator. | ||
*/ | ||
export type Evaluator = any; | ||
export declare abstract class Tensor { | ||
@@ -17,14 +12,2 @@ static unaryOpFunction: { | ||
}; | ||
static functions: { | ||
[name: string]: Function; | ||
}; | ||
/** | ||
* Linearized functions | ||
*/ | ||
static linearizedFunctions: { | ||
[name: string]: { | ||
func: Function; | ||
lin: boolean[]; | ||
}; | ||
}; | ||
readonly linearize: typeof MultiArray.linearize; | ||
@@ -62,23 +45,2 @@ static copy(right: any): any; | ||
static xor(left: any, right: any): any; | ||
/** | ||
* Convert subscripts to linear indices. | ||
* @param DIMS | ||
* @param S | ||
* @returns | ||
*/ | ||
static sub2ind(DIMS: any, ...S: any): ComplexDecimal; | ||
/** | ||
* Convert linear indices to subscripts. | ||
* @param DIMS | ||
* @param IND | ||
* @returns | ||
*/ | ||
static ind2sub(DIMS: any, IND: any): any; | ||
/** | ||
* Array size. | ||
* @param M Matrix | ||
* @param DIM | ||
* @returns | ||
*/ | ||
static size(M: MultiArray, ...DIM: ComplexDecimal[] | ComplexDecimal[][]): MultiArray | ComplexDecimal; | ||
} |
{ | ||
"name": "mathjslab", | ||
"version": "1.1.15", | ||
"version": "1.1.16", | ||
"description": "MathJSLab - An interpreter with language syntax like MATLAB®/Octave. ISBN 978-65-00-82338-7", | ||
@@ -62,3 +62,3 @@ "main": "lib/mathjslab.js", | ||
"@typescript-eslint/eslint-plugin": "^6.8.0", | ||
"eslint": "^8.51.0", | ||
"eslint": "^8.52.0", | ||
"eslint-config-prettier": "^9.0.0", | ||
@@ -65,0 +65,0 @@ "eslint-plugin-import": "^2.28.1", |
@@ -70,3 +70,3 @@ /** | ||
*/ | ||
export type NodeExpr = NodeName | NodeArgExpr | NodeOperation | NodeList | NodeRange | NodeReturnList; | ||
export type NodeExpr = NodeName | NodeArgExpr | NodeOperation | NodeList | NodeRange | NodeReturnList | MultiArray | ComplexDecimal; | ||
@@ -76,3 +76,3 @@ /** | ||
*/ | ||
interface NodeReserved extends PrimaryNode { } | ||
interface NodeReserved extends PrimaryNode {} | ||
@@ -359,3 +359,3 @@ /** | ||
public readonly linearize = MultiArray.linearize; | ||
public readonly toTensor = MultiArray.number2matrix1x1; | ||
public readonly toTensor = MultiArray.numberToMatrix; | ||
@@ -409,8 +409,5 @@ private readonly unparseMLFunctions: Record<string, (tree: any) => string> = { | ||
} | ||
for (const func in Tensor.functions) { | ||
this.defFunction(func, Tensor.functions[func]); | ||
for (const func in MultiArray.linearizedFunctions) { | ||
this.DefLinearizedFunction(func, MultiArray.linearizedFunctions[func].func, MultiArray.linearizedFunctions[func].lin); | ||
} | ||
for (const func in Tensor.linearizedFunctions) { | ||
this.DefLinearizedFunction(func, Tensor.linearizedFunctions[func].func, Tensor.linearizedFunctions[func].lin); | ||
} | ||
/* Configure unparserML */ | ||
@@ -731,2 +728,9 @@ for (const func in this.unparseMLFunctions) { | ||
public reduceIfReturnList(value: any): any { | ||
if (value.type === 'RETLIST') { | ||
return value.selector(1, 0); | ||
} else { | ||
return value; | ||
} | ||
} | ||
/** | ||
@@ -871,6 +875,6 @@ * Validate left hand side of assignment node. | ||
* Expression tree recursive evaluator. | ||
* @param tree | ||
* @param local | ||
* @param fname | ||
* @returns | ||
* @param tree Expression to evaluate. | ||
* @param local Set `true` if evaluating function. | ||
* @param fname Function name. | ||
* @returns Expression tree evaluated. | ||
*/ | ||
@@ -912,8 +916,11 @@ public Evaluator(tree: any, local: boolean = false, fname: string = ''): any { | ||
case '||': | ||
return this.opTable[tree.type](this.Evaluator(tree.left, local, fname), this.Evaluator(tree.right, local, fname)); | ||
return this.opTable[tree.type]( | ||
this.reduceIfReturnList(this.Evaluator(tree.left, local, fname)), | ||
this.reduceIfReturnList(this.Evaluator(tree.right, local, fname)), | ||
); | ||
case '()': | ||
return this.Evaluator(tree.right, local, fname); | ||
return this.reduceIfReturnList(this.Evaluator(tree.right, local, fname)); | ||
case '+_': | ||
case '-_': | ||
return this.opTable[tree.type](this.Evaluator(tree.right, local, fname)); | ||
return this.opTable[tree.type](this.reduceIfReturnList(this.Evaluator(tree.right, local, fname))); | ||
case '++_': | ||
@@ -945,65 +952,106 @@ case '--_': | ||
const op: string = tree.type.substring(0, tree.type.length - 1); | ||
if (assignment.length > 1 && op.length > 0) { | ||
throw new Error('computed multiple assignment not allowed.'); | ||
if (assignment.length > 1) { | ||
if (op.length > 0) { | ||
throw new EvalError('computed multiple assignment not allowed.'); | ||
} | ||
} | ||
const { left, id, args } = assignment[0]; | ||
if (args.length === 0) { | ||
/* Name definition. */ | ||
const expr = op.length ? this.nodeOp(op, left, tree.right) : tree.right; | ||
try { | ||
this.nameTable[id] = { args: [], expr: this.Evaluator(expr) }; | ||
return this.nodeOp('=', left, this.nameTable[id].expr); | ||
} catch (error) { | ||
this.nameTable[id] = { args: [], expr: expr }; | ||
throw error; | ||
} | ||
} else { | ||
/* Function definition or indexed matrix reference. */ | ||
if (op) { | ||
if (typeof this.nameTable[id] !== 'undefined') { | ||
if (this.nameTable[id].args.length === 0) { | ||
/* Indexed matrix reference on left hand side with operator. */ | ||
console.log('###############', this.nameTable[id].args.length); | ||
let right: any; | ||
try { | ||
right = this.Evaluator(tree.right, false, fname); | ||
} catch { | ||
right = tree.right; | ||
} | ||
if (right.type !== 'RETLIST') { | ||
right = this.nodeReturnList((length: number, index: number) => { | ||
if (index === 0) { | ||
return tree.right; | ||
} else { | ||
throw new EvalError(`element number ${index + 1} undefined in return list`); | ||
} | ||
}); | ||
} | ||
const resultList = this.nodeListFirst(); | ||
for (let n = 0; n < assignment.length; n++) { | ||
const { left, id, args } = assignment[n]; | ||
if (args.length === 0) { | ||
/* Name definition. */ | ||
if (right.type !== 'RETLIST') { | ||
right = this.Evaluator(right, false, fname); | ||
} | ||
const expr = op.length ? this.nodeOp(op, left, right.selector(assignment.length, n)) : right.selector(assignment.length, n); | ||
try { | ||
this.nameTable[id] = { args: [], expr: this.reduceIfReturnList(this.Evaluator(expr)) }; | ||
this.nodeList(resultList, this.nodeOp('=', left, this.nameTable[id].expr)); | ||
continue; | ||
} catch (error) { | ||
this.nameTable[id] = { args: [], expr: expr }; | ||
throw error; | ||
} | ||
} else { | ||
/* Function definition or indexed matrix reference. */ | ||
if (op) { | ||
if (typeof this.nameTable[id] !== 'undefined') { | ||
if (this.nameTable[id].args.length === 0) { | ||
/* Indexed matrix reference on left hand side with operator. */ | ||
this.setItems( | ||
this.nameTable, | ||
id, | ||
args.map((arg: any) => this.linearize(this.reduceIfReturnList(this.Evaluator(arg)))), | ||
this.toTensor( | ||
this.reduceIfReturnList( | ||
this.Evaluator( | ||
this.nodeOp( | ||
op, | ||
this.getItems(this.nameTable[id].expr, id, args), | ||
this.toTensor(this.reduceIfReturnList(this.Evaluator(right.selector(assignment.length, n)))), | ||
), | ||
false, | ||
fname, | ||
), | ||
), | ||
), | ||
); | ||
this.nodeList(resultList, this.nodeOp('=', this.nodeName(id), this.nameTable[id].expr)); | ||
continue; | ||
} else { | ||
throw new EvalError(`in computed assignment ${id}(index) OP= X, ${id} cannot be a function.`); | ||
} | ||
} else { | ||
throw new EvalError(`in computed assignment ${id}(index) OP= X, ${id} must be defined first.`); | ||
} | ||
} else { | ||
/* Test if is a function definition (test if args is a list of undefined NAME). */ | ||
let isFunction: boolean = true; | ||
for (let i = 0; i < args.length; i++) { | ||
isFunction &&= args[i].type === 'NAME'; | ||
if (isFunction) { | ||
isFunction &&= typeof this.nameTable[args[i].id] === 'undefined'; | ||
} | ||
if (!isFunction) { | ||
break; | ||
} | ||
} | ||
if (isFunction) { | ||
this.nameTable[id] = { args: args, expr: right.selector(assignment.length, n) }; | ||
this.nodeList(resultList, tree); | ||
continue; | ||
} else { | ||
/* Indexed matrix reference on left hand side. */ | ||
this.setItems( | ||
this.nameTable, | ||
id, | ||
args.map((arg: any) => this.linearize(this.Evaluator(arg))), | ||
this.toTensor( | ||
this.Evaluator(this.nodeOp(op, this.getItems(this.nameTable[id].expr, id, args), this.toTensor(this.Evaluator(tree.right))), false, fname), | ||
), | ||
args.map((arg: any) => this.linearize(this.reduceIfReturnList(this.Evaluator(arg)))), | ||
this.toTensor(this.reduceIfReturnList(this.Evaluator(right.selector(assignment.length, n)))), | ||
); | ||
return this.nodeOp('=', this.nodeName(id), this.nameTable[id].expr); | ||
} else { | ||
throw new Error(`in assignment ${id}(index) OP= X, ${id} cannot be a function.`); | ||
this.nodeList(resultList, this.nodeOp('=', this.nodeName(id), this.nameTable[id].expr)); | ||
continue; | ||
} | ||
} else { | ||
throw new Error(`in computed assignment ${id}(index) OP= X, ${id} must be defined first.`); | ||
} | ||
} else { | ||
/* Test if is a function definition (test if args is a list of undefined NAME). */ | ||
let isFunction: boolean = true; | ||
for (let i = 0; i < args.length; i++) { | ||
isFunction &&= args[i].type === 'NAME'; | ||
if (isFunction) { | ||
isFunction &&= typeof this.nameTable[args[i].id] === 'undefined'; | ||
} | ||
if (!isFunction) { | ||
break; | ||
} | ||
} | ||
if (isFunction) { | ||
this.nameTable[id] = { args: args, expr: tree.right }; | ||
return tree; | ||
} else { | ||
/* Indexed matrix reference on left hand side. */ | ||
this.setItems( | ||
this.nameTable, | ||
id, | ||
args.map((arg: any) => this.linearize(this.Evaluator(arg))), | ||
this.toTensor(this.Evaluator(tree.right)), | ||
); | ||
return this.nodeOp('=', this.nodeName(id), this.nameTable[id].expr); | ||
} | ||
} | ||
} | ||
if (resultList.list.length === 1) { | ||
return resultList.list[0]; | ||
} else { | ||
return resultList; | ||
} | ||
case 'NAME': | ||
@@ -1017,7 +1065,9 @@ if (local && this.localTable[fname] && this.localTable[fname][tree.id]) { | ||
/* Defined as name. */ | ||
return this.Evaluator(this.nameTable[tree.id].expr); | ||
return this.reduceIfReturnList(this.Evaluator(this.nameTable[tree.id].expr)); | ||
} else { | ||
/* Defined as function name. */ | ||
throw new Error(`calling ${tree.id} function without arguments list.`); | ||
throw new EvalError(`calling ${tree.id} function without arguments list.`); | ||
} | ||
} else { | ||
throw new EvalError(`'${tree.id}' undefined.`); | ||
} | ||
@@ -1041,3 +1091,3 @@ case 'LIST': | ||
} | ||
result.list[i] = this.Evaluator(tree.list[i], local, fname); | ||
result.list[i] = this.reduceIfReturnList(this.Evaluator(tree.list[i], local, fname)); | ||
if (typeof result.list[i].type === 'number') { | ||
@@ -1050,9 +1100,9 @@ this.nameTable['ans'] = { args: [], expr: result.list[i] }; | ||
return this.expandRange( | ||
this.Evaluator(tree.start, local, fname), | ||
this.Evaluator(tree.stop, local, fname), | ||
tree.stride ? this.Evaluator(tree.stride, local, fname) : null, | ||
this.reduceIfReturnList(this.Evaluator(tree.start, local, fname)), | ||
this.reduceIfReturnList(this.Evaluator(tree.stop, local, fname)), | ||
tree.stride ? this.reduceIfReturnList(this.Evaluator(tree.stride, local, fname)) : null, | ||
); | ||
case 'ARG': | ||
if (typeof tree.expr === 'undefined') { | ||
throw new Error(`'${tree.id}' undefined.`); | ||
throw new EvalError(`'${tree.id}' undefined.`); | ||
} | ||
@@ -1066,6 +1116,6 @@ if (tree.expr.type === 'NAME') { | ||
/* Arguments evaluated. */ | ||
const argumentsList = tree.args.map((arg: any) => this.Evaluator(arg, local, fname)); | ||
const argumentsList = tree.args.map((arg: any) => this.reduceIfReturnList(this.Evaluator(arg, local, fname))); | ||
if (this.baseFunctionTable[aliasTreeName].mapper && argumentsList.length !== 1) { | ||
/* Error if mapper and #arguments!==1 (Invalid call). */ | ||
throw new Error(`Invalid call to ${aliasTreeName}.`); | ||
throw new EvalError(`Invalid call to ${aliasTreeName}.`); | ||
} | ||
@@ -1081,3 +1131,5 @@ if (argumentsList.length === 1 && 'array' in argumentsList[0] && this.baseFunctionTable[aliasTreeName].mapper) { | ||
return this.baseFunctionTable[aliasTreeName].func( | ||
...tree.args.map((arg: any, i: number) => (this.baseFunctionTable[aliasTreeName].ev[i] ? this.Evaluator(arg, local, fname) : arg)), | ||
...tree.args.map((arg: any, i: number) => | ||
this.baseFunctionTable[aliasTreeName].ev[i] ? this.reduceIfReturnList(this.Evaluator(arg, local, fname)) : arg, | ||
), | ||
); | ||
@@ -1092,3 +1144,3 @@ } | ||
/* If is a defined name. */ | ||
const temp = this.Evaluator(this.nameTable[tree.expr.id].expr); | ||
const temp = this.reduceIfReturnList(this.Evaluator(this.nameTable[tree.expr.id].expr)); | ||
if (tree.args.length === 0) { | ||
@@ -1102,6 +1154,6 @@ /* Defined name. */ | ||
tree.expr.id, | ||
tree.args.map((arg: any) => this.Evaluator(arg, local, fname)), | ||
tree.args.map((arg: any) => this.reduceIfReturnList(this.Evaluator(arg, local, fname))), | ||
); | ||
} else { | ||
throw new Error('invalid matrix indexing or function arguments.'); | ||
throw new EvalError('invalid matrix indexing or function arguments.'); | ||
} | ||
@@ -1111,3 +1163,3 @@ } else { | ||
if (this.nameTable[tree.expr.id].args.length !== tree.args.length) { | ||
throw new Error(`invalid number of arguments in function ${tree.expr.id}.`); | ||
throw new EvalError(`invalid number of arguments in function ${tree.expr.id}.`); | ||
} | ||
@@ -1118,5 +1170,5 @@ /* Create localTable entry. */ | ||
/* Evaluate defined function arguments list. */ | ||
this.localTable[tree.expr.id][this.nameTable[tree.expr.id].args[i].id] = this.Evaluator(tree.args[i], true, fname); | ||
this.localTable[tree.expr.id][this.nameTable[tree.expr.id].args[i].id] = this.reduceIfReturnList(this.Evaluator(tree.args[i], true, fname)); | ||
} | ||
const temp = this.Evaluator(this.nameTable[tree.expr.id].expr, true, tree.expr.id); | ||
const temp = this.reduceIfReturnList(this.Evaluator(this.nameTable[tree.expr.id].expr, true, tree.expr.id)); | ||
/* Delete localTable entry. */ | ||
@@ -1127,3 +1179,3 @@ delete this.localTable[tree.expr.id]; | ||
} else { | ||
throw new Error(`'${tree.expr.id}' undefined.`); | ||
throw new EvalError(`'${tree.expr.id}' undefined.`); | ||
} | ||
@@ -1135,7 +1187,5 @@ } else { | ||
this.Unparse(tree.expr), | ||
tree.args.map((arg: any) => this.Evaluator(arg, local, fname)), | ||
tree.args.map((arg: any) => this.reduceIfReturnList(this.Evaluator(arg, local, fname))), | ||
); | ||
} | ||
case 'RETLIST': | ||
return this.Evaluator(tree.selector(1, 1), local, fname); | ||
case 'CmdWList': | ||
@@ -1146,3 +1196,3 @@ this.commandWordListTable[tree.id].func(...tree.args.map((word: { str: string }) => word.str)); | ||
default: | ||
throw new Error(`evaluating undefined type '${tree.type}'.`); | ||
throw new EvalError(`evaluating undefined type '${tree.type}'.`); | ||
} | ||
@@ -1176,4 +1226,3 @@ } | ||
return '<UNDEFINED>'; | ||
} | ||
if (this.isNumber(tree)) { | ||
} else if (this.isNumber(tree)) { | ||
/* NUMBER */ | ||
@@ -1268,2 +1317,4 @@ return this.unparseNumber(tree); | ||
return this.Unparse(tree.expr) + '(' + tree.args.map((value: any) => this.Unparse(value)).join(',') + ')'; | ||
case 'RETLIST': | ||
return '<RETLIST>'; | ||
case 'CmdWList': | ||
@@ -1289,4 +1340,3 @@ return tree.id + ' ' + tree.args.map((arg: any) => this.Unparse(arg)).join(' '); | ||
return '<mi>undefined</mi>'; | ||
} | ||
if (this.isNumber(tree)) { | ||
} else if (this.isNumber(tree)) { | ||
/* NUMBER */ | ||
@@ -1403,2 +1453,4 @@ return this.unparseNumberML(tree); | ||
} | ||
case 'RETLIST': | ||
return '<mi>RETLIST</mi>'; | ||
case 'CmdWList': | ||
@@ -1405,0 +1457,0 @@ return '<mtext>' + tree.id + ' ' + tree.args.map((arg: any) => this.unparserML(arg)).join(' ') + '</mtext>'; |
import { ComplexDecimal } from './complex-decimal'; | ||
import { MultiArray } from './multi-array'; | ||
/** | ||
* External reference for Evaluator. | ||
*/ | ||
export type Evaluator = any; | ||
declare let EvaluatorPointer: Evaluator; | ||
export abstract class Tensor { | ||
@@ -45,17 +39,2 @@ public static unaryOpFunction: { [name: string]: Function } = { | ||
public static functions: { [name: string]: Function } = { | ||
sub2ind: Tensor.sub2ind, | ||
ind2sub: Tensor.ind2sub, | ||
}; | ||
/** | ||
* Linearized functions | ||
*/ | ||
public static linearizedFunctions: { [name: string]: { func: Function; lin: boolean[] } } = { | ||
size: { | ||
func: Tensor.size, | ||
lin: [false, true], | ||
}, | ||
}; | ||
public readonly linearize = MultiArray.linearize; | ||
@@ -254,120 +233,2 @@ | ||
} | ||
/** | ||
* Convert subscripts to linear indices. | ||
* @param DIMS | ||
* @param S | ||
* @returns | ||
*/ | ||
public static sub2ind(DIMS: any, ...S: any) { | ||
if (arguments.length > 1) { | ||
const n = DIMS; | ||
return new ComplexDecimal(1, 0); | ||
} else { | ||
throw new Error(`Invalid call to sub2ind.`); | ||
} | ||
} | ||
/** | ||
* Convert linear indices to subscripts. | ||
* @param DIMS | ||
* @param IND | ||
* @returns | ||
*/ | ||
public static ind2sub(DIMS: any, IND: any): any { | ||
if (arguments.length === 2) { | ||
return EvaluatorPointer.nodeReturnList((length: number, index: number): any => { | ||
const dims = DIMS; | ||
const ind = IND; | ||
if (length === 1) { | ||
return ind; | ||
} else { | ||
return ind; | ||
} | ||
}); | ||
} else { | ||
throw new Error(`Invalid call to ind2sub.`); | ||
} | ||
} | ||
/** | ||
* Array size. | ||
* @param M Matrix | ||
* @param DIM | ||
* @returns | ||
*/ | ||
public static size(M: MultiArray, ...DIM: ComplexDecimal[] | ComplexDecimal[][]): MultiArray | ComplexDecimal { | ||
const testDimension = (dimension: ComplexDecimal): number => { | ||
const dim = dimension.re.toNumber(); | ||
if (dim < 1 || !dimension.re.trunc().eq(dimension.re)) { | ||
throw new Error(`size: requested dimension DIM (= ${Math.trunc(dimension.re.toNumber())}) out of range. DIM must be a positive integer.`); | ||
} | ||
return dim; | ||
}; | ||
if (DIM.length === 0) { | ||
if ('re' in M) { | ||
const result = new MultiArray([1, 2]); | ||
result.array = [[ComplexDecimal.one(), ComplexDecimal.one()]]; | ||
result.type = ComplexDecimal.numberClass.real; | ||
return result; | ||
} else { | ||
const result = new MultiArray([1, 2]); | ||
result.array = [[new ComplexDecimal(M.dim[0]), new ComplexDecimal(M.dim[1])]]; | ||
result.type = ComplexDecimal.numberClass.real; | ||
return result; | ||
} | ||
} else { | ||
if (DIM.length === 1) { | ||
if ('re' in M) { | ||
return ComplexDecimal.one(); | ||
} else { | ||
if ('re' in DIM[0]) { | ||
const dim = testDimension(DIM[0]); | ||
if (dim > M.dim.length) { | ||
return ComplexDecimal.one(); | ||
} else { | ||
return new ComplexDecimal(M.dim[dim - 1]); | ||
} | ||
} else { | ||
const result = new MultiArray([1, DIM[0].length]); | ||
result.array = [[]]; | ||
DIM[0].forEach((dimension) => { | ||
const dim = testDimension(dimension); | ||
if (dim > M.dim.length) { | ||
result.array[0].push(ComplexDecimal.one()); | ||
} else { | ||
result.array[0].push(new ComplexDecimal(M.dim[dim - 1])); | ||
} | ||
}); | ||
result.type = ComplexDecimal.numberClass.real; | ||
return result; | ||
} | ||
} | ||
} else { | ||
if ('re' in M) { | ||
const result = new MultiArray([1, DIM.length]); | ||
result.array = [[]]; | ||
(DIM as ComplexDecimal[]).forEach((dimension) => { | ||
testDimension(dimension); | ||
result.array[0].push(ComplexDecimal.one()); | ||
}); | ||
result.type = ComplexDecimal.numberClass.real; | ||
return result; | ||
} else { | ||
const result = new MultiArray([1, DIM.length]); | ||
result.array = [[]]; | ||
DIM.forEach((dimension) => { | ||
const dim = testDimension(dimension as ComplexDecimal); | ||
if (dim > M.dim.length) { | ||
result.array[0].push(ComplexDecimal.one()); | ||
} else { | ||
result.array[0].push(new ComplexDecimal(M.dim[dim - 1])); | ||
} | ||
}); | ||
result.type = ComplexDecimal.numberClass.real; | ||
return result; | ||
} | ||
} | ||
} | ||
} | ||
} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
455360
6951