-
So, I'm building a simple sigmaSum function that I'm importing via and the function works perfectly fine. e.g.:
Now the problem is, because it's a custom function and I have to use quotes for the arguments, I can't actually pass variables. e.g.: this does not work:
because I could live with const sigmaSum = function(n, k, expr){
const [n_Symbol, n_Value] = parseVar(n);
const [k_Symbol, k_Value] = parseVar(k);
let result = 0;
for (let i = n_Value; i <= k_Value; i++){
result += mathjs.evaluate(expr.replaceAll(n_Symbol, i).replaceAll(k_Symbol, k_Value))
}
return result;
};
mathjs.import({
sigmaSum,
}); any help would be appreciated :) |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 14 replies
-
Hi, here are a few pointers To access variables outside To be able to use Your function definition might be more usable if you don't assign it to a constant: Instead of const sigmaSum = function(n, k, expr){
} Try function sigmaSum(n, k, expr){
// this way you could call the function in lines before its definition
} You could remove the for loop by using Maybe use a helper function that always receives the arguments in the exact format. function summation(i0, n, f) {
const I = math.range(i0, n, true)
return math.sum(I.map(i => f(i, n)))
}
console.log(summation(1, 5, (n, k) => n ** 2 + k)) // 80
console.log(summation(1, 5, math.evaluate("f(n, k) = n^2 + k"))) // 80 |
Beta Was this translation helpful? Give feedback.
-
@NullDev you can use the Docs: https://mathjs.org/docs/expressions/customization.html#custom-argument-parsing Here a full example: import { create, all } from 'mathjs'
const mathjs = create(all)
function sigmaSum (args, math, scope){
const [nNode, kNode, exprNode] = args
if (!nNode.isAssignmentNode || !nNode.object.isSymbolNode) {
throw Error('First argument must define a variable, like "i=1"')
}
const nName = nNode.object.name
if (!kNode.isAssignmentNode || !kNode.object.isSymbolNode) {
throw Error('Second argument must define a variable, like "k=5"')
}
const kName = kNode.object.name
const n = nNode.compile().evaluate(scope);
const k = kNode.compile().evaluate(scope);
const expr = exprNode.compile()
let result = 0;
for (let i = n; i <= k; i++) {
const newScope = new Map()
scope.forEach((value, key) => newScope.set(key, value))
newScope.set(nName, i)
newScope.set(kName, k)
result += expr.evaluate(newScope)
}
return result;
}
sigmaSum.rawArgs = true
mathjs.import({
sigmaSum,
});
// Usage
const result1 = mathjs.evaluate('sigmaSum(n=1, k=5, n^2 + k)')
console.log('result1:', result1) // 80
const scope2 = new Map()
mathjs.evaluate('f(n) = sigmaSum(i=1, k=n-1, floor(1 / gcd(i, k)))', scope2)
const result2 = mathjs.evaluate('f(15)', scope2)
console.log('result2:', result2) // 6
const scope3 = new Map()
mathjs.evaluate('f(x) = sigmaSum(n=1, k=5, sigmaSum(a=1, b=5, x + a))', scope3)
const result3 = mathjs.evaluate('f(10)', scope3)
console.log('result3:', result3) EDIT: added copying the all existing scope variables before passing them to |
Beta Was this translation helpful? Give feedback.
@NullDev you can use the
rawArgs
feature, then you can usesigmaSum(n=1, k=5, n^2 + k)
andf(n) = sigmaSum(i=1, k=n-1, floor(1 / gcd(i, k))); f(15)
just like you want.Docs: https://mathjs.org/docs/expressions/customization.html#custom-argument-parsing
Here a full example: