make sub-expressions based on addition(+) operator MAPLE - symbolic-math

Arbitrary expression be
test := a*b*c+x+a*y+c*z;
output := SomeCommand(test, `+`);
output
[a*b*c,x,a*y,c*z];
Is there any command to do it as a expression.
I did this by converting it into string and using StringSplit command. converting each element from list to expression and in for loop.
test := convert(test, string)
with(StringTools):
output:=StringSplit(test, "+")
["a*b*c", "a*y", "c*z", "x"]
InertForm:-Parse(output[1])
value(output[1])
a*b*c
but, My interest is to get this done as a expression. is there any possibility??

You're question has input but no output. You should observe that the expression that you've assigned to test may have its addends stored in a different order from which they are typed in the input.
It is possible to pick off the addends of a sum, and put them in a list. The very simple code for this is below.
The order in which the addends appear in the list match the order in which they are stored internally.
restart;
f := proc(expr)
if type(expr, `+`) then
[op(expr)];
else
expr;
end if;
end proc:
test := a*b*c+x+a*y+c*z;
test := a b c + a y + c z + x
f( test );
[a b c, a y, c z, x]
Are you the same fellow who's asked all these (somewhat related) questions? Or taking the same course? Q1 Q2 Q3 Q4
If so then could you just tell use what you're really trying to accomplish?

Related

Access elements of group given by finite presentation in Magma Calculator

I have been trying to use the Magma Calculator: http://magma.maths.usyd.edu.au/calc/
Given a word u, in a finitely presented group, how do I declare g to be the group element represented by u?
Context:
I can define a group via a finite presentation. For example using the code:
G<a,b,c> := Group< a,b,c | a^2=b^2, b^2=c^2, c=a*b >;
If I then ask for the order of the group:
Order (G);
The correct answer of 8 is returned, so it does understand what G is.
However I want to know how to ask if two elements of the group are equal.
The problem is that a,b,c as well as G.1, G.2, G.3 denote elements of the free group generated by a,b,c. Similarly products of those symbols (and their inverses) represent words in the free group.
Thus
a*a^-1 eq a^-1*a;
returns true, as it is true in the free group, but
a^2 eq c^2;
returns false, even though it is true in the group G.
This is explained in https://magma.maths.usyd.edu.au/magma/handbook/text/851.
In the section "Operations on words" it says that:
"u eq v : Returns true if the words u and v are identical when freely reduced. NB When G is not a free group and false is returned, this does not imply that u and v do not represent the same element of G."
However Magma can do operations with group elements, including answering if two elements g,h, are the same:
g eq h;
The question is then, given a word u, in a finitely presented group, how do I declare g to be the group element represented by u?
Following the anwer by #Userulli I typed
G<a,b,c> := Group< a,b,c | a^2=b^2, b^2=c^2, c=a*b >;
u := a^2;
v := c^2;
g := ElementToSequence(G, u);
h := ElementToSequence(G, v);
g eq h;
and got the reply
>> g := ElementToSequence(G, u);
^
Runtime error in 'ElementToSequence': Bad argument types
Argument types given: GrpFP, GrpFPElt
>> h := ElementToSequence(G, v);
^
Runtime error in 'ElementToSequence': Bad argument types
Argument types given: GrpFP, GrpFPElt
>> g eq h;
^
User error: Identifier 'g' has not been declared or assigned
Have you tryied using the ElementToSequence method?
For example :
u := a^2;
g := ElementToSequence(u, G);
Then you can compare g with other elements in the group to see if they are the same:
v := c^2;
h := ElementToSequence(v, G);
h eq g; // this should return true
EDIT:
Stating the doc magma.maths.usyd.edu.au/magma/handbook/text/208 you need to use fields instead, so you should convert the group into a field, and then use ElementToSequence method to compare the two sequences?

Why does this code set the variable a to 9?

