定义一个以另一个函数作为参数的函数你好
我试图定义一个函数来计算假设另一个函数的区域中的线性的误差。
我的函数必须执行以下操作:
- 接受 3 个输入:非线性函数(最好只是在其他地方定义的函数名称 f(x))、区域中心 (xi) 和所研究区域的半宽 (delta)。
- 生成 xi、Lin(x) 中渐近线线性函数的斜率和截距。
- 根据定义生成误差函数 err(x) = Lin(x) - f(x), err(xi) = 0。
- 对从 xi-delta 到 xi+delta 的 err(x) 进行积分,然后除以 2*delta,即可找到该区域的平均误差。
- 使用平均误差计算区域内误差的标准差(也涉及积分)
在尝试做到这一点时,我遇到了三个问题:
- 如何让 jsl 中的 Function-function 接受另一个函数作为输入?
- 如何获得导数函数来区分由函数名称提供的函数参数,例如 Derivative(f(x),x)?
- 如何让jsl集成某个区域的功能? 我找不到内置函数来执行此操作。
我希望有人能帮忙。
回复:定义一个以另一个函数作为参数的函数仅供关注此帖子的人参考。 JMP 支持提供了另一种方法来从已定义的函数中获取表达式。 它是 Capture Log( Show(func) ) 的替代方案;
funcExpr = Parse( "Expr(" || Char( Name Expr( func ) ) || ")" );
innerf = Arg( Arg( funcExpr, 1 ), 2 );
回复:定义一个以另一个函数作为参数的函数我认为您的建议对我很有帮助。
与此同时,我改变了我想要这个函数做什么的想法。
但这是我到目前为止得到的:
expression = Expr( x ^ 2 );
LinearityError = Function( {expression, location, sigma, sigmaRange = 3},
locationY = Eval( Substitute( Name Expr( expression ), Expr( x ), location ) );
SlopeFunc = Derivative( Name Expr( expression ), x );
Slope = Eval( Substitute( Name Expr( SlopeFunc ), Expr( x ), location ) );
Intercept = locationY - Slope * location;
LinExpr = Parse( Eval Insert( "^Slope^*x + ^Intercept^" ) );
errExpr = Substitute( Expr( (a) - (b) ), Expr( a ), Name Expr( LinExpr ), Expr( b ), Name Expr( expression ) );
errExpr = Simplify Expr( Name Expr( errExpr ) );
lowerLimit = location - sigma * sigmaRange;
upperLimit = location + sigma * sigmaRange;
errMean = Integrate( errExpr, x, lowerLimit, upperLimit ) / (2 * sigma * sigmaRange);
errErrSquaredExpr = Substitute( Expr( ((a) - (b))^2 ), Expr( a ), Name Expr( errExpr ), Expr( b ), errMean );
errErrSquaredExpr = Simplify Expr( Name Expr( errErrSquaredExpr ) );
errStdDev = Sqrt(Integrate( errErrSquaredExpr, x, lowerLimit, upperLimit ) / (2 * sigma * sigmaRange));
Return(errStdDev);
);我将表达式作为参数而不是函数,但您为此提供了解决方案。 只是还没有实施而已。
保护你!
回复:定义一个以另一个函数作为参数的函数仅供参考博主的注释
JMP 14 有一个名为“自定义函数”的新对象,其中包含有用的消息。 我已请求获取 Expr 消息作为增强功能。 我认为它不适用于您的请求,但是,获取该函数会更容易: func << Get Function,而不是 LogCapture(show(func)) 等的 2 个步骤......
回复:定义一个以另一个函数作为参数的函数杰斯珀,
我知道您想要找到 Derivative( f(x), x),但是,JMP 符号导数函数要求第一个参数是表达式。如果您解释一下您希望它如何工作,可能会更容易为您提供帮助。 我希望您想要构建自己的具有 3 个参数的函数或应用程序,并且您提到了 f(x),但是f(x) 在哪里以及如何被读入或定义?
JMP 表达式和函数尝试立即求值。将下一个代码块复制到脚本窗口中,右键单击以显示嵌入的日志,然后突出显示并运行代码段并查看日志中的结果。 这就是 JMP 函数和表达式的工作方式。
Names Default to Here(1);
func = Function({x}, x^2);
xp = Expr(x^2);
show(func, func(x)); //will get an error func(x/*###*/) since there is no such symbol, x
//----run to here---
show(xp); // xp=x^2 JMP does not evaluate an expression within when it is a Show() function argument
//----run to here---
x= Empty();
show(func, func(x), xp, Eval(xp) ); //func(x) = .; since x is empty, then any calculation involving x is empty
//----run to here---
x=2;
show(func, func(x), xp, Eval(xp)); //func(x) = 4; since x = 2.
//----run to here---
Show(Derivative(xp,x), Derivative(NameExpr(xp),x) )
//----run to here---
//: JMP tries to evaluate func(x), and Derivative(xp,x) evaluates xp unless you specify NameExpr(xp)
因此,我知道使用内置 Derivative() 函数的唯一方法是将第一个参数设为表达式。
你的问题确实提出了一个有趣的问题, JSL如何提取表达式参数(最后一个参数)已定义的用户函数。也许其他专家博主有更好的解决方案。 或者,这可能是一个愿望清单项,JMP 的未来版本提供了从用户定义的函数中提取表达式的函数或消息。
下一个代码块显示了从用户定义的函数中提取表达式的方法。
因此,让博客知道该函数是如何读入(创建)的,也许您会得到一个更令人满意的解决方案。 例如,如果您的应用程序提示用户在文本框中输入某个功能,则处理文本会更简单。
func = Function({x},x^2);<BR />
//assumes a function has been defined
tfxp=Parse(Word( 2, Trim(LogCapture(show(func))), "=") );<BR />//show(func) writes the function definition to the Log<BR />//Log Capture() captures that as a string<BR />//the Word() function above gets the right hand side of the equal sign<BR />//Parse turns it into an expression<BR />
fxp = argExpr(tfxp, nargExpr(tfxp) );
//this extracts the last argument of Function()<BR />
show(Derivative(nameExpr(fxp),x));
//______________________________________________________________
//instead of creating a function and doing all the steps to extract the expression
//create the function from an expression
//---create expression
myxp = Expr(3*x^3 -17*x + 12 );
//---this is a template, an expression that will assign func to the expression
myfunc = Expr(func= Function({x}, _xp));
//---create the function
//this substitutes the expression and evaluates
//once it is run, func=Function({x}, 3*x^3 -17*x +12 ) has been defined
Eval(Substitute(NameExpr(myfunc), Expr(_xp), NameExpr(myxp)) );
//this verifies
show(func, myxp, func(2), Derivative(NameExpr(myxp), x));
回复:定义一个以另一个函数作为参数的函数哦,我使用 JMP 14
回复:定义一个以另一个函数作为参数的函数感谢你的回复。
积分功能解决了我的问题之一。
也许我不理解你代码中的所有内容,但我仍然无法让 jsl 给我命名函数的导数。 换句话说,我想要代码中的 der1=der2 :
func = Function({x},x^2);
der1 = Derivative(x^2,x);
der2 = Derivative(func(x),x);必须有某种方法来实现这一目标。
此外,您的代码还为 Jesper 函数提供了表达,不是函数姓名到 Jesper 函数。 我该怎么做呢? 理想情况下,Jesper 函数应该接受两者,即 Jesper(x^2) = Jesper(func(x))
回复:定义一个以另一个函数作为参数的函数杰斯珀,
您没有提及您使用的 JMP 版本。 JMP 12 及更高版本同时具有Integrated() 和符号导数() 函数。
附上一个例子。 它不创建渐近线性公式,而只是简单的线性。 但该脚本的目标是演示语法。要引用符号公式,它们必须是表达式。在 tehscripting Index 中,您应该查找:
- Substitute()、NameExpr、EvalInsert()、Parse()、Simplify() 和
- 当然是积分()、导数()。 注意积分函数使用空(点)来指定无穷大。
测试用例的结果被写入日志窗口,并显示在第二个代码窗口中。
您应该发布您的最终版本。 它看起来是一个很酷的功能。
Names Default to Here(1);
//I think you meant you wanted a formula.
//The Jesper Function just finds the linear function, not the asymptotic linear function ... this code is a syntax example.
funList = {2*x+3, 2^x + 3, 2*sqrt(x)+1.2}; //test case for 3 formulas for x1=1 and x2=2, i.e. cntr=1.5, delta=0.5
Jesper = Function({form_xp, cntr, delta}, {x1, x2, y1, y2, m, b, err_xp, err, deriv },
x1 = cntr - delta;
x2 = cntr + delta;
y1 = Eval( Substitute(NameExpr(form_xp), Expr(x), x1 ));
y2 = Eval( Substitute(NameExpr(form_xp), Expr(x), x2 ));
m = (y2-y1)/(x2-x1) ;
b = y2 - m*x2;
lin_xp = Parse( EvalInsert( "^m^*x + ^b^"));
err_xp = Substitute(Expr((a)-(b)), Expr(a), NameExpr(form_xp), Expr(b), NameExpr(lin_xp) );
err_xp = SimplifyExpr(NameExpr(err_xp));
err = 1/(2*delta) * Eval ( Substitute( NameExpr(Integrate(_xp, x, _lo, _hi)), Expr(_xp), NameExpr(err_xp), Expr(_lo), x1, Expr(_hi), x2) );
deriv = Derivative(NameExpr(form_xp), x);
Eval List({err, NameExpr(form_xp), NameExpr(lin_xp), NameExpr(err_xp), NameExpr(deriv)});
);
for(i=1 ,i<=nitems(funlist), i++,
{err, func_xp, line_xp, err_xp, deriv_xp} =Jesper(funlist[i], 1.5, .5);
show(i, err, func_xp, line_xp, err_xp, deriv_xp);
write("\!N" ||Repeat("-", 80) );
);这 3 个公式的结果是
/*:
i = 1;
err = 0;
func_xp = 2 * x + 3;
line_xp = 2 * x + 3;
err_xp = 0;
deriv_xp = 2;
--------------------------------------------------------------------------------
i = 2;
err = -0.114609918222073;
func_xp = 2 ^ x + 3;
line_xp = 2 * x + 3;
err_xp = -2 * x + 2 ^ x;
deriv_xp = 2 ^ x * Log(2);
--------------------------------------------------------------------------------
i = 3;
err = 0.0236892706214399;
func_xp = 2 * Sqrt(x) + 1.2;
line_xp = 0.82842712474619 * x + 2.37157287525381;
err_xp = (-1.17157287525381) + -0.82842712474619 * x + 2 * Sqrt(x);
deriv_xp = 2 * (0.5 / Sqrt(x));
--------------------------------------------------------------------------------