Julia 2d Matrix set value at index (i, j) - matrix

In Julia I created a Matrix A and want to set its value at (1, 1) to the value of 5. How do I do that? I tried this:
A = zeros(5, 5)
A[1][1] = 5
It throws the error
MethodError: no method matching setindex!(::Float64, ::Int64, ::Int64)
Stacktrace:
[1] top-level scope
# In[38]:4
[2] eval
# .\boot.jl:373 [inlined]
[3] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
# Base .\loading.jl:1196

DNF's comment already gives you the answer, but I'll elaborate a little.
The basic issue with what you're doing is that A[1] is a valid indexing operation returning the first element of A, and therefore A[1][1] is trying to index into that first element, which is just a number. To see:
julia> A[1]
0.0
julia> A[1][1]
0.0
Essentially what you are doing is equivalent to this:
julia> x = 1
1
julia> x[1] = 2
ERROR: MethodError: no method matching setindex!(::Int64, ::Int64, ::Int64)
Stacktrace:
[1] top-level scope
# REPL[12]:1
numbers in Julia are immutable, i.e. you cannot "replace" a number with another number in place. Arrays on the other hand are mutable:
julia> y = [1]
1-element Vector{Int64}:
1
julia> y[1] = 2
2
So you could also have done:
julia> A[1] = 5
5
julia> A
5×5 Matrix{Float64}:
5.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0
Why does A[1] work? A single index will give you the element you arrive at when you count down row-wise, continuing at the next column when you get to the bottom:
julia> z = rand(2, 2)
2×2 Matrix{Float64}:
0.727719 0.983778
0.792305 0.0408728
julia> z[3]
0.9837776491559934

Related

How can I generate a range of random floating point numbers in Julia?

I noticed that rand(x) where x is an integer gives me an array of random floating points. I want to know how I can generate an array of random float type variables within a certain range. I tried using a range as follows:
rand(.4:.6, 5, 5)
And I get:
0.4 0.4 0.4 0.4 0.4
0.4 0.4 0.4 0.4 0.4
0.4 0.4 0.4 0.4 0.4
0.4 0.4 0.4 0.4 0.4
0.4 0.4 0.4 0.4 0.4
How can I get a range instead of the lowest number in the range?
Perhaps a bit more elegant, as you actually want to sample from a Uniform distribution, you can use the Distribution package:
julia> using Distributions
julia> rand(Uniform(0.4,0.6),5,5)
5×5 Array{Float64,2}:
0.547602 0.513855 0.414453 0.511282 0.550517
0.575946 0.520085 0.564056 0.478139 0.48139
0.409698 0.596125 0.477438 0.53572 0.445147
0.567152 0.585673 0.53824 0.597792 0.594287
0.549916 0.56659 0.502528 0.550121 0.554276
The same method then applies from sampling from other well-known or user-defined distributions (just give the distribution as the first parameter to rand())
You need a step parameter:
rand(.4:.1:.6, 5, 5)
The .1 will provide a step for your range which is necessary for floating point numbers and not necessary for incrementing by 1. The issue is that it will assume 1 regardless of implicit precision. If you need the increment more precise than do the following:
rand(.4:.0001:.6, 5, 5)
This will give you a result that looks similar to:
0.4587 0.557 0.586 0.4541 0.4686
0.4545 0.4789 0.4921 0.4451 0.4212
0.4373 0.5056 0.4229 0.5167 0.5504
0.5494 0.4068 0.5316 0.4378 0.5495
0.4368 0.4384 0.5265 0.5995 0.5231
You can do it with
julia> map(x->0.4+x*(0.6-0.4),rand(5,5))
5×5 Array{Float64,2}:
0.455445 0.475007 0.518734 0.463064 0.400925
0.509436 0.527338 0.566976 0.482812 0.501817
0.405967 0.563425 0.574607 0.502343 0.483075
0.50317 0.482894 0.54584 0.594157 0.528844
0.50418 0.515788 0.5554 0.580199 0.505396
The general rule is
julia> map( x -> start + x * (stop - start), rand(5,5) )
where start is 0.4 and stop is 0.6
You can even generate a six sided dice this way by having x ranging from 1 to 7 that is 1 < x < 7 since the probability of x being exactly 1.0 or 7.0 is zero
julia> map(x->Integer(floor(1+x*(7-1))),rand(5,5))
5×5 Array{Int64,2}:
2 6 6 3 2
3 1 3 1 6
5 4 6 1 5
3 6 5 5 3
3 4 3 5 4
or you can use
julia> rand(1:6,5,5)
5×5 Array{Int64,2}:
3 6 3 5 5
2 1 3 3 3
1 5 4 1 5
5 5 5 5 1
3 2 1 5 6
Just another simple solution (using vectorized operations)
0.2 .* rand(5,5) .+ 0.4
And if efficiency matters...
#time 0.2 .* rand(10000, 10000) .+ 0.4
>> 0.798906 seconds (4 allocations: 1.490 GiB, 5.20% gc time)
#time map(x -> 0.4 + x * (0.6 - 0.4), rand(10000, 10000))
>> 0.836322 seconds (49.20 k allocations: 1.493 GiB, 7.08% gc time)
using Distributions
#time rand(Uniform(0.4, 0.6), 10000, 10000)
>> 1.310401 seconds (2 allocations: 762.940 MiB, 1.51% gc time)
#time rand(0.2:0.000001:0.4, 10000, 10000)
>> 1.715034 seconds (2 allocations: 762.940 MiB, 6.24% gc time)

