*a side-by-side reference sheet*

grammar and invocation | variables and expressions | arithmetic and logic | strings | arrays | sets | arithmetic sequences | dictionaries | functions | execution control | exceptions | streams | process and environment | libraries and namespaces | reflection

vectors | matrices | combinatorics | number theory | elliptic curves | rational and algebraic numbers | polynomials | special functions | permutations | groups | subgroups | group homomorphisms | actions

magma | gap | singular | pari/gp | |
---|---|---|---|---|

version used | 2.21 | 4.7 | 4.0 | 2.7 |

show version | $ gap -h | $ singular -vb | $ gp --version | |

grammar and invocation | ||||

magma | gap | singular | pari/gp | |

interpreter | $ singular -b foo.sing | $ cat hello.gp print("Hello, World!") quit $ gp -q hello.gp Hello, World! | ||

repl | online calculator | $ gap | $ singular | $ gp |

block delimiters | function( ) … endif then … elif then … else … fiwhile do … odfor do … od | { … } | { … }braces cannot be nested | |

statement separator | ;A line can be broken anywhere, even inside a numeric literal or string, if the newline is preceded by a backslash: \ | ;Two trailing semicolons ;; suppress echoing value of previous expression. | ; | newline or ;Newlines don't separate statements inside braces.A semicolon suppresses echoing value of previous expression. |

end-of-line comment | 1 + 1; // addition | 1 + 1; # addition | // comment | 1 + 1 \\ addition |

multiple line comment | 1 + /* addition */ 1; | none | /* comment line */another comment | 1 + /* addition */ 1 |

variables and expressions | ||||

magma | gap | singular | pari/gp | |

assignment | a := 3; | a := 3; | int a; a = 3; // It is an error to assign to undeclared variable. | x = 3.14 |

parallel assignment | none | int a, b; a, b = 3, 4; | [a, b] = [3, 4] | |

compound assignment | none | none | += -= *= /= \= \/= %= \\ bit operations: <<= >>= | |

increment and decrement | none | x++ x-- | postmodifiers:x++ x-- | |

non-referential identifier | none | none | none | any unassigned identifier is non-referential |

identifier as value | x = 3 y = 'x | |||

global variable | variables are global by default | |||

