# Eye in julia 0.7

**URL:** <https://discourse.julialang.org/t/eye-in-julia-0-7/9820>\
**Category:** New to Julia\
**Created:** [March 19, 2018, 5:30pm UTC](https://discourse.julialang.org/t/eye-in-julia-0-7/9820 "2018-03-19T17:30:21Z")\
**Posts on this page:** 18\
**Page:** 2

<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:** [March 20, 2018, 4:19pm UTC](https://discourse.julialang.org/t/eye-in-julia-0-7/9820/21 "2018-03-20T16:19:52Z")

</div>

In my case: to construct the generators of a Coxeter group from the Cartan matrix, you get the i-th one  
by subtracting the ith line of the Cartan matrix from the corresponding line of the identity matrix.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [March 20, 2018, 4:21pm UTC](https://discourse.julialang.org/t/eye-in-julia-0-7/9820/22 "2018-03-20T16:21:15Z")

</div>

> [@Jean\_Michel](#):
>
> In my case: to construct the generators of a Coxeter group from the Cartan matrix, you get the i-th one by subtracting the ith line of the Cartan matrix from the corresponding line of the identity matrix.

If you have a Cartan matrix `C`, why not just do `C - I` to get the matrix whose rows are the generators?

---

<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:** [March 20, 2018, 4:24pm UTC](https://discourse.julialang.org/t/eye-in-julia-0-7/9820/23 "2018-03-20T16:24:13Z")

</div>

Sorry, you did not get it. If the Cartan matrix C is nxn you get n generators which are nxn matrices.  
The i-th matrix is the identity `eye(C)` modified as follows: you subtract the i-th line of C from the i-th line of  
`eye(C)`

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [March 20, 2018, 4:35pm UTC](https://discourse.julialang.org/t/eye-in-julia-0-7/9820/24 "2018-03-20T16:35:20Z")

</div>

> [@Jean\_Michel](#):
>
> The i-th matrix is the identity eye(n) modified as follows: you subtract the i-th line of C from the i-th line of eye(n)

I see, so you are really computing `G = I - eᵢ*eᵢ'*C = I - eᵢ*C[i,:]'` where `eᵢ` is the unit coordinate vector `eᵢ = zeros(n); eᵢ[i]=1`. Yes, `G = one(C); G[i,:] = C[i,:]` (_correction:_ `G[i,:] .-= C[i,:]`) is perhaps the most compact way to construct this.

(Assuming you need to construct it at all; depending on what you are doing, you should also consider working with `G` implicitly in matrix-free fashion: you can multiply a vector by `G` _much_ more efficiently without constructing the matrix, given only `C` and `i`. Multiplying a vector by the full matrix `G` requires O(n²) operations, whereas multiplying by it implicitly using the definition requires only O(n) operations.)

---

<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:** [March 20, 2018, 4:39pm UTC](https://discourse.julialang.org/t/eye-in-julia-0-7/9820/25 "2018-03-20T16:39:33Z")

</div>

In the above `G[i,:] = C[i,:]` should be `G[i,:] -= C[i,:]`

I construct other elements of the Coxeter group W by multiplying the generators in various ways — I am not interested only on the action on the vector space.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [March 20, 2018, 4:43pm UTC](https://discourse.julialang.org/t/eye-in-julia-0-7/9820/26 "2018-03-20T16:43:54Z")

</div>

> [@Jean\_Michel](#):
>
> I construct other elements of the Coxeter group W by multiplying the generators in various way — I am not interested only on the action on the vector space.

You can probably still improve performance by not constructing the generator matrices explicitly. Multiplying m of your generator matrices via dense-matrix operations requires O(mn³) operations, but multiplying them implicitly requires only O(mn²) operations. Not constructing the product at all, but just storing it implicitly, you can compute the action of the product on a vector in O(mn) operations.

This seems like a good illustration of the general principle that explicitly constructing identity matrices is often a sign of suboptimal code.

---

<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:** [March 20, 2018, 4:46pm UTC](https://discourse.julialang.org/t/eye-in-julia-0-7/9820/27 "2018-03-20T16:46:18Z")

</div>

Yes but in my applications n is small and m is large. For instance, the Weyl group of type E8 has  
dimension n=8 but cardinality m about 6.0e8

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [March 20, 2018, 4:49pm UTC](https://discourse.julialang.org/t/eye-in-julia-0-7/9820/28 "2018-03-20T16:49:36Z")

</div>

> [@Jean\_Michel](#):
>
> Yes but in my applications n is small and m is large. For instance, the Weyl group of type E8 has dimension n=8 but cardinal m about 6.10^8

Then you probably want to store the product explicitly (if you are going to act it on more than n vectors), but you could still gain a factor of ~8 by going from O(mn³) to O(mn²) to construct the n×n product of m generators by not computing the individual generator matrices explicitly.

---

<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:** [March 20, 2018, 4:52pm UTC](https://discourse.julialang.org/t/eye-in-julia-0-7/9820/29 "2018-03-20T16:52:50Z")

</div>

Anyway, thank you for explaining the ultimate possible optimizations. I am currently trying to port large libraries  
and ease of programming is my main concern. When my port succeeds it will be time to optimize.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [March 20, 2018, 4:56pm UTC](https://discourse.julialang.org/t/eye-in-julia-0-7/9820/30 "2018-03-20T16:56:26Z")

</div>

> [@Jean\_Michel](#):
>
> I am currently trying to port large libraries and ease of programming is my main concern. When my port succeeds it will be time to optimize.

That’s understandable. Just realize that if you are porting from e.g. Matlab-style code that constructs zillions (you mentioned 10⁸, yikes) of little temporary matrices, performance is likely to be quite poor in Julia until you rewrite it in a more Julian style. (Factors of 10–100 speedup from rewriting with Julia performance in mind are not uncommon.)

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [March 23, 2018, 4:16pm UTC](https://discourse.julialang.org/t/eye-in-julia-0-7/9820/31 "2018-03-23T16:16:23Z")

</div>

12 posts were split to a new topic: [Porting a CAS to Julia](https://discourse.julialang.org/t/porting-a-cas-to-julia/9924)

---

<div class="post-metadata">

**Author:** ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)\
**Post date:** [March 23, 2018, 1:35pm UTC](https://discourse.julialang.org/t/eye-in-julia-0-7/9820/36 "2018-03-23T13:35:33Z")

</div>

> [@tkoolen](#):
>
> I’ve always wondered why there isn’t something like
> 
> struct Identity{T} \<: AbstractMatrix{T}  
> n::Int  
> m::Int # perhaps  
> end

Check out [GitHub - JuliaArrays/FillArrays.jl: Julia package for lazily representing matrices filled with a single entry](https://github.com/JuliaArrays/FillArrays.jl) which includes `Eye(n,m)`.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [March 23, 2018, 1:43pm UTC](https://discourse.julialang.org/t/eye-in-julia-0-7/9820/37 "2018-03-23T13:43:22Z")

</div>

Ah, nice. I have

[https://github.com/JuliaRobotics/RigidBodyDynamics.jl/blob/d2ecb7e4e24defeec2885e04b06c0457684df660/src/custom\_collections.jl#L60-L73](https://github.com/JuliaRobotics/RigidBodyDynamics.jl/blob/d2ecb7e4e24defeec2885e04b06c0457684df660/src/custom_collections.jl#L60-L73)

as a utility in RigidBodyDynamics, a special case of `Fill` (a much better name than `ConstVector`). I might switch to using `FillArrays`.

Edit: I really think FillArrays this should be part of stdlib.

---

<div class="post-metadata">

**Author:** ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)\
**Post date:** [March 23, 2018, 3:25pm UTC](https://discourse.julialang.org/t/eye-in-julia-0-7/9820/41 "2018-03-23T15:25:19Z")

</div>

> [@tkoolen](#):
>
> I really think FillArrays this should be part of stdlib

I think in the interest of keeping Stdlib as simple as possible, this is not necessary as users can easily add FillArrays.jl, and one would still need to type `using FillArrays` even if it were in Stdlib.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [March 23, 2018, 3:47pm UTC](https://discourse.julialang.org/t/eye-in-julia-0-7/9820/44 "2018-03-23T15:47:58Z")

</div>

I actually think `Fill`, `Ones`, etc. should be the return types of `fill`, `ones`, etc. Some reasons:

- there are many cases where `fill`, `ones`, etc. are used to construct a matrix that doesn’t need to be modified anymore, in which case `Fill`, `Ones`, etc. will result in much better performance.
- `Base.fill` is currently not very generic. It always returns an `Array`. Same for `ones`, `zeros`, etc. Accordingly, there are `spzeros`, `spdiagm`, `spones` (on 0.6) methods for sparse arrays. This seems suboptimal. Wouldn’t it be better to have

```julia
SparseArray(zeros(3, 3))
Array(zeros(3, 3))

```

if you need mutable versions of a specific type?

---

<div class="post-metadata">

**Author:** ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)\
**Post date:** [March 23, 2018, 3:58pm UTC](https://discourse.julialang.org/t/eye-in-julia-0-7/9820/47 "2018-03-23T15:58:16Z")

</div>

> [@tkoolen](#):
>
> actually think Fill, Ones, etc. should be the return types of fill, ones, etc

I was under the impression that `fill` and `ones` were going to be deprecated in favour of something like `Matrix(Rep(0), n, m)`. Though it looks like that may not happen anymore

[Deprecate `ones`? · Issue #24444 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/24444)

Feel free to use any code from FillArrays.jl if you feel like making the proposed change as a PR.

PS I’m of the opinion that having synonyms like `zeros(n,m) = Zeros(n,m)` (or for that matter `linspace(a,b,n) = LinSpace(a,b,n)`) is not necessary: just use the capitalized version.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [March 23, 2018, 4:11pm UTC](https://discourse.julialang.org/t/eye-in-julia-0-7/9820/48 "2018-03-23T16:11:30Z")

</div>

Wouldn’t it be worthwhile to factor this thread into multiple (it appears at least two)?

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [March 23, 2018, 4:17pm UTC](https://discourse.julialang.org/t/eye-in-julia-0-7/9820/49 "2018-03-23T16:17:41Z")

</div>

It’s not perfect because the thread gradually diverged, but I think this is slightly better. Split the CAS discussion to [Porting a CAS to Julia](https://discourse.julialang.org/t/porting-a-cas-to-julia/9924)

[Previous page](https://discourse.julialang.org/t/eye-in-julia-0-7/9820.md?page=1)
