I want to define a function of a function ( maybe functional) in Maxima. For example, I want to define T in the code:
f(r,GN,M)::=(2*GN*M^2)*(2*GN*M/r-(2*GN*M/(2*r))^2);
X(r,GN,M) ::= 2*GN*M/(2*r)+2*GN*M/r*(1-2*GN*M/(4*r));
T(r,GN,M) ::= diff(f(r,GN,M),r)+X(r,GN,M);
But I don't know the code.
In maxima it is convenient to use expressions.
Define two expressions
(%i1) display2d: false $
(%i2) f: (2*GN*M^2)*(2*GN*M/r-(2*GN*M/(2*r))^2) $
(%i3) X: 2*GN*M/(2*r)+2*GN*M/r*(1-2*GN*M/(4*r)) $
Define a function which operates on two expressions
(%i4) T(f, X) := diff(f, r) + X $
Call it. Result is an expression
(%i5) dfpX: T(f, X);
(%o5) (2*GN*M*(1-(GN*M)/(2*r)))/r+(GN*M)/r+2*GN*M^2
*((2*GN^2*M^2)/r^3-(2*GN*M)/r^2)
You can create a function based on dfpX
(%i6) define(f(r, GN, M), dfpX);
(%o6) f(r,GN,M):=(2*GN*M*(1-(GN*M)/(2*r)))/r+(GN*M)/r
+2*GN*M^2*((2*GN^2*M^2)/r^3-(2*GN*M)/r^2)
and call it
(%i7) f(1, 2, 3);
(%o7) 2142
but you can stay with expressions
(%i8) subst([r=1, GN=2, M=3], dfpX);
(%o8) 2142
Define T as a function, rather than a macro, so that it evaluates its arguments.
(%i) T(r,GN,M) := diff(f(r,GN,M),r)+X(r,GN,M)$
Now define a function t on T which quotes ' its arguments (so that T knows which variable to differentiate with respect to) and then evaluates the result %% with ev.
(%i) t(r,GN,M) := (T('r,'GN,'M),ev(%%))$
(%i) t(1,2,3);
(%o) 2142
Related
I want to generalize some predicate written in swi-prolog to calculate the power of some function. My predicate so far is:
% calculates the +Power and the +Argument of some function +Function with value +Value.
calc_power(Value, Argument, Function, Power) :-
not(Power is 0),
Power is Power_m1 + 1,
Value =..[Function, Buffer],
calc_power(Buffer, Argument, Function, Power_m1), !.
calc_power(Argument, Argument, _, 0).
The call calc_power((g(a)),A,f,POW). gives so far:
A = g(a),
POW = 0.
My generalization should also solve calls like that:
calc_power(A1, a, f, 3).
the solution should be in that special calse A1 = f(f(f(a))). But for some reason it doesn't work. I get the error:
ERROR: Arguments are not sufficiently instantiated
in line
Power is Power_m1 + 1
it means probably in swi prolog it is not possible to take plus with two variables. How can I solve this problem?
Can delay the + 1 operation with:
int_succ(I0, I1) :-
( nonvar(I0) ->
integer(I0),
I0 >= 0,
I1 is I0 + 1
; nonvar(I1) ->
integer(I1),
I1 >= 1,
I0 is I1 - 1
; when((nonvar(I0) ; nonvar(I1)), int_succ(I0, I1))
).
Example in swi-prolog:
?- int_succ(I0, I1), I1 = 7.
I0 = 6,
I1 = 7.
This is more flexible than https://www.swi-prolog.org/pldoc/man?predicate=succ/2 , and can of course be modified to support negative numbers if desired.
Found some solution
:- use_module(library(clpfd)).
% calculates the +Power and the +Argument of some function +Function with value +Value.
calc_power(Argument, Argument, _, 0).
calc_power(Value, Argument, Function, Power) :-
Power #\= 0,
Power #= Power_m1 + 1,
Value =..[Function, Buffer],
calc_power(Buffer, Argument, Function, Power_m1).
I have to find the inverse of a function which looks like:
T := ->x (x)^0.5/(x^0.5+(1-x)^0.5)^2.
As we can see from the polynomial, we have 4 solutions when solving y= f(x). In maple,I soled for the inverse of T(x)
V := x-> solve(t=T(x),x,useassumptions=true) assuming 0<=t<=1.
and I can evaluate V, i.e maple can do V(0)=0 V(1)=1 etc.
However, as discussed, there are four solutions to the inverse function, the output of V is an expressions sequence, which looks like (solution1, solution2, solution3, solution4).
In later part of the task, I have to find the derivative of V(x)and integrate it. When I apply diff(V(x),x), maple gives me an error, saying V(x) is not valid.As V(x) is an expression sequence. I tried to use the function D(V), but still no luck.
My questions is how would I be able to handle this V(x) as an expression sequence to finish the rest of the task. Is V(x) a piecewise function? If that's the case, how would I be able to convert this expression sequence to a piecewise function.
Regards,
restart:
T := proc (x) options operator, arrow; sqrt(x)/(sqrt(x)+sqrt(1-x))^2 end proc:
V := proc (x) options operator, arrow; solve(x = T(y), y) end proc:
sol := [allvalues(V(x))]:# Extract 4 solution, with command op(1, sol)->Only first solution is correct.
plot([x, T(x), op(1, sol)], x = 0 .. 2, legend = [typeset("Curve: ", "x"),
typeset("Curve: ", "T(x)"), typeset("Curve: ", "V(x)")]);
VV := proc (x) options operator, arrow; evalf(op(1, sol)) end proc;
eval(VV(x), x = 1/2); #Inverse function at point x=1/2
eval(diff(VV(x), x), x = 1/2);# Derivative of inverse function at point x=1/2
int(VV(x), x = 1/10 .. 1/2, numeric);# Integral of inverse function at range (1/10..1/2)
Mathematica 11.3 solution:
expr is giving unexpected results for 4 characters (t, n, f, y). And if you are doing some further calculation. then code is breaking. I could not understand why this is happening?
% expr (F)
F
% expr (F)*1
can't use non-numeric string as operand of "*"
And,
% expr (t)
t
% expr (n)
n
% expr (f)
f
% expr (y)
y
This is coming file for charcters : t, n, f, y. There are no variables named by these characters. It should flag variable not found or some other valid error. Am i missing some thing?
The [expr] conditions of commands such as [if] and [while] expect the expression to evaluate to a boolean, i.e., an integer or one of the following string values:
true, on, yes
false, off, no
I believe t, y, f and n are shortcuts for these.
I think you are expecting something wrong from expr.
That command is intended for evaluating expressions. It can do arithmetical operations on number, compare strings or number, execute some mathematical functions, and such.
Your lines
% expr (F)
% expr (t)
% expr (n)
% expr (f)
% expr (y)
all do the same thing: they ask to perform no operation on a literal string with higher precedence (the braces). So? There is nothing more and expr returns the string itself.
In
% expr (F)*1
however, you are trying to multiply a string to a number: an operation which is not defined. Indeed, expr gives you an error saying that one of the operands of * is a non numeric string (which number F should represent?).
With a literal string such F, or y, you can ask string comparison. For example, you can do these:
% expr F < f
1
(because in my encoding the upper case letters come before lower case ones)
% expr F == y
0
and so on.
So, expr is not giving any unexpected result, but maybe your expectations are wrong.
I assumed that values passed into a lisp function are assigned to a quote matching the name of the parameter. However, I was surprised that this:
(defun test (x) (print (eval 'x)))
(test 5)
doesn't work (the variable x is unbound). So if parameters aren't stored as symbols in the function, what exactly IS x in this example? Is there a way to access parameters from a symbol matching the parameter name?
More context:
What I would like to do is something like this:
defun slice (r1 c1 r2 c2 board)
(dolist (param '(r1 c1 r2 c2)) ;adjust for negative indices
(if (< (eval param) 0)
(set param (+ (length board) (eval param)))))
;Body of function
Basically, I want to iterate through the first four parameters and make an adjustment to any of their values if they are < 0. Of course, I could do a let and have an individual line for each parameter, but considering I'm doing the same thing for each of the four parameters this seemed cleaner.
However, I get the error that the variable R1 is unbound.
That's basically how lexical binding works: the variable name gets replaced within the lexical scope with a direct reference to where the variable's value is stored. Binding the variable name's symbol-value is only done for dynamic variable which you can declare with special.
One way to avoid repeating yourself would be a macro:
(defmacro with-adjusting ((&rest vars) adjust-value &body body)
`(let ,(loop for var in vars
collect `(,var (if (minusp ,var)
(+ ,var ,adjust-value)
,var)))
,#body))
(defun slice (r1 c1 r2 c2 board)
(with-adjusting (r1 c1 r2 c2) (length board)
;; function body
Is there a way to access parameters from a symbol matching the parameter name?
Not for lexical binding. Common Lisp gives no way to access a lexical variable from a similar named symbol. You would need to declare the variable special.
So if parameters aren't stored as symbols in the function, what exactly IS x in this example?
A processor register? A part of a stack frame?
With dynamic binding:
CL-USER 40 > (defun foo (a b)
(declare (special a b))
(dolist (v '(a b))
(if (zerop (symbol-value v))
(set v 10)))
(values a b))
FOO
CL-USER 41 > (foo 1 0)
1
10
As Rainer explained, you cannot access the lexical argument value by its name.
What you can do instead is use the &rest argument together with destructuring-bind if you want the variables too:
(defun slice (board &rest params)
(destructuring-bind (r1 c1 r2 c2)
(mapcar (lambda (param) ;adjust for negative indices
(if (minusp param)
(+ (length board) param)
param))
params)
... operate on r1 c1 r2 c2 ...))
I'm an OCaml noob. I'm trying to figure out how to handle a comparison operator that's passed into a function.
My function just tries to pass in a comparison operator (=, <, >, etc.) and an int.
let myFunction comparison x =
if (x (comparison) 10) then
10
else
x;;
I was hoping that this code would evaluate to (if a "=" were passed in):
if (x = 10) then
10
else
x;;
However, this is not working. In particular, it thinks that x is a bool, as evidenced by this error message:
This expression has type 'a -> int -> bool
but an expression was expected of type int
How can I do what I'm trying to do?
On a side question, how could I have figured this out on my own so I don't have to rely on outside help from a forum? What good resources are available?
Comparison operators like < and = are secretly two-parameter (binary) functions. To pass them as a parameter, you use the (<) notation. To use that parameter inside your function, you just treat it as function name:
let myFunction comp x =
if comp x 10 then
10
else
x;;
printf "%d" (myFunction (<) 5);; (* prints 10 *)
OCaml allows you to treat infix operators as identifiers by enclosing them in parentheses. This works not only for existing operators but for new ones that you want to define. They can appear as function names or even as parameters. They have to consist of symbol characters, and are given the precedence associated with their first character. So if you really wanted to, you could use infix notation for the comparison parameter of myFunction:
Objective Caml version 3.12.0
# let myFunction (#) x =
x # 10;;
val myFunction : ('a -> int -> 'b) -> 'a -> 'b = <fun>
# myFunction (<) 5;;
- : bool = true
# myFunction (<) 11;;
- : bool = false
# myFunction (=) 10;;
- : bool = true
# myFunction (+) 14;;
- : int = 24
#
(It's not clear this makes myFunction any easier to read. I think definition of new infix operators should be done sparingly.)
To answer your side question, lots of OCaml resources are listed on this other StackOverflow page:
https://stackoverflow.com/questions/2073436/ocaml-resources
Several possibilities:
Use a new definition to redefine your comparison operator:
let myFunction comparison x =
let (#) x y = comparison x y in
if (x # 10) then
10
else
x;;
You could also pass the # directly without the extra definition.
As another solution you can use some helper functions to define what you need:
let (/*) x f = f x
let (*/) f x = f x
let myFunction comparison x =
if x /* comparison */ 10 then
10
else
x