Add: julia-0.6.2

Former-commit-id: ccc667cf67d569f3fb3df39aa57c2134755a7551
This commit is contained in:
2018-02-10 10:27:19 -07:00
parent 94220957d7
commit 019f8e3064
723 changed files with 276164 additions and 0 deletions

View File

@@ -0,0 +1,247 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
using Base.Test
@testset "eigs" begin
let
srand(1234)
local n,a,asym,b,bsym,d,v
n = 10
areal = sprandn(n,n,0.4)
breal = sprandn(n,n,0.4)
acmplx = complex.(sprandn(n,n,0.4), sprandn(n,n,0.4))
bcmplx = complex.(sprandn(n,n,0.4), sprandn(n,n,0.4))
testtol = 1e-6
@testset for elty in (Float64, Complex128)
if elty == Complex64 || elty == Complex128
a = acmplx
b = bcmplx
else
a = areal
b = breal
end
a = convert(SparseMatrixCSC{elty}, a)
asym = a' + a # symmetric indefinite
apd = a'*a # symmetric positive-definite
b = convert(SparseMatrixCSC{elty}, b)
bsym = b' + b
bpd = b'*b
(d,v) = eigs(a, nev=3)
@test a*v[:,2] d[2]*v[:,2]
@test norm(v) > testtol # eigenvectors cannot be null vectors
# (d,v) = eigs(a, b, nev=3, tol=1e-8) # not handled yet
# @test a*v[:,2] ≈ d[2]*b*v[:,2] atol=testtol
# @test norm(v) > testtol # eigenvectors cannot be null vectors
(d,v) = eigs(asym, nev=3)
@test asym*v[:,1] d[1]*v[:,1]
@test eigs(asym; nev=1, sigma=d[3])[1][1] d[3]
@test norm(v) > testtol # eigenvectors cannot be null vectors
(d,v) = eigs(apd, nev=3)
@test apd*v[:,3] d[3]*v[:,3]
@test eigs(apd; nev=1, sigma=d[3])[1][1] d[3]
(d,v) = eigs(apd, bpd, nev=3, tol=1e-8)
@test apd*v[:,2] d[2]*bpd*v[:,2] atol=testtol
@test norm(v) > testtol # eigenvectors cannot be null vectors
@testset "(shift-and-)invert mode" begin
(d,v) = eigs(apd, nev=3, sigma=0)
@test apd*v[:,3] d[3]*v[:,3]
@test norm(v) > testtol # eigenvectors cannot be null vectors
(d,v) = eigs(apd, bpd, nev=3, sigma=0, tol=1e-8)
@test apd*v[:,1] d[1]*bpd*v[:,1] atol=testtol
@test norm(v) > testtol # eigenvectors cannot be null vectors
end
@testset "ArgumentErrors" begin
@test_throws ArgumentError eigs(rand(elty,2,2))
@test_throws ArgumentError eigs(a, nev=-1)
@test_throws ArgumentError eigs(a, which=:Z)
@test_throws ArgumentError eigs(a, which=:BE)
@test_throws DimensionMismatch eigs(a, v0=zeros(elty,n+2))
@test_throws ArgumentError eigs(a, v0=zeros(Int,n))
if elty == Float64
@test_throws ArgumentError eigs(a+a.',which=:SI)
@test_throws ArgumentError eigs(a+a.',which=:LI)
@test_throws ArgumentError eigs(a,sigma=rand(Complex64))
end
end
end
end
end
# Problematic example from #6965
let A6965 = [
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
-1.0 2.0 0.0 0.0 0.0 0.0 0.0 1.0
-1.0 0.0 3.0 0.0 0.0 0.0 0.0 1.0
-1.0 0.0 0.0 4.0 0.0 0.0 0.0 1.0
-1.0 0.0 0.0 0.0 5.0 0.0 0.0 1.0
-1.0 0.0 0.0 0.0 0.0 6.0 0.0 1.0
-1.0 0.0 0.0 0.0 0.0 0.0 7.0 1.0
-1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 8.0
]
d, = eigs(A6965,which=:SM,nev=2,ncv=4,tol=eps())
@test d[1] 2.5346936860350002
@test real(d[2]) 2.6159972444834976
@test abs(imag(d[2])) 1.2917858749046127
# Requires ARPACK 3.2 or a patched 3.1.5
#T6965 = [ 0.9 0.05 0.05
# 0.8 0.1 0.1
# 0.7 0.1 0.2 ]
#d,v,nconv = eigs(T6965,nev=1,which=:LM)
# @test T6965*v ≈ d[1]*v atol=1e-6
end
# Example from Quantum Information Theory
import Base: size, issymmetric, ishermitian
mutable struct CPM{T<:Base.LinAlg.BlasFloat} <: AbstractMatrix{T} # completely positive map
kraus::Array{T,3} # kraus operator representation
end
size(Phi::CPM) = (size(Phi.kraus,1)^2,size(Phi.kraus,3)^2)
issymmetric(Phi::CPM) = false
ishermitian(Phi::CPM) = false
import Base: A_mul_B!
function A_mul_B!{T<:Base.LinAlg.BlasFloat}(rho2::StridedVector{T},Phi::CPM{T},rho::StridedVector{T})
rho = reshape(rho,(size(Phi.kraus,3),size(Phi.kraus,3)))
rho1 = zeros(T,(size(Phi.kraus,1),size(Phi.kraus,1)))
for s = 1:size(Phi.kraus,2)
As = view(Phi.kraus,:,s,:)
rho1 += As*rho*As'
end
return copy!(rho2,rho1)
end
let
# Generate random isometry
(Q,R) = qr(randn(100,50))
Q = reshape(Q,(50,2,50))
# Construct trace-preserving completely positive map from this
Phi = CPM(copy(Q))
(d,v,nconv,numiter,numop,resid) = eigs(Phi,nev=1,which=:LM)
# Properties: largest eigenvalue should be 1, largest eigenvector, when reshaped as matrix
# should be a Hermitian positive definite matrix (up to an arbitrary phase)
@test d[1] 1. # largest eigenvalue should be 1.
v = reshape(v,(50,50)) # reshape to matrix
v /= trace(v) # factor out arbitrary phase
@test vecnorm(imag(v)) 0. # it should be real
v = real(v)
# @test vecnorm(v-v')/2 ≈ 0. # it should be Hermitian
# Since this fails sometimes (numerical precision error),this test is commented out
v = (v+v')/2
@test isposdef(v)
# Repeat with starting vector
(d2,v2,nconv2,numiter2,numop2,resid2) = eigs(Phi,nev=1,which=:LM,v0=reshape(v,(2500,)))
v2 = reshape(v2,(50,50))
v2 /= trace(v2)
@test numiter2 < numiter
@test v v2
@test eigs(speye(50), nev=10)[1] ones(10) #Issue 4246
end
@testset "real svds" begin
let A = sparse([1, 1, 2, 3, 4], [2, 1, 1, 3, 1], [2.0, -1.0, 6.1, 7.0, 1.5])
S1 = svds(A, nsv = 2)
S2 = svd(Array(A))
## singular values match:
@test S1[1][:S] S2[2][1:2]
@testset "singular vectors" begin
## 1st left singular vector
s1_left = sign(S1[1][:U][3,1]) * S1[1][:U][:,1]
s2_left = sign(S2[1][3,1]) * S2[1][:,1]
@test s1_left s2_left
## 1st right singular vector
s1_right = sign(S1[1][:V][3,1]) * S1[1][:V][:,1]
s2_right = sign(S2[3][3,1]) * S2[3][:,1]
@test s1_right s2_right
end
# Issue number 10329
# Ensure singular values from svds are in
# the correct order
@testset "singular values ordered correctly" begin
B = sparse(diagm([1.0, 2.0, 34.0, 5.0, 6.0]))
S3 = svds(B, ritzvec=false, nsv=2)
@test S3[1][:S] [34.0, 6.0]
S4 = svds(B, nsv=2)
@test S4[1][:S] [34.0, 6.0]
end
@testset "passing guess for Krylov vectors" begin
S1 = svds(A, nsv = 2, u0=rand(eltype(A),size(A,1)))
@test S1[1][:S] S2[2][1:2]
S1 = svds(A, nsv = 2, v0=rand(eltype(A),size(A,2)))
@test S1[1][:S] S2[2][1:2]
S1 = svds(A, nsv = 2, u0=rand(eltype(A),size(A,1)), v0=rand(eltype(A),size(A,2)))
@test S1[1][:S] S2[2][1:2]
end
@test_throws ArgumentError svds(A,nsv=0)
@test_throws ArgumentError svds(A,nsv=20)
@test_throws DimensionMismatch svds(A,nsv=2,u0=rand(size(A,1)+1))
@test_throws DimensionMismatch svds(A,nsv=2,v0=rand(size(A,2)+1))
end
end
@testset "complex svds" begin
let A = sparse([1, 1, 2, 3, 4], [2, 1, 1, 3, 1], exp.(im*[2.0:2:10;]))
S1 = svds(A, nsv = 2)
S2 = svd(Array(A))
## singular values match:
@test S1[1][:S] S2[2][1:2]
@testset "singular vectors" begin
## left singular vectors
s1_left = abs.(S1[1][:U][:,1:2])
s2_left = abs.(S2[1][:,1:2])
@test s1_left s2_left
## right singular vectors
s1_right = abs.(S1[1][:V][:,1:2])
s2_right = abs.(S2[3][:,1:2])
@test s1_right s2_right
end
@testset "passing guess for Krylov vectors" begin
S1 = svds(A, nsv = 2, u0=rand(eltype(A),size(A,1)))
@test S1[1][:S] S2[2][1:2]
S1 = svds(A, nsv = 2, v0=rand(eltype(A),size(A,2)))
@test S1[1][:S] S2[2][1:2]
S1 = svds(A, nsv = 2, u0=rand(eltype(A),size(A,1)), v0=rand(eltype(A),size(A,2)))
@test S1[1][:S] S2[2][1:2]
end
@test_throws ArgumentError svds(A,nsv=0)
@test_throws ArgumentError svds(A,nsv=20)
@test_throws DimensionMismatch svds(A,nsv=2,u0=complex(rand(size(A,1)+1)))
@test_throws DimensionMismatch svds(A,nsv=2,v0=complex(rand(size(A,2)+1)))
end
end
@testset "promotion" begin
eigs(rand(1:10, 10, 10))
eigs(rand(1:10, 10, 10), rand(1:10, 10, 10) |> t -> t't)
svds(rand(1:10, 10, 8))
@test_throws MethodError eigs(big.(rand(1:10, 10, 10)))
@test_throws MethodError eigs(big.(rand(1:10, 10, 10)), rand(1:10, 10, 10))
@test_throws MethodError svds(big.(rand(1:10, 10, 8)))
end
# Symmetric generalized with singular B
let n = 10
k = 3
A = randn(n,n); A = A'A
B = randn(n,k); B = B*B'
@test sort(eigs(A, B, nev = k, sigma = 1.0)[1]) sort(eigvals(A, B)[1:k])
end

View File

@@ -0,0 +1,330 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
using Base.Test
import Base.LinAlg: BlasReal, BlasFloat
n = 10 #Size of test matrix
srand(1)
@testset for relty in (Int, Float32, Float64, BigFloat), elty in (relty, Complex{relty})
if relty <: AbstractFloat
dv = convert(Vector{elty}, randn(n))
ev = convert(Vector{elty}, randn(n-1))
if (elty <: Complex)
dv += im*convert(Vector{elty}, randn(n))
ev += im*convert(Vector{elty}, randn(n-1))
end
elseif relty <: Integer
dv = convert(Vector{elty}, rand(1:10, n))
ev = convert(Vector{elty}, rand(1:10, n-1))
if (elty <: Complex)
dv += im*convert(Vector{elty}, rand(1:10, n))
ev += im*convert(Vector{elty}, rand(1:10, n-1))
end
end
@testset "Constructors" begin
@test Bidiagonal(dv,ev,'U') == Bidiagonal(dv,ev,true)
@test_throws ArgumentError Bidiagonal(dv,ev,'R')
@test_throws DimensionMismatch Bidiagonal(dv,ones(elty,n),true)
@test_throws ArgumentError Bidiagonal(dv,ev)
end
@testset "getindex, setindex!, size, and similar" begin
ubd = Bidiagonal(dv, ev, true)
lbd = Bidiagonal(dv, ev, false)
# bidiagonal getindex / upper & lower
@test_throws BoundsError ubd[n + 1, 1]
@test_throws BoundsError ubd[1, n + 1]
@test ubd[2, 2] == dv[2]
# bidiagonal getindex / upper
@test ubd[2, 3] == ev[2]
@test iszero(ubd[3, 2])
# bidiagonal getindex / lower
@test lbd[3, 2] == ev[2]
@test iszero(lbd[2, 3])
# bidiagonal setindex! / upper
cubd = copy(ubd)
@test_throws ArgumentError ubd[2, 1] = 1
@test_throws ArgumentError ubd[3, 1] = 1
@test (cubd[2, 1] = 0; cubd == ubd)
@test ((cubd[1, 2] = 10) == 10; cubd[1, 2] == 10)
# bidiagonal setindex! / lower
clbd = copy(lbd)
@test_throws ArgumentError lbd[1, 2] = 1
@test_throws ArgumentError lbd[1, 3] = 1
@test (clbd[1, 2] = 0; clbd == lbd)
@test ((clbd[2, 1] = 10) == 10; clbd[2, 1] == 10)
# bidiagonal setindex! / upper & lower
@test_throws BoundsError ubd[n + 1, 1] = 1
@test_throws BoundsError ubd[1, n + 1] = 1
@test ((cubd[2, 2] = 10) == 10; cubd[2, 2] == 10)
# bidiagonal size
@test_throws ArgumentError size(ubd, 0)
@test size(ubd, 1) == size(ubd, 2) == n
@test size(ubd, 3) == 1
# bidiagonal similar
@test isa(similar(ubd), Bidiagonal{elty})
@test isa(similar(ubd, Int), Bidiagonal{Int})
@test isa(similar(ubd, Int, (3, 2)), Matrix{Int})
end
BD = Bidiagonal(dv, ev, true)
@testset "show" begin
dstring = sprint(Base.print_matrix,BD.dv')
estring = sprint(Base.print_matrix,BD.ev')
@test sprint(show,BD) == "$(summary(BD)):\n diag:$dstring\n super:$estring"
BD = Bidiagonal(dv,ev,false)
@test sprint(show,BD) == "$(summary(BD)):\n diag:$dstring\n sub:$estring"
end
@testset for isupper in (true, false)
T = Bidiagonal(dv, ev, isupper)
@testset "Constructor and basic properties" begin
@test size(T, 1) == size(T, 2) == n
@test size(T) == (n, n)
@test Array(T) == diagm(dv) + diagm(ev, isupper?1:-1)
@test Bidiagonal(Array(T), isupper) == T
@test big.(T) == T
@test Array(abs.(T)) == abs.(diagm(dv)) + abs.(diagm(ev, isupper?1:-1))
@test Array(real(T)) == real(diagm(dv)) + real(diagm(ev, isupper?1:-1))
@test Array(imag(T)) == imag(diagm(dv)) + imag(diagm(ev, isupper?1:-1))
end
z = zeros(elty, n)
@testset for func in (conj, transpose, ctranspose)
@test func(func(T)) == T
end
@testset "triu and tril" begin
@test istril(Bidiagonal(dv,ev,'L'))
@test !istril(Bidiagonal(dv,ev,'U'))
@test tril!(Bidiagonal(dv,ev,'U'),-1) == Bidiagonal(zeros(dv),zeros(ev),'U')
@test tril!(Bidiagonal(dv,ev,'L'),-1) == Bidiagonal(zeros(dv),ev,'L')
@test tril!(Bidiagonal(dv,ev,'U'),-2) == Bidiagonal(zeros(dv),zeros(ev),'U')
@test tril!(Bidiagonal(dv,ev,'L'),-2) == Bidiagonal(zeros(dv),zeros(ev),'L')
@test tril!(Bidiagonal(dv,ev,'U'),1) == Bidiagonal(dv,ev,'U')
@test tril!(Bidiagonal(dv,ev,'L'),1) == Bidiagonal(dv,ev,'L')
@test tril!(Bidiagonal(dv,ev,'U')) == Bidiagonal(dv,zeros(ev),'U')
@test tril!(Bidiagonal(dv,ev,'L')) == Bidiagonal(dv,ev,'L')
@test_throws ArgumentError tril!(Bidiagonal(dv,ev,'U'),n+1)
@test istriu(Bidiagonal(dv,ev,'U'))
@test !istriu(Bidiagonal(dv,ev,'L'))
@test triu!(Bidiagonal(dv,ev,'L'),1) == Bidiagonal(zeros(dv),zeros(ev),'L')
@test triu!(Bidiagonal(dv,ev,'U'),1) == Bidiagonal(zeros(dv),ev,'U')
@test triu!(Bidiagonal(dv,ev,'U'),2) == Bidiagonal(zeros(dv),zeros(ev),'U')
@test triu!(Bidiagonal(dv,ev,'L'),2) == Bidiagonal(zeros(dv),zeros(ev),'L')
@test triu!(Bidiagonal(dv,ev,'U'),-1) == Bidiagonal(dv,ev,'U')
@test triu!(Bidiagonal(dv,ev,'L'),-1) == Bidiagonal(dv,ev,'L')
@test triu!(Bidiagonal(dv,ev,'L')) == Bidiagonal(dv,zeros(ev),'L')
@test triu!(Bidiagonal(dv,ev,'U')) == Bidiagonal(dv,ev,'U')
@test_throws ArgumentError triu!(Bidiagonal(dv,ev,'U'),n+1)
end
Tfull = Array(T)
@testset "Linear solves" begin
if relty <: AbstractFloat
c = convert(Matrix{elty}, randn(n,n))
b = convert(Matrix{elty}, randn(n, 2))
if (elty <: Complex)
b += im*convert(Matrix{elty}, randn(n, 2))
end
elseif relty <: Integer
c = convert(Matrix{elty}, rand(1:10, n, n))
b = convert(Matrix{elty}, rand(1:10, n, 2))
if (elty <: Complex)
b += im*convert(Matrix{elty}, rand(1:10, n, 2))
end
end
condT = cond(map(Complex128,Tfull))
promty = typeof((zero(relty)*zero(relty) + zero(relty)*zero(relty))/one(relty))
if relty != BigFloat
x = T.'\c.'
tx = Tfull.' \ c.'
elty <: AbstractFloat && @test norm(x-tx,Inf) <= 4*condT*max(eps()*norm(tx,Inf), eps(promty)*norm(x,Inf))
@test_throws DimensionMismatch T.'\b.'
x = T'\c.'
tx = Tfull' \ c.'
@test norm(x-tx,Inf) <= 4*condT*max(eps()*norm(tx,Inf), eps(promty)*norm(x,Inf))
@test_throws DimensionMismatch T'\b.'
x = T\c.'
tx = Tfull\c.'
@test norm(x-tx,Inf) <= 4*condT*max(eps()*norm(tx,Inf), eps(promty)*norm(x,Inf))
@test_throws DimensionMismatch T\b.'
end
@test_throws DimensionMismatch T \ ones(elty,n+1,2)
@test_throws DimensionMismatch T.' \ ones(elty,n+1,2)
@test_throws DimensionMismatch T' \ ones(elty,n+1,2)
@test_throws DimensionMismatch T \ RowVector(ones(elty,n+1))
@test_throws DimensionMismatch T.' \ RowVector(ones(elty,n+1))
@test_throws DimensionMismatch T' \ RowVector(ones(elty,n+1))
@test_throws DimensionMismatch Base.LinAlg.At_ldiv_B(T, RowVector(ones(elty,n+1)))
@test_throws DimensionMismatch Base.LinAlg.Ac_ldiv_B(T, RowVector(ones(elty,n+1)))
let bb = b, cc = c
for atype in ("Array", "SubArray")
if atype == "Array"
b = bb
c = cc
else
b = view(bb, 1:n)
c = view(cc, 1:n, 1:2)
end
end
x = T \ b
tx = Tfull \ b
@test_throws DimensionMismatch Base.LinAlg.naivesub!(T,ones(elty,n+1))
@test norm(x-tx,Inf) <= 4*condT*max(eps()*norm(tx,Inf), eps(promty)*norm(x,Inf))
@testset "Generic Mat-vec ops" begin
@test T*b Tfull*b
@test T'*b Tfull'*b
if relty != BigFloat # not supported by pivoted QR
@test T/b' Tfull/b'
end
end
end
end
@testset "Round,float,trunc,ceil" begin
if elty <: BlasReal
@test floor.(Int, T) == Bidiagonal(floor.(Int, T.dv), floor.(Int, T.ev), T.isupper)
@test isa(floor.(Int, T), Bidiagonal)
@test trunc.(Int,T) == Bidiagonal(trunc.(Int, T.dv), trunc.(Int, T.ev), T.isupper)
@test isa(trunc.(Int,T), Bidiagonal)
@test round.(Int, T) == Bidiagonal(round.(Int, T.dv), round.(Int, T.ev), T.isupper)
@test isa(round.(Int, T), Bidiagonal)
@test ceil.(Int,T) == Bidiagonal(ceil.(Int,T.dv), ceil.(Int,T.ev), T.isupper)
@test isa(ceil.(Int,T), Bidiagonal)
@test floor.(T) == Bidiagonal(floor.(T.dv), floor.(T.ev), T.isupper)
@test isa(floor.(T), Bidiagonal)
@test trunc.(T) == Bidiagonal(trunc.(T.dv), trunc.(T.ev), T.isupper)
@test isa(trunc.(T), Bidiagonal)
@test round.(T) == Bidiagonal(round.(T.dv), round.(T.ev), T.isupper)
@test isa(round.(T), Bidiagonal)
@test ceil.(T) == Bidiagonal(ceil.(T.dv), ceil.(T.ev), T.isupper)
@test isa(ceil.(T), Bidiagonal)
end
end
@testset "Diagonals" begin
@test diag(T,2) == zeros(elty, n-2)
@test_throws ArgumentError diag(T,n+1)
end
@testset "Eigensystems" begin
if relty <: AbstractFloat
d1, v1 = eig(T)
d2, v2 = eig(map(elty<:Complex ? Complex128 : Float64,Tfull))
@test (isupper ? d1 : reverse(d1)) d2
if elty <: Real
Test.test_approx_eq_modphase(v1, isupper ? v2 : v2[:,n:-1:1])
end
end
end
@testset "Singular systems" begin
if (elty <: BlasReal)
@test AbstractArray(svdfact(T)) AbstractArray(svdfact!(copy(Tfull)))
@test svdvals(Tfull) svdvals(T)
u1, d1, v1 = svd(Tfull)
u2, d2, v2 = svd(T)
@test d1 d2
if elty <: Real
Test.test_approx_eq_modphase(u1, u2)
Test.test_approx_eq_modphase(v1, v2)
end
@test 0 vecnorm(u2*diagm(d2)*v2'-Tfull) atol=n*max(n^2*eps(relty),vecnorm(u1*diagm(d1)*v1'-Tfull))
@inferred svdvals(T)
@inferred svd(T)
end
end
@testset "Binary operations" begin
@test -T == Bidiagonal(-T.dv,-T.ev,T.isupper)
@test convert(elty,-1.0) * T == Bidiagonal(-T.dv,-T.ev,T.isupper)
@test T * convert(elty,-1.0) == Bidiagonal(-T.dv,-T.ev,T.isupper)
@testset for isupper2 in (true, false)
dv = convert(Vector{elty}, relty <: AbstractFloat ? randn(n) : rand(1:10, n))
ev = convert(Vector{elty}, relty <: AbstractFloat ? randn(n-1) : rand(1:10, n-1))
T2 = Bidiagonal(dv, ev, isupper2)
Tfull2 = Array(T2)
for op in (+, -, *)
@test Array(op(T, T2)) op(Tfull, Tfull2)
end
end
end
@test inv(T)*Tfull eye(elty,n)
end
@test Matrix{Complex{Float64}}(BD) == BD
end
# Issue 10742 and similar
let A = Bidiagonal([1,2,3], [0,0], true)
@test istril(A)
@test isdiag(A)
end
# test construct from range
@test Bidiagonal(1:3, 1:2, true) == [1 1 0; 0 2 2; 0 0 3]
@testset "promote_rule" begin
A = Bidiagonal(ones(Float32,10),ones(Float32,9),true)
B = rand(Float64,10,10)
C = Tridiagonal(rand(Float64,9),rand(Float64,10),rand(Float64,9))
@test promote_rule(Matrix{Float64}, Bidiagonal{Float64}) == Matrix{Float64}
@test promote(B,A) == (B, convert(Matrix{Float64}, A))
@test promote(C,A) == (C,Tridiagonal(zeros(Float64,9),convert(Vector{Float64},A.dv),convert(Vector{Float64},A.ev)))
end
import Base.LinAlg: fillslots!, UnitLowerTriangular
@testset "fill! and fillslots!" begin
let #fill!
let # fillslots!
A = Tridiagonal(randn(2), randn(3), randn(2))
@test fillslots!(A, 3) == Tridiagonal([3, 3.], [3, 3, 3.], [3, 3.])
B = Bidiagonal(randn(3), randn(2), true)
@test fillslots!(B, 2) == Bidiagonal([2.,2,2], [2,2.], true)
S = SymTridiagonal(randn(3), randn(2))
@test fillslots!(S, 1) == SymTridiagonal([1,1,1.], [1,1.])
Ult = UnitLowerTriangular(randn(3,3))
@test fillslots!(Ult, 3) == UnitLowerTriangular([1 0 0; 3 1 0; 3 3 1])
end
let # fill!(exotic, 0)
exotic_arrays = Any[Tridiagonal(randn(3), randn(4), randn(3)),
Bidiagonal(randn(3), randn(2), rand(Bool)),
SymTridiagonal(randn(3), randn(2)),
sparse(randn(3,4)),
Diagonal(randn(5)),
sparse(rand(3)),
LowerTriangular(randn(3,3)),
UpperTriangular(randn(3,3))
]
for A in exotic_arrays
fill!(A, 0)
for a in A
@test a == 0
end
end
end
let # fill!(small, x)
val = randn()
b = Bidiagonal(randn(1,1), true)
st = SymTridiagonal(randn(1,1))
for x in (b, st)
@test Array(fill!(x, val)) == fill!(Array(x), val)
end
b = Bidiagonal(randn(2,2), true)
st = SymTridiagonal(randn(3), randn(2))
t = Tridiagonal(randn(3,3))
for x in (b, t, st)
@test_throws ArgumentError fill!(x, val)
@test Array(fill!(x, 0)) == fill!(Array(x), 0)
end
end
end
end

View File

@@ -0,0 +1,126 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
using Base.Test
using Base.LinAlg: BlasComplex, BlasFloat, BlasReal, QRPivoted
n = 10
# Split n into 2 parts for tests needing two matrices
n1 = div(n, 2)
n2 = 2*n1
srand(1234321)
areal = randn(n,n)/2
aimg = randn(n,n)/2
a2real = randn(n,n)/2
a2img = randn(n,n)/2
breal = randn(n,2)/2
bimg = randn(n,2)/2
@testset for eltya in (Float32, Float64, Complex64, Complex128, Int)
a = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(areal, aimg) : areal)
a2 = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(a2real, a2img) : a2real)
@testset for atype in ("Array", "SubArray")
asym = a'+a # symmetric indefinite
apd = a'*a # symmetric positive-definite
if atype == "Array"
a = a
a2 = a2
else
a = view(a, 1:n, 1:n)
a2 = view(a2, 1:n, 1:n)
asym = view(asym, 1:n, 1:n)
apd = view(apd, 1:n, 1:n)
end
ε = εa = eps(abs(float(one(eltya))))
@testset for eltyb in (Float32, Float64, Complex64, Complex128, Int)
b = eltyb == Int ? rand(1:5, n, 2) : convert(Matrix{eltyb}, eltyb <: Complex ? complex.(breal, bimg) : breal)
@testset for btype in ("Array", "SubArray")
if btype == "Array"
b = b
else
b = view(b, 1:n, 1:2)
end
εb = eps(abs(float(one(eltyb))))
ε = max(εa,εb)
@testset "(Automatic) Bunch-Kaufman factor of indefinite matrix" begin
bc1 = factorize(asym)
@test logabsdet(bc1)[1] log(abs(det(bc1)))
if eltya <: Real
@test logabsdet(bc1)[2] == sign(det(bc1))
else
@test logabsdet(bc1)[2] sign(det(bc1))
end
@test inv(bc1)*asym eye(n)
@test asym*(bc1\b) b atol=1000ε
@testset for rook in (false, true)
@test inv(bkfact(a.'+a, :U, true, rook))*(a.'+a) eye(n)
@test size(bc1) == size(bc1.LD)
@test size(bc1,1) == size(bc1.LD,1)
@test size(bc1,2) == size(bc1.LD,2)
if eltya <: BlasReal
@test_throws ArgumentError bkfact(a)
end
end
end
@testset "Bunch-Kaufman factors of a pos-def matrix" begin
@testset for rook in (false, true)
bc2 = bkfact(apd, :U, issymmetric(apd), rook)
@test logdet(bc2) log(det(bc2))
@test logabsdet(bc2)[1] log(abs(det(bc2)))
@test logabsdet(bc2)[2] == sign(det(bc2))
@test inv(bc2)*apd eye(n)
@test apd*(bc2\b) b atol=150000ε
@test ishermitian(bc2) == !issymmetric(bc2)
end
end
end
end
end
end
@testset "Bunch-Kaufman factors of a singular matrix" begin
let As1 = ones(n, n)
As2 = complex(ones(n, n))
As3 = complex(ones(n, n))
As3[end, 1] += im
As3[1, end] -= im
for As = (As1, As2, As3)
@testset for Astype in ("Array", "SubArray")
if Astype == "Array"
As = As
else
As = view(As, 1:n, 1:n)
end
@testset for rook in (false, true)
F = bkfact(As, :U, issymmetric(As), rook)
@test det(F) == 0
@test_throws LinAlg.SingularException inv(F)
@test_throws LinAlg.SingularException F \ ones(size(As, 1))
end
end
end
end
end
# test example due to @timholy in PR 15354
let
A = rand(6,5); A = complex(A'*A) # to avoid calling the real-lhs-complex-rhs method
F = cholfact(A);
v6 = rand(Complex128, 6)
v5 = view(v6, 1:5)
@test F\v5 == F\v6[1:5]
end
@test_throws DomainError logdet(bkfact([-1 -1; -1 1]))
@test logabsdet(bkfact([8 4; 4 2]))[1] == -Inf

View File

@@ -0,0 +1,274 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
debug = false
using Base.Test
using Base.LinAlg: BlasComplex, BlasFloat, BlasReal, QRPivoted
n = 10
# Split n into 2 parts for tests needing two matrices
n1 = div(n, 2)
n2 = 2*n1
srand(1234321)
areal = randn(n,n)/2
aimg = randn(n,n)/2
a2real = randn(n,n)/2
a2img = randn(n,n)/2
breal = randn(n,2)/2
bimg = randn(n,2)/2
for eltya in (Float32, Float64, Complex64, Complex128, BigFloat, Int)
a = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(areal, aimg) : areal)
a2 = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(a2real, a2img) : a2real)
apd = a'*a # symmetric positive-definite
apds = Symmetric(apd)
apdsL = Symmetric(apd, :L)
apdh = Hermitian(apd)
apdhL = Hermitian(apd, :L)
ε = εa = eps(abs(float(one(eltya))))
@inferred cholfact(apd)
@inferred chol(apd)
capd = factorize(apd)
r = capd[:U]
κ = cond(apd, 1) #condition number
#getindex
@test_throws KeyError capd[:Z]
#Test error bound on reconstruction of matrix: LAWNS 14, Lemma 2.1
#these tests were failing on 64-bit linux when inside the inner loop
#for eltya = Complex64 and eltyb = Int. The E[i,j] had NaN32 elements
#but only with srand(1234321) set before the loops.
E = abs.(apd - r'*r)
for i=1:n, j=1:n
@test E[i,j] <= (n+1)ε/(1-(n+1)ε)*real(sqrt(apd[i,i]*apd[j,j]))
end
E = abs.(apd - full(capd))
for i=1:n, j=1:n
@test E[i,j] <= (n+1)ε/(1-(n+1)ε)*real(sqrt(apd[i,i]*apd[j,j]))
end
@test apd*inv(capd) eye(n)
@test abs((det(capd) - det(apd))/det(capd)) <= ε*κ*n # Ad hoc, but statistically verified, revisit
@test @inferred(logdet(capd)) log(det(capd)) # logdet is less likely to overflow
apos = apd[1,1] # test chol(x::Number), needs x>0
@test all(x -> x apos, cholfact(apos).factors)
@test_throws ArgumentError chol(-one(eltya))
if eltya <: Real
capds = cholfact(apds)
@test inv(capds)*apds eye(n)
@test abs((det(capds) - det(apd))/det(capds)) <= ε*κ*n
if eltya <: BlasReal
capds = cholfact!(copy(apds))
@test inv(capds)*apds eye(n)
@test abs((det(capds) - det(apd))/det(capds)) <= ε*κ*n
end
ulstring = sprint(show,capds[:UL])
@test sprint(show,capds) == "$(typeof(capds)) with factor:\n$ulstring"
else
capdh = cholfact(apdh)
@test inv(capdh)*apdh eye(n)
@test abs((det(capdh) - det(apd))/det(capdh)) <= ε*κ*n
capdh = cholfact!(copy(apdh))
@test inv(capdh)*apdh eye(n)
@test abs((det(capdh) - det(apd))/det(capdh)) <= ε*κ*n
capdh = cholfact!(copy(apd))
@test inv(capdh)*apdh eye(n)
@test abs((det(capdh) - det(apd))/det(capdh)) <= ε*κ*n
capdh = cholfact!(copy(apd), :L)
@test inv(capdh)*apdh eye(n)
@test abs((det(capdh) - det(apd))/det(capdh)) <= ε*κ*n
ulstring = sprint(show,capdh[:UL])
@test sprint(show,capdh) == "$(typeof(capdh)) with factor:\n$ulstring"
end
# test chol of 2x2 Strang matrix
S = convert(AbstractMatrix{eltya},full(SymTridiagonal([2,2],[-1])))
U = Bidiagonal([2,sqrt(eltya(3))],[-1],true) / sqrt(eltya(2))
@test full(chol(S)) full(U)
#lower Cholesky factor
lapd = cholfact(apd, :L)
@test full(lapd) apd
l = lapd[:L]
@test l*l' apd
@test triu(capd.factors) lapd[:U]
@test tril(lapd.factors) capd[:L]
if eltya <: Real
capds = cholfact(apds)
lapds = cholfact(apdsL)
cl = chol(apdsL)
ls = lapds[:L]
@test ls*ls' apd
@test triu(capds.factors) lapds[:U]
@test tril(lapds.factors) capds[:L]
@test istriu(cl)
@test cl'cl apds
@test cl'cl apdsL
else
capdh = cholfact(apdh)
lapdh = cholfact(apdhL)
cl = chol(apdhL)
ls = lapdh[:L]
@test ls*ls' apd
@test triu(capdh.factors) lapdh[:U]
@test tril(lapdh.factors) capdh[:L]
@test istriu(cl)
@test cl'cl apdh
@test cl'cl apdhL
end
#pivoted upper Cholesky
if eltya != BigFloat
cz = cholfact(zeros(eltya,n,n), :U, Val{true})
@test_throws Base.LinAlg.RankDeficientException Base.LinAlg.chkfullrank(cz)
cpapd = cholfact(apd, :U, Val{true})
@test rank(cpapd) == n
@test all(diff(diag(real(cpapd.factors))).<=0.) # diagonal should be non-increasing
if isreal(apd)
@test apd*inv(cpapd) eye(n)
end
@test full(cpapd) apd
#getindex
@test_throws KeyError cpapd[:Z]
@test size(cpapd) == size(apd)
@test full(copy(cpapd)) apd
@test det(cpapd) det(apd)
@test logdet(cpapd) logdet(apd)
@test cpapd[:P]*cpapd[:L]*cpapd[:U]*cpapd[:P]' apd
end
for eltyb in (Float32, Float64, Complex64, Complex128, Int)
b = eltyb == Int ? rand(1:5, n, 2) : convert(Matrix{eltyb}, eltyb <: Complex ? complex.(breal, bimg) : breal)
εb = eps(abs(float(one(eltyb))))
ε = max(εa,εb)
debug && println("\ntype of a: ", eltya, " type of b: ", eltyb, "\n")
let Bs = b
for atype in ("Array", "SubArray")
if atype == "Array"
b = Bs
else
b = view(Bs, 1:n, 1)
end
# Test error bound on linear solver: LAWNS 14, Theorem 2.1
# This is a surprisingly loose bound
x = capd\b
@test norm(x-apd\b,1)/norm(x,1) <= (3n^2 + n + n^3*ε)*ε/(1-(n+1)*ε)*κ
@test norm(apd*x-b,1)/norm(b,1) <= (3n^2 + n + n^3*ε)*ε/(1-(n+1)*ε)*κ
@test norm(a*(capd\(a'*b)) - b,1)/norm(b,1) <= ε*κ*n # Ad hoc, revisit
if eltya != BigFloat && eltyb != BigFloat
@test norm(apd * (lapd\b) - b)/norm(b) <= ε*κ*n
@test norm(apd * (lapd\b[1:n]) - b[1:n])/norm(b[1:n]) <= ε*κ*n
end
@test_throws DimensionMismatch lapd\RowVector(ones(n))
debug && println("pivoted Cholesky decomposition")
if eltya != BigFloat && eltyb != BigFloat # Note! Need to implement pivoted Cholesky decomposition in julia
@test norm(apd * (cpapd\b) - b)/norm(b) <= ε*κ*n # Ad hoc, revisit
@test norm(apd * (cpapd\b[1:n]) - b[1:n])/norm(b[1:n]) <= ε*κ*n
lpapd = cholfact(apd, :L, Val{true})
@test norm(apd * (lpapd\b) - b)/norm(b) <= ε*κ*n # Ad hoc, revisit
@test norm(apd * (lpapd\b[1:n]) - b[1:n])/norm(b[1:n]) <= ε*κ*n
@test_throws BoundsError lpapd\RowVector(ones(n))
end
end
end
end
end
begin
# Cholesky factor of Matrix with non-commutative elements, here 2x2-matrices
X = Matrix{Float64}[0.1*rand(2,2) for i in 1:3, j = 1:3]
L = full(Base.LinAlg._chol!(X*X', LowerTriangular))
U = full(Base.LinAlg._chol!(X*X', UpperTriangular))
XX = full(X*X')
@test sum(sum(norm, L*L' - XX)) < eps()
@test sum(sum(norm, U'*U - XX)) < eps()
end
# Test generic cholfact!
for elty in (Float32, Float64, Complex{Float32}, Complex{Float64})
if elty <: Complex
A = complex.(randn(5,5), randn(5,5))
else
A = randn(5,5)
end
A = convert(Matrix{elty}, A'A)
@test full(cholfact(A)[:L]) full(invoke(Base.LinAlg._chol!, Tuple{AbstractMatrix, Type{LowerTriangular}}, copy(A), LowerTriangular))
@test full(cholfact(A)[:U]) full(invoke(Base.LinAlg._chol!, Tuple{AbstractMatrix, Type{UpperTriangular}}, copy(A), UpperTriangular))
end
# Test up- and downdates
let A = complex.(randn(10,5), randn(10, 5)), v = complex.(randn(5), randn(5))
for uplo in (:U, :L)
AcA = A'A
BcB = AcA + v*v'
BcB = (BcB + BcB')/2
F = cholfact(AcA, uplo)
G = cholfact(BcB, uplo)
@test LinAlg.lowrankupdate(F, v)[uplo] G[uplo]
@test_throws DimensionMismatch LinAlg.lowrankupdate(F, ones(eltype(v), length(v)+1))
@test LinAlg.lowrankdowndate(G, v)[uplo] F[uplo]
@test_throws DimensionMismatch LinAlg.lowrankdowndate(G, ones(eltype(v), length(v)+1))
end
end
# issue #13243, unexpected nans in complex cholfact
let apd = [5.8525753f0 + 0.0f0im -0.79540455f0 + 0.7066077f0im 0.98274714f0 + 1.3824869f0im 2.619998f0 + 1.8532984f0im -1.8306153f0 - 1.2336911f0im 0.32275113f0 + 0.015575029f0im 2.1968813f0 + 1.0640624f0im 0.27894387f0 + 0.97911835f0im 3.0476584f0 + 0.18548489f0im 0.3842994f0 + 0.7050991f0im
-0.79540455f0 - 0.7066077f0im 8.313246f0 + 0.0f0im -1.8076122f0 - 0.8882447f0im 0.47806996f0 + 0.48494184f0im 0.5096429f0 - 0.5395974f0im -0.7285097f0 - 0.10360408f0im -1.1760061f0 - 2.7146957f0im -0.4271084f0 + 0.042899966f0im -1.7228563f0 + 2.8335886f0im 1.8942566f0 + 0.6389735f0im
0.98274714f0 - 1.3824869f0im -1.8076122f0 + 0.8882447f0im 9.367975f0 + 0.0f0im -0.1838578f0 + 0.6468568f0im -1.8338387f0 + 0.7064959f0im 0.041852742f0 - 0.6556877f0im 2.5673025f0 + 1.9732997f0im -1.1148382f0 - 0.15693812f0im 2.4704504f0 - 1.0389464f0im 1.0858271f0 - 1.298006f0im
2.619998f0 - 1.8532984f0im 0.47806996f0 - 0.48494184f0im -0.1838578f0 - 0.6468568f0im 3.1117508f0 + 0.0f0im -1.956626f0 + 0.22825956f0im 0.07081801f0 - 0.31801307f0im 0.3698375f0 - 0.5400855f0im 0.80686307f0 + 1.5315914f0im 1.5649154f0 - 1.6229297f0im -0.112077385f0 + 1.2014246f0im
-1.8306153f0 + 1.2336911f0im 0.5096429f0 + 0.5395974f0im -1.8338387f0 - 0.7064959f0im -1.956626f0 - 0.22825956f0im 3.6439795f0 + 0.0f0im -0.2594722f0 + 0.48786148f0im -0.47636223f0 - 0.27821827f0im -0.61608654f0 - 2.01858f0im -2.7767487f0 + 1.7693765f0im 0.048102796f0 - 0.9741874f0im
0.32275113f0 - 0.015575029f0im -0.7285097f0 + 0.10360408f0im 0.041852742f0 + 0.6556877f0im 0.07081801f0 + 0.31801307f0im -0.2594722f0 - 0.48786148f0im 3.624376f0 + 0.0f0im -1.6697118f0 + 0.4017511f0im -1.4397877f0 - 0.7550918f0im -0.31456697f0 - 1.0403451f0im -0.31978557f0 + 0.13701046f0im
2.1968813f0 - 1.0640624f0im -1.1760061f0 + 2.7146957f0im 2.5673025f0 - 1.9732997f0im 0.3698375f0 + 0.5400855f0im -0.47636223f0 + 0.27821827f0im -1.6697118f0 - 0.4017511f0im 6.8273163f0 + 0.0f0im -0.10051322f0 + 0.24303961f0im 1.4415971f0 + 0.29750675f0im 1.221786f0 - 0.85654986f0im
0.27894387f0 - 0.97911835f0im -0.4271084f0 - 0.042899966f0im -1.1148382f0 + 0.15693812f0im 0.80686307f0 - 1.5315914f0im -0.61608654f0 + 2.01858f0im -1.4397877f0 + 0.7550918f0im -0.10051322f0 - 0.24303961f0im 3.4057708f0 + 0.0f0im -0.5856801f0 - 1.0203559f0im 0.7103452f0 + 0.8422135f0im
3.0476584f0 - 0.18548489f0im -1.7228563f0 - 2.8335886f0im 2.4704504f0 + 1.0389464f0im 1.5649154f0 + 1.6229297f0im -2.7767487f0 - 1.7693765f0im -0.31456697f0 + 1.0403451f0im 1.4415971f0 - 0.29750675f0im -0.5856801f0 + 1.0203559f0im 7.005772f0 + 0.0f0im -0.9617417f0 - 1.2486815f0im
0.3842994f0 - 0.7050991f0im 1.8942566f0 - 0.6389735f0im 1.0858271f0 + 1.298006f0im -0.112077385f0 - 1.2014246f0im 0.048102796f0 + 0.9741874f0im -0.31978557f0 - 0.13701046f0im 1.221786f0 + 0.85654986f0im 0.7103452f0 - 0.8422135f0im -0.9617417f0 + 1.2486815f0im 3.4629636f0 + 0.0f0im]
b = [-0.905011814118756 + 0.2847570854574069im -0.7122162951294634 - 0.630289556702497im
-0.7620356655676837 + 0.15533508334193666im 0.39947219167701153 - 0.4576746001199889im
-0.21782716937787788 - 0.9222220085490986im -0.727775859267237 + 0.50638268521728im
-1.0509472322215125 + 0.5022165705328413im -0.7264975746431271 + 0.31670415674097235im
-0.6650468984506477 - 0.5000967284800251im -0.023682508769195098 + 0.18093440285319276im
-0.20604111555491242 + 0.10570814584017311im 0.562377322638969 - 0.2578030745663871im
-0.3451346708401685 + 1.076948486041297im 0.9870834574024372 - 0.2825689605519449im
0.25336108035924787 + 0.975317836492159im 0.0628393808469436 - 0.1253397353973715im
0.11192755545114 - 0.1603741874112385im 0.8439562576196216 + 1.0850814110398734im
-1.0568488936791578 - 0.06025820467086475im 0.12696236014017806 - 0.09853584666755086im]
cholfact(apd, :L, Val{true}) \ b
r = factorize(apd)[:U]
E = abs.(apd - r'*r)
ε = eps(abs(float(one(Complex64))))
n = 10
for i=1:n, j=1:n
@test E[i,j] <= (n+1)ε/(1-(n+1)ε)*real(sqrt(apd[i,i]*apd[j,j]))
end
end
# Fail if non-Hermitian
@test_throws ArgumentError cholfact(randn(5,5))
@test_throws ArgumentError cholfact(complex.(randn(5,5), randn(5,5)))
@test_throws ArgumentError Base.LinAlg.chol!(randn(5,5))
@test_throws ArgumentError Base.LinAlg.cholfact!(randn(5,5),:U,Val{false})
@test_throws ArgumentError Base.LinAlg.cholfact!(randn(5,5),:U,Val{true})
@test_throws ArgumentError cholfact(randn(5,5),:U,Val{false})
# Fail for non-BLAS element types
@test_throws ArgumentError cholfact!(Hermitian(rand(Float16, 5,5)), Val{true})

View File

@@ -0,0 +1,28 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
@testset "Core" begin
m = [1+im 2; 2 4-im]
cm = ConjMatrix(m)
@test cm[1,1] == 1-im
@test cm[1] == 1-im
@test trace(cm*m) == 27
@test cm' == m
cm[:,2] = [3; 3-im] #setindex! with a vector
@test conj(cm) == [1+im 3; 2 3+im]
v = [[1+im], [1-im]]
cv = ConjVector(v)
@test cv[1] == [1-im]
end
@testset "RowVector conjugates" begin
v = [1+im, 1-im]
rv = v'
@test (parent(rv) isa ConjArray)
@test rv' === v
# Currently, view behavior defaults to only RowVectors.
@test isa((v').', Vector)
@test isa((v.')', Vector)
end

View File

@@ -0,0 +1,640 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
using Base.Test
@testset "Check that non-floats are correctly promoted" begin
@test [1 0 0; 0 1 0]\[1,1] [1;1;0]
end
using Base.LinAlg: BlasComplex, BlasFloat, BlasReal
n = 10
# Split n into 2 parts for tests needing two matrices
n1 = div(n, 2)
n2 = 2*n1
srand(1234321)
@testset "Matrix condition number" begin
ainit = rand(n,n)
@testset "for $elty" for elty in (Float32, Float64, Complex64, Complex128)
ainit = convert(Matrix{elty}, ainit)
for arraytype in ("Array", "SubArray")
if arraytype == "Array"
a = ainit
else
a = view(ainit, 1:n, 1:n)
end
@test cond(a,1) 4.837320054554436e+02 atol=0.01
@test cond(a,2) 1.960057871514615e+02 atol=0.01
@test cond(a,Inf) 3.757017682707787e+02 atol=0.01
@test cond(a[:,1:5]) 10.233059337453463 atol=0.01
@test_throws ArgumentError cond(a,3)
end
end
end
areal = randn(n,n)/2
aimg = randn(n,n)/2
a2real = randn(n,n)/2
a2img = randn(n,n)/2
breal = randn(n,2)/2
bimg = randn(n,2)/2
@testset "For A containing $eltya" for eltya in (Float32, Float64, Complex64, Complex128, Int)
ainit = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(areal, aimg) : areal)
ainit2 = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(a2real, a2img) : a2real)
ε = εa = eps(abs(float(one(eltya))))
apd = ainit'*ainit # symmetric positive-definite
@testset "Positive definiteness" begin
@test isposdef(apd,:U)
end
@testset "For b containing $eltyb" for eltyb in (Float32, Float64, Complex64, Complex128, Int)
binit = eltyb == Int ? rand(1:5, n, 2) : convert(Matrix{eltyb}, eltyb <: Complex ? complex.(breal, bimg) : breal)
εb = eps(abs(float(one(eltyb))))
ε = max(εa,εb)
for arraytype in ("Array", "SubArray")
if arraytype == "Array"
a = ainit
b = binit
else
a = view(ainit, 1:n, 1:n)
b = view(binit, 1:n, 1:2)
end
@testset "Solve square general system of equations" begin
κ = cond(a,1)
x = a \ b
@test_throws DimensionMismatch b'\b
@test_throws DimensionMismatch b\b'
@test norm(a*x - b, 1)/norm(b) < ε*κ*n*2 # Ad hoc, revisit!
@test zeros(eltya,n)\ones(eltya,n) zeros(eltya,n,1)\ones(eltya,n,1)
end
@testset "Test nullspace" begin
a15null = nullspace(a[:,1:n1]')
@test rank([a[:,1:n1] a15null]) == 10
@test norm(a[:,1:n1]'a15null,Inf) zero(eltya) atol=300ε
@test norm(a15null'a[:,1:n1],Inf) zero(eltya) atol=400ε
@test size(nullspace(b), 2) == 0
@test nullspace(zeros(eltya,n)) == eye(eltya,1)
end
end
end # for eltyb
for arraytype in ("Array", "SubArray")
if arraytype == "Array"
a = ainit
a2 = ainit2
else
a = view(ainit, 1:n, 1:n)
a2 = view(ainit2, 1:n, 1:n)
end
@testset "Test pinv" begin
pinva15 = pinv(a[:,1:n1])
@test a[:,1:n1]*pinva15*a[:,1:n1] a[:,1:n1]
@test pinva15*a[:,1:n1]*pinva15 pinva15
@test size(pinv(ones(eltya,0,0))) == (0,0)
end
@testset "Lyapunov/Sylvester" begin
x = lyap(a, a2)
@test -a2 a*x + x*a'
x2 = sylvester(a[1:3, 1:3], a[4:n, 4:n], a2[1:3,4:n])
@test -a2[1:3, 4:n] a[1:3, 1:3]*x2 + x2*a[4:n, 4:n]
end
@testset "Matrix square root" begin
asq = sqrtm(a)
@test asq*asq a
asym = a'+a # symmetric indefinite
asymsq = sqrtm(asym)
@test asymsq*asymsq asym
end
@testset "Powers" begin
if eltya <: AbstractFloat
z = zero(eltya)
t = convert(eltya,2)
r = convert(eltya,2.5)
@test a^z eye(a)
@test a^t a^2
@test eye(eltya,n,n)^r eye(a)
end
end
end # end for loop over arraytype
@testset "Numbers" begin
α = rand(eltya)
A = zeros(eltya,1,1)
A[1,1] = α
@test diagm(α) == A # Test behavior of `diagm` when passed a scalar
@test expm(α) == exp(α) # `expm` should behave like `exp` with scalar argument
end
@testset "Factorize" begin
d = rand(eltya,n)
e = rand(eltya,n-1)
e2 = rand(eltya,n-1)
f = rand(eltya,n-2)
A = diagm(d)
@test factorize(A) == Diagonal(d)
A += diagm(e,-1)
@test factorize(A) == Bidiagonal(d,e,false)
A += diagm(f,-2)
@test factorize(A) == LowerTriangular(A)
A = diagm(d) + diagm(e,1)
@test factorize(A) == Bidiagonal(d,e,true)
if eltya <: Real
A = diagm(d) + diagm(e,1) + diagm(e,-1)
@test full(factorize(A)) full(factorize(SymTridiagonal(d,e)))
A = diagm(d) + diagm(e,1) + diagm(e,-1) + diagm(f,2) + diagm(f,-2)
@test inv(factorize(A)) inv(factorize(Symmetric(A)))
end
A = diagm(d) + diagm(e,1) + diagm(e2,-1)
@test full(factorize(A)) full(factorize(Tridiagonal(e2,d,e)))
A = diagm(d) + diagm(e,1) + diagm(f,2)
@test factorize(A) == UpperTriangular(A)
end
end # for eltya
@testset "test triu/tril bounds checking" begin
ainit = rand(5,7)
for arraytype in ("Array", "SubArray")
if arraytype == "Array"
a = ainit
else
a = view(ainit, 1:size(ainit, 1), 1:size(ainit, 2))
end
@test_throws(ArgumentError,triu(a,8))
@test_throws(ArgumentError,triu(a,-6))
@test_throws(ArgumentError,tril(a,8))
@test_throws(ArgumentError,tril(a,-6))
end
end
@testset "Test gradient for $elty" for elty in (Int32, Int64, Float32, Float64, Complex64, Complex128)
if elty <: Real
x = convert(Vector{elty}, [1:3;])
g = ones(elty, 3)
else
x = convert(Vector{elty}, complex.([1:3;], [1:3;]))
g = convert(Vector{elty}, complex.(ones(3), ones(3)))
end
xsub = view(x, 1:size(x, 1))
@test gradient(x) g
@test gradient(xsub) g # Test gradient on SubArray
@test gradient(ones(elty,1)) == zeros(elty,1)
end
@testset "Tests norms" begin
nnorm = 10
mmat = 10
nmat = 8
@testset "For $elty" for elty in (Float32, Float64, BigFloat, Complex{Float32}, Complex{Float64}, Complex{BigFloat}, Int32, Int64, BigInt)
x = ones(elty,10)
@testset "Vector" begin
xs = view(x,1:2:10)
@test norm(x, -Inf) 1
@test norm(x, -1) 1/10
@test norm(x, 0) 10
@test norm(x, 1) 10
@test norm(x, 2) sqrt(10)
@test norm(x, 3) cbrt(10)
@test norm(x, Inf) 1
if elty <: Base.LinAlg.BlasFloat
@test norm(x, 1:4) 2
@test_throws BoundsError norm(x,-1:4)
@test_throws BoundsError norm(x,1:11)
end
@test norm(xs, -Inf) 1
@test norm(xs, -1) 1/5
@test norm(xs, 0) 5
@test norm(xs, 1) 5
@test norm(xs, 2) sqrt(5)
@test norm(xs, 3) cbrt(5)
@test norm(xs, Inf) 1
end
@testset "Issue #12552:" begin
if real(elty) <: AbstractFloat
for p in [-Inf,-1,1,2,3,Inf]
@test isnan(norm(elty[0,NaN],p))
@test isnan(norm(elty[NaN,0],p))
end
end
end
@testset "Number" begin
norm(x[1:1]) === norm(x[1], -Inf)
norm(x[1:1]) === norm(x[1], 0)
norm(x[1:1]) === norm(x[1], 1)
norm(x[1:1]) === norm(x[1], 2)
norm(x[1:1]) === norm(x[1], Inf)
end
@testset "Absolute homogeneity, triangle inequality, & vectorized versions" begin
for i = 1:10
xinit = elty <: Integer ? convert(Vector{elty}, rand(1:10, nnorm)) :
elty <: Complex ? convert(Vector{elty}, complex.(randn(nnorm), randn(nnorm))) :
convert(Vector{elty}, randn(nnorm))
yinit = elty <: Integer ? convert(Vector{elty}, rand(1:10, nnorm)) :
elty <: Complex ? convert(Vector{elty}, complex.(randn(nnorm), randn(nnorm))) :
convert(Vector{elty}, randn(nnorm))
α = elty <: Integer ? randn() :
elty <: Complex ? convert(elty, complex(randn(),randn())) :
convert(elty, randn())
for arraytype in ("Array", "SubArray")
if arraytype == "Array"
x = xinit
y = yinit
else
x = view(xinit,1:2:nnorm)
y = view(yinit,1:2:nnorm)
end
# Absolute homogeneity
@test norm(α*x,-Inf) abs(α)*norm(x,-Inf)
@test norm(α*x,-1) abs(α)*norm(x,-1)
@test norm(α*x,1) abs(α)*norm(x,1)
@test norm(α*x) abs(α)*norm(x) # two is default
@test norm(α*x,3) abs(α)*norm(x,3)
@test norm(α*x,Inf) abs(α)*norm(x,Inf)
# Triangle inequality
@test norm(x + y,1) <= norm(x,1) + norm(y,1)
@test norm(x + y) <= norm(x) + norm(y) # two is default
@test norm(x + y,3) <= norm(x,3) + norm(y,3)
@test norm(x + y,Inf) <= norm(x,Inf) + norm(y,Inf)
# Against vectorized versions
@test norm(x,-Inf) minimum(abs.(x))
@test norm(x,-1) inv(sum(1./abs.(x)))
@test norm(x,0) sum(x .!= 0)
@test norm(x,1) sum(abs.(x))
@test norm(x) sqrt(sum(abs2.(x)))
@test norm(x,3) cbrt(sum(abs.(x).^3.))
@test norm(x,Inf) maximum(abs.(x))
end
end
end
@testset "Matrix (Operator)" begin
A = ones(elty,10,10)
As = view(A,1:5,1:5)
@test norm(A, 1) 10
elty <: Union{BigFloat,Complex{BigFloat},BigInt} || @test norm(A, 2) 10
@test norm(A, Inf) 10
@test norm(As, 1) 5
elty <: Union{BigFloat,Complex{BigFloat},BigInt} || @test norm(As, 2) 5
@test norm(As, Inf) 5
end
@testset "Absolute homogeneity, triangle inequality, & vecnorm" begin
for i = 1:10
Ainit = elty <: Integer ? convert(Matrix{elty}, rand(1:10, mmat, nmat)) :
elty <: Complex ? convert(Matrix{elty}, complex.(randn(mmat, nmat), randn(mmat, nmat))) :
convert(Matrix{elty}, randn(mmat, nmat))
Binit = elty <: Integer ? convert(Matrix{elty}, rand(1:10, mmat, nmat)) :
elty <: Complex ? convert(Matrix{elty}, complex.(randn(mmat, nmat), randn(mmat, nmat))) :
convert(Matrix{elty}, randn(mmat, nmat))
α = elty <: Integer ? randn() :
elty <: Complex ? convert(elty, complex(randn(),randn())) :
convert(elty, randn())
for arraytype in ("Array", "SubArray")
if arraytype == "Array"
A = Ainit
B = Binit
else
A = view(Ainit,1:nmat,1:nmat)
B = view(Binit,1:nmat,1:nmat)
end
# Absolute homogeneity
@test norm(α*A,1) abs(α)*norm(A,1)
elty <: Union{BigFloat,Complex{BigFloat},BigInt} || @test norm(α*A) abs(α)*norm(A) # two is default
@test norm(α*A,Inf) abs(α)*norm(A,Inf)
# Triangle inequality
@test norm(A + B,1) <= norm(A,1) + norm(B,1)
elty <: Union{BigFloat,Complex{BigFloat},BigInt} || @test norm(A + B) <= norm(A) + norm(B) # two is default
@test norm(A + B,Inf) <= norm(A,Inf) + norm(B,Inf)
# vecnorm:
for p = -2:3
@test norm(reshape(A, length(A)), p) == vecnorm(A, p)
end
end
end
@testset "issue #10234" begin
if elty <: AbstractFloat || elty <: Complex
z = zeros(elty, 100)
z[1] = -Inf
for p in [-2,-1.5,-1,-0.5,0.5,1,1.5,2,Inf]
@test norm(z, p) == (p < 0 ? 0 : Inf)
@test norm(elty[Inf],p) == Inf
end
end
end
end
end
@testset "issue #10234" begin
@test norm(Any[Inf],-2) == norm(Any[Inf],-1) == norm(Any[Inf],1) == norm(Any[Inf],1.5) == norm(Any[Inf],2) == norm(Any[Inf],Inf) == Inf
end
@testset "overflow/underflow in norms" begin
@test norm(Float64[1e-300, 1], -3)*1e300 1
@test norm(Float64[1e300, 1], 3)*1e-300 1
end
end
## Issue related tests
@testset "issue #1447" begin
A = [1.+0.0im 0; 0 1]
B = pinv(A)
for i = 1:4
@test A[i] B[i]
end
end
@testset "issue #2246" begin
A = [1 2 0 0; 0 1 0 0; 0 0 0 0; 0 0 0 0]
Asq = sqrtm(A)
@test Asq*Asq A
A2 = view(A, 1:2, 1:2)
A2sq = sqrtm(A2)
@test A2sq*A2sq A2
N = 3
@test log(det(eye(N))) logdet(eye(N))
end
@testset "issue #2637" begin
a = [1, 2, 3]
b = [4, 5, 6]
@test kron(eye(2),eye(2)) == eye(4)
@test kron(a,b) == [4,5,6,8,10,12,12,15,18]
@test kron(a',b') == [4 5 6 8 10 12 12 15 18]
@test kron(a,b') == [4 5 6; 8 10 12; 12 15 18]
@test kron(a',b) == [4 8 12; 5 10 15; 6 12 18]
@test kron(a,eye(2)) == [1 0; 0 1; 2 0; 0 2; 3 0; 0 3]
@test kron(eye(2),a) == [ 1 0; 2 0; 3 0; 0 1; 0 2; 0 3]
@test kron(eye(2),2) == 2*eye(2)
@test kron(3,eye(3)) == 3*eye(3)
@test kron(a,2) == [2, 4, 6]
@test kron(b',2) == [8 10 12]
end
@testset "issue #4796" begin
dim=2
S=zeros(Complex,dim,dim)
T=zeros(Complex,dim,dim)
T[:] = 1
z = 2.5 + 1.5im
S[1] = z
@test S*T == [z z; 0 0]
# similar issue for Array{Real}
@test Real[1 2] * Real[1.5; 2.0] == Real[5.5]
end
@testset "Matrix exponential" begin
@testset "Tests for $elty" for elty in (Float32, Float64, Complex64, Complex128)
A1 = convert(Matrix{elty}, [4 2 0; 1 4 1; 1 1 4])
eA1 = convert(Matrix{elty}, [147.866622446369 127.781085523181 127.781085523182;
183.765138646367 183.765138646366 163.679601723179;
71.797032399996 91.8825693231832 111.968106246371]')
@test expm(A1) eA1
A2 = convert(Matrix{elty},
[29.87942128909879 0.7815750847907159 -2.289519314033932;
0.7815750847907159 25.72656945571064 8.680737820540137;
-2.289519314033932 8.680737820540137 34.39400925519054])
eA2 = convert(Matrix{elty},
[ 5496313853692458.0 -18231880972009236.0 -30475770808580460.0;
-18231880972009252.0 60605228702221920.0 101291842930249760.0;
-30475770808580480.0 101291842930249728.0 169294411240851968.0])
@test expm(A2) eA2
A3 = convert(Matrix{elty}, [-131 19 18;-390 56 54;-387 57 52])
eA3 = convert(Matrix{elty}, [-1.50964415879218 -5.6325707998812 -4.934938326092;
0.367879439109187 1.47151775849686 1.10363831732856;
0.135335281175235 0.406005843524598 0.541341126763207]')
@test expm(A3) eA3
A4 = convert(Matrix{elty}, [0.25 0.25; 0 0])
eA4 = convert(Matrix{elty}, [1.2840254166877416 0.2840254166877415; 0 1])
@test expm(A4) eA4
A5 = convert(Matrix{elty}, [0 0.02; 0 0])
eA5 = convert(Matrix{elty}, [1 0.02; 0 1])
@test expm(A5) eA5
# Hessenberg
@test hessfact(A1)[:H] convert(Matrix{elty},
[4.000000000000000 -1.414213562373094 -1.414213562373095
-1.414213562373095 4.999999999999996 -0.000000000000000
0 -0.000000000000002 3.000000000000000])
end
@testset "Additional tests for $elty" for elty in (Float64, Complex{Float64})
A4 = convert(Matrix{elty}, [1/2 1/3 1/4 1/5+eps();
1/3 1/4 1/5 1/6;
1/4 1/5 1/6 1/7;
1/5 1/6 1/7 1/8])
@test expm(logm(A4)) A4
A5 = convert(Matrix{elty}, [1 1 0 1; 0 1 1 0; 0 0 1 1; 1 0 0 1])
@test expm(logm(A5)) A5
A6 = convert(Matrix{elty}, [-5 2 0 0 ; 1/2 -7 3 0; 0 1/3 -9 4; 0 0 1/4 -11])
@test expm(logm(A6)) A6
A7 = convert(Matrix{elty}, [1 0 0 1e-8; 0 1 0 0; 0 0 1 0; 0 0 0 1])
@test expm(logm(A7)) A7
end
A8 = 100 * [-1+1im 0 0 1e-8; 0 1 0 0; 0 0 1 0; 0 0 0 1]
@test expm(logm(A8)) A8
end
@testset "issue 5116" begin
A9 = [0 10 0 0; -1 0 0 0; 0 0 0 0; -2 0 0 0]
eA9 = [-0.999786072879326 -0.065407069689389 0.0 0.0
0.006540706968939 -0.999786072879326 0.0 0.0
0.0 0.0 1.0 0.0
0.013081413937878 -3.999572145758650 0.0 1.0]
@test expm(A9) eA9
A10 = [ 0. 0. 0. 0. ; 0. 0. -im 0.; 0. im 0. 0.; 0. 0. 0. 0.]
eA10 = [ 1.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im
0.0+0.0im 1.543080634815244+0.0im 0.0-1.175201193643801im 0.0+0.0im
0.0+0.0im 0.0+1.175201193643801im 1.543080634815243+0.0im 0.0+0.0im
0.0+0.0im 0.0+0.0im 0.0+0.0im 1.0+0.0im]
@test expm(A10) eA10
end
@testset "Additional matrix logarithm tests" for elty in (Float64, Complex{Float64})
A11 = convert(Matrix{elty}, [3 2; -5 -3])
@test expm(logm(A11)) A11
A12 = convert(Matrix{elty}, [1 -1; 1 -1])
@test typeof(logm(A12)) == Array{Complex{Float64}, 2}
A1 = convert(Matrix{elty}, [4 2 0; 1 4 1; 1 1 4])
logmA1 = convert(Matrix{elty}, [1.329661349 0.5302876358 -0.06818951543;
0.2310490602 1.295566591 0.2651438179;
0.2310490602 0.1969543025 1.363756107])
@test logm(A1) logmA1
@test expm(logm(A1)) A1
A4 = convert(Matrix{elty}, [1/2 1/3 1/4 1/5+eps();
1/3 1/4 1/5 1/6;
1/4 1/5 1/6 1/7;
1/5 1/6 1/7 1/8])
logmA4 = convert(Matrix{elty}, [-1.73297159 1.857349738 0.4462766564 0.2414170219;
1.857349738 -5.335033737 2.994142974 0.5865285289;
0.4462766564 2.994142974 -7.351095988 3.318413247;
0.2414170219 0.5865285289 3.318413247 -5.444632124])
@test logm(A4) logmA4
@test expm(logm(A4)) A4
end
@testset "issue #7181" begin
A = [ 1 5 9
2 6 10
3 7 11
4 8 12 ]
@test_throws ArgumentError diag(A, -5)
@test diag(A,-4) == []
@test diag(A,-3) == [4]
@test diag(A,-2) == [3,8]
@test diag(A,-1) == [2,7,12]
@test diag(A, 0) == [1,6,11]
@test diag(A, 1) == [5,10]
@test diag(A, 2) == [9]
@test diag(A, 3) == []
@test_throws ArgumentError diag(A, 4)
@test diag(zeros(0,0)) == []
@test_throws ArgumentError diag(zeros(0,0),1)
@test_throws ArgumentError diag(zeros(0,0),-1)
@test diag(zeros(1,0)) == []
@test diag(zeros(1,0),-1) == []
@test_throws ArgumentError diag(zeros(1,0),1)
@test_throws ArgumentError diag(zeros(1,0),-2)
@test diag(zeros(0,1)) == []
@test diag(zeros(0,1),1) == []
@test_throws ArgumentError diag(zeros(0,1),-1)
@test_throws ArgumentError diag(zeros(0,1),2)
end
@testset "Matrix to real power" for elty in (Float64, Complex{Float64})
# Tests proposed at Higham, Deadman: Testing Matrix Function Algorithms Using Identities, March 2014
#Aa : only positive real eigenvalues
Aa = convert(Matrix{elty}, [5 4 2 1; 0 1 -1 -1; -1 -1 3 0; 1 1 -1 2])
@test Aa^(1/2) sqrtm(Aa)
@test Aa^(-1/2) inv(sqrtm(Aa))
@test Aa^(3/4) sqrtm(Aa) * sqrtm(sqrtm(Aa))
@test Aa^(-3/4) inv(Aa) * sqrtm(sqrtm(Aa))
@test Aa^(17/8) Aa^2 * sqrtm(sqrtm(sqrtm(Aa)))
@test Aa^(-17/8) inv(Aa^2 * sqrtm(sqrtm(sqrtm(Aa))))
@test (Aa^0.2)^5 Aa
@test (Aa^(2/3))*(Aa^(1/3)) Aa
@test (Aa^im)^(-im) Aa
#Ab : both positive and negative real eigenvalues
Ab = convert(Matrix{elty}, [1 2 3; 4 7 1; 2 1 4])
@test Ab^(1/2) sqrtm(Ab)
@test Ab^(-1/2) inv(sqrtm(Ab))
@test Ab^(3/4) sqrtm(Ab) * sqrtm(sqrtm(Ab))
@test Ab^(-3/4) inv(Ab) * sqrtm(sqrtm(Ab))
@test Ab^(17/8) Ab^2 * sqrtm(sqrtm(sqrtm(Ab)))
@test Ab^(-17/8) inv(Ab^2 * sqrtm(sqrtm(sqrtm(Ab))))
@test (Ab^0.2)^5 Ab
@test (Ab^(2/3))*(Ab^(1/3)) Ab
@test (Ab^im)^(-im) Ab
#Ac : complex eigenvalues
Ac = convert(Matrix{elty}, [5 4 2 1;0 1 -1 -1;-1 -1 3 6;1 1 -1 5])
@test Ac^(1/2) sqrtm(Ac)
@test Ac^(-1/2) inv(sqrtm(Ac))
@test Ac^(3/4) sqrtm(Ac) * sqrtm(sqrtm(Ac))
@test Ac^(-3/4) inv(Ac) * sqrtm(sqrtm(Ac))
@test Ac^(17/8) Ac^2 * sqrtm(sqrtm(sqrtm(Ac)))
@test Ac^(-17/8) inv(Ac^2 * sqrtm(sqrtm(sqrtm(Ac))))
@test (Ac^0.2)^5 Ac
@test (Ac^(2/3))*(Ac^(1/3)) Ac
@test (Ac^im)^(-im) Ac
#Ad : defective Matrix
Ad = convert(Matrix{elty}, [3 1; 0 3])
@test Ad^(1/2) sqrtm(Ad)
@test Ad^(-1/2) inv(sqrtm(Ad))
@test Ad^(3/4) sqrtm(Ad) * sqrtm(sqrtm(Ad))
@test Ad^(-3/4) inv(Ad) * sqrtm(sqrtm(Ad))
@test Ad^(17/8) Ad^2 * sqrtm(sqrtm(sqrtm(Ad)))
@test Ad^(-17/8) inv(Ad^2 * sqrtm(sqrtm(sqrtm(Ad))))
@test (Ad^0.2)^5 Ad
@test (Ad^(2/3))*(Ad^(1/3)) Ad
@test (Ad^im)^(-im) Ad
end
@testset "Least squares solutions" begin
a = [ones(20) 1:20 1:20]
b = reshape(eye(8, 5), 20, 2)
@testset "Tests for type $elty" for elty in (Float32, Float64, Complex64, Complex128)
a = convert(Matrix{elty}, a)
b = convert(Matrix{elty}, b)
# Vector rhs
x = a[:,1:2]\b[:,1]
@test ((a[:,1:2]*x-b[:,1])'*(a[:,1:2]*x-b[:,1]))[1] convert(elty, 2.546616541353384)
# Matrix rhs
x = a[:,1:2]\b
@test det((a[:,1:2]*x-b)'*(a[:,1:2]*x-b)) convert(elty, 4.437969924812031)
# Rank deficient
x = a\b
@test det((a*x-b)'*(a*x-b)) convert(elty, 4.437969924812031)
# Underdetermined minimum norm
x = convert(Matrix{elty}, [1 0 0; 0 1 -1]) \ convert(Vector{elty}, [1,1])
@test x convert(Vector{elty}, [1, 0.5, -0.5])
# symmetric, positive definite
@test inv(convert(Matrix{elty}, [6. 2; 2 1])) convert(Matrix{elty}, [0.5 -1; -1 3])
# symmetric, indefinite
@test inv(convert(Matrix{elty}, [1. 2; 2 1])) convert(Matrix{elty}, [-1. 2; 2 -1]/3)
end
end
@testset "test ops on Numbers for $elty" for elty in [Float32,Float64,Complex64,Complex128]
a = rand(elty)
@test expm(a) == exp(a)
@test isposdef(one(elty))
@test sqrtm(a) == sqrt(a)
@test logm(a) log(a)
@test lyap(one(elty),a) == -a/2
end
@testset "stride1" begin
a = rand(10)
b = view(a,2:2:10)
@test Base.LinAlg.stride1(b) == 2
end

View File

@@ -0,0 +1,370 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
using Base.Test
import Base.LinAlg: BlasFloat, BlasComplex, SingularException
n=12 #Size of matrix problem to test
srand(1)
@testset for relty in (Float32, Float64, BigFloat), elty in (relty, Complex{relty})
d=convert(Vector{elty}, randn(n))
v=convert(Vector{elty}, randn(n))
U=convert(Matrix{elty}, randn(n,n))
if elty <: Complex
d+=im*convert(Vector{elty}, randn(n))
v+=im*convert(Vector{elty}, randn(n))
U+=im*convert(Matrix{elty}, randn(n,n))
end
D = Diagonal(d)
DM = diagm(d)
@testset "Basic properties" begin
@test eye(Diagonal{elty},n) == Diagonal(ones(elty,n))
@test_throws ArgumentError size(D,0)
@test typeof(convert(Diagonal{Complex64},D)) == Diagonal{Complex64}
@test typeof(convert(AbstractMatrix{Complex64},D)) == Diagonal{Complex64}
@test Array(real(D)) == real(DM)
@test Array(abs.(D)) == abs.(DM)
@test Array(imag(D)) == imag(DM)
@test parent(D) == d
@test diag(D) == d
@test D[1,1] == d[1]
@test D[1,2] == 0
@test issymmetric(D)
@test istriu(D)
@test istril(D)
if elty <: Real
@test ishermitian(D)
end
end
@testset "Simple unary functions" begin
for op in (-,)
@test op(D)==op(DM)
end
for func in (det, trace)
@test func(D) func(DM) atol=n^2*eps(relty)*(1+(elty<:Complex))
end
if relty <: BlasFloat
for func in (expm,)
@test func(D) func(DM) atol=n^3*eps(relty)
end
@test logm(Diagonal(abs.(D.diag))) logm(abs.(DM)) atol=n^3*eps(relty)
end
if elty <: BlasComplex
for func in (logdet, sqrtm)
@test func(D) func(DM) atol=n^2*eps(relty)*2
end
end
end
@testset "Linear solve" begin
let vv = v, UU = U
@testset for atype in ("Array", "SubArray")
if atype == "Array"
v = vv
U = UU
else
v = view(vv, 1:n)
U = view(UU, 1:n, 1:2)
end
@test D*v DM*v atol=n*eps(relty)*(1+(elty<:Complex))
@test D*U DM*U atol=n^2*eps(relty)*(1+(elty<:Complex))
@test U.'*D U.'*Array(D)
@test U'*D U'*Array(D)
if relty != BigFloat
@test D\v DM\v atol=2n^2*eps(relty)*(1+(elty<:Complex))
@test D\U DM\U atol=2n^3*eps(relty)*(1+(elty<:Complex))
@test A_ldiv_B!(D,copy(v)) DM\v atol=2n^2*eps(relty)*(1+(elty<:Complex))
@test A_ldiv_B!(D,copy(U)) DM\U atol=2n^3*eps(relty)*(1+(elty<:Complex))
@test A_ldiv_B!(D,eye(D)) D\eye(D) atol=2n^3*eps(relty)*(1+(elty<:Complex))
@test_throws DimensionMismatch A_ldiv_B!(D, ones(elty, n + 1))
@test_throws SingularException A_ldiv_B!(Diagonal(zeros(relty,n)),copy(v))
b = rand(elty,n,n)
b = sparse(b)
@test A_ldiv_B!(D,copy(b)) Array(D)\Array(b)
@test_throws SingularException A_ldiv_B!(Diagonal(zeros(elty,n)),copy(b))
b = view(rand(elty,n),collect(1:n))
b2 = copy(b)
c = A_ldiv_B!(D,b)
d = Array(D)\b2
for i in 1:n
@test c[i] d[i]
end
@test_throws SingularException A_ldiv_B!(Diagonal(zeros(elty,n)),b)
b = rand(elty,n+1,n+1)
b = sparse(b)
@test_throws DimensionMismatch A_ldiv_B!(D,copy(b))
b = view(rand(elty,n+1),collect(1:n+1))
@test_throws DimensionMismatch A_ldiv_B!(D,b)
end
end
end
end
d = convert(Vector{elty}, randn(n))
D2 = Diagonal(d)
DM2= diagm(d)
@testset "Binary operations" begin
for op in (+, -, *)
@test Array(op(D, D2)) op(DM, DM2)
end
@testset "with plain numbers" begin
a = rand()
@test Array(a*D) a*DM
@test Array(D*a) DM*a
@test Array(D/a) DM/a
if relty <: BlasFloat
b = rand(elty,n,n)
b = sparse(b)
@test A_mul_B!(copy(D), copy(b)) Array(D)*Array(b)
@test At_mul_B!(copy(D), copy(b)) Array(D).'*Array(b)
@test Ac_mul_B!(copy(D), copy(b)) Array(D)'*Array(b)
end
end
#a few missing mults
bd = Bidiagonal(D2)
@test D*D2.' Array(D)*Array(D2).'
@test D2*D.' Array(D2)*Array(D).'
@test D2*D' Array(D2)*Array(D)'
#division of two Diagonals
@test D/D2 Diagonal(D.diag./D2.diag)
@test D\D2 Diagonal(D2.diag./D.diag)
# Performance specialisations for A*_mul_B!
vv = similar(v)
@test (r = full(D) * v ; A_mul_B!(vv, D, v) r vv)
@test (r = full(D)' * v ; Ac_mul_B!(vv, D, v) r vv)
@test (r = full(D).' * v ; At_mul_B!(vv, D, v) r vv)
UU = similar(U)
@test (r = full(D) * U ; A_mul_B!(UU, D, U) r UU)
@test (r = full(D)' * U ; Ac_mul_B!(UU, D, U) r UU)
@test (r = full(D).' * U ; At_mul_B!(UU, D, U) r UU)
end
@testset "triu/tril" begin
@test istriu(D)
@test istril(D)
@test triu(D,1) == zeros(D)
@test triu(D,0) == D
@test triu(D,-1) == D
@test tril(D,1) == D
@test tril(D,-1) == zeros(D)
@test tril(D,0) == D
@test_throws ArgumentError tril(D,n+1)
@test_throws ArgumentError triu(D,n+1)
end
# factorize
@test factorize(D) == D
@testset "Eigensystem" begin
eigD = eigfact(D)
@test Diagonal(eigD[:values]) D
@test eigD[:vectors] == eye(D)
end
@testset "ldiv" begin
v = rand(n + 1)
@test_throws DimensionMismatch D\v
v = rand(n)
@test D\v DM\v
V = rand(n + 1, n)
@test_throws DimensionMismatch D\V
V = rand(n, n)
@test D\V DM\V
end
@testset "conj and transpose" begin
@test transpose(D) == D
if elty <: BlasComplex
@test Array(conj(D)) conj(DM)
@test ctranspose(D) == conj(D)
end
# Translates to Ac/t_mul_B, which is specialized after issue 21286
@test(D' * v == conj(D) * v)
@test(D.' * v == D * v)
end
#logdet
if relty <: Real
ld=convert(Vector{relty},rand(n))
@test logdet(Diagonal(ld)) logdet(diagm(ld))
end
@testset "similar" begin
@test isa(similar(D), Diagonal{elty})
@test isa(similar(D, Int), Diagonal{Int})
@test isa(similar(D, (3,2)), Matrix{elty})
@test isa(similar(D, Int, (3,2)), Matrix{Int})
end
# Issue number 10036
# make sure issymmetric/ishermitian work for
# non-real diagonal matrices
@testset "issymmetric/hermitian for complex Diagonal" begin
@test issymmetric(D2)
@test ishermitian(D2)
if elty <: Complex
dc = d + im*convert(Vector{elty}, ones(n))
D3 = Diagonal(dc)
@test issymmetric(D3)
@test !ishermitian(D3)
end
end
@testset "svd (#11120/#11247)" begin
U, s, V = svd(D)
@test (U*Diagonal(s))*V' D
@test svdvals(D) == s
@test svdfact(D)[:V] == V
end
end
@testset "svdvals and eigvals (#11120/#11247)" begin
D = Diagonal(Matrix{Float64}[randn(3,3), randn(2,2)])
@test sort([svdvals(D)...;], rev = true) svdvals([D.diag[1] zeros(3,2); zeros(2,3) D.diag[2]])
@test [eigvals(D)...;] eigvals([D.diag[1] zeros(3,2); zeros(2,3) D.diag[2]])
end
@testset "isposdef" begin
@test !isposdef(Diagonal(-1.0 * rand(n)))
end
@testset "getindex" begin
d = randn(n)
D = Diagonal(d)
# getindex bounds checking
@test_throws BoundsError D[0, 0]
@test_throws BoundsError D[-1, -2]
@test_throws BoundsError D[n, n + 1]
@test_throws BoundsError D[n + 1, n]
@test_throws BoundsError D[n + 1, n + 1]
# getindex on and off the diagonal
for i in 1:n, j in 1:n
@test D[i, j] == (i == j ? d[i] : 0)
end
end
@testset "setindex!" begin
d = randn(n)
D = Diagonal(d)
# setindex! bounds checking
@test_throws BoundsError D[0, 0] = 0
@test_throws BoundsError D[-1 , -2] = 0
@test_throws BoundsError D[n, n + 1] = 0
@test_throws BoundsError D[n + 1, n] = 0
@test_throws BoundsError D[n + 1, n + 1] = 0
for i in 1:n, j in 1:n
if i == j
# setindex on! the diagonal
@test ((D[i, j] = i) == i; D[i, j] == i)
else
# setindex! off the diagonal
@test ((D[i, j] = 0) == 0; iszero(D[i, j]))
@test_throws ArgumentError D[i, j] = 1
end
end
end
@testset "inverse" begin
for d in (randn(n), [1, 2, 3], [1im, 2im, 3im])
D = Diagonal(d)
@test inv(D) inv(Array(D))
end
@test_throws SingularException inv(Diagonal(zeros(n)))
@test_throws SingularException inv(Diagonal([0, 1, 2]))
@test_throws SingularException inv(Diagonal([0im, 1im, 2im]))
end
# allow construct from range
@test Diagonal(linspace(1,3,3)) == Diagonal([1.,2.,3.])
# Issue 12803
for t in (Float32, Float64, Int, Complex{Float64}, Rational{Int})
@test Diagonal(Matrix{t}[ones(t, 2, 2), ones(t, 3, 3)])[2,1] == zeros(t, 3, 2)
end
# Issue 15401
@test eye(5) \ Diagonal(ones(5)) == eye(5)
@testset "Triangular and Diagonal" begin
for T in (LowerTriangular(randn(5,5)), LinAlg.UnitLowerTriangular(randn(5,5)))
D = Diagonal(randn(5))
@test T*D == Array(T)*Array(D)
@test T'D == Array(T)'*Array(D)
@test T.'D == Array(T).'*Array(D)
@test D*T' == Array(D)*Array(T)'
@test D*T.' == Array(D)*Array(T).'
@test D*T == Array(D)*Array(T)
end
end
let D1 = Diagonal(rand(5)), D2 = Diagonal(rand(5))
@test_throws MethodError A_mul_B!(D1,D2)
@test_throws MethodError At_mul_B!(D1,D2)
@test_throws MethodError Ac_mul_B!(D1,D2)
end
@testset "multiplication of QR Q-factor and Diagonal (#16615 spot test)" begin
D = Diagonal(randn(5))
Q = qrfact(randn(5, 5))[:Q]
@test D * Q' == Array(D) * Q'
end
@testset "block diagonal matrices" begin
D = Diagonal([[1 2; 3 4], [1 2; 3 4]])
Dherm = Diagonal([[1 1+im; 1-im 1], [1 1+im; 1-im 1]])
Dsym = Diagonal([[1 1+im; 1+im 1], [1 1+im; 1+im 1]])
@test D' == Diagonal([[1 3; 2 4], [1 3; 2 4]])
@test D.' == Diagonal([[1 3; 2 4], [1 3; 2 4]])
@test Dherm' == Dherm
@test Dherm.' == Diagonal([[1 1-im; 1+im 1], [1 1-im; 1+im 1]])
@test Dsym' == Diagonal([[1 1-im; 1-im 1], [1 1-im; 1-im 1]])
@test Dsym.' == Dsym
v = [[1, 2], [3, 4]]
@test Dherm' * v == Dherm * v
@test D.' * v == [[7, 10], [15, 22]]
@test issymmetric(D) == false
@test issymmetric(Dherm) == false
@test issymmetric(Dsym) == true
@test ishermitian(D) == false
@test ishermitian(Dherm) == true
@test ishermitian(Dsym) == false
@test expm(D) == Diagonal([expm([1 2; 3 4]), expm([1 2; 3 4])])
@test logm(D) == Diagonal([logm([1 2; 3 4]), logm([1 2; 3 4])])
@test sqrtm(D) == Diagonal([sqrtm([1 2; 3 4]), sqrtm([1 2; 3 4])])
end
@testset "multiplication with Symmetric/Hermitian" begin
for T in (Float64, Complex128)
if T <: Complex
R = Float64
D = Diagonal(complex.(randn(R, n), randn(R, n)))
A = complex.(randn(R, n, n), randn(R, n, n))
else
D = Diagonal(randn(T, n))
A = randn(T, n, n)
end
A = A'A
S = Symmetric(A)
H = Hermitian(A)
for f in (*, Ac_mul_B, A_mul_Bc, Ac_mul_Bc, At_mul_B, A_mul_Bt, At_mul_Bt)
@test f(D, S) f(Matrix(D), Matrix(S))
@test f(D, H) f(Matrix(D), Matrix(H))
@test f(S, D) f(Matrix(S), Matrix(D))
@test f(S, H) f(Matrix(S), Matrix(H))
end
end
end

View File

@@ -0,0 +1,121 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
using Base.Test
using Base.LinAlg: BlasComplex, BlasFloat, BlasReal, QRPivoted
n = 10
# Split n into 2 parts for tests needing two matrices
n1 = div(n, 2)
n2 = 2*n1
srand(1234321)
areal = randn(n,n)/2
aimg = randn(n,n)/2
@testset for eltya in (Float32, Float64, Complex64, Complex128, Int)
aa = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(areal, aimg) : areal)
asym = aa'+aa # symmetric indefinite
apd = aa'*aa # symmetric positive-definite
@testset for atype in ("Array", "SubArray")
if atype == "Array"
a = aa
else
a = view(aa, 1:n, 1:n)
asym = view(asym, 1:n, 1:n)
apd = view(apd, 1:n, 1:n)
end
ε = εa = eps(abs(float(one(eltya))))
α = rand(eltya)
β = rand(eltya)
eab = eig(α,β)
@test eab[1] == eigvals(fill(α,1,1),fill(β,1,1))
@test eab[2] == eigvecs(fill(α,1,1),fill(β,1,1))
d,v = eig(a)
@testset "non-symmetric eigen decomposition" begin
for i in 1:size(a,2)
@test a*v[:,i] d[i]*v[:,i]
end
f = eigfact(a)
@test det(a) det(f)
@test inv(a) inv(f)
@test eigvals(f) === f[:values]
@test eigvecs(f) === f[:vectors]
num_fact = eigfact(one(eltya))
@test num_fact.values[1] == one(eltya)
h = asym
@test minimum(eigvals(h)) eigmin(h)
@test maximum(eigvals(h)) eigmax(h)
@test_throws DomainError eigmin(a - a')
@test_throws DomainError eigmax(a - a')
end
@testset "symmetric generalized eigenproblem" begin
if atype == "Array"
asym_sg = asym[1:n1, 1:n1]
a_sg = a[:,n1+1:n2]
else
asym_sg = view(asym, 1:n1, 1:n1)
a_sg = view(a, 1:n, n1+1:n2)
end
f = eigfact(asym_sg, a_sg'a_sg)
@test asym_sg*f[:vectors] (a_sg'a_sg*f[:vectors]) * Diagonal(f[:values])
@test f[:values] eigvals(asym_sg, a_sg'a_sg)
@test prod(f[:values]) prod(eigvals(asym_sg/(a_sg'a_sg))) atol=200ε
@test eigvecs(asym_sg, a_sg'a_sg) == f[:vectors]
@test eigvals(f) === f[:values]
@test eigvecs(f) === f[:vectors]
@test_throws KeyError f[:Z]
d,v = eig(asym_sg, a_sg'a_sg)
@test d == f[:values]
@test v == f[:vectors]
end
@testset "Non-symmetric generalized eigenproblem" begin
if atype == "Array"
a1_nsg = a[1:n1, 1:n1]
a2_nsg = a[n1+1:n2, n1+1:n2]
else
a1_nsg = view(a, 1:n1, 1:n1)
a2_nsg = view(a, n1+1:n2, n1+1:n2)
end
f = eigfact(a1_nsg, a2_nsg)
@test a1_nsg*f[:vectors] (a2_nsg*f[:vectors]) * Diagonal(f[:values])
@test f[:values] eigvals(a1_nsg, a2_nsg)
@test prod(f[:values]) prod(eigvals(a1_nsg/a2_nsg)) atol=50000ε
@test eigvecs(a1_nsg, a2_nsg) == f[:vectors]
@test_throws KeyError f[:Z]
d,v = eig(a1_nsg, a2_nsg)
@test d == f[:values]
@test v == f[:vectors]
end
end
end
@testset "eigenvalue computations with NaNs" begin
for eltya in (NaN16, NaN32, NaN)
@test_throws(ArgumentError, eig(fill(eltya, 1, 1)))
@test_throws(ArgumentError, eig(fill(eltya, 2, 2)))
test_matrix = rand(typeof(eltya),3,3)
test_matrix[2,2] = eltya
@test_throws(ArgumentError, eig(test_matrix))
end
end
# test a matrix larger than 140-by-140 for #14174
let aa = rand(200, 200)
for atype in ("Array", "SubArray")
if atype == "Array"
a = aa
else
a = view(aa, 1:n, 1:n)
end
f = eigfact(a)
@test a f[:vectors] * Diagonal(f[:values]) / f[:vectors]
end
end

View File

@@ -0,0 +1,312 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
import Base: -, *, /, \
using Base.Test
# A custom Quaternion type with minimal defined interface and methods.
# Used to test scale and scale! methods to show non-commutativity.
struct Quaternion{T<:Real} <: Number
s::T
v1::T
v2::T
v3::T
end
Quaternion(s::Real, v1::Real, v2::Real, v3::Real) = Quaternion(promote(s, v1, v2, v3)...)
Base.abs2(q::Quaternion) = q.s*q.s + q.v1*q.v1 + q.v2*q.v2 + q.v3*q.v3
Base.abs(q::Quaternion) = sqrt(abs2(q))
Base.real{T}(::Type{Quaternion{T}}) = T
Base.conj(q::Quaternion) = Quaternion(q.s, -q.v1, -q.v2, -q.v3)
Base.isfinite(q::Quaternion) = isfinite(q.s) & isfinite(q.v1) & isfinite(q.v2) & isfinite(q.v3)
(-)(ql::Quaternion, qr::Quaternion) =
Quaternion(ql.s - qr.s, ql.v1 - qr.v1, ql.v2 - qr.v2, ql.v3 - qr.v3)
(*)(q::Quaternion, w::Quaternion) = Quaternion(q.s*w.s - q.v1*w.v1 - q.v2*w.v2 - q.v3*w.v3,
q.s*w.v1 + q.v1*w.s + q.v2*w.v3 - q.v3*w.v2,
q.s*w.v2 - q.v1*w.v3 + q.v2*w.s + q.v3*w.v1,
q.s*w.v3 + q.v1*w.v2 - q.v2*w.v1 + q.v3*w.s)
(*)(q::Quaternion, r::Real) = Quaternion(q.s*r, q.v1*r, q.v2*r, q.v3*r)
(*)(q::Quaternion, b::Bool) = b * q # remove method ambiguity
(/)(q::Quaternion, w::Quaternion) = q * conj(w) * (1.0 / abs2(w))
(\)(q::Quaternion, w::Quaternion) = conj(q) * w * (1.0 / abs2(q))
debug = false
srand(123)
n = 5 # should be odd
for elty in (Int, Rational{BigInt}, Float32, Float64, BigFloat, Complex{Float32}, Complex{Float64}, Complex{BigFloat})
if elty <: Int
A = rand(-n:n, n, n) + 10I
elseif elty <: Rational
A = Rational{BigInt}[rand(-n:n)/rand(1:n) for i = 1:n, j = 1:n] + 10I
elseif elty <: Real
A = convert(Matrix{elty}, randn(n,n)) + 10I
else
A = convert(Matrix{elty}, complex.(randn(n,n), randn(n,n)))
end
debug && println("element type: $elty")
@test logdet(A) log(det(A))
@test logabsdet(A)[1] log(abs(det(A)))
@test logabsdet(convert(Matrix{elty}, -eye(n)))[2] == -1
if elty <: Real
@test logabsdet(A)[2] == sign(det(A))
@test_throws DomainError logdet(convert(Matrix{elty}, -eye(n)))
else
@test logabsdet(A)[2] sign(det(A))
end
end
# test diff, throw ArgumentError for invalid dimension argument
let X = [3 9 5;
7 4 2;
2 1 10]
@test diff(X,1) == [4 -5 -3; -5 -3 8]
@test diff(X,2) == [6 -4; -3 -2; -1 9]
@test diff(view(X, 1:2, 1:2),1) == [4 -5]
@test diff(view(X, 1:2, 1:2),2) == reshape([6; -3], (2,1))
@test diff(view(X, 2:3, 2:3),1) == [-3 8]
@test diff(view(X, 2:3, 2:3),2) == reshape([-2; 9], (2,1))
@test_throws ArgumentError diff(X,3)
@test_throws ArgumentError diff(X,-1)
end
# test linrange
# make sure unequal input arrays throw an error
x = [2; 5; 6]
y = [3; 7; 10; 10]
@test_throws DimensionMismatch linreg(x, y)
x = [2 5 6]
y = [3; 7; 10]
@test_throws MethodError linreg(x, y)
# check (UnitRange, Array)
x = 1:12
y = [5.5; 6.3; 7.6; 8.8; 10.9; 11.79; 13.48; 15.02; 17.77; 20.81; 22.0; 22.99]
@test [linreg(x,y)...] [2.5559090909090867, 1.6960139860139862]
@test [linreg(view(x,1:6),view(y,1:6))...] [3.8366666666666642,1.3271428571428574]
# check (LinSpace, UnitRange)
x = linspace(1.0, 12.0, 100)
y = -100:-1
@test [linreg(x, y)...] [-109.0, 9.0]
# check (UnitRange, UnitRange)
x = 1:12
y = 12:-1:1
@test [linreg(x, y)...] [13.0, -1.0]
# check (LinSpace, LinSpace)
x = linspace(-5, 10, 100)
y = linspace(50, 200, 100)
@test [linreg(x, y)...] [100.0, 10.0]
# check (Array, Array)
# Anscombe's quartet (https://en.wikipedia.org/wiki/Anscombe%27s_quartet)
x123 = [10.0; 8.0; 13.0; 9.0; 11.0; 14.0; 6.0; 4.0; 12.0; 7.0; 5.0]
y1 = [8.04; 6.95; 7.58; 8.81; 8.33; 9.96; 7.24; 4.26; 10.84; 4.82; 5.68]
@test [linreg(x123,y1)...] [3.0,0.5] atol=15e-5
y2 = [9.14; 8.14; 8.74; 8.77; 9.26; 8.10; 6.12; 3.10; 9.13; 7.26; 4.74]
@test [linreg(x123,y2)...] [3.0,0.5] atol=10e-3
y3 = [7.46; 6.77; 12.74; 7.11; 7.81; 8.84; 6.08; 5.39; 8.15; 6.42; 5.73]
@test [linreg(x123,y3)...] [3.0,0.5] atol=10e-3
x4 = [8.0; 8.0; 8.0; 8.0; 8.0; 8.0; 8.0; 19.0; 8.0; 8.0; 8.0]
y4 = [6.58; 5.76; 7.71; 8.84; 8.47; 7.04; 5.25; 12.50; 5.56; 7.91; 6.89]
@test [linreg(x4,y4)...] [3.0,0.5] atol=10e-3
# test diag
let A = eye(4)
@test diag(A) == ones(4)
@test diag(view(A, 1:3, 1:3)) == ones(3)
@test diag(view(A, 1:2, 1:2)) == ones(2)
end
# test generic axpy
x = ['a','b','c','d','e']
y = ['a','b','c','d','e']
α = 'f'
@test_throws DimensionMismatch Base.LinAlg.axpy!(α,x,['g'])
@test_throws BoundsError Base.LinAlg.axpy!(α,x,collect(-1:5),y,collect(1:7))
@test_throws BoundsError Base.LinAlg.axpy!(α,x,collect(1:7),y,collect(-1:5))
@test_throws BoundsError Base.LinAlg.axpy!(α,x,collect(1:7),y,collect(1:7))
@test_throws DimensionMismatch Base.LinAlg.axpy!(α,x,collect(1:3),y,collect(1:5))
@test_throws ArgumentError diag(rand(10))
@test !issymmetric(ones(5,3))
@test !ishermitian(ones(5,3))
@test cross(ones(3),ones(3)) == zeros(3)
@test trace(Bidiagonal(ones(5),zeros(4),true)) == 5
# array and subarray tests
let aa = reshape([1.:6;], (2,3))
for atype in ("Array", "SubArray")
if atype == "Array"
a = aa
else
a = view(aa, 1:2, 1:2)
end
# 2-argument version of scale!
@test scale!(copy(a), 5.) == a*5
@test scale!(5., copy(a)) == a*5
b = randn(Base.LinAlg.SCAL_CUTOFF) # make sure we try BLAS path
subB = view(b, :, :)
@test scale!(copy(b), 5.) == b*5
@test scale!(copy(subB), 5.) == subB*5
@test scale!([1.; 2.], copy(a)) == a.*[1; 2]
@test scale!([1; 2], copy(a)) == a.*[1; 2]
@test_throws DimensionMismatch scale!(ones(3), a)
if atype == "Array"
@test scale!(copy(a), [1.; 2.; 3.]) == a.*[1 2 3]
@test scale!(copy(a), [1; 2; 3]) == a.*[1 2 3]
@test_throws DimensionMismatch scale!(a, ones(2))
else
@test scale!(copy(a), [1.; 2.]) == a.*[1 2]
@test scale!(copy(a), [1; 2]) == a.*[1 2]
@test_throws DimensionMismatch scale!(a, ones(3))
end
# 3-argument version of scale!
@test scale!(similar(a), 5., a) == a*5
@test scale!(similar(a), a, 5.) == a*5
@test scale!(similar(a), [1.; 2.], a) == a.*[1; 2]
@test scale!(similar(a), [1; 2], a) == a.*[1; 2]
@test_throws DimensionMismatch scale!(similar(a), ones(3), a)
@test_throws DimensionMismatch scale!(Array{Float64}(3, 2), a, ones(3))
if atype == "Array"
@test scale!(similar(a), a, [1.; 2.; 3.]) == a.*[1 2 3]
@test scale!(similar(a), a, [1; 2; 3]) == a.*[1 2 3]
@test_throws DimensionMismatch scale!(similar(a), a, ones(2))
else
@test scale!(similar(a), a, [1.; 2.]) == a.*[1 2]
@test scale!(similar(a), a, [1; 2]) == a.*[1 2]
@test_throws DimensionMismatch scale!(similar(a), a, ones(3))
end
end
end
# scale real matrix by complex type
@test_throws InexactError scale!([1.0], 2.0im)
@test isequal([1.0] * 2.0im, Complex{Float64}[2.0im])
@test isequal(2.0im * [1.0], Complex{Float64}[2.0im])
@test isequal(Float32[1.0] * 2.0f0im, Complex{Float32}[2.0im])
@test isequal(Float32[1.0] * 2.0im, Complex{Float64}[2.0im])
@test isequal(Float64[1.0] * 2.0f0im, Complex{Float64}[2.0im])
@test isequal(Float32[1.0] * big(2.0)im, Complex{BigFloat}[2.0im])
@test isequal(Float64[1.0] * big(2.0)im, Complex{BigFloat}[2.0im])
@test isequal(BigFloat[1.0] * 2.0im, Complex{BigFloat}[2.0im])
@test isequal(BigFloat[1.0] * 2.0f0im, Complex{BigFloat}[2.0im])
# test scale and scale! for non-commutative multiplication
q = Quaternion(0.44567, 0.755871, 0.882548, 0.423612)
qmat = [Quaternion(0.015007, 0.355067, 0.418645, 0.318373)]
@test scale!(q, copy(qmat)) != scale!(copy(qmat), q)
## Test * because it doesn't dispatch to scale!
@test q*qmat qmat*q
@test conj(q*qmat) conj(qmat)*conj(q)
@test q * (q \ qmat) qmat (qmat / q) * q
@test q\qmat qmat/q
# test ops on Numbers
for elty in [Float32,Float64,Complex64,Complex128]
a = rand(elty)
@test trace(a) == a
@test rank(zero(elty)) == 0
@test rank(one(elty)) == 1
@test !isfinite(cond(zero(elty)))
@test cond(a) == one(elty)
@test cond(a,1) == one(elty)
@test issymmetric(a)
@test ishermitian(one(elty))
@test det(a) == a
end
@test !issymmetric(NaN16)
@test !issymmetric(NaN32)
@test !issymmetric(NaN)
@test rank([1.0 0.0; 0.0 0.9],0.95) == 1
@test qr(big.([0 1; 0 0]))[2] == [0 1; 0 0]
@test norm([2.4e-322, 4.4e-323]) 2.47e-322
@test norm([2.4e-322, 4.4e-323], 3) 2.4e-322
@test_throws ArgumentError norm(ones(5,5),5)
# test generic vecnorm for arrays of arrays
let x = Vector{Int}[[1,2], [3,4]]
@test norm(x) sqrt(30)
@test norm(x, 1) sqrt(5) + 5
@test norm(x, 3) cbrt(sqrt(125)+125)
end
# test that LinAlg.axpy! works for element type without commutative multiplication
let
α = ones(Int, 2, 2)
x = fill([1 0; 1 1], 3)
y = fill(zeros(Int, 2, 2), 3)
@test LinAlg.axpy!(α, x, deepcopy(y)) == x .* Matrix{Int}[α]
@test LinAlg.axpy!(α, x, deepcopy(y)) != Matrix{Int}[α] .* x
end
# test that LinAlg.axpy! works for x and y of different dimensions
let
α = 5
x = 2:5
y = ones(Int, 2, 4)
rx = [1 4]
ry = [2 8]
@test LinAlg.axpy!(α, x, rx, y, ry) == [1 1 1 1; 11 1 1 26]
end
let
vr = [3.0, 4.0]
for Tr in (Float32, Float64)
for T in (Tr, Complex{Tr})
v = convert(Vector{T}, vr)
@test norm(v) == 5.0
w = normalize(v)
@test norm(w - [0.6, 0.8], Inf) < eps(Tr)
@test norm(w) == 1.0
@test norm(normalize!(copy(v)) - w, Inf) < eps(Tr)
@test isempty(normalize!(T[]))
end
end
end
#Test potential overflow in normalize!
let
δ = inv(prevfloat(typemax(Float64)))
v = [δ, -δ]
@test norm(v) === 7.866824069956793e-309
w = normalize(v)
@test w [1/2, -1/2]
@test norm(w) === 1.0
@test norm(normalize!(v) - w, Inf) < eps()
end
# Issue 14657
@test det([true false; false true]) == det(eye(Int, 2))
@test_throws ArgumentError Base.LinAlg.char_uplo(:Z)
# Issue 17650
@test [0.01311489462160816, Inf] [0.013114894621608135, Inf]
# Issue 19035
@test Base.LinAlg.promote_leaf_eltypes([1, 2, [3.0, 4.0]]) == Float64
@test Base.LinAlg.promote_leaf_eltypes([[1,2, [3,4]], 5.0, [6im, [7.0, 8.0]]]) == Complex128
@test [1, 2, 3] [1, 2, 3]
@test [[1, 2], [3, 4]] [[1, 2], [3, 4]]
@test [[1, 2], [3, 4]] [[1.0-eps(), 2.0+eps()], [3.0+2eps(), 4.0-1e8eps()]]
@test [[1, 2], [3, 4]] [[1.0-eps(), 2.0+eps()], [3.0+2eps(), 4.0-1e9eps()]]
@test [[1,2, [3,4]], 5.0, [6im, [7.0, 8.0]]] [[1,2, [3,4]], 5.0, [6im, [7.0, 8.0]]]

View File

@@ -0,0 +1,75 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
using Base.Test
let
debug = false
# Test givens rotations
for elty in (Float32, Float64, Complex64, Complex128)
debug && println("elty is $elty")
if elty <: Real
A = convert(Matrix{elty}, randn(10,10))
else
A = convert(Matrix{elty}, complex.(randn(10,10),randn(10,10)))
end
for Atype in ("Array", "SubArray")
if Atype == "Array"
A = A
else
A = view(A, 1:10, 1:10)
end
Ac = copy(A)
R = Base.LinAlg.Rotation(Base.LinAlg.Givens{elty}[])
for j = 1:8
for i = j+2:10
G, _ = givens(A, j+1, i, j)
A_mul_B!(G, A)
A_mul_Bc!(A, G)
A_mul_B!(G, R)
@test A_mul_B!(G,eye(elty,10,10)) == [G[i,j] for i=1:10,j=1:10]
# test transposes
@test ctranspose(G)*G*eye(10) eye(elty, 10)
@test ctranspose(R)*(R*eye(10)) eye(elty, 10)
@test_throws ErrorException transpose(G)
@test_throws ErrorException transpose(R)
end
end
@test_throws ArgumentError givens(A, 3, 3, 2)
@test_throws ArgumentError givens(one(elty),zero(elty),2,2)
G, _ = givens(one(elty),zero(elty),11,12)
@test_throws DimensionMismatch A_mul_B!(G, A)
@test_throws DimensionMismatch A_mul_Bc!(A,G)
@test abs.(A) abs.(hessfact(Ac)[:H])
@test norm(R*eye(elty, 10)) one(elty)
G, _ = givens(one(elty),zero(elty),9,10)
@test ctranspose(G*eye(elty,10))*(G*eye(elty,10)) eye(elty, 10)
K, _ = givens(zero(elty),one(elty),9,10)
@test ctranspose(K*eye(elty,10))*(K*eye(elty,10)) eye(elty, 10)
# test that Givens * work for vectors
if Atype == "Array"
x = A[:, 1]
else
x = view(A, 1:10, 1)
end
G, r = givens(x[2], x[4], 2, 4)
@test (G*x)[2] r
@test abs((G*x)[4]) < eps(real(elty))
@inferred givens(x[2], x[4], 2, 4)
G, r = givens(x, 2, 4)
@test (G*x)[2] r
@test abs((G*x)[4]) < eps(real(elty))
@inferred givens(x, 2, 4)
G, r = givens(x, 4, 2)
@test (G*x)[4] r
@test abs((G*x)[2]) < eps(real(elty))
end
end
end #let

View File

@@ -0,0 +1,33 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
using Base.Test
using Base.LinAlg: BlasComplex, BlasFloat, BlasReal, QRPivoted
let n = 10
srand(1234321)
Areal = randn(n,n)/2
Aimg = randn(n,n)/2
@testset for eltya in (Float32, Float64, Complex64, Complex128, BigFloat, Int)
A = eltya == Int ?
rand(1:7, n, n) :
convert(Matrix{eltya}, eltya <: Complex ?
complex.(Areal, Aimg) :
Areal)
if eltya != BigFloat
H = hessfact(A)
@test size(H[:Q], 1) == size(A, 1)
@test size(H[:Q], 2) == size(A, 2)
@test size(H[:Q]) == size(A)
@test_throws KeyError H[:Z]
@test AbstractArray(H) A
@test (H[:Q] * H[:H]) * H[:Q]' A
@test (H[:Q]' *A) * H[:Q] H[:H]
#getindex for HessenbergQ
@test H[:Q][1,1] Array(H[:Q])[1,1]
end
end
end

View File

@@ -0,0 +1,620 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
using Base.Test
import Base.LinAlg.BlasInt
@test_throws ArgumentError Base.LinAlg.LAPACK.chkuplo('Z')
@test_throws ArgumentError Base.LinAlg.LAPACK.chkside('Z')
@test_throws ArgumentError Base.LinAlg.LAPACK.chkdiag('Z')
@test_throws ArgumentError Base.LinAlg.LAPACK.chktrans('Z')
@testset "syevr" begin
let
srand(123)
Ainit = randn(5,5)
@testset for elty in (Float32, Float64, Complex64, Complex128)
if elty == Complex64 || elty == Complex128
A = complex.(Ainit, Ainit)
else
A = Ainit
end
A = convert(Array{elty, 2}, A)
Asym = A'A
vals, Z = LAPACK.syevr!('V', copy(Asym))
@test Z*(Diagonal(vals)*Z') Asym
@test all(vals .> 0.0)
@test LAPACK.syevr!('N','V','U',copy(Asym),0.0,1.0,4,5,-1.0)[1] vals[vals .< 1.0]
@test LAPACK.syevr!('N','I','U',copy(Asym),0.0,1.0,4,5,-1.0)[1] vals[4:5]
@test vals LAPACK.syev!('N','U',copy(Asym))
@test_throws DimensionMismatch LAPACK.sygvd!(1,'V','U',copy(Asym),ones(elty,6,6))
end
end
end
@testset "gglse" begin
let
@testset for elty in (Float32, Float64, Complex64, Complex128)
A = convert(Array{elty, 2}, [1 1 1 1; 1 3 1 1; 1 -1 3 1; 1 1 1 3; 1 1 1 -1])
c = convert(Array{elty, 1}, [2, 1, 6, 3, 1])
B = convert(Array{elty, 2}, [1 1 1 -1; 1 -1 1 1; 1 1 -1 1])
d = convert(Array{elty, 1}, [1, 3, -1])
@test LAPACK.gglse!(A, c, B, d)[1] convert(Array{elty}, [0.5, -0.5, 1.5, 0.5])
end
end
end
@testset "gebrd, bdsqr, throw for bdsdc" begin
let
n = 10
@testset for elty in (Float32, Float64)
d, e = convert(Vector{elty}, randn(n)), convert(Vector{elty}, randn(n - 1))
U, Vt, C = eye(elty, n), eye(elty, n), eye(elty, n)
s, _ = LAPACK.bdsqr!('U', copy(d), copy(e), Vt, U, C)
@test Array(Bidiagonal(d, e, true)) U*Diagonal(s)*Vt
@test_throws ArgumentError LAPACK.bdsqr!('A', d, e, Vt, U, C)
@test_throws DimensionMismatch LAPACK.bdsqr!('U', d, [e; 1], Vt, U, C)
@test_throws DimensionMismatch LAPACK.bdsqr!('U', d, e, Vt[1:end - 1, :], U, C)
@test_throws DimensionMismatch LAPACK.bdsqr!('U', d, e, Vt, U[:,1:end - 1], C)
@test_throws DimensionMismatch LAPACK.bdsqr!('U', d, e, Vt, U, C[1:end - 1, :])
@test_throws ArgumentError LAPACK.bdsdc!('U','Z',d,e)
A = rand(elty,n,n)
B = copy(A)
B, d, e, tauq, taup = LAPACK.gebrd!(B)
U, Vt, C = eye(elty, n), eye(elty, n), eye(elty, n)
s, _ = LAPACK.bdsqr!('U',d,e[1:n-1],Vt, U, C)
@test s svdvals(A)
end
end
end
@testset "Issue #7886" begin
let
x, r = LAPACK.gelsy!([0 1; 0 2; 0 3.], [2, 4, 6.])
@test x [0,2]
@test r == 1
end
end
@testset "geqrt(3)" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
A = rand(elty,10,10)
B = copy(A)
C,T = LAPACK.geqrt!(A,zeros(elty,10,10))
D,S = LAPACK.geqrt3!(A,zeros(elty,10,10))
@test C D
end
end
@testset "gbtrf and gbtrs" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
d = rand(elty,6)
dl = rand(elty,5)
du = rand(elty,5)
dl2 = rand(elty,4)
AB = zeros(elty,6,6)
AB[6,1:4] = dl2
AB[5,1:5] = dl
AB[4,:] = d
AB[3,2:6] = du
AB,ipiv = LAPACK.gbtrf!(2,1,6,AB)
C = rand(elty,6,6)
D = copy(C)
D = LAPACK.gbtrs!('N',2,1,6,AB,ipiv,D)
A = diagm(dl2,-2) + diagm(dl,-1) + diagm(d) + diagm(du,1)
@test A\C D
@test_throws DimensionMismatch LAPACK.gbtrs!('N',2,1,6,AB,ipiv,ones(elty,7,6))
@test_throws Base.LinAlg.LAPACKException LAPACK.gbtrf!(2,1,6,zeros(AB))
end
end
@testset "geqp3, geqrt error handling" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
A = rand(elty,10,10)
@test_throws DimensionMismatch LAPACK.geqlf!(A,zeros(elty,11))
@test_throws DimensionMismatch LAPACK.gelqf!(A,zeros(elty,11))
@test_throws DimensionMismatch LAPACK.geqp3!(A,ones(Base.LinAlg.BlasInt,11),zeros(elty,10))
@test_throws DimensionMismatch LAPACK.geqp3!(A,ones(Base.LinAlg.BlasInt,10),zeros(elty,11))
@test_throws ArgumentError LAPACK.geqrt!(A,zeros(elty,11,10))
@test_throws DimensionMismatch LAPACK.geqrt3!(A,zeros(elty,11,10))
@test_throws DimensionMismatch LAPACK.geqrt3!(ones(elty,10,11),zeros(elty,11,11))
@test_throws DimensionMismatch LAPACK.geqrf!(A,zeros(elty,11))
@test_throws DimensionMismatch LAPACK.gerqf!(A,zeros(elty,11))
end
end
@testset "gels, gesv, getrs, getri error handling" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
A = rand(elty,10,10)
B = rand(elty,11,11)
@test_throws DimensionMismatch LAPACK.gels!('N',A,B)
@test_throws DimensionMismatch LAPACK.gels!('T',A,B)
@test_throws DimensionMismatch LAPACK.gesv!(A,B)
@test_throws DimensionMismatch LAPACK.getrs!('N',A,ones(Base.LinAlg.BlasInt,10),B)
@test_throws DimensionMismatch LAPACK.getrs!('T',A,ones(Base.LinAlg.BlasInt,10),B)
@test_throws DimensionMismatch LAPACK.getri!(A,ones(Base.LinAlg.BlasInt,11))
end
end
@testset "gelsy, gelsd" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
A = rand(elty,10,10)
B = rand(elty,10,10)
C, j = LAPACK.gelsd!(copy(A),copy(B))
D, k = LAPACK.gelsy!(copy(A),copy(B))
@test C D
@test_throws DimensionMismatch LAPACK.gelsd!(A,rand(elty,12,10))
@test_throws DimensionMismatch LAPACK.gelsy!(A,rand(elty,12,10))
end
end
@testset "gglse errors" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
A = rand(elty,10,10)
@test_throws DimensionMismatch LAPACK.gglse!(A,zeros(elty,10),rand(elty,12,11),zeros(elty,12))
@test_throws DimensionMismatch LAPACK.gglse!(A,zeros(elty,11),rand(elty,10,10),zeros(elty,10))
@test_throws DimensionMismatch LAPACK.gglse!(A,zeros(elty,10),rand(elty,10,10),zeros(elty,11))
end
end
@testset "gesvd, ggsvd" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
A = rand(elty,10,5)
U,S,V = svd(A)
lU,lS,lVt = LAPACK.gesvd!('S','S',A)
@test U lU
@test S lS
@test V' lVt
B = rand(elty,10,10)
# xggsvd3 replaced xggsvd in LAPACK 3.6.0
if LAPACK.laver() < (3, 6, 0)
@test_throws DimensionMismatch LAPACK.ggsvd!('S','S','S',A,B)
else
@test_throws DimensionMismatch LAPACK.ggsvd3!('S','S','S',A,B)
end
end
end
@testset "geevx, ggev errors" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
A = rand(elty,10,10)
B = rand(elty,10,10)
@test_throws ArgumentError LAPACK.geevx!('M','N','N','N',A)
@test_throws ArgumentError LAPACK.geevx!('N','Z','N','N',A)
@test_throws ArgumentError LAPACK.geevx!('N','N','Z','N',A)
@test_throws ArgumentError LAPACK.geevx!('N','N','N','Z',A)
@test_throws ArgumentError LAPACK.ggev!('N','B',A,B)
@test_throws ArgumentError LAPACK.ggev!('B','N',A,B)
@test_throws DimensionMismatch LAPACK.ggev!('N','N',A,zeros(elty,12,12))
end
end
@testset "gebal/gebak" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
A = rand(elty,10,10) * Diagonal(exp10.(linspace(-10,10,10)))
B = copy(A)
ilo, ihi, scale = LAPACK.gebal!('S',B)
Bvs = eigvecs(B)
Avs = eigvecs(A)
Bvs = LAPACK.gebak!('S','R',ilo,ihi,scale,Bvs)
@test norm(diff(Avs ./ Bvs)) < 100 * eps(abs(float(one(elty))))
end
end
@testset "gels" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
A = rand(elty,10,10)
X = rand(elty,10)
B,Y,z = LAPACK.gels!('N',copy(A),copy(X))
@test A\X Y
end
end
@testset "getrf/getri" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
A = rand(elty,10,10)
iA = inv(A)
A, ipiv = LAPACK.getrf!(A)
A = LAPACK.getri!(A, ipiv)
@test A iA
end
end
@testset "geev" begin
# complex is easier for now
@testset for elty in (Complex64, Complex128)
A = rand(elty,10,10)
Aw, Avl, Avr = LAPACK.geev!('N','V',copy(A))
fA = eigfact(A)
@test fA[:values] Aw
@test fA[:vectors] Avr
end
end
@testset "gtsv" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
du = rand(elty,9)
d = rand(elty,10)
dl = rand(elty,9)
b = rand(elty,10)
c = Tridiagonal(dl,d,du) \ b
b = LAPACK.gtsv!(dl,d,du,b)
@test b c
@test_throws DimensionMismatch LAPACK.gtsv!(zeros(elty,11),d,du,b)
@test_throws DimensionMismatch LAPACK.gtsv!(dl,d,zeros(elty,11),b)
@test_throws DimensionMismatch LAPACK.gtsv!(dl,d,du,zeros(elty,11))
@test LAPACK.gtsv!(elty[],elty[],elty[],elty[]) == elty[]
end
end
@testset "gttrs,gttrf errors" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
du = rand(elty,9)
d = rand(elty,10)
dl = rand(elty,9)
b = rand(elty,10)
@test_throws DimensionMismatch LAPACK.gttrf!(zeros(elty,11),d,du)
@test_throws DimensionMismatch LAPACK.gttrf!(dl,d,zeros(elty,11))
@test_throws DimensionMismatch LAPACK.gttrs!('N',zeros(elty,11),d,du,ones(elty,9),zeros(Base.LinAlg.BlasInt,10),b)
@test_throws DimensionMismatch LAPACK.gttrs!('N',dl,d,zeros(elty,11),ones(elty,9),zeros(Base.LinAlg.BlasInt,10),b)
@test_throws DimensionMismatch LAPACK.gttrs!('N',dl,d,du,ones(elty,9),zeros(Base.LinAlg.BlasInt,10),zeros(elty,11))
A = lufact(Tridiagonal(dl,d,du))
b = rand(elty,10,5)
c = copy(b)
dl,d,du,du2,ipiv = LAPACK.gttrf!(dl,d,du)
c = LAPACK.gttrs!('N',dl,d,du,du2,ipiv,c)
@test A\b c
end
end
@testset "orglq and friends errors" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
A = rand(elty,10,10)
A,tau = LAPACK.gelqf!(A)
@test_throws DimensionMismatch LAPACK.orglq!(A,tau,11)
@test_throws DimensionMismatch LAPACK.ormlq!('R','N',A,tau,rand(elty,11,11))
@test_throws DimensionMismatch LAPACK.ormlq!('L','N',A,tau,rand(elty,11,11))
@test_throws DimensionMismatch LAPACK.ormlq!('R','N',A,zeros(elty,11),rand(elty,10,10))
@test_throws DimensionMismatch LAPACK.ormlq!('L','N',A,zeros(elty,11),rand(elty,10,10))
B = copy(A)
C = LAPACK.orglq!(B,tau)
@test LAPACK.ormlq!('R','N',A,tau,eye(elty,10)) C
A = rand(elty,10,10)
A,tau = LAPACK.geqrf!(A)
@test_throws DimensionMismatch LAPACK.orgqr!(A,tau,11)
B = copy(A)
@test LAPACK.orgqr!(B,tau) LAPACK.ormqr!('R','N',A,tau,eye(elty,10))
@test_throws DimensionMismatch LAPACK.ormqr!('R','N',A,tau,rand(elty,11,11))
@test_throws DimensionMismatch LAPACK.ormqr!('L','N',A,tau,rand(elty,11,11))
@test_throws DimensionMismatch LAPACK.ormqr!('R','N',A,zeros(elty,11),rand(elty,10,10))
@test_throws DimensionMismatch LAPACK.ormqr!('L','N',A,zeros(elty,11),rand(elty,10,10))
A = rand(elty,10,10)
A,tau = LAPACK.geqlf!(A)
@test_throws DimensionMismatch LAPACK.orgql!(A,tau,11)
B = copy(A)
@test LAPACK.orgql!(B,tau) LAPACK.ormql!('R','N',A,tau,eye(elty,10))
@test_throws DimensionMismatch LAPACK.ormql!('R','N',A,tau,rand(elty,11,11))
@test_throws DimensionMismatch LAPACK.ormql!('L','N',A,tau,rand(elty,11,11))
@test_throws DimensionMismatch LAPACK.ormql!('R','N',A,zeros(elty,11),rand(elty,10,10))
@test_throws DimensionMismatch LAPACK.ormql!('L','N',A,zeros(elty,11),rand(elty,10,10))
A = rand(elty,10,10)
A,tau = LAPACK.gerqf!(A)
@test_throws DimensionMismatch LAPACK.orgrq!(A,tau,11)
B = copy(A)
@test LAPACK.orgrq!(B,tau) LAPACK.ormrq!('R','N',A,tau,eye(elty,10))
@test_throws DimensionMismatch LAPACK.ormrq!('R','N',A,tau,rand(elty,11,11))
@test_throws DimensionMismatch LAPACK.ormrq!('L','N',A,tau,rand(elty,11,11))
@test_throws DimensionMismatch LAPACK.ormrq!('R','N',A,zeros(elty,11),rand(elty,10,10))
@test_throws DimensionMismatch LAPACK.ormrq!('L','N',A,zeros(elty,11),rand(elty,10,10))
C = rand(elty,10,10)
V = rand(elty,10,10)
T = zeros(elty,10,11)
@test_throws DimensionMismatch LAPACK.gemqrt!('L','N',V,T,C)
@test_throws DimensionMismatch LAPACK.gemqrt!('R','N',V,T,C)
C = rand(elty,10,10)
V = rand(elty,11,10)
T = zeros(elty,10,10)
@test_throws DimensionMismatch LAPACK.gemqrt!('R','N',V,T,C)
@test_throws DimensionMismatch LAPACK.gemqrt!('L','N',V,T,C)
# test size(T) = (nb,k) ensures 1 <= nb <= k
T = zeros(elty,10,10)
V = rand(elty,5,10)
@test_throws DimensionMismatch LAPACK.gemqrt!('L','N',V,T,C)
C = rand(elty,10,10)
V = rand(elty,10,10)
T = zeros(elty,11,10)
@test_throws DimensionMismatch LAPACK.gemqrt!('R','N',V,T,C)
@test_throws DimensionMismatch LAPACK.orghr!(1, 10, C, zeros(elty,11))
end
end
@testset "sytri, sytrs, and sytrf" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
A = rand(elty,10,10)
A = A + A.' #symmetric!
B = copy(A)
B,ipiv = LAPACK.sytrf!('U',B)
@test triu(inv(A)) triu(LAPACK.sytri!('U',B,ipiv))
@test_throws DimensionMismatch LAPACK.sytrs!('U',B,ipiv,rand(elty,11,5))
@test LAPACK.sytrf!('U',zeros(elty,0,0)) == (zeros(elty,0,0),zeros(BlasInt,0))
end
# Rook-pivoting variants
@testset for elty in (Float32, Float64, Complex64, Complex128)
A = rand(elty,10,10)
A = A + A.' #symmetric!
B = copy(A)
B,ipiv = LAPACK.sytrf_rook!('U',B)
@test triu(inv(A)) triu(LAPACK.sytri_rook!('U',B,ipiv))
@test_throws DimensionMismatch LAPACK.sytrs_rook!('U',B,ipiv,rand(elty,11,5))
@test LAPACK.sytrf_rook!('U',zeros(elty,0,0)) == (zeros(elty,0,0),zeros(BlasInt,0))
A = rand(elty,10,10)
A = A + A.' #symmetric!
b = rand(elty,10)
c = A \ b
b,A = LAPACK.sysv_rook!('U',A,b)
@test b c
@test_throws DimensionMismatch LAPACK.sysv_rook!('U',A,rand(elty,11))
end
end
@testset "hetrf, hetrs" begin
@testset for elty in (Complex64, Complex128)
A = rand(elty,10,10)
A = A + A' #hermitian!
B = copy(A)
B,ipiv = LAPACK.hetrf!('U',B)
@test_throws DimensionMismatch LAPACK.hetrs!('U',B,ipiv,rand(elty,11,5))
@test_throws DimensionMismatch LAPACK.hetrs_rook!('U',B,ipiv,rand(elty,11,5))
end
end
@testset "stev, stebz, stein, stegr" begin
@testset for elty in (Float32, Float64)
d = rand(elty,10)
e = rand(elty,9)
@test_throws DimensionMismatch LAPACK.stev!('U',d,rand(elty,10))
@test_throws DimensionMismatch LAPACK.stebz!('A','B',zero(elty),zero(elty),0,0,-1.,d,rand(elty,10))
@test_throws DimensionMismatch LAPACK.stegr!('N','A',d,rand(elty,10),zero(elty),zero(elty),0,0)
@test_throws DimensionMismatch LAPACK.stein!(d,zeros(elty,10),zeros(d),zeros(BlasInt,10),zeros(BlasInt,10))
@test_throws DimensionMismatch LAPACK.stein!(d,e,zeros(elty,11),zeros(BlasInt,10),zeros(BlasInt,10))
end
end
@testset "trtri & trtrs" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
A = rand(elty,10,10)
A = triu(A)
B = copy(A)
@test inv(A) LAPACK.trtri!('U','N',B)
@test_throws DimensionMismatch LAPACK.trtrs!('U','N','N',B,zeros(elty,11,10))
end
end
@testset "tgsen, tzrzf, & trsyl" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
Z = zeros(elty,10,10)
@test_throws DimensionMismatch LAPACK.tgsen!(zeros(BlasInt,10),Z,zeros(elty,11,11),Z,Z)
@test_throws DimensionMismatch LAPACK.tgsen!(zeros(BlasInt,10),Z,Z,zeros(elty,11,11),Z)
@test_throws DimensionMismatch LAPACK.tgsen!(zeros(BlasInt,10),Z,Z,Z,zeros(elty,11,11))
@test_throws DimensionMismatch LAPACK.trsyl!('N','N',Z,Z,zeros(elty,11,11))
@test_throws DimensionMismatch LAPACK.tzrzf!(zeros(elty,10,5))
end
end
@testset "sysv" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
A = rand(elty,10,10)
A = A + A.' #symmetric!
b = rand(elty,10)
c = A \ b
b,A = LAPACK.sysv!('U',A,b)
@test b c
@test_throws DimensionMismatch LAPACK.sysv!('U',A,rand(elty,11))
end
end
@testset "hesv" begin
@testset for elty in (Complex64, Complex128)
A = rand(elty,10,10)
A = A + A' #hermitian!
b = rand(elty,10)
c = A \ b
b,A = LAPACK.hesv!('U',A,b)
@test b c
@test_throws DimensionMismatch LAPACK.hesv!('U',A,rand(elty,11))
A = rand(elty,10,10)
A = A + A' #hermitian!
b = rand(elty,10)
c = A \ b
b,A = LAPACK.hesv_rook!('U',A,b)
@test b c
@test_throws DimensionMismatch LAPACK.hesv_rook!('U',A,rand(elty,11))
end
end
@testset "ptsv" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
dv = real(ones(elty,10))
ev = zeros(elty,9)
A = SymTridiagonal(dv,ev)
if elty <: Complex
A = Tridiagonal(conj(ev),dv,ev)
end
B = rand(elty,10,10)
C = copy(B)
@test A\B LAPACK.ptsv!(dv,ev,C)
@test_throws DimensionMismatch LAPACK.ptsv!(dv,ones(elty,10),C)
@test_throws DimensionMismatch LAPACK.ptsv!(dv,ev,ones(elty,11,11))
end
end
@testset "pttrf and pttrs" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
dv = real(ones(elty,10))
ev = zeros(elty,9)
A = SymTridiagonal(dv,ev)
if elty <: Complex
A = Tridiagonal(conj(ev),dv,ev)
end
dv,ev = LAPACK.pttrf!(dv,ev)
@test_throws DimensionMismatch LAPACK.pttrf!(dv,ones(elty,10))
B = rand(elty,10,10)
C = copy(B)
if elty <: Complex
@test A\B LAPACK.pttrs!('U',dv,ev,C)
@test_throws DimensionMismatch LAPACK.pttrs!('U',dv,ones(elty,10),C)
@test_throws DimensionMismatch LAPACK.pttrs!('U',dv,ev,rand(elty,11,11))
else
@test A\B LAPACK.pttrs!(dv,ev,C)
@test_throws DimensionMismatch LAPACK.pttrs!(dv,ones(elty,10),C)
@test_throws DimensionMismatch LAPACK.pttrs!(dv,ev,rand(elty,11,11))
end
end
end
@testset "posv and some errors for friends" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
A = rand(elty,10,10)/100
A += real(diagm(10*real(rand(elty,10))))
if elty <: Complex
A = A + A'
else
A = A + A.'
end
B = rand(elty,10,10)
D = copy(A)
C = copy(B)
D,C = LAPACK.posv!('U',D,C)
@test A\B C
@test_throws DimensionMismatch LAPACK.posv!('U',D,ones(elty,12,12))
@test_throws DimensionMismatch LAPACK.potrs!('U',D,ones(elty,12,12))
@test LAPACK.potrs!('U',zeros(elty,0,0),ones(elty,0)) == ones(elty,0)
end
end
@testset "gesvx" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
A = rand(elty,10,10)
B = rand(elty,10,5)
C = copy(A)
D = copy(B)
X, rcond, f, b, r = LAPACK.gesvx!(C,D)
@test X A\B
end
end
@testset "gees, gges error throwing" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
A = rand(elty,10,10)
B = rand(elty,11,11)
@test_throws DimensionMismatch LAPACK.gges!('V','V',A,B)
end
end
@testset "trrfs & trevc" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
T = triu(rand(elty,10,10))
S = copy(T)
select = zeros(Base.LinAlg.BlasInt,10)
select[1] = 1
select,Vr = LAPACK.trevc!('R','S',select,copy(T))
@test Vr eigvecs(S)[:,1]
select = zeros(Base.LinAlg.BlasInt,10)
select[1] = 1
select,Vl = LAPACK.trevc!('L','S',select,copy(T))
select = zeros(Base.LinAlg.BlasInt,10)
select[1] = 1
select,Vln,Vrn = LAPACK.trevc!('B','S',select,copy(T))
@test Vrn eigvecs(S)[:,1]
@test Vln Vl
@test_throws ArgumentError LAPACK.trevc!('V','S',select,copy(T))
@test_throws DimensionMismatch LAPACK.trrfs!('U','N','N',T,rand(elty,10,10),rand(elty,10,11))
end
end
@testset "laic1" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
@test_throws DimensionMismatch LAPACK.laic1!(1,rand(elty,10),real(rand(elty)),rand(elty,11),rand(elty))
end
end
@testset "trexc" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
for c in ('V', 'N')
A = convert(Matrix{elty}, [7 2 2 1; 1 5 2 0; 0 3 9 4; 1 1 1 4])
T,Q,d = schur(A)
Base.LinAlg.LAPACK.trsen!('N',c,Array{LinAlg.BlasInt}([0,1,0,0]),T,Q)
@test d[1] T[2,2]
@test d[2] T[1,1]
if c == 'V'
@test Q*T*Q' A
end
end
end
end
@testset "trexc and trsen" begin
@testset for elty in (Float32, Float64, Complex64, Complex128)
for c in ('V', 'N')
A = convert(Matrix{elty}, [7 2 2 1; 1 5 2 0; 0 3 9 4; 1 1 1 4])
T,Q,d = schur(A)
Base.LinAlg.LAPACK.trexc!(c,LinAlg.BlasInt(1),LinAlg.BlasInt(2),T,Q)
@test d[1] T[2,2]
@test d[2] T[1,1]
if c == 'V'
@test Q*T*Q' A
end
end
end
end
@testset "Julia vs LAPACK" begin
# Test our own linear algebra functionality against LAPACK
@testset for elty in (Float32, Float64, Complex{Float32}, Complex{Float64})
for nn in (5,10,15)
if elty <: Real
A = convert(Matrix{elty}, randn(10,nn))
else
A = convert(Matrix{elty}, complex.(randn(10,nn),randn(10,nn)))
end ## LU (only equal for real because LAPACK uses different absolute value when choosing permutations)
if elty <: Real
FJulia = Base.LinAlg.generic_lufact!(copy(A))
FLAPACK = Base.LinAlg.LAPACK.getrf!(copy(A))
@test FJulia.factors FLAPACK[1]
@test FJulia.ipiv FLAPACK[2]
@test FJulia.info FLAPACK[3]
end
## QR
FJulia = LinAlg.qrfactUnblocked!(copy(A))
FLAPACK = Base.LinAlg.LAPACK.geqrf!(copy(A))
@test FJulia.factors FLAPACK[1]
@test FJulia.τ FLAPACK[2]
end
end
end
# Issue 13976
let A = [NaN 0.0 NaN; 0 0 0; NaN 0 NaN]
@test_throws ArgumentError expm(A)
end
# Issue 14065 (and 14220)
let A = [NaN NaN; NaN NaN]
@test_throws ArgumentError eigfact(A)
end

View File

@@ -0,0 +1,136 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
using Base.Test
using Base.LinAlg: BlasComplex, BlasFloat, BlasReal
n = 10
# Split n into 2 parts for tests needing two matrices
n1 = div(n, 2)
n2 = 2*n1
srand(1234321)
areal = randn(n,n)/2
aimg = randn(n,n)/2
a2real = randn(n,n)/2
a2img = randn(n,n)/2
breal = randn(n,2)/2
bimg = randn(n,2)/2
@testset for eltya in (Float32, Float64, Complex64, Complex128)
a = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(areal, aimg) : areal)
a2 = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(a2real, a2img) : a2real)
asym = a'+a # symmetric indefinite
apd = a'*a # symmetric positive-definite
ε = εa = eps(abs(float(one(eltya))))
@testset for eltyb in (Float32, Float64, Complex64, Complex128, Int)
b = eltyb == Int ? rand(1:5, n, 2) : convert(Matrix{eltyb}, eltyb <: Complex ? complex.(breal, bimg) : breal)
εb = eps(abs(float(one(eltyb))))
ε = max(εa,εb)
α = rand(eltya)
aα = fill(α,1,1)
@test lqfact(α)[:L]*lqfact(α)[:Q] lqfact(aα)[:L]*lqfact(aα)[:Q]
@test lq(α)[1]*lq(α)[2] lqfact(aα)[:L]*lqfact(aα)[:Q]
@test abs(lqfact(α)[:Q][1,1]) one(eltya)
tab = promote_type(eltya,eltyb)
for i = 1:2
let a = i == 1 ? a : view(a, 1:n - 1, 1:n - 1), b = i == 1 ? b : view(b, 1:n - 1), n = i == 1 ? n : n - 1
lqa = lqfact(a)
l,q = lqa[:L], lqa[:Q]
qra = qrfact(a)
@testset "Basic ops" begin
@test size(lqa,1) == size(a,1)
@test size(lqa,3) == 1
@test size(lqa[:Q],3) == 1
@test Base.LinAlg.getq(lqa) == lqa[:Q]
@test_throws KeyError lqa[:Z]
@test full(lqa') a'
@test lqa * lqa' a * a'
@test lqa' * lqa a' * a
@test q*full(q, thin = false)' eye(eltya,n)
@test l*q a
@test full(lqa) a
@test full(copy(lqa)) a
lstring = sprint(show,l)
qstring = sprint(show,q)
@test sprint(show,lqa) == "$(typeof(lqa)) with factors L and Q:\n$lstring\n$qstring"
end
@testset "Binary ops" begin
@test a*(lqa\b) b atol=3000ε
@test lqa*b qra[:Q]*qra[:R]*b atol=3000ε
@test A_mul_Bc(eye(eltyb,size(q.factors,2)),q)*full(q,thin=false) eye(n) atol=5000ε
if eltya != Int
@test eye(eltyb,n)*q convert(AbstractMatrix{tab},q)
end
@test q*b full(q,thin=false)*b atol=100ε
@test q.'*b full(q,thin=false).'*b atol=100ε
@test q'*b full(q,thin=false)'*b atol=100ε
@test a*q a*full(q,thin=false) atol=100ε
@test a*q.' a*full(q,thin=false).' atol=100ε
@test a*q' a*full(q,thin=false)' atol=100ε
@test a'*q a'*full(q,thin=false) atol=100ε
@test a'*q' a'*full(q,thin=false)' atol=100ε
@test_throws DimensionMismatch q*b[1:n1 + 1]
@test_throws DimensionMismatch Ac_mul_B(q,ones(eltya,n+2,n+2))
@test_throws DimensionMismatch ones(eltyb,n+2,n+2)*q
if isa(a, DenseArray) && isa(b, DenseArray)
# use this to test 2nd branch in mult code
pad_a = vcat(eye(a), a)
pad_b = hcat(eye(b), b)
@test pad_a*q pad_a*full(q,thin=false) atol=100ε
@test q.'*pad_b full(q,thin=false).'*pad_b atol=100ε
@test q'*pad_b full(q,thin=false)'*pad_b atol=100ε
end
end
end
end
@testset "Matmul with LQ factorizations" begin
lqa = lqfact(a[:,1:n1])
l,q = lqa[:L], lqa[:Q]
@test full(q)*full(q)' eye(eltya,n1)
@test (full(q,thin=false)'*full(q,thin=false))[1:n1,:] eye(eltya,n1,n)
@test_throws DimensionMismatch A_mul_B!(eye(eltya,n+1),q)
@test Ac_mul_B!(q,full(q)) eye(eltya,n1)
@test_throws DimensionMismatch A_mul_Bc!(eye(eltya,n+1),q)
@test_throws BoundsError size(q,-1)
end
end
end
@testset "getindex on LQPackedQ (#23733)" begin
function getqs(F::Base.LinAlg.LQ)
implicitQ = F[:Q]
explicitQ = A_mul_B!(implicitQ, eye(eltype(implicitQ), size(implicitQ.factors, 2)))
return implicitQ, explicitQ
end
m, n = 3, 3 # thin Q 3-by-3, square Q 3-by-3
implicitQ, explicitQ = getqs(lqfact(randn(m, n)))
@test implicitQ[1, 1] == explicitQ[1, 1]
@test implicitQ[m, 1] == explicitQ[m, 1]
@test implicitQ[1, n] == explicitQ[1, n]
@test implicitQ[m, n] == explicitQ[m, n]
m, n = 3, 4 # thin Q 3-by-4, square Q 4-by-4
implicitQ, explicitQ = getqs(lqfact(randn(m, n)))
@test implicitQ[1, 1] == explicitQ[1, 1]
@test implicitQ[m, 1] == explicitQ[m, 1]
@test implicitQ[1, n] == explicitQ[1, n]
@test implicitQ[m, n] == explicitQ[m, n]
@test implicitQ[m+1, 1] == explicitQ[m+1, 1]
@test implicitQ[m+1, n] == explicitQ[m+1, n]
m, n = 4, 3 # thin Q 3-by-3, square Q 3-by-3
implicitQ, explicitQ = getqs(lqfact(randn(m, n)))
@test implicitQ[1, 1] == explicitQ[1, 1]
@test implicitQ[n, 1] == explicitQ[n, 1]
@test implicitQ[1, n] == explicitQ[1, n]
@test implicitQ[n, n] == explicitQ[n, n]
end

View File

@@ -0,0 +1,210 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
debug = false
using Base.Test
import Base.LinAlg.BlasInt, Base.LinAlg.BlasFloat
n = 10
# Split n into 2 parts for tests needing two matrices
n1 = div(n, 2)
n2 = 2*n1
srand(1234321)
a = rand(n,n)
areal = randn(n,n)/2
aimg = randn(n,n)/2
breal = randn(n,2)/2
bimg = randn(n,2)/2
creal = randn(n)/2
cimg = randn(n)/2
dureal = randn(n-1)/2
duimg = randn(n-1)/2
dlreal = randn(n-1)/2
dlimg = randn(n-1)/2
dreal = randn(n)/2
dimg = randn(n)/2
for eltya in (Float32, Float64, Complex64, Complex128, BigFloat, Int)
a = eltya == Int ? rand(1:7, n, n) :
convert(Matrix{eltya}, eltya <: Complex ? complex.(areal, aimg) : areal)
d = if eltya == Int
Tridiagonal(rand(1:7, n-1), rand(1:7, n), rand(1:7, n-1))
elseif eltya <: Complex
convert(Tridiagonal{eltya}, Tridiagonal(
complex.(dlreal, dlimg), complex.(dreal, dimg), complex.(dureal, duimg)))
else
convert(Tridiagonal{eltya}, Tridiagonal(dlreal, dreal, dureal))
end
ε = εa = eps(abs(float(one(eltya))))
if eltya <: BlasFloat
num = rand(eltya)
@test lu(num) == (one(eltya),num,1)
@test AbstractArray(lufact(num)) eltya[num]
end
for eltyb in (Float32, Float64, Complex64, Complex128, Int)
b = eltyb == Int ? rand(1:5, n, 2) :
convert(Matrix{eltyb}, eltyb <: Complex ? complex.(breal, bimg) : breal)
c = eltyb == Int ? rand(1:5, n) :
convert(Vector{eltyb}, eltyb <: Complex ? complex.(creal, cimg) : creal)
εb = eps(abs(float(one(eltyb))))
ε = max(εa,εb)
debug && println("(Automatic) Square LU decomposition. eltya: $eltya, eltyb: $eltyb")
κ = cond(a,1)
lua = factorize(a)
@test_throws KeyError lua[:Z]
l,u,p = lua[:L], lua[:U], lua[:p]
ll,ul,pl = lu(a)
@test ll * ul a[pl,:]
@test l*u a[p,:]
@test (l*u)[invperm(p),:] a
@test a * inv(lua) eye(n)
lstring = sprint(show,l)
ustring = sprint(show,u)
@test sprint(show,lua) == "$(typeof(lua)) with factors L and U:\n$lstring\n$ustring"
let Bs = b, Cs = c
for atype in ("Array", "SubArray")
if atype == "Array"
b = Bs
c = Cs
else
b = view(Bs, 1:n, 1)
c = view(Cs, 1:n)
end
@test norm(a*(lua\b) - b, 1) < ε*κ*n*2 # Two because the right hand side has two columns
@test norm(a'*(lua'\b) - b, 1) < ε*κ*n*2 # Two because the right hand side has two columns
@test norm(a'*(lua'\a') - a', 1) < ε*κ*n^2
@test norm(a*(lua\c) - c, 1) < ε*κ*n # c is a vector
@test norm(a'*(lua'\c) - c, 1) < ε*κ*n # c is a vector
@test AbstractArray(lua) a
if eltya <: Real && eltyb <: Real
@test norm(a.'*(lua.'\b) - b,1) < ε*κ*n*2 # Two because the right hand side has two columns
@test norm(a.'*(lua.'\c) - c,1) < ε*κ*n
end
end
end
if eltya <: BlasFloat && eltyb <: BlasFloat
e = rand(eltyb,n,n)
@test norm(e/lua - e/a,1) < ε*κ*n^2
end
debug && println("Tridiagonal LU")
κd = cond(Array(d),1)
lud = lufact(d)
@test lufact(lud) == lud
@test_throws KeyError lud[:Z]
@test lud[:L]*lud[:U] lud[:P]*Array(d)
@test lud[:L]*lud[:U] Array(d)[lud[:p],:]
@test AbstractArray(lud) d
f = zeros(eltyb, n+1)
@test_throws DimensionMismatch lud\f
@test_throws DimensionMismatch lud.'\f
@test_throws DimensionMismatch lud'\f
@test_throws DimensionMismatch Base.LinAlg.At_ldiv_B!(lud, f)
let Bs = b
for atype in ("Array", "SubArray")
if atype == "Array"
b = Bs
else
b = view(Bs, 1:n, 1)
end
@test norm(d*(lud\b) - b, 1) < ε*κd*n*2 # Two because the right hand side has two columns
if eltya <: Real
@test norm((lud.'\b) - Array(d.')\b, 1) < ε*κd*n*2 # Two because the right hand side has two columns
if eltya != Int && eltyb != Int
@test norm(Base.LinAlg.At_ldiv_B!(lud, copy(b)) - Array(d.')\b, 1) < ε*κd*n*2
end
end
if eltya <: Complex
@test norm((lud'\b) - Array(d')\b, 1) < ε*κd*n*2 # Two because the right hand side has two columns
end
end
end
if eltya <: BlasFloat && eltyb <: BlasFloat
e = rand(eltyb,n,n)
@test norm(e/lud - e/d,1) < ε*κ*n^2
@test norm((lud.'\e') - Array(d.')\e',1) < ε*κd*n^2
#test singular
du = rand(eltya,n-1)
dl = rand(eltya,n-1)
dd = rand(eltya,n)
dd[1] = zero(eltya)
du[1] = zero(eltya)
dl[1] = zero(eltya)
zT = Tridiagonal(dl,dd,du)
@test lufact(zT).info == 1
end
debug && println("Thin LU")
lua = @inferred lufact(a[:,1:n1])
@test lua[:L]*lua[:U] lua[:P]*a[:,1:n1]
debug && println("Fat LU")
lua = lufact(a[1:n1,:])
@test lua[:L]*lua[:U] lua[:P]*a[1:n1,:]
end
end
# test conversion routine
a = Tridiagonal(rand(9),rand(10),rand(9))
fa = Array(a)
falu = lufact(fa)
alu = lufact(a)
falu = convert(typeof(falu),alu)
@test AbstractArray(alu) == fa
# Test rational matrices
## Integrate in general tests when more linear algebra is implemented in julia
a = convert(Matrix{Rational{BigInt}}, rand(1:10//1,n,n))/n
b = rand(1:10,n,2)
@inferred lufact(a)
lua = factorize(a)
l,u,p = lua[:L], lua[:U], lua[:p]
@test l*u a[p,:]
@test l[invperm(p),:]*u a
@test a*inv(lua) eye(n)
let Bs = b
for atype in ("Array", "SubArray")
if atype == "Array"
b = Bs
else
b = view(Bs, 1:n, 1)
end
@test a*(lua\b) b
end
end
@test @inferred(det(a)) det(Array{Float64}(a))
## Hilbert Matrix (very ill conditioned)
## Testing Rational{BigInt} and BigFloat version
nHilbert = 50
H = Rational{BigInt}[1//(i+j-1) for i = 1:nHilbert,j = 1:nHilbert]
Hinv = Rational{BigInt}[(-1)^(i+j)*(i+j-1)*binomial(nHilbert+i-1,nHilbert-j)*
binomial(nHilbert+j-1,nHilbert-i)*binomial(i+j-2,i-1)^2
for i = big(1):nHilbert,j=big(1):nHilbert]
@test inv(H) == Hinv
setprecision(2^10) do
@test norm(Array{Float64}(inv(float(H)) - float(Hinv))) < 1e-100
end
# Test balancing in eigenvector calculations
for elty in (Float32, Float64, Complex64, Complex128)
A = convert(Matrix{elty}, [ 3.0 -2.0 -0.9 2*eps(real(one(elty)));
-2.0 4.0 1.0 -eps(real(one(elty)));
-eps(real(one(elty)))/4 eps(real(one(elty)))/2 -1.0 0;
-0.5 -0.5 0.1 1.0])
F = eigfact(A, permute=false, scale=false)
eig(A, permute=false, scale=false)
@test F[:vectors]*Diagonal(F[:values])/F[:vectors] A
F = eigfact(A)
# @test norm(F[:vectors]*Diagonal(F[:values])/F[:vectors] - A) > 0.01
end
@test @inferred(logdet(Complex64[1.0f0 0.5f0; 0.5f0 -1.0f0])) === 0.22314355f0 + 3.1415927f0im
@test_throws DomainError logdet([1 1; 1 -1])

View File

@@ -0,0 +1,422 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
using Base.Test
## Test Julia fallbacks to BLAS routines
# matrices with zero dimensions
@test ones(0,5)*ones(5,3) == zeros(0,3)
@test ones(3,5)*ones(5,0) == zeros(3,0)
@test ones(3,0)*ones(0,4) == zeros(3,4)
@test ones(0,5)*ones(5,0) == zeros(0,0)
@test ones(0,0)*ones(0,4) == zeros(0,4)
@test ones(3,0)*ones(0,0) == zeros(3,0)
@test ones(0,0)*ones(0,0) == zeros(0,0)
@test Array{Float64}(5, 0) |> t -> t't == zeros(0,0)
@test Array{Float64}(5, 0) |> t -> t*t' == zeros(5,5)
@test Array{Complex128}(5, 0) |> t -> t't == zeros(0,0)
@test Array{Complex128}(5, 0) |> t -> t*t' == zeros(5,5)
# 2x2
let
AA = [1 2; 3 4]
BB = [5 6; 7 8]
AAi = AA+(0.5*im).*BB
BBi = BB+(2.5*im).*AA[[2,1],[2,1]]
for Atype = ["Array", "SubArray"], Btype = ["Array", "SubArray"]
A = Atype == "Array" ? AA : view(AA, 1:2, 1:2)
B = Btype == "Array" ? BB : view(BB, 1:2, 1:2)
@test A*B == [19 22; 43 50]
@test At_mul_B(A, B) == [26 30; 38 44]
@test A_mul_Bt(A, B) == [17 23; 39 53]
@test At_mul_Bt(A, B) == [23 31; 34 46]
Ai = Atype == "Array" ? AAi : view(AAi, 1:2, 1:2)
Bi = Btype == "Array" ? BBi : view(BBi, 1:2, 1:2)
@test Ai*Bi == [-21+53.5im -4.25+51.5im; -12+95.5im 13.75+85.5im]
@test Ac_mul_B(Ai, Bi) == [68.5-12im 57.5-28im; 88-3im 76.5-25im]
@test A_mul_Bc(Ai, Bi) == [64.5+5.5im 43+31.5im; 104-18.5im 80.5+31.5im]
@test Ac_mul_Bc(Ai, Bi) == [-28.25-66im 9.75-58im; -26-89im 21-73im]
@test_throws DimensionMismatch [1 2; 0 0; 0 0] * [1 2]
end
CC = ones(3, 3)
@test_throws DimensionMismatch A_mul_B!(CC, AA, BB)
end
# 3x3
let
AA = [1 2 3; 4 5 6; 7 8 9].-5
BB = [1 0 5; 6 -10 3; 2 -4 -1]
AAi = AA+(0.5*im).*BB
BBi = BB+(2.5*im).*AA[[2,1,3],[2,3,1]]
for Atype = ["Array", "SubArray"], Btype = ["Array", "SubArray"]
A = Atype == "Array" ? AA : view(AA, 1:3, 1:3)
B = Btype == "Array" ? BB : view(BB, 1:3, 1:3)
@test A*B == [-26 38 -27; 1 -4 -6; 28 -46 15]
@test Ac_mul_B(A, B) == [-6 2 -25; 3 -12 -18; 12 -26 -11]
@test A_mul_Bc(A, B) == [-14 0 6; 4 -3 -3; 22 -6 -12]
@test Ac_mul_Bc(A, B) == [6 -8 -6; 12 -9 -9; 18 -10 -12]
Ai = Atype == "Array" ? AAi : view(AAi, 1:3, 1:3)
Bi = Btype == "Array" ? BBi : view(BBi, 1:3, 1:3)
@test Ai*Bi == [-44.75+13im 11.75-25im -38.25+30im; -47.75-16.5im -51.5+51.5im -56+6im; 16.75-4.5im -53.5+52im -15.5im]
@test Ac_mul_B(Ai, Bi) == [-21+2im -1.75+49im -51.25+19.5im; 25.5+56.5im -7-35.5im 22+35.5im; -3+12im -32.25+43im -34.75-2.5im]
@test A_mul_Bc(Ai, Bi) == [-20.25+15.5im -28.75-54.5im 22.25+68.5im; -12.25+13im -15.5+75im -23+27im; 18.25+im 1.5+94.5im -27-54.5im]
@test Ac_mul_Bc(Ai, Bi) == [1+2im 20.75+9im -44.75+42im; 19.5+17.5im -54-36.5im 51-14.5im; 13+7.5im 11.25+31.5im -43.25-14.5im]
@test_throws DimensionMismatch [1 2 3; 0 0 0; 0 0 0] * [1 2 3]
end
CC = ones(4, 4)
@test_throws DimensionMismatch A_mul_B!(CC, AA, BB)
end
# Generic integer matrix multiplication
# Generic AbstractArrays
module MyArray15367
using Base.Test
struct MyArray{T,N} <: AbstractArray{T,N}
data::Array{T,N}
end
Base.size(A::MyArray) = size(A.data)
Base.getindex(A::MyArray, indexes...) = A.data[indexes...]
A = MyArray(rand(4,5))
b = rand(5)
@test A*b A.data*b
end
let
AA = [1 2 3; 4 5 6] .- 3
BB = [2 -2; 3 -5; -4 7]
for Atype = ["Array", "SubArray"], Btype = ["Array", "SubArray"]
A = Atype == "Array" ? AA : view(AA, 1:2, 1:3)
B = Btype == "Array" ? BB : view(BB, 1:3, 1:2)
@test A*B == [-7 9; -4 9]
@test At_mul_Bt(A, B) == [-6 -11 15; -6 -13 18; -6 -15 21]
end
AA = ones(Int, 2, 100)
BB = ones(Int, 100, 3)
for Atype = ["Array", "SubArray"], Btype = ["Array", "SubArray"]
A = Atype == "Array" ? AA : view(AA, 1:2, 1:100)
B = Btype == "Array" ? BB : view(BB, 1:100, 1:3)
@test A*B == [100 100 100; 100 100 100]
end
AA = rand(1:20, 5, 5) .- 10
BB = rand(1:20, 5, 5) .- 10
CC = Array{Int}(size(AA, 1), size(BB, 2))
for Atype = ["Array", "SubArray"], Btype = ["Array", "SubArray"], Ctype = ["Array", "SubArray"]
A = Atype == "Array" ? AA : view(AA, 1:5, 1:5)
B = Btype == "Array" ? BB : view(BB, 1:5, 1:5)
C = Btype == "Array" ? CC : view(CC, 1:5, 1:5)
@test At_mul_B(A, B) == A'*B
@test A_mul_Bt(A, B) == A*B'
# Preallocated
@test A_mul_B!(C, A, B) == A*B
@test At_mul_B!(C, A, B) == A'*B
@test A_mul_Bt!(C, A, B) == A*B'
@test At_mul_Bt!(C, A, B) == A'*B'
@test Base.LinAlg.Ac_mul_Bt!(C, A, B) == A'*B.'
#test DimensionMismatch for generic_matmatmul
@test_throws DimensionMismatch Base.LinAlg.Ac_mul_Bt!(C,A,ones(Int,4,4))
@test_throws DimensionMismatch Base.LinAlg.Ac_mul_Bt!(C,ones(Int,4,4),B)
end
vv = [1,2]
CC = Array{Int}(2, 2)
for vtype = ["Array", "SubArray"], Ctype = ["Array", "SubArray"]
v = vtype == "Array" ? vv : view(vv, 1:2)
C = Ctype == "Array" ? CC : view(CC, 1:2, 1:2)
@test @inferred(A_mul_Bc!(C, v, v)) == [1 2; 2 4]
end
end
#and for generic_matvecmul
let
AA = rand(5,5)
BB = rand(5)
for Atype = ["Array", "SubArray"], Btype = ["Array", "SubArray"]
A = Atype == "Array" ? AA : view(AA, 1:5, 1:5)
B = Btype == "Array" ? BB : view(BB, 1:5)
@test_throws DimensionMismatch Base.LinAlg.generic_matvecmul!(zeros(6),'N',A,B)
@test_throws DimensionMismatch Base.LinAlg.generic_matvecmul!(B,'N',A,zeros(6))
end
vv = [1,2,3]
CC = Array{Int}(3, 3)
for vtype = ["Array", "SubArray"], Ctype = ["Array", "SubArray"]
v = vtype == "Array" ? vv : view(vv, 1:3)
C = Ctype == "Array" ? CC : view(CC, 1:3, 1:3)
@test A_mul_Bt!(C, v, v) == v*v'
end
vvf = map(Float64,vv)
CC = Array{Float64}(3, 3)
for vtype = ["Array", "SubArray"], Ctype = ["Array", "SubArray"]
vf = vtype == "Array" ? vvf : view(vvf, 1:3)
C = Ctype == "Array" ? CC : view(CC, 1:3, 1:3)
@test A_mul_Bt!(C, vf, vf) == vf*vf'
end
end
# fallbacks & such for BlasFloats
let
AA = rand(Float64,6,6)
BB = rand(Float64,6,6)
CC = zeros(Float64,6,6)
for Atype = ["Array", "SubArray"], Btype = ["Array", "SubArray"], Ctype = ["Array", "SubArray"]
A = Atype == "Array" ? AA : view(AA, 1:6, 1:6)
B = Btype == "Array" ? BB : view(BB, 1:6, 1:6)
C = Ctype == "Array" ? CC : view(CC, 1:6, 1:6)
@test Base.LinAlg.At_mul_Bt!(C,A,B) == A.'*B.'
@test Base.LinAlg.A_mul_Bc!(C,A,B) == A*B.'
@test Base.LinAlg.Ac_mul_B!(C,A,B) == A.'*B
end
end
# matrix algebra with subarrays of floats (stride != 1)
let
A = reshape(map(Float64,1:20),5,4)
Aref = A[1:2:end,1:2:end]
Asub = view(A, 1:2:5, 1:2:4)
b = [1.2,-2.5]
@test (Aref*b) == (Asub*b)
@test At_mul_B(Asub, Asub) == At_mul_B(Aref, Aref)
@test A_mul_Bt(Asub, Asub) == A_mul_Bt(Aref, Aref)
Ai = A .+ im
Aref = Ai[1:2:end,1:2:end]
Asub = view(Ai, 1:2:5, 1:2:4)
@test Ac_mul_B(Asub, Asub) == Ac_mul_B(Aref, Aref)
@test A_mul_Bc(Asub, Asub) == A_mul_Bc(Aref, Aref)
end
# issue #15286
let A = reshape(map(Float64, 1:20), 5, 4), C = zeros(8, 8), sC = view(C, 1:2:8, 1:2:8), B = reshape(map(Float64,-9:10),5,4)
@test At_mul_B!(sC, A, A) == A'*A
@test At_mul_B!(sC, A, B) == A'*B
Aim = A .- im
C = zeros(Complex128,8,8)
sC = view(C, 1:2:8, 1:2:8)
B = reshape(map(Float64,-9:10),5,4) .+ im
@test Ac_mul_B!(sC, Aim, Aim) == Aim'*Aim
@test Ac_mul_B!(sC, Aim, B) == Aim'*B
end
# syrk & herk
let
AA = reshape(1:1503, 501, 3).-750.0
res = Float64[135228751 9979252 -115270247; 9979252 10481254 10983256; -115270247 10983256 137236759]
for Atype = ["Array", "SubArray"]
A = Atype == "Array" ? AA : view(AA, 1:501, 1:3)
@test At_mul_B(A, A) == res
@test A_mul_Bt(A',A') == res
end
cutoff = 501
A = reshape(1:6*cutoff,2*cutoff,3).-(6*cutoff)/2
Asub = view(A, 1:2:2*cutoff, 1:3)
Aref = A[1:2:2*cutoff, 1:3]
@test At_mul_B(Asub, Asub) == At_mul_B(Aref, Aref)
Ai = A .- im
Asub = view(Ai, 1:2:2*cutoff, 1:3)
Aref = Ai[1:2:2*cutoff, 1:3]
@test Ac_mul_B(Asub, Asub) == Ac_mul_B(Aref, Aref)
@test_throws DimensionMismatch Base.LinAlg.syrk_wrapper!(zeros(5,5),'N',ones(6,5))
@test_throws DimensionMismatch Base.LinAlg.herk_wrapper!(zeros(5,5),'N',ones(6,5))
end
# matmul for types w/o sizeof (issue #1282)
let
AA = fill(complex(1,1), 10, 10)
for Atype = ["Array", "SubArray"]
A = Atype == "Array" ? AA : view(AA, 1:10, 1:10)
A2 = A^2
@test A2[1,1] == 20im
end
end
let
AA = zeros(5, 5)
BB = ones(5)
CC = rand(5, 6)
for Atype = ["Array", "SubArray"], Btype = ["Array", "SubArray"]
for Ctype = ["Array", "SubArray"]
A = Atype == "Array" ? AA : view(AA, 1:5, 1:5)
B = Btype == "Array" ? BB : view(BB, 1:5)
C = Ctype == "Array" ? CC : view(CC, 1:5, 1:6)
@test_throws DimensionMismatch scale!(A, B, C)
end
end
end
# issue #6450
@test dot(Any[1.0,2.0], Any[3.5,4.5]) === 12.5
for elty in (Float32,Float64,Complex64,Complex128)
x = convert(Vector{elty},[1.0,2.0,3.0])
y = convert(Vector{elty},[3.5,4.5,5.5])
@test_throws DimensionMismatch dot(x, 1:2, y, 1:3)
@test_throws BoundsError dot(x, 1:4, y, 1:4)
@test_throws BoundsError dot(x, 1:3, y, 2:4)
@test dot(x,1:2,y,1:2) == convert(elty,12.5)
@test x.'*y == convert(elty,29.0)
end
vecdot_(x,y) = invoke(vecdot, Tuple{Any,Any}, x,y) # generic vecdot
let AA = [1+2im 3+4im; 5+6im 7+8im], BB = [2+7im 4+1im; 3+8im 6+5im]
for Atype = ["Array", "SubArray"], Btype = ["Array", "SubArray"]
A = Atype == "Array" ? AA : view(AA, 1:2, 1:2)
B = Btype == "Array" ? BB : view(BB, 1:2, 1:2)
@test vecdot(A,B) == dot(vec(A),vec(B)) == vecdot_(A,B) == vecdot(float.(A),float.(B))
@test vecdot(Int[], Int[]) == 0 == vecdot_(Int[], Int[])
@test_throws MethodError vecdot(Any[], Any[])
@test_throws MethodError vecdot_(Any[], Any[])
for n1 = 0:2, n2 = 0:2, d in (vecdot, vecdot_)
if n1 != n2
@test_throws DimensionMismatch d(1:n1, 1:n2)
else
@test d(1:n1, 1:n2) vecnorm(1:n1)^2
end
end
end
end
# Issue 11978
let
A = Array{Matrix{Float64}}(2, 2)
A[1,1] = eye(3)
A[1,2] = eye(3,2)
A[2,1] = eye(2,3)
A[2,2] = eye(2)
b = Array{Vector{Float64}}(2)
b[1] = ones(3)
b[2] = ones(2)
@test A*b == Vector{Float64}[[2,2,1], [2,2]]
end
@test_throws ArgumentError Base.LinAlg.copytri!(ones(10,10),'Z')
for elty in [Float32,Float64,Complex128,Complex64]
@test_throws DimensionMismatch Base.LinAlg.gemv!(ones(elty,10),'N',rand(elty,10,10),ones(elty,11))
@test_throws DimensionMismatch Base.LinAlg.gemv!(ones(elty,11),'N',rand(elty,10,10),ones(elty,10))
@test Base.LinAlg.gemv!(ones(elty,0),'N',rand(elty,0,0),rand(elty,0)) == ones(elty,0)
@test Base.LinAlg.gemv!(ones(elty,10), 'N',ones(elty,10,0),ones(elty,0)) == zeros(elty,10)
@test Base.LinAlg.gemm_wrapper('N','N',eye(elty,10,10),eye(elty,10,10)) == eye(elty,10,10)
@test_throws DimensionMismatch Base.LinAlg.gemm_wrapper!(eye(elty,10,10),'N','N',eye(elty,10,11),eye(elty,10,10))
@test_throws DimensionMismatch Base.LinAlg.gemm_wrapper!(eye(elty,10,10),'N','N',eye(elty,0,0),eye(elty,0,0))
A = rand(elty,3,3)
@test Base.LinAlg.matmul3x3('T','N',A,eye(elty,3)) == A.'
end
# 13593, #13488
let
aa = rand(3,3)
bb = rand(3,3)
for atype = ["Array", "SubArray"], btype = ["Array", "SubArray"]
a = atype == "Array" ? aa : view(aa, 1:3, 1:3)
b = btype == "Array" ? bb : view(bb, 1:3, 1:3)
@test_throws ArgumentError A_mul_B!(a, a, b)
@test_throws ArgumentError A_mul_B!(a, b, a)
@test_throws ArgumentError A_mul_B!(a, a, a)
end
end
# Number types that lack conversion to the destination type (#14293)
struct RootInt
i::Int
end
import Base: *, transpose
(*)(x::RootInt, y::RootInt) = x.i*y.i
transpose(x::RootInt) = x
@test Base.promote_op(*, RootInt, RootInt) === Int
a = [RootInt(3)]
C = [0]
A_mul_Bt!(C, a, a)
@test C[1] == 9
a = [RootInt(2),RootInt(10)]
@test a*a' == [4 20; 20 100]
A = [RootInt(3) RootInt(5)]
@test A*a == [56]
function test_mul(C, A, B)
A_mul_B!(C, A, B)
@test Array(A) * Array(B) C
@test A*B C
end
let
eltypes = [Float32, Float64, Int64]
for k in [3, 4, 10]
T = rand(eltypes)
bi1 = Bidiagonal(rand(T, k), rand(T, k-1), rand(Bool))
bi2 = Bidiagonal(rand(T, k), rand(T, k-1), rand(Bool))
tri1 = Tridiagonal(rand(T,k-1), rand(T, k), rand(T, k-1))
tri2 = Tridiagonal(rand(T,k-1), rand(T, k), rand(T, k-1))
stri1 = SymTridiagonal(rand(T, k), rand(T, k-1))
stri2 = SymTridiagonal(rand(T, k), rand(T, k-1))
C = rand(T, k, k)
specialmatrices = (bi1, bi2, tri1, tri2, stri1, stri2)
for A in specialmatrices
B = specialmatrices[rand(1:length(specialmatrices))]
test_mul(C, A, B)
end
for S in specialmatrices
l = rand(1:6)
B = randn(k, l)
C = randn(k, l)
test_mul(C, S, B)
A = randn(l, k)
C = randn(l, k)
test_mul(C, A, S)
end
end
for T in eltypes
A = Bidiagonal(rand(T, 2), rand(T, 1), rand(Bool))
B = Bidiagonal(rand(T, 2), rand(T, 1), rand(Bool))
C = randn(2,2)
test_mul(C, A, B)
B = randn(2, 9)
C = randn(2, 9)
test_mul(C, A, B)
end
let
tri44 = Tridiagonal(randn(3), randn(4), randn(3))
tri33 = Tridiagonal(randn(2), randn(3), randn(2))
full43 = randn(4, 3)
full24 = randn(2, 4)
full33 = randn(3, 3)
full44 = randn(4, 4)
@test_throws DimensionMismatch A_mul_B!(full43, tri44, tri33)
@test_throws DimensionMismatch A_mul_B!(full44, tri44, tri33)
@test_throws DimensionMismatch A_mul_B!(full44, tri44, full43)
@test_throws DimensionMismatch A_mul_B!(full43, tri33, full43)
@test_throws DimensionMismatch A_mul_B!(full43, full43, tri44)
end
end
# #18218
module TestPR18218
using Base.Test
import Base.*, Base.+, Base.zero
struct TypeA
x::Int
end
Base.convert(::Type{TypeA}, x::Int) = TypeA(x)
struct TypeB
x::Int
end
struct TypeC
x::Int
end
Base.convert(::Type{TypeC}, x::Int) = TypeC(x)
zero(c::TypeC) = TypeC(0)
zero(::Type{TypeC}) = TypeC(0)
(*)(x::Int, a::TypeA) = TypeB(x*a.x)
(*)(a::TypeA, x::Int) = TypeB(a.x*x)
(+)(a::Union{TypeB,TypeC}, b::Union{TypeB,TypeC}) = TypeC(a.x+b.x)
A = TypeA[1 2; 3 4]
b = [1, 2]
d = A * b
@test typeof(d) == Vector{TypeC}
@test d == TypeC[5, 11]
end

View File

@@ -0,0 +1,327 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
#
# Test the pseudo-inverse
#
debug = false
using Base.Test
function hilb(T::Type, n::Integer)
a=Array{T}(n,n)
for i=1:n
for j=1:n
a[j,i]=one(T)/(i+j-one(T))
end
end
return a
end
hilb(n::Integer) = hilb(Float64,n)
function hilb(T::Type, m::Integer, n::Integer)
a=Array{T}(m,n)
for i=1:n
for j=1:m
a[j,i]=one(T)/(i+j-one(T))
end
end
return a
end
hilb(m::Integer, n::Integer) = hilb(Float64,m,n)
function onediag(T::Type, m::Integer, n::Integer)
a=zeros(T,m,n)
for i=1:min(n,m)
a[i,i]=one(T)/(float(i)^5)
end
a[1,1] = 0
a[min(m,n),min(m,n)] = 0
return a
end
onediag(m::Integer, n::Integer) = onediag(Float64, m::Integer, n::Integer)
function onediag_sparse(T::Type, n::Integer)
a=zeros(T,n)
for i=1:n
a[i]=one(T)/(float(i)^5)
end
a[1] = 0
a[n] = 0
return Diagonal(a)
end
onediag_sparse(n::Integer) = onediag_sparse(Float64, n::Integer)
function tridiag(T::Type, m::Integer, n::Integer)
a=zeros(T,m,n)
for i=1:min(n,m)
a[i,i]=one(T)/(float(i)^5)
end
for i=1:min(n,m)-1
a[i+1,i]=2*one(T)/(float(i)^5)
a[1,i+1]=2*one(T)/(float(i)^5)
end
return a
end
tridiag(m::Integer, n::Integer) = tridiag(Float64, m::Integer, n::Integer)
function randn_float64(m::Integer, n::Integer)
a=randn(m,n)
b=Array{Float64}(m,n)
for i=1:n
for j=1:m
b[j,i]=convert(Float64,a[j,i])
end
end
return b
end
function randn_float32(m::Integer, n::Integer)
a=randn(m,n)
b=Array{Float32}(m,n)
for i=1:n
for j=1:m
b[j,i]=convert(Float32,a[j,i])
end
end
return b
end
function test_pinv(a,m,n,tol1,tol2,tol3)
debug && println("=== julia/matlab pinv, default tol=eps(1.0)*max(size(a)) ===")
apinv = @inferred pinv(a)
@test vecnorm(a*apinv*a-a)/vecnorm(a) 0 atol=tol1
x0 = randn(n); b = a*x0; x = apinv*b
@test vecnorm(a*x-b)/vecnorm(b) 0 atol=tol1
debug && println(vecnorm(a*apinv*a - a)/vecnorm(a))
debug && println(vecnorm(a*x-b)/vecnorm(b))
debug && println("=== julia pinv, tol=sqrt(eps(1.0)) ===")
apinv = pinv(a,sqrt(eps(real(one(eltype(a))))))
@test vecnorm(a*apinv*a-a)/vecnorm(a) 0 atol=tol2
x0 = randn(n); b = a*x0; x = apinv*b
@test vecnorm(a*x-b)/vecnorm(b) 0 atol=tol2
debug && println(vecnorm(a*apinv*a - a)/vecnorm(a))
debug && println(vecnorm(a*x-b)/vecnorm(b))
end
srand(12345)
let
for eltya in (Float64, Complex128)
debug && println("\n\n<<<<<", eltya, ">>>>>")
m = 1000
n = 100
debug && println("\n\n n = ", n, ", m = ",m)
default_tol = (real(one(eltya))) * max(m,n) * 10
debug && println("\n--- dense/ill-conditioned matrix ---\n")
### a = randn_float64(m,n) * hilb(eltya,n)
a = hilb(eltya,m,n)
test_pinv(a,m,n,1e-2,1e-5,1e-5)
debug && println("\n--- dense/diagonal matrix ---\n")
a = onediag(eltya,m,n)
test_pinv(a,m,n,default_tol,default_tol,default_tol)
debug && println("\n--- dense/tri-diagonal matrix ---\n")
a = tridiag(eltya,m,n)
test_pinv(a,m,n,default_tol,1e-5,default_tol)
debug && println("\n--- Diagonal matrix ---\n")
a = onediag_sparse(eltya,m)
test_pinv(a,m,m,default_tol,default_tol,default_tol)
m = 100
n = 100
debug && println("\n\n n = ", n, ", m = ",m)
default_tol = (real(one(eltya))) * max(m,n) * 10
debug && println("\n--- dense/ill-conditioned matrix ---\n")
### a = randn_float64(m,n) * hilb(eltya,n)
a = hilb(eltya,m,n)
test_pinv(a,m,n,1e-2,1e-5,1e-5)
debug && println("\n--- dense/diagonal matrix ---\n")
a = onediag(eltya,m,n)
test_pinv(a,m,n,default_tol,default_tol,default_tol)
debug && println("\n--- dense/tri-diagonal matrix ---\n")
a = tridiag(eltya,m,n)
test_pinv(a,m,n,default_tol,1e-5,default_tol)
debug && println("\n--- Diagonal matrix ---\n")
a = onediag_sparse(eltya,m)
test_pinv(a,m,m,default_tol,default_tol,default_tol)
m = 100
n = 1000
debug && println("\n\n n = ", n, ", m = ",m)
default_tol = (real(one(eltya))) * max(m,n) * 10
debug && println("\n--- dense/ill-conditioned matrix ---\n")
### a = randn_float64(m,n) * hilb(eltya,n)
a = hilb(eltya,m,n)
test_pinv(a,m,n,1e-2,1e-5,1e-5)
debug && println("\n--- dense/diagonal matrix ---\n")
a = onediag(eltya,m,n)
test_pinv(a,m,n,default_tol,default_tol,default_tol)
debug && println("\n--- dense/tri-diagonal matrix ---\n")
a = tridiag(eltya,m,n)
test_pinv(a,m,n,default_tol,1e-5,default_tol)
debug && println("\n--- Diagonal matrix ---\n")
a = onediag_sparse(eltya,m)
test_pinv(a,m,m,default_tol,default_tol,default_tol)
end
end
for eltya in (Float32, Complex64)
debug && println("\n\n<<<<<", eltya, ">>>>>")
m = 1000
n = 100
debug && println("\n\n n = ", n, ", m = ",m)
default_tol = (real(one(eltya))) * max(m,n) * 10
debug && println("\n--- dense/ill-conditioned matrix ---\n")
### a = randn_float32(m,n) * hilb(eltya,n)
a = hilb(eltya,m,n)
test_pinv(a,m,n,1e0,1e-2,1e-2)
debug && println("\n--- dense/diagonal matrix ---\n")
a = onediag(eltya,m,n)
test_pinv(a,m,n,default_tol,default_tol,default_tol)
debug && println("\n--- dense/tri-diagonal matrix ---\n")
a = tridiag(eltya,m,n)
test_pinv(a,m,n,default_tol,1e-2,default_tol)
debug && println("\n--- Diagonal matrix ---\n")
a = onediag_sparse(eltya,m)
test_pinv(a,m,m,default_tol,default_tol,default_tol)
m = 100
n = 100
debug && println("\n\n n = ", n, ", m = ",m)
default_tol = (real(one(eltya))) * max(m,n) * 10
debug && println("\n--- dense/ill-conditioned matrix ---\n")
### a = randn_float32(m,n) * hilb(eltya,n)
a = hilb(eltya,m,n)
test_pinv(a,m,n,1e0,1e-2,1e-2)
debug && println("\n--- dense/diagonal matrix ---\n")
a = onediag(eltya,m,n)
test_pinv(a,m,n,default_tol,default_tol,default_tol)
debug && println("\n--- dense/tri-diagonal matrix ---\n")
a = tridiag(eltya,m,n)
test_pinv(a,m,n,default_tol,1e-2,default_tol)
debug && println("\n--- Diagonal matrix ---\n")
a = onediag_sparse(eltya,m)
test_pinv(a,m,m,default_tol,default_tol,default_tol)
m = 100
n = 1000
debug && println("\n\n n = ", n, ", m = ",m)
default_tol = (real(one(eltya))) * max(m,n) * 10
debug && println("\n--- dense/ill-conditioned matrix ---\n")
### a = randn_float32(m,n) * hilb(eltya,n)
a = hilb(eltya,m,n)
test_pinv(a,m,n,1e0,1e-2,1e-2)
debug && println("\n--- dense/diagonal matrix ---\n")
a = onediag(eltya,m,n)
test_pinv(a,m,n,default_tol,default_tol,default_tol)
debug && println("\n--- dense/tri-diagonal matrix ---\n")
a = tridiag(eltya,m,n)
test_pinv(a,m,n,default_tol,1e-2,default_tol)
debug && println("\n--- Diagonal matrix ---\n")
a = onediag_sparse(eltya,m)
test_pinv(a,m,m,default_tol,default_tol,default_tol)
end
# test zero matrices
for eltya in (Float32, Float64, Complex64, Complex128)
debug && println("\n\n<<<<<", eltya, ">>>>>")
debug && println("\n--- zero constant ---")
a = pinv(zero(eltya))
@test a 0.0
end
for eltya in (Float32, Float64, Complex64, Complex128)
debug && println("\n\n<<<<<", eltya, ">>>>>")
debug && println("\n--- zero vector ---")
a = pinv([zero(eltya); zero(eltya)])
@test a[1] 0.0
@test a[2] 0.0
end
for eltya in (Float32, Float64, Complex64, Complex128)
debug && println("\n\n<<<<<", eltya, ">>>>>")
debug && println("\n--- zero Diagonal matrix ---")
a = pinv(Diagonal([zero(eltya); zero(eltya)]))
@test a.diag[1] 0.0
@test a.diag[2] 0.0
end
# test sub-normal matrices
for eltya in (Float32, Float64)
debug && println("\n\n<<<<<", eltya, ">>>>>")
debug && println("\n--- sub-normal constant ---")
a = pinv(realmin(eltya)/100)
@test a 0.0
debug && println("\n\n<<<<<Complex{", eltya, "}>>>>>")
debug && println("\n--- sub-normal constant ---")
a = pinv(realmin(eltya)/100*(1+1im))
@test a 0.0
end
for eltya in (Float32, Float64)
debug && println("\n\n<<<<<", eltya, ">>>>>")
debug && println("\n--- sub-normal vector ---")
a = pinv([realmin(eltya); realmin(eltya)]/100)
@test a[1] 0.0
@test a[2] 0.0
debug && println("\n\n<<<<<Complex{", eltya, "}>>>>>")
debug && println("\n--- sub-normal vector ---")
a = pinv([realmin(eltya); realmin(eltya)]/100*(1+1im))
@test a[1] 0.0
@test a[2] 0.0
end
for eltya in (Float32, Float64)
debug && println("\n\n<<<<<", eltya, ">>>>>")
debug && println("\n--- sub-normal Diagonal matrix ---")
a = pinv(Diagonal([realmin(eltya); realmin(eltya)]/100))
@test a.diag[1] 0.0
@test a.diag[2] 0.0
debug && println("\n\n<<<<<Complex{", eltya, "}>>>>>")
debug && println("\n--- sub-normal Diagonal matrix ---")
a = pinv(Diagonal([realmin(eltya); realmin(eltya)]/100*(1+1im)))
@test a.diag[1] 0.0
@test a.diag[2] 0.0
end

View File

@@ -0,0 +1,198 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
debug = false
using Base.Test
using Base.LinAlg: BlasComplex, BlasFloat, BlasReal, QRPivoted
n = 10
# Split n into 2 parts for tests needing two matrices
n1 = div(n, 2)
n2 = 2*n1
srand(1234321)
areal = randn(n,n)/2
aimg = randn(n,n)/2
a2real = randn(n,n)/2
a2img = randn(n,n)/2
breal = randn(n,2)/2
bimg = randn(n,2)/2
for eltya in (Float32, Float64, Complex64, Complex128, BigFloat, Int)
a = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(areal, aimg) : areal)
a2 = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(a2real, a2img) : a2real)
asym = a'+a # symmetric indefinite
apd = a'*a # symmetric positive-definite
ε = εa = eps(abs(float(one(eltya))))
for eltyb in (Float32, Float64, Complex64, Complex128, Int)
b = eltyb == Int ? rand(1:5, n, 2) : convert(Matrix{eltyb}, eltyb <: Complex ? complex.(breal, bimg) : breal)
εb = eps(abs(float(one(eltyb))))
ε = max(εa,εb)
α = rand(eltyb)
aα = fill(α,1,1)
@test qrfact(α)[:Q]*qrfact(α)[:R] qrfact(aα)[:Q]*qrfact(aα)[:R]
@test abs(qrfact(α)[:Q][1,1]) one(eltyb)
tab = promote_type(eltya,eltyb)
debug && println("\ntype of a: ", eltya, " type of b: ", eltyb, "\n")
debug && println("QR decomposition (without pivoting)")
for i = 1:2
let a = i == 1 ? a : view(a, 1:n - 1, 1:n - 1), b = i == 1 ? b : view(b, 1:n - 1), n = i == 1 ? n : n - 1
qra = @inferred qrfact(a)
@inferred qr(a)
q, r = qra[:Q], qra[:R]
@test_throws KeyError qra[:Z]
@test q'*full(q, thin=false) eye(n)
@test q*full(q, thin=false)' eye(n)
@test q'*eye(n)' full(q, thin=false)'
@test full(q, thin=false)'q eye(n)
@test eye(n)'q' full(q, thin=false)'
@test q*r a
@test a*(qra\b) b atol=3000ε
@test full(qra) a
@test A_mul_Bc(eye(eltyb,size(q.factors,2)),q)*full(q,thin=false) eye(n) atol=5000ε
if eltya != Int
@test eye(eltyb,n)*q convert(AbstractMatrix{tab},q)
ac = copy(a)
@test qrfact!(a[:, 1:5])\b == qrfact!(view(ac, :, 1:5))\b
end
rstring = sprint(show,r)
qstring = sprint(show,q)
@test sprint(show,qra) == "$(typeof(qra)) with factors Q and R:\n$qstring\n$rstring"
debug && println("Thin QR decomposition (without pivoting)")
qra = @inferred qrfact(a[:,1:n1], Val{false})
@inferred qr(a[:,1:n1], Val{false})
q,r = qra[:Q], qra[:R]
@test_throws KeyError qra[:Z]
@test q'*full(q, thin=false) eye(n)
@test q'*full(q) eye(n,n1)
@test q*r a[:,1:n1]
@test q*b[1:n1] full(q)*b[1:n1] atol=100ε
@test q*b full(q,thin=false)*b atol=100ε
@test_throws DimensionMismatch q*b[1:n1 + 1]
@test_throws DimensionMismatch b[1:n1 + 1]*q'
@test A_mul_Bc(UpperTriangular(eye(eltyb,size(q.factors,2))),q)*full(q,thin=false) eye(n1,n) atol=5000ε
if eltya != Int
@test eye(eltyb,n)*q convert(AbstractMatrix{tab},q)
end
debug && println("(Automatic) Fat (pivoted) QR decomposition")
@inferred qrfact(a, Val{true})
@inferred qr(a, Val{true})
qrpa = factorize(a[1:n1,:])
q,r = qrpa[:Q], qrpa[:R]
@test_throws KeyError qrpa[:Z]
p = qrpa[:p]
@test q'*full(q, thin=false) eye(n1)
@test q*full(q, thin=false)' eye(n1)
@test (UpperTriangular(eye(eltya,size(q,2)))*q')*full(q, thin=false) eye(n1)
@test q*r (isa(qrpa,QRPivoted) ? a[1:n1,p] : a[1:n1,:])
@test q*r[:,invperm(p)] a[1:n1,:]
@test q*r*qrpa[:P].' a[1:n1,:]
@test a[1:n1,:]*(qrpa\b[1:n1]) b[1:n1] atol=5000ε
@test full(qrpa) a[1:5,:]
@test_throws DimensionMismatch q*b[1:n1+1]
@test_throws DimensionMismatch b[1:n1+1]*q'
if eltya != Int
@test eye(eltyb,n1)*q convert(AbstractMatrix{tab},q)
end
debug && println("(Automatic) Thin (pivoted) QR decomposition")
qrpa = factorize(a[:,1:n1])
q,r = qrpa[:Q], qrpa[:R]
@test_throws KeyError qrpa[:Z]
p = qrpa[:p]
@test q'*full(q, thin=false) eye(n)
@test q*full(q, thin=false)' eye(n)
@test q*r a[:,p]
@test q*r[:,invperm(p)] a[:,1:n1]
@test full(qrpa) a[:,1:5]
@test_throws DimensionMismatch q*b[1:n1+1]
@test_throws DimensionMismatch b[1:n1+1]*q'
@test A_mul_Bc(UpperTriangular(eye(eltyb,size(q.factors,2))),q)*full(q,thin=false) eye(n1,n) atol=5000ε
if eltya != Int
@test eye(eltyb,n)*q convert(AbstractMatrix{tab},q)
end
end
end
debug && println("Matmul with QR factorizations")
if eltya != Int
qrpa = factorize(a[:,1:n1])
q, r = qrpa[:Q], qrpa[:R]
@test A_mul_B!(full(q, thin=false)',q) eye(n)
@test_throws DimensionMismatch A_mul_B!(eye(eltya,n+1),q)
@test A_mul_Bc!(full(q, thin=false),q) eye(n)
@test_throws DimensionMismatch A_mul_Bc!(eye(eltya,n+1),q)
@test_throws BoundsError size(q,-1)
@test_throws DimensionMismatch Base.LinAlg.A_mul_B!(q,zeros(eltya,n1+1))
@test_throws DimensionMismatch Base.LinAlg.Ac_mul_B!(q,zeros(eltya,n1+1))
qra = qrfact(a[:,1:n1], Val{false})
q, r = qra[:Q], qra[:R]
@test A_mul_B!(full(q, thin=false)',q) eye(n)
@test_throws DimensionMismatch A_mul_B!(eye(eltya,n+1),q)
@test A_mul_Bc!(full(q, thin=false),q) eye(n)
@test_throws DimensionMismatch A_mul_Bc!(eye(eltya,n+1),q)
@test_throws BoundsError size(q,-1)
@test_throws DimensionMismatch q * eye(Int8,n+4)
end
end
end
# Because transpose(x) == x
@test_throws ErrorException transpose(qrfact(randn(3,3)))
@test_throws ErrorException ctranspose(qrfact(randn(3,3)))
@test_throws ErrorException transpose(qrfact(randn(3,3), Val{false}))
@test_throws ErrorException ctranspose(qrfact(randn(3,3), Val{false}))
@test_throws ErrorException transpose(qrfact(big.(randn(3,3))))
@test_throws ErrorException ctranspose(qrfact(big.(randn(3,3))))
# Issue 7304
let
A = [-.5 -.5; -.5 .5]
Q = full(qrfact(A)[:Q])
@test vecnorm(A-Q) < eps()
end
let
debug && println("qr on AbstractVector")
vr = [3.0, 4.0]
for Tr in (Float32, Float64)
for T in (Tr, Complex{Tr})
v = convert(Vector{T}, vr)
nv, nm = qr(v)
@test norm(nv - [0.6, 0.8], Inf) < eps(Tr)
@test nm == 5.0
end
end
end
@test qr(Int[]) == (Int[],1)
@test Base.LinAlg.qr!(Int[1]) == (Int[1],1)
B = rand(7,2)
@test (1:7)\B collect(1:7)\B
# Issue 16520
@test_throws DimensionMismatch ones(3,2)\(1:5)
# Issue 22810
let
A = zeros(1, 2)
B = zeros(1, 1)
@test A \ B == zeros(2, 1)
@test qrfact(A, Val{true}) \ B == zeros(2, 1)
end
@testset "Issue 24107" begin
A = rand(200,2)
@test A \ linspace(0,1,200) == A \ collect(linspace(0,1,200))
end

View File

@@ -0,0 +1,270 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
@testset "Core" begin
v = [1,2,3]
z = [1+im,2,3]
@test RowVector(v) == [1 2 3]
@test RowVector{Int}(v) == [1 2 3]
@test size(RowVector{Int}(3)) === (1,3)
@test size(RowVector{Int}(1,3)) === (1,3)
@test size(RowVector{Int}((3,))) === (1,3)
@test size(RowVector{Int}((1,3))) === (1,3)
@test_throws ErrorException RowVector{Float64, Vector{Int}}(v)
@test (v.')::RowVector == [1 2 3]
@test (v')::RowVector == [1 2 3]
@test (z.')::RowVector == [1+im 2 3]
@test (z')::RowVector == [1-im 2 3]
rv = v.'
tz = z.'
@test (rv.')::Vector == [1, 2, 3]
@test (rv')::Vector == [1, 2, 3]
@test (tz.')::Vector == [1+im, 2, 3]
@test (tz')::Vector == [1-im, 2, 3]
@test conj(rv) === rv
@test conj(tz) == [1-im 2 3]
@test isa(similar(rv), RowVector)
@test isa(similar(rv, Float64), RowVector)
@test isa(copy(rv), RowVector)
@test rv[2] === v[2]
@test rv[1,2] === v[2]
@test (rv2 = copy(rv); rv2[2] = 6; rv2[2] === 6)
@test (rv2 = copy(rv); rv2[1,2] = 6; rv2[2] === 6)
@test length(rv) === 3
@test size(rv) === (1,3)
@test size(rv,1) === 1
@test size(rv,2) === 3
@test map(-, rv)::RowVector == [-1 -2 -3]
@test (-).(rv)::RowVector == [-1 -2 -3]
@test (-).(rv,1)::RowVector == [0 1 2]
y = rand(Complex{Float64},3)
@test sum(abs2, imag.(diag(y .+ y'))) < 1e-20
end
@testset "Diagonal ambiguity methods" begin
d = Diagonal([1,2,3])
v = [2,3,4]
rv = v.'
@test (rv*d)::RowVector == [2,6,12].'
@test_throws DimensionMismatch d*rv
@test (d*rv.')::Vector == [2,6,12]
@test_throws DimensionMismatch rv.'*d
@test (d*rv')::Vector == [2,6,12]
@test_throws DimensionMismatch rv'*d
@test (rv/d)::RowVector [2/1 3/2 4/3]
@test_throws DimensionMismatch d \ rv
end
@testset "Bidiagonal ambiguity methods" begin
bd = Bidiagonal([1,2,3], [0,0], true)
v = [2,3,4]
rv = v.'
@test (rv/bd)::RowVector [2/1 3/2 4/3]
@test_throws DimensionMismatch bd \ rv
end
@testset "hcat" begin
@test isa([([1, 2, 3].') 4], RowVector{Int})
@test isa([([1, 2, 3].') ([4, 5].')], RowVector{Int})
end
@testset "Left Division" begin
mat = diagm([1,2,3])
v = [2,3,4]
rv = v.'
@test_throws DimensionMismatch mat \ rv
end
@testset "Multiplication" begin
v = [1,2,3]
rv = v.'
mat = diagm([1,2,3])
@test (rv*v) === 14
@test (rv*mat)::RowVector == [1 4 9]
@test [1]*reshape([1],(1,1)) == reshape([1], (1,1))
@test_throws DimensionMismatch rv*rv
@test (v*rv)::Matrix == [1 2 3; 2 4 6; 3 6 9]
@test_throws DimensionMismatch v*v # Was previously a missing method error, now an error message
@test_throws DimensionMismatch mat*rv
@test_throws DimensionMismatch rv*v.'
@test (rv*mat.')::RowVector == [1 4 9]
@test [1]*reshape([1],(1,1)).' == reshape([1], (1,1))
@test rv*rv.' === 14
@test_throws DimensionMismatch v*rv.'
@test (v*v.')::Matrix == [1 2 3; 2 4 6; 3 6 9]
@test (mat*rv.')::Vector == [1,4,9]
@test (rv.'*v.')::Matrix == [1 2 3; 2 4 6; 3 6 9]
@test_throws DimensionMismatch rv.'*mat.'
@test (v.'*mat.')::RowVector == [1 4 9]
@test_throws DimensionMismatch rv.'*rv.'
@test v.'*rv.' === 14
@test_throws DimensionMismatch v.'*v.'
@test (mat.'*rv.')::Vector == [1,4,9]
@test_throws DimensionMismatch rv.'*v
@test_throws DimensionMismatch rv.'*mat
@test (v.'*mat)::RowVector == [1 4 9]
@test (rv.'*rv)::Matrix == [1 2 3; 2 4 6; 3 6 9]
@test_throws DimensionMismatch v.'*rv
@test v.'*v === 14
@test_throws DimensionMismatch mat.'*rv
z = [1+im,2,3]
cz = z'
mat = diagm([1+im,2,3])
@test cz*z === 15 + 0im
@test_throws DimensionMismatch cz*z'
@test (cz*mat')::RowVector == [-2im 4 9]
@test [1]*reshape([1],(1,1))' == reshape([1], (1,1))
@test cz*cz' === 15 + 0im
@test_throws DimensionMismatch z*cz'
@test (z*z')::Matrix == [2 2+2im 3+3im; 2-2im 4 6; 3-3im 6 9]
@test (mat*cz')::Vector == [2im,4,9]
@test (cz'*z')::Matrix == [2 2+2im 3+3im; 2-2im 4 6; 3-3im 6 9]
@test_throws DimensionMismatch cz'*mat'
@test (z'*mat')::RowVector == [-2im 4 9]
@test_throws DimensionMismatch cz'*cz'
@test z'*cz' === 15 + 0im
@test_throws DimensionMismatch z'*z'
@test (mat'*cz')::Vector == [2,4,9]
@test_throws DimensionMismatch cz'*z
@test_throws DimensionMismatch cz'*mat
@test (z'*mat)::RowVector == [2 4 9]
@test (cz'*cz)::Matrix == [2 2+2im 3+3im; 2-2im 4 6; 3-3im 6 9]
@test_throws DimensionMismatch z'*cz
@test z'*z === 15 + 0im
@test_throws DimensionMismatch mat'*cz
end
@testset "norm" begin
@test norm([3.0,4.0].') 5.0
@test norm([3.0,4.0].', 1) 4.0
@test norm([3.0,4.0].', Inf) 7.0
end
@testset "QR ambiguity methods" begin
qrmat = Base.LinAlg.getq(qrfact(eye(3)))
v = [2,3,4]
rv = v.'
@test (rv*qrmat')::RowVector == [2 3 4]
end
@testset "Right Division" begin
mat = diagm([1,2,3])
v = [2,3,4]
rv = v.'
@test (rv/mat)::RowVector [2/1 3/2 4/3]
@test (v.'/mat)::RowVector [2/1 3/2 4/3]
@test (v.'/mat.')::RowVector [2/1 3/2 4/3]
@test (rv/mat.')::RowVector [2/1 3/2 4/3]
@test (v'/mat)::RowVector [2/1 3/2 4/3]
@test (v'/mat')::RowVector [2/1 3/2 4/3]
@test (rv/mat')::RowVector [2/1 3/2 4/3]
end
@testset "Sparse ambiguity methods" begin
mat = sparse(diagm([1,2,3]))
v = [2,3,4]
rv = v.'
@test (rv/mat)::RowVector [2/1 3/2 4/3]
@test_throws DimensionMismatch mat\rv
end
@testset "AbstractTriangular ambiguity methods" begin
ut = UpperTriangular([1 0 0; 0 2 0; 0 0 3])
v = [2,3,4]
rv = v.'
@test (rv*ut)::RowVector == [2 6 12]
@test_throws DimensionMismatch ut*rv
@test (rv*ut.')::RowVector == [2 6 12]
@test (ut*rv.')::Vector == [2,6,12]
@test (ut.'*rv.')::Vector == [2,6,12]
@test_throws DimensionMismatch rv.'*ut.'
@test_throws DimensionMismatch ut.'*rv
@test_throws DimensionMismatch rv.'*ut
@test (rv*ut')::RowVector == [2 6 12]
@test (ut*rv')::Vector == [2,6,12]
@test_throws DimensionMismatch rv'*ut'
@test (ut'*rv')::Vector == [2,6,12]
@test_throws DimensionMismatch ut'*rv
@test_throws DimensionMismatch rv'*ut
@test (rv/ut)::RowVector [2/1 3/2 4/3]
@test (rv/ut.')::RowVector [2/1 3/2 4/3]
@test (rv/ut')::RowVector [2/1 3/2 4/3]
@test_throws DimensionMismatch ut\rv
end
# issue #20389
@testset "1 row/col vec*mat" begin
let x=[1,2,3], A=ones(1,4), y=x', B=A', C=x.*A
@test x*A == y'*A == x*B' == y'*B' == C
@test A'*x' == A'*y == B*x' == B*y == C'
end
end
@testset "complex 1 row/col vec*mat" begin
let x=[1,2,3]*im, A=ones(1,4)*im, y=x', B=A', C=x.*A
@test x*A == y'*A == x*B' == y'*B' == C
@test A'*x' == A'*y == B*x' == B*y == C'
end
end
@testset "issue #20979" begin
f20979(z::Complex) = [z.re -z.im; z.im z.re]
v = [1+2im]'
@test (f20979.(v))[1] == f20979(v[1])
@test f20979.(v) == f20979.(collect(v))
w = rand(Complex128, 3)
@test f20979.(v') == f20979.(collect(v')) == (f20979.(v))'
g20979(x, y) = [x[2,1] x[1,2]; y[1,2] y[2,1]]
v = [rand(2,2), rand(2,2), rand(2,2)]
@test g20979.(v', v') == g20979.(collect(v'), collect(v')) ==
map(g20979, v', v') == map(g20979, collect(v'), collect(v'))
end
@testset "ambiguity between * methods with RowVectors and ConjRowVectors (#20971)" begin
@test RowVector(ConjArray(ones(4))) * ones(4) == 4
end

View File

@@ -0,0 +1,109 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
using Base.Test
using Base.LinAlg: BlasComplex, BlasFloat, BlasReal, QRPivoted
n = 10
# Split n into 2 parts for tests needing two matrices
n1 = div(n, 2)
n2 = 2*n1
srand(1234321)
areal = randn(n,n)/2
aimg = randn(n,n)/2
@testset for eltya in (Float32, Float64, Complex64, Complex128, Int)
a = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(areal, aimg) : areal)
asym = a'+a # symmetric indefinite
apd = a'*a # symmetric positive-definite
@testset for atype in ("Array", "SubArray")
if atype == "Array"
a = a
else
a = view(a, 1:n, 1:n)
asym = view(asym, 1:n, 1:n)
apd = view(apd, 1:n, 1:n)
end
ε = εa = eps(abs(float(one(eltya))))
d,v = eig(a)
f = schurfact(a)
@test f[:vectors]*f[:Schur]*f[:vectors]' a
@test sort(real(f[:values])) sort(real(d))
@test sort(imag(f[:values])) sort(imag(d))
@test istriu(f[:Schur]) || eltype(a)<:Real
@test AbstractArray(f) a
@test_throws KeyError f[:A]
tstring = sprint(show,f[:T])
zstring = sprint(show,f[:Z])
vstring = sprint(show,f[:values])
@test sprint(show,f) == "$(typeof(f)) with factors T and Z:\n$tstring\n$(zstring)\nand values:\n$vstring"
@testset "Reorder Schur" begin
# use asym for real schur to enforce tridiag structure
# avoiding partly selection of conj. eigenvalues
ordschura = eltya <: Complex ? a : asym
S = schurfact(ordschura)
select = bitrand(n)
O = ordschur(S, select)
sum(select) != 0 && @test S[:values][find(select)] O[:values][1:sum(select)]
@test O[:vectors]*O[:Schur]*O[:vectors]' ordschura
@test_throws KeyError f[:A]
Snew = Base.LinAlg.Schur(S.T, S.Z, S.values)
SchurNew = ordschur!(copy(Snew), select)
@test O[:vectors] SchurNew[:vectors]
@test O[:Schur] SchurNew[:Schur]
end
if atype == "Array"
a1_sf = a[1:n1, 1:n1]
a2_sf = a[n1+1:n2, n1+1:n2]
else
a1_sf = view(a, 1:n1, 1:n1)
a2_sf = view(a, n1+1:n2, n1+1:n2)
end
@testset "Generalized Schur" begin
f = schurfact(a1_sf, a2_sf)
@test f[:Q]*f[:S]*f[:Z]' a1_sf
@test f[:Q]*f[:T]*f[:Z]' a2_sf
@test istriu(f[:S]) || eltype(a)<:Real
@test istriu(f[:T]) || eltype(a)<:Real
@test_throws KeyError f[:A]
end
@testset "Reorder Generalized Schur" begin
NS = schurfact(a1_sf, a2_sf)
# Currently just testing with selecting gen eig values < 1
select = abs2.(NS[:values]) .< 1
m = sum(select)
S = ordschur(NS, select)
# Make sure that the new factorization stil factors matrix
@test S[:Q]*S[:S]*S[:Z]' a1_sf
@test S[:Q]*S[:T]*S[:Z]' a2_sf
# Make sure that we have sorted it correctly
@test NS[:values][find(select)] S[:values][1:m]
Snew = Base.LinAlg.GeneralizedSchur(NS.S, NS.T, NS.alpha, NS.beta, NS.Q, NS.Z)
SchurNew = ordschur!(copy(Snew), select)
@test S[:Q] SchurNew[:Q]
@test S[:S] SchurNew[:S]
@test S[:T] SchurNew[:T]
@test S[:Z] SchurNew[:Z]
@test S[:alpha] SchurNew[:alpha]
@test S[:beta] SchurNew[:beta]
sS,sT,sQ,sZ = schur(a1_sf,a2_sf)
@test NS[:Q] sQ
@test NS[:T] sT
@test NS[:S] sS
@test NS[:Z] sZ
end
end
@testset "0x0 matrix" for A in (zeros(eltya, 0, 0), view(rand(eltya, 2, 2), 1:0, 1:0))
T, Z, λ = Base.LinAlg.schur(A)
@test T == A
@test Z == A
@test λ == zeros(0)
end
end

View File

@@ -0,0 +1,252 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
using Base.Test
debug = false
n= 10 #Size of matrix to test
srand(1)
debug && println("Test interconversion between special matrix types")
let a=[1.0:n;]
A=Diagonal(a)
for newtype in [Diagonal, Bidiagonal, SymTridiagonal, Tridiagonal, Matrix]
debug && println("newtype is $(newtype)")
@test full(convert(newtype, A)) == full(A)
end
for isupper in (true, false)
debug && println("isupper is $(isupper)")
A=Bidiagonal(a, [1.0:n-1;], isupper)
for newtype in [Bidiagonal, Tridiagonal, Matrix]
debug && println("newtype is $(newtype)")
@test full(convert(newtype, A)) == full(A)
@test full(newtype(A)) == full(A)
end
@test_throws ArgumentError convert(SymTridiagonal, A)
tritype = isupper ? UpperTriangular : LowerTriangular
@test full(tritype(A)) == full(A)
A=Bidiagonal(a, zeros(n-1), isupper) #morally Diagonal
for newtype in [Diagonal, Bidiagonal, SymTridiagonal, Tridiagonal, Matrix]
debug && println("newtype is $(newtype)")
@test full(convert(newtype, A)) == full(A)
@test full(newtype(A)) == full(A)
end
@test full(tritype(A)) == full(A)
end
A = SymTridiagonal(a, [1.0:n-1;])
for newtype in [Tridiagonal, Matrix]
@test full(convert(newtype, A)) == full(A)
end
for newtype in [Diagonal, Bidiagonal]
@test_throws ArgumentError convert(newtype,A)
end
A = SymTridiagonal(a, zeros(n-1))
@test full(convert(Bidiagonal,A)) == full(A)
A = Tridiagonal(zeros(n-1), [1.0:n;], zeros(n-1)) #morally Diagonal
for newtype in [Diagonal, Bidiagonal, SymTridiagonal, Matrix]
@test full(convert(newtype, A)) == full(A)
end
A = Tridiagonal(ones(n-1), [1.0:n;], ones(n-1)) #not morally Diagonal
for newtype in [SymTridiagonal, Matrix]
@test full(convert(newtype, A)) == full(A)
end
for newtype in [Diagonal, Bidiagonal]
@test_throws ArgumentError convert(newtype,A)
end
A = Tridiagonal(zeros(n-1), [1.0:n;], ones(n-1)) #not morally Diagonal
@test full(convert(Bidiagonal, A)) == full(A)
A = UpperTriangular(Tridiagonal(zeros(n-1), [1.0:n;], ones(n-1)))
@test full(convert(Bidiagonal, A)) == full(A)
A = Tridiagonal(ones(n-1), [1.0:n;], zeros(n-1)) #not morally Diagonal
@test full(convert(Bidiagonal, A)) == full(A)
A = LowerTriangular(Tridiagonal(ones(n-1), [1.0:n;], zeros(n-1)))
@test full(convert(Bidiagonal, A)) == full(A)
@test_throws ArgumentError convert(SymTridiagonal,A)
A = LowerTriangular(full(Diagonal(a))) #morally Diagonal
for newtype in [Diagonal, Bidiagonal, SymTridiagonal, LowerTriangular, Matrix]
@test full(convert(newtype, A)) == full(A)
end
A = UpperTriangular(full(Diagonal(a))) #morally Diagonal
for newtype in [Diagonal, Bidiagonal, SymTridiagonal, UpperTriangular, Matrix]
@test full(convert(newtype, A)) == full(A)
end
A = UpperTriangular(triu(rand(n,n)))
for newtype in [Diagonal, Bidiagonal, Tridiagonal, SymTridiagonal]
@test_throws ArgumentError convert(newtype,A)
end
end
# Binary ops among special types
let a=[1.0:n;]
A=Diagonal(a)
Spectypes = [Diagonal, Bidiagonal, Tridiagonal, Matrix]
for (idx, type1) in enumerate(Spectypes)
for type2 in Spectypes
B = convert(type1,A)
C = convert(type2,A)
@test full(B + C) full(A + A)
@test full(B - C) full(A - A)
end
end
B = SymTridiagonal(a, ones(n-1))
for Spectype in [Diagonal, Bidiagonal, Tridiagonal, Matrix]
@test full(B + convert(Spectype,A)) full(B + A)
@test full(convert(Spectype,A) + B) full(B + A)
@test full(B - convert(Spectype,A)) full(B - A)
@test full(convert(Spectype,A) - B) full(A - B)
end
C = rand(n,n)
for TriType in [Base.LinAlg.UnitLowerTriangular, Base.LinAlg.UnitUpperTriangular, UpperTriangular, LowerTriangular]
D = TriType(C)
for Spectype in [Diagonal, Bidiagonal, Tridiagonal, Matrix]
@test full(D + convert(Spectype,A)) full(D + A)
@test full(convert(Spectype,A) + D) full(A + D)
@test full(D - convert(Spectype,A)) full(D - A)
@test full(convert(Spectype,A) - D) full(A - D)
end
end
end
#Triangular Types and QR
for typ in [UpperTriangular,LowerTriangular,Base.LinAlg.UnitUpperTriangular,Base.LinAlg.UnitLowerTriangular]
a = rand(n,n)
atri = typ(a)
b = rand(n,n)
qrb = qrfact(b,Val{true})
@test Base.LinAlg.A_mul_Bc(atri,qrb[:Q]) full(atri) * qrb[:Q]'
@test Base.LinAlg.A_mul_Bc!(copy(atri),qrb[:Q]) full(atri) * qrb[:Q]'
qrb = qrfact(b,Val{false})
@test Base.LinAlg.A_mul_Bc(atri,qrb[:Q]) full(atri) * qrb[:Q]'
@test Base.LinAlg.A_mul_Bc!(copy(atri),qrb[:Q]) full(atri) * qrb[:Q]'
end
# Test that concatenations of combinations of special and other matrix types yield sparse arrays
let N = 4
# Test concatenating pairwise combinations of special matrices
diagmat = Diagonal(ones(N))
bidiagmat = Bidiagonal(ones(N), ones(N-1), true)
tridiagmat = Tridiagonal(ones(N-1), ones(N), ones(N-1))
symtridiagmat = SymTridiagonal(ones(N), ones(N-1))
specialmats = (diagmat, bidiagmat, tridiagmat, symtridiagmat)
for specialmata in specialmats, specialmatb in specialmats
@test issparse(hcat(specialmata, specialmatb))
@test issparse(vcat(specialmata, specialmatb))
@test issparse(hvcat((1,1), specialmata, specialmatb))
@test issparse(cat((1,2), specialmata, specialmatb))
end
# Test concatenating pairwise combinations of special matrices with sparse matrices,
# dense matrices, or dense vectors
densevec = ones(N)
densemat = diagm(ones(N))
spmat = spdiagm(ones(N))
for specialmat in specialmats
# --> Tests applicable only to pairs of matrices
for othermat in (spmat, densemat)
@test issparse(vcat(specialmat, othermat))
@test issparse(vcat(othermat, specialmat))
end
# --> Tests applicable also to pairs including vectors
for specialmat in specialmats, othermatorvec in (spmat, densemat, densevec)
@test issparse(hcat(specialmat, othermatorvec))
@test issparse(hcat(othermatorvec, specialmat))
@test issparse(hvcat((2,), specialmat, othermatorvec))
@test issparse(hvcat((2,), othermatorvec, specialmat))
@test issparse(cat((1,2), specialmat, othermatorvec))
@test issparse(cat((1,2), othermatorvec, specialmat))
end
end
end
# Test that concatenations of annotated sparse/special matrix types with other matrix
# types yield sparse arrays, and that the code which effects that does not make concatenations
# strictly involving un/annotated dense matrices yield sparse arrays
#
# TODO: As with the associated code, these tests should be moved to a more appropriate
# location, particularly some future equivalent of base/linalg/special.jl dedicated to
# intereactions between a broader set of matrix types
let
N = 4
# The tested annotation types
testfull = Bool(parse(Int,(get(ENV, "JULIA_TESTFULL", "0"))))
utriannotations = (UpperTriangular, Base.LinAlg.UnitUpperTriangular)
ltriannotations = (LowerTriangular, Base.LinAlg.UnitLowerTriangular)
triannotations = (utriannotations..., ltriannotations...)
symannotations = (Symmetric, Hermitian)
annotations = testfull ? (triannotations..., symannotations...) : (LowerTriangular, Symmetric)
# Concatenations involving these types, un/annotated, should yield sparse arrays
spvec = spzeros(N)
spmat = speye(N)
diagmat = Diagonal(ones(N))
bidiagmat = Bidiagonal(ones(N), ones(N-1), true)
tridiagmat = Tridiagonal(ones(N-1), ones(N), ones(N-1))
symtridiagmat = SymTridiagonal(ones(N), ones(N-1))
sparseconcatmats = testfull ? (spmat, diagmat, bidiagmat, tridiagmat, symtridiagmat) : (spmat, diagmat)
# Concatenations involving strictly these types, un/annotated, should yield dense arrays
densevec = ones(N)
densemat = ones(N, N)
# Annotated collections
annodmats = [annot(densemat) for annot in annotations]
annospcmats = [annot(spcmat) for annot in annotations, spcmat in sparseconcatmats]
# Test that concatenations of pairwise combinations of annotated sparse/special
# yield sparse matrices
for annospcmata in annospcmats, annospcmatb in annospcmats
@test issparse(vcat(annospcmata, annospcmatb))
@test issparse(hcat(annospcmata, annospcmatb))
@test issparse(hvcat((2,), annospcmata, annospcmatb))
@test issparse(cat((1,2), annospcmata, annospcmatb))
end
# Test that concatenations of pairwise combinations of annotated sparse/special
# matrices and other matrix/vector types yield sparse matrices
for annospcmat in annospcmats
# --> Tests applicable to pairs including only matrices
for othermat in (densemat, annodmats..., sparseconcatmats...)
@test issparse(vcat(annospcmat, othermat))
@test issparse(vcat(othermat, annospcmat))
end
# --> Tests applicable to pairs including other vectors or matrices
for other in (spvec, densevec, densemat, annodmats..., sparseconcatmats...)
@test issparse(hcat(annospcmat, other))
@test issparse(hcat(other, annospcmat))
@test issparse(hvcat((2,), annospcmat, other))
@test issparse(hvcat((2,), other, annospcmat))
@test issparse(cat((1,2), annospcmat, other))
@test issparse(cat((1,2), other, annospcmat))
end
end
# The preceding tests should cover multi-way combinations of those types, but for good
# measure test a few multi-way combinations involving those types
@test issparse(vcat(spmat, densemat, annospcmats[1], annodmats[2]))
@test issparse(vcat(densemat, spmat, annodmats[1], annospcmats[2]))
@test issparse(hcat(spvec, annodmats[1], annospcmats[3], densevec, diagmat))
@test issparse(hcat(annodmats[2], annospcmats[4], spvec, densevec, diagmat))
@test issparse(hvcat((5,), diagmat, densevec, spvec, annodmats[1], annospcmats[1]))
@test issparse(hvcat((5,), spvec, annodmats[2], diagmat, densevec, annospcmats[2]))
@test issparse(cat((1,2), annodmats[1], diagmat, annospcmats[3], densevec, spvec))
@test issparse(cat((1,2), spvec, diagmat, densevec, annospcmats[4], annodmats[2]))
# Test that concatenations strictly involving un/annotated dense matrices/vectors
# yield dense arrays
for densemata in (densemat, annodmats...)
# --> Tests applicable to pairs including only matrices
for densematb in (densemat, annodmats...)
@test !issparse(vcat(densemata, densematb))
@test !issparse(vcat(densematb, densemata))
end
# --> Tests applicable to pairs including vectors or matrices
for otherdense in (densevec, densemat, annodmats...)
@test !issparse(hcat(densemata, otherdense))
@test !issparse(hcat(otherdense, densemata))
@test !issparse(hvcat((2,), densemata, otherdense))
@test !issparse(hvcat((2,), otherdense, densemata))
@test !issparse(cat((1,2), densemata, otherdense))
@test !issparse(cat((1,2), otherdense, densemata))
end
end
end
@testset "vcat of Vectors with SparseVectors should yield SparseVector (#22225)" begin
@test isa((@inferred vcat(Float64[], spzeros(1))), SparseVector)
end

View File

@@ -0,0 +1,81 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
using Base.Test
using Base.LinAlg: BlasComplex, BlasFloat, BlasReal, QRPivoted
n = 10
# Split n into 2 parts for tests needing two matrices
n1 = div(n, 2)
n2 = 2*n1
srand(1234321)
areal = randn(n,n)/2
aimg = randn(n,n)/2
a2real = randn(n,n)/2
a2img = randn(n,n)/2
@testset for eltya in (Float32, Float64, Complex64, Complex128, Int)
aa = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(areal, aimg) : areal)
aa2 = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(a2real, a2img) : a2real)
asym = aa'+aa # symmetric indefinite
apd = aa'*aa # symmetric positive-definite
@testset for atype in ("Array", "SubArray")
if atype == "Array"
a = aa
a2 = aa2
else
a = view(aa, 1:n, 1:n)
a2 = view(aa2, 1:n, 1:n)
end
ε = εa = eps(abs(float(one(eltya))))
usv = svdfact(a)
@testset "singular value decomposition" begin
@test usv[:S] === svdvals(usv)
@test usv[:U] * (Diagonal(usv[:S]) * usv[:Vt]) a
@test AbstractArray(usv) a
@test usv[:Vt]' usv[:V]
@test_throws KeyError usv[:Z]
b = rand(eltya,n)
@test usv\b a\b
if eltya <: BlasFloat
svdz = svdfact!(ones(eltya,0,0))
@test svdz[:U] eye(eltya,0,0)
@test svdz[:S] real(zeros(eltya,0))
@test svdz[:Vt] eye(eltya,0,0)
end
end
@testset "Generalized svd" begin
a_svd = a[1:n1, :]
gsvd = svdfact(a,a_svd)
@test gsvd[:U]*gsvd[:D1]*gsvd[:R]*gsvd[:Q]' a
@test gsvd[:V]*gsvd[:D2]*gsvd[:R]*gsvd[:Q]' a_svd
@test usv[:Vt]' usv[:V]
@test_throws KeyError usv[:Z]
@test_throws KeyError gsvd[:Z]
@test gsvd[:vals] svdvals(a,a_svd)
α = eltya == Int ? -1 : rand(eltya)
β = svdfact(α)
@test β[:S] == [abs(α)]
@test svdvals(α) == abs(α)
u,v,q,d1,d2,r0 = svd(a,a_svd)
@test u gsvd[:U]
@test v gsvd[:V]
@test d1 gsvd[:D1]
@test d2 gsvd[:D2]
@test q gsvd[:Q]
@test gsvd[:a].^2 + gsvd[:b].^2 ones(eltya,length(gsvd[:a]))
#testing the other layout for D1 & D2
b = rand(eltya,n,2*n)
c = rand(eltya,n,2*n)
gsvd = svdfact(b,c)
@test gsvd[:U]*gsvd[:D1]*gsvd[:R]*gsvd[:Q]' b
@test gsvd[:V]*gsvd[:D2]*gsvd[:R]*gsvd[:Q]' c
end
end
end

View File

@@ -0,0 +1,303 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
using Base.Test
srand(101)
debug = false #Turn on for more debugging info
#Pauli σ-matrices
for σ in map(Hermitian, Any[ eye(2), [0 1; 1 0], [0 -im; im 0], [1 0; 0 -1] ])
@test ishermitian(σ)
end
# Hermitian matrix exponential/log
let A1 = randn(4,4) + im*randn(4,4)
A2 = A1 + A1'
@test expm(A2) expm(Hermitian(A2))
@test logm(A2) logm(Hermitian(A2))
A3 = A1 * A1' # posdef
@test expm(A3) expm(Hermitian(A3))
@test logm(A3) logm(Hermitian(A3))
end
let A1 = randn(4,4)
A3 = A1 * A1'
A4 = A1 + A1.'
@test expm(A4) expm(Symmetric(A4))
@test logm(A3) logm(Symmetric(A3))
@test logm(A3) logm(Hermitian(A3))
end
let n=10
areal = randn(n,n)/2
aimg = randn(n,n)/2
debug && println("symmetric eigendecomposition")
for eltya in (Float32, Float64, Complex64, Complex128, BigFloat, Int)
a = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(areal, aimg) : areal)
asym = a'+a # symmetric indefinite
ε = εa = eps(abs(float(one(eltya))))
x = randn(n)
y = randn(n)
b = randn(n,n)/2
x = eltya == Int ? rand(1:7, n) : convert(Vector{eltya}, eltya <: Complex ? complex.(x, zeros(n)) : x)
y = eltya == Int ? rand(1:7, n) : convert(Vector{eltya}, eltya <: Complex ? complex.(y, zeros(n)) : y)
b = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(b, zeros(n,n)) : b)
debug && println("\ntype of a: ", eltya, "\n")
# constructor
@test Symmetric(Symmetric(asym, :U)) === Symmetric(asym, :U)
@test Hermitian(Hermitian(asym, :U)) === Hermitian(asym, :U)
@test Symmetric(Symmetric(asym, :U), :U) === Symmetric(asym, :U)
@test Hermitian(Hermitian(asym, :U), :U) === Hermitian(asym, :U)
@test_throws ArgumentError Symmetric(Symmetric(asym, :U), :L)
@test_throws ArgumentError Hermitian(Hermitian(asym, :U), :L)
# similar
@test isa(similar(Symmetric(asym)), Symmetric{eltya})
@test isa(similar(Hermitian(asym)), Hermitian{eltya})
@test isa(similar(Symmetric(asym), Int), Symmetric{Int})
@test isa(similar(Hermitian(asym), Int), Hermitian{Int})
@test isa(similar(Symmetric(asym), (3,2)), Matrix{eltya})
@test isa(similar(Hermitian(asym), (3,2)), Matrix{eltya})
@test isa(similar(Symmetric(asym), Int, (3,2)), Matrix{Int})
@test isa(similar(Hermitian(asym), Int, (3,2)), Matrix{Int})
# full
@test asym == full(Hermitian(asym))
# parent
@test asym == parent(Hermitian(asym))
# getindex
@test asym[1,1] == Hermitian(asym)[1,1]
@test asym[1,1] == Symmetric(asym)[1,1]
#trace
@test trace(asym) == trace(Hermitian(asym))
# issymmetric, ishermitian
if eltya <: Real
@test issymmetric(Symmetric(asym))
@test ishermitian(Symmetric(asym))
end
if eltya <: Complex
@test ishermitian(Symmetric(b + b'))
end
#transpose, ctranspose
if eltya <: Real
@test transpose(Symmetric(asym)) == asym
else
@test transpose(Hermitian(asym)) == transpose(asym)
end
@test ctranspose(Symmetric(asym)) == Symmetric(conj(asym))
@test ctranspose(Hermitian(asym)) == asym
#tril/triu
for di in -n:n
@test triu(Symmetric(a+a.'),di) == triu(a+a.',di)
@test tril(Symmetric(a+a.'),di) == tril(a+a.',di)
@test triu(Hermitian(asym),di) == triu(asym,di)
@test tril(Hermitian(asym),di) == tril(asym,di)
@test triu(Symmetric(a+a.',:L),di) == triu(a+a.',di)
@test tril(Symmetric(a+a.',:L),di) == tril(a+a.',di)
@test triu(Hermitian(asym,:L),di) == triu(asym,di)
@test tril(Hermitian(asym,:L),di) == tril(asym,di)
end
eltya == BigFloat && continue # Revisit when implemented in julia
d, v = eig(asym)
@test asym*v[:,1] d[1]*v[:,1]
@test v*Diagonal(d)*v' asym
@test isequal(eigvals(asym[1]), eigvals(asym[1:1,1:1]))
@test abs.(eigfact(Hermitian(asym), 1:2)[:vectors]'v[:,1:2]) eye(eltya, 2)
eig(Hermitian(asym), 1:2) # same result, but checks that method works
@test abs.(eigfact(Hermitian(asym), d[1] - 1, (d[2] + d[3])/2)[:vectors]'v[:,1:2]) eye(eltya, 2)
eig(Hermitian(asym), d[1] - 1, (d[2] + d[3])/2) # same result, but checks that method works
@test eigvals(Hermitian(asym), 1:2) d[1:2]
@test eigvals(Hermitian(asym), d[1] - 1, (d[2] + d[3])/2) d[1:2]
@test full(eigfact(asym)) asym
@test eigvecs(Hermitian(asym)) eigvecs(asym)
# relation to svdvals
@test sum(sort(abs.(eigvals(Hermitian(asym))))) == sum(sort(svdvals(Hermitian(asym))))
# cond
@test cond(Hermitian(asym)) cond(asym)
# det
@test det(asym) det(Hermitian(asym, :U))
@test det(asym) det(Hermitian(asym, :L))
if eltya <: Real
@test det(asym) det(Symmetric(asym, :U))
@test det(asym) det(Symmetric(asym, :L))
end
@test det(a + a.') det(Symmetric(a + a.', :U))
@test det(a + a.') det(Symmetric(a + a.', :L))
# isposdef[!]
@test isposdef(Symmetric(asym)) == isposdef(full(Symmetric(asym)))
@test isposdef(Hermitian(asym)) == isposdef(full(Hermitian(asym)))
if eltya != Int
@test isposdef!(Symmetric(copy(asym))) == isposdef(full(Symmetric(asym)))
@test isposdef!(Hermitian(copy(asym))) == isposdef(full(Hermitian(asym)))
end
# rank
let A = a[:,1:5]*a[:,1:5]'
# Make sure A is Hermitian even in the present of rounding error
# xianyi/OpenBLAS#729
A = (A' + A) / 2
@test rank(A) == rank(Hermitian(A))
end
# mat * vec
if eltya <: Complex
@test Hermitian(asym)*x+y asym*x+y
end
if eltya <: Real && eltya != Int
@test Symmetric(asym)*x+y asym*x+y
end
C = zeros(eltya,n,n)
# mat * mat
if eltya <: Complex
@test Hermitian(asym) * a asym * a
@test a * Hermitian(asym) a * asym
@test Hermitian(asym) * Hermitian(asym) asym*asym
@test_throws DimensionMismatch Hermitian(asym) * ones(eltya,n+1)
Base.LinAlg.A_mul_B!(C,a,Hermitian(asym))
@test C a*asym
end
if eltya <: Real && eltya != Int
@test Symmetric(asym) * Symmetric(asym) asym*asym
@test Symmetric(asym) * a asym * a
@test a * Symmetric(asym) a * asym
@test_throws DimensionMismatch Symmetric(asym) * ones(eltya,n+1)
Base.LinAlg.A_mul_B!(C,a,Symmetric(asym))
@test C a*asym
end
# solver
@test Hermitian(asym)\x asym\x
if eltya <: Real
@test Symmetric(asym)\x asym\x
end
#inversion
@test inv(Hermitian(asym)) inv(asym)
if eltya <: Real && eltya != Int
@test inv(Symmetric(asym)) inv(asym)
@test inv(Hermitian(a)) inv(full(Hermitian(a)))
@test inv(Symmetric(a)) inv(full(Symmetric(a)))
end
# conversion
@test Symmetric(asym) == convert(Symmetric,Symmetric(asym))
if eltya <: Real && eltya != Int
typs = [Float16,Float32,Float64]
for typ in typs
@test Symmetric(convert(Matrix{typ},asym)) == convert(Symmetric{typ,Matrix{typ}},Symmetric(asym))
end
end
if eltya <: Complex && eltya != Int
typs = [Complex64,Complex128]
for typ in typs
@test Hermitian(convert(Matrix{typ},asym)) == convert(Hermitian{typ,Matrix{typ}},Hermitian(asym))
end
end
#unsafe_getindex
if eltya <: Real
@test Symmetric(asym)[1:2,1:2] == asym[1:2,1:2]
end
@test Hermitian(asym)[1:2,1:2] == asym[1:2,1:2]
end
end
#Issue #7647: test xsyevr, xheevr, xstevr drivers
for Mi7647 in (Symmetric(diagm(1.0:3.0)),
Hermitian(diagm(1.0:3.0)),
Hermitian(diagm(complex(1.0:3.0))),
SymTridiagonal([1.0:3.0;], zeros(2)))
debug && println("Eigenvalues in interval for $(typeof(Mi7647))")
@test eigmin(Mi7647) == eigvals(Mi7647, 0.5, 1.5)[1] == 1.0
@test eigmax(Mi7647) == eigvals(Mi7647, 2.5, 3.5)[1] == 3.0
@test eigvals(Mi7647) == eigvals(Mi7647, 0.5, 3.5) == [1.0:3.0;]
end
#Issue #7933
let A7933 = [1 2; 3 4]
B7933 = copy(A7933)
C7933 = full(Symmetric(A7933))
@test A7933 == B7933
end
# Issues #8057 and #8058
for f in (eigfact, eigvals, eig)
for A in (Symmetric([0 1; 1 0]), Hermitian([0 im; -im 0]))
@test_throws ArgumentError f(A, 3, 2)
@test_throws ArgumentError f(A, 1:4)
end
end
#Issue 10671
let A = [1.0+im 2.0; 2.0 0.0]
@test !ishermitian(A)
@test_throws ArgumentError Hermitian(A)
end
# Unary minus for Symmetric matrices
let A = Symmetric(randn(5,5))
B = -A
@test A + B zeros(5,5)
end
# 17780
let a = randn(2,2)
a = a'a
b = complex.(a,a)
c = Symmetric(b)
@test conj(c) == conj(Array(c))
cc = copy(c)
@test conj!(c) == conj(Array(cc))
c = Hermitian(b + b')
@test conj(c) == conj(Array(c))
cc = copy(c)
@test conj!(c) == conj(Array(c))
end
# 19225
let X = [1 -1; -1 1]
for T in (Symmetric, Hermitian)
Y = T(copy(X))
_Y = similar(Y)
copy!(_Y, Y)
@test _Y == Y
W = T(copy(X), :L)
copy!(W, Y)
@test W.data == Y.data
@test W.uplo != Y.uplo
W[1,1] = 4
@test W == T([4 -1; -1 1])
@test_throws ArgumentError (W[1,2] = 2)
@test Y + I == T([2 -1; -1 2])
@test Y - I == T([0 -1; -1 0])
@test Y * I == Y
@test Y + 1 == T([2 0; 0 2])
@test Y - 1 == T([0 -2; -2 0])
@test Y * 2 == T([2 -2; -2 2])
@test Y / 1 == Y
@test T([true false; false true]) + true == T([2 1; 1 2])
end
@test_throws ArgumentError Hermitian(X) + 2im*I
@test_throws ArgumentError Hermitian(X) - 2im*I
end

View File

@@ -0,0 +1,513 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
debug = false
using Base.Test
using Base.LinAlg: BlasFloat, errorbounds, full!, naivesub!, transpose!, UnitUpperTriangular, UnitLowerTriangular, A_rdiv_B!, A_rdiv_Bt!, A_rdiv_Bc!
debug && println("Triangular matrices")
n = 9
srand(123)
debug && println("Test basic type functionality")
@test_throws DimensionMismatch LowerTriangular(randn(5, 4))
@test LowerTriangular(randn(3, 3)) |> t -> [size(t, i) for i = 1:3] == [size(full(t), i) for i = 1:3]
# The following test block tries to call all methods in base/linalg/triangular.jl in order for a combination of input element types. Keep the ordering when adding code.
for elty1 in (Float32, Float64, BigFloat, Complex64, Complex128, Complex{BigFloat}, Int)
# Begin loop for first Triangular matrix
for (t1, uplo1) in ((UpperTriangular, :U),
(UnitUpperTriangular, :U),
(LowerTriangular, :L),
(UnitLowerTriangular, :L))
# Construct test matrix
A1 = t1(elty1 == Int ? rand(1:7, n, n) : convert(Matrix{elty1}, (elty1 <: Complex ? complex.(randn(n, n), randn(n, n)) : randn(n, n)) |> t -> chol(t't) |> t -> uplo1 == :U ? t : ctranspose(t)))
debug && println("elty1: $elty1, A1: $t1")
# Convert
@test convert(AbstractMatrix{elty1}, A1) == A1
@test convert(Matrix, A1) == full(A1)
# full!
@test full!(copy(A1)) == full(A1)
# fill!
@test full!(fill!(copy(A1), 1)) == full(t1(ones(size(A1)...)))
# similar
@test isa(similar(A1), t1)
@test eltype(similar(A1)) == elty1
@test isa(similar(A1, Int), t1)
@test eltype(similar(A1, Int)) == Int
@test isa(similar(A1, (3,2)), Matrix{elty1})
@test isa(similar(A1, Int, (3,2)), Matrix{Int})
#copy!
simA1 = similar(A1)
copy!(simA1, A1)
@test simA1 == A1
# getindex
## Linear indexing
for i = 1:length(A1)
@test A1[i] == full(A1)[i]
end
@test isa(A1[2:4,1], Vector)
## Cartesian indexing
for i = 1:size(A1, 1)
for j = 1:size(A1, 2)
@test A1[i,j] == full(A1)[i,j]
end
end
# setindex! (and copy)
A1c = copy(A1)
for i = 1:size(A1, 1)
for j = 1:size(A1, 2)
if uplo1 == :U
if i > j
A1c[i,j] = 0
@test_throws ArgumentError A1c[i,j] = 1
elseif i == j && t1 == UnitUpperTriangular
A1c[i,j] = 1
@test_throws ArgumentError A1c[i,j] = 0
else
A1c[i,j] = 0
@test A1c[i,j] == 0
end
else
if i < j
A1c[i,j] = 0
@test_throws ArgumentError A1c[i,j] = 1
elseif i == j && t1 == UnitLowerTriangular
A1c[i,j] = 1
@test_throws ArgumentError A1c[i,j] = 0
else
A1c[i,j] = 0
@test A1c[i,j] == 0
end
end
end
end
# istril/istriu
if uplo1 == :L
@test istril(A1)
@test !istriu(A1)
else
@test istriu(A1)
@test !istril(A1)
end
#tril/triu
if uplo1 == :L
@test tril(A1,0) == A1
@test tril(A1,-1) == LowerTriangular(tril(full(A1),-1))
@test tril(A1,1) == t1(tril(tril(full(A1),1)))
@test_throws ArgumentError tril!(A1,n+1)
@test triu(A1,0) == t1(diagm(diag(A1)))
@test triu(A1,-1) == t1(tril(triu(A1.data,-1)))
@test triu(A1,1) == LowerTriangular(zeros(A1.data))
@test_throws ArgumentError triu!(A1,n+1)
else
@test triu(A1,0) == A1
@test triu(A1,1) == UpperTriangular(triu(full(A1),1))
@test triu(A1,-1) == t1(triu(triu(full(A1),-1)))
@test_throws ArgumentError triu!(A1,n+1)
@test tril(A1,0) == t1(diagm(diag(A1)))
@test tril(A1,1) == t1(triu(tril(A1.data,1)))
@test tril(A1,-1) == UpperTriangular(zeros(A1.data))
@test_throws ArgumentError tril!(A1,n+1)
end
# factorize
@test factorize(A1) == A1
# [c]transpose[!] (test views as well, see issue #14317)
let vrange = 1:n-1, viewA1 = t1(view(A1.data, vrange, vrange))
# transpose
@test full(A1.') == full(A1).'
@test full(viewA1.') == full(viewA1).'
# ctranspose
@test full(A1') == full(A1)'
@test full(viewA1') == full(viewA1)'
# transpose!
@test transpose!(copy(A1)) == A1.'
@test transpose!(t1(view(copy(A1).data, vrange, vrange))) == viewA1.'
# ctranspose!
@test ctranspose!(copy(A1)) == A1'
@test ctranspose!(t1(view(copy(A1).data, vrange, vrange))) == viewA1'
end
# diag
@test diag(A1) == diag(full(A1))
# real
@test full(real(A1)) == real(full(A1))
@test full(imag(A1)) == imag(full(A1))
@test full(abs.(A1)) == abs.(full(A1))
# Unary operations
@test full(-A1) == -full(A1)
# copy and copy! (test views as well, see issue #14317)
let vrange = 1:n-1, viewA1 = t1(view(A1.data, vrange, vrange))
# copy
@test copy(A1) == copy(full(A1))
@test copy(viewA1) == copy(full(viewA1))
# copy!
B = similar(A1)
copy!(B, A1)
@test B == A1
B = similar(A1.')
copy!(B, A1.')
@test B == A1.'
B = similar(viewA1)
copy!(B, viewA1)
@test B == viewA1
B = similar(viewA1.')
copy!(B, viewA1.')
@test B == viewA1.'
end
#expm/logm
if (elty1 == Float64 || elty1 == Complex128) && (t1 == UpperTriangular || t1 == LowerTriangular)
@test expm(full(logm(A1))) full(A1)
end
# scale
if (t1 == UpperTriangular || t1 == LowerTriangular)
unitt = istriu(A1) ? UnitUpperTriangular : UnitLowerTriangular
if elty1 == Int
cr = 2
else
cr = 0.5
end
ci = cr * im
if elty1 <: Real
A1tmp = copy(A1)
scale!(A1tmp,cr)
@test A1tmp == cr*A1
A1tmp = copy(A1)
scale!(cr,A1tmp)
@test A1tmp == cr*A1
A1tmp = copy(A1)
A2tmp = unitt(A1)
scale!(A1tmp,A2tmp,cr)
@test A1tmp == cr * A2tmp
else
A1tmp = copy(A1)
scale!(A1tmp,ci)
@test A1tmp == ci*A1
A1tmp = copy(A1)
scale!(ci,A1tmp)
@test A1tmp == ci*A1
A1tmp = copy(A1)
A2tmp = unitt(A1)
scale!(A1tmp,A2tmp,ci)
@test A1tmp == ci * A2tmp
end
end
# Binary operations
@test A1*0.5 == full(A1)*0.5
@test 0.5*A1 == 0.5*full(A1)
@test A1/0.5 == full(A1)/0.5
@test 0.5\A1 == 0.5\full(A1)
# inversion
@test inv(A1) inv(lufact(full(A1)))
inv(full(A1)) # issue #11298
@test isa(inv(A1), t1)
# make sure the call to LAPACK works right
if elty1 <: BlasFloat
@test Base.LinAlg.inv!(copy(A1)) inv(lufact(full(A1)))
end
# Determinant
@test det(A1) det(lufact(full(A1))) atol=sqrt(eps(real(float(one(elty1)))))*n*n
@test logdet(A1) logdet(lufact(full(A1))) atol=sqrt(eps(real(float(one(elty1)))))*n*n
lada, ladb = logabsdet(A1)
flada, fladb = logabsdet(lufact(full(A1)))
@test lada flada atol=sqrt(eps(real(float(one(elty1)))))*n*n
@test ladb fladb atol=sqrt(eps(real(float(one(elty1)))))*n*n
# Matrix square root
@test sqrtm(A1) |> t -> t*t A1
# naivesub errors
@test_throws DimensionMismatch naivesub!(A1,ones(elty1,n+1))
# eigenproblems
if !(elty1 in (BigFloat, Complex{BigFloat})) # Not handled yet
vals, vecs = eig(A1)
if (t1 == UpperTriangular || t1 == LowerTriangular) && elty1 != Int # Cannot really handle degenerate eigen space and Int matrices will probably have repeated eigenvalues.
@test vecs*diagm(vals)/vecs full(A1) atol=sqrt(eps(float(real(one(vals[1])))))*(norm(A1,Inf)*n)^2
end
end
# Condition number tests - can be VERY approximate
if elty1 <:BlasFloat
for p in (1.0, Inf)
@test cond(A1,p) cond(A1,p) atol=(cond(A1,p)+cond(A1,p))
end
@test cond(A1,2) == cond(full(A1),2)
end
if !(elty1 in (BigFloat, Complex{BigFloat})) # Not implemented yet
svd(A1)
svdfact(A1)
elty1 <: BlasFloat && svdfact!(copy(A1))
svdvals(A1)
end
# Begin loop for second Triangular matrix
for elty2 in (Float32, Float64, BigFloat, Complex64, Complex128, Complex{BigFloat}, Int)
for (t2, uplo2) in ((UpperTriangular, :U),
(UnitUpperTriangular, :U),
(LowerTriangular, :L),
(UnitLowerTriangular, :L))
debug && println("elty1: $elty1, A1: $t1, elty2: $elty2")
A2 = t2(elty2 == Int ? rand(1:7, n, n) : convert(Matrix{elty2}, (elty2 <: Complex ? complex.(randn(n, n), randn(n, n)) : randn(n, n)) |> t -> chol(t't) |> t -> uplo2 == :U ? t : ctranspose(t)))
# Convert
if elty1 <: Real && !(elty2 <: Integer)
@test convert(AbstractMatrix{elty2}, A1) == t1(convert(Matrix{elty2}, A1.data))
elseif elty2 <: Real && !(elty1 <: Integer)
@test_throws InexactError convert(AbstractMatrix{elty2}, A1) == t1(convert(Matrix{elty2}, A1.data))
end
# Binary operations
@test full(A1 + A2) == full(A1) + full(A2)
@test full(A1 - A2) == full(A1) - full(A2)
# Triangular-Triangualar multiplication and division
@test full(A1*A2) full(A1)*full(A2)
@test full(A1.'A2) full(A1).'full(A2)
@test full(A1'A2) full(A1)'full(A2)
@test full(A1*A2.') full(A1)*full(A2).'
@test full(A1*A2') full(A1)*full(A2)'
@test full(A1.'A2.') full(A1).'full(A2).'
@test full(A1'A2') full(A1)'full(A2)'
@test full(A1/A2) full(A1)/full(A2)
@test full(A1\A2) full(A1)\full(A2)
@test_throws DimensionMismatch eye(n+1)/A2
@test_throws DimensionMismatch eye(n+1)/A2.'
@test_throws DimensionMismatch eye(n+1)/A2'
@test_throws DimensionMismatch eye(n+1)*A2
@test_throws DimensionMismatch eye(n+1)*A2.'
@test_throws DimensionMismatch eye(n+1)*A2'
@test_throws DimensionMismatch A2.'*eye(n+1)
@test_throws DimensionMismatch A2'*eye(n+1)
@test_throws DimensionMismatch A2*eye(n+1)
@test_throws DimensionMismatch A2*ones(n+1) # redundant with immediately preceding test?
end
end
for eltyB in (Float32, Float64, BigFloat, Complex64, Complex128, Complex{BigFloat})
B = convert(Matrix{eltyB}, elty1 <: Complex ? real(A1)*ones(n, n) : A1*ones(n, n))
debug && println("elty1: $elty1, A1: $t1, B: $eltyB")
if !(eltyB in (BigFloat, Complex{BigFloat})) # rand does not support BigFloat and Complex{BigFloat} as of Dec 2015
Tri = Tridiagonal(rand(eltyB,n-1),rand(eltyB,n),rand(eltyB,n-1))
@test Base.LinAlg.A_mul_B!(Tri,copy(A1)) Tri*full(A1)
end
# Triangular-dense Matrix/vector multiplication
@test A1*B[:,1] full(A1)*B[:,1]
@test A1*B full(A1)*B
@test A1.'B[:,1] full(A1).'B[:,1]
@test A1'B[:,1] full(A1)'B[:,1]
@test A1.'B full(A1).'B
@test A1'B full(A1)'B
@test A1*B.' full(A1)*B.'
@test A1*B' full(A1)*B'
@test B*A1 B*full(A1)
@test B[:,1].'A1 B[:,1].'full(A1)
@test B[:,1]'A1 B[:,1]'full(A1)
@test B.'A1 B.'full(A1)
@test B'A1 B'full(A1)
@test B*A1.' B*full(A1).'
@test B*A1' B*full(A1)'
@test B[:,1].'A1.' B[:,1].'full(A1).'
@test B[:,1]'A1' B[:,1]'full(A1)'
@test B.'A1.' B.'full(A1).'
@test B'A1' B'full(A1)'
if eltyB == elty1
@test A_mul_B!(zeros(B),A1,B) A1*B
@test A_mul_Bc!(zeros(B),A1,B) A1*B'
@test A_mul_Bt!(zeros(B),A1,B) A1*B.'
end
#error handling
@test_throws DimensionMismatch Base.LinAlg.A_mul_B!(A1, ones(eltyB,n+1))
@test_throws DimensionMismatch Base.LinAlg.A_mul_B!(ones(eltyB,n+1,n+1), A1)
@test_throws DimensionMismatch Base.LinAlg.At_mul_B!(A1, ones(eltyB,n+1))
@test_throws DimensionMismatch Base.LinAlg.Ac_mul_B!(A1, ones(eltyB,n+1))
@test_throws DimensionMismatch Base.LinAlg.A_mul_Bc!(ones(eltyB,n+1,n+1),A1)
@test_throws DimensionMismatch Base.LinAlg.A_mul_Bt!(ones(eltyB,n+1,n+1),A1)
# ... and division
@test A1\B[:,1] full(A1)\B[:,1]
@test A1\B full(A1)\B
@test A1.'\B[:,1] full(A1).'\B[:,1]
@test A1'\B[:,1] full(A1)'\B[:,1]
@test A1.'\B full(A1).'\B
@test A1'\B full(A1)'\B
@test A1\B.' full(A1)\B.'
@test A1\B' full(A1)\B'
@test A1.'\B.' full(A1).'\B.'
@test A1'\B' full(A1)'\B'
@test_throws DimensionMismatch A1\ones(elty1,n+2)
@test_throws DimensionMismatch A1'\ones(elty1,n+2)
@test_throws DimensionMismatch A1.'\ones(elty1,n+2)
if t1 == UpperTriangular || t1 == LowerTriangular
@test_throws Base.LinAlg.SingularException naivesub!(t1(zeros(elty1,n,n)),ones(eltyB,n))
end
@test B/A1 B/full(A1)
@test B/A1.' B/full(A1).'
@test B/A1' B/full(A1)'
@test B.'/A1 B.'/full(A1)
@test B'/A1 B'/full(A1)
@test B.'/A1.' B.'/full(A1).'
@test B'/A1' B'/full(A1)'
# Error bounds
!(elty1 in (BigFloat, Complex{BigFloat})) && !(eltyB in (BigFloat, Complex{BigFloat})) && errorbounds(A1, A1\B, B)
end
end
end
# Matrix square root
Atn = UpperTriangular([-1 1 2; 0 -2 2; 0 0 -3])
Atp = UpperTriangular([1 1 2; 0 2 2; 0 0 3])
@test sqrtm(Atn) |> t->t*t Atn
@test typeof(sqrtm(Atn)[1,1]) <: Complex
@test sqrtm(Atp) |> t->t*t Atp
@test typeof(sqrtm(Atp)[1,1]) <: Real
Areal = randn(n, n)/2
Aimg = randn(n, n)/2
A2real = randn(n, n)/2
A2img = randn(n, n)/2
for eltya in (Float32, Float64, Complex64, Complex128, BigFloat, Int)
A = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(Areal, Aimg) : Areal)
# a2 = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(a2real, a2img) : a2real)
εa = eps(abs(float(one(eltya))))
for eltyb in (Float32, Float64, Complex64, Complex128)
εb = eps(abs(float(one(eltyb))))
ε = max(εa,εb)
debug && println("\ntype of A: ", eltya, " type of b: ", eltyb, "\n")
debug && println("Solve upper triangular system")
Atri = UpperTriangular(lufact(A)[:U]) |> t -> eltya <: Complex && eltyb <: Real ? real(t) : t # Here the triangular matrix can't be too badly conditioned
b = convert(Matrix{eltyb}, eltya <: Complex ? full(Atri)*ones(n, 2) : full(Atri)*ones(n, 2))
x = full(Atri) \ b
debug && println("Test error estimates")
if eltya != BigFloat && eltyb != BigFloat
for i = 1:2
@test norm(x[:,1] .- 1) <= errorbounds(UpperTriangular(A), x, b)[1][i]
end
end
debug && println("Test forward error [JIN 5705] if this is not a BigFloat")
x = Atri \ b
γ = n*ε/(1 - n*ε)
if eltya != BigFloat
bigA = big.(Atri)
= ones(n, 2)
for i = 1:size(b, 2)
@test norm([:,i] - x[:,i], Inf)/norm([:,i], Inf) <= condskeel(bigA, [:,i])*γ/(1 - condskeel(bigA)*γ)
end
end
debug && println("Test backward error [JIN 5705]")
for i = 1:size(b, 2)
@test norm(abs.(b[:,i] - Atri*x[:,i]), Inf) <= γ * norm(Atri, Inf) * norm(x[:,i], Inf)
end
debug && println("Solve lower triangular system")
Atri = UpperTriangular(lufact(A)[:U]) |> t -> eltya <: Complex && eltyb <: Real ? real(t) : t # Here the triangular matrix can't be too badly conditioned
b = convert(Matrix{eltyb}, eltya <: Complex ? full(Atri)*ones(n, 2) : full(Atri)*ones(n, 2))
x = full(Atri)\b
debug && println("Test error estimates")
if eltya != BigFloat && eltyb != BigFloat
for i = 1:2
@test norm(x[:,1] .- 1) <= errorbounds(UpperTriangular(A), x, b)[1][i]
end
end
debug && println("Test forward error [JIN 5705] if this is not a BigFloat")
b = eltyb == Int ? trunc.(Int,Atri*ones(n, 2)) : convert(Matrix{eltyb}, Atri*ones(eltya, n, 2))
x = Atri \ b
γ = n*ε/(1 - n*ε)
if eltya != BigFloat
bigA = big.(Atri)
= ones(n, 2)
for i = 1:size(b, 2)
@test norm([:,i] - x[:,i], Inf)/norm([:,i], Inf) <= condskeel(bigA, [:,i])*γ/(1 - condskeel(bigA)*γ)
end
end
debug && println("Test backward error [JIN 5705]")
for i = 1:size(b, 2)
@test norm(abs.(b[:,i] - Atri*x[:,i]), Inf) <= γ * norm(Atri, Inf) * norm(x[:,i], Inf)
end
end
end
# Issue 10742 and similar
@test istril(UpperTriangular(diagm([1,2,3,4])))
@test istriu(LowerTriangular(diagm([1,2,3,4])))
@test isdiag(UpperTriangular(diagm([1,2,3,4])))
@test isdiag(LowerTriangular(diagm([1,2,3,4])))
@test !isdiag(UpperTriangular(rand(4, 4)))
@test !isdiag(LowerTriangular(rand(4, 4)))
# Test throwing in fallbacks for non BlasFloat/BlasComplex in A_rdiv_Bx!
let
n = 5
A = rand(Float16, n, n)
B = rand(Float16, n-1, n-1)
@test_throws DimensionMismatch A_rdiv_B!(A, LowerTriangular(B))
@test_throws DimensionMismatch A_rdiv_B!(A, UpperTriangular(B))
@test_throws DimensionMismatch A_rdiv_B!(A, UnitLowerTriangular(B))
@test_throws DimensionMismatch A_rdiv_B!(A, UnitUpperTriangular(B))
@test_throws DimensionMismatch A_rdiv_Bc!(A, LowerTriangular(B))
@test_throws DimensionMismatch A_rdiv_Bc!(A, UpperTriangular(B))
@test_throws DimensionMismatch A_rdiv_Bc!(A, UnitLowerTriangular(B))
@test_throws DimensionMismatch A_rdiv_Bc!(A, UnitUpperTriangular(B))
@test_throws DimensionMismatch A_rdiv_Bt!(A, LowerTriangular(B))
@test_throws DimensionMismatch A_rdiv_Bt!(A, UpperTriangular(B))
@test_throws DimensionMismatch A_rdiv_Bt!(A, UnitLowerTriangular(B))
@test_throws DimensionMismatch A_rdiv_Bt!(A, UnitUpperTriangular(B))
end
# Test that UpperTriangular(LowerTriangular) throws. See #16201
@test_throws ArgumentError LowerTriangular(UpperTriangular(randn(3,3)))
@test_throws ArgumentError UpperTriangular(LowerTriangular(randn(3,3)))
# Issue 16196
@test UpperTriangular(eye(3)) \ view(ones(3), [1,2,3]) == ones(3)
# dimensional correctness:
isdefined(Main, :TestHelpers) || @eval Main include("../TestHelpers.jl")
using TestHelpers.Furlong
let A = UpperTriangular([Furlong(1) Furlong(4); Furlong(0) Furlong(1)])
@test sqrtm(A) == Furlong{1//2}.(UpperTriangular([1 2; 0 1]))
end

View File

@@ -0,0 +1,483 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
debug = false
# basic tridiagonal operations
n = 5
srand(123)
d = 1 .+ rand(n)
dl = -rand(n-1)
du = -rand(n-1)
v = randn(n)
B = randn(n,2)
for elty in (Float32, Float64, Complex64, Complex128, Int)
if elty == Int
srand(61516384)
d = rand(1:100, n)
dl = -rand(0:10, n-1)
du = -rand(0:10, n-1)
v = rand(1:100, n)
B = rand(1:100, n, 2)
else
d = convert(Vector{elty}, d)
dl = convert(Vector{elty}, dl)
du = convert(Vector{elty}, du)
v = convert(Vector{elty}, v)
B = convert(Matrix{elty}, B)
end
ε = eps(abs2(float(one(elty))))
T = Tridiagonal(dl, d, du)
Ts = SymTridiagonal(d, dl)
@test_throws ArgumentError size(Ts,0)
@test size(Ts,3) == 1
@test size(T, 1) == n
@test size(T) == (n, n)
F = diagm(d)
for i = 1:n-1
F[i,i+1] = du[i]
F[i+1,i] = dl[i]
end
@test Array(T) == F
# elementary operations on tridiagonals
@test conj(T) == Tridiagonal(conj(dl), conj(d), conj(du))
@test transpose(T) == Tridiagonal(du, d, dl)
@test ctranspose(T) == Tridiagonal(conj(du), conj(d), conj(dl))
@test abs.(T) == Tridiagonal(abs.(dl),abs.(d),abs.(du))
if elty <: Real
@test round.(T) == Tridiagonal(round.(dl),round.(d),round.(du))
@test isa(round.(T), Tridiagonal)
@test trunc.(T) == Tridiagonal(trunc.(dl),trunc.(d),trunc.(du))
@test isa(trunc.(T), Tridiagonal)
@test floor.(T) == Tridiagonal(floor.(dl),floor.(d),floor.(du))
@test isa(floor.(T), Tridiagonal)
@test ceil.(T) == Tridiagonal(ceil.(dl),ceil.(d),ceil.(du))
@test isa(ceil.(T), Tridiagonal)
end
@test real(T) == Tridiagonal(real(dl),real(d),real(du))
@test imag(T) == Tridiagonal(imag(dl),imag(d),imag(du))
@test abs.(Ts) == SymTridiagonal(abs.(d),abs.(dl))
if elty <: Real
@test round.(Ts) == SymTridiagonal(round.(d),round.(dl))
@test isa(round.(Ts), SymTridiagonal)
@test trunc.(Ts) == SymTridiagonal(trunc.(d),trunc.(dl))
@test isa(trunc.(Ts), SymTridiagonal)
@test floor.(Ts) == SymTridiagonal(floor.(d),floor.(dl))
@test isa(floor.(Ts), SymTridiagonal)
@test ceil.(Ts) == SymTridiagonal(ceil.(d),ceil.(dl))
@test isa(ceil.(Ts), SymTridiagonal)
end
@test real(Ts) == SymTridiagonal(real(d),real(dl))
@test imag(Ts) == SymTridiagonal(imag(d),imag(dl))
# test interconversion of Tridiagonal and SymTridiagonal
@test Tridiagonal(dl, d, dl) == SymTridiagonal(d, dl)
@test SymTridiagonal(d, dl) == Tridiagonal(dl, d, dl)
@test Tridiagonal(dl, d, du) + Tridiagonal(du, d, dl) == SymTridiagonal(2d, dl+du)
@test SymTridiagonal(d, dl) + Tridiagonal(dl, d, du) == Tridiagonal(dl + dl, d+d, dl+du)
@test convert(SymTridiagonal,Tridiagonal(Ts)) == Ts
@test Array(convert(SymTridiagonal{Complex64},Tridiagonal(Ts))) == convert(Matrix{Complex64}, Ts)
if elty == Int
vv = rand(1:100, n)
BB = rand(1:100, n, 2)
else
vv = convert(Vector{elty}, v)
BB = convert(Matrix{elty}, B)
end
let Bs = BB, vs = vv
for atype in ("Array", "SubArray")
if atype == "Array"
BB = Bs
vv = vs
else
BB = view(Bs, 1:n, 1)
vv = view(vs, 1:n)
end
end
# tridiagonal linear algebra
@test T*vv F*vv
invFv = F\vv
@test T\vv invFv
# @test Base.solve(T,v) ≈ invFv
# @test Base.solve(T, B) ≈ F\B
Tlu = factorize(T)
x = Tlu\vv
@test x invFv
end
@test det(T) det(F)
@test T*Base.LinAlg.UnitUpperTriangular(eye(n)) F*eye(n)
@test T*Base.LinAlg.UnitLowerTriangular(eye(n)) F*eye(n)
@test T*UpperTriangular(eye(n)) F*eye(n)
@test T*LowerTriangular(eye(n)) F*eye(n)
# symmetric tridiagonal
if elty <: Real
Ts = SymTridiagonal(d, dl)
Fs = Array(Ts)
Tldlt = factorize(Ts)
@test_throws DimensionMismatch Tldlt\rand(elty,n+1)
@test size(Tldlt) == size(Ts)
if elty <: AbstractFloat
@test typeof(convert(Base.LinAlg.LDLt{Float32},Tldlt)) == Base.LinAlg.LDLt{Float32,SymTridiagonal{elty}}
end
let vs = vv
for atype in ("Array", "SubArray")
if atype == "Array"
vv = vs
else
vv = view(vs, 1:n)
end
end
invFsv = Fs\vv
x = Ts\vv
@test x invFsv
@test Array(AbstractArray(Tldlt)) Fs
end
# similar
@test isa(similar(Ts), SymTridiagonal{elty})
@test isa(similar(Ts, Int), SymTridiagonal{Int})
@test isa(similar(Ts, Int, (3,2)), Matrix{Int})
end
# eigenvalues/eigenvectors of symmetric tridiagonal
if elty === Float32 || elty === Float64
DT, VT = @inferred eig(Ts)
@inferred eig(Ts, 2:4)
@inferred eig(Ts, 1.0, 2.0)
D, Vecs = eig(Fs)
@test DT D
@test abs.(VT'Vecs) eye(elty, n)
@test eigvecs(Ts) == eigvecs(Fs)
#call to LAPACK.stein here
Test.test_approx_eq_modphase(eigvecs(Ts,eigvals(Ts)),eigvecs(Fs))
elseif elty != Int
# check that undef is determined accurately even if type inference
# bails out due to the number of try/catch blocks in this code.
@test_throws UndefVarError Fs
end
# Test det(A::Matrix)
# In the long run, these tests should step through Strang's
# axiomatic definition of determinants.
# If all axioms are satisfied and all the composition rules work,
# all determinants will be correct except for floating point errors.
# The determinant of the identity matrix should always be 1.
for i = 1:10
A = eye(elty, i)
@test det(A) one(elty)
end
# The determinant of a Householder reflection matrix should always be -1.
for i = 1:10
A = eye(elty, 10)
A[i, i] = -one(elty)
@test det(A) -one(elty)
end
# The determinant of a rotation matrix should always be 1.
if elty != Int
for theta = convert(Vector{elty}, pi ./ [1:4;])
R = [cos(theta) -sin(theta);
sin(theta) cos(theta)]
@test convert(elty, det(R)) one(elty)
end
# issue #1490
@test det(ones(elty,3,3)) zero(elty) atol=3*eps(real(one(elty)))
@test det(SymTridiagonal(elty[],elty[])) == one(elty)
#tril/triu
@test_throws ArgumentError tril!(SymTridiagonal(d,dl),n+1)
@test_throws ArgumentError tril!(Tridiagonal(dl,d,du),n+1)
@test tril(SymTridiagonal(d,dl)) == Tridiagonal(dl,d,zeros(dl))
@test tril(SymTridiagonal(d,dl),1) == Tridiagonal(dl,d,dl)
@test tril(SymTridiagonal(d,dl),-1) == Tridiagonal(dl,zeros(d),zeros(dl))
@test tril(SymTridiagonal(d,dl),-2) == Tridiagonal(zeros(dl),zeros(d),zeros(dl))
@test tril(Tridiagonal(dl,d,du)) == Tridiagonal(dl,d,zeros(du))
@test tril(Tridiagonal(dl,d,du),1) == Tridiagonal(dl,d,du)
@test tril(Tridiagonal(dl,d,du),-1) == Tridiagonal(dl,zeros(d),zeros(du))
@test tril(Tridiagonal(dl,d,du),-2) == Tridiagonal(zeros(dl),zeros(d),zeros(du))
@test_throws ArgumentError triu!(SymTridiagonal(d,dl),n+1)
@test_throws ArgumentError triu!(Tridiagonal(dl,d,du),n+1)
@test triu(SymTridiagonal(d,dl)) == Tridiagonal(zeros(dl),d,dl)
@test triu(SymTridiagonal(d,dl),-1) == Tridiagonal(dl,d,dl)
@test triu(SymTridiagonal(d,dl),1) == Tridiagonal(zeros(dl),zeros(d),dl)
@test triu(SymTridiagonal(d,dl),2) == Tridiagonal(zeros(dl),zeros(d),zeros(dl))
@test triu(Tridiagonal(dl,d,du)) == Tridiagonal(zeros(dl),d,du)
@test triu(Tridiagonal(dl,d,du),-1) == Tridiagonal(dl,d,du)
@test triu(Tridiagonal(dl,d,du),1) == Tridiagonal(zeros(dl),zeros(d),du)
@test triu(Tridiagonal(dl,d,du),2) == Tridiagonal(zeros(dl),zeros(d),zeros(du))
@test !istril(SymTridiagonal(d,dl))
@test !istriu(SymTridiagonal(d,dl))
@test istriu(Tridiagonal(zeros(dl),d,du))
@test istril(Tridiagonal(dl,d,zeros(du)))
end
end
#Test equivalence of eigenvectors/singular vectors taking into account possible phase (sign) differences
function test_approx_eq_vecs{S<:Real,T<:Real}(a::StridedVecOrMat{S}, b::StridedVecOrMat{T}, error=nothing)
n = size(a, 1)
@test n==size(b,1) && size(a,2)==size(b,2)
error===nothing && (error=n^3*(eps(S)+eps(T)))
for i=1:n
ev1, ev2 = a[:,i], b[:,i]
deviation = min(abs(norm(ev1-ev2)),abs(norm(ev1+ev2)))
if !isnan(deviation)
@test deviation 0.0 atol=error
end
end
end
let n = 12 #Size of matrix problem to test
srand(123)
debug && println("SymTridiagonal (symmetric tridiagonal) matrices")
for relty in (Float32, Float64), elty in (relty, Complex{relty})
debug && println("elty is $(elty), relty is $(relty)")
a = convert(Vector{elty}, randn(n))
b = convert(Vector{elty}, randn(n-1))
if elty <: Complex
a += im*convert(Vector{elty}, randn(n))
b += im*convert(Vector{elty}, randn(n-1))
end
@test_throws DimensionMismatch SymTridiagonal(a, ones(n+1))
@test_throws ArgumentError SymTridiagonal(rand(n,n))
A = SymTridiagonal(a, b)
fA = map(elty <: Complex ? Complex128 : Float64, Array(A))
debug && println("getindex")
@test_throws BoundsError A[n+1,1]
@test_throws BoundsError A[1,n+1]
@test A[1,n] == convert(elty,0.0)
@test A[1,1] == a[1]
debug && println("setindex!")
@test_throws BoundsError A[n + 1, 1] = 0 # test bounds check
@test_throws BoundsError A[1, n + 1] = 0 # test bounds check
@test ((A[3, 3] = A[3, 3]) == A[3, 3]; A == fA) # test assignment on the main diagonal
@test_throws ArgumentError A[3, 2] = 1 # test assignment on the subdiagonal
@test_throws ArgumentError A[2, 3] = 1 # test assignment on the superdiagonal
@test_throws ArgumentError A[1, 3] = 1 # test assignment off the main/sub/super diagonal
debug && println("Diagonal extraction")
@test diag(A,1) == b
@test diag(A,-1) == b
@test diag(A,0) == a
@test diag(A,n-1) == zeros(elty,1)
@test_throws ArgumentError diag(A,n+1)
debug && println("Idempotent tests")
for func in (conj, transpose, ctranspose)
@test func(func(A)) == A
end
debug && println("Simple unary functions")
for func in (det, inv)
@test func(A) func(fA) atol=n^2*sqrt(eps(relty))
end
debug && println("Rounding to Ints")
if elty <: Real
@test round.(Int,A) == round.(Int,fA)
@test isa(round.(Int,A), SymTridiagonal)
@test trunc.(Int,A) == trunc.(Int,fA)
@test isa(trunc.(Int,A), SymTridiagonal)
@test ceil.(Int,A) == ceil.(Int,fA)
@test isa(ceil.(Int,A), SymTridiagonal)
@test floor.(Int,A) == floor.(Int,fA)
@test isa(floor.(Int,A), SymTridiagonal)
end
debug && println("Tridiagonal/SymTridiagonal mixing ops")
B = convert(Tridiagonal{elty},A)
@test B == A
@test B + A == A + B
@test B - A == A - B
debug && println("Multiplication with strided vector")
@test A*ones(n) Array(A)*ones(n)
debug && println("Multiplication with strided matrix")
@test A*ones(n, 2) Array(A)*ones(n, 2)
debug && println("Eigensystems")
if elty <: Real
zero, infinity = convert(elty, 0), convert(elty, Inf)
debug && println("This tests eigenvalue and eigenvector computations using stebz! and stein!")
w, iblock, isplit = LAPACK.stebz!('V', 'B', -infinity, infinity, 0, 0, zero, a, b)
evecs = LAPACK.stein!(a, b, w)
(e, v) = eig(SymTridiagonal(a, b))
@test e w
test_approx_eq_vecs(v, evecs)
debug && println("stein! call using iblock and isplit")
w, iblock, isplit = LAPACK.stebz!('V', 'B', -infinity, infinity, 0, 0, zero, a, b)
evecs = LAPACK.stein!(a, b, w, iblock, isplit)
test_approx_eq_vecs(v, evecs)
debug && println("stegr! call with index range")
F = eigfact(SymTridiagonal(a, b),1:2)
fF = eigfact(Symmetric(Array(SymTridiagonal(a, b))),1:2)
Test.test_approx_eq_modphase(F[:vectors], fF[:vectors])
@test F[:values] fF[:values]
debug && println("stegr! call with value range")
F = eigfact(SymTridiagonal(a, b),0.0,1.0)
fF = eigfact(Symmetric(Array(SymTridiagonal(a, b))),0.0,1.0)
Test.test_approx_eq_modphase(F[:vectors], fF[:vectors])
@test F[:values] fF[:values]
end
debug && println("Binary operations")
a = convert(Vector{elty}, randn(n))
b = convert(Vector{elty}, randn(n - 1))
if elty <: Complex
a += im*convert(Vector{elty}, randn(n))
b += im*convert(Vector{elty}, randn(n - 1))
end
B = SymTridiagonal(a, b)
fB = map(elty <: Complex ? Complex128 : Float64, Array(B))
for op in (+, -, *)
@test Array(op(A, B)) op(fA, fB)
end
α = rand(elty)
@test Array(α*A) α*Array(A)
@test Array(A*α) Array(A)*α
@test Array(A/α) Array(A)/α
debug && println("A_mul_B!")
@test_throws DimensionMismatch A_mul_B!(zeros(elty,n,n),B,ones(elty,n+1,n))
@test_throws DimensionMismatch A_mul_B!(zeros(elty,n+1,n),B,ones(elty,n,n))
@test_throws DimensionMismatch A_mul_B!(zeros(elty,n,n+1),B,ones(elty,n,n))
end
debug && println("Tridiagonal matrices")
for relty in (Float32, Float64), elty in (relty, Complex{relty})
debug && println("relty is $(relty), elty is $(elty)")
a = convert(Vector{elty}, randn(n - 1))
b = convert(Vector{elty}, randn(n))
c = convert(Vector{elty}, randn(n - 1))
if elty <: Complex
a += im*convert(Vector{elty}, randn(n - 1))
b += im*convert(Vector{elty}, randn(n))
c += im*convert(Vector{elty}, randn(n - 1))
end
@test_throws ArgumentError Tridiagonal(a,a,a)
A = Tridiagonal(a, b, c)
fA = map(elty <: Complex ? Complex128 : Float64, Array(A))
debug && println("Similar, size, and copy!")
B = similar(A)
@test size(B) == size(A)
copy!(B,A)
@test B == A
@test isa(similar(A), Tridiagonal{elty})
@test isa(similar(A, Int), Tridiagonal{Int})
@test isa(similar(A, Int, (3,2)), Matrix{Int})
@test size(A,3) == 1
@test_throws ArgumentError size(A,0)
debug && println("Diagonal extraction")
@test diag(A,-1) == a
@test diag(A,0) == b
@test diag(A,1) == c
@test diag(A,n-1) == zeros(elty,1)
@test_throws ArgumentError diag(A,n+1)
debug && println("Simple unary functions")
for func in (det, inv)
@test func(A) func(fA) atol=n^2*sqrt(eps(relty))
end
debug && println("Rounding to Ints")
if elty <: Real
@test round.(Int,A) == round.(Int,fA)
@test isa(round.(Int,A), Tridiagonal)
@test trunc.(Int,A) == trunc.(Int,fA)
@test isa(trunc.(Int,A), Tridiagonal)
@test ceil.(Int,A) == ceil.(Int,fA)
@test isa(ceil.(Int,A), Tridiagonal)
@test floor.(Int,A) == floor.(Int,fA)
@test isa(floor.(Int,A), Tridiagonal)
end
debug && println("Binary operations")
a = convert(Vector{elty}, randn(n - 1))
b = convert(Vector{elty}, randn(n))
c = convert(Vector{elty}, randn(n - 1))
if elty <: Complex
a += im*convert(Vector{elty}, randn(n - 1))
b += im*convert(Vector{elty}, randn(n))
c += im*convert(Vector{elty}, randn(n - 1))
end
debug && println("Multiplication with strided vector")
@test A*ones(n) Array(A)*ones(n)
debug && println("Multiplication with strided matrix")
@test A*ones(n, 2) Array(A)*ones(n, 2)
B = Tridiagonal(a, b, c)
fB = map(elty <: Complex ? Complex128 : Float64, Array(B))
for op in (+, -, *)
@test Array(op(A, B)) op(fA, fB)
end
α = rand(elty)
@test Array(α*A) α*Array(A)
@test Array(A*α) Array(A)*α
@test Array(A/α) Array(A)/α
@test_throws ArgumentError convert(SymTridiagonal{elty},A)
debug && println("A_mul_B!")
@test_throws DimensionMismatch Base.LinAlg.A_mul_B!(zeros(fA),A,ones(elty,n,n+1))
@test_throws DimensionMismatch Base.LinAlg.A_mul_B!(zeros(fA),A,ones(elty,n+1,n))
debug && println("getindex")
@test_throws BoundsError A[n+1,1]
@test_throws BoundsError A[1,n+1]
debug && println("setindex!")
@test_throws BoundsError A[n + 1, 1] = 0 # test bounds check
@test_throws BoundsError A[1, n + 1] = 0 # test bounds check
@test (A[3, 3] = A[3, 3]; A == fA) # test assignment on the main diagonal
@test (A[3, 2] = A[3, 2]; A == fA) # test assignment on the subdiagonal
@test (A[2, 3] = A[2, 3]; A == fA) # test assignment on the superdiagonal
@test ((A[1, 3] = 0) == 0; A == fA) # test zero assignment off the main/sub/super diagonal
@test_throws ArgumentError A[1, 3] = 1 # test non-zero assignment off the main/sub/super diagonal
end
end
# Issue 12068
SymTridiagonal([1, 2], [0])^3 == [1 0; 0 8]
#test convert for SymTridiagonal
@test convert(SymTridiagonal{Float64},SymTridiagonal(ones(Float32,5),ones(Float32,4))) == SymTridiagonal(ones(Float64,5),ones(Float64,4))
@test convert(AbstractMatrix{Float64},SymTridiagonal(ones(Float32,5),ones(Float32,4))) == SymTridiagonal(ones(Float64,5),ones(Float64,4))
# Test constructors from matrix
@test SymTridiagonal([1 2 3; 2 5 6; 0 6 9]) == [1 2 0; 2 5 6; 0 6 9]
@test Tridiagonal([1 2 3; 4 5 6; 7 8 9]) == [1 2 0; 4 5 6; 0 8 9]
# Test constructors with range and other abstract vectors
@test SymTridiagonal(1:3, 1:2) == [1 1 0; 1 2 2; 0 2 3]
@test Tridiagonal(4:5, 1:3, 1:2) == [1 1 0; 4 2 2; 0 5 3]

View File

@@ -0,0 +1,169 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
using Base.Test
srand(123)
@testset "basic functions" begin
@test I[1,1] == 1 # getindex
@test I[1,2] == 0 # getindex
@test I === I' # transpose
@test ndims(I) == 2
@test one(UniformScaling{Float32}) == UniformScaling(one(Float32))
@test zero(UniformScaling{Float32}) == UniformScaling(zero(Float32))
@test eltype(one(UniformScaling{Float32})) == Float32
@test zero(UniformScaling(rand(Complex128))) == zero(UniformScaling{Complex128})
@test one(UniformScaling(rand(Complex128))) == one(UniformScaling{Complex128})
@test eltype(one(UniformScaling(rand(Complex128)))) == Complex128
@test -one(UniformScaling(2)) == UniformScaling(-1)
@test sparse(3I,4,5) == spdiagm(fill(3,4),0,4,5)
@test sparse(3I,5,4) == spdiagm(fill(3,4),0,5,4)
end
@testset "istriu, istril, issymmetric, ishermitian, isapprox" begin
@test istriu(I)
@test istril(I)
@test issymmetric(I)
@test issymmetric(UniformScaling(complex(1.0,1.0)))
@test ishermitian(I)
@test !ishermitian(UniformScaling(complex(1.0,1.0)))
@test UniformScaling(4.00000000000001) UniformScaling(4.0)
@test UniformScaling(4.32) UniformScaling(4.3) rtol=0.1 atol=0.01
end
@testset "* and / with number" begin
α = randn()
@test α .* UniformScaling(1.0) == UniformScaling(1.0) .* α
@test UniformScaling(α)./α == UniformScaling(1.0)
end
@test copy(UniformScaling(one(Float64))) == UniformScaling(one(Float64))
@test sprint(show,UniformScaling(one(Complex128))) == "UniformScaling{Complex{Float64}}\n(1.0 + 0.0im)*I"
@test sprint(show,UniformScaling(one(Float32))) == "UniformScaling{Float32}\n1.0*I"
λ = complex(randn(),randn())
J = UniformScaling(λ)
@testset "transpose, conj, inv" begin
@test ndims(J) == 2
@test transpose(J) == J
@test J*eye(2) == conj(J'eye(2)) # ctranpose (and A(c)_mul_B)
@test I + I === UniformScaling(2) # +
@test inv(I) == I
@test inv(J) == UniformScaling(inv(λ))
@test cond(I) == 1
@test cond(J) == (λ zero(λ) ? one(real(λ)) : oftype(real(λ), Inf))
end
B = bitrand(2,2)
@test B + I == B + eye(B)
@test I + B == B + eye(B)
@testset "binary ops with matrices" begin
let AA = randn(2, 2)
for SS in (sprandn(3,3, 0.5), speye(Int, 3))
@testset for atype in ("Array", "SubArray")
if atype == "Array"
A = AA
S = SS
else
A = view(AA, 1:2, 1:2)
S = view(SS, 1:3, 1:3)
end
@test @inferred(A + I) == A + eye(A)
@test @inferred(I + A) == A + eye(A)
@test @inferred(I - I) === UniformScaling(0)
@test @inferred(B - I) == B - eye(B)
@test @inferred(I - B) == eye(B) - B
@test @inferred(A - I) == A - eye(A)
@test @inferred(I - A) == eye(A) - A
@test @inferred(I*J) === UniformScaling(λ)
@test @inferred(B*J) == B*λ
@test @inferred(J*B) == B*λ
@test @inferred(I*A) !== A # Don't alias
@test @inferred(I*S) !== S # Don't alias
@test @inferred(A*I) !== A # Don't alias
@test @inferred(S*I) !== S # Don't alias
@test @inferred(S*J) == S*λ
@test @inferred(J*S) == S*λ
@test @inferred(A*J) == A*λ
@test @inferred(J*A) == A*λ
@test @inferred(J*ones(3)) == ones(3)*λ
@test @inferred(λ*J) === UniformScaling(λ*J.λ)
@test @inferred(J*λ) === UniformScaling(λ*J.λ)
@test @inferred(J/I) === J
@test @inferred(I/A) == inv(A)
@test @inferred(A/I) == A
@test @inferred(I/λ) === UniformScaling(1/λ)
@test @inferred(I\J) === J
if atype == "Array"
T = LowerTriangular(randn(3,3))
else
T = LowerTriangular(view(randn(3,3), 1:3, 1:3))
end
@test @inferred(T + J) == full(T) + J
@test @inferred(J + T) == J + full(T)
@test @inferred(T - J) == full(T) - J
@test @inferred(J - T) == J - full(T)
@test @inferred(T\I) == inv(T)
if atype == "Array"
T = LinAlg.UnitLowerTriangular(randn(3,3))
else
T = LinAlg.UnitLowerTriangular(view(randn(3,3), 1:3, 1:3))
end
@test @inferred(T + J) == full(T) + J
@test @inferred(J + T) == J + full(T)
@test @inferred(T - J) == full(T) - J
@test @inferred(J - T) == J - full(T)
@test @inferred(T\I) == inv(T)
if atype == "Array"
T = UpperTriangular(randn(3,3))
else
T = UpperTriangular(view(randn(3,3), 1:3, 1:3))
end
@test @inferred(T + J) == full(T) + J
@test @inferred(J + T) == J + full(T)
@test @inferred(T - J) == full(T) - J
@test @inferred(J - T) == J - full(T)
@test @inferred(T\I) == inv(T)
if atype == "Array"
T = LinAlg.UnitUpperTriangular(randn(3,3))
else
T = LinAlg.UnitUpperTriangular(view(randn(3,3), 1:3, 1:3))
end
@test @inferred(T + J) == full(T) + J
@test @inferred(J + T) == J + full(T)
@test @inferred(T - J) == full(T) - J
@test @inferred(J - T) == J - full(T)
@test @inferred(T\I) == inv(T)
@test @inferred(I\A) == A
@test @inferred(A\I) == inv(A)
@test @inferred(λ\I) === UniformScaling(1/λ)
end
end
end
end
@testset "hcat and vcat" begin
@test_throws ArgumentError hcat(I)
@test_throws ArgumentError [I I]
@test_throws ArgumentError vcat(I)
@test_throws ArgumentError [I; I]
@test_throws ArgumentError [I I; I]
for T in (Matrix, SparseMatrixCSC)
A = T(rand(3,4))
B = T(rand(3,3))
@test (hcat(A,2I))::T == hcat(A,2eye(3,3))
@test (vcat(A,2I))::T == vcat(A,2eye(4,4))
@test (hcat(I,3I,A,2I))::T == hcat(eye(3,3),3eye(3,3),A,2eye(3,3))
@test (vcat(I,3I,A,2I))::T == vcat(eye(4,4),3eye(4,4),A,2eye(4,4))
@test (hvcat((2,1,2),B,2I,I,3I,4I))::T ==
hvcat((2,1,2),B,2eye(3,3),eye(6,6),3eye(3,3),4eye(3,3))
end
end