diff --git a/Project.toml b/Project.toml index a94c91f..eb4f4e0 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "LinearAlgebraX" uuid = "9b3f67b0-2d00-526e-9884-9e4938f8fb88" -version = "0.2.8" +version = "0.2.9" [deps] LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" diff --git a/README.md b/README.md index a7637c5..0c5c09b 100644 --- a/README.md +++ b/README.md @@ -29,15 +29,15 @@ For exact types (such as `Int`s) these functions give exact results. * `char_poly` -- characteristic polynomial * `permanent` -- permanent of a square matrix -## Examples +Examples follow. -### Determinant +## Determinant ``` julia> A = ones(Int,10,10)+eye(Int,10); julia> det(A) -11.000000000000004 +10.999999999999998 julia> detx(A) 11 @@ -75,7 +75,7 @@ Mod{10}(4) -### Nullspace +## Nullspace ``` julia> A = reshape(collect(1:12),3,4) @@ -99,7 +99,7 @@ julia> nullspace(A) -0.519821 0.172585 ``` -### Rank +## Rank Consider the 12-by-12 Hibert matrix, `H` (see `hilbert.jl` in the `extras` folder): ``` @@ -127,7 +127,7 @@ julia> rankx(H) 12 ``` -### Inverse +## Inverse ``` julia> using Mods @@ -157,7 +157,7 @@ julia> A*B Mod{11}(0) Mod{11}(0) Mod{11}(0) Mod{11}(0) Mod{11}(1) ``` - ### Characteristic polynomial + ## Characteristic polynomial ``` julia> using SimplePolynomials, LinearAlgebra @@ -195,7 +195,7 @@ julia> detx(A) Mod{17}(1) ``` - ### Row reduced echelon form + ## Row reduced echelon form ``` julia> A = rand(Int,4,6) .% 10 @@ -265,7 +265,7 @@ julia> Vector(v) ``` However, entries cannot be assigned: ``` -ulia> v[2] = 3//4 +julia> v[2] = 3//4 ERROR: MethodError: no method matching setindex!(::HVector{Rational{Int64}}, ::Rational{Int64}, ::Int64) ``` @@ -332,5 +332,5 @@ julia> Matrix(ans) 0//1 4//3 -1//1 -1//3 -4//3 2//3 -1//1 0//1 1//1 - ``` +``` diff --git a/docs/build/.documenter-siteinfo.json b/docs/build/.documenter-siteinfo.json index e280513..c675f40 100644 --- a/docs/build/.documenter-siteinfo.json +++ b/docs/build/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.10.4","generation_timestamp":"2024-08-25T16:14:53","documenter_version":"1.5.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.10.5","generation_timestamp":"2024-08-30T07:38:13","documenter_version":"1.5.0"}} \ No newline at end of file diff --git a/docs/build/index.html b/docs/build/index.html index 4da8f39..c2c877d 100644 --- a/docs/build/index.html +++ b/docs/build/index.html @@ -1,8 +1,8 @@ -LinearAlgebraX · LinearAlgebraX

LinearAlgebraX

This module implements basic linear algebra methods for matrices with exact entries (e.g., Rational{Int} values). The function names typically match the standard ones in Julia but with an x (for "exact") appended.

The functions in this module work for all types of Integer, Rational, Complex{Integer}, Complex{Rational}, and Mod entries in matrices. Other exact numbers may work as well, but are not tested.

As the goal of this module is always to give exact answers and, at the same time, be type stable, the results of many of these functions are big. That is, the detx of an integer matrix returns a BigInt.

Functions

These functions in this module end with the letter x and have the same definitions as their counterparts that do not have an x. For exact types (such as Ints) these functions give exact results.

  • detx – exact determinant
  • cofactor_det– slower exact determinant (via cofactor expansion)
  • nullspacex – exact nullspace
  • rankx – exact rank
  • invx – exact inverse
  • rrefx – row reduced echelon form
  • eye – lovingly restored
  • char_poly – characteristic polynomial
  • permanent – permanent of a square matrix

Examples

Determinant

julia> A = ones(Int,10,10)+eye(Int,10);
+LinearAlgebraX · LinearAlgebraX

LinearAlgebraX

This module implements basic linear algebra methods for matrices with exact entries (e.g., Rational{Int} values). The function names typically match the standard ones in Julia but with an x (for "exact") appended.

The functions in this module work for all types of Integer, Rational, Complex{Integer}, Complex{Rational}, and Mod entries in matrices. Other exact numbers may work as well, but are not tested.

As the goal of this module is always to give exact answers and, at the same time, be type stable, the results of many of these functions are big. That is, the detx of an integer matrix returns a BigInt.

Functions

