Definición de una función que toma otra función como argumentoHola
Estoy tratando de definir una función que calcule el error de asumir linealidad en una región de otra función.
Mi función debe hacer lo siguiente:
- Acepte 3 entradas, la función no lineal (preferiblemente solo un nombre de función definido en otro lugar, f(x)), el centro de la región (xi) y la mitad del ancho de la región que se está investigando (delta).
- Genere la pendiente y el intercepto de la función lineal asíntota en xi, Lin(x).
- Genere una función de error err(x) = Lin(x) - f(x), err(xi) = 0 por definición.
- Integre err(x), de xi-delta a xi+delta, y divida por 2*delta, para encontrar el error medio en la región.
- Use el error medio para calcular la desviación estándar del error en la región (también implica integración)
Al tratar de hacer esto me encuentro con tres problemas:
- ¿Cómo obtengo la función Función en jsl para aceptar otra función como entrada?
- ¿Cómo obtengo la función Derivada para diferenciar un argumento de función, proporcionado por el nombre de la función, por ejemplo, Derivada (f (x), x)?
- ¿Cómo consigo que jsl integre una función en cierta región? No puedo encontrar una función incorporada para hacer esto.
Espero que algunos puedan ayudar.
Re: Definir una función que toma otra función como argumentoSolo un FYI para quien estaba siguiendo esta publicación. JMP Support proporcionó métodos alternativos para obtener la expresión de una función ya definida. Es una alternativa a Capture Log( Show(func) );
funcExpr = Parse( "Expr(" || Char( Name Expr( func ) ) || ")" );
innerf = Arg( Arg( funcExpr, 1 ), 2 );
Re: Definir una función que toma otra función como argumentoCreo que sus sugerencias me ayudaron en el camino.
Mientras tanto, cambié de opinión sobre lo que quiero que haga la función.
Pero esto es lo que tengo hasta ahora:
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);
);Tomo una expresión como argumento en lugar de una función, pero proporcionó una solución para eso. Simplemente no está implementado todavía.
¡Gracias!
Re: Definir una función que toma otra función como argumentoNota del blogger FYI
JMP 14 tiene un nuevo objeto llamado Custom Function, con mensajes útiles. He solicitado un mensaje Get Expr como mejora. No creo que se aplique a su solicitud, sin embargo, sería más fácil obtener la función: func << Get Function, en lugar de los 2 pasos con LogCapture(show(func)) etc....
Re: Definir una función que toma otra función como argumentoJesper,
Sé que le gustaría encontrar Derivada (f (x), x), sin embargo, la función Derivada simbólica JMP requiere que el primer argumento sea una expresión.Puede ser más fácil ayudarte si explicas cómo quieres que funcione. Espero que quieras construir tu propia función o aplicación que tenga 3 argumentos y mencionaste f(x), pero ¿Dónde y cómo se lee o define f(x)?
Las expresiones y funciones JMP intentan evaluarse inmediatamente.Copie este siguiente bloque de código en una ventana de secuencia de comandos, haga clic con el botón derecho para mostrar el registro incrustado, luego resalte y ejecute los segmentos de código y observe los resultados en el registro. Esta es la forma en que funcionan las funciones y expresiones 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)
Entonces, el único método que conozco para usar la función Derivada() incorporada es hacer que el primer argumento sea una expresión.
Su pregunta planteó una pregunta interesante, ¿Cómo puede JSL extraer el argumento de la expresión? (el último argumento) de una función de usuario ya definida.Tal vez otros bloggers expertos tengan una solución mejor. O tal vez este sea un elemento de la lista de deseos, que una versión futura de JMP proporcione una función o mensaje que extraiga la expresión de una función definida por el usuario.
El siguiente bloque de código muestra un método para extraer la expresión de una función definida por el usuario.
Por lo tanto, infórmele al blog cómo se está leyendo (creando) la función y tal vez obtenga una solución más aceptable. Por ejemplo, si su aplicación solicita al usuario una función en un cuadro de texto, trabajar con texto puede ser más simple.
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: Definir una función que toma otra función como argumentoAh, y uso JMP 14
Re: Definir una función que toma otra función como argumentoGracias por su respuesta.
La función Integrar resolvió uno de mis problemas.
Tal vez no entiendo todo en su código, pero aún no puedo obtener jsl para darme la derivada de una función con nombre. En otras palabras, quiero der1=der2 en el código:
func = Function({x},x^2);
der1 = Derivative(x^2,x);
der2 = Derivative(func(x),x);Debe haber alguna manera de lograr esto.
Además, su código alimenta la función Jesper un expresión , no la función nombre a la función de Jesper. ¿Cómo hago esto? Idealmente, la función Jesper debería aceptar ambos, es decir, Jesper (x ^ 2) = Jesper (func (x))
Re: Definir una función que toma otra función como argumentoJesper,
No mencionó qué versión de JMP está utilizando. JMP 12 y versiones posteriores tienen funciones tanto de integración() como de derivada simbólica().
Adjunto un ejemplo. No crea la forma lineal asintótica, solo una lineal simple. Pero el objetivo de este script es demostrar la sintaxis.Para hacer referencia a fórmulas simbólicas, deben ser expresiones.En tehscripting Index, deberías buscar:
- Substitute(), NameExpr, EvalInsert(), Parse(), Simplify() y
- por supuesto, Integrar(), Derivar(). Tenga en cuenta que para la función de integración use un (punto) vacío para especificar el infinito.
Los resultados de los casos de prueba se escriben en la ventana de registro y se muestran en la segunda ventana de código.
Deberías publicar tu versión final. Parece una función genial.
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) );
);Los resultados de estas 3 fórmulas son
/*:
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));
--------------------------------------------------------------------------------