Skip to content

Commit c66ee94

Browse files
author
maechler
committed
kappa(<singular>, exact=TRUE) |--> Inf "always"
git-svn-id: https://svn.r-project.org/R/trunk@87289 00db46b3-68df-0310-9c12-caf00c1e9a41
1 parent cbb481a commit c66ee94

File tree

4 files changed

+38
-5
lines changed

4 files changed

+38
-5
lines changed

doc/NEWS.Rd

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,15 @@
352352
}
353353
}
354354

355+
\section{\Rlogo CHANGES IN R 4.4.2 patched}{
356+
\subsection{BUG FIXES}{
357+
\itemize{
358+
\item \code{kappa(A, exact=TRUE)} returns \code{Inf} more generally,
359+
fixing \PR{18817} reported by \I{Mikael Jagan}.
360+
}
361+
}
362+
}
363+
355364
\section{\Rlogo CHANGES IN R 4.4.2}{
356365
\subsection{C-LEVEL FACILITIES}{
357366
\itemize{

src/library/base/R/kappa.R

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# File src/library/base/R/kappa.R
22
# Part of the R package, https://www.R-project.org
33
#
4-
# Copyright (C) 1998-2023 The R Core Team
4+
# Copyright (C) 1998-2024 The R Core Team
55
# Copyright (C) 1998 B. D. Ripley
66
#
77
# This program is free software; you can redistribute it and/or modify
@@ -73,8 +73,8 @@ kappa.default <- function(z, exact = FALSE,
7373
nNorm <- is.null(norm)
7474
if(exact) {
7575
if(nNorm || norm == "2") {
76-
s <- svd(z, nu = 0L, nv = 0L)$d
77-
max(s)/min(s[s > 0])
76+
s <- svd(z, nu = 0L, nv = 0L)$d # decreasing, non-negative
77+
if(s[1]) s[1]/s[length(s)] else Inf # when s is all zero
7878
}
7979
else {
8080
if(nNorm) norm <- "1"
@@ -115,8 +115,9 @@ kappa.qr <- function(z, ...)
115115
return(0)
116116
if(exact) {
117117
if(is.null(norm) || identical("2", norm)) { # 2-norm : *not* assuming 'triangular'
118+
## identically to kappa.default(z, exact=TRUE) :
118119
s <- svd(z, nu = 0L, nv = 0L)$d
119-
max(s)/min(s[s > 0]) ## <==> kappa.default(z, exact=TRUE)
120+
if(s[1]) s[1]/s[length(s)] else Inf
120121
}
121122
else norm(z, type=norm) * norm(solve(z), type=norm) # == kappa.default(z, exact=TRUE, norm=norm,..)
122123
}

src/library/base/man/kappa.Rd

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
% File src/library/base/man/kappa.Rd
22
% Part of the R package, https://www.R-project.org
3-
% Copyright 1995-2023 R Core Team
3+
% Copyright 1995-2024 R Core Team
44
% Copyright 2008-2010 The R Foundation
55
% Distributed under GPL 2 or later
66

@@ -203,5 +203,15 @@ iX <- pinv(m79)
203203
kappa(m79, exact=TRUE, norm="1", inv_z = iX)
204204
kappa(m79, exact=TRUE, norm="M", inv_z = iX)
205205
kappa(m79, exact=TRUE, norm="I", inv_z = iX)
206+
207+
## Using a more "accurate" than default inv_z [example by Cleve Moler]:
208+
A <- rbind(c(4.1, 2.8),
209+
c(9.676, 6.608))
210+
kappa(A) # -> Inf
211+
kappa(A, exact=TRUE) # 8.675057e+15 ( 2-norm )
212+
213+
## now for the 1-norm :
214+
try(kappa(A, exact=TRUE, norm = "1")) #-> Error: computationally singular
215+
kappa(A, exact=TRUE, norm = "1", inv_z = solve(A, tol = 1e-19)) ## 5.22057e16
206216
}
207217
\keyword{math}

tests/reg-tests-1e.R

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1540,6 +1540,19 @@ stopifnot(identical(ch1, ch2),
15401540
## error msg was "'length = 2' in coercion to 'logical(1)'"
15411541

15421542

1543+
## kappa(*, exact=TRUE) for exactly singular cases - PR#18817
1544+
for(x in list(x3 = {n <- 3L; x <- diag(n); x[n,n] <- 0; x},
1545+
z2 = rbind(1:2, 0),
1546+
D0 = diag(0, nrow = 3))) { print(x)
1547+
stopifnot(exprs = {
1548+
identical(Inf, kappa(x, exact = TRUE))
1549+
identical(Inf, kappa(x, exact = TRUE, norm = "2"))
1550+
identical(Inf, .kappa_tri(x, exact = TRUE, norm = "2"))
1551+
})
1552+
}
1553+
## kappa(..) returned 1 or {0 with a warning} in R <= 4.4.2
1554+
1555+
15431556

15441557
## keep at end
15451558
rbind(last = proc.time() - .pt,

0 commit comments

Comments
 (0)