# Rank of matrix on Z2 field

**URL:** https://discourse.julialang.org/t/rank-of-matrix-on-z2-field/81078
**Category:** New to Julia
**Tags:** math, matrices, fast-math
**Created:** [May 14, 2022, 11:52pm UTC](https://discourse.julialang.org/t/rank-of-matrix-on-z2-field/81078 "2022-05-14T23:52:53Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![jisutich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jisutich/32/33342_2.png) [@jisutich](https://discourse.julialang.org/u/jisutich)
#### Post date: [May 14, 2022, 11:52pm UTC](https://discourse.julialang.org/t/rank-of-matrix-on-z2-field/81078/1 "2022-05-14T23:52:53Z")

</div>

Hi

Suppose I have a symmetric matrix defined on the Z2 field {0,1}. I want to calculate its rank. Do we have any function to do this? Thanks

---

<div class="post-metadata">

### Author: ![jd-foster](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jd-foster/32/35824_2.png) [@jd-foster](https://discourse.julialang.org/u/jd-foster)
#### Post date: [May 15, 2022, 12:10am UTC](https://discourse.julialang.org/t/rank-of-matrix-on-z2-field/81078/2 "2022-05-15T00:10:11Z")

</div>

Look at the Nemo and AbstractAlgebra packages:  
[https://nemocas.github.io/Nemo.jl/dev/residue/](https://nemocas.github.io/Nemo.jl/dev/residue/)

There is a `rank` function in AbstractAlgebra.

---

<div class="post-metadata">

### Author: ![jisutich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jisutich/32/33342_2.png) [@jisutich](https://discourse.julialang.org/u/jisutich)
#### Post date: [May 15, 2022, 12:28am UTC](https://discourse.julialang.org/t/rank-of-matrix-on-z2-field/81078/3 "2022-05-15T00:28:53Z")

</div>

Hi

I find a `rank` function in `AbstractAlgebra.jl`. But I still don’t know how to use it. I guess this is partially due to my ignorance about abstract algebra. Could you please give me more hints? Thanks

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [May 15, 2022, 2:13am UTC](https://discourse.julialang.org/t/rank-of-matrix-on-z2-field/81078/4 "2022-05-15T02:13:07Z")

</div>

Boolean algebra is already Z2. You could just use `LinearAlbegra.rank` on a `Matrix{Bool}`.

For example

```julia
julia> rank([true false
             true true])
2

julia> rank([true true
             true true])
1
```

---

<div class="post-metadata">

### Author: ![jisutich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jisutich/32/33342_2.png) [@jisutich](https://discourse.julialang.org/u/jisutich)
#### Post date: [May 15, 2022, 2:30am UTC](https://discourse.julialang.org/t/rank-of-matrix-on-z2-field/81078/5 "2022-05-15T02:30:22Z")

</div>

Oh this is what I want. Thanks.

---

<div class="post-metadata">

### Author: ![jisutich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jisutich/32/33342_2.png) [@jisutich](https://discourse.julialang.org/u/jisutich)
#### Post date: [May 15, 2022, 3:08am UTC](https://discourse.julialang.org/t/rank-of-matrix-on-z2-field/81078/6 "2022-05-15T03:08:13Z")

</div>

Hi Mason:

One more question is if my matrix dimension is large, will the result be inaccurate? Also, do you know the time complexity of using `rank` on a matrix of Boolean variables.

Thanks

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [May 15, 2022, 3:25am UTC](https://discourse.julialang.org/t/rank-of-matrix-on-z2-field/81078/7 "2022-05-15T03:25:29Z")

</div>

Hm, the `rank` is determined via the singular value decomposition and it does this by promoting everything to `Float64` so I’m not sure how well this will actually preserve the Z2 properties you’re after. I _think_ it’s fine but I’m not sure.

Accuracy can be controlled via the tolerance keywords, and the time complexity is just the regular SVD time complexity.

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [May 15, 2022, 3:30am UTC](https://discourse.julialang.org/t/rank-of-matrix-on-z2-field/81078/8 "2022-05-15T03:30:21Z")

</div>

Maybe check out [GitHub - scheinerman/LinearAlgebraX.jl: Exact linear algebra functions](https://github.com/scheinerman/LinearAlgebraX.jl). This is pretty slick. You can make a matrix of `Mod{2}` values and then use `rankx` for an exact rank. Probably has worse time complexity than floats, maybe worth testing.

---

<div class="post-metadata">

### Author: ![jd-foster](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jd-foster/32/35824_2.png) [@jd-foster](https://discourse.julialang.org/u/jd-foster)
#### Post date: [May 15, 2022, 10:20am UTC](https://discourse.julialang.org/t/rank-of-matrix-on-z2-field/81078/9 "2022-05-15T10:20:38Z")

</div>

There was a previous discussion and example given here:

> [@Rank is wrong for Rational matrices](https://discourse.julialang.org/t/rank-is-wrong-for-rational-matrices/19380):
>
> consider the matrix: julia\> m=[1//(n+m) for n in 1:11, m in 1:11]; it can be inverted exactly with no problem: julia\> one(m)==inv(m)\*m true however: julia\> rank(m) 10 The reason is that rank begins by converting its argument to floating-point. It seems to me that given a field (Rationals, but it could be rational fractions or any other field), the rank should be computed by computing the echelon form of the matrix rather that trying to convert to floats (which would not make sense for r…

---

<div class="post-metadata">

### Author: ![jisutich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jisutich/32/33342_2.png) [@jisutich](https://discourse.julialang.org/u/jisutich)
#### Post date: [May 15, 2022, 4:28pm UTC](https://discourse.julialang.org/t/rank-of-matrix-on-z2-field/81078/10 "2022-05-15T16:28:13Z")

</div>

Hi Mason. In fact I am worried that transferring bools to `Float64` and doing SVD will lead to problems. I guess what James posted shows this issue. Let me try the function `rankx` instead.

---

<div class="post-metadata">

### Author: ![jd-foster](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jd-foster/32/35824_2.png) [@jd-foster](https://discourse.julialang.org/u/jd-foster)
#### Post date: [May 16, 2022, 12:54am UTC](https://discourse.julialang.org/t/rank-of-matrix-on-z2-field/81078/11 "2022-05-16T00:54:35Z")

</div>

Here is an example using Nemo; first define the field \mathbb{Z}\_2:

```julia
using Nemo
Z2 = ResidueRing(ZZ, 2)

```

For purposes of the example, create a random base matrix, e.g.  
`X = rand([0,1], 4,5) `  
or define one:

```julia
X = [
 0 1 1 0 1
 1 0 1 1 0
 0 1 1 1 1
 0 1 1 0 1
]

```

then convert it into a Nemo object in the field (residue ring) \mathbb{Z}\_2

```julia
A = matrix(Z2, X)

```

Then call `rank`:

```julia
julia> rank(A)
3

```

---

<div class="post-metadata">

### Author: ![jisutich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jisutich/32/33342_2.png) [@jisutich](https://discourse.julialang.org/u/jisutich)
#### Post date: [May 16, 2022, 7:13pm UTC](https://discourse.julialang.org/t/rank-of-matrix-on-z2-field/81078/12 "2022-05-16T19:13:28Z")

</div>

Oh I got it. Thanks.

---

<div class="post-metadata">

### Author: ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)
#### Post date: [May 17, 2022, 8:56am UTC](https://discourse.julialang.org/t/rank-of-matrix-on-z2-field/81078/13 "2022-05-17T08:56:41Z")

</div>

> [@Mason](#):
>
> I _think_ it’s fine but I’m not sure.

No rank does depend on the field over which you consider the matrix for instance:

```julia
julia> using LinearAlgebra

julia> A = [1 0 1; 0 1 1; 1 1 0]
3×3 Matrix{Int64}:
 1 0 1
 0 1 1
 1 1 0

julia> det(A)
-2.0

```

What does it tell us? This matrix is invertible over the reals since its deteminant is nonzero. But over Z/2 its determinant is zero so it is not invertible. So over one field it has full rank and over the other it does not have full rank.