These functions in this module end with the letter x and have the same definitions as their counterparts that do not have an x. For exact types (such as Ints) these functions give exact results.

  • detx – exact determinant
  • cofactor_det– slower exact determinant (via cofactor expansion)
  • nullspacex – exact nullspace
  • rankx – exact rank
  • invx – exact inverse
  • rrefx – row reduced echelon form
  • eye – lovingly restored
  • char_poly – characteristic polynomial
  • permanent – permanent of a square matrix

Examples follow.

Determinant

julia> A = ones(Int,10,10)+eye(Int,10);
 
 julia> det(A)
-11.000000000000004
+10.999999999999998
 
 julia> detx(A)
 11
@@ -26,7 +26,7 @@
 julia> detx(A)
 ┌ Warning: Using cofactor expansion to calculate determinant; may be very slow.
 └ @ LinearAlgebraX ~/.julia/dev/LinearAlgebraX/src/detx.jl:41
-Mod{10}(4)

Nullspace

julia> A = reshape(collect(1:12),3,4)
+Mod{10}(4)

Nullspace

julia> A = reshape(collect(1:12),3,4)
 3×4 Array{Int64,2}:
  1  4  7  10
  2  5  8  11
@@ -44,7 +44,7 @@
  -0.475185  -0.272395
   0.430549   0.717376
   0.564458  -0.617566
- -0.519821   0.172585

Rank

Consider the 12-by-12 Hibert matrix, H (see hilbert.jl in the extras folder):

12×12 Array{Rational{Int64},2}:
+ -0.519821   0.172585

Rank

Consider the 12-by-12 Hibert matrix, H (see hilbert.jl in the extras folder):

12×12 Array{Rational{Int64},2}:
  1//1   1//2   1//3   1//4   1//5   1//6   1//7   1//8   1//9   1//10  1//11  1//12
  1//2   1//3   1//4   1//5   1//6   1//7   1//8   1//9   1//10  1//11  1//12  1//13
  1//3   1//4   1//5   1//6   1//7   1//8   1//9   1//10  1//11  1//12  1//13  1//14
@@ -60,7 +60,7 @@
 11
 
 julia> rankx(H)
-12

Inverse

julia> using Mods
+12

Inverse

julia> using Mods
 
 julia> A = rand(Mod{11},5,5)
 5×5 Array{Mod{11},2}:
@@ -87,9 +87,9 @@
  Mod{11}(0)  Mod{11}(0)  Mod{11}(0)  Mod{11}(0)  Mod{11}(1)
  ```
 
- ### Characteristic polynomial
+ ## Characteristic polynomial
 

julia> using SimplePolynomials, LinearAlgebra

julia> x = getx() x

julia> A = triu(ones(Int,5,5)) 5×5 Array{Int64,2}: 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1

julia> char_poly(A) -1 + 5x - 10x^2 + 10x^3 - 5x^4 + x^5

julia> ans == (x-1)^5 true

julia> using Mods

julia> A = rand(Mod{17},4,4) 4×4 Array{Mod{17},2}: Mod{17}(16) Mod{17}(10) Mod{17}(9) Mod{17}(12) Mod{17}(15) Mod{17}(1) Mod{17}(1) Mod{17}(6) Mod{17}(3) Mod{17}(2) Mod{17}(5) Mod{17}(11) Mod{17}(5) Mod{17}(15) Mod{17}(15) Mod{17}(7)

julia> char_poly(A) Mod{17}(1) + Mod{17}(1)x + Mod{17}(16)x^2 + Mod{17}(5)x^3 + Mod{17}(1)x^4

julia> detx(A) Mod{17}(1)


- ### Row reduced echelon form
+ ## Row reduced echelon form
 
  ```
  julia> A = rand(Int,4,6) .% 10
@@ -149,7 +149,7 @@
 3-element Array{Rational{Int64},1}:
   1//3
  -2//3
-  1//1

However, entries cannot be assigned:

ulia> v[2] = 3//4
+  1//1

However, entries cannot be assigned:

julia> v[2] = 3//4
 ERROR: MethodError: no method matching setindex!(::HVector{Rational{Int64}}, ::Rational{Int64}, ::Int64)

Operations for HVectors

The product of a matrix and a homogeneous vector is a homogeneous vector:

julia> A = rand(Int,3,3) .% 5
 3×3 Array{Int64,2}:
  -1   0   0