I am confused by this piece of code:
| a b c| a := 1. b := [a := a + 1]. c := [a := a - 2. b].
10 timesRepeat: (a even ifTrue: b ifFalse: c). a
My assumption was that this piece of code would set a to -19. Each iteration would test if a was even, but a would be odd so c would be called, substracting 2 from a without affecting its parity. c would not call b because, if my understanding of blocks is correct, the last element of the block is returned instead of evaluated; so c would return b, but timesRepeat discards whatever is returned anyway so this b in c has no effect.
My assumption was proven to be wrong: this piece of code sets a to 9 instead. To see what's going on I modified this piece of code slightly:
| a b c| a := 1. b := [Transcript show: (a displayString). a := a + 1]. c := [Transcript show: (a displayString). a := a - 2. b.].
10 timesRepeat: (a even ifTrue: b ifFalse: c). a
This is what gets printed:
1-1012345678
So it would seem b is called after all? Was my assumption wrong that b is returned instead of called?
Let's try to check this:
jkl := [Transcript show: 'I am called too.'].
asdf := [Transcript show: 'I am called!'. jkl].
10 timesRepeat: asdf
Nope, asdf does not call jkl here:
I am called!I am called!I am called!I am called!I am called!I am called!I am called!I am called!I am called!I am called!
And anyway, if c was always just calling b, its effect would be to effectively substract 1 from a; but this doesn't happen. Instead, the first iteration seems to call c and then, mysteriously, each iteration seems to call b instead, even if a is odd!!
What's going on here??
The timesRepeat: selector wants a block as an argument. You are calling it with an expression inside of parentheses:
10 timesRepeat: (a even ifTrue: b ifFalse: c).
It just so happens, though, that c is defined as the block [a := a - 2. b] which returns the value of b and that happens to be a block. So timesRepeat: is happy, and it executes the block b on each iteration in which a is odd. If you write it correctly as:
10 timesRepeat: [a even ifTrue: b ifFalse: c].
Then at the end, a will be -19 as expected.
Regarding your statement: if my understanding of blocks is correct, the last element of the block is returned instead of evaluated, this isn't really the case. There's no special treatment for the last statement in a block other than it's result is indeed returned as the value of the block when that block is executed. Your last statement in the block is just the name of a variable. The value of the variable just happens to be a block, but no matter what it is, just having a variable name by itself as a statement in Smalltalk just returns the value of the variable. If the variable happens to be a block, you get the block. The block is not executed.
Consider the following blocks:
[a := 1. b := 2. c := a+b]
When this block is executed, then a will have the value 1, b the value 2, and c the value 3. The value the block will return is the value of c, which is 3.
[a := 1. b := 2. a]
If you execute this block, the result will be the value of a, which is 1.
[a := 1. b := 2. c := [a+b]. c]
If you execute this block, the result will be the block that the variable c represents. It does not execute the block c. This is consistent with the prior example.
So, when you execute the block, [Transcript show: 'I am called!'. jkl]., the jkl at the end is not executed. It's value is just returned. If you want to execute it, you could write asdf := [Transcript show: 'I am called!'. jkl value]. A block will execute when sent the value message. The result of executing block [Transcript show: 'I am called!'. jkl value]. will be the result of executing the block jkl.
I may be the only one, but I find the second sentence below a little bit obscure:
It just so happens, though, that c is defined as the block [a := a - 2. b] which returns the value of b and that happens to be a block. So timesRepeat: is happy, and it executes the block b on each iteration in which a is odd.
The semantics of Smalltalk is:
Evaluate the receiver
Evaluate the arguments
Send the message
The order is crucial because evaluations may have side effects.
So, what actually happens is:
Receiver 10 evaluates to 10
Argument a even ifTrue: b ifFalse: c evaluates to b. Side effect a = -1.
The message 10 timesRepeat: b or 10 timesRepeat: [a := a + 1] is sent
Hence, a = 9.

Generic to integer conversion in Eiffel

