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
455360
6951