Computer Algebra Software: Mathematica, Maxima, Pari/GP
mathematica | maxima | pari/gp | |
---|---|---|---|
version used | 8.0 | 5.21 | 2.3 |
show version | select About Mathematica in Mathematica menu | $ maxima --version | $ gp --version |
grammar and invocation | |||
mathematica | maxima | pari/gp | |
interpreter | $ maxima -b foo.mac | $ gp -q foo.gp | |
repl | $ math | $ maxima | $ gp |
block delimiters | ( stmt; …) | block ( … ) | { … } |
statement separator | ; or sometimes newline ; before a newline suppresses output | ; suppresses output: $ | newline or ; a trailing semicolon suppresses output |
end-of-line comment | none | none | 1 + 1 \\ addition |
multiple line comment | 1 + (* addition *) 1 | 1 + /* addition */ 1 | 1 + /* addition */ 1 |
variables and expressions | |||
mathematica | maxima | pari/gp | |
assignment | a = 3 Set[a, 3] | a: 3 | a = 3 |
parallel assignment | {a, b} = {3, 4} Set[{a, b}, {3, 4}] | [a, b]: [3, 4] | none |
compound assignment | += -= *= /= corresponding functions: AddTo SubtractFrom TimeBy DivideBy | none | += -= *= /= %= |
increment and decrement | ++x --x PreIncrement[x] PreDecrement[x] x++ x-- Increment[x] Decrement[x] | none | return value after increment or decrement: x++ x-- |
null | Null | ||
null test | |||
undefined variable access | treated as an unknown number | treated as an unknown symbol | treated as an unknown number |
remove variable binding | Clear[x] Remove[x] | kill(x) | kill(x) |
conditional expression | If[x > 0, x, -x] | if is(x > 0) then x else -x | if(x > 0, x, -x) |
arithmetic and logic | |||
mathematica | maxima | pari/gp | |
true and false | True False | true false | 1 0 |
falsehoods | False | false | 0 |
logical operators | ! True || (True && False) Or[Not[True], And[True, False]] | is(not true or (true and false)) | ! 1 || (1 && 0) |
relational operators | == != > < >= <= corresponding functions: Equal Unequal Greater Less GreaterEqual LessEqual | = # > < >= <= | == != > < >= <= |
arithmetic operators | + - * / Quotient Mod adjacent terms are multiplied, so * is not necessary. Quotient and Mod are functions, not binary infix operators. These functions are also available: Plus Subtract Times Divide | + - * / quotient mod quotient and mod are functions, not binary infix operators | + - * / none % |
integer division | Quotient[a, b] | quotient(a, b) | divrem(a, b)[1] |
integer division by zero | dividend is zero: Indeterminate otherwise: ComplexInfinity | error | error |
float division | exact division: a / b | float(a) / b | exact division: a / b |
float division by zero | dividend is zero: Indeterminate otherwise: ComplexInfinity | error | error |
power | 2 ^ 16 Power[2, 16] | 2 ^ 16 | 2 ^ 16 |
sqrt | returns symbolic expression: Sqrt[2] | returns symbolic expression: sqrt(2) | returns float: sqrt(2) |
sqrt -1 | I | %i | 1.000 * I |
transcendental functions | Exp Log Sin Cos Tan ArcSin ArcCos ArcTan ArcTan ArcTan accepts 1 or 2 arguments | exp log sin cos tan asin acos atan atan2 | exp log sin cos tan asin acos atan none |
transcendental constants pi and the euler constant | Pi E | %pi %e | Pi exp(1) |
float truncation round towards zero, round to nearest integer, round down, round up | IntegerPart Round Floor Ceiling | truncate round floor ceiling | truncate round floor ceil |
absolute value and signum | Abs Sign | abs sign | abs sign |
integer overflow | none, has arbitrary length integer type | none, has arbitrary length integer type | none, has arbitrary length integer type |
float overflow | none | error | error |
rational construction | use integer division: 1 / 7 | use integer division: 1 / 7 | use integer division: 1 / 7 |
rational decomposition | Numerator Denominator | ratnumer ratdenom | numerator denominator |
complex construction | 1 + 3I | 1 + 3 * %i | 1 + 3 * I |
complex decomposition real and imaginary part, argument and modulus, conjugate | Re Im Arg Abs Conjugate | realpart imagpart carg abs conjugate | real imag ?? abs conj |
random number uniform integer, uniform float | RandomInteger[{0, 99}] RandomReal[] | random(100) random(1.0) | random(100) ?? |
random seed set, get | SeedRandom[17] ?? | set_random_state(make_random_state(17)); ?? | setrand(17) getrand() |
binary, octal, and hex literals | 2^^101010 8^^52 16^^2a | ||
base conversion | BaseForm[42, 7] BaseForm[7^^60, 10] | \\ 42 as powers of 7 up to 9th power: 42 + O(7^10) | |
strings | |||
mathematica | maxima | pari/gp | |
string literals | "don't say \"no\"" | "don't say \"no\"" | "don't say \"no\"" |
newline in literal | yes | no; use \n escape | |
string literal escapes | \\ \" \b \f \n \r \t \ooo | \n \t \" \\ | |
character access | Characters["hello"][[1]] | charat("hello", 1) | |
chr and ord | FromCharacterCode[{65}] ToCharacterCode["A"][[1]] | ||
length | StringLength["hello"] | slength("hello") | length("hello") |
concatenate | "one " <> "two " <> "three" | concat("one", "two", "three"); | Str("one", "two", "three") |
index of substring | StringPosition["hello", "el"][[1]][[1]] StringPosition returns an array of pairs, one for each occurrence of the substring. Each pair contains the index of the first and last character of the occurrence. | ssearch("el", "hello") counts from one, returns false if not found | |
extract substring | StringTake["hello", {1, 4}] | substring("hello", 1, 5) | |
split | StringSplit["foo,bar,baz", ","] | split("foo,bar,baz",",") | |
join | StringJoin[Riffle[{"foo", "bar", "baz"}, ","]] | simplode(["foo","bar","baz"],",") | |
trim | StringTrim[" foo "] | strim(" ", " foo ") striml(" ", " foo") strimr(" ", "foo ") | |
convert from string, to string | 7 + ToExpression["12"] 73.9 + ToExpression[".037"] "value: " <> ToString[8] | 7 + parse_string("12") 73.9 + parse_string(".037") | |
case manipulation | ToUpperCase["foo"] ToLowerCase["FOO"] | supcase("foo") sdowncase("FOO") | |
regular expressions | |||
mathematica | maxima | pari/gp | |
regex test | re = RegularExpression["[a-z]+"] sc = StringCases["hello", re] Length[sc] > 0 | ||
regex substitution | s = "foo bar bar" re = RegularExpression["bar"] StringReplace[s, re -> "baz", 1] StringReplace[s, re -> "baz"] | ||
arrays | |||
mathematica | maxima | pari/gp | |
literal | {1, 2, 3} List[1, 2, 3] | [1, 2, 3] | \\ [1, 2, 3] is a vector literal: List([1, 2, 3]) |
size | Length[{1, 2, 3}] | length([1, 2, 3]) | length(List([1, 2, 3])) |
empty test | Length[{}] == 0 | emptyp([]); | length(List([])) == 0 |
lookup | (* access time is O(1) *) (* indices start at one: *) {1, 2, 3}[[1]] Part[{1, 2, 3}, 1] | /* access time is O(n) */ /* indices start at one: */ [1, 2, 3][1]; | \\ access time is O(1). \\ indices start at one: List([1, 2, 3])[1] |
update | a[[1]] = 7 | a[1]: 7; | listput(a, 7, 1) |
out-of-bounds behavior | left as unevaluated Part[] expression | invalid index error | out of allowed range error |
element index | (* returns list of all positions: *) First /@ Position[{7, 8, 9, 9}, 9] | /* returns list of all positions: */ sublist_indices([7, 8, 9, 9], lambda([x], x = 9)); | none |
slice | {1, 2, 3}[[1 ;; 2]] | none | none |
array of integers as index | (* evaluates to {7, 9, 9} *) {7, 8, 9}[[{1, 3, 3}]] | none | none |
manipulate back | a = {6,7,8} AppendTo[a, 9] elem = a[[Length[a]]] a = Delete[a, Length[a]] elem | a: [6, 7, 8]; a: endcons(9, a); last(a); /* no easy way to delete last element */ | a = List([6, 7, 8]) listput(a, 9) elem = listpop(a) |
manipulate front | a = {6,7,8} PrependTo[a, 5] elem = a[[1]] a = Delete[a, 1] elem | load("basic"); a: [6, 7, 8]; push(5, a); elem: pop(a); | a = List([6, 7, 8]); listinsert(a, 5, 1); elem = a[1]; listpop(a, 1); |
head | First[{1, 2, 3}] | first([1, 2, 3]); | List([1, 2, 3])[1] |
tail | Rest[{1, 2, 3}] | rest([1, 2, 3]); | none |
cons | (* first arg must be an array *) Prepend[{2, 3}, 1] | /* second arg must be an array */ cons(1, [2, 3]); | a = List([1, 2, 3]); listinsert(a, 1, 1); |
concatenate | Join[{1, 2, 3}, {4, 5, 6}] | append([1, 2, 3], [4, 5, 6]) | concat(List([1, 2, 3]), List([4, 5, 6])) |
replicate | ten_zeros = Table[0, {i, 0, 9}] | ten_zeros: makelist(0, 10); | |
copy | a2 = a | a2: copylist(a); | a2 = a |
iterate | Function[x, Print[x]] /@ {1, 2, 3} | a: [1, 2, 3]; for i from 1 thru length(a) do print(a[i]); | a = List([1, 2, 3]) for(i=1, length(a), print(a[i])) |
reverse | Reverse[{1, 2, 3}] | reverse([1, 2, 3]); | a = List([1, 2, 3]) a2 = listcreate() while(i > 0, listput(a2, a[i]); i—) |
sort | Sort[{3, 1, 4, 2}] | sort([3, 1, 4, 2]); | a = List([3,1,4,2]) listsort(a) a |
dedupe | Union[{1, 2, 2, 3}] | unique([1, 2, 2, 3]); | |
membership | MemberQ[{1, 2, 3}, 2] | member(2, [1, 2, 3]); | /* The Set() constructor takes an array or vector as an argument. It converts the elements to strings and sorts them, discarding duplicates. setsearch() returns the index of the element or zero if not in the set. */ setsearch(Set([1, 2, 3]), 2) |
intersection | Intersect[{1, 2}, {2, 3, 4}] | /* { } is literal notation for a set; use setify() to convert array to set */ intersect({1, 2}, {2, 3, 4}); | setintersect(Set([1, 2]), Set([2, 3, 4])) |
union | Union[{1, 2}, {2, 3, 4}] | union({1, 2}, {2, 3, 4}); | setunion(Set([1, 2]), Set([2, 3, 4])) |
relative complement, symmetric difference | Complement[{1, 2, 3}, {2}] none | setdifference({1, 2, 3}, {2}); symmdifference({1, 2}, {2, 3, 4}); | setminus(Set([1, 2, 3]), Set([2])) |
map | Function[x, x x] /@ {1, 2, 3} Map[Function[x, x x], {1, 2, 3}] | map(lambda([x], x * x), [1, 2, 3]) | |
filter | Select[{1, 2, 3}, # > 2 &] | sublist([1, 2, 3], lambda([x], x > 2)) | |
reduce | Fold[Plus, 0, {1, 2, 3}] | /* returns -4: */ lreduce(lambda([x,y], x - y), [1, 2, 3]) /* returns 2: */ rreduce(lambda([x,y], x - y), [1, 2, 3]) | |
universal and existential tests | none | every(evenp, [1, 2, 3]); some(evenp, [1, 2, 3]); | |
min and max element | Min[{1, 2, 3}] Max[{1, 2, 3}] | apply(min, [1, 2, 3]); apply(max, [1, 2, 3]); | |
shuffle and sample | x = {3, 7, 5, 12, 19, 8, 4} RandomSample[x] RandomSample[x, 3] | random_permutation([3, 7, 5, 12, 19, 8, 4]); | |
zip | (* list of six elements: *) Riffle[{1, 2, 3}, {"a", "b", "c"}] | /* list of six elements: */ join([1, 2, 3], ["a", "b", "c"]) | |
sequences | |||
mathematica | maxima | pari/gp | |
range | Range[1, 100] | makelist(i, i, 1, 100) | |
arithmetic sequence of integers with difference 10 | Range[1, 100, 10] | ||
arithmetic sequence of floats with difference 0.1 | Range[1, 100, .1] | ||
multidimensional-arrays | |||
mathematica | maxima | pari/gp | |
dictionaries | |||
mathematica | maxima | pari/gp | |
record literal | r = { n -> 10, avg -> 3.7, sd -> 0.4} | defstruct(point(x, y, z)); p: point(2, 3, 5); | |
record member access | n /. r | p@x | |
functions | |||
mathematica | maxima | pari/gp | |
definition | add[a_, b_] := a + b (* alternate syntax: *) add = Function[{a, b}, a + b] | add(a, b) := a + b; | add(x, y) = x + y |
invocation | add[3, 7] add @@ {3, 7} | add(3, 7); | add(3, 7) |
return value | |||
function value | |||
anonymous function | Function[{a, b}, a + b] (#1 + #2) & | lambda([a, b], a + b) | |
missing argument | error | ||
extra argument | error | ||
default argument | |||
variable number of arguments | f(x, [L]) := if emptyp(L) then x else [x, apply("+", L)]; f(1); f(1, 2, 3); | ||
execution control | |||
mathematica | maxima | pari/gp | |
if | If[x > 0, Print["positive"], If[x < 0, Print["negative"], Print["zero"]]] | if (is(x > 0)) then print("positive") elseif (is(x < 0)) then print("negative") else print("zero") | if(x > 0, \ print("positive"), \ if(x < 0, \ print("negative"), \ print("zero"))) |
while | i = 0 While[i < 10, Print[i]; i++] | i = 0 while(i < 10, print(i); i++) | |
for | For[i = 0, i < 10, i++, Print[i]] | for i from 0 thru 9 do print(i); | for(i=0, 9, print(i)) |
break/continue | Break[] Continue[] | break continue | |
raise exception | Throw["failed"] | throw("failed"); error("failed"); | error("failed") |
handle exception | Print[Catch[Throw["failed"]]] | catch(throw("failed")); errcatch(error("failed")); | |
finally block | none | ||
files | |||
mathematica | maxima | pari/gp | |
write to stdout | Print["hello"] | print("hello") | print("hello") |
read entire file into string or array | s = Import["/etc/hosts"] a = StringSplit[s, "\n"] | ||
redirect to file | |||
libraries and namespaces | |||
mathematica | maxima | pari/gp | |
load | |||
reflection | |||
mathematica | maxima | pari/gp | |
list function documentation | ?? | ? | |
get function documentation | ?Tan Information[Tan] | ? tan describe(tan) | ? tan |
grep documentation | ?? tan | ||
query data type | Head[x] | bigfloatp(x) floatnump(x) integerp(x) numberp(x) ratnump(x) stringp(x) listp(x) | type(x) |
list variables in scope | ? 0 | ||
algebra | |||
mathematica | maxima | pari/gp | |
solution to an equation | Solve[x^3 + x + 3 == 0, x] | solve(x^3 + x + 3, x) | |
solution to two equations | Solve[x + y == 3 && x == 2y, {x, y}] | solve([x+y=3, x=2*y], [x, y]) | |
numerical approximation | N[Exp[1]] Exp[1] + 0. N[Exp[1], 10] | float(exp(1)) | 1/7 + 0. |
expand polynomial | Expand[(1 + x)^5] | expand((1+x)^5) | |
factor polynomial | Factor[3 + 10 x + 9 x^2 + 2 x^3] | factor(3 + 10*x + 9*x^2 + 2*x^3) | |
add fractions | Together[a/b + c/d] | ratsimp(a/b + c/d) | |
decompose fraction | Apart[(b c + a d)/(b d)] | ||
calculus | |||
mathematica | maxima | pari/gp | |
differentation | D[x^3 + x + 3, x] | diff(x^3 + x + 3, x) diff(sin(x), x) | P = x^3 + x + 3 P' sin(x)' |
higher order differentiation | D[Log[x], {x, 3}] | diff(log(x), x, 3); | |
integration | Integrate[x^3 + x + 3, x] Integrate[x^3 + x + 3, {x, 0, 1}] | integrate(x^3 + 3*x + 3, x); integrate(x^3 + 3*x + 3, x, 0, 1); | |
find minimal value | Minimize[Sqrt[a^2 + x^2] + Sqrt[(b - x)^2 + c^2], x] | ||
number theory | |||
mathematica | maxima | pari/gp | |
number tests | IntegerQ[7] PrimeQ[7] rational test? real test? | integerp(7) primep(7) ratnump(1/7) | |
solve diophantine equation | Solve[a^2 + b^2 == c^2 && a > 0 && a < 10 && b > 0 && b < 10 && c > 0 && c < 10, {a, b, c}, Integers] | ||
factorial | 10! | 10! | 10! |
binomial coefficient | Binomial[10,3] | binomial(10,3) | |
greatest common divisor | GCD[14, 21] | gcd(14, 21) | gcd(14, 21) |
prime factors | returns {{2, 2}, {3, 1}, {7, 1}} FactorInteger[84] | factor(84) | returns [2,2; 3,1; 7,1] factor(84) |
Euler totient | EulerPhi[256] | totient(256) | |
vectors | |||
mathematica | maxima | pari/gp | |
vector literal | (* same as array: *) {1, 2, 3} | /* same as list: */ [1, 2, 3] | [1, 2, 3] |
vector coordinate | indices start at one: {1,v2, 3}[[1]] | indices start at one: [1, 2, 3][1] | indices start at one: [1, 2, 3][1] |
vector dimension | Length[{1, 2, 3}] | length([1, 2, 3]) | length([1, 2, 3]) |
element-wise arithmetic operators | + - * / adjacent lists are multiplied element-wise | + - * / | + - |
vector length mismatch | error | error | error |
scalar multiplication | 3 {1, 2, 3} {1, 2, 3} 3 * may also be used | 3 * [1, 2, 3] [1, 2, 3] * 3 | 3 * [1, 2, 3] [1, 2, 3] * 3 |
dot product | {1, 1, 1} . {2, 2, 2} Dot[{1, 1, 1}, {2, 2, 2}] | [1,1,1] . [2,2,2] | |
cross product | Cross[{1, 0, 0}, {0, 1, 0}] | load("vect"); express([1, 0, 0] ~ [0, 1, 0]); | |
norms | Norm[{1, 2, 3}, 1] Norm[{1, 2, 3}] Norm[{1, 2, 3}, Infinity] | ||
matrices | |||
mathematica | maxima | pari/gp | |
literal or constructor | A = {{1, 2}, {3, 4}} B = {{4, 3}, {2, 1}} | A: matrix([1, 2], [3, 4]); B: matrix([4, 3], [2, 1]); | A = [1, 2; 3, 4] B = [4, 3; 2, 1] |
zero, identity, ones, diagonal matrix | ConstantArray[0, {3, 3}] IdentityMatrix[3] ConstantArray[1, {3, 3}] DiagonalMatrix[{1, 2, 3}] | zeromatrix(3, 3) ident(3) 1 + zeromatrix(3, 3) diag_matrix(1, 2, 3) | |
dimensions rows, columns | Length[A] Length[A[[1]]] | matrix_size(A)[1] matrix_size(A)[2] | |
element access | A[[1, 1]] | A[1, 1] | A[1, 1] |
row access | A[[1]] | as list: A[1] as 1xn matrix: row(A, 1) | |
column access | col(A, 1) | ||
submatrix access | # [[1]] & /@ A | ||
scalar multiplication | 3 A A 3 * can also be used | 3 * A A * 3 | |
element-wise operators | + - * / adjacent matrices are multiplied element-wise | + - * / | |
multiplication | A . B | A . B | |
kronecker product | KroneckerProduct[A, B] | kronecker_product(A, B); | |
comparison | A == B A != B | is(A = B) is(A # B) | |
norms | Norm[A, 1] Norm[A] Norm[A, Infinity] Norm[A, "Frobenius"] | ||
transpose | Transpose[A] | ||
conjugate transpose | A = {{I, 2 I}, {3 I, 4 I}} ConjugateTranspose[A] | ||
inverse | Inverse[A] | ||
determinant | Det[A] | matdet(A) | |
trace | Tr[A] | trace(A) | |
eigenvalues | Eigenvalues[A] | ||
eigenvectors | Eigenvectors[A] | ||
system of equations | Solve[A. {x, y} == { 2, 3}, {x, y}] | ||
distributions | |||
mathematica | maxima | pari/gp | |
normal | nd = NormalDistribution[0,1] RandomVariate[nd] | load(distrib); random_normal(0,1); | |
exponential | ed = ExponentialDistribution[1] RandomVariate[ed] | load(distrib); random_exp(1); | |
poisson | pd = PoissonDistribution[1] RandomVariate[pd] | load(distrib); random_poisson(1); | |
univariate charts | |||
mathematica | maxima | pari/gp | |
vertical bar chart | BarChart[{7, 3, 8, 5, 5}, ChartLegends-> {"a","b","c","d","e"}] | ||
horizontal bar chart | BarChart[{7, 3, 8, 5, 5}, BarOrigin -> Left] | ||
pie chart | PieChart[{7, 3, 8, 5, 5}] | ||
stem-and-leaf plot | Needs["StatisticalPlots`"] nd = NormalDistribution[0, 1] n100 = RandomVariate[nd, 100] StemLeafPlot[20 * n100] | ||
histogram | nd = NormalDistribution[0, 1] Histogram[RandomReal[nd, 100], 10] | ||
box-and-whisker plot | nd = NormalDistribution[0, 1] n100 = RandomVariate[nd, 100] BoxWhiskerChart[d] ed = ExponentialDistribution[1] e100 = RandomVariate[ed, 100] u100 = RandomReal[1, 100] d = {n100, e100, u100} BoxWhiskerChart[d] | ||
set chart title | BoxWhiskerChart[data, PlotLabel -> "chart example"] | ||
chart options | PlotLabel -> "an example" AxisLabel -> {"time", "distance"} | ||
bivariate charts | |||
mathematica | maxima | pari/gp | |
stacked bar chart | d = {{7, 1}, {3, 2}, {8, 1}, {5, 3}, {5, 1}} BarChart[d, ChartLayout -> "Stacked"] | ||
scatter plot | nd = NormalDistribution[0, 1] rn = Function[RandomReal[nd]] d = {rn[],rn[]} & /@ Range[1,50] ListPlot[d] | ||
linear regression line | d = Table[{i, 2 i + RandomReal[{-5, 5}]}, {i, 0, 20}] model = LinearModelFit[d, x, x] Show[ListPlot[d], Plot[model["BestFit"], {x, 0, 20}]] | ||
polygonal line plot | f = Function[i, {i, rn[]}] d = f /@ Range[1, 20] ListLinePlot[d] | ||
area chart | d = {{7, 1, 3, 2, 8}, {1, 5, 3, 5, 1}} sd = {d[[1]], d[[1]] + d[[2]]} ListLinePlot[sd, Filling -> {1 -> {Axis, LightBlue}, 2 -> {{1}, LightRed}}] | ||
cubic spline | d = Table[{i, RandomReal[nd]}, {i, 0, 20}] f = Interpolation[d, InterpolationOrder -> 3] Show[ListPlot[d], Plot[f[x], {x, 0, 20}]] | ||
function plot | Plot[Sin[x], {x, -4, 4}] | plot2d(sin(x),[x,-4,4]); | ploth(x=-4, 4, sin(x)) |
quantile-quantile plot | nd = NormalDistribution[0, 1] d1 = RandomReal[1, 50] d2 = RandomReal[nd, 50] QuantilePlot[d1, d2] | ||
axis label | d = Table[{i, i^2}, {i, 1, 20}] ListLinePlot[d, AxesLabel -> {x, x^2}] | plot2d(sin(x), [x,-4,4], [ylabel,"sine function"]); | |
logarithmic y-axis | LogPlot[{x^2, x^3, x^4, x^5}, {x, 0, 20}] | ||
trivariate charts | |||
mathematica | maxima | pari/gp | |
3d scatter plot | nd = NormalDistribution[0,1] d = RandomReal[nd, {50, 3}] ListPointPlot3D[d] | ||
additional data set | nd = NormalDistribution[0, 1] x1 = RandomReal[nd, 20] x2 = RandomReal[nd, 20] ListLinePlot[{x1, x2}] | ||
bubble chart | nd = NormalDistribution[0,1] d = RandomReal[nd, {50, 3}] BubbleChart[d] | ||
surface plot | Plot3D[Sinc[Sqrt[x^2 + y^2]], {x, -25, 25}, {y, -25, 25}] | sinc(x) := sin(%pi*x)/(%pi*x);sinc(x) := sin(%pi*x)/(%pi*x); plot3d(sinc(sqrt(x^2+y^2)),[x,-25,25],[y,-25,25]); | |
______________________________________________________ | ______________________________________________________ | ______________________________________________________ |