Sum under main diagonal in julia - julia

How to sum under the main diagonal without using main diagonal in matrix, in julia?
I was using sum=tril(a)-1 but it doesn't work in julia.
I know I need a mask but I don't know how to use it.

You're looking for the LinearAlgebra module, which is part of the standard library and contains a tril function:
julia> using LinearAlgebra
julia> A = ones(5, 5)
5×5 Array{Float64,2}:
1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0
julia> tril(A, -1)
5×5 Array{Float64,2}:
0.0 0.0 0.0 0.0 0.0
1.0 0.0 0.0 0.0 0.0
1.0 1.0 0.0 0.0 0.0
1.0 1.0 1.0 0.0 0.0
1.0 1.0 1.0 1.0 0.0
julia> sum(tril(A, -1))
10.0

tril function is in the Linear Algebra standard library. To use it, you need to import the LinearAlgebra module. tril takes a second optional argument to specify where you want to start the lower triangular part. You can set it to -1 in order not to take the main diagonal.
using LinearAlgebra
A = rand(5, 5)
lowerA = tril(A, -1)
println(sum(lowerA))
You might also want to take a look at lazy lower triangular view constructors such as LowerTriangular or OneUnitLowerTriangular.

Related

How can I efficiently turn a vector of 1-dim array into a 2-dim array(matrix) in Julia?

As mentioned I have a vector of 1D matrice, such as:
P_predefined = [[.3 .4 .2 .1], [.2 .3 .5 0.], [.1 0. .8 .1], [.4 0. 0. .6]]
I would like to turn it into a matrix of 2D, I tried to use vcat, for which I expected to behave like vstack in Python, but it doesn't work.
vcat(algorithm.predefinedP)
It still returns a vector
[[0.3 0.4 0.2 0.1], [0.2 0.3 0.5 0.0], [0.1 0.0 0.8 0.1], [0.4 0.0 0.0 0.6]] #Vector{Matrix{Float64}}
How should I do it in the right way?
Julia 1.9 has stack, which can be used on earlier Julia versions via the package Compat.
julia> using Compat
julia> P_predefined = vec.([[.3 .4 .2 .1], [.2 .3 .5 0.], [.1 0. .8 .1], [.4 0. 0. .6]])
4-element Vector{Vector{Float64}}:
[0.3, 0.4, 0.2, 0.1]
[0.2, 0.3, 0.5, 0.0]
[0.1, 0.0, 0.8, 0.1]
[0.4, 0.0, 0.0, 0.6]
julia> stack(P_predefined)
4×4 Matrix{Float64}:
0.3 0.2 0.1 0.4
0.4 0.3 0.0 0.0
0.2 0.5 0.8 0.0
0.1 0.0 0.1 0.6
julia> stack(P_predefined; dims=1)
4×4 Matrix{Float64}:
0.3 0.4 0.2 0.1
0.2 0.3 0.5 0.0
0.1 0.0 0.8 0.1
0.4 0.0 0.0 0.6
Note: your P_predefined is a vector of 1xn matrices, instead of vectors. I've used vec here to convert them to vectors.
vcat(A...)
Concatenate along dimension 1. To efficiently concatenate a large
vector of arrays, use reduce(vcat, x).
julia> reduce(vcat, P_predefined)
4×4 Matrix{Float64}:
0.3 0.4 0.2 0.1
0.2 0.3 0.5 0.0
0.1 0.0 0.8 0.1
0.4 0.0 0.0 0.6
Since you mention efficiency, a comprehension will be 2X faster than vcat.
m, n = length(P_predefined), length(P_predefined[1])
#btime mat = [$P_predefined[i][j] for i=1:$m, j=1:$n]
#btime mat = reduce(vcat, $P_predefined)
# 29.347 ns (1 allocation: 192 bytes)
# 72.131 ns (1 allocation: 192 bytes)

Julia: Floats sum is wrong?