Puzzling performance/output behavior with rank-2 polymorphism in Haskell

The below code (annotated inline with locations) gives a minimal example of the puzzling behavior I'm experiencing.
Essentially, why does (2) result in terrible space/time performance while (1) does not?
The below code is compiled and run as follows on ghc version 8.4.3:
ghc -prof -fprof-auto -rtsopts test.hs; ./test +RTS -p
{-# LANGUAGE Rank2Types #-}
import Debug.Trace
-- Not sure how to get rid of the record
data State = State {
-- (0) If vstate :: Float, the extra "hello"s go away
vstate :: forall a . (Fractional a) => a
}
step :: State -> State
step s =
-- (1) one "hello" per step
-- let vs = trace "hello" (vstate s) in
-- s { vstate = vs `seq` vstate s }
-- (2) increasing "hello"s per step
s { vstate = (trace "hello" (vstate s)) `seq` vstate s }
main :: IO ()
main = do
let initState = State { vstate = 0 }
-- (3) step 3 times
-- let res = step $ step $ step initState
-- print $ vstate res
-- (4) step 20 times to profile time/space performance
let res = iterate step initState
print $ vstate $ last $ take 20 res
print "done"
a. With (1) and (3) commented in, compiled without -O2, the code only outputs "hello" three times, as I expect it to.
b. With (2) and (3) commented in, compiled without -O2, the code outputs "hello" eight times. It seems to output one additional "hello" per step. I don't understand why this is happening.
c. With (1) and (4) commented in, compiled without -O2, the code runs extremely fast.
d. With (2) and (4) commented in, compiled without -O2, the code runs very slowly, and the performance report (included below) shows that makes many more calls to vstate and uses much more memory than variant c. I also don't understand why this is happening.
e. With (2) and (4) commented in, compiled with -O2, the code behaves the same as variant c. So clearly ghc is able to optimize away whatever pathological behavior is happening in variant d.
Here is the profiling report for variant c (fast):
Mon Aug 13 15:48 2018 Time and Allocation Profiling Report (Final)
partial +RTS -p -RTS
total time = 0.00 secs (0 ticks # 1000 us, 1 processor)
total alloc = 107,560 bytes (excludes profiling overheads)
COST CENTRE MODULE SRC %time %alloc
CAF GHC.IO.Handle.FD <entire-module> 0.0 32.3
CAF GHC.IO.Encoding <entire-module> 0.0 3.1
main Main partial.hs:(24,1)-(35,16) 0.0 13.4
main.res Main partial.hs:32:9-36 0.0 1.6
step Main partial.hs:(15,1)-(18,36) 0.0 1.1
step.vs Main partial.hs:17:9-37 0.0 46.1
individual inherited
COST CENTRE MODULE SRC no. entries %time %alloc %time %alloc
MAIN MAIN <built-in> 114 0 0.0 0.6 0.0 100.0
CAF Main <entire-module> 227 0 0.0 0.1 0.0 52.2
main Main partial.hs:(24,1)-(35,16) 228 1 0.0 2.7 0.0 52.1
vstate Main partial.hs:11:5-10 230 20 0.0 0.0 0.0 0.0
main.initState Main partial.hs:25:9-40 239 0 0.0 0.0 0.0 0.0
main.res Main partial.hs:32:9-36 234 0 0.0 0.0 0.0 0.0
step Main partial.hs:(15,1)-(18,36) 235 0 0.0 0.0 0.0 0.0
main.initState Main partial.hs:25:9-40 233 1 0.0 0.0 0.0 0.0
main.res Main partial.hs:32:9-36 231 1 0.0 1.6 0.0 49.4
step Main partial.hs:(15,1)-(18,36) 232 19 0.0 1.1 0.0 47.8
step.vs Main partial.hs:17:9-37 236 19 0.0 46.1 0.0 46.7
vstate Main partial.hs:11:5-10 237 190 0.0 0.0 0.0 0.6
main.initState Main partial.hs:25:9-40 238 0 0.0 0.6 0.0 0.6
CAF Debug.Trace <entire-module> 217 0 0.0 0.2 0.0 0.2
CAF GHC.Conc.Signal <entire-module> 206 0 0.0 0.6 0.0 0.6
CAF GHC.IO.Encoding <entire-module> 189 0 0.0 3.1 0.0 3.1
CAF GHC.IO.Encoding.Iconv <entire-module> 187 0 0.0 0.2 0.0 0.2
CAF GHC.IO.Handle.FD <entire-module> 178 0 0.0 32.3 0.0 32.3
CAF GHC.IO.Handle.Text <entire-module> 176 0 0.0 0.1 0.0 0.1
main Main partial.hs:(24,1)-(35,16) 229 0 0.0 10.7 0.0 10.7
Here is the profiling report for variant d (slow; without -O2):
Mon Aug 13 15:25 2018 Time and Allocation Profiling Report (Final)
partial +RTS -p -RTS
total time = 1.48 secs (1480 ticks # 1000 us, 1 processor)
total alloc = 1,384,174,472 bytes (excludes profiling overheads)
COST CENTRE MODULE SRC %time %alloc
step Main partial.hs:(15,1)-(21,60) 95.7 98.8
main.initState Main partial.hs:25:9-40 3.0 1.2
vstate Main partial.hs:11:5-10 1.4 0.0
individual inherited
COST CENTRE MODULE SRC no. entries %time %alloc %time %alloc
MAIN MAIN <built-in> 114 0 0.0 0.0 100.0 100.0
CAF Main <entire-module> 227 0 0.0 0.0 100.0 100.0
main Main partial.hs:(24,1)-(35,16) 228 1 0.0 0.0 100.0 100.0
vstate Main partial.hs:11:5-10 230 1048575 1.4 0.0 100.0 100.0
main.initState Main partial.hs:25:9-40 236 0 3.0 1.2 3.0 1.2
main.res Main partial.hs:32:9-36 234 0 0.0 0.0 95.7 98.8
step Main partial.hs:(15,1)-(21,60) 235 0 95.7 98.8 95.7 98.8
main.initState Main partial.hs:25:9-40 233 1 0.0 0.0 0.0 0.0
main.res Main partial.hs:32:9-36 231 1 0.0 0.0 0.0 0.0
step Main partial.hs:(15,1)-(21,60) 232 19 0.0 0.0 0.0 0.0
CAF Debug.Trace <entire-module> 217 0 0.0 0.0 0.0 0.0
CAF GHC.Conc.Signal <entire-module> 206 0 0.0 0.0 0.0 0.0
CAF GHC.IO.Encoding <entire-module> 189 0 0.0 0.0 0.0 0.0
CAF GHC.IO.Encoding.Iconv <entire-module> 187 0 0.0 0.0 0.0 0.0
CAF GHC.IO.Handle.FD <entire-module> 178 0 0.0 0.0 0.0 0.0
CAF GHC.IO.Handle.Text <entire-module> 176 0 0.0 0.0 0.0 0.0
main Main partial.hs:(24,1)-(35,16) 229 0 0.0 0.0 0.0 0.0
Here are some notes/guesses/questions on why this is happening:
What's the relationship of the degrading performance to the increasing "hello" count? The pathological version seems to output one more "hello" with each additional step. Why?
I'm aware that polymorphism in Haskell is slow, as detailed in this StackOverflow question. That might be part of the problem, since the pathological behavior goes away when vstate is monomorphized as vstate :: Float. But I don't see why the lack of a let-binding, as in location (2), would cause such bad time/space performance.
This is the minimal version of a performance bug in a larger codebase, which we fixed by "monomorphizing" floating-type numbers using realToFrac (the commit is here in case anyone is curious). I know that compiling with -O2 fixes the behavior in the minimal example, but I tried it in the larger codebase and it does not fix the performance issues. (The reason we need rank-2 polymorphism in the larger codebase is to use the ad library for autodiff.) Is there a more principled fix than using realToFrac, such as an inline specialization that can be applied?
forall a . (Fractional a) => a is a function type.
It has two arguments, a type (a :: *) and an instance with type Fractional a. Whenever you see =>, it's a function operationally, and compiles to a function in GHC's core representation, and sometimes stays a function in machine code as well. The main difference between -> and => is that arguments for the latter cannot be explicitly given by programmers, and they are always filled in implicitly by instance resolution.
Let's see the fast step first:
step :: State -> State
step (State f) =
let vs = trace "hello" f
in State (vs `seq` f)
Here, vs has an undetermined Fractional type which defaults to Double. If you turn on -Wtype-defaults warning, GHC will point this out to you. Since vs :: Double, it's just a numeric value, which is captured by the returned closure. Right, vs `seq` f is a function, since it has a functional type forall a . (Fractional a) => a, and it's desugared to an actual lambda expression by GHC. This lambda abstracts over the two arguments, captures vs as free variable, and passes along both arguments to f.
So, each step creates a new function closure which captures a vs :: Double. If we call step three times, we get three closures with three Doubles inside, each closure referring to the previous one. Then, when we write vstate (step $ step $ step initState), we again default to Double, and GHC calls this closure with the Fractional Double instance. All the vs-es call previous closures with Fractional Double, but every vs is evaluated only once, because they are regular lazy Double values which are not recomputed.
However, if we enable NoMonomorphismRestriction, vs is generalized to forall a. Fractional a => a, so it becomes a function as well, and its calls are not memoized anymore. Hence, in this case the fast version behaves the same as the slow version.
Now, the slow step:
step :: State -> State
step (State f) = State ((trace "hello" f) `seq` f)
This has exponential number of calls in the number of steps, because step f calls f twice, and without optimizations no computation is shared, because both calls occur under a lambda. In (trace "hello" f) `seq` f, the first call to f defaults to Fractional Double, and the second call just passes along the implicit Fractional a instance as before.
If we switch on optimization, GHC observes that the first f call does not depend on the function parameters, and floats out trace "hello" f to a let-binding, resulting in pretty much the same code as in the fast version.

Extract lower triangle portion of a matrix

I was wondering if there is a command or a package in Julia that permits us to extract directly the lower triangle portion of a matrix, excluding the diagonal. I can call R commands for that (like lowerTriangle of the gdata package), obviously, but I'd like to know if Julia has something similar. For example, imagine I have the matrix
1.0 0.751 0.734
0.751 1.0 0.948
0.734 0.948 1.0
I don't want to create a lower triangular matrix like
NA NA NA
0.751 NA NA
0.734 0.948 NA
but extract the lower portion of the matrix as an array: 0.751 0.734 0.948
If you're OK with creating a lower triangular matrix as an intermediate step, you can use logical indexing and tril! with an extra argument to get what you need.
julia> M = [1.0 0.751 0.734
0.751 1.0 0.948
0.734 0.948 1.0];
julia> v = M[tril!(trues(size(M)), -1)]
3-element Array{Float64, 1}:
0.751
0.734
0.948
The trues call returns an array of M's shape filled with boolean true values. tril! then prunes this down to just the part of the matrix that we want. The second argument to tril! tells it which superdiagonal to start from, which we use here to avoid the values in the leading diagonal.
We use the result of that for indexing into M, and that returns an array with the required values.
Using comprehensions:
julia> [M[m, n] for m in 2:size(M, 1) for n in 1:m-1]
3-element Array{Float64,1}:
0.751
0.734
0.948
But it is much slower than the sundar/Matt B. solution:
lower_triangular_1(M) = [M[m, n] for m in 2:size(M, 1) for n in 1:m-1]
lower_triangular_2(M) = [M[m, n] for n in 1:size(M, 2) for m in n+1:size(M, 1)]
lower_triangular_3(M) = M[tril!(trues(size(M)), -1)]
using BenchmarkTools
using LinearAlgebra # avoid warning in 0.7
M=rand(100, 100)
Testing with Julia Version 0.7.0-alpha.0:
julia> #btime lower_triangular_1(M);
73.179 μs (10115 allocations: 444.34 KiB)
julia> #btime lower_triangular_2(M);
71.157 μs (10117 allocations: 444.41 KiB)
julia> #btime lower_triangular_3(M);
16.325 μs (6 allocations: 40.19 KiB)
Not elegant, but faster (with #views):
function lower_triangular_4(M)
# works only for square matrices
res = similar(M, ((size(M, 1)-1) * size(M, 2)) ÷ 2)
start_idx = 1
for n = 1:size(M, 2)-1
#views column = M[n+1:end, n]
last_idx = start_idx -1 + length(column)
#views res[start_idx:last_idx] = column[:]
start_idx = last_idx + 1
end
end
julia> #btime lower_triangular_4(M);
4.272 μs (101 allocations: 44.95 KiB)

Julia AffineTransforms sign of rotation angle

I am using AffineTransforms to rotate a volume. I am confused now by the sign of the rotation angle. For a right-hand system, when looking down an axis, say Z axis, rotating the XY plane counter-clockwise should be positive angles. I define a rotation matrix r = [0.0 -1. 0.0; 1.0 0.0 0.0; 0.0 0.0 1.0], which is to rotate along the Z axis 90 degree counter-clockwise. Indeed, r * [1 0 0]' gives [0 1 0]', which rotates X axis to Y axis.
Now I define a volume v.
3×3×3 Array{Float64,3}:
[:, :, 1] =
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
[:, :, 2] =
0.0 0.0 0.0
1.0 0.0 0.0
0.0 0.0 0.0
[:, :, 3] =
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
then I define tfm = AffineTransform(r, vec([0 0 0]))) which is the same as tfm = tformrotate(vec([0 0 1]), π/2).
then transform(v, tfm). The rotation center is the input array center. I got
3×3×3 Array{Float64,3}:
[:, :, 1] =
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
[:, :, 2] =
0.0 1.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
[:, :, 3] =
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
This is surprising to me because the output is the 90 degree rotation along Z axis but clockwise. It seems to me that this is actually a -90 degree rotation. Could somebody point out what I did wrong? Thanks.
Admittedly, this confused me too. Had to read the help for transform and TransformedArray again.
First, the print order of arrays is a bit confusing, with the first index shown in columns, but it is the X-axis, as the dimensions of v are x,y,z in this order.
In the original v, we have v[2,1,2] == 1.0. But, by default, transform uses the center of the array as origin, so 2,1,2 is relative to center (0,-1,0) i.e. a unit vector in the negative y-axis direction.
The array returned by transform has values which are evaluated at x,y,z by giving the value of the original v at tfm((x,y,z)) (see ?TransformedArray).
Specifically, we have transform(v,tfm)[1,2,2] is v[tfm((-1,0,0))] which is v[(0,-1,0)] (because rotating (-1,0,0) counterclockwise is (0,-1,0)) which is v[2,1,2] in the uncentered v indices. Finally, v[2,1,2] == 1.0 as was in the output in the question.
Coordinate transformation are always tricky, and it is easy to confuse transformations and their inverse.
Hope this helps.

matrix of sparse complex numbers in Julia

In Julia, I can create a sparse matrix of zeros:
julia> a = spzeros(2,2)
2x2 sparse matrix with 0 Float64 entries:
julia> a[1,1] = 1
1
julia> full(a)
2x2 Array{Float64,2}:
1.0 0.0
0.0 0.0
and I can create a complex matrix:
julia> b = [ 1 ; im ]
2-element Array{Complex{Int64},1}:
1+0im
0+1im
If I try assigning a complex value to a sparse matrix of zeros I get an error:
julia> a[1,1] = im
ERROR: InexactError()
in setindex! at sparse/sparsematrix.jl:1095
which is consistent with the spzeros() returned type being parametrized by Float64:
julia> typeof(a)
SparseMatrixCSC{Float64,Int64} (constructor with 1 method)
How can I create a sparse matrix of complex-typed zeros in Julia?
Looking at what we can pass to spzeros:
julia> methods(spzeros)
# 5 methods for generic function "spzeros":
spzeros(m::Integer,n::Integer) at sparse/sparsematrix.jl:406
spzeros(Tv::Type{T<:Top},m::Integer,n::Integer) at sparse/sparsematrix.jl:407
spzeros(Tv::Type{T<:Top},Ti::Type{T<:Top},m::Integer,n::Integer) at sparse/sparsematrix.jl:409
spzeros(m::Integer) at deprecated.jl:28
spzeros(Tv::Type{T<:Top},m::Integer) at deprecated.jl:28
We see we should be able to pass a type as the first argument:
julia> a = spzeros(Complex{Float64}, 2,2)
2x2 sparse matrix with 0 Complex{Float64} entries:
julia> full(a)
2x2 Array{Complex{Float64},2}:
0.0+0.0im 0.0+0.0im
0.0+0.0im 0.0+0.0im
julia> a[1,1] = 2+3.4im
2.0 + 3.4im
julia> a
2x2 sparse matrix with 1 Complex{Float64} entries:
[1, 1] = 2.0+3.4im

Resources