Definire una funzione che accetta un'altra funzione come argomentoCIAO
Sto cercando di definire una funzione che calcola l'errore di assumere linearità in una regione di un'altra funzione.
La mia funzione deve fare quanto segue:
- Accetta 3 input, la funzione non lineare (preferibilmente solo un nome di funzione definito altrove, f(x)), il centro della regione (xi) e la metà della regione in esame (delta).
- Genera pendenza e intercetta della funzione lineare asintotica in xi, Lin(x).
- Genera una funzione di errore err(x) = Lin(x) - f(x), err(xi) = 0 per definizione.
- Integra err(x), da xi-delta a xi+delta, e dividi per 2*delta, per trovare l'errore medio nella regione.
- Utilizzare l'errore medio per calcolare la deviazione standard dell'errore nella regione (comprende anche l'integrazione)
Nel provare a farlo mi imbatto in tre problemi:
- Come posso ottenere la funzione Function in jsl per accettare un'altra funzione come input?
- Come posso ottenere la funzione derivata per differenziare un argomento di funzione, fornito dal nome della funzione, ad esempio Derivative(f(x),x)?
- Come posso ottenere jsl per integrare una funzione in una determinata regione? Non riesco a trovare una funzione integrata per farlo.
Spero che qualcuno possa aiutare.
Re: Definizione di una funzione che accetta un'altra funzione come argomentoSolo un FYI a chiunque stesse seguendo questo post. Il supporto JMP ha fornito metodi alternativi per ottenere l'espressione da una funzione già definita. È un'alternativa a Capture Log( Show(func) );
funcExpr = Parse( "Expr(" || Char( Name Expr( func ) ) || ")" );
innerf = Arg( Arg( funcExpr, 1 ), 2 );
Re: Definizione di una funzione che accetta un'altra funzione come argomentoPenso che i tuoi suggerimenti mi abbiano aiutato lungo la strada.
Nel frattempo ho cambiato idea su cosa voglio che faccia la funzione.
Ma ecco cosa ho ottenuto finora:
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);
);Prendo un'espressione come argomento anziché una funzione, ma tu hai fornito una soluzione per questo. Semplicemente non è ancora implementato.
Grazie!
Re: Definizione di una funzione che accetta un'altra funzione come argomentoNota del blogger FYI
JMP 14 ha un nuovo oggetto chiamato Funzione personalizzata, con messaggi utili. Ho richiesto un messaggio Get Expr come miglioramento. Non penso che si applichi alla tua richiesta, tuttavia, sarebbe più facile ottenere la funzione: func << Ottieni funzione, invece dei 2 passaggi con LogCapture(show(func)) ecc....
Re: Definizione di una funzione che accetta un'altra funzione come argomentoJesper,
So che vorresti trovare Derivative( f(x), x), tuttavia, la funzione simbolica Derivative di JMP richiede che il primo argomento sia un'espressione.Potrebbe essere più facile aiutarti, se spieghi come vuoi che funzioni. Mi aspetto che tu voglia creare la tua funzione o applicazione con 3 argomenti e hai menzionato f(x), ma dove e come viene letto o definito f(x)?
Le espressioni e le funzioni di JMP cercano di valutare immediatamente.Copia il prossimo blocco di codice in una finestra di script, fai clic con il pulsante destro del mouse per visualizzare il registro incorporato, quindi evidenzia ed esegui i segmenti di codice e osserva i risultati nel registro. Questo è il modo in cui funzionano le funzioni e le espressioni di 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)
Quindi l'unico metodo che conosco per usare la funzione incorporata Derivative() è trasformare il primo argomento in un'espressione.
La tua domanda ha sollevato una domanda interessante, come può JSL estrarre l'argomento dell'espressione (l'ultimo argomento) di una funzione utente già definita.Forse altri blogger esperti hanno una soluzione migliore. O forse questo è un elemento della lista dei desideri, che una versione futura di JMP fornisce una funzione o un messaggio che estrae l'espressione da una funzione definita dall'utente.
Il prossimo blocco di codice mostra un metodo per estrarre l'espressione da una funzione definita dall'utente.
Quindi, fai sapere al blog come viene letta (creata) la funzione e forse otterrai una soluzione più appetibile. Ad esempio, se l'applicazione richiede all'utente una funzione in una casella di testo, lavorare con il testo può essere più semplice.
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));
Re: Definizione di una funzione che accetta un'altra funzione come argomentoOh, e io uso JMP 14
Re: Definizione di una funzione che accetta un'altra funzione come argomentoGrazie per la risposta.
La funzione Integra ha risolto uno dei miei problemi.
Forse non capisco tutto nel tuo codice, ma non riesco ancora a convincere jsl a darmi la derivata di una funzione denominata. In altre parole, voglio der1=der2 nel codice:
func = Function({x},x^2);
der1 = Derivative(x^2,x);
der2 = Derivative(func(x),x);Ci deve essere un modo per raggiungere questo obiettivo.
Inoltre, il tuo codice alimenta la funzione Jesper an espressione , non la funzione nome alla funzione di Jesper. Come faccio a fare questo? Idealmente la funzione Jesper dovrebbe accettare entrambi, cioè Jesper(x^2) = Jesper(func(x))
Re: Definizione di una funzione che accetta un'altra funzione come argomentoJesper,
Non hai menzionato quale versione di JMP stai utilizzando. JMP 12 e versioni successive hanno entrambe le funzioni integrate() e simbolica derivata().
In allegato un esempio. Non crea il formale lineare asintotico solo un semplice lineare. Ma l'obiettivo di questo script è dimostrare la sintassi.Per fare riferimento a formule simboliche, devono essere espressioni.Nell'indice di scripting, dovresti cercare:
- Substitute(), NameExpr, EvalInsert(), Parse(), Simplify() e
- ovviamente, Integrate(), Derivative(). Nota per la funzione di integrazione utilizzare un vuoto (punto) per specificare l'infinito.
I risultati dei test case vengono scritti nella finestra Log e mostrati nella seconda finestra del codice.
Dovresti postare la tua versione finale. Sembra una funzione interessante.
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) );
);I risultati di queste 3 formule sono
/*:
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));
--------------------------------------------------------------------------------