File: solvePosDef.Rd

package info (click to toggle)
r-cran-randomfieldsutils 1.2.5-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,956 kB
  • sloc: ansic: 7,119; cpp: 6,437; fortran: 3,403; makefile: 7; sh: 1
file content (131 lines) | stat: -rw-r--r-- 3,710 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
\name{solve}
\alias{solvePosDef}
\alias{solvex}
\alias{solve}
\title{Solve a System of Equations for Positive Definite Matrices}
\description{
  This function solves the equality \eqn{a x = b} for \eqn{x}
  where \eqn{a} is a \bold{positive definite}
  matrix and \eqn{b} is a vector or a
  matrix. It is slightly faster than the inversion by the
  \code{\link[base]{chol}}esky decomposition and clearly faster than
  \code{\link[base]{solve}}.
  It also returns the logarithm of the
  determinant at no additional computational costs.
}

\usage{
solvex(a, b=NULL, logdeterminant=FALSE)
%, sparse=NA, method=-1)
}
\arguments{
  \item{a}{a square real-valued matrix containing the
          coefficients of the linear system.  Logical matrices are
          coerced to numeric.
  }
  \item{b}{
    a numeric or complex vector or matrix giving the right-hand
    side(s) of the linear system.  If missing, \code{b} is taken to be
    an identity matrix and \code{solvex} will return the inverse of
    \code{a}.
  }
  \item{logdeterminant}{logical.
    whether the logarithm of the determinant should also be returned
  }
}
\value{
  If \code{logdeterminant=FALSE} the function returns a vector or a matrix,
  depending on \code{b} which is the solution to the linear equation.
  Else the function returns a list containing both
  the solution to the linear equation and
  the logarithm of the
  determinant of \code{a}.
}
\details{
%  The values of \code{method} could be:
%  \itemize{
%    \item \code{<0} :
If the matrix is diagonal direct calculations are performed.
 
Else if the matrix is sparse the package \pkg{spam} is used.

Else the Cholesky decomposition is tried. Note that with
\code{RFoptions(pivot=  )} pivoting can be enabled. Pivoting is about
30\% slower.

If it fails, the eigen value decomposition is tried.
}

\references{
 % See \link[spam]{chol.spam} of the package \pkg{spam}
 See \code{chol.spam} of the package \pkg{spam}.
}
%\seealso{
%  \link[spam]{chol.spam} in the package \pkg{spam}
%}
\me
\keyword{math}
\examples{
%   library(RandomFieldsUtils)

RFoptions(solve_method = "cholesky", printlevel=1)
set.seed(1)
n <- 1000
x <- 1:n
y <- runif(n)


## FIRST EXAMPLE: full rank matrix
M <- exp(-as.matrix(dist(x) / n)) 
b0 <- matrix(nr=n, runif(n * 5))
b <- M \%*\% b0 + runif(n)

## standard with 'solve'
print(system.time(z <- zR <- solve(M, b)))
print(range(b - M \%*\% z))
stopifnot(all(abs((b - M \%*\% z)) < 2e-11))

## using exactly the algorithm used in R
RFoptions(pivot=PIVOT_NONE, la_mode=LA_R) ## (default)
print(system.time(z <- solvex(M, b)))
print(range(b - M \%*\% z))
stopifnot(all(z == zR))

## Without pivoting, internal code:
RFoptions(pivot=PIVOT_NONE, la_mode=LA_INTERN) ## (default)
print(system.time(z <- solvex(M, b)))
print(range(b - M \%*\% z))
stopifnot(all(abs((b - M \%*\% z)) < 2e-11))

## Pivoting is slower here:
RFoptions(pivot=PIVOT_DO, la_mode=LA_INTERN) 
print(system.time(z <- solvex(M, b)))
print(range(b - M \%*\% z))
stopifnot(all(abs((b - M \%*\% z)) < 2e-11))


## SECOND EXAMPLE: low rank matrix
M <- x \%*\% t(x) + rev(x) \%*\% t(rev(x)) + y \%*\% t(y)
b1 <- M \%*\% b0

## Without pivoting, it does not work
RFoptions(pivot=PIVOT_NONE, la_mode=LA_R)
\dontrun{try(solve(M, b1))}
RFoptions(pivot=PIVOT_NONE, la_mode=LA_INTERN)
\dontrun{try(solvex(M, b1))}

## Pivoting works -- the precision however is reduced :
RFoptions(pivot=PIVOT_DO, la_mode=LA_INTERN) 
print(system.time(z1 <- solvex(M, b1)))
print(range(b1 - M \%*\% z1))
stopifnot(all(abs((b1 - M \%*\% z1)) < 2e-6))

## Pivoting fails, when the equation system is not solvable:
b2 <- M + runif(n)
\dontrun{try(solvex(M, b2))}


RFoptions(pivot = PIVOT_AUTO, la_mode = LA_AUTO)

}