Skip to content

Commit cd966eb

Browse files
committed
combining all of the redundant methods and adding support for block diagonal matrices
1 parent bf04a2a commit cd966eb

File tree

5 files changed

+25
-36
lines changed

5 files changed

+25
-36
lines changed

stdlib/LinearAlgebra/src/bidiag.jl

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -214,16 +214,6 @@ function _opnorm1Inf(B::Bidiagonal, p)
214214
return max(mapreduce(t -> sum(norm, t), max, zip(view(B.dv, (1:length(B.ev)) .+ !case), B.ev)), normdend)
215215
end
216216

217-
function opnorm(B::Bidiagonal, p::Real=2)
218-
if p == 2
219-
return opnorm2(B)
220-
elseif p == 1 || p == Inf
221-
return _opnorm1Inf(B, p)
222-
else
223-
throw(ArgumentError("invalid p-norm p=$p. Valid: 1, 2, Inf"))
224-
end
225-
end
226-
227217
####################
228218
# Generic routines #
229219
####################

stdlib/LinearAlgebra/src/diagonal.jl

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -548,12 +548,11 @@ function svd(D::Diagonal{<:Number})
548548
return SVD(Up, S[piv], copy(Vp'))
549549
end
550550

551-
_opnorm1Inf(A::Diagonal) = maximum(norm(x) for x in A.diag)
551+
_opnorm12Inf(A::Diagonal, p) = maximum(opnorm(x, p) for x in A.diag)
552+
552553
function opnorm(A::Diagonal, p::Real=2)
553-
if p == 2
554-
return opnorm2(A)
555-
elseif p == 1 || p == Inf
556-
return _opnorm1Inf(A)
554+
if p == 1 || p == Inf || p == 2
555+
return _opnorm12Inf(A, p)
557556
else
558557
throw(ArgumentError("invalid p-norm p=$p. Valid: 1, 2, Inf"))
559558
end

stdlib/LinearAlgebra/src/special.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,3 +338,16 @@ end
338338

339339
==(A::Bidiagonal, B::SymTridiagonal) = iszero(B.ev) && iszero(A.ev) && A.dv == B.dv
340340
==(B::SymTridiagonal, A::Bidiagonal) = A == B
341+
342+
# op norm for structured matrices other than diagonal
343+
# the _opnorm1Inf methods are housed in the structured type's respective files
344+
345+
function opnorm(A::Union{Bidiagonal,Tridiagonal,SymTridiagonal}, p::Real=2)
346+
if p == 2
347+
return opnorm2(A)
348+
elseif p == 1 || p == Inf
349+
return _opnorm1Inf(A, p)
350+
else
351+
throw(ArgumentError("invalid p-norm p=$p. Valid: 1, 2, Inf"))
352+
end
353+
end

stdlib/LinearAlgebra/src/tridiag.jl

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -656,19 +656,9 @@ function _opnorm1Inf(A::Tridiagonal, p)
656656
normfirst, normend)
657657
end
658658

659-
function opnorm(A::Tridiagonal, p::Real=2)
660-
if p == 2
661-
return opnorm2(A)
662-
elseif p == 1 || p == Inf
663-
_opnorm1Inf(A, p)
664-
else
665-
throw(ArgumentError("invalid p-norm p=$p. Valid: 1, 2, Inf"))
666-
end
667-
end
668-
669659
# SymTridiagonal
670660

671-
function _opnorm1Inf(A::SymTridiagonal)
661+
function _opnorm1Inf(A::SymTridiagonal, p::Real)
672662
size(A, 1) == 1 && return norm(first(A.dv))
673663
lowerrange, upperrange = 1:length(A.ev)-1, 2:length(A.ev)
674664
normfirst, normend = norm(first(A.dv))+norm(first(A.ev)), norm(last(A.ev))+norm(last(A.dv))
@@ -680,13 +670,3 @@ function _opnorm1Inf(A::SymTridiagonal)
680670
),
681671
normfirst, normend)
682672
end
683-
684-
function opnorm(A::SymTridiagonal, p::Real=2)
685-
if p == 2
686-
return opnorm2(A)
687-
elseif p == 1 || p == Inf # these are the same for symmetric matrices
688-
return _opnorm1Inf(A)
689-
else
690-
throw(ArgumentError("invalid p-norm p=$p. Valid: 1, 2, Inf"))
691-
end
692-
end

stdlib/LinearAlgebra/test/diagonal.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,13 @@ end
511511
@test opnorm(D, 1) == opnorm(Matrix(D), 1)
512512
@test opnorm(D, 2) opnorm(Matrix(D), 2)
513513
@test opnorm(D, Inf) == opnorm(Matrix(D), Inf)
514+
515+
# block diagonal matrices
516+
D = Diagonal([[1 2; 3 4], [5 6; 7 8]])
517+
A = [1 2 0 0; 3 4 0 0; 0 0 5 6; 0 0 7 8] # full matrix of D
518+
@test opnorm(D, 1) == opnorm(A, 1)
519+
@test opnorm(D, 2) == opnorm(A, 2)
520+
@test opnorm(D, Inf) == opnorm(A, Inf)
514521
end
515522

516523
@testset "eigenvalue sorting" begin

0 commit comments

Comments
 (0)