I have some codes like follow:
keys: LINKED_LIST[K]
...
test
local
tempK:K
tempI:INTEGER
do
...
across
keys as cursor
loop
tempK := cursor.item
if tempK ~ 1 then
tempI := tempK
end
end
...
end
"cursor.item" is type of "K". However, the real value inside there is integer type.
thus, "if tempK ~ 1 then" works fine. But "tempI := tempK" doesn't work.
How can I convert tempK's K type to integer? so that it can compile?
In this particular case, where you know that tempK is 1, tempI := 1 will do.
If the idea is to initialize tempI as soon the values stored in the list are of type INTEGER, there are several ways. One is to use an object test:
if attached {INTEGER} tempK as i then
tempI := i
end
However, in this case the test is performed for every element, i.e. inefficient. Changing the code to test for the list type before the loop will help:
if attached {LINKED_LIST [INTEGER]} keys as integer_keys then
...
across
integer_keys as cursor
loop
tempI := cursor.item
end
...
end
If the only operation in the loop is the assignment, the equivalent code is to take just the last element of the list:
...
if not keys.is_empty and then attached {LINKED_LIST [INTEGER]} keys as integer_keys then
tempI := integer_keys.last
end
...
Instead of specialization, the code could also be generalized to take a generic agent that will be passed the key, and the client will supply the procedure to handle the key. But this might be too much, depending on what is the purpose of the task you are solving.

Defining the difference of compositions in the Wolfram Language

I've been trying to define a function compdiff on the Wolfram Language that takes two mathematical expressions f and g and a variable x as input and outputs the difference of their compositions f[g[x]]-g[f[x]] (a sort of commutator if you are into abstract algebra).
For example: compdiff[x^2,x+1,x] = (x+1)^2-(x^2+1).
I've tried with
compdiff[f_,g_,x_]:= Composition[f,g][x]-Composition[g,f][x]
and
compdiff[f_,g_,x_]:= f #* g # x-g #* f # x
but when I input
compdiff[x^2,x+1,x]
it outputs
(x^2)[(1 + x)[x]] - (1 + x)[(x^2)[x]]
What am I doing wrong?
You need to use functions instead of expressions. For example:
f[x_] := x^2
g[x_] := x+1
Then compdiff[f, g, x] will work:
In[398]:= compdiff[f,g,x]
Out[398]= -1-x^2+(1+x)^2
Alternatively, you could use pure functions, as in:
In[399]:= compdiff[#^2&,#+1&,x]
Out[399]= -1-x^2+(1+x)^2

Plotting multiple arrays in maple

I'm trying to plot 4 data-sets in a single coordinate-system. I can plot every single one of them by themselves. However when I try to plot 2 or more with the same plot function I get an error. I can't use lists since I want to scale the arrays up to 2*10000, which a list can't. I'm using Maple 18.
Can anybody please help me solve this?
This is my code:
Here is a plotted data-set:
Here is the error I get, when trying to plot multiple sets(note I have tried using {} instead of []):
Your problem is that your use of pair and zip is not going to produce Arrays P[i] whose layout is valid for plotting. (Perhaps you cribbed that bit of code from something which was intended to produce a list of lists instead of an Array.)
Instead, you could construct the P[i] as iterator-by-2 Matrices (ie. 2-column Matrices).
One way:
restart;
mu := 2.5:
iterator := 25:
fcn := proc(a)
local F,i;
F := Array(1..iterator);
F[1] := a;
for i from 2 by 1 to iterator do
F[i] := mu*F[i-1]*(1-F[i-1]);
end do;
F;
end proc:
f[1]:=fcn(0.01):
f[2]:=fcn(0.1):
f[3]:=fcn(0.3):
f[4]:=fcn(0.5):
x := Array([seq(i,i=1..iterator)]):
for i from 1 to 4 do
P[i] := <x,f[i]>^%T:
end do:
plot([P[1],P[2],P[3],P[4]]);
Another (similar) way:
restart;
mu := 2.5:
iterator := 25:
fcn := proc(a)
local F,i;
F := Vector(1..iterator);
F[1] := a;
for i from 2 by 1 to iterator do
F[i] := mu*F[i-1]*(1-F[i-1]);
end do;
F;
end proc:
f[1]:=fcn(0.01):
f[2]:=fcn(0.1):
f[3]:=fcn(0.3):
f[4]:=fcn(0.5):
x := Vector([seq(i,i=1..iterator)]):
for i from 1 to 4 do
P[i] := <x|f[i]>:
end do:
plot([P[1],P[2],P[3],P[4]]);
You could alternatively use the command plots:-listplot directly on your f[i], though you'd likely way to also specify different colors for each so that it looked nice when you used plots:-display to render them all together.
I leave aside considerations of performance. There are ways to do all this and get faster computation. I deliberately keep your basic methodology.

Resources