How can I make sure that by adding 0.2 at every iteration I get the correct result?
some = 0.0
for i in 1:10
some += 0.2
println(some)
end
the code above gives me
0.2
0.4
0.6000000000000001
0.8
1.0
1.2
1.4
1.5999999999999999
1.7999999999999998
1.9999999999999998
Floats are only approximatively correct and if adding up to infinity the error will become infinite, but you can still calculate with it pretty precisely. If you need to evaluate the result and look if it is correct you can use isapprox(a,b) or a ≈ b.
I.e.
some = 0.
for i in 1:1000000
some += 0.2
end
isapprox(some, 1000000 * 0.2)
# true
Otherwise, you can add integer numbers in the for loop and then divide by 10.
some = 0.
for i in 1:10
some += 2.
println(some/10.)
end
#0.2
#0.4
#0.6
#0.8
#1.0
#1.2
#1.4
#1.6
#1.8
#2.0
More info about counting with floats:
https://en.wikipedia.org/wiki/Floating-point_arithmetic
You can iterate over a range since they use some clever tricks to return more "natural" values:
julia> collect(0:0.2:2)
11-element Vector{Float64}:
0.0
0.2
0.4
0.6
0.8
1.0
1.2
1.4
1.6
1.8
2.0
julia> collect(range(0.0, step=0.2, length=11))
11-element Vector{Float64}:
0.0
0.2
0.4
0.6
0.8
1.0
1.2
1.4
1.6
1.8
2.0

I want to make a matrix from 1D Arrays in Julia

I am new to Julia and need some help.
I have a list of 1D Arrays, I want to produce a matrix like this
g = [ 2.0 -1.0 0.0 0.0;
-1.0 2.0 -1.0 0.0;
0.0 -1.0 2.0 -1.0;
0.0 0.0 -1.0 3.0]
I am able to follow simple examples given on docs, but how do I achieve this using loops?
Cheers,
Ayush
with loops you can create a matrix and then fill it.
with loops
horizontally:
julia> arr = [[2.0,-1.0,0.0,0.0],[-1.0,2.0,-1.0,0.0],[0.0,-1.0,2.0,-1.0],[0.0,0.0,-1.0,3.0],[1.,1.,1.,1.]]
5-element Array{Array{Float64,1},1}:
[2.0, -1.0, 0.0, 0.0]
[-1.0, 2.0, -1.0, 0.0]
[0.0, -1.0, 2.0, -1.0]
[0.0, 0.0, -1.0, 3.0]
[1.0, 1.0, 1.0, 1.0]
julia> function make_matrix(input::Vector{<:Vector})
element_type = eltype(eltype(input))
if (length(input) == 0)
return Array{element_type,2}(undef,0,0)
end
height,width = length(input[1]), length(input)
for col in input
(height == length(col)) ? nothing : throw("inconsistent array size")
end
output = Array{element_type}(undef,height,width)
for i in 1:width
output[:,i] = input[i]
end
return output
end
make_matrix (generic function with 1 method)
julia> make_matrix(arr)
4×5 Array{Float64,2}:
2.0 -1.0 0.0 0.0 1.0
-1.0 2.0 -1.0 0.0 1.0
0.0 -1.0 2.0 -1.0 1.0
0.0 0.0 -1.0 3.0 1.0
vertically:
julia> function vmake_matrix(input::Vector{<:Vector})
element_type = eltype(eltype(input))
if (length(input) == 0)
return Array{element_type,2}(undef,0,0)
end
height,width = length(input),length(input[1])
for col in input
(width == length(col)) ? nothing : throw("inconsistent array size")
end
output = Array{element_type}(undef,height,width)
for i in 1:height
output[i,:] = input[i]
end
return output
end
vmake_matrix (generic function with 1 method)
julia> vmake_matrix(arr)
5×4 Array{Float64,2}:
2.0 -1.0 0.0 0.0
-1.0 2.0 -1.0 0.0
0.0 -1.0 2.0 -1.0
0.0 0.0 -1.0 3.0
1.0 1.0 1.0 1.0
without loops
without loops you can use vcat or hcat depending on the direction you want to concatenate the arrays in.
julia> H_arr = [ [ 2.0 -1.0 0.0 0.0],[-1.0 2.0 -1.0 0.0],[0.0 -1.0 2.0 -1.0],[0.0 0.0 -1.0 3.0] ]
4-element Array{Array{Float64,2},1}:
[2.0 -1.0 0.0 0.0]
[-1.0 2.0 -1.0 0.0]
[0.0 -1.0 2.0 -1.0]
[0.0 0.0 -1.0 3.0]
julia> vcat(H_arr...)
4×4 Array{Float64,2}:
2.0 -1.0 0.0 0.0
-1.0 2.0 -1.0 0.0
0.0 -1.0 2.0 -1.0
0.0 0.0 -1.0 3.0
julia> V_arr = [[2.0,-1.0,0.0,0.0],[-1.0,2.0,-1.0,0.0],[0.0,-1.0,2.0,-1.0],[0.0,0.0,-1.0,3.0]]
4-element Array{Array{Float64,1},1}:
[2.0, -1.0, 0.0, 0.0]
[-1.0, 2.0, -1.0, 0.0]
[0.0, -1.0, 2.0, -1.0]
[0.0, 0.0, -1.0, 3.0]
julia> hcat(V_arr...)
4×4 Array{Float64,2}:
2.0 -1.0 0.0 0.0
-1.0 2.0 -1.0 0.0
0.0 -1.0 2.0 -1.0
0.0 0.0 -1.0 3.0

