Maxima block and variable - maxima

I want to display the square of numbers 1 to 5 using block command:
expr : 10*i;
myList (expr, iMin, iMax) := block(
local(expr),
print(expr),
print(''expr),
print( makelist(expr, i, iMin, iMax)),
print( makelist(''expr, i, iMin, iMax))
)$
ai : i^2$
myList (ai,1,5);
Here's what I get with this code:
i^2
10*i
[i^2,i^2,i^2,i^2,i^2]
[10,20,30,40,50]
Why the "expr" variable (with quote quote) in the myList is not the variable "ai"?

The short answer is that quote-quote is applied only at the time the expression is input, not when it is evaluated. Try grind(myList); to see that quote-quote has interpolated (pasted) the current value of expr into the function definition.
The longer answer is that Maxima generally has a one-time evaluation policy (i.e. variables are evaluated just once), but some functions "quote" (do not evaluate) their arguments or evaluate their arguments in a peculiar way, and makelist is one of those. That makes it tricky to write a function like myList which wants to supply an argument to makelist.
My advice is to write apply(makelist, [...]) (i.e. apply makelist to the list of arguments) instead of makelist(...). Writing it with apply will ensure that the arguments are evaluated.
(%i5) myList(expr, iMin, iMax) := apply (makelist, [expr, i, iMin, iMax]) $
(%i6) expr:i^2 $
(%i7) myList(expr, 1, 5);
(%o7) [1, 4, 9, 16, 25]

Related

Maxima: replace function f(x) by its definition?

I cannot find anything about this, sorry.
If I have expressions with the symbolic function f(x) and now I want to replace in these expression f(x) by its explicit form how to do it?
For example:
I have
f(x):= x^2+sin(x)
and in the differentiation
diff (%e**sqrt(f(x)*a), x,2);
I want to replace now f(x) by the expression above?
Thanks
Karl
(%i1) i: integrate(f(x)*f(4*x), x, 0, 1) $
(%i2) f(x):= x^2+sin(x) $
(%i3) ev(i, f);
1
/
[ 2 2
(%o3) I (sin(x) + x ) (sin(4 x) + 16 x ) dx
]
/
0
-- Function: ev (<expr>, <arg_1>, ..., <arg_n>)
Evaluates the expression <expr> in the environment specified by the
arguments <arg_1>, ..., <arg_n>. The arguments are switches
(Boolean flags), assignments, equations, and functions. 'ev'
returns the result (another expression) of the evaluation.

Erlang, pattern matching on a particular map's key?

