I had a complex problem which is solved. Now i would love to automate it. In doing so, I do address a position in a matrix. This positions does contain a variable. I want to assign a value to this variable, by its position in the matrix. Here is a simple example of what I want to do:
(%i1) M:[a,b,c];
(%o1) [a,b,c]
(%i2) M[1];
(%o2) a
(%i3) ev(M[1]):3;
(%o3) error: assignment: cannot assign to ev(M[1])
(%i4) float(a);
(%o4) a
I would love the variable "a" to be 3 now. But ev() is clearly not the right function for this.
My question is: is what i want even possible? does anyone know how to do? I looked the whole day and I am really depressed now :-(
I think what you want is the :: operator, which evaluates its left-hand side and assigns to that.
(%i1) M : [a, b, c] $
(%i2) M[1] :: 123 $
(%i3) a;
(%o3) 123
To replace a in M with the value 3:
M: M, a=3;
Which is, of course, just a shorter version of writing:
M: ev(M, a=3);
Or simply use ev(M, a=3) instead of M to use M with a=3 once without changing M in memory.
To set the 1st element in M to 3:
M[1]: 3
To replace the variable stored in M[1] in all of M:
M: ev(M, M[1]=3);
I hope one of those answers your question..
Related
Initializing a defstruct using new or without new, seems to do the same, is there any difference?
(%i1) defstruct(foo(a,b));
(%o1) [foo(a, b)]
(%i2) f: foo(1,2);
(%o2) foo(a = 1, b = 2)
(%i3) f#a;
(%o3) 1
(%i4) f_new: new(foo(1,2));
(%o4) foo(a = 1, b = 2)
(%i5) f_new#a;
(%o5) 1
(%i6)
Without using new, the code seems a bit shorter and easier, but I'm not sure if some code will break if I use this pattern.
I think both ways are OK. The only difference so far as I know is that new(foo(...)) will ensure that there are the correct number of initial values. For example new(foo(1)) and new(foo(1, 2, 3)) will give errors, with foo as defined above. Just writing foo(1) or foo(1, 2, 3) doesn't trigger an error (maybe it should).
Consider the following statements:
(%i1) matchdeclare([a,b], constantp);
(%o1) done
(%i2) defmatch(match, a*x+b);
(%o2) match
(%i3) match(2*x+3);
(%o3) [b = 3, a = 2]
I want to generalise this pattern in a function. But then it doesn't seem to work anymore:
(%i1) matchForm(test, form, constants) := block(
matchdeclare(constants, constantp),
defmatch(match, form),
match(test)
);
(%o1) matchForm(test, form, constants) :=
block(matchdeclare(constants, constantp), defmatch(match, form), match(test))
(%i2) test: 2*x+3;
(%o2) 2 x + 3
(%i3) form: a*x+b;
(%o3) a x + b
(%i4) constants: [a,b];
(%o4) [a, b]
(%i5) matchForm(test, form, constants);
defmatch: evaluation of atomic pattern yields: a x + b
(%o5) false
Debugging a bit, a bit it seems like the issue is that matchdeclare doesn't accept the argument to be a variable. Is ther any way to make a function like I try to make in maxima?
I haven't tried this, but: perhaps you can get the effect you want via
apply (matchdeclare, [constants, 'constantp]),
which will evaluate constants before calling matchdeclare.
In maxima, is the following behavior intended?
First example:
(%i1) declare(a,constant);
(%o1) done
(%i2) constantp(a);
(%o2) true
(%i3) square(a):=a^2;
define: in definition of square, found bad argument a
-- an error. To debug this try: debugmode(true);
(%i4) load("linearalgebra.mac");
define: in definition of dotproduct, found bad argument a
-- an error. To debug this try: debugmode(true);
Second example:
(%i1) a:5;
(%o1) 5
(%i2) constantp(a);
(%o2) true
(%i3) square(a):=a^2;
2
(%o3) square(a) := a
(%i4) square(a);
(%o4) 25
Third example:
(%i1) declare(a,scalar);
(%o1) done
(%i2) mat_f(a,b):=a.b - b.a;
(%o2) mat_f(a, b) := a . b - b . a
(%i4) mat_f(matrix([1,2],[3,4]),matrix([3,4],[1,2]));
[ - 10 - 14 ]
(%o4) [ ]
[ 6 10 ]
It seems like declare(a,constant) has a global effect which to me seems strange in maxima. The second and third example work exactly how I would expect it.
Also are there any similar cases where something like this happens in maxima?
Maxima has a very weak notion of scope. Essentially all symbols are in the same scope, so when you make a declaration about a, it is about all instances of a, even the ones which are function arguments.
Maxima is actually a very old program and this is one of those aspects which has never been updated. There is discussion about giving Maxima a stronger notion of scope, but that will take some time.
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.
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.