Create a submatrix of UpperTriangularMatrix in Julia

Given a list of columns and rows, I want to produce a submatrix of a cholesky factorization. Example:
julia> A = rand(10,10)
julia> R = chol(A'*A)
julia> ind = [1,3,6,8,9]
julia> R[ind,ind]
However, this results in an error:
ERROR: BoundsError: attempt to access 5x5
UpperTriangular{Float64,Array{Float64,2}}:
1.28259 0.0 0.0 0.0 0.0
0.0 6.51646e-314 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
at index [2,1]
in _unsafe_getindex at multidimensional.jl:197
in getindex at abstractarray.jl:483
I understand that this would work for a typical matrix, but the UpperTriangular type obviously requires something different... I can't find documentation on this.
Looks like Triangular matrices haven't been updated to take advantage of fallback non-scalar indexing in 0.4 (this was a missing method error in 0.3).
Easiest ways around this for now are conversion to a full array before you index:
julia> full(R)[ind,ind]
5x5 Array{Float64,2}:
2.2261 1.28096 1.69087 1.26135 1.50703
0.0 1.03681 0.115735 0.559855 0.70766
0.0 0.0 0.702936 -0.111155 -0.61263
0.0 0.0 0.0 0.661491 0.33661
0.0 0.0 0.0 0.0 0.159691
Or by using a SubArray, which creates a view into the original data (so modifications will propagate):
julia> sub(R, ind, ind)
5x5 SubArray{Float64,2,UpperTriangular{Float64,Array{Float64,2}},Tuple{Array{Int64,1},Array{Int64,1}},0}:
2.2261 1.28096 1.69087 1.26135 1.50703
0.0 1.03681 0.115735 0.559855 0.70766
0.0 0.0 0.702936 -0.111155 -0.61263
0.0 0.0 0.0 0.661491 0.33661
0.0 0.0 0.0 0.0 0.159691

How to get more info on julia array bounds error?

I'd coded a Julia function with an array bounds error:
function wrong()
alphas = [ 0.5, 1, 1.25, 2.0 ] ;
theta = 0:0.02:1 * pi ;
U = zeros( length(theta), 4 ) ;
i = 1 ;
j = 1 ;
for a = alphas
kd = pi * a ;
for t = theta
v = (cos( kd * cos( t ) ) - cos( kd ))/sin( t ) ;
U[i, j] = v ;
i = i + 1 ;
end
j = j + 1 ;
end
end
Here i=1 should be in the loop. I get:
julia> wrong()
ERROR: BoundsError()
in setindex! at array.jl:308 (repeats 2 times)
Is there any way to get the julia interpreter to give more detailed information about exceptions when they are hit, or ways to debug into the failing statement and see what's going on? For example, knowing what the index values that were caused the bounds error when this occurred would have been helpful to debug this.
Bounds error reporting has improved in julia v0.4 via this pull request https://github.com/JuliaLang/julia/pull/9534. In julia 0.4 the array as well as the index you were trying to access get printed by default:
julia> wrong()
ERROR: BoundsError: attempt to access 158x4 Array{Float64,2}:
NaN 0.0 0.0 0.0
0.0157085 0.0 0.0 0.0
0.0314201 0.0 0.0 0.0
0.047138 0.0 0.0 0.0
0.0628651 0.0 0.0 0.0
0.0786045 0.0 0.0 0.0
0.094359 0.0 0.0 0.0
0.110131 0.0 0.0 0.0
0.125924 0.0 0.0 0.0
0.141739 0.0 0.0 0.0
⋮
0.127183 0.0 0.0 0.0
0.111388 0.0 0.0 0.0
0.0956143 0.0 0.0 0.0
0.0798585 0.0 0.0 0.0
0.064118 0.0 0.0 0.0
0.04839 0.0 0.0 0.0
0.0326715 0.0 0.0 0.0
0.0169595 0.0 0.0 0.0
0.00125087 0.0 0.0 0.0
at index [159,2]
in wrong at none:15
I don't know if you can backport the changes to your julia version, but switching to 0.4 should solve your problem.

Resources