Pivoted QR in Julia? - matrix

In Julia, the function qr(A) will perform a QR decomposition on a given matrix A. However, is there any function/way in Julia to do a "pivoted" QR decomposition on a given matrix?

Just pass in the magic option:
julia> A = 10*log.(1 .- rand(4,3));
julia> qr(A, ColumnNorm())
QRPivoted{Float64, Matrix{Float64}}
Q factor:
4×4 LinearAlgebra.QRPackedQ{Float64, Matrix{Float64}}:
-0.0101543 -0.218633 0.804736 -0.551812
-0.118832 -0.376628 0.446673 0.802816
-0.118236 -0.88692 -0.390704 -0.216204
-0.985797 0.154029 -0.0152722 -0.0651594
R factor:
3×3 Matrix{Float64}:
26.4193 4.80784 8.92215
0.0 18.7537 15.1792
0.0 0.0 -9.77702
permutation:
3-element Vector{Int64}:
2
3
1
Note that the docs are a little off.

Related

Define a custom sortperm function

In Julia, let's suppose I have the following matrix:
julia> rank = [[1.0,2.0,NaN] [5.0,3.0,1.0]]
3×2 Array{Float64,2}:
1.0 5.0
2.0 3.0
NaN 1.0
Using mapslices and sortperm to get a ranking on each column gives:
r = mapslices(sortperm, rank; dims=1)
3×2 Array{Int64,2}:
1 3
2 2
3 1
The problem being that NaN are considered as "worst" elements instead of being kept in final matrix. What I finally want is:
3×2 Array{Int64,2}:
1 3
2 2
NaN 1
My current workaround is to compare each element of r with those of rank. But I'm quite sure Julia has a classier way of doing it :p.
Current workaround: not enough because requires extra computation after mapslices as well as creating another array new_r.
nrow, ncol = size(r)
new_r = [Float64(ifelse(isnan(rank[i,j]), NaN, r[i,j])) for i in 1:nrow, j in 1:ncol]
NaN is not "special" in Julia. It is just a floating point value. If you want NaN to be treated as missing value you should first convert it to missing and then use ordinalrank function from StatsBase.jl:
julia> rank = [[1.0,2.0,NaN] [5.0,3.0,1.0]]
3×2 Array{Float64,2}:
1.0 5.0
2.0 3.0
NaN 1.0
julia> using StatsBase
julia> mapslices(rank; dims=1) do x
ordinalrank(replace(x, NaN=>missing))
end
3×2 Array{Union{Missing, Int64},2}:
1 3
2 2
missing 1

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)

How to create a uniformly random matrix in Julia?

l want to get a matrix with uniformly random values sampled from [-1,2]
x= rand([-1,2],(3,3))
3x3 Array{Int64,2}:
-1 -1 -1
2 -1 -1
-1 -1 -1
but it takes into consideration just -1 and 2, and I'm looking for continuous values for instance -0.9 , 0.75, -0.09, 1.80.
How can I do that?
Note: I am assuming here that you're looking for uniform random variables.
You can also use the Distributions package:
## Pkg.add("Distributions") # If you don't already have it installed.
using Distributions
rand(Uniform(-1,2), 3,3)
I do quite like isebarn's solution though, as it gets you thinking about the actual properties of the underlying probability distributions.
for random number in range [a,b]
rand() * (b-a) + a
and it works for a matrix aswell
rand(3,3) * (2 - (-1)) - 1
3x3 Array{Float64,2}:
1.85611 0.456955 -0.0219579
1.91196 -0.0352324 0.0296134
1.63924 -0.567682 0.45602
You need to use a FloatRange{Float64} with the dessired step:
julia> rand(-1.0:0.01:2.0, 3, 3)
3x3 Array{Float64,2}:
0.79 1.73 0.95
0.73 1.4 -0.46
1.42 1.68 -0.55

Function or operator for matrix exponential in Julia

I am looking for a function or operator
that computes the n-th matrix exponential in Julia
where n is a non-negative integer.
For example, in MATLAB I would write expm(A, 3) for A * A * A.
I could just call the product using * multiple times,
but is there a way to compute the matrix exponential
without doing this?
julia> A = [1 -1; 0 2]
2x2 Array{Int64,2}:
1 -1
0 2
julia> A * A
2x2 Array{Int64,2}:
1 -3
0 4
julia> A * A * A
2x2 Array{Int64,2}:
1 -7
0 8
Simply use the exponentiation operator.
julia> A = [1 -1; 0 2]
2x2 Array{Int64,2}:
1 -1
0 2
julia> A^2
2x2 Array{Int64,2}:
1 -3
0 4
julia> A^3
2x2 Array{Int64,2}:
1 -7
0 8
To find out where it's implemented, you can use the function methods
julia> methods(^)
# 45 methods for generic function "^":
...
^(A::Array{T,2}, p::Integer) at linalg/dense.jl:170
^(x, p::Integer) at intfuncs.jl:108
^(A::Array{T,2}, p::Number) at linalg/dense.jl:173
Given that information, you can find it in the Julia repository.

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