# Is Julia lazy?

**URL:** <https://discourse.julialang.org/t/is-julia-lazy/64192>\
**Category:** New to Julia\
**Created:** [July 7, 2021, 4:25am UTC](https://discourse.julialang.org/t/is-julia-lazy/64192 "2021-07-07T04:25:57Z")\
**Posts on this page:** 20\
**Page:** 5

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [July 10, 2021, 5:29pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/81 "2021-07-10T17:29:11Z")

</div>

Because you are lazy, I’m making some notes to make things even easier for you 😉

From your link:

```julia
f(M)=broadcast(x->F(x),M)
M=f([1 2 3;0 2 4;1 1 1])

```

Firstly, you shouldn’t write `broadcast(x->F(x),M)`, you should just write `broadcast(F,M)`, since `x->F(x)` is the same as `F` (except it’s even a bit worse.)

Secondly, you shouldn’t write `broadcast(F,M)`, you should write `F.(M)`, since that is the user-facing syntax for broadcasting.

Thirdly, you shouldn’t define `f(M)` _at all_, because broadcasting shouldn’t be hidden away like this, but be on the surface, so, you should write `F.([1 2 3;0 2 4;1 1 1])` instead of `f([1 2 3;0 2 4;1 1 1])`.

Fourthly, you shouldn’t write `F.([1 2 3;0 2 4;1 1 1])`, because that allocates an unnecessary temporary array and _then_ converts it to `F`, you should instead write `F[1 2 3;0 2 4;1 1 1]`, which directly constructs the array with the correct element type 😃

---

<div class="post-metadata">

**Author:** ![Gilles\_Dubois](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gilles_dubois/32/25830_2.png) [@Gilles\_Dubois](https://discourse.julialang.org/u/Gilles_Dubois)\
**Post date:** [July 10, 2021, 5:36pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/82 "2021-07-10T17:36:28Z")

</div>

very good lesson of laziness!

---

<div class="post-metadata">

**Author:** ![Gilles\_Dubois](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gilles_dubois/32/25830_2.png) [@Gilles\_Dubois](https://discourse.julialang.org/u/Gilles_Dubois)\
**Post date:** [July 10, 2021, 7:13pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/83 "2021-07-10T19:13:46Z")

</div>

Corrections made according your suggestions. If you want to check maybe necessary to clean cache. I didn’t go so far as to delete naming of matrices which would save two additional lines.

I hope you’ll stop with additional simplifications so that some piece of code will be left…

Anyway to reach emptiness is total elegance. Vacuum leaves space free for your imagination.

Tomorrow is football festival (they call it soccer in US). If you’re Brit, I wish you good luck.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [July 10, 2021, 7:31pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/84 "2021-07-10T19:31:50Z")

</div>

The most efficient calculation is to do nothing 😉

> [@Gilles\_Dubois](#):
>
> If you’re Brit, I wish you good luck.

Thanks, but, unfortunately, my country regrettably fell short of qualifying for the Euros, much less the final😢

---

<div class="post-metadata">

**Author:** ![Gilles\_Dubois](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gilles_dubois/32/25830_2.png) [@Gilles\_Dubois](https://discourse.julialang.org/u/Gilles_Dubois)\
**Post date:** [July 12, 2021, 6:32am UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/85 "2021-07-12T06:32:59Z")

</div>

It’s time for a conclusion now.  
First I would like to thank all contributors, who gave to me good advises and spent time for experiments. Among them a special mention to DNF and genkuroki.  
The recommendation to have a look at GaloisFields.jl was again of great value.  
From the various notes I learned a lot of things about sub-typing and promotion rules and understood why my model with macro, although possible to use was not adequate.  
I remind my purpose here for the moment : to teach linear algebra to students giving examples with finite fields where ‘exact’ computations are possible to illustrate the main technique of this discipline, for example computation of determinants, simplification of matrices, resolution of linear systems.  
At the moment of choice I decided to adopt the Tmo Kluck’s model at least for the primary p-fields Z/pZ, it’s enough to introduce this model with the two lines :

```julia
using GaloisFields
const F = @GaloisField 5 #F will be the primary 𝔽₅=ℤ/5ℤ field

```

The problem now is what to do with vector spaces of finite dimension over these 𝔽p 's ? Is it advisable to continue with Dr Kluck’s model ?  
First I was really impressed by the construction via a given minimal polynomial. I used this possibility in a demonstration example earlier.  
I was even more impressed by such constructions :

```julia
const G, β = GaloisField(81, :β) # degree-4 extension of ℤ/3ℤ
const G, β = GaloisField(3, 4, :β) # same; avoid having to factorize 81

```

I mean without passing an irreducible polynomial as an argument. It is well known that for any n it exists an irreducible polynomial of degree n over 𝔽ₚ but I couldn’t find anywhere a fast algorithm to find one. Examples here and there use brute force together with tricks (should be unitary, divisor of X^q -X where q=p^n , shouldn’t have any root in 𝔽ₚ and all this stuff).  
It seems to me that multiplication rules between elements given as linear combinations of powers of β need to know this polynomial. So the author has a trick either to find it or to bypass it. I didn’t go further in this direction but it’s very interesting.  
Now Dr Kluck concentrate on the fact that such extension have a field structure, namely an algebra over 𝔽ₚ, this is too much for us; we just need to use finite powers of 𝔽ₚ with the canonical basis.  
So I decided to abandon Timo’s model for vector spaces. and used instead

```julia
using Base.Iterators
using GaloisFields
const F = @GaloisField 5 #corps ℤ/5ℤ
PowerX_n(X, n) = Iterators.product(ntuple(i->X, n)...)
n=3 #puissance
P=PowerX_n(F,n) #ensembles de 3-uples
convert(t)=F[t[i] for i in 1:n]
const E=[convert(t) for t in P] #ℤ/5ℤ^3

```

This allows to build the space as a full list of elements or as a simple iterator by own choice.  
Furthermore I decided to study vector spaces on the basic 𝔽ₚ fields only. I’m just looking for examples after all not a complete theory.  
We noted that The author used indirect derivation from the basic abstract type ‘Number’ . one could hope that call for help to such beautiful tools as LinearAlgebra or AbstractAlgebra would help to compute let’s say determinants, inverses and solve systems. Alas ! it doesn’t work like genkuroki noted.  
The reason is that such function use for efficiency LU decomposition and the algorithm uses such fonctions as abs, conv, adjoint, together with binary relations ‘isless’ and so on. which have meaning for real and complex fields but cannot have any equivalent with finite fields.  
So since I want to use this only for educational purpose where efficiency is not a criteria I decided to write own ‘hand-made’ such functions using text-books formulas.

```julia
using GaloisFields
const F = @GaloisField 5
A=F[1 1 2;0 2 4;0 0 4]
delrowcol(M,i,j)=M[1:end .!=i,1:end .!=j] #suppression de la ième ligne et de la jème colonne
#développement suivant la première ligne
function DET(M)
    if size(M,1)==1
        return M[1,1]
    end
    s=size(M,1)
    L=[(-1)^(1+j)*M[1,j]*DET(delrowcol(M,1,j)) for j in 1:s]
    return reduce(+,L)
end

println(DET(A))

```

and as well

```julia
using GaloisFields
const F = @GaloisField 5
A=F[1 1 2;0 2 4;0 0 4]

delrowcol(M,i,j)=M[1:end .!=i,1:end .!=j] #suppression de la ième ligne et de la jème colonne
cofacteur(M,i,j)=(-1)^(i+j)*DET(delrowcol(M,i,j))

#développement suivant la première ligne
function DET(M)
    if size(M,1)==1
        return M[1,1]
    end
    s=size(M,1)
    L=[(-1)^(1+j)*M[1,j]*DET(delrowcol(M,1,j)) for j in 1:s]
    return reduce(+,L)
end
function cofacteurs(M)
    s=size(M,1)
    B=zeros(F,s,s)
    s=size(M,1)
    for i in 1:s ,j in 1:s
        B[i,j]=cofacteur(M,i,j)
    end
    return B
end

INV(M)=DET(M)^(-1)*transpose(cofacteurs(M))
println(DET(A))
println(INV(A))
println(A*INV(A))

```

I feel a little shy to send this last post because of possible reaction of DNF who estimates (Latin atavism) that I’m too much verbose.  
Thank you again to you all and see you soon about affine geometry.

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [July 12, 2021, 7:00am UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/86 "2021-07-12T07:00:04Z")

</div>

> [@Gilles\_Dubois](#):
>
> We noted that The author used indirect derivation from the basic abstract type ‘Number’ . one could hope that call for help to such beautiful tools as LinearAlgebra or AbstractAlgebra would help to compute let’s say determinants, inverses and solve systems. Alas ! it doesn’t work like genkuroki noted.

For what it’s worth, `det` works out of the box.

```julia
julia> using GaloisFields
       const F = @GaloisField 5
       A=F[1 1 2;0 2 4;0 0 4]
3×3 Matrix{𝔽₅}:
 1 1 2
 0 2 4
 0 0 4

julia> using LinearAlgebra
       det(A)
3

```

If we convince Julia that `conj` is identity, `inv` and system solving work as well.

```julia
julia> Base.conj(x::GaloisFields.AbstractGaloisField) = x
       inv(A)
3×3 Matrix{𝔽₅}:
 1 2 0
 0 3 2
 0 0 4

julia> A \ A[:, 1]
3-element Vector{𝔽₅}:
 1
 0
 0

```

---

<div class="post-metadata">

**Author:** ![Gilles\_Dubois](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gilles_dubois/32/25830_2.png) [@Gilles\_Dubois](https://discourse.julialang.org/u/Gilles_Dubois)\
**Post date:** [July 12, 2021, 7:41am UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/87 "2021-07-12T07:41:48Z")

</div>

You’re completely right .  
First this error with abs doesn’t appear anymore (mystery)  
Second I overloaded simply conj and not Base.conj (my mistake)  
Third these errors linked to undefined isless do not appear anymore (other mystery)  
Thank you in any case for your checking .  
Of course for somebody not used to the language.

```julia
Base.conj(x::GaloisFields.AbstractGaloisField) = x
  

```

looks like a magic formula.  
So it must be accompanied by a long comment.  
BTW

```julia
Base.conj(x::F) = x

```

works as well.

---

<div class="post-metadata">

**Author:** ![genkuroki](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/genkuroki/32/18030_2.png) [@genkuroki](https://discourse.julialang.org/u/genkuroki)\
**Post date:** [July 12, 2021, 7:45am UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/88 "2021-07-12T07:45:28Z")

</div>

Since the matrix `A` over 𝔽₅ of GaloisFields.jl is upper triangular, `LinearAlgebra.det(A)` is executed successfully. But it is not the case for a generic matrix over 𝔽₅.

```julia
using GaloisFields, LinearAlgebra
const F5 = @GaloisField 5
A = F5[1 2; 0 3]

```

```julia
2×2 Matrix{𝔽₅}:
 1 2
 0 3

```

```julia
det(A)

```

```julia
3

```

```julia
B = F5[1 2; 3 4]

```

```julia
2×2 Matrix{𝔽₅}:
 1 2
 3 4

```

```julia
MethodError: no method matching abs(::𝔽₅)
......

```

Ref. [Is Julia lazy? - #73 by genkuroki](https://discourse.julialang.org/t/is-julia-lazy/64192/73)

```julia
Base.abs(x::GaloisFields.PrimeField) = x.n # type-piracy!
det(B)

```

```julia
3

```

```julia
Base.abs(x::GaloisFields.ExtensionField) = x.coeffs # type-piracy!
Base.isless(x::GaloisFields.PrimeField, y::GaloisFields.PrimeField) = isless(x.n, y.n) # type-piracy!
F9 = @GaloisField! 3 a^2 + 1
C = F9[1+a 2+a; 2+a 2+a]

```

```julia
2×2 Matrix{𝔽₉}:
 a + 1 a + 2
 a + 2 a + 2

```

```julia
det(C)

```

```julia
2 * a + 1

```

Ref. [Avoid type piracy](https://docs.julialang.org/en/v1/manual/style-guide/#Avoid-type-piracy)

Edit 1: minor revision.  
Edit 2: add a type-piracy code.  
Edit 3: add an example of ExtensionField type-piracy code.  
Edit 4: add ref. for type-piracy.

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [July 12, 2021, 7:50am UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/89 "2021-07-12T07:50:51Z")

</div>

Ah, there’s the difference. However, the `abs` codepath is really just to choose the pivot in a numerically good way, which doesn’t matter on a finite field as long as zero is avoided. So we can fool Julia to pass that hurdle with

```julia
Base.abs(x::GaloisFields.AbstractGaloisField) = x.n

```

Hardly a sound solution though.

---

<div class="post-metadata">

**Author:** ![Gilles\_Dubois](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gilles_dubois/32/25830_2.png) [@Gilles\_Dubois](https://discourse.julialang.org/u/Gilles_Dubois)\
**Post date:** [July 12, 2021, 8:09am UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/90 "2021-07-12T08:09:29Z")

</div>

I used this yesterday.  
It worked for det not for inv.

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [July 12, 2021, 12:39pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/91 "2021-07-12T12:39:17Z")

</div>

If you want an easier `<: Number` object, use [https://github.com/SimonDanisch/AbstractNumbers.jl](https://github.com/SimonDanisch/AbstractNumbers.jl)

---

<div class="post-metadata">

**Author:** ![Gilles\_Dubois](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gilles_dubois/32/25830_2.png) [@Gilles\_Dubois](https://discourse.julialang.org/u/Gilles_Dubois)\
**Post date:** [July 12, 2021, 1:06pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/92 "2021-07-12T13:06:27Z")

</div>

```julia
Base.conj(x::F) = x

```

works as well.  
But only AFTER declaration of const F …

So his proposition is better ! can be placed anywhere before call to det and inv.  
I made some checking

```julia
using GaloisFields
using LinearAlgebra
Base.conj(x::GaloisFields.PrimeField) = x 
Base.abs(x::GaloisFields.PrimeField) = x.n 
const F = @GaloisField 5
#M=F[1 1 2;0 2 4;1 0 3]

#println(M*inv(M))
delrowcol(M,i,j)=M[1:end .!=i,1:end .!=j] #suppression de la ième ligne et de la jème colonne

#développement suivant la première ligne
function DET(M)
    if size(M,1)==1
        return M[1,1]
    end
    s=size(M,1)
    L=[(-1)^(1+j)*M[1,j]*DET(delrowcol(M,1,j)) for j in 1:s] 
    return reduce(+,L)
end

cofacteur(M,i,j)=(-1)^(i+j)*DET(delrowcol(M,i,j))

function cofacteurs(M)
    s=size(M,1)
    B=zeros(F,s,s)
    s=size(M,1)
    for i in 1:s ,j in 1:s
        B[i,j]=cofacteur(M,i,j)
    end
    return B
end

INV(M)=DET(M)^(-1)*transpose(cofacteurs(M))

for i in 0:100
    M=F[rand(0:4) rand(0:4) rand(0:4) ; rand(0:4) rand(0:4) rand(0:4) ; rand(0:4) rand(0:4) rand(0:4)]
    d=det(M) ; D=DET(M)
    print(d);print("--"); println(D)
        if !iszero(D)
            println(inv(M)==INV(M)) 
        end
 end

```

Seems everything OK ! det and DET are the same inv and INV also  
Maybe we can suggest the author to add these two lines in the library ?

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [July 12, 2021, 1:27pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/93 "2021-07-12T13:27:11Z")

</div>

> [@Gilles\_Dubois](#):
>
> Maybe we can suggest the author to add these two lines in the library ?

The `conj` method doesn’t look too controversial. The `abs` method is highly sketchy and I doubt it would be accepted (I wouldn’t accept it if it was my package. 🙂 )

However, there’s already a recent open issue about this, either coincidental or triggered by this thread:  
[Use GF as matrix element type? · Issue #15 · tkluck/GaloisFields.jl · GitHub](https://github.com/tkluck/GaloisFields.jl/issues/15). Better chime in there.

---

<div class="post-metadata">

**Author:** ![scheinerman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scheinerman/32/35303_2.png) [@scheinerman](https://discourse.julialang.org/u/scheinerman)\
**Post date:** [July 12, 2021, 8:28pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/94 "2021-07-12T20:28:10Z")

</div>

I haven’t read through all this, but you might find using `Mods` and `LinearAlgebraX` to be helpful. The `Mods` module defines Z\_p numbers and `LinearAlgebraX` provides exact determinants, null spaces, etc.

---

<div class="post-metadata">

**Author:** ![Gilles\_Dubois](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gilles_dubois/32/25830_2.png) [@Gilles\_Dubois](https://discourse.julialang.org/u/Gilles_Dubois)\
**Post date:** [July 12, 2021, 10:05pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/95 "2021-07-12T22:05:56Z")

</div>

Thank you for this interesting reference. Exact computation is what is needed for educational purposes.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [July 12, 2021, 11:27pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/96 "2021-07-12T23:27:23Z")

</div>

It’s also needed to educate people that floating-point arithmetic is what’s usually used and how that inexactness happens, and what its pitfalls are.

---

<div class="post-metadata">

**Author:** ![Jean\_Michel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jean_michel/32/8282_2.png) [@Jean\_Michel](https://discourse.julialang.org/u/Jean_Michel)\
**Post date:** [July 13, 2021, 9:17pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/97 "2021-07-13T21:17:45Z")

</div>

If you want a recent reference explaining all tricks about programming finite fields, look at

> **[Standard Generators of Finite Fields and their Cyclic Subgroups](https://arxiv.org/abs/2107.02257)**
>
> We define standardized constructions of finite fields, and standardized generators of (multiplicative) cyclic subgroups in these fields.
> The motivation is to provide a substitute for Conway polynomials which can be used by various software packages...

---

<div class="post-metadata">

**Author:** ![John\_Gibson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/john_gibson/32/5321_2.png) [@John\_Gibson](https://discourse.julialang.org/u/John_Gibson)\
**Post date:** [July 13, 2021, 11:03pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/98 "2021-07-13T23:03:38Z")

</div>

> [@Gilles\_Dubois](#):
>
> Thank you for this interesting reference. Exact computation is what is needed for educational purposes.

I actually think numerical linear algebra, with finite precision arithmetic, opens up a relatively dry topic and makes it interesting! As in, for example, the real-valued condition number is deeper, more revealing, and more important than the binary distinction between singular and nonsingular. Read Trefethen and Bau’s Numerical Linear Algebra. It’s fascinating.

---

<div class="post-metadata">

**Author:** ![sswatson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sswatson/32/5135_2.png) [@sswatson](https://discourse.julialang.org/u/sswatson)\
**Post date:** [July 13, 2021, 11:44pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/99 "2021-07-13T23:44:44Z")

</div>

I agree with this sentiment wholeheartedly. I found it unsatisfactory in introductory linear algebra that linear independence is a discontinuous property, as if you could somehow solve problems arising from rank deficiencies by perturbing the matrix. The singular value decomposition brings that issue (and many others) into clear focus.

Incidentally, if you want to see a presentation of the SVD with less sophistication and depth than Trefethen and Bau but brief and with mathlets and some code that you can execute in-browser, I’d like to suggest [this Prismia lesson](https://prismia.chat/shared/linear-algebra-2/fc0000c2-a8b3-4721-bfb3-aca7e01d336c). [But grain of salt: I’m plugging my own stuff.]

---

<div class="post-metadata">

**Author:** ![Gilles\_Dubois](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gilles_dubois/32/25830_2.png) [@Gilles\_Dubois](https://discourse.julialang.org/u/Gilles_Dubois)\
**Post date:** [July 15, 2021, 8:53am UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/100 "2021-07-15T08:53:57Z")

</div>

Unfortunately if div and inv both work, rank doesn’t .  
Some conversion is needed from base type to AbstractFloat ???  
No idea how to overload this …  
So I wrote some home-made function based on gaussean pivot .

```julia
delrowcol(M,i,j)=M[1:end .!=i,1:end .!=j] #suppression de la ième ligne et de la jème colonne
delrow(M,i)=M[1:end .!=i,1:end]
nulrow(M,i)=all((M[i,j] ==0 for j in 1:size(M,2))) 

function findpivot(M)
    L=M[1,:]
    s=size(M,1)
    for j in 1:s
        if M[1,j] !=0
            return j,M[1,j]
        end
    end
end

function rang(M)
    m,n=size(M,1),size(M,2)
    if m==1
        return nulrow(M,1) ? 0 : 1
     end
    if nulrow(M,1)
        return rang(delrow(M,1))
    end
    j,x=findpivot(M)
    N=zeros(typeof(M[1,1]),m,n)
    for i in 2:m
        N[i,:]=M[i,:]-M[1,:]*(x^(-1))*M[i,1]
    end
    return 1+rang(delrowcol(N,1,j))
end    

```

Any better idea ?

[Previous page](https://discourse.julialang.org/t/is-julia-lazy/64192.md?page=4)

[Next page](https://discourse.julialang.org/t/is-julia-lazy/64192.md?page=6)
