定義一個以另一個函數作為參數的函數你好
我試圖定義一個函數來計算假設另一個函數的區域中的線性的誤差。
我的函數必須執行以下操作:
- 接受 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));
--------------------------------------------------------------------------------