@@ -178,4 +178,17 @@
 [-1//1 : 2//1 : 1//1]
 
 julia> dot(v,w)
-1

Homogeneous Matrices

We also provide HMatrix to represent a homogeneous matrix. These are constructed by passing an (ordinary) matrix. ``` julia> A = rand(Int,3,3).%5 3×3 Array{Int64,2}: 0 -4 3 1 4 -2 3 0 -3

julia> HMatrix(A) HMatrix: Rational{Int64}[0//1 4//3 -1//1; -1//3 -4//3 2//3; -1//1 0//1 1//1]

julia> Matrix(ans) 3×3 Array{Rational{Int64},2}: 0//1 4//3 -1//1 -1//3 -4//3 2//3 -1//1 0//1 1//1 ```

+1

Homogeneous Matrices

We also provide HMatrix to represent a homogeneous matrix. These are constructed by passing an (ordinary) matrix.

julia> A = rand(Int,3,3).%5
+3×3 Array{Int64,2}:
+ 0  -4   3
+ 1   4  -2
+ 3   0  -3
+
+julia> HMatrix(A)
+HMatrix: Rational{Int64}[0//1 4//3 -1//1; -1//3 -4//3 2//3; -1//1 0//1 1//1]
+
+julia> Matrix(ans)
+3×3 Array{Rational{Int64},2}:
+  0//1   4//3  -1//1
+ -1//3  -4//3   2//3
+ -1//1   0//1   1//1
diff --git a/docs/build/objects.inv b/docs/build/objects.inv index 35b51ed..30402f2 100644 Binary files a/docs/build/objects.inv and b/docs/build/objects.inv differ diff --git a/docs/build/search_index.js b/docs/build/search_index.js index ab1b985..d2523b1 100644 --- a/docs/build/search_index.js +++ b/docs/build/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"#LinearAlgebraX","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"","category":"section"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"This module implements basic linear algebra methods for matrices with exact entries (e.g., Rational{Int} values). The function names typically match the standard ones in Julia but with an x (for \"exact\") appended.","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"The functions in this module work for all types of Integer, Rational, Complex{Integer}, Complex{Rational}, and Mod entries in matrices. Other exact numbers may work as well, but are not tested. ","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"As the goal of this module is always to give exact answers and, at the same time, be type stable, the results of many of these functions are big. That is, the detx of an integer matrix returns a BigInt. ","category":"page"},{"location":"#Functions","page":"LinearAlgebraX","title":"Functions","text":"","category":"section"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"These functions in this module end with the letter x and have the same definitions as their counterparts that do not have an x. For exact types (such as Ints) these functions give exact results.","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"detx – exact determinant \ncofactor_det– slower exact determinant (via cofactor expansion)\nnullspacex – exact nullspace\nrankx – exact rank\ninvx – exact inverse\nrrefx – row reduced echelon form\neye – lovingly restored\nchar_poly – characteristic polynomial\npermanent – permanent of a square matrix","category":"page"},{"location":"#Examples","page":"LinearAlgebraX","title":"Examples","text":"","category":"section"},{"location":"#Determinant","page":"LinearAlgebraX","title":"Determinant","text":"","category":"section"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> A = ones(Int,10,10)+eye(Int,10);\n\njulia> det(A)\n11.000000000000004\n\njulia> detx(A)\n11\n\njulia> A = rand(Int,20,20) .% 20;\n\njulia> det(A)\n3.3905496651565455e29\n\njulia> detx(A)\n339054966515654744413389494504","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"For certain Mod matrices, there may be noninvertible nonzero elements in which case the Gaussian elimination algorithm may fail. If that happens, detx falls back to using cofactor expansion which may be very slow. Should that happen, a warning is generated.","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> using Mods\n\njulia> A = rand(Mod{10},5,5)\n5×5 Array{Mod{10},2}:\n Mod{10}(6) Mod{10}(1) Mod{10}(8) Mod{10}(7) Mod{10}(9)\n Mod{10}(6) Mod{10}(4) Mod{10}(6) Mod{10}(9) Mod{10}(0)\n Mod{10}(9) Mod{10}(8) Mod{10}(7) Mod{10}(8) Mod{10}(0)\n Mod{10}(9) Mod{10}(1) Mod{10}(9) Mod{10}(1) Mod{10}(3)\n Mod{10}(5) Mod{10}(4) Mod{10}(5) Mod{10}(9) Mod{10}(0)\n\njulia> detx(A)\n┌ Warning: Using cofactor expansion to calculate determinant; may be very slow.\n└ @ LinearAlgebraX ~/.julia/dev/LinearAlgebraX/src/detx.jl:41\nMod{10}(4)","category":"page"},{"location":"#Nullspace","page":"LinearAlgebraX","title":"Nullspace","text":"","category":"section"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> A = reshape(collect(1:12),3,4)\n3×4 Array{Int64,2}:\n 1 4 7 10\n 2 5 8 11\n 3 6 9 12\n\njulia> nullspacex(A)\n4×2 Array{Rational{BigInt},2}:\n 1//1 2//1\n -2//1 -3//1\n 1//1 0//1\n 0//1 1//1\n\njulia> nullspace(A)\n4×2 Array{Float64,2}:\n -0.475185 -0.272395\n 0.430549 0.717376\n 0.564458 -0.617566\n -0.519821 0.172585","category":"page"},{"location":"#Rank","page":"LinearAlgebraX","title":"Rank","text":"","category":"section"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"Consider the 12-by-12 Hibert matrix, H (see hilbert.jl in the extras folder):","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"12×12 Array{Rational{Int64},2}:\n 1//1 1//2 1//3 1//4 1//5 1//6 1//7 1//8 1//9 1//10 1//11 1//12\n 1//2 1//3 1//4 1//5 1//6 1//7 1//8 1//9 1//10 1//11 1//12 1//13\n 1//3 1//4 1//5 1//6 1//7 1//8 1//9 1//10 1//11 1//12 1//13 1//14\n 1//4 1//5 1//6 1//7 1//8 1//9 1//10 1//11 1//12 1//13 1//14 1//15\n 1//5 1//6 1//7 1//8 1//9 1//10 1//11 1//12 1//13 1//14 1//15 1//16\n 1//6 1//7 1//8 1//9 1//10 1//11 1//12 1//13 1//14 1//15 1//16 1//17\n 1//7 1//8 1//9 1//10 1//11 1//12 1//13 1//14 1//15 1//16 1//17 1//18\n 1//8 1//9 1//10 1//11 1//12 1//13 1//14 1//15 1//16 1//17 1//18 1//19\n 1//9 1//10 1//11 1//12 1//13 1//14 1//15 1//16 1//17 1//18 1//19 1//20\n 1//10 1//11 1//12 1//13 1//14 1//15 1//16 1//17 1//18 1//19 1//20 1//21\n 1//11 1//12 1//13 1//14 1//15 1//16 1//17 1//18 1//19 1//20 1//21 1//22\n 1//12 1//13 1//14 1//15 1//16 1//17 1//18 1//19 1//20 1//21 1//22 1//23","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"We compare the results of rank (from the LinearAlgebra module) and rankx (in this module):","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> rank(H)\n11\n\njulia> rankx(H)\n12","category":"page"},{"location":"#Inverse","page":"LinearAlgebraX","title":"Inverse","text":"","category":"section"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> using Mods\n\njulia> A = rand(Mod{11},5,5)\n5×5 Array{Mod{11},2}:\n Mod{11}(2) Mod{11}(4) Mod{11}(4) Mod{11}(0) Mod{11}(2)\n Mod{11}(9) Mod{11}(4) Mod{11}(5) Mod{11}(1) Mod{11}(10)\n Mod{11}(3) Mod{11}(4) Mod{11}(5) Mod{11}(6) Mod{11}(0)\n Mod{11}(5) Mod{11}(10) Mod{11}(4) Mod{11}(5) Mod{11}(4)\n Mod{11}(9) Mod{11}(10) Mod{11}(7) Mod{11}(8) Mod{11}(9)\n\njulia> B = invx(A)\n5×5 Array{Mod{11},2}:\n Mod{11}(4) Mod{11}(5) Mod{11}(0) Mod{11}(6) Mod{11}(8)\n Mod{11}(7) Mod{11}(4) Mod{11}(9) Mod{11}(10) Mod{11}(3)\n Mod{11}(6) Mod{11}(0) Mod{11}(2) Mod{11}(5) Mod{11}(5)\n Mod{11}(3) Mod{11}(4) Mod{11}(9) Mod{11}(10) Mod{11}(10)\n Mod{11}(9) Mod{11}(9) Mod{11}(0) Mod{11}(8) Mod{11}(9)\n\njulia> A*B\n5×5 Array{Mod{11},2}:\n Mod{11}(1) Mod{11}(0) Mod{11}(0) Mod{11}(0) Mod{11}(0)\n Mod{11}(0) Mod{11}(1) Mod{11}(0) Mod{11}(0) Mod{11}(0)\n Mod{11}(0) Mod{11}(0) Mod{11}(1) Mod{11}(0) Mod{11}(0)\n Mod{11}(0) Mod{11}(0) Mod{11}(0) Mod{11}(1) Mod{11}(0)\n Mod{11}(0) Mod{11}(0) Mod{11}(0) Mod{11}(0) Mod{11}(1)\n ```\n\n ### Characteristic polynomial\n","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> using SimplePolynomials, LinearAlgebra","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> x = getx() x","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> A = triu(ones(Int,5,5)) 5×5 Array{Int64,2}: 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> char_poly(A) -1 + 5x - 10x^2 + 10x^3 - 5x^4 + x^5","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> ans == (x-1)^5 true","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> using Mods","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> A = rand(Mod{17},4,4) 4×4 Array{Mod{17},2}: Mod{17}(16) Mod{17}(10) Mod{17}(9) Mod{17}(12) Mod{17}(15) Mod{17}(1) Mod{17}(1) Mod{17}(6) Mod{17}(3) Mod{17}(2) Mod{17}(5) Mod{17}(11) Mod{17}(5) Mod{17}(15) Mod{17}(15) Mod{17}(7)","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> char_poly(A) Mod{17}(1) + Mod{17}(1)x + Mod{17}(16)x^2 + Mod{17}(5)x^3 + Mod{17}(1)x^4","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> detx(A) Mod{17}(1)","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"\n ### Row reduced echelon form\n\n ```\n julia> A = rand(Int,4,6) .% 10\n4×6 Array{Int64,2}:\n 6 8 0 -6 -5 4\n 0 -5 2 0 -3 -4\n 0 -4 2 -8 7 -8\n 1 -3 7 2 -6 2\n\njulia> c = A[:,1] + A[:,2] - A[:,3]\n4-element Array{Int64,1}:\n 14\n -7\n -6\n -9\n\njulia> A = [c A]\n4×7 Array{Int64,2}:\n 14 6 8 0 -6 -5 4\n -7 0 -5 2 0 -3 -4\n -6 0 -4 2 -8 7 -8\n -9 1 -3 7 2 -6 2\n\njulia> rrefx(A)\n4×7 Array{Rational{Int64},2}:\n 1//1 0//1 0//1 -1//1 0//1 -23//130 -36//65\n 0//1 1//1 0//1 1//1 0//1 -883//325 158//325\n 0//1 0//1 1//1 1//1 0//1 551//650 512//325\n 0//1 0//1 0//1 0//1 1//1 -379//325 204//325\n ```\n\n ## Homogeneous Vectors\n\n A point in projective space is represented by a *homogeneous vector*. This is \n a list of numbers (like an ordinary vector) but two such vectors are equal \n if and only if one is a nonzero multiple of the other. \n\n We provide the `HVector` type to represent homogeneous vectors. The entries \n in an `HVector` are scaled so that the last nonzero coordinate is `1`. \n (Technically, we should forbid the all zero vector, but we don't implement\n that restriction.)\n\n To create an `HVector` provide either a list (one-dimensional array) of values \n or a list of arguments:\n ```\n julia> v = HVector([1,-2,3])\n[1//3 : -2//3 : 1//1]\n\njulia> w = HVector(2,-4,6)\n[1//3 : -2//3 : 1//1]\n\njulia> v==w\ntrue","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"Entries in an HVector can be retrieved individually, or the entire vector can be converted to an array:","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> v[2]\n-2//3\n\njulia> Vector(v)\n3-element Array{Rational{Int64},1}:\n 1//3\n -2//3\n 1//1","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"However, entries cannot be assigned:","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"ulia> v[2] = 3//4\nERROR: MethodError: no method matching setindex!(::HVector{Rational{Int64}}, ::Rational{Int64}, ::Int64)","category":"page"},{"location":"#Operations-for-HVectors","page":"LinearAlgebraX","title":"Operations for HVectors","text":"","category":"section"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"The product of a matrix and a homogeneous vector is a homogeneous vector:","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> A = rand(Int,3,3) .% 5\n3×3 Array{Int64,2}:\n -1 0 0\n 3 0 -2\n 3 -1 -2\n\njulia> A*v\n[1//1 : 3//1 : 1//1]\n\njulia> A*Vector(v)\n3-element Array{Rational{Int64},1}:\n -1//3\n -1//1\n -1//3","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"The dot product of two homogeneous vectors is a scalar. Since homogeneous vectors are unchanged by scaling, we only distinguish between zero and nonzero results. Specifically, the dot product is 0 if the two vectors are orthogonal and 1 otherwise. ","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> using Mods\n\njulia> u = Mod{3}(1)\nMod{3}(1)\n\njulia> v = HVector(u,u,u)\n[Mod{3}(1) : Mod{3}(1) : Mod{3}(1)]\n\njulia> dot(v,v)\n0\n\njulia> w = HVector(-1,2,1)\n[-1//1 : 2//1 : 1//1]\n\njulia> dot(v,w)\n1","category":"page"},{"location":"#Homogeneous-Matrices","page":"LinearAlgebraX","title":"Homogeneous Matrices","text":"","category":"section"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"We also provide HMatrix to represent a homogeneous matrix. These are constructed by passing an (ordinary) matrix. ``` julia> A = rand(Int,3,3).%5 3×3 Array{Int64,2}: 0 -4 3 1 4 -2 3 0 -3","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> HMatrix(A) HMatrix: Rational{Int64}[0//1 4//3 -1//1; -1//3 -4//3 2//3; -1//1 0//1 1//1]","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> Matrix(ans) 3×3 Array{Rational{Int64},2}: 0//1 4//3 -1//1 -1//3 -4//3 2//3 -1//1 0//1 1//1 ```","category":"page"}] +[{"location":"#LinearAlgebraX","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"","category":"section"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"This module implements basic linear algebra methods for matrices with exact entries (e.g., Rational{Int} values). The function names typically match the standard ones in Julia but with an x (for \"exact\") appended.","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"The functions in this module work for all types of Integer, Rational, Complex{Integer}, Complex{Rational}, and Mod entries in matrices. Other exact numbers may work as well, but are not tested. ","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"As the goal of this module is always to give exact answers and, at the same time, be type stable, the results of many of these functions are big. That is, the detx of an integer matrix returns a BigInt. ","category":"page"},{"location":"#Functions","page":"LinearAlgebraX","title":"Functions","text":"","category":"section"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"These functions in this module end with the letter x and have the same definitions as their counterparts that do not have an x. For exact types (such as Ints) these functions give exact results.","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"detx – exact determinant \ncofactor_det– slower exact determinant (via cofactor expansion)\nnullspacex – exact nullspace\nrankx – exact rank\ninvx – exact inverse\nrrefx – row reduced echelon form\neye – lovingly restored\nchar_poly – characteristic polynomial\npermanent – permanent of a square matrix","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"Examples follow.","category":"page"},{"location":"#Determinant","page":"LinearAlgebraX","title":"Determinant","text":"","category":"section"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> A = ones(Int,10,10)+eye(Int,10);\n\njulia> det(A)\n10.999999999999998\n\njulia> detx(A)\n11\n\njulia> A = rand(Int,20,20) .% 20;\n\njulia> det(A)\n3.3905496651565455e29\n\njulia> detx(A)\n339054966515654744413389494504","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"For certain Mod matrices, there may be noninvertible nonzero elements in which case the Gaussian elimination algorithm may fail. If that happens, detx falls back to using cofactor expansion which may be very slow. Should that happen, a warning is generated.","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> using Mods\n\njulia> A = rand(Mod{10},5,5)\n5×5 Array{Mod{10},2}:\n Mod{10}(6) Mod{10}(1) Mod{10}(8) Mod{10}(7) Mod{10}(9)\n Mod{10}(6) Mod{10}(4) Mod{10}(6) Mod{10}(9) Mod{10}(0)\n Mod{10}(9) Mod{10}(8) Mod{10}(7) Mod{10}(8) Mod{10}(0)\n Mod{10}(9) Mod{10}(1) Mod{10}(9) Mod{10}(1) Mod{10}(3)\n Mod{10}(5) Mod{10}(4) Mod{10}(5) Mod{10}(9) Mod{10}(0)\n\njulia> detx(A)\n┌ Warning: Using cofactor expansion to calculate determinant; may be very slow.\n└ @ LinearAlgebraX ~/.julia/dev/LinearAlgebraX/src/detx.jl:41\nMod{10}(4)","category":"page"},{"location":"#Nullspace","page":"LinearAlgebraX","title":"Nullspace","text":"","category":"section"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> A = reshape(collect(1:12),3,4)\n3×4 Array{Int64,2}:\n 1 4 7 10\n 2 5 8 11\n 3 6 9 12\n\njulia> nullspacex(A)\n4×2 Array{Rational{BigInt},2}:\n 1//1 2//1\n -2//1 -3//1\n 1//1 0//1\n 0//1 1//1\n\njulia> nullspace(A)\n4×2 Array{Float64,2}:\n -0.475185 -0.272395\n 0.430549 0.717376\n 0.564458 -0.617566\n -0.519821 0.172585","category":"page"},{"location":"#Rank","page":"LinearAlgebraX","title":"Rank","text":"","category":"section"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"Consider the 12-by-12 Hibert matrix, H (see hilbert.jl in the extras folder):","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"12×12 Array{Rational{Int64},2}:\n 1//1 1//2 1//3 1//4 1//5 1//6 1//7 1//8 1//9 1//10 1//11 1//12\n 1//2 1//3 1//4 1//5 1//6 1//7 1//8 1//9 1//10 1//11 1//12 1//13\n 1//3 1//4 1//5 1//6 1//7 1//8 1//9 1//10 1//11 1//12 1//13 1//14\n 1//4 1//5 1//6 1//7 1//8 1//9 1//10 1//11 1//12 1//13 1//14 1//15\n 1//5 1//6 1//7 1//8 1//9 1//10 1//11 1//12 1//13 1//14 1//15 1//16\n 1//6 1//7 1//8 1//9 1//10 1//11 1//12 1//13 1//14 1//15 1//16 1//17\n 1//7 1//8 1//9 1//10 1//11 1//12 1//13 1//14 1//15 1//16 1//17 1//18\n 1//8 1//9 1//10 1//11 1//12 1//13 1//14 1//15 1//16 1//17 1//18 1//19\n 1//9 1//10 1//11 1//12 1//13 1//14 1//15 1//16 1//17 1//18 1//19 1//20\n 1//10 1//11 1//12 1//13 1//14 1//15 1//16 1//17 1//18 1//19 1//20 1//21\n 1//11 1//12 1//13 1//14 1//15 1//16 1//17 1//18 1//19 1//20 1//21 1//22\n 1//12 1//13 1//14 1//15 1//16 1//17 1//18 1//19 1//20 1//21 1//22 1//23","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"We compare the results of rank (from the LinearAlgebra module) and rankx (in this module):","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> rank(H)\n11\n\njulia> rankx(H)\n12","category":"page"},{"location":"#Inverse","page":"LinearAlgebraX","title":"Inverse","text":"","category":"section"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> using Mods\n\njulia> A = rand(Mod{11},5,5)\n5×5 Array{Mod{11},2}:\n Mod{11}(2) Mod{11}(4) Mod{11}(4) Mod{11}(0) Mod{11}(2)\n Mod{11}(9) Mod{11}(4) Mod{11}(5) Mod{11}(1) Mod{11}(10)\n Mod{11}(3) Mod{11}(4) Mod{11}(5) Mod{11}(6) Mod{11}(0)\n Mod{11}(5) Mod{11}(10) Mod{11}(4) Mod{11}(5) Mod{11}(4)\n Mod{11}(9) Mod{11}(10) Mod{11}(7) Mod{11}(8) Mod{11}(9)\n\njulia> B = invx(A)\n5×5 Array{Mod{11},2}:\n Mod{11}(4) Mod{11}(5) Mod{11}(0) Mod{11}(6) Mod{11}(8)\n Mod{11}(7) Mod{11}(4) Mod{11}(9) Mod{11}(10) Mod{11}(3)\n Mod{11}(6) Mod{11}(0) Mod{11}(2) Mod{11}(5) Mod{11}(5)\n Mod{11}(3) Mod{11}(4) Mod{11}(9) Mod{11}(10) Mod{11}(10)\n Mod{11}(9) Mod{11}(9) Mod{11}(0) Mod{11}(8) Mod{11}(9)\n\njulia> A*B\n5×5 Array{Mod{11},2}:\n Mod{11}(1) Mod{11}(0) Mod{11}(0) Mod{11}(0) Mod{11}(0)\n Mod{11}(0) Mod{11}(1) Mod{11}(0) Mod{11}(0) Mod{11}(0)\n Mod{11}(0) Mod{11}(0) Mod{11}(1) Mod{11}(0) Mod{11}(0)\n Mod{11}(0) Mod{11}(0) Mod{11}(0) Mod{11}(1) Mod{11}(0)\n Mod{11}(0) Mod{11}(0) Mod{11}(0) Mod{11}(0) Mod{11}(1)\n ```\n\n ## Characteristic polynomial\n","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> using SimplePolynomials, LinearAlgebra","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> x = getx() x","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> A = triu(ones(Int,5,5)) 5×5 Array{Int64,2}: 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> char_poly(A) -1 + 5x - 10x^2 + 10x^3 - 5x^4 + x^5","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> ans == (x-1)^5 true","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> using Mods","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> A = rand(Mod{17},4,4) 4×4 Array{Mod{17},2}: Mod{17}(16) Mod{17}(10) Mod{17}(9) Mod{17}(12) Mod{17}(15) Mod{17}(1) Mod{17}(1) Mod{17}(6) Mod{17}(3) Mod{17}(2) Mod{17}(5) Mod{17}(11) Mod{17}(5) Mod{17}(15) Mod{17}(15) Mod{17}(7)","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> char_poly(A) Mod{17}(1) + Mod{17}(1)x + Mod{17}(16)x^2 + Mod{17}(5)x^3 + Mod{17}(1)x^4","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> detx(A) Mod{17}(1)","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"\n ## Row reduced echelon form\n\n ```\n julia> A = rand(Int,4,6) .% 10\n4×6 Array{Int64,2}:\n 6 8 0 -6 -5 4\n 0 -5 2 0 -3 -4\n 0 -4 2 -8 7 -8\n 1 -3 7 2 -6 2\n\njulia> c = A[:,1] + A[:,2] - A[:,3]\n4-element Array{Int64,1}:\n 14\n -7\n -6\n -9\n\njulia> A = [c A]\n4×7 Array{Int64,2}:\n 14 6 8 0 -6 -5 4\n -7 0 -5 2 0 -3 -4\n -6 0 -4 2 -8 7 -8\n -9 1 -3 7 2 -6 2\n\njulia> rrefx(A)\n4×7 Array{Rational{Int64},2}:\n 1//1 0//1 0//1 -1//1 0//1 -23//130 -36//65\n 0//1 1//1 0//1 1//1 0//1 -883//325 158//325\n 0//1 0//1 1//1 1//1 0//1 551//650 512//325\n 0//1 0//1 0//1 0//1 1//1 -379//325 204//325\n ```\n\n ## Homogeneous Vectors\n\n A point in projective space is represented by a *homogeneous vector*. This is \n a list of numbers (like an ordinary vector) but two such vectors are equal \n if and only if one is a nonzero multiple of the other. \n\n We provide the `HVector` type to represent homogeneous vectors. The entries \n in an `HVector` are scaled so that the last nonzero coordinate is `1`. \n (Technically, we should forbid the all zero vector, but we don't implement\n that restriction.)\n\n To create an `HVector` provide either a list (one-dimensional array) of values \n or a list of arguments:\n ```\n julia> v = HVector([1,-2,3])\n[1//3 : -2//3 : 1//1]\n\njulia> w = HVector(2,-4,6)\n[1//3 : -2//3 : 1//1]\n\njulia> v==w\ntrue","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"Entries in an HVector can be retrieved individually, or the entire vector can be converted to an array:","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> v[2]\n-2//3\n\njulia> Vector(v)\n3-element Array{Rational{Int64},1}:\n 1//3\n -2//3\n 1//1","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"However, entries cannot be assigned:","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> v[2] = 3//4\nERROR: MethodError: no method matching setindex!(::HVector{Rational{Int64}}, ::Rational{Int64}, ::Int64)","category":"page"},{"location":"#Operations-for-HVectors","page":"LinearAlgebraX","title":"Operations for HVectors","text":"","category":"section"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"The product of a matrix and a homogeneous vector is a homogeneous vector:","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> A = rand(Int,3,3) .% 5\n3×3 Array{Int64,2}:\n -1 0 0\n 3 0 -2\n 3 -1 -2\n\njulia> A*v\n[1//1 : 3//1 : 1//1]\n\njulia> A*Vector(v)\n3-element Array{Rational{Int64},1}:\n -1//3\n -1//1\n -1//3","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"The dot product of two homogeneous vectors is a scalar. Since homogeneous vectors are unchanged by scaling, we only distinguish between zero and nonzero results. Specifically, the dot product is 0 if the two vectors are orthogonal and 1 otherwise. ","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> using Mods\n\njulia> u = Mod{3}(1)\nMod{3}(1)\n\njulia> v = HVector(u,u,u)\n[Mod{3}(1) : Mod{3}(1) : Mod{3}(1)]\n\njulia> dot(v,v)\n0\n\njulia> w = HVector(-1,2,1)\n[-1//1 : 2//1 : 1//1]\n\njulia> dot(v,w)\n1","category":"page"},{"location":"#Homogeneous-Matrices","page":"LinearAlgebraX","title":"Homogeneous Matrices","text":"","category":"section"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"We also provide HMatrix to represent a homogeneous matrix. These are constructed by passing an (ordinary) matrix.","category":"page"},{"location":"","page":"LinearAlgebraX","title":"LinearAlgebraX","text":"julia> A = rand(Int,3,3).%5\n3×3 Array{Int64,2}:\n 0 -4 3\n 1 4 -2\n 3 0 -3\n\njulia> HMatrix(A)\nHMatrix: Rational{Int64}[0//1 4//3 -1//1; -1//3 -4//3 2//3; -1//1 0//1 1//1]\n\njulia> Matrix(ans)\n3×3 Array{Rational{Int64},2}:\n 0//1 4//3 -1//1\n -1//3 -4//3 2//3\n -1//1 0//1 1//1","category":"page"}] } diff --git a/docs/src/index.md b/docs/src/index.md index a7637c5..0c5c09b 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -29,15 +29,15 @@ For exact types (such as `Int`s) these functions give exact results. * `char_poly` -- characteristic polynomial * `permanent` -- permanent of a square matrix -## Examples +Examples follow. -### Determinant +## Determinant ``` julia> A = ones(Int,10,10)+eye(Int,10); julia> det(A) -11.000000000000004 +10.999999999999998 julia> detx(A) 11 @@ -75,7 +75,7 @@ Mod{10}(4) -### Nullspace +## Nullspace ``` julia> A = reshape(collect(1:12),3,4) @@ -99,7 +99,7 @@ julia> nullspace(A) -0.519821 0.172585 ``` -### Rank +## Rank Consider the 12-by-12 Hibert matrix, `H` (see `hilbert.jl` in the `extras` folder): ``` @@ -127,7 +127,7 @@ julia> rankx(H) 12 ``` -### Inverse +## Inverse ``` julia> using Mods @@ -157,7 +157,7 @@ julia> A*B Mod{11}(0) Mod{11}(0) Mod{11}(0) Mod{11}(0) Mod{11}(1) ``` - ### Characteristic polynomial + ## Characteristic polynomial ``` julia> using SimplePolynomials, LinearAlgebra @@ -195,7 +195,7 @@ julia> detx(A) Mod{17}(1) ``` - ### Row reduced echelon form + ## Row reduced echelon form ``` julia> A = rand(Int,4,6) .% 10 @@ -265,7 +265,7 @@ julia> Vector(v) ``` However, entries cannot be assigned: ``` -ulia> v[2] = 3//4 +julia> v[2] = 3//4 ERROR: MethodError: no method matching setindex!(::HVector{Rational{Int64}}, ::Rational{Int64}, ::Int64) ``` @@ -332,5 +332,5 @@ julia> Matrix(ans) 0//1 4//3 -1//1 -1//3 -4//3 2//3 -1//1 0//1 1//1 - ``` +```