local variable | tmp = 19 add(x, y, z) = { \\ don't overwrite global tmp: my(tmp = x + y); tmp + z } \\ local keyword declares dynamic scope | |||

null | none | |||

null test | none | |||

undefined variable access | error | treated as an unknown number | ||

remove variable binding | delete x; | kill(x) | ||

conditional expression | if x lt 0 then -x; else x; end if; | if(x > 0, x, -x) | ||

arithmetic and logic | ||||

magma | gap | singular | pari/gp | |

true and false | true false | true false | 1 0 | 1 0 |

falsehoods | false | false | 0 | 0 0.0 Mod(0, 5) Pol([0]) [0, 0, 0] [0, 0; 0, 0] [[0, 0], 0] |

logical operators | not true or (true and false); | not true or (true and false) | ! 1 || (1 && 0) | && || ! |

relational operators | eq ne lt gt le ge eq raises an error when the operands are of different type.cmpeq does not. | = <> < > <= >= | == != < > <= >= <> is a synonym for != | == != > < >= <= |

arithmetic operators | + - * / mod | + - * / modthe operators + - * / are overloaded for integers, rationals, and floats; other arithmetic functions aren't and there are no implicit conversions; use constructors to convert:Rat(3.1) Float(3) Float(31/10) | Operators are for integers only unlessbase ring with coefficient field is declared. + - * / % mod is synonym for % | + - * / % |

integer division | a := 7; b := 3; div(a, b); | QuoInt(a, b); | int a, b = 7, 3; a div b; // a / b also performs integer division when // no base ring is declared. | a \ b divrem(a, b)[1] \\ rounded integer division: a \/ b |

integer division by zero | User error | error | error | error |

float division | depending upon the types of a and b, the value can be an exact rational, a machine float, or an arbitrary precision float:a / b | ring r = real,(x,y,z),(dp); 3.1 / 7.2; | 7 / 3 | |

float division by zero | Runtime error | error | error | error |

power | 2 ^ 32; | 2 ^ 32 | 2 ^ 16 2 ** 16 | 2 ^ 32 |

sqrt | Sqrt(2); | 2.0 ^ 0.5 | none | sqrt(2) |

sqrt -1 | -1.0 ^ 0.5 evaluates to -1. | none | 1.000 * I | |

transcendental functions | Exp Log Sin Cos Tan Arcsin Arccos Arctan Arctan2 | arguments must be floats; no implicit conversion of integers to floats:Exp Log Sin Cos Tan Asin Acos Atan Atan2( y, x) | none | exp log nonesin cos tan asin acos atan none |

transcendental constantsπ and Euler's number | FLOAT.PI FLOAT.E | LIB "general.lib"; // print specified number of digits: number_pi(100); number_e(100); | Pi exp(1) | |

float truncationround towards zero, round to nearest integer, round down, round up | Trunc Round Floor Ceil | truncate(x) round(x) floor(x) ceil(x) | ||

absolute valueand signum | AbsIntno absolute value for floats?SignInt SignFloat | LIB "general.lib"; absValue(-7); ring r = real,(x,y,z),(dp); absValue(-7.1); | abs(x) sign(x) | |

integer overflow | none, has arbitrary length integer type | none, has arbitrary length integer type | modular arithmetic with warning | none, has arbitrary length integer type |

float overflow | # prints as inf: FLOAT.INFINTY | error | ||

rational construction | 2 / 7; | 2 / 7 | 2 / 7 | |

rational decomposition | Numerator(2 / 7); Denominator(2 / 7 ); | x := 2 / 7; NumeratorRat(x); DenominatorRat(x); | x = 2 / 7 numerator(x) denominator(x) | |

decimal approximation | 2 / 7 + 0. \\ change precision to 100: \p 100 2 / 7 + 0. | |||

complex construction | none | 1 + 3 * I | ||

complex decompositionreal and imaginary part, argument and modulus, conjugate | none | real(z) imag(z) arg(z) abs(z) conj(z) | ||

random numberuniform integer, uniform float | Random(0, 99);?? | rs := RandomSource(IsMersenneTwister); Random(rs, 0, 99); ?? | random(100) random(1.0) | |

random seedset, get | SetSeed(42); seed := GetSeed((); | rs := RandomSource(IsMersenneTwister, 17); State(rs); | setrand(17) getrand() | |

bit operators | none | \\ left shift: 5 << 1 \\ right shift: 5 >> 1 | ||

binary, octal, and hex literals | none | |||

radix | IntegerToString(42, 7); | none | \\ 42 as powers of 7 up to 9th power: 42 + O(7^10) | |

to array of digits | ListOfDigits(1234); # other bases? | \\ base 10: digits(1234) \\ base 2: digits(1234, 2) \\ number of digits in base 10: sizedigits(1234) | ||

strings | ||||

magma | gap | singular | pari/gp | |

string literal | "don't say \"no\"" | "don't say \"no\"" | string s = "don't say \"no\""; | "don't say \"no\"" |

newline in literal | A line break in a string literal results in a newline in the string unless preceded by a backslash. | no | Yes; runaway strings are possible; there is a predefined string variable newline which contains a single newline character. | no; use \n escape |

literal escapes | \" \\ \n \r \t | \b \c \n \r \" \' \\ \ooowhen writing to a buffered output stream, encountering a \c causes a flush of output. | \" \\ | \n \t \" \\ |

concatenate | "one " cat "two " cat "three"; "one " * "two " * "three"; &cat ["one ", "two ", "three "]; &* ["one ", "two ", "three "]; | Concatenation("one ", "two ", "three"); | string s = "one" + "two" + "three"; | Str("one ", "two ", "three") concat("one ", "two ", "three") |

replicate | hbar := "-" ^ 80; | |||

translate case | UppercaseString("foo"); LowercaseString("FOO"); | |||

trim | none | |||

number to string | "value: " * IntegerToString(8); | Concatenation("value: ", String(8)); | "value: " + string(8) | Str(8) \\ implicit conversion to string: concat("value: ", 8) |

string to number | 7 + Int("12"); 73.9 + Float(".037"); | 7 + eval("12") 73.9 + eval(".037") | ||

string join | a := ["foo", "bar", "baz"]; JoinStringsWithSeparator(a, ","); | |||

split | Split("foo,bar,baz", ","); | SplitString("foo,bar,baz", ","); | ||

substitute | # replace all occurrences: ReplacedString("do re mi mi", "mi", "ma"); | |||

length | # "hello"; | Length("hello"); | size("hello"); | length("hello") #"hello" |

index of substring | Index("hello", "el"); Position("hello", "el"); /* both return 0 if substring not found */ | // evaluates to 2: find("hello", "el"); | ||

extract substring | Substring("hello", 2, 2); | s := "hello"; s{[2..3]}; | // start index and substring length: "hello"[2, 2] | |

character literal | 'h' | |||

character lookup | s := "hello"; # the character 'h': s[1]; # cannot use index notation on string literal | // the character h: "hello"[1] | ||

chr and ord | CharInt(65) IntChar('A') | Strchr([65]) Vecsmall("A") | ||

delete characters | s := "disemvowel me"; # no retval; modifies s in place: RemoveCharacters(s, "aeiou"); | |||

arrays | ||||

magma | gap | singular | pari/gp | |

literal | a := [1, 2, 3]; | [1, 2, 3]; # creates array with gap at fourth index; # reading a[4] causes an error: a := [1, 2, 3, , 5]; | list a= 1, 2, 3; list a = list(1, 2, 3); // Singular lists are fixed length. | \\ [1, 2, 3] is a vector literal: List([1, 2, 3]) |

size | # [1, 2, 3]; | Length([1, 2, 3]); | size(a); | length(List([1, 2, 3])) #List([1, 2, 3]) |

lookup | // indices start at one: [6, 7, 8][1]; | # indices start at one: a := [1, 2, 3]; a[1]; | // indices start at one: a[1]; | \\ access time is O(1). \\ indices start at one: List([1, 2, 3])[1] |

update | a[1] := 7; | a[1] := 7; | a[1] = 7; | listput(a, 7, 1) |

out-of-bounds behavior | Runtime error on lookup.For update, size of array is increased if necessary; runtime error to look up unassigned slot in between assigned slots. | Lookups result in errors; arrays can have gaps which also cause lookup errors.An update will expand the array, possibly creating gaps. | error | out of allowed range error |

element index | # returns 3: Position([7, 8, 9, 9], 9); # returns [3, 4]: Positions([7, 8, 9, 9], 9); | none | ||

slice | none | |||

array of integers as index | none | |||

manipulate back | a := [6, 7, 8]; // a not modified: a2 := Append(a, 9); // a2 not modified: a3 := Prune(a2); // a modified: Append(~a, 9); Prune(~a); | a = [6, 7, 8]; Add(a, 9); elem := Remove(a); | list a = list(6, 7, 8); list a2 = insert(a, 9, size(a)); int popme = a2[size(a2)]; list a3 = delete(a2, size(a2)); | a = List([6, 7, 8]) listput(a, 9) elem = listpop(a) |

manipulate front | a = List([6, 7, 8]); listinsert(a, 5, 1); elem = a[1]; listpop(a, 1); | |||

head | List([1, 2, 3])[1] | |||

tail | none | |||

cons | a = List([1, 2, 3]); listinsert(a, 1, 1); | |||

concatenate | Concatenation([1, 2, 3], [4, 5, 6]); | list a1 = 1, 2, 3; list a2 = 4, 5, 6; list a3 = a1 + a2; | concat(List([1, 2, 3]), List([4, 5, 6])) | |

replicate | ||||

copy | a2 = a | |||

iterate | Perform([1, 2, 3], function(x) Print(x); Print("\n"); end); | a = List([1, 2, 3]) for(i=1, length(a), print(a[i])) | ||

reverse | Reversed([1, 2, 3]) | a = List([1, 2, 3]) a2 = listcreate() while(i > 0, listput(a2, a[i]); i—) | ||

sort | A := [3, 1, 4, 2] Sort(A); | a = List([3,1,4,2]) listsort(a) a | ||

dedupe | Set([1, 2, 2, 3]); Unique([1, 2, 2, 3]); | Set([1, 2, 2, 3]) | ||

membership | 2 in [1, 2, 3] | \\ returns 1-based index of first occurrence \\ or 0 if not found: setsearch([1, 2, 3], 2) | ||

intersection | Intersection(Set([1, 2]), Set([2, 3, 4])); | setintersect([1, 2], [2, 3, 4]) | ||

union | Union(Set([1, 2]), Set([2, 3, 4])); | setunion([1, 2], [2, 3, 4]) | ||

relative complement, symmetric difference | setminus([1, 2, 3], [2])?? | |||

map | A := [1, 2, 3]; # modifies A: Apply(A, x -> x * x); | apply(x -> x * x, [1, 2, 3]) | ||

filter | select(x -> x > 2, [1, 2, 3]) | |||

reduce | ||||

universal and existential tests | ||||

min and max element | Minimum([1, 2, 3]) Maximum([1, 2, 3]) | vecmin([1, 2, 3]) vecmax([1, 2, 3]) | ||

shuffle and sample | Shuffle([1, 2, 3, 4]) | |||

flattenone level, completely | # completely: Flat([1, [2, [3, 4]]]) | |||

zip | ||||

cartesian product | Cartesian([1, 2, 3], ["a", "b", "c"]) | |||

sets | ||||

magma | gap | singular | pari/gp | |

literal | {1, 2, 3}; | |||

size | # {1, 2, 3}; | |||

add element | s := {1, 2, 3}; Inlude(~s, 4); | |||

remove element | s := {1, 2, 3}; Exclude(~s, 1); | |||

membership test | 7 in {6, 7, 8}; | |||

disjoint test | IsDisjoint({1, 2, 3}, {2, 3, 4}); | |||

union | // {1, 2, 3, 4}: s := {1, 2, 3} join {2, 3, 4}; | |||

intersection | // {2, 3}: s := {1, 2, 3} meet {2, 3, 4}; | |||

relative complement | // {1}: s := {1, 2, 3} diff {2, 3, 4}; | |||

arithmetic sequences | ||||

magma | gap | singular | pari/gp | |

unit difference | [1 .. 100]; | [1 .. 100] | [1 .. 100] vector(100, i, i) | |

difference of 10 | [1 .. 100 by 10]; | [1,11 .. 91] | vector(10, i, 10 * i - 9) | |

difference of 0.1 | [0.1 * i: i in [1 .. 1000]]; | none | vector(1000 - 9, i, i / 10 + 9 / 10) | |

dictionaries | ||||

magma | gap | singular | pari/gp | |

literal | // None, just empty constructor: d := AssociativeArray(); d["t"] := 1; d["f"] := 0; | # dictionary constructor; type of keys derived # from first arg: d := NewDictionary("", true); AddDictionary(d, "t", 1); AddDictionary(d, "f", 0); # record literal with identifier keys: r := rec(t := 1, f := 0); # record literal with string keys: r2 := rec(("t") := 1, ("f") := 0); | ||

size | # d; | # no way to get size of dictionary? Length(RecNames(r)); | ||

lookup | d["t"]; | LookupDictionary(d, "t"); # the same key can be looked up with identifier # or string notation: r.t; r.("t"); | ||

update | d["f"] := -1; | AddDictionary(d, "f", -1); r.f := -1; r2.("f") := -1; | ||

missing key behavior | Runtime error | # returns special object "fail": LookupDictionary(d, "not_a_key"); # raises an error: r.not_a_key; | ||

is key present | IsDefined(d, "t"); | KnowsDictionary(d, "t"); # RecNames returns keys as strings: "t" in RecNames(r); | ||

delete | Remove(~d, "t"); | |||

iterate | # no way to iterate over dictionary? for i in RecNames(r) do Print(r.(i)); od; | |||

keys and values as arrays | Keys(d);?? | RecNames(r); | ||

functions | ||||

magma | gap | singular | pari/gp | |

define function | add := function(a, b) return a + b; end function; // no return value: show := procedure(s) print(s); end procedure; | add := function(x, y) return x + y; end; | proc add(int x, int y) { return(x + y); } | add(x, y) = x + y \\ function body w/ sequence of statements: say(s1, s2, s3) = print(s1); print(s2); print(s3) \\ function body w/ newlines: dire(s1, s2, s3) = { print(s1); print(s2); print(s3); } |

invoke function | add(3, 7); | add(3, 7); | add(3, 7); | add(3, 7) |

undefine function | kill(add) | |||

redefine function | add(x, y, z) = x + y + z | |||

overload function | none | |||

missing function behavior | "not a function" error | |||

missing argument behavior | set to zero | |||

extra argument behavior | "too many parameters" error | |||

default argument | mylog(x = 1, base = 10) = log(x) / log(base) \\ log10(3): mylog(3) \\ ln(3): mylog(3, exp(1)) \\ ln(1): mylog(, exp(1)) \\ If neither caller nor function definition \\ provide a value, zero is used. | |||

return value | ||||

anonymous function | # unary functions only? f := x -> x * x; f2 := function(x, y) return 2 * x + 3 * y; end; | f = (x, y) -> x + y f(1, 2) | ||

variable number of arguments | ||||

pass array elements as separate arguments | ||||

execution control | ||||

magma | gap | singular | pari/gp | |

if | if n gt 0 then print "positive"; else if n lt 0 then print "negative"; else print "zero"; end if; end if; | if x > 0 then Print("positive\n"); elif x < 0 then Print("negative\n"); else Print("zero\n"); fi; | int x = -3; if (x > 0) { print("positive"); } else { if (x < 0) { print("negative"); } else { print("zero"); } }; | if(x > 0, \ print("positive"), \ if(x < 0, \ print("negative"), \ print("zero"))) |

while | i := 0; while i lt 10 do print i; i := i + 1; end while; | i := 0; while i < 10 do Print(i, "\n"); i := i + 1; od; | int i = 0; while (i < 10) { print(i); i++; }; | i = 0 while(i < 10, print(i); i++) |

for | for i := 0 to 9 by 1 do print i; end for; | for i in [0..9] do Print(i, "\n"); od; | int i; for (i = 0; i < 10; i++) { print(i); }; | for(i = 0, 9, print(i)) |

break | break | break | break | |

continue | continue | continue | next | |

exceptions | ||||

magma | gap | singular | pari/gp | |

raise exception | error "failed"; | Error("failed"); | error("failed") | |

handle exception | try error "failed"; catch e print "caught error"; end try; | iferr(error("failed"), E, \ print(errname(E), ": ", component(E, 1))) | ||

uncaught exception behavior | Error() invokes the GAP debugger. TypeQuit; to return to REPL. | |||

streams | ||||

magma | gap | singular | pari/gp | |

write line to stdout | print "hello"; | Print("hello"); | print("hello"); | print("hello") |

read file into array of strings | a = readstr("/etc/hosts") | |||

processes and environment | ||||

magma | gap | singular | pari/gp | |

environment variable | getenv("HOME") | |||

[[#external-cmd]]external command | system("ls /etc") | |||

command substitution | \\ array of output lines: lines = externstr("ls /etc") | |||

libraries and namespaces | ||||

magma | gap | singular | pari/gp | |

load library | Read('foo.g'); | LIB "add.sing"; | ||

define library | $ cat add.sing version="1.0" category="misc" info="an add function" proc add(int x, int y) { return(x + y); } | |||

library path | Searches current directory; additional directories can be added to the search path by adding them separated by colons to the/ SINGULARPATH //environment variable. | |||

reflection | ||||

magma | gap | singular | pari/gp | |

list function documentation | ? | |||

get function documentation | help killall; | ? tan | ||

query data type | Type(x); | typeof(x); | type(x) | |

list types | \t | |||

list variables in scope | listvar(); | variable() | ||

list built-in functions | ?* | |||

list metacommands | ?\ | |||

search documentation | ??DirectProduct | ??? modulus | ||

vectors | ||||

magma | gap | singular | pari/gp | |

vector literal | # row vector is same as array: [1, 2, 3] | // A ring must be declared. The elements of the vector are not // limited to the coefficient field, but can be any element of // the ring. ring r = read, (x), dp; vector v= [1.5, 3.2, 7.1]; | [1, 2, 3] | |

constant vectorall zeros, all ones | vector(100, i, 0) vector(100, i, 1) | |||

vector coordinate | vec := [1, 2, 3]; # indices start at one: v[1]; | v[1]; | \\ indices start at one: [1, 2, 3][1] | |

vector dimension | Length([1, 2, 3]) | nrows(v); | length([1, 2, 3]) #[1, 2, 3] | |

element-wise arithmetic operators | + - * / | + - | + - | |

vector length mismatch | shorter vector is zero-padded | shorter vector is zero-padded | error | |

scalar multiplication | 3 * [1, 2, 3]; [1, 2, 3] * 3; | 3 * v; v * 3; // Scalar can be any ring element: (1 + x) * v; | 3 * [1, 2, 3] [1, 2, 3] * 3 | |

dot product | [1, 1, 1] * [2, 2, 2] | [1, 1, 1] * [2, 2, 2] ~ | ||

cross product | ||||

norms | vec = [1, 2, 3] normlp(vec, 1) normlp(vec, 2) normlp(vec) | |||

orthonormal basis | ||||

matrices | ||||

magma | gap | singular | pari/gp | |

literal | [[1, 2], [3, 4]] | // A ring must be declared. The elements of the matrix are not // limited to the coefficient field, but can be any element of // the ring. ring r = read, (x), dp; matrix m[2][2] = 1, 2, 3, 4; | [1, 2; 3, 4] \\ from rows: row1 = [1, 2] row2 = [3, 4] matconcat([row1; row2]) | |

construct from columns | col1 = [1, 3]~ col2 = [2, 4]~ matconcat([col1, col2]) | |||

construct from submatrices | A = [1, 2; 3, 4] B = [4, 3; 2, 1] \\ 4x4 matrix: C = matconcat([A, B; B, A]) | |||

constant matrices | matrix(3, 3, i, j, 0) matrix(3, 3, i, j, 1) \\ 3x3 Hilbert matrix: matrix(3, 3, i, j, 1 / (i + j - 1)) | |||

diagonal matricesand identity | DiagonalMat([1, 2, 3]) IdentityMat(3) | matdiagonal([1, 2, 3]) matid(3) | ||

dimensions | # returns [3, 2]: DimensionsMat([[1, 2], [3, 4], [5, 6]]) | nrows(m); ncols(m); | \\ [3, 2]: matsize([1, 2; 3, 4; 5, 6]) | |

element lookup | A := [[1, 2], [3, 4]]; # top left corner: A[1][1] | matrix m[2][2] = 1, 2, 3, 4; m[1][1]; | \\ top left corner: A[1, 1] | |

extract row | \\ first row: [1, 2; 3, 4][1, ] | |||

extract column | \\ first column: [1, 2; 3, 4][, 1] | |||

extract submatrix | A = [1, 2, 3; 4, 5, 6; 7, 8, 9] vecextract(A, "1..2", "1..2") | |||

element-wise operators | + - | + - | + - | |

product | A := [[1, 2], [3, 4]]; B := [[4, 3], [2, 1]]; A * B; | matrix m[2][2] = 1, 2, 3, 4; matrix m2[2][2] = 4, 3, 2, 1; m * m2; | A = [1, 2; 3, 4] B = [4, 3; 2, 1] A * B | |

power | [[1, 2], [3, 4]] ^ 3 | [1, 2; 3, 4] ^ 3 | ||

exponential | ||||

log | ||||

kronecker product | A := [[1, 2], [3, 4]]; B := [[4, 3], [2, 1]]; KroneckerProduct(A, B); | |||

norms | ||||

transpose | A~ mattranspose(A) | |||

conjugate transpose | conj([1, I; 2, -I] ~) | |||

inverse | Inverse([[1, 2], [3, 4]]) | [1, 2; 3, 4] ^ -1 1 / [1, 2; 3, 4] | ||

row echelon form | ||||

pseudoinverse | ||||

determinant | Determinant([[1, 2], [3, 4]]) | matrix m[2][2] = 1, 2, 3, 4; det(m); | matdet([1, 2; 3, 4]) | |

trace | Trace([[1, 2], [3, 4]]) | matrix m[2][2] = 1, 2, 3, 4; trace(m); | trace([1, 2; 3, 4]) | |

rank | RankMat([[1, 1], [0, 0]]) | matrank([1, 1; 0, 0]) | ||

nullspace basis | matker([1, 1; 0, 0]) | |||

range basis | matimage([1, 1; 0, 0]) | |||

eigenvalues | [vals, vecs] = mateigen([1, 2; 3, 4], flag=1) | |||

eigenvectors | mateigen([1, 2; 3, 4]) | |||

singular value decomposition | ||||

qr decomposition | matqr([1, 2; 3, 4]) | |||

solve system of equations | A = [1, 2; 3, 4] matsolve(A, [2, 3]~) | |||

combinatorics | ||||

magma | gap | singular | pari/gp | |

factorial | Factorial(10); | Factorial(10); | LIB "general.lib"; factorial(10); | 10! |

binomial coefficient | Binomial(10, 3); | Binomial(10, 3); | LIB "general.lib"; binomial(10, 3); | binomial(10, 3) |

multinomial coefficient | Multinomial(12, [3, 4, 5]); | |||

integer partitionsand count | Partitions(10); NumberOfPartitions(10); | Partitions(10); NrPartitions(10); | partitions(10) length(partitions(10)) | |

set partitionsand Bell number | StirlingSecond(10, 3); Bell(10); | stirling(10, 3, 2) sum(i=1, 10, stirling(10, i, 2)) | ||

permutations with k disjoint cycles | Abs(StirlingFirst(n, k)); | abs(stirling(n, k, 1)) | ||

fibonacci numberand lucas number | Fibonacci(10); Lucas(10); | fibonacci(10) | ||

bernoulli number | BernoulliNumber(100); | bernfrac(100) | ||

catalan number | Catalan(10); | |||

number theory | ||||

magma | gap | singular | pari/gp | |

pseudoprime test | IsProbablyPrime(7); | IsPrimeInt(7); | ispseudoprime(7) | |

true prime test | IsPrime(7); | isprime(7) | ||

divisors | // [1, 2, 4, 5, 10, 20, 25, 50, 100]: Divisors(100); | DivisorsInt(100); | divisors(100) | |

prime factors | // [2, 3, 7]: PrimeDivisors(84); | # [ 2, 2, 3, 7 ]: FactorsInt(84); | \\ [2,2; 3,1; 7,1]: factor(84) | |

next primeand preceding | NextPrime(1000); PreviousPrime(1000); | NextPrimeInt(1000); PrevPrimeInt(1000); | ?prime(1000); | nextprime(1000) precprime(1000) |

nth prime | NthPrime(100); | \\ first 100 primes: primes(100) primes(100)[100] | ||

prime counting function | LIB "general.lib"; size(primes(1, 100)); | primepi(100) | ||

divmod | divrem(7, 3) | |||

greatest common divisorand relatively prime test | Gcd(14, 21); Gcd(Gcd(14, 21), 777); | GcdInt(14, 21); GcdInt(GcdInt(14, 21), 777); | gcd(14, 21) gcd(gcd(14, 21), 777) | |

extended euclidean algorithm | ret := Gcdex(3, 5); # 2: ret.coeff1; # -1: ret.coeff2; # 1: ret.gcd; | \\ [2, -1, 1]: gcdext(3, 5) | ||

least common multiple | Lcm(14, 21); | LcmInt(14, 21); | lcm(14, 21) | |

integer residues | r := ZmodnZ(5); fam := ElementsFamily(FamilyObj(r));; ZmodnZObj(fam, 2) + ZmodnZObj(fam, 3); | Mod(2, 5) + Mod(3, 5) Mod(2, 5) - Mod(3, 5) Mod(2, 5) * Mod(3, 5) Mod(2, 5)^2 | ||

multiplicative inverse | r := ZmodnZ(7); fam := ElementsFamily(FamilyObj(r));; ZmodnZObj(2, 7)^-1; | Mod(2, 7)^-1 \\ raises error: Mod(2, 4)^-1 | ||

chinese remainder theorem | # 173: ChineseRem([17, 11], [3, 8]); | \\ Mod(173, 187): chinese(Mod(3, 17), Mod(8, 11)) | ||

lift integer residue | \\ 7: lift(-17, 12) \\ -5: centerlift(-17, 12) | |||

euler totient | Phi(256); | eulerphi(256) | ||

multiplicative order | OrderMod(7, 108); | znorder(Mod(7, 108)) | ||

primitive roots | PrimitiveRootMod(11); | znprimroot(11) | ||

discrete logarithm | # arg: 10, base: 2, modulus: 11 LogMod(10, 2, 11); | znlog(10, Mod(2, 11)) znlog(Mod(10, 11), Mod(2, 11)) | ||

carmichael function | Lambda(561); | lcm(znstar(561)[2]) | ||

kronecker symboland jacobi symbol | Jacobi(3, 5); | kronecker(3, 5) | ||

moebius function | MoebiusMu(11); | MoebiusMu(11); | moebius(11) | |

riemann zeta function | zeta(2) | |||

mangoldt lambda | ||||

dirichlet character | ||||

elliptic curves | ||||

magma | gap | singular | pari/gp | |

elliptic curve from coefficients | \\ ellinit([a, b, c, d, e]) where \\ \\ y^2 + axy + by = x^3 + cx^2 + dx + e \\ e0 = ellinit([0,0,1,-7,6]) \\ ellinit([a, b]) where \\ \\ y^2 = x^3 + ax + b \\ e1 = ellinit([-1, 0]) | |||

discriminant | e0.disc | |||

conductor | ellglobalred(e0)[1] | |||

singularity test | e0.disc == 0 | |||

convert to minimal model | e0 = ellinit([6, -3, 9, -16, -14]) e = ellminimalmodel(e0) | |||

coordinate transformation on point | e0 = ellinit([6, -3, 9, -16, -14]) e = ellminimalmodel(e0, &v) \\ minimal to original: ellchangepointinv([0, 0], v) \\ original to minimal: ellchangepoint([-2, 2], v) | |||

coordinate transformation on curve: ellchangecurve | e0 = ellinit([6, -3, 9, -16, -14]) e = ellminimalmodel(e0, &v) \\ same as e0: ellchangecurve(e, v) | |||

point on curve test | ellisoncurve(e, [0, 2]) | |||

abscissa to ordinates | \\ vector of size 0, 1, or 2: ellordinate(e, 0) | |||

group identity | [0] | |||

group operation | elladd(e, [0, 2], [1, -1]) | |||

group inverse | ellneg(e, [0, 2]) | |||

group multiplication | ellmul(e, [0, 2], 3) | |||

canonical height of point | ellheight(e, [0, -3]) | |||

order of point | \\ returns 0 for infinite order: ellorder(e, [0, 2]) ellorder(e1, [0, 0]) | |||

torsion subgroup | e1 = ellinit([-1, 0]) \\ returns [t, v1, v2]: \\ \\ t: order of torsion group \\ v1: orders of component cyclic groups \\ v2: generators of same cyclic groups \\ elltors(e1) | |||

analytic rank | \\ first value is rank: [a, b] = ellanalyticrank(e) \\ recompute second value to higher precision: \p 100 b = ellL1(e, a) | |||

L-function value | elllseries(e, 1 + I) | |||

L-function coefficients | \\ tenth coefficient: ellak(e, 10) \\ first ten coefficients: ellan(e, 10) | |||

rational and algebraic numbers | ||||

magma | gap | singular | pari/gp | |

to continued fraction | \p 100 contfrac(Pi) | |||

from continued fraction | ||||

p-adic number | \\ p is 2 and precision in powers of 2 is 100: 1/2 + O(2^100) | |||

lift p-adic to rational | lift(1/2 + O(2^100)) | |||

gaussian integer norm | norm(1 + I) | |||

quadratic extension | \\ make w equal to sqrt(D)/4: D = -4 w = quadgen(D) | |||

quadratic number | (1 + w)^2 | |||

polynomials | ||||

magma | gap | singular | pari/gp | |

from expression with indeterminates | // A ring must be declared before a polynomial can be defined. // To define a ring, one specifies (1) the coefficient field // (or ring), (2) the indeterminate variables, and (3) the term // ordering. ring r = integer, (x, y), dp; poly p1 = (x - 1) * (x - 2); poly p2 = (1 + x)^2 * (2 + y)^3; | (x - 1) * (x - 2) (1+x)^2 * (2+y)^3 | ||

from coefficient array | Pol([1, -3, 2]) @@\\@ zero-degree coefficient first: Polrev([2, -3, 1]) | |||

to coefficient array | poly p = (1 + x)^10; coeffs(p, x); | Vec((x+1)^10) | ||

lookup coefficient | polcoeff((x+1)^10, 3) | |||

substitute indeterminate | subst((x - 1) * (x - 2), x, 3); subst((x - 1) * (x - 2), x, (x - 1)); | \\ replace x with 3: subst((x-1)*(x-2), x, 3) \\ replace x with (x-1): subst((x-1)*(x-2), x, (x-1)) | ||

degree | poly p = (1 + x)^10; deg(p); | poldegree((x-1)^10) | ||

operations | + - * / | |||

division and remainder | ||||

expand polynomial | Polynomials are displayed in expanded form. | |||

factor polynomial | ring r = 7, (x), dp; // Doesn't work in ring with real or int. coefficients: factorize(x^2 + 3*x + 2); | |||

collect terms | ring r = integer, (x, y), dp; coeffs((x + 2*y + 1)^10, x); | |||

factor | factor(x^2-1) | |||

roots | polroots(x^3+3*x^2+2*x-1) | |||

greatest common divisor | p1 = x^3 + 2*x^2 -x -2 p2 = x^3 -7*x + 6 gcd(p1, p2) | |||

resultant | polresultant((x-1)*(x-2), (x-3)^2) | |||

discriminant | poldisc((x+1)*(x-2)) | |||

homogenity test | homog((x + y)^2); | |||

groebner basis | none | |||

specify ordering | none | |||

symmetric polynomial | none | |||

cyclotomic polynomial | polcyclo(10) | |||

hermite polynomial | polhermite(4) | |||

chebyshev polynomialfirst and second kind | polchebyshev(4, 1) polychebyshev(4, 2) | |||

interpolation polynomial | polinterpolate([1, 2, 3], [2, 4, 7]) | |||

characteristic polynomial | charpoly([1, 2; 3, 4]) | |||

minimal polynomial | ||||

piecewise polynomial | ||||

rational function | (x - 1) / (x - 2)^2 | |||

add fractions | ||||

partial fraction decomposition | ||||

special functions | ||||

magma | gap | singular | pari/gp | |

gamma | gamma(1/2) | |||

hyperbolic | sinh cosh tanh | |||

elliptic integerals | ||||

bessel functions | besselh1 besselh2 besseli besselj besseljh besselk besseln | |||

Riemann zeta | zeta(2) | |||

permutations | ||||

magma | gap | singular | pari/gp | |

permutation from disjoint cycles | S4 := Sym(4); p := S4!(1, 2)(3, 4); | p := (1, 2)(3, 4); | ||

permutation from list | S4 := Sym(4); p2 := elt<S4 | 2, 1, 4, 3>; | p2 := PermList([2, 1, 4, 3]); | ||

permutation from two lists | # must be positive integers: p := MappingPermListList([6, 8, 4, 2], [2, 4, 6, 8]) | |||

act on element | 1 ^ p; # preimage of 1 under p: 1 / p; | |||

act on list | ||||

compose | S4 := Sym(4); S4!(1,2)(3,4) * S4!(1,3); | (1, 2)(3, 4) * (1, 3); | ||

invert | S3 := Sym(3); S3!(1,2,3) ^ -1; Inverse(S3!(1,2,3)); | (1, 2, 3) ^ -1; | ||

power | S5 := Sym(5); S5!(1,2,3,4,5) ^ 3; | (1, 2, 3, 4, 5) ^ 3; | ||

order | S3 := Sym(3); Order(S3!(1,2,3)); | Order((1, 2, 3)); | ||

support | MovedPoints((1, 3, 5)(7, 8)); | |||

number of inversions | ||||

parity | ||||

to inversion vector | ||||

from inversion vector | ||||

all permutations | ||||

random permutation | ||||

groups | ||||

magma | gap | singular | pari/gp | |

named groupssymmetric, alternating, cyclic, dihedral | S4 := Sym(4); A4 := AlternatingGroup(4); Z5 := CyclicGroup(5); D10 := DihedralGroup(10); | S4 := SymmetricGroup(4); A4 := AlternatingGroup(4); Z5 := CyclicGroup(5); # argument is order of group, not vertices # of polygon: D10 := DihedralGroup(2 * 10); | ||

group by order | NumberOfSmallGroups(8); // first group of order 8: G := SmallGroup(8, 1); | # number of groups of order 8: Length(AllSmallGroups(8)); # first group of order 8: G := AllSmallGroups(8)[1]; | ||

group from permutation generators | S5 := Sym(5); p1 := S5!(1, 3, 5, 2); p2 := S5!(1, 2); G := PermutationGroup<5 | p1, p2>; | G := Group((1, 3, 5, 2), (1, 2)); # or G := GroupWithGenerators([(1, 3, 5, 2), (1, 2)]); | ||

direct product | Z3 := CyclicGroup(3); A4 := AlternatingGroup(4); G := DirectProduct(z3, a4); | Z3 := CyclicGroup(3); A4 := AlternatingGroup(4); G := DirectProduct(Z3, A4); | ||

free product | F := FreeProduct(CyclicGroup(3), CyclicGroup(2)); | |||

free group | # integers under addition: Z := FreeGroup(1); # free group with 2 generators: F := FreeGroup("a", "b"); | |||

group from presentation | F := FreeGroup( "a", "b" ); G := F / [ F.1^2, F.2^3, (F.1 * F.2)^5 ]; | |||

all elements | Perform(Enumerator(Z3), function(e) Print(e); Print("\n"); end); | |||

generators | S10 := Sym(10); Generators(s10); // notation for individual generators: S10.1; S10.2; | S10 := SymmetricGroup(10); # return generators in an array: GeneratorsOfGroup(S10); # notation for individual generators: S10.1; S10.2; | ||

identity element | Id(G); | Identity(G); One(G); | ||

random element | Random(G); | Random(G) | ||

group operation | e1 := Random(G); e2 := Random(G); e1 * e2; | e1 := Random(G); e2 := Random(G); e1 * e2; | ||

inverse element | Inverse(e1); // or: e1 ^ -1; | Inverse(e1); # or: e1^-1; | ||

generator word for element | S10 := SymmetricGroup(10); Factorization(S10, (1,3,8,10,5,9,2,7)); | |||

elements by generator word length | S6 := SymmetricGroup(6); GrowthFunctionOfGroup(S6); | |||

element order | D10 := DihedralGroup(10); Order(D10.1); Order(D10.2); | D10 := DihedralGroup(2 * 10); Order(D10.1); Order(D10.2); | ||

identify group | // C2*C4: GroupName(SmallGroup(8, 2)); // <8, 1>: IdentifyGroup(CyclicGroup(8)); | # C4 x C2: StructureDescription(AllSmallGroups(8)[2]); | ||

group to presentation | FPGroup(AlternatingGroup(10)); | |||

group order | Order(Sym(4)); | Size(SymmetricGroup(4)); | ||

cyclic test | IsCyclic(AlternatingGroup(10)); | IsCyclic(AlternatingGroup(10)); | ||

abelian test | IsAbelian(CyclicGroup(10)); | IsAbelian(CyclicGroup(10)); | ||

subgroups | ||||

magma | gap | singular | pari/gp | |

all subgroups | Subgroups(Sym(4)); | AllSubgroups(SymmetricGroup(4)); | ||

subgroup lattice | SubgroupLattice(Sym(4)); | S4 := SymmetricGroup(4); lat := LatticeSubgroups(S4); DotFileLatticeSubgroups(lat, "lattice.dot"); # dot -Tpng < lattice.dot > lattice.png | ||

maximal subgroups | MaximalSubgroups(Sym(4)); | MaximalSubgroups(S4); | ||

frattini subgroup | D4 := DihedralGroup(4); FrattiniSubgroup(D4); | FrattiniSubgroup(DihedralGroup(2 * 4)); | ||

subgroup from generators | G := Group((1, 3, 5, 7), (2, 4)); H := Subgroup(G, [(2, 4)]); | |||

normal subgroups | NormalSubgroups(Sym(4)); | NormalSubgroups(S4); | ||

cosets | RightCoset() CanonicalRightCosetElement() CosetDecomposition() RightTraversal(G, U) | |||

quotient group | ||||

center | Z4 := CyclicGroup(4); D6 := DihedralGroup(6); G := DirectProduct(Z4, D6); center := Centre(G); | g := DirectProduct(CyclicGroup(4), DihedralGroup(2 * 6)); Center(g); | ||

centralizer | g := SymmetricGroup(5); h := Centralizer(g, (1, 3)(4, 5)); | |||

normalizer | S4 := SymmetricGroup(4); G := Group([(1,2)(3,4)]); Normalizer(S4, G); | |||

commutator | # e1^-1 * e2^-1 * e1 * e2: Comm(e1, e2); | |||

commutator subgroup | G1 := Group((1,2,3),(1,2)); G2 := Group((2,3,4),(3,4)); CommutatorSubgroup(G1, G2); | |||

subgroup test | ||||

subgroup index | Index(Sym(4), AlternatingGroup(4)); | Index(G, H); | ||

normal test | IsNormal(G, H); | |||

subnormal test | IsSubnormal(G, H); | |||

nonabelian simple groups | # argument is list of orders: AllSmallNonabelianSimpleGroups([1..10000]); | |||

simple test | IsSimple(SymmetricGroup(4)); | |||

solvable test | IsSolvable(SymmetricGroup(4)); | |||

derived series | DerivedSeriesOfGroup(SymmetricGroup(4)); | |||

characteristic test | S4 := SymmetricGroup(4); H := Subgroup(s4, [(1,4)(2,3), (1,3)(2,4), (2,4,3)]); IsCharacteristicSubgroup(S4, H); | |||

semidirect product | ||||

group homomorphisms | ||||

magma | gap | singular | pari/gp | |

all homomorphisms | S4 := SymmetricGroup(4); S3 := SymmetricGroup(3); AllHomomorphisms(S3, S4); | |||

all homomorphims classes | AllHomomorphismClasses(S3, S4); | |||

endomorphisms and automorphisms | AllEndomorphisms(S4); AllAutomorphisms(S4); | |||

homomorphism from generator images | hom := GroupHomomorphismByImages(S3, S4, [(1,2,3), (1,2)], [(2,3,4), (2,3)]); # uses generators of S3: hom := GroupHomomorphismByImages(S3, S4, [(2,3,4), (2,3)]); | |||

surjective test | IsSurjective(hom); | |||

injective test | IsInjective(hom); | |||

bijective test | IsBijective(hom); | |||

kernel | Kernel(AllHomomorphisms(S3, S4)[1]); | |||

image | Image(AllHomomorphisms(S3, S4)[1]); | |||

actions | ||||

magma | gap | singular | pari/gp | |

conjugate element | # (1,2,3)^-1 * (1,2) * (1,2,3): (1,2)^(1,2,3) | |||

conjugate set | S3 := SymmetricGroup(3); S3^(3,4); (3,4)^S3; | |||

conjugacy class | S4 := SymmetricGroup(4); AsList(ConjugacyClass(S4, (1,2,3))); | |||

conjugate group | ConjugateGroup(SymmetricGroup(4), (4, 5)); | |||

conjugacy classes | ConjugacyClasses(SymmetricGroup(4)); | |||

stabilizer | ||||

orbit | ||||

transitive test | ||||

_______________________________________________________ | _______________________________________________________ | _______________________________________________________ | _______________________________________________________ |

# Grammar and Invocation

# Variables and Expressions

# Arithmetic and Logic

# Strings

# Arrays

# Sets

# Arithmetic Sequences

# Dictionaries

# Functions

# Execution Control

# Exceptions

# Streams

# Processes and Environment

# Libraries and Namespaces

# Reflection

# Vectors

# Matrices

# Combinatorics

## factorial

*n!* is the product of the integers 1 through *n*.

*n!* is the number of permutations or bijections on a set of *n* elements.

## binomial coefficient

## multinomial coefficient

## integer partitions

The number of ways of writing a positive integer *n* as a sum of positive integers.

When counting integer partitions, *2 + 1* and *1 + 2* are not considered to be distinct ways of summing to 3. In other words, one is counting the multisets which sum to *n*.

## set partitions

## permutations with k disjoint cycles

## fibonacci number

## bernoulli number

## catalan number

# Number Theory

# Elliptic Curves

# Rational and Algebraic Numbers

# Polynomials

# Special Functions

# Permutations

# Groups

A *group* is a set G and a binary operator—written here as`*`—which takes elements of the set as operands and obeys the following axioms:

*Closure:*For every g and h in G, g * h is also in G.*Identity:*There exists e in G such that for all g in G, e * g = g * e = g.*Associativity:*For all f, g and h in G, (f * g) * h = f * (g * h).*Inverse:*For every g in G, there exists g' in G such that g * g' = g' * g = e.

*Abelian* groups obey an additional axiom:

*Commutativity:*For all g and h in G, g * h = h * g.

The *order* of a group is the number elements in the set. The smallest group is the *trivial group*, which contains a single element which is the identity. It has order 1.

The integers, rationals, real numbers, and complex numbers are Abelian groups under addition; zero is the identity element. The integers and rationals are countably infinite. The real numbers and complex numbers are uncountably infinite.

The integers modulo *n* are an Abelian group under addition; zero is the identity number. The group is finite and has order *n*.

The non-zero rationals, non-zero real numbers, and non-zero complex numbers are Abelian groups under multiplication; one is the identity element.

A permutation is a bijection on a set of *n* elements. The permutations of size *n* form a group under composition; the group is non-Abelian when *n > 2*. The identity permutation which maps each element of the set to itself is the group identity. The order of the group is *n*!.

The classical Lie groups are examples of infinite, non-Abelian groups. In all cases the group operation is matrix multiplication:

GL(n, ℝ) | general linear group of degree n | invertible n×n matrices |

SL(n, ℝ) | special linear group of degree n | n×n matrices with determinant one |

O(n, ℝ) | orthogonal group of degree n | n×n orthogonal matrices; i.e. MM^{T} = I |

SO(n, ℝ) | special orthogonal group of degree n | n×n orthogonal matrices with determinant one |

U(n, ℂ) | unitary group of degree n | n×n unitary matrices; i.e. MM* = I |

SU(n, ℂ) | special unitary group of degree n | n×n unitary matrices with determinant one |

## named groups

Some well-known groups can be specified by name.

The symmetric group S_{n} is the group of permutations on a set of *n* elements.

The alternating group A_{n} is the group of *even* permutations on a set of *n* elements.

The cyclic group Z/n is a group generated by a single element of order *n*. It is Abelian group and is isomorphic to the integers modulo *n* under addition.

The dihedral group D_{n} is the symmetry group of the regular n-polygon.

## group by order

## group from permutation generators

**gap:**

When a group is created using `GroupByGenerators`, the generators returned by `GeneratorsOfGroup` will not necessarily be the same as the generators provided to the constructor.

If the group is created using `GroupWithGenerators`, then the generators returned by `GeneratorsOfGroup` will be the same.

## direct product

The direct product is a group defined on the Cartesian product of two groups.

Given groups *G* and *H*, elements *g, g'* in *G*, and elements *h, h'* in *H*, the group operation is *(g, h) * (g', h') = (g * g', h * h')*.

## free product

A free product is group defined on equivalence classes of words consisting of elements from two groups *G* and *H*.

The equivalence relation is defined in terms of reductions. Two adjacent elements in the word from the same group can be replaced by their product, and the identity element of either group can be removed.

The group operation is concatenation.

The free product is an infinite group when both groups are non-trivial.

**gap**

Some functions do not appear to work on free products: `Order()` and `Random()`.

## free group

## group from presentation

## all elements

How to iterate through all elements in a group.

## generators

## identity element

The group identity *e*.

For all *g* in *G*, *e * g = g * e = g*.

## random element

How to select an element from the group randomly.

## group operation

How

## inverse element

Each element *g* in a group has an inverse *g ^{-1}* such that

*g * g*where

^{-1}= g^{-1}* g = e*e*is the identity element.

## commutator

## generator word for element

## elements by generator word length

## element order

For an element *g* in a finite group, there must be a positive integer *n* such that *g ^{n}* is the identity element. The order of an element is the smallest such

*n*.

## identify group

## group to presentation

Provide a presentation for the group.

## group order

How many elements are in the group.

## cyclic test

Is the group generated by single element.

## abelian test

Is the group operation commutative.

# Subroups

A *subgroup* is a subset of a group which is itself a group.

A nontrivial group always has at least two subgroups: the group itself and the trivial subgroup. A proper subgroup is a subgroup which is not equal to the group itself.

One test whether a subset *H* of a group *G* is a subgroup is verify that *H* is nonempty and for every *x* and *y* in *H*, *xy ^{-1}* is in

*H*.

*Lagrange's theorem and Sylow Theorems*

## all subgroups

A list of all subgroups in a group.

## subgroup lattice

The subgroups arranged by inclusion in a lattice.

## maximal subgroups

A maximal subgroup is a proper subgroup which is not contained in any other proper subgroup.

## frattini subgroup

The Frattini subgroup is the intersection of all maximal subgroups.

## subgroup from generators

**gap:**

`ClosureGroup` finds the smallest group containing a group and a list of elements, some of which might not be in the group which is the first argument.

## normal subgroups

The normal subgroups of a group.

A subgroup *H* of a group *G* is normal if its left and right cosets coincide. That is *gH = Hg* for all *g* in *G*. Another way to express this is that *H* is invariant under conjugation, or that *H = g ^{-1}Hg* for all

*g*in

*G*.

The significance of normal subgroups is that we can define a group operation on the cosets using representatives if and only if the subgroup is normal.

The first group isomorphism theorem states that the kernel of a group homomorphism is a normal subgroup.

For *n ≥ 5*, the only proper non-trivial normal subgroup of *S _{n}* is

*A*.

_{n}# Group Homomorphisms

A *homomorphism* is a function φ from (G, *) to (H, *') such that

- φ(x * y) = φ(x) *' φ(y) for all x, y ∈ G.

An *isomorphism* is a bijective *homomorphism*.

If an isomorphism exists between two groups, they are said to be *isomorphic*. Isomorphic groups are in a sense the same; group theory is the study of properties which are invariant under isomorphism. Elsewhere we may speak of two isomorphic groups as being the same group.

# Actions

A group G is said to *act* on a set A if there is an operation ⋅: G × A → A such that

- g₁⋅(g₂⋅a) = (g₁*g₂)⋅a for all g₁, g₂ ∈ G and a ∈ A
- e⋅a = a for all a ∈ A where e is the identity in A

# Magma

# GAP

# Singular

# Pari/GP

A Tutorial for Pari/GP (pdf)

Pari/GP Functions by Category

Pari/GP Reference Card (pdf)