Here is an example from the "Programming with Erlang" (2nd edition):
count_chars([], Result) ->
Result;
count_chars([C|Substring], #{C := N}=Result) ->
count_chars(Substring, Result#{C := N+1 });
count_chars([C|Substring], Result) ->
count_chars(Substring, Result#{C => 1}).
..which mercylessly yields the following error:
variable 'C' is unbound
So I am kind of stuck here; to my view, variable 'C' is bound, namely it must be a head of the string (just a linked list of chars, right?). Yet Erlang disagrees with me, breaking example from the (probably, outdated?) book I'am reading right now.
So what's wrong? What's the right way to pattern-match in this particular example?
P.S. A screenshot from the book. Pay attention at slightly different syntax, which also doesn't work for me:
P.P.S. I am using the latest version of Erlang I've managed to download from the official site.
C must be bound before the expression #{C := N}=Result is evaluated.
You consider that C is bound since the first parameter [C|Substring] was evaluated before: #{C := N}=Result. In fact it is not the case. There is no real assignment until a head evaluation succeed and the function enters the body.
Writing count_chars([C|Substring], #{C := N}=Result) -> is exactly the same as count_chars([C1|Substring], #{C2 := N}=Result) when C1 =:= C2 ->
During the head evaluation, each element is stored in a different element (a place in the heap) to check if all the parameters match the head definition. In your case the compiler want store the value C in an element, let's say x1 and the key C? in another element, let's say x2, and then verify that x1 and x2 are equals. the second operation is not possible without a deep modification of the compiler behavior.
I wrote a small example to show how it works, and compiled it with the option 'S' to see the result of the compilation:
test([K|_],K,M) -> % to see how the test of parameter equality is done
#{K := V} = M, % to verify that this pattern works when K is bound.
V.
the assembly result is :
{function, test, 3, 33}.
{label,32}.
{line,[{location,"mod.erl",64}]}.
{func_info,{atom,mod},{atom,test},3}.
{label,33}.
{test,is_nonempty_list,{f,32},[{x,0}]}. % the whole list is assigned to x0
{get_hd,{x,0},{x,3}}. % the list's head is assigned to x3
{test,is_eq_exact,{f,32},[{x,1},{x,3}]}. % the second parameter K is assigned to x1, verify if x1 =:= x3
{test,is_map,{f,34},[{x,2}]}. % the third parameter M is assigned to x2, check if it is a map if not go to label 34
{get_map_elements,{f,34},{x,2},{list,[{x,3},{x,0}]}}. % get the value associated to key x3 in the map x2 and store it into x0, if no suck key go to label 34
return.
{label,34}. % throw a badmatch error
{line,[{location,"mod.erl",65}]}.
{badmatch,{x,2}}.
Now, to code your function you can simply write:
count_chars([], Result) ->
Result;
count_chars([C|Substring], Result) ->
N = maps:get(C, Result, 0) +1,
count_chars(Substring, Result#{C => N }).

How to compute derivative in Maxima?

I want to calculate the seventh derivative of tan(x) at x=pi/4 in Maxima:
f(x) := diff(tan(x), x, 7);
f(%pi / 4);
Yet I cannot get the result. Ay ideas?
I would do it like this,
at(diff(tan(x),x,7),[x=%pi/4]);
The function diff returns a function as its result. You can evaluate this function at a point by using the at function.
Another way of doing is like so,
f: diff(tan(x), x, 7);
at(f, [x=%pi/4]);
Now f is just a variable that holds the output of diff and then at is used to evaluate it at a point.
I hope this helps.
When you define a function via :=, the function body is quoted (i.e., not evaluated). You can tell Maxima to evaluate an expression by using the quote-quote '' operator.
(%i1) display2d : false $
(%i2) f(x) := ''(diff (tan(x), x, 7));
(%o2) f(x):=64*sec(x)^2*tan(x)^6+1824*sec(x)^4*tan(x)^4+2880*sec(x)^6*tan(x)^2
+272*sec(x)^8
(%i3) f(%pi / 4);
(%o3) 34816
Note that '' has the possibly-surprising property that it is only applied once, when an expression is entered, not every time the expression is evaluated.

How to pass an array as an argument to a maxima function?

I'm working on creating maxima functions to simplify the del operator on vectors. How can I pass a list/vector to a function in maxima? This works:
(%i7) dot(a,b) := a[1]*b[1]+a[2]*b[2]+a[3]*b[3];
(%o7) dot(a, b) := a b + a b + a b
1 1 2 2 3 3
(%i8) dot(a,b);
2
(%o8) 3 x y - 4 x
but this doesn't:
(%i13) grad(a) := diff(a[1],x) + diff(a[2],y) + diff(a[3],z);
define: argument cannot be an atom or a subscripted memoizing function; found:
a
-- an error. To debug this try: debugmode(true);
Maxima has extremely confusing rules about scope and subscripts. First of all, I'll apologize for that.
My guess is that you already have an array named a by the time you define grad. Try a different name for the argument of grad -- try something which you haven't used yet. Does it work that way?
Anyway, shouldn't the definition be:
grad(a) := [diff(a, x), diff(a, y), diff(a, z)];
??

Maxima - Effect of the commas when not in a function

With Maxima, it is possible to replace an unknown by a value using at() statement.
But this use a list, for the substitution, and the solve() statement don't return a list.
Code:
(%i1) g(x):=x^2+a;
2
(%o1) g(x) := x + a
(%i2) g(x),solve(x=3),a=2;
(%o2) 11
I managed to compute a result using commas, but I can't create a function to do so:
(%i3) f(y) := g(x),solve(x=3),a=y;
(%o3) f(y) := g(x)
(%i4) f(2);
2
(%o4) x + a
Is there a statement for which the commas acts like it acts directly in the line?
Edit:
Actually, it is possible to use at() with solve() to create the function f(), as solve() just return a list of lists. So the code would be:
(%i5) f(y) := at(at(g(x), solve(x=3)[1]), a=y);
(%o5) f(y) := at(at(g(x), solve(x = 3) ), a = y)
(%i6) f(2);
(%o6) 11
Notice the [1] after solve(x=3) in the (%i5). It select the the first item (solution) of list.
I'm not sure what you are trying to accomplish -- probably it would be best if you would back up a couple of steps and describe the larger problem you are trying to solve here.
My best guess as to what you want is that you are trying to use the result of 'solve' to find a value to substitute into some expression. If so you can achieve it like this: f(eq, u) := map (lambda ([e], subst (e, g(u))), solve (eq, x)); where eq is an equation to solve for x and then substitute into g(u). Note that 'solve' can return multiple solutions so that's why I use 'map' to apply something to each solution. Here is an example output:
(%i7) f(eq) := map (lambda ([e], subst (e, g(x))), solve (eq, x));
(%o7) f(eq) := map(lambda([e], subst(e, g(x))), solve(eq, x))
(%i8) solve (x^2 + 2*x + 2);
(%o8) [x = - %i - 1, x = %i - 1]
(%i9) f (x^2 + 2*x + 2);
(%o9) [g(- %i - 1), g(%i - 1)]
Of course you can define 'g' in whatever way is appropriate.
The answer to your specific question (which I believe is not actually very much relevant, but anyway) is to use 'block' to group together expressions to be evaluated. E.g. f(x) := block (...);
Perhaps I'm answering the wrong question. Maybe what you want is ev(foo, bar, baz) -- ev is the function that is actually called when you write foo, bar, baz at the console input prompt. So the function would be written f(y) := ev (g(x), solve(x=3), a=y).
However, bear in mind that there are several different kinds of functionality built into ev, so it is hard to understand (see the documentation for ev). Instead, consider using subst which is much simpler.

Resources