Matrix/ 0000755 0001751 0000144 00000000000 14577245211 011544 5 ustar hornik users Matrix/NAMESPACE 0000644 0001751 0000144 00000024766 14575137654 013013 0 ustar hornik users useDynLib(Matrix, .registration = TRUE)
## ==== IMPORTS ========================================================
## Try to import all of the functions that we need
## (including generic functions for which we define methods),
## but not more ...
importFrom("grDevices", colorRampPalette, grey)
importFrom("graphics", image, par)
importFrom("grid", convertHeight, convertWidth, current.viewport,
gpar, grid.rect)
importFrom("lattice", levelplot, panel.levelplot.raster)
importFrom("methods", .hasSlot, .selectSuperClasses, .slotNames,
Arith, Compare, Complex, Logic, Math, Math2, Ops, Summary,
as, callGeneric, callNextMethod, canCoerce, cbind2, coerce,
extends, getClassDef, getGroupMembers,
is, isClassDef, kronecker, new, rbind2,
setAs, setClass, setClassUnion, setGeneric, setMethod,
setOldClass, show, slot, "slot<-", slotNames, validObject)
importFrom("stats", contr.SAS, contr.helmert, contr.poly, contr.sum,
contr.treatment, "contrasts<-", cov2cor , diffinv, model.frame,
rnorm, runif, symnum, terms, toeplitz, update)
importFrom("utils", capture.output, head, head.matrix, str, tail, tail.matrix)
## ==== EXPORTS ========================================================
## ---- Non-generic functions ------------------------------------------
export(.M2C,
.M2R,
.M2T,
.M2V,
.M2diag,
.M2gen,
.M2kind,
.M2m,
.M2packed,
.M2sym,
.M2tri,
.M2unpacked,
.M2v,
.bdiag,
.dense2sparse,
.diag.dsC,
.diag2dense,
.diag2sparse,
.diagN2U,
.diagU2N,
.ind2dense,
.ind2sparse,
.formatSparseSimple,
.m2V,
.m2dense,
.m2sparse,
.sparse2dense,
.sparseDiagonal,
.symDiagonal,
.trDiagonal,
.solve.dgC.chol,
.solve.dgC.lu,
.solve.dgC.qr,
.tCRT,
.updateCHMfactor,
.validateCsparse,
Diagonal,
Hilbert,
KhatriRao,
Matrix,
Matrix.Version,
MatrixClass,
T2graph,
abIseq,
abIseq1,
aggregateT,
anyDuplicatedT,
asPerm,
asUniqueT,
bandSparse,
bdiag,
## 'c' dispatches on first argument only, so allow direct method calls :
## c.Matrix, # not yet (see below)
c.sparseVector,
colScale,
condest,
det,
diagN2U,
diagU2N,
dimScale,
dmperm,
drop0,
fac2Sparse,
fac2sparse,
formatSpMatrix,
formatSparseM,
graph2T,
invPerm,
invertPerm,
is.null.DN,
isLDL,
isPerm,
isUniqueT,
mat2triplet,
nearPD,
onenormest,
qr2rankMatrix,
qrR,
printSpMatrix,
printSpMatrix2,
rankMatrix,
readHB,
readMM,
rep2abI,
rowScale,
rsparsematrix,
signPerm,
spMatrix,
sparse.model.matrix,
sparseMatrix,
sparseVector)
## Deprecated since Matrix 1.5-4 {Apr 2023}
export(..2dge, .C2nC, .T2Cmat, .asmatrix, .dense2sy,
.diag2mat, .diag2sT, .diag2tT, .dsy2dsp, .dsy2mat, .dxC2mat,
.m2dgC, .m2lgC, .m2ngC, .m2ngCn, .m2ngTn, .n2dgT, .nC2d, .nC2l)
## Defunct since Matrix 1.3-3 {May 2021}
export(cBind, rBind)
## Redundant now but not yet deprecated ...
export(.CR2RC, .CR2T, .SuiteSparse_version, .T2CR, .dense2g, .dense2kind,
.dense2m, .dense2v, .sparse2g, .sparse2kind, .sparse2m, .sparse2v,
.tCR2RC, uniqTsparse)
## ---- S3 generic functions -------------------------------------------
## export() # {probably none ever}
## ---- S3 methods -----------------------------------------------------
## So that dispatch also happens inside of 'base' functions:
S3method(as.matrix, Matrix)
S3method(as.matrix, sparseVector)
S3method(as.array, Matrix)
S3method(as.array, sparseVector)
## Because S4 dispatch is "hard" for c():
## S3method(c, Matrix) # breaks 7 rev. dep. {2023-09-08}
S3method(c, sparseVector)
S3method(c, abIndex)
## For printing return values of our summary() methods:
S3method(print, diagSummary)
S3method(print, sparseSummary)
## ---- S4 generic functions, methods ----------------------------------
export(crossprod, tcrossprod) # *necessary* (once .Primitive in base)
## MJ: why these and not also export(dim, ...) which are also primitive ??
## From 'Matrix' {no need to also export(); see WRE}
exportMethods("%&%",
BunchKaufman,
Cholesky,
Schur,
band,
expand,
expand1,
expand2,
expm,
facmul,
forceSymmetric,
isDiagonal,
isTriangular,
lu,
nnzero,
pack,
skewpart,
symmpart,
tril,
triu,
unpack,
updown,
writeMM)
## From 'base'
exportMethods("!",
"%*%",
"+",
all.equal,
as.array,
as.complex,
as.integer,
as.logical,
as.matrix,
as.numeric,
as.vector,
chol,
chol2inv,
colMeans,
colSums,
crossprod,
determinant,
diag,
"diag<-",
diff,
dim,
"dim<-",
dimnames,
"dimnames<-",
drop,
format,
is.finite,
is.infinite,
is.na,
isSymmetric,
kronecker,
length,
mean,
norm,
print,
qr,
qr.Q,
qr.R,
qr.X,
qr.coef,
qr.fitted,
qr.resid,
qr.qty,
qr.qy,
rcond,
rep,
rowMeans,
rowSums,
solve,
summary,
t,
tcrossprod,
unname,
which,
zapsmall)
## From 'graphics'
exportMethods(image)
## From 'methods'
exportMethods(Arith, Compare, Logic, Math, Math2, Ops, Summary,
cbind2, coerce, rbind2, show)
## From 'stats'
exportMethods(cov2cor, toeplitz, update)
## From 'utils'
exportMethods(head, tail)
## ---- S4 CLASSES -----------------------------------------------------
exportClasses(Matrix, # and its subclasses .............................
generalMatrix,
symmetricMatrix,
triangularMatrix,
diagonalMatrix,
denseMatrix,
unpackedMatrix,
packedMatrix,
sparseMatrix,
CsparseMatrix,
RsparseMatrix,
TsparseMatrix,
nMatrix,
ndenseMatrix,
ngeMatrix,
nsyMatrix,
nspMatrix,
ntrMatrix,
ntpMatrix,
nsparseMatrix,
ngCMatrix,
ngRMatrix,
ngTMatrix,
nsCMatrix,
nsRMatrix,
nsTMatrix,
ntCMatrix,
ntRMatrix,
ntTMatrix,
ndiMatrix,
lMatrix,
ldenseMatrix,
lgeMatrix,
lsyMatrix,
lspMatrix,
ltrMatrix,
ltpMatrix,
lsparseMatrix,
lgCMatrix,
lgRMatrix,
lgTMatrix,
lsCMatrix,
lsRMatrix,
lsTMatrix,
ltCMatrix,
ltRMatrix,
ltTMatrix,
ldiMatrix,
iMatrix,
## idenseMatrix,
## igeMatrix,
## isyMatrix,
## ispMatrix,
## itrMatrix,
## itpMatrix,
## isparseMatrix,
## igCMatrix,
## igRMatrix,
## igTMatrix,
## isCMatrix,
## isRMatrix,
## isTMatrix,
## itCMatrix,
## itRMatrix,
## itTMatrix,
## idiMatrix,
dMatrix,
ddenseMatrix,
dgeMatrix,
dsyMatrix,
dspMatrix,
dpoMatrix,
dppMatrix,
corMatrix,
copMatrix,
dtrMatrix,
dtpMatrix,
dsparseMatrix,
dgCMatrix,
dgRMatrix,
dgTMatrix,
dsCMatrix,
dsRMatrix,
dsTMatrix,
dtCMatrix,
dtRMatrix,
dtTMatrix,
ddiMatrix,
zMatrix,
## zdenseMatrix,
## zgeMatrix,
## zsyMatrix,
## zspMatrix,
## ztrMatrix,
## ztpMatrix,
## zsparseMatrix,
## zgCMatrix,
## zgRMatrix,
## zgTMatrix,
## zsCMatrix,
## zsRMatrix,
## zsTMatrix,
## ztCMatrix,
## ztRMatrix,
## ztTMatrix,
## zdiMatrix,
indMatrix,
pMatrix,
MatrixFactorization, # and its subclasses ................
LU,
denseLU,
sparseLU,
QR,
## denseQR,
sparseQR,
SchurFactorization,
Schur,
BunchKaufmanFactorization,
BunchKaufman,
pBunchKaufman,
CholeskyFactorization,
Cholesky,
pCholesky,
CHMfactor,
CHMsuper,
dCHMsuper,
nCHMsuper, # unused
CHMsimpl,
dCHMsimpl,
nCHMsimpl, # unused
sparseVector, # and its subclasses .......................
nsparseVector,
lsparseVector,
isparseVector,
dsparseVector,
zsparseVector,
## MJ: aim to deprecate and eventually remove these
## (except perhaps 'index')
abIndex,
atomicVector,
compMatrix,
index,
number,
replValue,
rleDiff)
Matrix/.Rinstignore 0000644 0001751 0000144 00000000024 14444344620 014041 0 ustar hornik users ## currently unused
Matrix/LICENCE 0000644 0001751 0000144 00000107537 14561103552 012540 0 ustar hornik users R package Matrix is developed on R-Forge and released on CRAN. It has
two components:
1. The source code of Matrix, excluding external libraries, is contained
primarily in R/*.R, src/*.[ch], man/*.Rd, tests/*.R, vignettes/*.Rnw,
inst/*.R, and inst/include/*. It is licensed under the GNU GPL,
version 3, pasted below. The files were created and are maintained
by Douglas Bates, Martin Maechler, and Mikael Jagan, hence they are:
Copyright (C) 1999-2020 Douglas Bates, Martin Maechler
Copyright (C) 2021-2024 Douglas Bates, Martin Maechler, Mikael Jagan
2. Matrix contains patched versions of external libraries CXSparse,
AMD, COLAMD, CCAMD, CCOLAMD, and CHOLMOD, all from the SuiteSparse
collection of Timothy A. Davis. AMD, COLAMD, CAMD, and CCOLAMD
use the BSD 3-clause licence. CXSparse and CHOLMOD modules Check,
Cholesky, Partition, and Utility use the GNU LGPL licence, version
2.1 or greater. CHOLMOD modules MatrixOps, Modify, and Supernodal
use the GNU GPL licence, version 2 or greater. Compiled into CHOLMOD
is the METIS library, which uses the Apache licence, version 2.0.
Licence files and copyrights are copied under inst/doc/SuiteSparse.
Douglas M. Bates
University of Wisconsin-Madison
bates@stat.wisc.edu
Martin Maechler
ETH Zurich
maechler@stat.math.ethz.ch | maechler@r-project.org
Mikael Jagan
McMaster University
jaganmn@mcmaster.ca
The following is obtained from http://www.gnu.org/licenses/gpl-3.0.txt :
---------------------------------------
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
Matrix/data/ 0000755 0001751 0000144 00000000000 14576343415 012461 5 ustar hornik users Matrix/data/USCounties.R 0000644 0001751 0000144 00000000735 13612521507 014640 0 ustar hornik users stopifnot(requireNamespace("Matrix" , quietly = TRUE)) # includes 'methods'
USCounties <-
local({
load(system.file(file.path("external", "USCounties_slots.rda"),
package = "Matrix"))
## -> 'L'
r <- methods::new("dsCMatrix")
`slot<-` <- methods::`slot<-`
for (n in c("Dim", "i","p","x"))
slot(r, n) <- L[[n]]
r
})
## The reverse:
if(FALSE) {
L <- list()
for (n in c("Dim", "i","p","x")) L[[n]] <- slot(USCounties, n)
}
Matrix/data/datalist 0000644 0001751 0000144 00000000037 13517134750 014203 0 ustar hornik users CAex
KNex
USCounties
wrld_1deg
Matrix/data/KNex.R 0000644 0001751 0000144 00000000575 13612521507 013446 0 ustar hornik users stopifnot(requireNamespace("Matrix" , quietly = TRUE)) # includes 'methods'
KNex <-
local({
load(system.file(file.path("external", "KNex_slots.rda"), package = "Matrix"))
## -> 'L'
r <- list(mm = methods::new("dgCMatrix"), y = L[["y"]])
`slot<-` <- methods::`slot<-`
for (n in c("Dim", "i","p","x")) ## needs methods::slot<-
slot(r$mm, n) <- L[[n]]
r
})
Matrix/data/CAex.R 0000644 0001751 0000144 00000001020 13612521507 013403 0 ustar hornik users stopifnot(requireNamespace("Matrix" , quietly = TRUE)) # includes 'methods'
CAex <-
local({
load(system.file(file.path("external", "CAex_slots.rda"), package = "Matrix"))
## -> 'L'
r <- methods::new("dgCMatrix")
for (n in c("Dim", "i","p","x"))
methods::slot(r, n) <- L[[n]]
r
})
## The reverse { CAex |--> L } is
if(FALSE) {
sNms <- c("Dim", "i", "p", "x")
L <- lapply(sNms, function(N) slot(CAex, N)); names(L) <- sNms
save(L, file = "/u/maechler/R/Pkgs/Matrix/inst/external/CAex_slots.rda")
}
Matrix/data/wrld_1deg.R 0000644 0001751 0000144 00000000673 13612521507 014450 0 ustar hornik users stopifnot(requireNamespace("Matrix" , quietly = TRUE)) # includes 'methods'
wrld_1deg <-
local({
load(system.file(file.path("external", "wrld_1deg_slots.rda"),
package = "Matrix"))
## -> 'L'
r <- methods::new("dsCMatrix")
for (n in c("Dim", "i","p","x"))
methods::slot(r, n) <- L[[n]]
r
})
if(FALSE) {## The reverse:
L <- list()
for (n in c("Dim", "i","p","x")) L[[n]] <- slot(wrld_1deg, n)
}
Matrix/man/ 0000755 0001751 0000144 00000000000 14576343415 012323 5 ustar hornik users Matrix/man/cbind2-methods.Rd 0000644 0001751 0000144 00000006156 14575137654 015431 0 ustar hornik users \name{cbind2-methods}
\title{'cbind()' and 'rbind()' recursively built on cbind2/rbind2}
%
\docType{methods}
\keyword{array}
\keyword{manip}
\keyword{methods}
%
\alias{cbind2}
\alias{cbind2-methods}
\alias{rbind2}
\alias{rbind2-methods}
%
\alias{cbind2,Matrix,Matrix-method}
\alias{cbind2,Matrix,NULL-method}
\alias{cbind2,Matrix,matrix-method}
\alias{cbind2,Matrix,missing-method}
\alias{cbind2,Matrix,vector-method}
\alias{cbind2,NULL,Matrix-method}
\alias{cbind2,matrix,Matrix-method}
\alias{cbind2,vector,Matrix-method}
%
\alias{rbind2,Matrix,Matrix-method}
\alias{rbind2,Matrix,NULL-method}
\alias{rbind2,Matrix,matrix-method}
\alias{rbind2,Matrix,missing-method}
\alias{rbind2,Matrix,vector-method}
\alias{rbind2,NULL,Matrix-method}
\alias{rbind2,matrix,Matrix-method}
\alias{rbind2,vector,Matrix-method}
%
\description{
The base functions \code{\link{cbind}} and \code{\link{rbind}} are
defined for an arbitrary number of arguments and hence have the first
formal argument \code{...}. Now, when S4 objects are found among the arguments,
base \code{cbind()} and \code{rbind()} internally \dQuote{dispatch}
\emph{recursively}, calling \code{\link{cbind2}} or \code{\link{rbind2}}
respectively, where these have methods defined and so should dispatch
appropriately.
\code{\link{cbind2}()} and \code{\link{rbind2}()} are from the
\pkg{methods} package, i.e., standard \R, and have been provided for
binding together \emph{two} matrices, where in \pkg{Matrix}, we have
defined methods for these and the \code{'Matrix'} matrices.
}
\usage{
## cbind(..., deparse.level = 1)
## rbind(..., deparse.level = 1)
\S4method{cbind2}{Matrix,Matrix}(x, y, \dots)
\S4method{rbind2}{Matrix,Matrix}(x, y, \dots)
}
\arguments{
\item{\dots}{for \code{[cr]bind}, vector- or matrix-like \R objects
to be bound together; for \code{[cr]bind2}, further arguments
passed to or from methods; see \code{\link{cbind}} and
\code{\link[methods]{cbind2}}.}
\item{deparse.level}{integer controlling the construction of labels
in the case of non-matrix-like arguments; see \code{\link{cbind}}.}
\item{x, y}{vector- or matrix-like \R objects to be bound together.}
}
\value{
typically a \sQuote{matrix-like} object of a similar
\code{\link{class}} as the first argument in \code{\dots}.
Note that sometimes by default, the result is a
\code{\linkS4class{sparseMatrix}} if one of the arguments is (even in
the case where this is not efficient). In other cases,
the result is chosen to be sparse when there are more zero entries is
than non-zero ones (as the default \code{sparse} in
\code{\link{Matrix}()}).
}
\author{Martin Maechler}
\seealso{\code{\link{cbind}}, \code{\link[methods]{cbind2}}.
Our class definition help pages mentioning \code{cbind2()} and
\code{rbind2()} methods:
\code{"\linkS4class{denseMatrix}"},
\code{"\linkS4class{diagonalMatrix}"},
\code{"\linkS4class{indMatrix}"}.
}
\examples{
(a <- matrix(c(2:1,1:2), 2,2))
(M1 <- cbind(0, rbind(a, 7))) # a traditional matrix
D <- Diagonal(2)
(M2 <- cbind(4, a, D, -1, D, 0)) # a sparse Matrix
stopifnot(validObject(M2), inherits(M2, "sparseMatrix"),
dim(M2) == c(2,9))
}
Matrix/man/printSpMatrix.Rd 0000644 0001751 0000144 00000015353 14561342731 015437 0 ustar hornik users \name{printSpMatrix}
\title{Format and Print Sparse Matrices Flexibly}
%
\keyword{character}
\keyword{print}
\keyword{utilities}
%
\alias{formatSpMatrix}
\alias{printSpMatrix}
\alias{printSpMatrix2}
%
\description{
Format and print sparse matrices flexibly. These are the \dQuote{workhorses} used by
the \code{\link{format}}, \code{\link{show}} and \code{\link{print}}
methods for sparse matrices. If \code{x} is large,
\code{printSpMatrix2(x)} calls \code{printSpMatrix()} twice, namely,
for the first and the last few rows, suppressing those in between, and
also suppresses columns when \code{x} is too wide.
\code{printSpMatrix()} basically prints the result of
\code{formatSpMatrix()}.
}
\usage{
formatSpMatrix(x, digits = NULL, maxp = 1e9,
cld = getClassDef(class(x)), zero.print = ".",
col.names, note.dropping.colnames = TRUE, uniDiag = TRUE,
align = c("fancy", "right"), \dots)
printSpMatrix(x, digits = NULL, maxp = max(100L, getOption("max.print")),
cld = getClassDef(class(x)),
zero.print = ".", col.names, note.dropping.colnames = TRUE,
uniDiag = TRUE, col.trailer = "",
align = c("fancy", "right"), \dots)
printSpMatrix2(x, digits = NULL, maxp = max(100L, getOption("max.print")),
zero.print = ".", col.names, note.dropping.colnames = TRUE,
uniDiag = TRUE, suppRows = NULL, suppCols = NULL,
col.trailer = if(suppCols) "......" else "",
align = c("fancy", "right"),
width = getOption("width"), fitWidth = TRUE, \dots)
}
\arguments{
\item{x}{an \R object inheriting from class \code{\linkS4class{sparseMatrix}}.}
\item{digits}{significant digits to use for printing, see
\code{\link{print.default}}, the default, \code{\link{NULL}},
corresponds to using \code{\link{getOption}("digits")}.}
\item{maxp}{integer, default from \code{\link{options}(max.print)},
influences how many entries of large matrices are printed at all.
Typically should not be smaller than around 1000; values smaller than
100 are silently \dQuote{rounded up} to 100.}% for now
\item{cld}{the class definition of \code{x}; must be equivalent to
\code{\link{getClassDef}(class(x))} and exists mainly for possible
speedup.}
\item{zero.print}{character which should be printed for
\emph{structural} zeroes. The default \code{"."} may occasionally
be replaced by \code{" "} (blank); using \code{"0"} would look
almost like \code{print()}ing of non-sparse matrices.}
\item{col.names}{logical or string specifying if and how column names of
\code{x} should be printed, possibly abbreviated. The default is
taken from \code{\link{options}("sparse.colnames")} if that is set, otherwise
\code{FALSE} unless there are less than ten columns. When
\code{TRUE} the full column names are printed.\cr
When \code{col.names} is a string beginning with \code{"abb"} or
\code{"sub"} and ending with an integer \code{n} (i.e., of the form
\code{"abb... "}),
the column names are \code{\link{abbreviate}()}d or
\code{\link{substring}()}ed to (target) length \code{n}, see the examples.
}
\item{note.dropping.colnames}{logical specifying, when
\code{col.names} is \code{FALSE} if the dropping of the column names
should be noted, \code{TRUE} by default.}
\item{uniDiag}{logical indicating if the diagonal entries of a sparse
unit triangular or unit-diagonal matrix should be formatted as
\code{"I"} instead of \code{"1"} (to emphasize that the 1's are
\dQuote{structural}).}
\item{col.trailer}{a string to be appended to the right of each
column; this is typically made use of by \code{\link{show}()}
only, when suppressing columns.}
\item{suppRows, suppCols}{logicals or \code{NULL}, for
\code{printSpMatrix2()} specifying if rows or columns should be
suppressed in printing. If \code{NULL}, sensible defaults are
determined from \code{\link{dim}(x)} and
\code{\link{options}(c("width", "max.print"))}.
Setting both to \code{FALSE} may be a very bad idea.}
\item{align}{a string specifying how the \code{zero.print} codes
should be aligned, i.e., padded as strings. The default,
\code{"fancy"}, takes some effort to align the typical
\code{zero.print = "."} with the position of \code{0}, i.e., the
first decimal (one left of decimal point) of the numbers printed,
whereas \code{align = "right"} just makes use of
\code{\link{print}(*, right = TRUE)}.}
\item{width}{number, a positive integer, indicating the approximately
desired (line) width of the output, see also \code{fitWidth}.}
\item{fitWidth}{logical indicating if some effort should be made to
match the desired \code{width} or temporarily enlarge that if deemed
necessary.}
\item{\dots}{unused optional arguments.}
}
\details{
\describe{
\item{formatSpMatrix:}{
If \code{x} is large, only the first rows making up the
approximately first \code{maxp} entries is used, otherwise all of \code{x}.
\code{\link{.formatSparseSimple}()} is applied to (a dense version
of) the matrix. Then, \code{\link{formatSparseM}} is used, unless
in trivial cases or for sparse matrices without \code{x} slot.}
}
}
\value{
\item{formatSpMatrix()}{returns a character matrix with possibly empty
column names, depending on \code{col.names} etc, see above.}
\item{printSpMatrix*()}{return \code{x} \emph{invisibly}, see \code{\link{invisible}}.}
}
\author{Martin Maechler}
\seealso{the virtual class \code{\linkS4class{sparseMatrix}} and the
classes extending it; maybe \code{\link{sparseMatrix}} or
\code{\link{spMatrix}} as simple constructors of such matrices.
The underlying utilities \code{\link{formatSparseM}} and
\code{.formatSparseSimple()} (on the same page).
}
\examples{
f1 <- gl(5, 3, labels = LETTERS[1:5])
X <- as(f1, "sparseMatrix")
X ## <==> show(X) <==> print(X)
t(X) ## shows column names, since only 5 columns
X2 <- as(gl(12, 3, labels = paste(LETTERS[1:12],"c",sep=".")),
"sparseMatrix")
X2
## less nice, but possible:
print(X2, col.names = TRUE) # use [,1] [,2] .. => does not fit
## Possibilities with column names printing:
t(X2) # suppressing column names
print(t(X2), col.names=TRUE)
print(t(X2), zero.print = "", col.names="abbr. 1")
print(t(X2), zero.print = "-", col.names="substring 2")
\dontshow{% show() was slow in 0.9975-8 because of slow adjust="fancy"
op <- options(max.print = 25000, width = 80)
sink(print(tempfile()))
M <- Matrix(0, 10000, 100)
M[1,1] <- M[2,3] <- 3.14
st <- system.time(show(M))
sink()
st
if(interactive() || nzchar(Sys.getenv("R_MATRIX_CHECK_EXTRA")))
## valgrind (2023-07-26) gave 10.5 sec!
stopifnot(st[1] < 1.0) # only 0.09 on cmath-3
options(op)
}
}
Matrix/man/externalFormats.Rd 0000644 0001751 0000144 00000007376 14446607050 015777 0 ustar hornik users \name{externalFormats}
\title{Read and write external matrix formats}
%
\docType{methods}
\keyword{connection}
\keyword{file}
\keyword{methods}
\keyword{utilities}
%
\alias{readHB}
\alias{readMM}
%\alias{writeHB}
\alias{writeMM}
%
\alias{writeMM,CsparseMatrix-method}
\alias{writeMM,sparseMatrix-method}
%
\description{
Read matrices stored in the Harwell-Boeing or MatrixMarket formats
or write \code{\linkS4class{sparseMatrix}} objects to one of these
formats.
}
\usage{
readHB(file)
readMM(file)
writeMM(obj, file, \dots)
}
\arguments{
\item{obj}{a real sparse matrix}
\item{file}{for \code{writeMM} - the name of the file to be written.
For \code{readHB} and \code{readMM} the name of the file to read, as
a character scalar. The names of files storing matrices in the
Harwell-Boeing format usually end in \code{".rua"} or \code{".rsa"}.
Those storing matrices in the MatrixMarket format usually end in
\code{".mtx"}.
Alternatively, \code{readHB} and \code{readMM} accept connection objects.}
\item{\dots}{optional additional arguments. Currently none are used in
any methods.}
}
\value{
The \code{readHB} and \code{readMM} functions return an object that
inherits from the \code{"\linkS4class{Matrix}"} class. Methods for the
\code{writeMM} generic functions usually return
\code{\link{NULL}} and, as a side effect, the matrix \code{obj} is
written to \code{file} in the MatrixMarket format (writeMM).
}
\note{
The Harwell-Boeing format is older and less flexible than the
MatrixMarket format. The function \code{writeHB} was deprecated and
has now been removed. Please use \code{writeMM} instead.
Note that these formats do \emph{not} know anything about
\code{\link{dimnames}}, hence these are dropped by \code{writeMM()}.
A very simple way to export small sparse matrices \code{S}, is to use
\code{summary(S)} which returns a \code{\link{data.frame}} with
columns \code{i}, \code{j}, and possibly \code{x}, see \code{summary} in
\code{\link{sparseMatrix-class}}, and an example below.
}
\references{
\url{https://math.nist.gov/MatrixMarket/}
\url{https://sparse.tamu.edu/}% was https://www.cise.ufl.edu/research/sparse/matrices/
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
str(pores <- readMM(system.file("external/pores_1.mtx", package = "Matrix")))
str(utm <- readHB(system.file("external/utm300.rua" , package = "Matrix")))
str(lundA <- readMM(system.file("external/lund_a.mtx" , package = "Matrix")))
str(lundA <- readHB(system.file("external/lund_a.rsa" , package = "Matrix")))
## https://math.nist.gov/MatrixMarket/data/Harwell-Boeing/counterx/counterx.htm
str(jgl <- readMM(system.file("external/jgl009.mtx" , package = "Matrix")))
## NOTE: The following examples take quite some time
## ---- even on a fast internet connection:
if(FALSE) {
## The URL has been corrected, but we need an untar step:
u. <- url("https://www.cise.ufl.edu/research/sparse/RB/Boeing/msc00726.tar.gz")
str(sm <- readHB(gzcon(u.)))
}
data(KNex, package = "Matrix")
## Store as MatrixMarket (".mtx") file, here inside temporary dir./folder:
(MMfile <- file.path(tempdir(), "mmMM.mtx"))
writeMM(KNex$mm, file=MMfile)
file.info(MMfile)[,c("size", "ctime")] # (some confirmation of the file's)
## very simple export - in triplet format - to text file:
data(CAex, package = "Matrix")
s.CA <- summary(CAex)
s.CA # shows (i, j, x) [columns of a data frame]
message("writing to ", outf <- tempfile())
write.table(s.CA, file = outf, row.names=FALSE)
## and read it back -- showing off sparseMatrix():
str(dd <- read.table(outf, header=TRUE))
## has columns (i, j, x) -> we can use via do.call() as arguments to sparseMatrix():
mm <- do.call(sparseMatrix, dd)
stopifnot(all.equal(mm, CAex, tolerance=1e-15))
}
Matrix/man/chol-methods.Rd 0000644 0001751 0000144 00000017667 14575137654 015226 0 ustar hornik users \name{chol-methods}
\title{Compute the Cholesky Factor of a Matrix}
\docType{methods}
%
\keyword{algebra}
\keyword{array}
\keyword{methods}
%
\alias{chol}
\alias{chol-methods}
%
\alias{chol,ddiMatrix-method}
\alias{chol,diagonalMatrix-method}
\alias{chol,dsCMatrix-method}
\alias{chol,dsRMatrix-method}
\alias{chol,dsTMatrix-method}
\alias{chol,dspMatrix-method}
\alias{chol,dsyMatrix-method}
\alias{chol,generalMatrix-method}
\alias{chol,symmetricMatrix-method}
\alias{chol,triangularMatrix-method}
%
\description{
Computes the upper triangular Cholesky factor of an
\eqn{n \times n}{n-by-n} real, symmetric, positive semidefinite
matrix \eqn{A}, optionally after pivoting.
That is the factor \eqn{L'} in
\deqn{P_{1} A P_{1}' = L L'}{P1 * A * P1' = L * L'}
or (equivalently)
\deqn{A = P_{1}' L L' P_{1}}{A = P1' * L * L' * P1}
where
\eqn{P_{1}}{P1} is a permutation matrix.
Methods for \code{\linkS4class{denseMatrix}} are built on
LAPACK routines \code{dpstrf}, \code{dpotrf}, and \code{dpptrf},
The latter two do not permute rows or columns,
so that \eqn{P_{1}}{P1} is an identity matrix.
Methods for \code{\linkS4class{sparseMatrix}} are built on
CHOLMOD routines \code{cholmod_analyze} and \code{cholmod_factorize_p}.
}
\usage{
chol(x, \dots)
\S4method{chol}{dsyMatrix}(x, pivot = FALSE, tol = -1, \dots)
\S4method{chol}{dspMatrix}(x, \dots)
\S4method{chol}{dsCMatrix}(x, pivot = FALSE, \dots)
\S4method{chol}{ddiMatrix}(x, \dots)
\S4method{chol}{generalMatrix}(x, uplo = "U", \dots)
\S4method{chol}{triangularMatrix}(x, uplo = "U", \dots)
}
\arguments{
\item{x}{a \link[=is.finite]{finite}, symmetric, positive
semidefinite matrix or \code{\linkS4class{Matrix}} to
be factorized. If \code{x} is square but not symmetric,
then it will be \emph{treated} as symmetric; see \code{uplo}.
Methods for dense \code{x} require positive definiteness
when \code{pivot = FALSE}.
Methods for sparse (but not diagonal) \code{x} require
positive definiteness unconditionally.}
\item{pivot}{a logical indicating if the rows and columns
of \eqn{x} should be pivoted. Methods for sparse \code{x}
employ the approximate minimum degree (AMD) algorithm
in order to reduce fill-in, i.e., without regard for
numerical stability.}
\item{tol}{a \link[=is.finite]{finite} numeric tolerance,
used only if \code{pivot = TRUE}.
The factorization algorithm stops if the pivot is less than
or equal to \code{tol}. Negative \code{tol} is equivalent
to \code{nrow(x) * .Machine$double.eps * max(diag(x))}.}
\item{uplo}{a string, either \code{"U"} or \code{"L"},
indicating which triangle of \code{x} should be used
to compute the factorization. The default is \code{"U"},
even for lower triangular \code{x}, to be consistent with
\code{\link[base]{chol}} from \pkg{base}.}
\item{\dots}{further arguments passed to or from methods.}
}
\value{
A matrix, \code{\linkS4class{triangularMatrix}},
or \code{\linkS4class{diagonalMatrix}} representing
the upper triangular Cholesky factor \eqn{L'}.
The result is a traditional matrix if \code{x} is a
traditional matrix, dense if \code{x} is dense, and
sparse if \code{x} is sparse.
}
\details{
For \code{x} inheriting from \code{\linkS4class{diagonalMatrix}},
the diagonal result is computed directly and without pivoting,
i.e., bypassing CHOLMOD.
For all other \code{x}, \code{chol(x, pivot = value)} calls
\code{\link{Cholesky}(x, perm = value, \dots)} under the hood.
If you must know the permutation \eqn{P_{1}}{P1} in addition
to the Cholesky factor \eqn{L'}, then call \code{\link{Cholesky}}
directly, as the result of \code{chol(x, pivot = TRUE)} specifies
\eqn{L'} but not \eqn{P_{1}}{P1}.
}
\seealso{
The default method from \pkg{base}, \code{\link[base]{chol}},
called for traditional matrices \code{x}.
Generic function \code{\link{Cholesky}}, for more flexibility
notably when computing the Cholesky \emph{factorization} and
not only the \emph{factor} \eqn{L'}.
}
\references{
The LAPACK source code, including documentation; see
\url{https://netlib.org/lapack/double/dpstrf.f},
\url{https://netlib.org/lapack/double/dpotrf.f}, and
\url{https://netlib.org/lapack/double/dpptrf.f}.
The CHOLMOD source code; see
\url{https://github.com/DrTimothyAldenDavis/SuiteSparse},
notably the header file \file{CHOLMOD/Include/cholmod.h}
defining \code{cholmod_factor_struct}.
Chen, Y., Davis, T. A., Hager, W. W., & Rajamanickam, S. (2008).
Algorithm 887: CHOLMOD, supernodal sparse Cholesky factorization
and update/downdate.
\emph{ACM Transactions on Mathematical Software},
\emph{35}(3), Article 22, 1-14.
\doi{10.1145/1391989.1391995}
Amestoy, P. R., Davis, T. A., & Duff, I. S. (2004).
Algorithm 837: AMD, an approximate minimum degree ordering algorithm.
\emph{ACM Transactions on Mathematical Software},
\emph{17}(4), 886-905.
\doi{10.1145/1024074.1024081}
Golub, G. H., & Van Loan, C. F. (2013).
\emph{Matrix computations} (4th ed.).
Johns Hopkins University Press.
\doi{10.56021/9781421407944}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
}
showMethods("chol", inherited = FALSE)
set.seed(0)
## ---- Dense ----------------------------------------------------------
## chol(x, pivot = value) wrapping Cholesky(x, perm = value)
selectMethod("chol", "dsyMatrix")
## Except in packed cases where pivoting is not yet available
selectMethod("chol", "dspMatrix")
## .... Positive definite ..............................................
(A1 <- new("dsyMatrix", Dim = c(2L, 2L), x = c(1, 2, 2, 5)))
(R1.nopivot <- chol(A1))
(R1 <- chol(A1, pivot = TRUE))
## In 2-by-2 cases, we know that the permutation is 1:2 or 2:1,
## even if in general 'chol' does not say ...
stopifnot(exprs = {
all.equal( A1 , as(crossprod(R1.nopivot), "dsyMatrix"))
all.equal(t(A1[2:1, 2:1]), as(crossprod(R1 ), "dsyMatrix"))
identical(Cholesky(A1)@perm, 2:1) # because 5 > 1
})
## .... Positive semidefinite but not positive definite ................
(A2 <- new("dpoMatrix", Dim = c(2L, 2L), x = c(1, 2, 2, 4)))
try(R2.nopivot <- chol(A2)) # fails as not positive definite
(R2 <- chol(A2, pivot = TRUE)) # returns, with a warning and ...
stopifnot(exprs = {
all.equal(t(A2[2:1, 2:1]), as(crossprod(R2), "dsyMatrix"))
identical(Cholesky(A2)@perm, 2:1) # because 4 > 1
})
## .... Not positive semidefinite ......................................
(A3 <- new("dsyMatrix", Dim = c(2L, 2L), x = c(1, 2, 2, 3)))
try(R3.nopivot <- chol(A3)) # fails as not positive definite
(R3 <- chol(A3, pivot = TRUE)) # returns, with a warning and ...
## _Not_ equal: see details and examples in help("Cholesky")
all.equal(t(A3[2:1, 2:1]), as(crossprod(R3), "dsyMatrix"))
## ---- Sparse ---------------------------------------------------------
## chol(x, pivot = value) wrapping
## Cholesky(x, perm = value, LDL = FALSE, super = FALSE)
selectMethod("chol", "dsCMatrix")
## Except in diagonal cases which are handled "directly"
selectMethod("chol", "ddiMatrix")
(A4 <- toeplitz(as(c(10, 0, 1, 0, 3), "sparseVector")))
(ch.A4.nopivot <- Cholesky(A4, perm = FALSE, LDL = FALSE, super = FALSE))
(ch.A4 <- Cholesky(A4, perm = TRUE, LDL = FALSE, super = FALSE))
(R4.nopivot <- chol(A4))
(R4 <- chol(A4, pivot = TRUE))
det4 <- det(A4)
b4 <- rnorm(5L)
x4 <- solve(A4, b4)
stopifnot(exprs = {
identical(R4.nopivot, expand1(ch.A4.nopivot, "L."))
identical(R4, expand1(ch.A4, "L."))
all.equal(A4, crossprod(R4.nopivot))
all.equal(A4[ch.A4@perm + 1L, ch.A4@perm + 1L], crossprod(R4))
all.equal(diag(R4.nopivot), sqrt(diag(ch.A4.nopivot)))
all.equal(diag(R4), sqrt(diag(ch.A4)))
all.equal(sqrt(det4), det(R4.nopivot))
all.equal(sqrt(det4), det(R4))
all.equal(det4, det(ch.A4.nopivot, sqrt = FALSE))
all.equal(det4, det(ch.A4, sqrt = FALSE))
all.equal(x4, solve(R4.nopivot, solve(t(R4.nopivot), b4)))
all.equal(x4, solve(ch.A4.nopivot, b4))
all.equal(x4, solve(ch.A4, b4))
})
}
Matrix/man/denseLU-class.Rd 0000644 0001751 0000144 00000011551 14575137654 015264 0 ustar hornik users \name{denseLU-class}
\title{Dense LU Factorizations}
%
\docType{class}
\keyword{algebra}
\keyword{array}
\keyword{classes}
%
\alias{denseLU-class}
%
\alias{coerce,denseLU,dgeMatrix-method}
\alias{determinant,denseLU,logical-method}
%
\description{
\code{denseLU} is the class of dense, row-pivoted LU factorizations
of \eqn{m \times n}{m-by-n} real matrices \eqn{A},
having the general form
\deqn{P_{1} A = L U}{P1 * A = L * U}
or (equivalently)
\deqn{A = P_{1}' L U}{A = P1' * L * U}
where
\eqn{P_{1}}{P1} is an \eqn{m \times m}{m-by-m} permutation matrix,
\eqn{L} is an \eqn{m \times \min(m,n)}{m-by-min(m,n)}
unit lower trapezoidal matrix, and
\eqn{U} is a \eqn{\min(m,n) \times n}{min(m,n)-by-n}
upper trapezoidal matrix. If \eqn{m = n}, then the factors
\eqn{L} and \eqn{U} are triangular.
}
\section{Slots}{
\describe{
\item{\code{Dim}, \code{Dimnames}}{inherited from virtual class
\code{\linkS4class{MatrixFactorization}}.}
\item{\code{x}}{a numeric vector of length \code{prod(Dim)} storing
the triangular \eqn{L} and \eqn{U} factors together in a packed
format. The details of the representation are specified by the
manual for LAPACK routine \code{dgetrf}.}
\item{\code{perm}}{an integer vector of length \code{min(Dim)}
specifying the permutation \eqn{P_{1}}{P1} as a product of
transpositions. The corresponding permutation vector can
be obtained as \code{\link{asPerm}(perm)}.}
}
}
\section{Extends}{
Class \code{\linkS4class{LU}}, directly.
Class \code{\linkS4class{MatrixFactorization}}, by class
\code{\linkS4class{LU}}, distance 2.
}
\section{Instantiation}{
Objects can be generated directly by calls of the form
\code{new("denseLU", ...)}, but they are more typically obtained
as the value of \code{\link{lu}(x)} for \code{x} inheriting from
\code{\linkS4class{denseMatrix}} (often \code{\linkS4class{dgeMatrix}}).
}
\section{Methods}{
\describe{
\item{\code{coerce}}{\code{signature(from = "denseLU", to = "dgeMatrix")}:
returns a \code{\linkS4class{dgeMatrix}} with the dimensions
of the factorized matrix \eqn{A}, equal to \eqn{L} below the
diagonal and equal to \eqn{U} on and above the diagonal.}
\item{\code{determinant}}{\code{signature(from = "denseLU", logarithm = "logical")}:
computes the determinant of the factorized matrix \eqn{A}
or its logarithm.}
\item{\code{expand}}{\code{signature(x = "denseLU")}:
see \code{\link{expand-methods}}.}
\item{\code{expand1}}{\code{signature(x = "denseLU")}:
see \code{\link{expand1-methods}}.}
\item{\code{expand2}}{\code{signature(x = "denseLU")}:
see \code{\link{expand2-methods}}.}
\item{\code{solve}}{\code{signature(a = "denseLU", b = "missing")}:
see \code{\link{solve-methods}}.}
}
}
\seealso{
Class \code{\linkS4class{sparseLU}} for sparse LU factorizations.
Class \code{\linkS4class{dgeMatrix}}.
Generic functions \code{\link{lu}},
\code{\link{expand1}} and \code{\link{expand2}}.
}
\references{
The LAPACK source code, including documentation; see
\url{https://netlib.org/lapack/double/dgetrf.f}.
Golub, G. H., & Van Loan, C. F. (2013).
\emph{Matrix computations} (4th ed.).
Johns Hopkins University Press.
\doi{10.56021/9781421407944}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
library(utils, pos = "package:base", verbose = FALSE)
}
showClass("denseLU")
set.seed(1)
n <- 3L
(A <- Matrix(round(rnorm(n * n), 2L), n, n))
## With dimnames, to see that they are propagated :
dimnames(A) <- dn <- list(paste0("r", seq_len(n)),
paste0("c", seq_len(n)))
(lu.A <- lu(A))
str(e.lu.A <- expand2(lu.A), max.level = 2L)
## Underlying LAPACK representation
(m.lu.A <- as(lu.A, "dgeMatrix")) # which is L and U interlaced
stopifnot(identical(as(m.lu.A, "matrix"), `dim<-`(lu.A@x, lu.A@Dim)))
ae1 <- function(a, b, ...) all.equal(as(a, "matrix"), as(b, "matrix"), ...)
ae2 <- function(a, b, ...) ae1(unname(a), unname(b), ...)
## A ~ P1' L U in floating point
stopifnot(exprs = {
identical(names(e.lu.A), c("P1.", "L", "U"))
identical(e.lu.A[["P1."]],
new( "pMatrix", Dim = c(n, n), Dimnames = c(dn[1L], list(NULL)),
margin = 1L, perm = invertPerm(asPerm(lu.A@perm))))
identical(e.lu.A[["L"]],
new("dtrMatrix", Dim = c(n, n), Dimnames = list(NULL, NULL),
uplo = "L", diag = "U", x = lu.A@x))
identical(e.lu.A[["U"]],
new("dtrMatrix", Dim = c(n, n), Dimnames = c(list(NULL), dn[2L]),
uplo = "U", diag = "N", x = lu.A@x))
ae1(A, with(e.lu.A, P1. \%*\% L \%*\% U))
ae2(A[asPerm(lu.A@perm), ], with(e.lu.A, L \%*\% U))
})
## Factorization handled as factorized matrix
b <- rnorm(n)
stopifnot(identical(det(A), det(lu.A)),
identical(solve(A, b), solve(lu.A, b)))
}
Matrix/man/all.equal-methods.Rd 0000644 0001751 0000144 00000003327 14467060443 016132 0 ustar hornik users \name{all.equal-methods}
\title{Matrix Package Methods for Function all.equal()}
%
\docType{methods}
\keyword{arith}
\keyword{logic}
\keyword{methods}
\keyword{programming}
%
\alias{all.equal}
\alias{all.equal-methods}
%
\alias{all.equal,Matrix,Matrix-method}
\alias{all.equal,Matrix,sparseVector-method}
\alias{all.equal,Matrix,vector-method}
\alias{all.equal,abIndex,abIndex-method}
\alias{all.equal,abIndex,numLike-method}
\alias{all.equal,numLike,abIndex-method}
\alias{all.equal,sparseVector,Matrix-method}
\alias{all.equal,sparseVector,sparseVector-method}
\alias{all.equal,sparseVector,vector-method}
\alias{all.equal,vector,Matrix-method}
\alias{all.equal,vector,sparseVector-method}
%
\description{
Methods for function \code{\link{all.equal}()} (from \R package
\pkg{base}) are defined for all \code{\linkS4class{Matrix}} classes.
}
\section{Methods}{
\describe{
\item{target = "Matrix", current = "Matrix"}{\ }
\item{target = "ANY", current = "Matrix"}{\ }
\item{target = "Matrix", current = "ANY"}{these three methods are
simply using \code{\link{all.equal.numeric}} directly and work via
\code{\link{as.vector}()}.}
}
There are more methods, notably also for
\code{"\linkS4class{sparseVector}"}'s, see \code{showMethods("all.equal")}.
}
\examples{
showMethods("all.equal")
(A <- spMatrix(3,3, i= c(1:3,2:1), j=c(3:1,1:2), x = 1:5))
ex <- expand(lu. <- lu(A))
stopifnot( all.equal(as(A[lu.@p + 1L, lu.@q + 1L], "CsparseMatrix"),
lu.@L \%*\% lu.@U),
with(ex, all.equal(as(P \%*\% A \%*\% t(Q), "CsparseMatrix"),
L \%*\% U)),
with(ex, all.equal(as(A, "CsparseMatrix"),
t(P) \%*\% L \%*\% U \%*\% Q)))
}
Matrix/man/Matrix-class.Rd 0000644 0001751 0000144 00000020216 14574054462 015161 0 ustar hornik users \name{Matrix-class}
\title{Virtual Class "Matrix" of Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{Matrix-class}
%
\alias{!,Matrix-method}
\alias{&,Matrix,ddiMatrix-method}
\alias{&,Matrix,ldiMatrix-method}
\alias{&,Matrix,ndiMatrix-method}
\alias{*,Matrix,ddiMatrix-method}
\alias{*,Matrix,ldiMatrix-method}
\alias{*,Matrix,ndiMatrix-method}
\alias{+,Matrix,missing-method}
\alias{-,Matrix,missing-method}
\alias{Arith,Matrix,Matrix-method}
\alias{Arith,Matrix,lsparseMatrix-method}
\alias{Arith,Matrix,nsparseMatrix-method}
\alias{Logic,ANY,Matrix-method}
\alias{Logic,Matrix,ANY-method}
\alias{Logic,Matrix,nMatrix-method}
\alias{Math2,Matrix-method}
\alias{Ops,ANY,Matrix-method}
\alias{Ops,Matrix,ANY-method}
\alias{Ops,Matrix,NULL-method}
\alias{Ops,Matrix,ddiMatrix-method}
\alias{Ops,Matrix,ldiMatrix-method}
\alias{Ops,Matrix,matrix-method}
\alias{Ops,Matrix,sparseVector-method}
\alias{Ops,NULL,Matrix-method}
\alias{Ops,matrix,Matrix-method}
\alias{^,Matrix,ddiMatrix-method}
\alias{^,Matrix,ldiMatrix-method}
\alias{^,Matrix,ndiMatrix-method}
\alias{as.array,Matrix-method}
\alias{as.complex,Matrix-method}
\alias{as.integer,Matrix-method}
\alias{as.logical,Matrix-method}
\alias{as.matrix,Matrix-method}
\alias{as.numeric,Matrix-method}
\alias{as.vector,Matrix-method}
\alias{coerce,ANY,Matrix-method}
\alias{coerce,Matrix,CsparseMatrix-method}
\alias{coerce,Matrix,RsparseMatrix-method}
\alias{coerce,Matrix,TsparseMatrix-method}
\alias{coerce,Matrix,copMatrix-method}
\alias{coerce,Matrix,corMatrix-method}
\alias{coerce,Matrix,dMatrix-method}
\alias{coerce,Matrix,ddenseMatrix-method}
\alias{coerce,Matrix,denseMatrix-method}
\alias{coerce,Matrix,diagonalMatrix-method}
\alias{coerce,Matrix,dpoMatrix-method}
\alias{coerce,Matrix,dppMatrix-method}
\alias{coerce,Matrix,dsparseMatrix-method}
\alias{coerce,Matrix,generalMatrix-method}
\alias{coerce,Matrix,indMatrix-method}
\alias{coerce,Matrix,lMatrix-method}
\alias{coerce,Matrix,ldenseMatrix-method}
\alias{coerce,Matrix,lsparseMatrix-method}
\alias{coerce,Matrix,matrix-method}
\alias{coerce,Matrix,nMatrix-method}
\alias{coerce,Matrix,ndenseMatrix-method}
\alias{coerce,Matrix,nsparseMatrix-method}
\alias{coerce,Matrix,pMatrix-method}
\alias{coerce,Matrix,packedMatrix-method}
\alias{coerce,Matrix,sparseMatrix-method}
\alias{coerce,Matrix,sparseVector-method}
\alias{coerce,Matrix,symmetricMatrix-method}
\alias{coerce,Matrix,triangularMatrix-method}
\alias{coerce,Matrix,unpackedMatrix-method}
\alias{coerce,matrix,Matrix-method}
\alias{coerce,vector,Matrix-method}
\alias{determinant,Matrix,missing-method}
\alias{determinant,Matrix,logical-method}
\alias{dim,Matrix-method}
\alias{dimnames,Matrix-method}
\alias{dimnames<-,Matrix,NULL-method}
\alias{dimnames<-,Matrix,list-method}
\alias{drop,Matrix-method}
\alias{head,Matrix-method}
\alias{initialize,Matrix-method}
\alias{length,Matrix-method}
\alias{tail,Matrix-method}
\alias{unname,Matrix-method}
\alias{zapsmall,Matrix-method}
%
\alias{c.Matrix}
%
\alias{Matrix.Version} % FIXME: belongs in non-existent Matrix-package.Rd
\alias{det} % FIXME: ditto
%
\description{
The \code{Matrix} class is a class contained by all actual
classes in the \pkg{Matrix} package. It is a \dQuote{virtual} class.
}
\section{Slots}{
\describe{
\item{\code{Dim}}{an integer vector of length 2 giving the
dimensions of the matrix.}
\item{\code{Dimnames}}{a list of length 2. Each element must
be \code{NULL} or a character vector of length equal to the
corresponding element of \code{Dim}.}
}
}
\section{Methods}{
\describe{
\item{determinant}{\code{signature(x = "Matrix", logarithm = "missing")}: and}
\item{determinant}{\code{signature(x = "Matrix", logarithm = "logical")}:
compute the (\eqn{\log}) determinant of \code{x}. The method
chosen depends on the actual Matrix class of \code{x}. Note that
\code{\link[base]{det}} also works for all our matrices, calling the
appropriate \code{determinant()} method. The \code{Matrix::det}
is an exact copy of \code{base::det}, but in the correct
namespace, and hence calling the S4-aware version of
\code{determinant()}.).}
\item{diff}{\code{signature(x = "Matrix")}: As \code{\link{diff}()}
for traditional matrices, i.e., applying \code{diff()} to each
column.}
\item{dim}{\code{signature(x = "Matrix")}: extract matrix dimensions
\code{\link{dim}}.}
\item{dim<-}{\code{signature(x = "Matrix", value = "ANY")}: where
\code{value} is integer of length 2. Allows to \emph{reshape}
Matrix objects, but only when \code{prod(value) == prod(dim(x))}.}
\item{dimnames}{\code{signature(x = "Matrix")}: extract
\code{\link{dimnames}}.}
\item{dimnames<-}{\code{signature(x = "Matrix", value = "list")}: set
the \code{dimnames} to a \code{\link{list}} of length 2, see
\code{\link{dimnames<-}}.}
\item{length}{\code{signature(x = "Matrix")}: simply defined as
\code{prod(dim(x))} (and hence of mode \code{"double"}).}
\item{show}{\code{signature(object = "Matrix")}: \code{\link{show}}
method for \code{\link{print}}ing. For printing \emph{sparse}
matrices, see \code{\link{printSpMatrix}}.}
\item{zapsmall}{\code{signature(x = "Matrix")}: typically used for
\code{"\linkS4class{dMatrix}"}: \code{\link{round}()} matrix entries
such that (relatively) very small entries become zero exactly.}
\item{image}{\code{signature(object = "Matrix")}: draws an
\code{\link{image}} of the matrix entries, using
\code{\link[lattice]{levelplot}()} from package \pkg{lattice}.}
\item{head}{\code{signature(object = "Matrix")}: return only the
\emph{\dQuote{head}}, i.e., the first few rows.}
\item{tail}{\code{signature(object = "Matrix")}: return only the
\emph{\dQuote{tail}}, i.e., the last few rows of the respective matrix.}
\cr %------------------------------------
\item{as.matrix, as.array}{\code{signature(x = "Matrix")}: the same as
\code{as(x, "matrix")}; see also the note below.}
\item{as.vector}{\code{signature(x = "Matrix", mode = "missing")}:
\code{as.vector(m)} should be identical to \code{as.vector(as(m,
"matrix"))}, implemented more efficiently for some subclasses.}
\item{as(x, "vector"), as(x, "numeric")}{etc, similarly.}
\item{coerce}{\code{signature(from = "ANY", to = "Matrix")}: This
relies on a correct \code{\link{as.matrix}()} method for \code{from}.}
}
There are many more methods that (conceptually should) work for all
\code{"Matrix"} objects, e.g., \code{\link{colSums}},
\code{\link{rowMeans}}. Even \pkg{base} functions may work
automagically (if they first call \code{\link{as.matrix}()} on their
principal argument), e.g., \code{\link{apply}}, \code{\link{eigen}},
\code{\link{svd}} or \code{\link{kappa}} all do work via coercion to a
\dQuote{traditional} (dense) \code{\link{matrix}}.
%% --> ../tests/base-matrix-fun.R
}
\note{
Loading the \code{Matrix} namespace \dQuote{overloads}
\code{\link{as.matrix}} and \code{\link{as.array}} in the \pkg{base}
namespace by the equivalent of \code{function(x) as(x, "matrix")}.
Consequently, \code{as.matrix(m)} or \code{as.array(m)} will properly
work when \code{m} inherits from the \code{"Matrix"} class ---
\emph{also} for functions in package \pkg{base} and other packages.
E.g., \code{\link{apply}} or \code{\link{outer}} can therefore be applied
to \code{"Matrix"} matrices.
}
\author{Douglas Bates \email{bates@stat.wisc.edu} and Martin Maechler}
\seealso{
the classes \code{\linkS4class{dgeMatrix}},
\code{\linkS4class{dgCMatrix}}, and function
\code{\link{Matrix}} for construction (and examples).
Methods, e.g., for \code{\link[=kronecker-methods]{kronecker}}.
}
\examples{
slotNames("Matrix")
cl <- getClass("Matrix")
names(cl@subclasses) # more than 40 ..
showClass("Matrix")#> output with slots and all subclasses
(M <- Matrix(c(0,1,0,0), 6, 4))
dim(M)
diag(M)
cm <- M[1:4,] + 10*Diagonal(4)
diff(M)
## can reshape it even :
dim(M) <- c(2, 12)
M
stopifnot(identical(M, Matrix(c(0,1,0,0), 2,12)),
all.equal(det(cm),
determinant(as(cm,"matrix"), log=FALSE)$modulus,
check.attributes=FALSE))
}
Matrix/man/lsyMatrix-class.Rd 0000644 0001751 0000144 00000004001 14467516513 015704 0 ustar hornik users \name{lsyMatrix-class}
\title{Symmetric Dense Logical Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{lsyMatrix-class}
\alias{lspMatrix-class}
%
\description{
The \code{"lsyMatrix"} class is the class of symmetric, dense logical
matrices in non-packed storage and \code{"lspMatrix"} is the class of
of these in packed storage. In the packed form, only the upper
triangle or the lower triangle is stored.
}
\section{Objects from the Class}{
Objects can be created by calls of the form \code{new("lsyMatrix", ...)}.
}
\section{Slots}{
\describe{
\item{\code{uplo}:}{Object of class \code{"character"}. Must be
either "U", for upper triangular, and "L", for lower triangular.}
\item{\code{x}:}{Object of class \code{"logical"}. The logical
values that constitute the matrix, stored in column-major order.}
\item{\code{Dim},\code{Dimnames}:}{The dimension (a length-2
\code{"integer"}) and corresponding names (or \code{NULL}), see the
\code{\linkS4class{Matrix}} class.}
\item{\code{factors}:}{Object of class \code{"list"}. A named
list of factorizations that have been computed for the matrix.}
}
}
\section{Extends}{
Both extend classes \code{"\linkS4class{ldenseMatrix}"} and
\code{"\linkS4class{symmetricMatrix}"}, directly; further, class
\code{"Matrix"} and others, \emph{in}directly. Use
\code{\link{showClass}("lsyMatrix")}, e.g., for details.
}
\section{Methods}{
Currently, mainly \code{\link{t}()} and coercion methods (for
\code{\link{as}(.)}; use, e.g.,
\code{\link{showMethods}(class="lsyMatrix")} for details.
}
%\references{}
%\author{}
\seealso{
\code{\linkS4class{lgeMatrix}}, \code{\linkS4class{Matrix}},
\code{\link[base]{t}}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
(M2 <- Matrix(c(TRUE, NA, FALSE, FALSE), 2, 2)) # logical dense (ltr)
str(M2)
# can
(sM <- M2 | t(M2)) # "lge"
as(sM, "symmetricMatrix")
str(sM <- as(sM, "packedMatrix")) # packed symmetric
}
Matrix/man/Hilbert.Rd 0000644 0001751 0000144 00000001100 14422605232 014157 0 ustar hornik users \name{Hilbert}
\title{Generate a Hilbert matrix}
%
\keyword{array}
\keyword{utilities}
%
\alias{Hilbert}
%
\description{
Generate the \code{n} by \code{n} symmetric Hilbert matrix. Because
these matrices are ill-conditioned for moderate to large \code{n},
they are often used for testing numerical linear algebra code.
}
\usage{
Hilbert(n)
}
\arguments{
\item{n}{a non-negative integer.}
}
\value{
the \code{n} by \code{n} symmetric Hilbert matrix as a
\code{"dpoMatrix"} object.
}
\seealso{the class \code{\linkS4class{dpoMatrix}}}
\examples{
Hilbert(6)
}
Matrix/man/ldenseMatrix-class.Rd 0000644 0001751 0000144 00000003463 14500644730 016351 0 ustar hornik users \name{ldenseMatrix-class}
\title{Virtual Class "ldenseMatrix" of Dense Logical Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{ldenseMatrix-class}
%
\alias{!,ldenseMatrix-method}
\alias{&,ldenseMatrix,ddiMatrix-method}
\alias{&,ldenseMatrix,ldiMatrix-method}
\alias{&,ldenseMatrix,ndiMatrix-method}
\alias{*,ldenseMatrix,ddiMatrix-method}
\alias{*,ldenseMatrix,ldiMatrix-method}
\alias{*,ldenseMatrix,ndiMatrix-method}
\alias{Logic,ldenseMatrix,lsparseMatrix-method}
\alias{Ops,ldenseMatrix,ldenseMatrix-method}
\alias{^,ldenseMatrix,ddiMatrix-method}
\alias{^,ldenseMatrix,ldiMatrix-method}
\alias{^,ldenseMatrix,ndiMatrix-method}
\alias{coerce,matrix,ldenseMatrix-method}
\alias{coerce,vector,ldenseMatrix-method}
\alias{which,ldenseMatrix-method}
%
\description{
\code{ldenseMatrix} is the virtual class of all dense \bold{l}ogical
(S4) matrices. It extends both \code{\linkS4class{denseMatrix}}
and \code{\linkS4class{lMatrix}} directly.
}
\section{Slots}{
\describe{
\item{\code{x}:}{logical vector containing the entries of the matrix.}
\item{\code{Dim}, \code{Dimnames}:}{see \code{\linkS4class{Matrix}}.}
}
}
\section{Extends}{
Class \code{"lMatrix"}, directly.
Class \code{"denseMatrix"}, directly.
Class \code{"Matrix"}, by class \code{"lMatrix"}.
Class \code{"Matrix"}, by class \code{"denseMatrix"}.
}
\section{Methods}{
\describe{
\item{as.vector}{\code{signature(x = "ldenseMatrix", mode = "missing")}: ...}
\item{which}{\code{signature(x = "ndenseMatrix")}, semantically
equivalent to \pkg{base} function \code{\link{which}(x, arr.ind)};
for details, see the \code{\linkS4class{lMatrix}} class documentation.}
}
}
\seealso{
Class \code{\linkS4class{lgeMatrix}} and the other subclasses.
}
\examples{
showClass("ldenseMatrix")
as(diag(3) > 0, "ldenseMatrix")
}
Matrix/man/dmperm.Rd 0000644 0001751 0000144 00000006643 14446607050 014101 0 ustar hornik users \name{dmperm}
\title{Dulmage-Mendelsohn Permutation / Decomposition}
%
\keyword{algebra}
\keyword{array}
\keyword{utilities}
%
\alias{dmperm}
%
\description{
For any \eqn{n \times m}{n * m} (typically) sparse matrix \code{x}
compute the Dulmage-Mendelsohn row and columns permutations which at
first splits the \eqn{n} rows and \code{m} columns into coarse partitions
each; and then a finer one, reordering rows and columns such that the
permutated matrix is \dQuote{as upper triangular} as possible.
}
\usage{
dmperm(x, nAns = 6L, seed = 0L)
}
\arguments{
\item{x}{a typically sparse matrix; internally coerced to either
\code{"\linkS4class{dgCMatrix}"} or
\code{"\linkS4class{dtCMatrix}"}.}
\item{nAns}{an integer specifying the \code{\link{length}} of the
resulting \code{\link{list}}. Must be 2, 4, or 6.
%% FIXME: more
}
\item{seed}{an integer code in -1,0,1; determining the (initial)
permutation; by default, \code{seed = 0}, no (or the identity) permutation;
\code{seed = -1} uses the \dQuote{reverse} permutation \code{k:1}; for
\code{seed = 1}, it is a \emph{random} permutation (using R's RNG,
seed, etc).}
}
\details{
See the book section by Tim Davis; page 122--127, in the References.
}
\value{
a named \code{\link{list}} with (by default) 6 components,
\item{p}{integer vector with the permutation \code{p}, of length \code{nrow(x)}.}
\item{q}{integer vector with the permutation \code{q}, of length \code{ncol(x)}.}
%% FIXME: give __examples__ below, showing the blocks !!
\item{r}{integer vector of length \code{nb+1}, where block k is rows r[k] to r[k+1]-1 in A[p,q].}
\item{s}{integer vector of length \code{nb+1}, where block k is cols s[k] to s[k+1]-1 in A[p,q].}
\item{rr5}{integer vector of length 5, defining the coarse row
decomposition.}% FIXME: more specifically ?
\item{cc5}{integer vector of length 5, defining the coarse column decomposition.}
}
\references{
Section 7.4 \emph{Dulmage-Mendelsohn decomposition}, pp. 122 ff of
\cr
Timothy A. Davis (2006)
\emph{Direct Methods for Sparse Linear Systems}, SIAM Series
\dQuote{Fundamentals of Algorithms}.
}
\author{Martin Maechler, with a lot of \dQuote{encouragement} by Mauricio
Vargas.
}
%% \note{
%%
%% }
\seealso{
\code{\link{Schur}}, the class of permutation matrices; \code{"\linkS4class{pMatrix}"}.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
set.seed(17)
(S9 <- rsparsematrix(9, 9, nnz = 10, symmetric=TRUE)) # dsCMatrix
str( dm9 <- dmperm(S9) )
(S9p <- with(dm9, S9[p, q]))
## looks good, but *not* quite upper triangular; these, too:
str( dm9.0 <- dmperm(S9, seed=-1)) # non-random too.
str( dm9_1 <- dmperm(S9, seed= 1)) # a random one
## The last two permutations differ, but have the same effect!
(S9p0 <- with(dm9.0, S9[p, q])) # .. hmm ..
stopifnot(all.equal(S9p0, S9p))# same as as default, but different from the random one
set.seed(11)
(M <- triu(rsparsematrix(9,11, 1/4)))
dM <- dmperm(M); with(dM, M[p, q])
(Mp <- M[sample.int(nrow(M)), sample.int(ncol(M))])
dMp <- dmperm(Mp); with(dMp, Mp[p, q])
set.seed(7)
(n7 <- rsparsematrix(5, 12, nnz = 10, rand.x = NULL))
str( dm.7 <- dmperm(n7) )
stopifnot(exprs = {
lengths(dm.7[1:2]) == dim(n7)
identical(dm.7, dmperm(as(n7, "dMatrix")))
identical(dm.7[1:4], dmperm(n7, nAns=4))
identical(dm.7[1:2], dmperm(n7, nAns=2))
})
%% FIXME: Check permutations / blocks etc -- does it work ???
}
Matrix/man/solve-methods.Rd 0000644 0001751 0000144 00000027205 14552026002 015371 0 ustar hornik users \name{solve-methods}
\title{Methods in Package \pkg{Matrix} for Function \code{solve}}
%
\docType{methods}
\keyword{algebra}
\keyword{array}
\keyword{methods}
%
\alias{solve}
\alias{solve-methods}
%
\alias{solve,ANY,ANY-method}
\alias{solve,BunchKaufman,missing-method}
\alias{solve,BunchKaufman,dgeMatrix-method}
\alias{solve,CHMfactor,missing-method}
\alias{solve,CHMfactor,dgeMatrix-method}
\alias{solve,CHMfactor,dgCMatrix-method}
\alias{solve,Cholesky,missing-method}
\alias{solve,Cholesky,dgeMatrix-method}
\alias{solve,CsparseMatrix,ANY-method}
\alias{solve,Matrix,sparseVector-method}
\alias{solve,MatrixFactorization,CsparseMatrix-method}
\alias{solve,MatrixFactorization,RsparseMatrix-method}
\alias{solve,MatrixFactorization,TsparseMatrix-method}
\alias{solve,MatrixFactorization,denseMatrix-method}
\alias{solve,MatrixFactorization,dgCMatrix-method}
\alias{solve,MatrixFactorization,dgeMatrix-method}
\alias{solve,MatrixFactorization,diagonalMatrix-method}
\alias{solve,MatrixFactorization,indMatrix-method}
\alias{solve,MatrixFactorization,matrix-method}
\alias{solve,MatrixFactorization,sparseVector-method}
\alias{solve,MatrixFactorization,vector-method}
\alias{solve,RsparseMatrix,ANY-method}
\alias{solve,Schur,ANY-method}
\alias{solve,TsparseMatrix,ANY-method}
\alias{solve,ddiMatrix,Matrix-method}
\alias{solve,ddiMatrix,matrix-method}
\alias{solve,ddiMatrix,missing-method}
\alias{solve,ddiMatrix,vector-method}
\alias{solve,denseLU,missing-method}
\alias{solve,denseLU,dgeMatrix-method}
\alias{solve,denseMatrix,ANY-method}
\alias{solve,dgCMatrix,denseMatrix-method}
\alias{solve,dgCMatrix,matrix-method}
\alias{solve,dgCMatrix,missing-method}
\alias{solve,dgCMatrix,sparseMatrix-method}
\alias{solve,dgCMatrix,vector-method}
\alias{solve,dgeMatrix,ANY-method}
\alias{solve,diagonalMatrix,ANY-method}
\alias{solve,dpoMatrix,ANY-method}
\alias{solve,dppMatrix,ANY-method}
\alias{solve,dsCMatrix,denseMatrix-method}
\alias{solve,dsCMatrix,matrix-method}
\alias{solve,dsCMatrix,missing-method}
\alias{solve,dsCMatrix,sparseMatrix-method}
\alias{solve,dsCMatrix,vector-method}
\alias{solve,dspMatrix,ANY-method}
\alias{solve,dsyMatrix,ANY-method}
\alias{solve,dtCMatrix,dgCMatrix-method}
\alias{solve,dtCMatrix,dgeMatrix-method}
\alias{solve,dtCMatrix,missing-method}
\alias{solve,dtCMatrix,triangularMatrix-method}
\alias{solve,dtpMatrix,dgeMatrix-method}
\alias{solve,dtpMatrix,missing-method}
\alias{solve,dtpMatrix,triangularMatrix-method}
\alias{solve,dtrMatrix,dgeMatrix-method}
\alias{solve,dtrMatrix,missing-method}
\alias{solve,dtrMatrix,triangularMatrix-method}
\alias{solve,indMatrix,ANY-method}
\alias{solve,matrix,Matrix-method}
\alias{solve,matrix,sparseVector-method}
\alias{solve,pBunchKaufman,missing-method}
\alias{solve,pBunchKaufman,dgeMatrix-method}
\alias{solve,pCholesky,missing-method}
\alias{solve,pCholesky,dgeMatrix-method}
\alias{solve,pMatrix,Matrix-method}
\alias{solve,pMatrix,matrix-method}
\alias{solve,pMatrix,missing-method}
\alias{solve,pMatrix,vector-method}
\alias{solve,sparseLU,missing-method}
\alias{solve,sparseLU,dgeMatrix-method}
\alias{solve,sparseLU,dgCMatrix-method}
\alias{solve,sparseQR,missing-method}
\alias{solve,sparseQR,dgeMatrix-method}
\alias{solve,sparseQR,dgCMatrix-method}
\alias{solve,triangularMatrix,CsparseMatrix-method}
\alias{solve,triangularMatrix,RsparseMatrix-method}
\alias{solve,triangularMatrix,TsparseMatrix-method}
\alias{solve,triangularMatrix,denseMatrix-method}
\alias{solve,triangularMatrix,dgCMatrix-method}
\alias{solve,triangularMatrix,dgeMatrix-method}
\alias{solve,triangularMatrix,diagonalMatrix-method}
\alias{solve,triangularMatrix,indMatrix-method}
\alias{solve,triangularMatrix,matrix-method}
\alias{solve,triangularMatrix,vector-method}
%
\description{
Methods for generic function \code{\link[base]{solve}} for solving
linear systems of equations,
i.e., for \eqn{X} in \eqn{A X = B}{A * X = B},
where \eqn{A} is a square matrix and \eqn{X} and \eqn{B} are matrices
with dimensions consistent with \eqn{A}.
}
\usage{
solve(a, b, ...)
\S4method{solve}{dgeMatrix,ANY}(a, b, tol = .Machine$double.eps, \dots)
\S4method{solve}{dgCMatrix,missing}(a, b, sparse = TRUE, \dots)
\S4method{solve}{dgCMatrix,matrix}(a, b, sparse = FALSE, \dots)
\S4method{solve}{dgCMatrix,denseMatrix}(a, b, sparse = FALSE, \dots)
\S4method{solve}{dgCMatrix,sparseMatrix}(a, b, sparse = TRUE, \dots)
\S4method{solve}{denseLU,dgeMatrix}(a, b, \dots)
\S4method{solve}{BunchKaufman,dgeMatrix}(a, b, \dots)
\S4method{solve}{Cholesky,dgeMatrix}(a, b, \dots)
\S4method{solve}{sparseLU,dgCMatrix}(a, b, tol = .Machine$double.eps, \dots)
\S4method{solve}{sparseQR,dgCMatrix}(a, b, \dots)
\S4method{solve}{CHMfactor,dgCMatrix}(a, b, system = c("A", "LDLt", "LD", "DLt", "L", "Lt", "D", "P", "Pt"), \dots)
}
\arguments{
\item{a}{a \link[=is.finite]{finite} square matrix or
\code{\linkS4class{Matrix}} containing the coefficients
of the linear system, or otherwise a
\code{\linkS4class{MatrixFactorization}},
in which case methods behave (by default)
as if the factorized matrix were specified.}
\item{b}{a vector, \code{\linkS4class{sparseVector}},
matrix, or \code{\linkS4class{Matrix}} satisfying
\code{NROW(b) == nrow(a)}, giving the right-hand side(s)
of the linear system. Vectors \code{b} are treated as
\code{length(b)}-by-1 matrices. If \code{b} is missing,
then methods take \code{b} to be an identity matrix.}
\item{tol}{a non-negative number. For \code{a} inheriting from
\code{\linkS4class{denseMatrix}}, an error is signaled if the
reciprocal one-norm condition number (see \code{\link[base]{rcond}})
of \code{a} is less than \code{tol}, indicating that \code{a} is
near-singular. For \code{a} of class \code{\linkS4class{sparseLU}},
an error is signaled if the ratio \code{min(d)/max(d)} is less
than \code{tol}, where \code{d = abs(diag(a@U))}. (Interpret
with care, as this ratio is a cheap heuristic and \emph{not}
in general equal to or even proportional to the reciprocal
one-norm condition number.) Setting \code{tol = 0} disables
the test.}
\item{sparse}{a logical indicating if the result should be formally
sparse, i.e., if the result should inherit from virtual class
\code{\linkS4class{sparseMatrix}}.
Only methods for sparse \code{a} and missing or matrix \code{b}
have this argument.
Methods for missing or sparse \code{b} use \code{sparse = TRUE}
by default. Methods for dense \code{b} use \code{sparse = FALSE}
by default.}
\item{system}{a string specifying a linear system to be solved.
Only methods for \code{a}
inheriting from \code{\linkS4class{CHMfactor}} have this argument.
See \sQuote{Details}.}
\item{\dots}{further arguments passed to or from methods.}
}
\details{
Methods for general and symmetric matrices \code{a} compute a
triangular factorization (LU, Bunch-Kaufman, or Cholesky)
and call the method for the corresponding factorization class.
The factorization is sparse if \code{a} is. Methods for sparse,
symmetric matrices \code{a} attempt a Cholesky factorization
and perform an LU factorization only if that fails (typically
because \code{a} is not positive definite).
Triangular, diagonal, and permutation matrices do not require
factorization (they are already \dQuote{factors}), hence methods
for those are implemented directly. For triangular \code{a},
solutions are obtained by forward or backward substitution;
for diagonal \code{a}, they are obtained by scaling the rows
of \code{b}; and for permutations \code{a}, they are obtained
by permuting the rows of \code{b}.
Methods for dense \code{a} are built on 14 LAPACK routines:
class \code{d..Matrix}, where \code{..=(ge|tr|tp|sy|sp|po|pp)},
uses routines \code{d..tri} and \code{d..trs} for missing
and non-missing \code{b}, respectively. A corollary is that
these methods always give a dense result.
Methods for sparse \code{a} are built on CXSparse routines
\code{cs_lsolve}, \code{cs_usolve}, and \code{cs_spsolve} and
CHOLMOD routines \code{cholmod_solve} and \code{cholmod_spsolve}.
By default, these methods give a vector result if \code{b}
is a vector, a sparse matrix result if \code{b} is missing
or a sparse matrix, and a dense matrix result if \code{b}
is a dense matrix. One can override this behaviour by setting
the \code{sparse} argument, where available, but that should
be done with care. Note that a sparse result may be sparse only
in the formal sense and not at all in the mathematical sense,
depending on the nonzero patterns of \code{a} and \code{b}.
Furthermore, whereas dense results are fully preallocated,
sparse results must be \dQuote{grown} in a loop over the columns
of \code{b}.
Methods for \code{a} of class \code{\linkS4class{sparseQR}}
are simple wrappers around \code{\link{qr.coef}}, giving the
\emph{least squares} solution in overdetermined cases.
Methods for \code{a} inheriting from \code{\linkS4class{CHMfactor}}
can solve systems other than the default one \eqn{A X = B}{A * X = B}.
The correspondence between its \code{system} argument the system
actually solved is outlined in the table below.
See \code{\link{CHMfactor-class}} for a definition of notation.
\tabular{rrr}{
\code{system} \tab \code{\link{isLDL}(a)=TRUE} \tab \code{\link{isLDL}(a)=FALSE}\cr
\code{"A"} \tab \eqn{A X = B}{A * X = B} \tab \eqn{A X = B}{A * X = B}\cr
\code{"LDLt"} \tab \eqn{L_{1} D L_{1}' X = B}{L1 * D * L1' * X = B} \tab \eqn{L L' X = B}{L * L' * X = B}\cr
\code{"LD"} \tab \eqn{L_{1} D X = B}{L1 * D * X = B} \tab \eqn{L X = B}{L * X = B}\cr
\code{"DLt"} \tab \eqn{D L_{1}' X = B}{D * L1' * X = B} \tab \eqn{L' X = B}{L' * X = B}\cr
\code{"L"} \tab \eqn{L_{1} X = B}{L1 * X = B} \tab \eqn{L X = B}{L * X = B}\cr
\code{"Lt"} \tab \eqn{L_{1}' X = B}{L1' * X = B} \tab \eqn{L' X = B}{L' * X = B}\cr
\code{"D"} \tab \eqn{D X = B}{D * X = B} \tab \eqn{X = B}{X = B}\cr
\code{"P"} \tab \eqn{X = P_{1} B}{X = P1 * B} \tab \eqn{X = P_{1} B}{X = P1 * B}\cr
\code{"Pt"} \tab \eqn{X = P_{1}' B}{X = P1' * B} \tab \eqn{X = P_{1}' B}{X = P1' * B}
}
}
\seealso{
Virtual class \code{\linkS4class{MatrixFactorization}} and its
subclasses.
Generic functions \code{\link{Cholesky}}, \code{\link{BunchKaufman}},
\code{\link{Schur}}, \code{\link{lu}}, and \code{\link{qr}} for
\emph{computing} factorizations.
Generic function \code{\link[base]{solve}} from \pkg{base}.
Function \code{\link{qr.coef}} from \pkg{base} for computing
least squares solutions of overdetermined linear systems.
}
\examples{
## A close to symmetric example with "quite sparse" inverse:
n1 <- 7; n2 <- 3
dd <- data.frame(a = gl(n1,n2), b = gl(n2,1,n1*n2))# balanced 2-way
X <- sparse.model.matrix(~ -1+ a + b, dd)# no intercept --> even sparser
XXt <- tcrossprod(X)
diag(XXt) <- rep(c(0,0,1,0), length.out = nrow(XXt))
n <- nrow(ZZ <- kronecker(XXt, Diagonal(x=c(4,1))))
image(a <- 2*Diagonal(n) + ZZ \%*\% Diagonal(x=c(10, rep(1, n-1))))
isSymmetric(a) # FALSE
image(drop0(skewpart(a)))
image(ia0 <- solve(a, tol = 0)) # checker board, dense [but really, a is singular!]
try(solve(a, sparse=TRUE))##-> error [ TODO: assertError ]
ia. <- solve(a, sparse=TRUE, tol = 1e-19)##-> *no* error
if(R.version$arch == "x86_64")
## Fails on 32-bit [Fedora 19, R 3.0.2] from Matrix 1.1-0 on [FIXME ??] only
stopifnot(all.equal(as.matrix(ia.), as.matrix(ia0)))
a <- a + Diagonal(n)
iad <- solve(a)
ias <- solve(a, sparse=FALSE)
stopifnot(all.equal(as(iad,"denseMatrix"), ias, tolerance=1e-14))
I. <- iad \%*\% a ; image(I.)
I0 <- drop0(zapsmall(I.)); image(I0)
.I <- a \%*\% iad
.I0 <- drop0(zapsmall(.I))
stopifnot( all.equal(as(I0, "diagonalMatrix"), Diagonal(n)),
all.equal(as(.I0,"diagonalMatrix"), Diagonal(n)) )
}
Matrix/man/ddenseMatrix-class.Rd 0000644 0001751 0000144 00000003462 14500644730 016340 0 ustar hornik users \name{ddenseMatrix-class}
\title{Virtual Class "ddenseMatrix" of Numeric Dense Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{ddenseMatrix-class}
%
\alias{&,ddenseMatrix,ddiMatrix-method}
\alias{&,ddenseMatrix,ldiMatrix-method}
\alias{&,ddenseMatrix,ndiMatrix-method}
\alias{*,ddenseMatrix,ddiMatrix-method}
\alias{*,ddenseMatrix,ldiMatrix-method}
\alias{*,ddenseMatrix,ndiMatrix-method}
\alias{Arith,ddenseMatrix,logical-method}
\alias{Arith,ddenseMatrix,numeric-method}
\alias{Arith,ddenseMatrix,sparseVector-method}
\alias{Arith,logical,ddenseMatrix-method}
\alias{Arith,numeric,ddenseMatrix-method}
\alias{^,ddenseMatrix,ddiMatrix-method}
\alias{^,ddenseMatrix,ldiMatrix-method}
\alias{^,ddenseMatrix,ndiMatrix-method}
\alias{coerce,matrix,ddenseMatrix-method}
\alias{coerce,vector,ddenseMatrix-method}
%
\description{This is the virtual class of all dense numeric (i.e.,
\bold{d}ouble, hence \emph{\dQuote{ddense}}) S4 matrices.
Its most important subclass is the \code{\linkS4class{dgeMatrix}} class.
%% and now say what the difference is ! __ FIXME __
}
\section{Extends}{
Class \code{"dMatrix"} directly;
class \code{"Matrix"}, by the above.
}
\section{Slots}{
the same slots at its subclass \code{\linkS4class{dgeMatrix}}, see
there.
}
\section{Methods}{
Most methods are implemented via \code{as(*, "generalMatrix")} and are
mainly used as \dQuote{fallbacks} when the subclass doesn't need its
own specialized method.
Use \code{\link{showMethods}(class = "ddenseMatrix", where =
"package:Matrix")} for an overview.
}
%\references{}
%\note{}
\seealso{
The virtual classes \code{\linkS4class{Matrix}},
\code{\linkS4class{dMatrix}}, and \code{\linkS4class{dsparseMatrix}}.
}
\examples{
showClass("ddenseMatrix")
showMethods(class = "ddenseMatrix", where = "package:Matrix")
}
Matrix/man/drop0.Rd 0000644 0001751 0000144 00000005221 14462010167 013623 0 ustar hornik users \name{drop0}
\title{Drop Non-Structural Zeros from a Sparse Matrix}
%
\keyword{array}
\keyword{manip}
\keyword{utilities}
%
\alias{drop0}
%
\description{
Deletes \dQuote{non-structural} zeros (i.e., zeros stored explicitly,
in memory) from a sparse matrix and returns the result.
}
\usage{
drop0(x, tol = 0, is.Csparse = NA, give.Csparse = TRUE)
}
\arguments{
\item{x}{a \code{\linkS4class{Matrix}}, typically inheriting
from virtual class \code{\linkS4class{sparseMatrix}}.
\code{\linkS4class{denseMatrix}} and traditional vectors and
matrices are coerced to \code{\linkS4class{CsparseMatrix}},
with zeros dropped automatically, hence users passing such
\code{x} should consider \code{as(x, "CsparseMatrix")} instead,
notably in the \code{tol = 0} case.}
\item{tol}{a non-negative number. If \code{x} is numeric,
then entries less than or equal to \code{tol} in absolute value
are deleted.}
\item{is.Csparse}{a logical used only if \code{give.Csparse}
is \code{TRUE}, indicating if \code{x} already inherits from
virtual class \code{\linkS4class{CsparseMatrix}}, in which
case coercion is not attempted, permitting some (typically
small) speed-up.}
\item{give.Csparse}{a logical indicating if the result must
inherit from virtual class \code{\linkS4class{CsparseMatrix}}.
If \code{FALSE} and \code{x} inherits from
\code{\linkS4class{RsparseMatrix}},
\code{\linkS4class{TsparseMatrix}}, or
\code{\linkS4class{indMatrix}},
then the result preserves the class of \code{x}.
The default value is \code{TRUE} only for backwards compatibility.}
}
\value{
A \code{\linkS4class{sparseMatrix}}, the result of deleting
non-structural zeros from \code{x}, possibly after coercion.
}
\note{
\code{drop0} is sometimes called in conjunction with
\code{\link{zapsmall}}, e.g., when dealing with sparse
matrix products; see the example.
}
\seealso{
Function \code{\link{sparseMatrix}}, for constructing objects
inheriting from virtual class \code{\linkS4class{sparseMatrix}};
\code{\link{nnzero}}.
}
\examples{
(m <- sparseMatrix(i = 1:8, j = 2:9, x = c(0:2, 3:-1),
dims = c(10L, 20L)))
drop0(m)
## A larger example:
t5 <- new("dtCMatrix", Dim = c(5L, 5L), uplo = "L",
x = c(10, 1, 3, 10, 1, 10, 1, 10, 10),
i = c(0L,2L,4L, 1L, 3L,2L,4L, 3L, 4L),
p = c(0L, 3L, 5L, 7:9))
TT <- kronecker(t5, kronecker(kronecker(t5, t5), t5))
IT <- solve(TT)
I. <- TT \%*\% IT ; nnzero(I.) # 697 ( == 625 + 72 )
I.0 <- drop0(zapsmall(I.))
## which actually can be more efficiently achieved by
I.. <- drop0(I., tol = 1e-15)
stopifnot(all(I.0 == Diagonal(625)), nnzero(I..) == 625)
}
Matrix/man/dtrMatrix-class-dense.Rd 0000644 0001751 0000144 00000005613 14575137654 017001 0 ustar hornik users \name{dtrMatrix-class}
\title{Triangular, dense, numeric matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{dtrMatrix-class}
%
\description{
The \code{"dtrMatrix"} class is the class of triangular, dense,
numeric matrices in nonpacked storage. The \code{"dtpMatrix"} class
is the same except in packed storage, see \code{\link{pack}()}.
}
\section{Objects from the Class}{
Objects can be created by calls of the form \code{new("dtrMatrix", ...)}.
}
\section{Slots}{
\describe{
\item{\code{uplo}:}{Object of class \code{"character"}. Must be
either "U", for upper triangular, and "L", for lower triangular.}
\item{\code{diag}:}{Object of class \code{"character"}. Must be
either \code{"U"}, for unit triangular (diagonal is all ones), or
\code{"N"}; see \code{\linkS4class{triangularMatrix}}.}
\item{\code{x}:}{Object of class \code{"numeric"}. The numeric
values that constitute the matrix, stored in column-major order.}
\item{\code{Dim}:}{Object of class \code{"integer"}. The dimensions
of the matrix which must be a two-element vector of non-negative
integers.}
}
}
\section{Extends}{
Class \code{"ddenseMatrix"}, directly.
Class \code{"triangularMatrix"}, directly.
Class \code{"Matrix"} and others, by class \code{"ddenseMatrix"}.
}
\section{Methods}{
Among others (such as matrix products, e.g. \code{?\link{crossprod-methods}}),
\describe{
\item{norm}{\code{signature(x = "dtrMatrix", type = "character")}: ..}
\item{rcond}{\code{signature(x = "dtrMatrix", norm = "character")}: ..}
\item{solve}{\code{signature(a = "dtrMatrix", b = "....")}: efficiently
use a \dQuote{forwardsolve} or \code{backsolve} for a lower or
upper triangular matrix, respectively, see also
\code{\link{solve-methods}}.}
\item{+, -, *, \dots, ==, >=, \dots}{ all the \code{\link{Ops}} group
methods are available. When applied to two triangular matrices,
these return a triangular matrix when easily possible.}
}
}
%\references{}
%\author{}
\seealso{
Classes \code{\linkS4class{ddenseMatrix}}, \code{\linkS4class{dtpMatrix}},
\code{\linkS4class{triangularMatrix}}
}
\examples{%% this is used from ./dtpMatrix-class.Rd (change with care!)
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
(m <- rbind(2:3, 0:-1))
(M <- as(m, "generalMatrix"))
(T <- as(M, "triangularMatrix")) # formally upper triangular
(T2 <- as(t(M), "triangularMatrix"))
stopifnot(T@uplo == "U", T2@uplo == "L", identical(T2, t(T)))
m <- matrix(0,4,4); m[upper.tri(m)] <- 1:6
(t1 <- Matrix(m+diag(,4)))
str(t1p <- pack(t1))
(t1pu <- diagN2U(t1p))
stopifnot(exprs = {
inherits(t1 , "dtrMatrix"); validObject(t1)
inherits(t1p, "dtpMatrix"); validObject(t1p)
inherits(t1pu,"dtCMatrix"); validObject(t1pu)
t1pu@x == 1:6
all(t1pu == t1p)
identical((t1pu - t1)@x, numeric())# sparse all-0
})
}
Matrix/man/pack-methods.Rd 0000644 0001751 0000144 00000007612 14575137654 015204 0 ustar hornik users \name{pack-methods}
\title{Representation of Packed and Unpacked Dense Matrices}
%
\docType{methods}
\keyword{array}
\keyword{methods}
%
\alias{pack}
\alias{pack-methods}
\alias{unpack}
\alias{unpack-methods}
%
\alias{pack,dgeMatrix-method}
\alias{pack,lgeMatrix-method}
\alias{pack,matrix-method}
\alias{pack,ngeMatrix-method}
\alias{pack,packedMatrix-method}
\alias{pack,sparseMatrix-method}
\alias{pack,unpackedMatrix-method}
%
\alias{unpack,matrix-method}
\alias{unpack,packedMatrix-method}
\alias{unpack,sparseMatrix-method}
\alias{unpack,unpackedMatrix-method}
%
\description{
\code{pack()} coerces dense symmetric and dense triangular matrices
from unpacked format (storing the full matrix) to packed format
(storing only one of the upper and lower triangles). \code{unpack()}
performs the reverse coercion. The two formats are formalized
by the virtual classes \code{"\linkS4class{packedMatrix}"} and
\code{"\linkS4class{unpackedMatrix}"}.
}
\usage{
pack(x, \dots)
\S4method{pack}{dgeMatrix}(x, symmetric = NA, upperTri = NA, \dots)
\S4method{pack}{lgeMatrix}(x, symmetric = NA, upperTri = NA, \dots)
\S4method{pack}{ngeMatrix}(x, symmetric = NA, upperTri = NA, \dots)
\S4method{pack}{matrix}(x, symmetric = NA, upperTri = NA, \dots)
unpack(x, \dots)
}
\arguments{
\item{x}{A dense symmetric or dense triangular matrix.
\describe{
\item{For \code{pack()}:}{typically an \code{"unpackedMatrix"}
or a standard \code{"matrix"}, though \code{"packedMatrix"}
are allowed and returned unchanged.}
\item{For \code{unpack()}:}{typically a \code{"packedMatrix"},
though \code{"unpackedMatrix"} are allowed and returned unchanged.}
}
}
\item{symmetric}{logical (including \code{NA}) optionally
indicating whether \code{x} is symmetric (or triangular).}
\item{upperTri}{(for triangular \code{x} only) logical
(including \code{NA}) indicating whether \code{x} is
upper (or lower) triangular.}
\item{\dots}{further arguments passed to or from other methods.}
}
\value{
\describe{
\item{For \code{pack()}:}{a \code{"packedMatrix"} giving
the condensed representation of \code{x}.}
\item{For \code{unpack()}:}{an \code{"unpackedMatrix"} giving
the full storage representation of \code{x}.}
}
}
\details{
\code{pack(x)} checks matrices \code{x} \emph{not} inheriting from
one of the virtual classes \code{"\linkS4class{symmetricMatrix}"}
\code{"\linkS4class{triangularMatrix}"} for symmetry
(via \code{\link[=isSymmetric-methods]{isSymmetric}()})
then for upper and lower triangularity
(via \code{\link{isTriangular}()}) in order to identify a suitable
coercion. Setting one or both of \code{symmetric} and \code{upperTri}
to \code{TRUE} or \code{FALSE} rather than \code{NA} allows skipping
of irrelevant tests for large matrices known to be symmetric or
(upper or lower) triangular.
Users should \emph{not} assume that \code{pack()} and \code{unpack()}
are inverse operations. Specifically, \code{y <- unpack(pack(x))}
may not reproduce an \code{"unpackedMatrix"} \code{x} in the sense of
\code{\link{identical}()}. See the examples.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
showMethods("pack")
(s <- crossprod(matrix(sample(15), 5,3))) # traditional symmetric matrix
(sp <- pack(s))
mt <- as.matrix(tt <- tril(s))
(pt <- pack(mt))
stopifnot(identical(pt, pack(tt)),
dim(s ) == dim(sp), all(s == sp),
dim(mt) == dim(pt), all(mt == pt), all(mt == tt))
showMethods("unpack")
(cp4 <- chol(Hilbert(4))) # is triangular
tp4 <- pack(cp4) # [t]riangular [p]acked
str(tp4)
(unpack(tp4))
stopifnot(identical(tp4, pack(unpack(tp4))))
z1 <- new("dsyMatrix", Dim = c(2L, 2L), x = as.double(1:4), uplo = "U")
z2 <- unpack(pack(z1))
stopifnot(!identical(z1, z2), # _not_ identical
all(z1 == z2)) # but mathematically equal
cbind(z1@x, z2@x) # (unused!) lower triangle is "lost" in translation
}
Matrix/man/chol2inv-methods.Rd 0000644 0001751 0000144 00000005706 14516234475 016006 0 ustar hornik users \name{chol2inv-methods}
\title{Inverse from Cholesky Factor}
%
\docType{methods}
\keyword{algebra}
\keyword{array}
\keyword{methods}
%
\alias{chol2inv}
\alias{chol2inv-methods}
%
\alias{chol2inv,ANY-method}
\alias{chol2inv,ddiMatrix-method}
\alias{chol2inv,diagonalMatrix-method}
\alias{chol2inv,dtCMatrix-method}
\alias{chol2inv,dtRMatrix-method}
\alias{chol2inv,dtTMatrix-method}
\alias{chol2inv,dtrMatrix-method}
\alias{chol2inv,dtpMatrix-method}
\alias{chol2inv,generalMatrix-method}
\alias{chol2inv,symmetricMatrix-method}
\alias{chol2inv,triangularMatrix-method}
%
\description{
Given \emph{formally} upper and lower triangular matrices
\eqn{U} and \eqn{L}, compute \eqn{(U' U)^{-1}}{(U' U)^(-1)}
and \eqn{(L L')^{-1}}{(L L')^(-1)}, respectively.
This function can be seen as way to compute the inverse of a
symmetric positive definite matrix given its Cholesky factor.
Equivalently, it can be seen as a way to compute
\eqn{(X' X)^{-1}}{(X' X)^(-1)} given the \eqn{R} part of the
QR factorization of \eqn{X}, if \eqn{R} is constrained to have
positive diagonal entries.
}
\usage{
chol2inv(x, \dots)
\S4method{chol2inv}{dtrMatrix}(x, \dots)
\S4method{chol2inv}{dtCMatrix}(x, \dots)
\S4method{chol2inv}{generalMatrix}(x, uplo = "U", \dots)
}
\arguments{
\item{x}{a square matrix or \code{\linkS4class{Matrix}},
typically the result of a call to \code{\link{chol}}.
If \code{x} is square but not (formally) triangular,
then only the upper or lower triangle is considered,
depending on optional argument \code{uplo} if \code{x}
is a \code{\linkS4class{Matrix}}.}
\item{uplo}{a string, either \code{"U"} or \code{"L"},
indicating which triangle of \code{x} contains the
Cholesky factor. The default is \code{"U"}, to be
consistent with \code{\link[base]{chol2inv}} from \pkg{base}.}
\item{\dots}{further arguments passed to or from methods.}
}
\value{
A matrix, \code{\linkS4class{symmetricMatrix}},
or \code{\linkS4class{diagonalMatrix}} representing
the inverse of the positive definite matrix whose
Cholesky factor is \code{x}.
The result is a traditional matrix if \code{x} is a
traditional matrix, dense if \code{x} is dense, and
sparse if \code{x} is sparse.
}
\seealso{
The default method from \pkg{base}, \code{\link[base]{chol2inv}},
called for traditional matrices \code{x}.
Generic function \code{\link{chol}}, for computing the upper
triangular Cholesky factor \eqn{L'} of a symmetric positive
semidefinite matrix.
Generic function \code{\link{solve}}, for solving linear systems
and (as a corollary) for computing inverses more generally.
}
\examples{
(A <- Matrix(cbind(c(1, 1, 1), c(1, 2, 4), c(1, 4, 16))))
(R <- chol(A))
(L <- t(R))
(R2i <- chol2inv(R))
(L2i <- chol2inv(R))
stopifnot(exprs = {
all.equal(R2i, tcrossprod(solve(R)))
all.equal(L2i, crossprod(solve(L)))
all.equal(as(R2i \%*\% A, "matrix"), diag(3L)) # the identity
all.equal(as(L2i \%*\% A, "matrix"), diag(3L)) # ditto
})
}
Matrix/man/forceSymmetric-methods.Rd 0000644 0001751 0000144 00000004500 14575137654 017252 0 ustar hornik users \name{forceSymmetric-methods}
\title{Force a Matrix to 'symmetricMatrix' Without Symmetry Checks}
%
\docType{methods}
\keyword{array}
\keyword{methods}
%
\alias{forceSymmetric}
\alias{forceSymmetric-methods}
%
\alias{forceSymmetric,CsparseMatrix,character-method}
\alias{forceSymmetric,CsparseMatrix,missing-method}
\alias{forceSymmetric,RsparseMatrix,character-method}
\alias{forceSymmetric,RsparseMatrix,missing-method}
\alias{forceSymmetric,TsparseMatrix,character-method}
\alias{forceSymmetric,TsparseMatrix,missing-method}
\alias{forceSymmetric,denseMatrix,character-method}
\alias{forceSymmetric,denseMatrix,missing-method}
\alias{forceSymmetric,diagonalMatrix,character-method}
\alias{forceSymmetric,diagonalMatrix,missing-method}
\alias{forceSymmetric,indMatrix,character-method}
\alias{forceSymmetric,indMatrix,missing-method}
\alias{forceSymmetric,matrix,character-method}
\alias{forceSymmetric,matrix,missing-method}
%
\description{
Force a square matrix \code{x} to a \code{\linkS4class{symmetricMatrix}},
\bold{without} a symmetry check as it would be applied for \code{as(x,
"symmetricMatrix")}.
}
\usage{
forceSymmetric(x, uplo)
}
\arguments{
\item{x}{any square matrix (of numbers), either \dQuote{"traditional"}
(\code{\link{matrix}}) or inheriting from
\code{\linkS4class{Matrix}}.}
\item{uplo}{optional string, \code{"U"} or \code{"L"} indicating which
\dQuote{triangle} half of \code{x} should determine the result. The
default is \code{"U"} unless \code{x} already has a \code{uplo} slot
(i.e., when it is \code{\linkS4class{symmetricMatrix}}, or
\code{\linkS4class{triangularMatrix}}), where the default will be
\code{x@uplo}.}
}
% \details{
%
% }
\value{
a square matrix inheriting from class
\code{\linkS4class{symmetricMatrix}}.
}
\seealso{\code{\link{symmpart}} for the symmetric part of a matrix, or
the coercions \code{as(x, )}.
}
\examples{
## Hilbert matrix
i <- 1:6
h6 <- 1/outer(i - 1L, i, "+")
sd <- sqrt(diag(h6))
hh <- t(h6/sd)/sd # theoretically symmetric
isSymmetric(hh, tol=0) # FALSE; hence
try( as(hh, "symmetricMatrix") ) # fails, but this works fine:
H6 <- forceSymmetric(hh)
## result can be pretty surprising:
(M <- Matrix(1:36, 6))
forceSymmetric(M) # symmetric, hence very different in lower triangle
(tm <- tril(M))
forceSymmetric(tm)
}
Matrix/man/rep2abI.Rd 0000644 0001751 0000144 00000001304 14422605232 014060 0 ustar hornik users \name{rep2abI}
\title{Replicate Vectors into 'abIndex' Result}
%
\keyword{manip}
\keyword{utilities}
%
\alias{rep2abI}
%
\description{
\code{rep2abI(x, times)} conceptually computes
\code{\link{rep.int}(x, times)} but with an
\code{\linkS4class{abIndex}} class result.
}
\usage{
rep2abI(x, times)
}
\arguments{
\item{x}{numeric vector}
\item{times}{integer (valued) scalar: the number of repetitions}
}
% \details{
% }
\value{
a vector of \code{\link{class}} \code{\linkS4class{abIndex}}
}
\seealso{
\code{\link{rep.int}()}, the base function;
\code{\link{abIseq}}, \code{\linkS4class{abIndex}}.
}
\examples{
(ab <- rep2abI(2:7, 4))
stopifnot(identical(as(ab, "numeric"),
rep(2:7, 4)))
}
Matrix/man/dtRMatrix-class-sparse.Rd 0000644 0001751 0000144 00000005361 14575137654 017140 0 ustar hornik users \name{dtRMatrix-class}
\title{Triangular Sparse Compressed Row Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{dtRMatrix-class}
%
\description{The \code{dtRMatrix} class is a class of triangular, sparse
matrices in the compressed, row-oriented format. In this
implementation the non-zero elements in the rows are sorted into
increasing columnd order.
}
\section{Objects from the Class}{
This class is currently still mostly unimplemented!
Objects can be created by calls of the form \code{new("dtRMatrix", ...)}.
}
\section{Slots}{
\describe{
\item{\code{uplo}:}{Object of class \code{"character"}. Must be
either "U", for upper triangular, and "L", for lower triangular.
At present only the lower triangle form is allowed.}
\item{\code{diag}:}{Object of class \code{"character"}. Must be
either \code{"U"}, for unit triangular (diagonal is all ones), or
\code{"N"}; see \code{\linkS4class{triangularMatrix}}.}
\item{\code{j}:}{Object of class \code{"integer"} of length
\code{\link{nnzero}(.)} (number of non-zero elements). These are
the row numbers for each non-zero element in the matrix.}
\item{\code{p}:}{Object of class \code{"integer"} of pointers, one
for each row, to the initial (zero-based) index of elements in
the row. (Only present in the \code{dsRMatrix} class.)}
\item{\code{x}:}{Object of class \code{"numeric"} - the non-zero
elements of the matrix.}
\item{\code{Dim}:}{The dimension (a length-2 \code{"integer"})}
\item{\code{Dimnames}:}{corresponding names (or \code{NULL}),
inherited from the \code{\linkS4class{Matrix}}, see there.}
}
}
\section{Extends}{
Class \code{"dgRMatrix"}, directly.
Class \code{"dsparseMatrix"}, by class \code{"dgRMatrix"}.
Class \code{"dMatrix"}, by class \code{"dgRMatrix"}.
Class \code{"sparseMatrix"}, by class \code{"dgRMatrix"}.
Class \code{"Matrix"}, by class \code{"dgRMatrix"}.
}
\section{Methods}{
No methods currently with class "dsRMatrix" in the signature.
% \describe{
% \item{solve}{\code{signature(a = "dsRMatrix", b = "matrix")}: Solve
% a linear system of equations defined by \code{x} using a Cholesky
% decomposition.}
% ......
% \item{coerce}{\code{signature(from = "dsRMatrix", to = "dgTMatrix")}}
% ......
% }
}
%\references{}
%\author{}
%\note{}
\seealso{
Classes \code{\linkS4class{dgCMatrix}}, \code{\linkS4class{dgTMatrix}},
\code{\linkS4class{dgeMatrix}}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
(m0 <- new("dtRMatrix"))
(m2 <- new("dtRMatrix", Dim = c(2L,2L),
x = c(5, 1:2), p = c(0L,2:3), j= c(0:1,1L)))
str(m2)
(m3 <- as(Diagonal(2), "RsparseMatrix"))# --> dtRMatrix
}
Matrix/man/dMatrix-class.Rd 0000644 0001751 0000144 00000011433 14574054462 015326 0 ustar hornik users \name{dMatrix-class}
\title{(Virtual) Class "dMatrix" of "double" Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{dMatrix-class}
\alias{lMatrix-class}
%
\alias{Compare,dMatrix,logical-method}
\alias{Compare,dMatrix,numeric-method}
\alias{Compare,logical,dMatrix-method}
\alias{Compare,numeric,dMatrix-method}
\alias{Logic,dMatrix,logical-method}
\alias{Logic,dMatrix,numeric-method}
\alias{Logic,dMatrix,sparseVector-method}
\alias{Logic,logical,dMatrix-method}
\alias{Logic,numeric,dMatrix-method}
\alias{Ops,dMatrix,dMatrix-method}
\alias{Ops,dMatrix,ddiMatrix-method}
\alias{Ops,dMatrix,lMatrix-method}
\alias{Ops,dMatrix,ldiMatrix-method}
\alias{Ops,dMatrix,nMatrix-method}
\alias{coerce,matrix,dMatrix-method}
\alias{coerce,vector,dMatrix-method}
%
\alias{Arith,lMatrix,numeric-method}
\alias{Arith,lMatrix,logical-method}
\alias{Arith,logical,lMatrix-method}
\alias{Arith,numeric,lMatrix-method}
\alias{Compare,lMatrix,logical-method}
\alias{Compare,lMatrix,numeric-method}
\alias{Compare,logical,lMatrix-method}
\alias{Compare,numeric,lMatrix-method}
\alias{Logic,lMatrix,logical-method}
\alias{Logic,lMatrix,numeric-method}
\alias{Logic,lMatrix,sparseVector-method}
\alias{Logic,logical,lMatrix-method}
\alias{Logic,numeric,lMatrix-method}
\alias{Ops,lMatrix,dMatrix-method}
\alias{Ops,lMatrix,lMatrix-method}
\alias{Ops,lMatrix,nMatrix-method}
\alias{Ops,lMatrix,numeric-method}
\alias{Ops,numeric,lMatrix-method}
\alias{coerce,matrix,lMatrix-method}
\alias{coerce,vector,lMatrix-method}
%
\description{
The \code{dMatrix} class is a virtual class contained by all actual
classes of numeric matrices in the \pkg{Matrix} package. Similarly,
all the actual classes of logical matrices inherit from the
\code{lMatrix} class.
}
%\section{Objects from the Class}{A virtual Class: No objects may be
% created from it.
%}
\section{Slots}{
Common to \emph{all} matrix object in the package:
\describe{
\item{\code{Dim}:}{Object of class \code{"integer"} - the dimensions
of the matrix - must be an integer vector with exactly two
non-negative values.}
\item{\code{Dimnames}:}{list of length two; each component
containing NULL or a \code{\link{character}} vector length
equal the corresponding \code{Dim} element.}
}
}
\section{Methods}{
There are (relatively simple) group methods (see, e.g., \code{\link{Arith}})
\describe{
\item{Arith}{\code{signature(e1 = "dMatrix", e2 = "dMatrix")}: ... }
\item{Arith}{\code{signature(e1 = "dMatrix", e2 = "numeric")}: ... }
\item{Arith}{\code{signature(e1 = "numeric", e2 = "dMatrix")}: ... }
\item{Math}{\code{signature(x = "dMatrix")}: ... }
\item{Math2}{\code{signature(x = "dMatrix", digits = "numeric")}:
this group contains \code{\link{round}()} and \code{\link{signif}()}.}
\item{Compare}{\code{signature(e1 = "numeric", e2 = "dMatrix")}: ... }
\item{Compare}{\code{signature(e1 = "dMatrix", e2 = "numeric")}: ... }
\item{Compare}{\code{signature(e1 = "dMatrix", e2 = "dMatrix")}: ... }
\item{Summary}{\code{signature(x = "dMatrix")}: The \code{"Summary"}
group contains the seven functions
\code{\link{max}()}, \code{\link{min}()}, \code{\link{range}()},
\code{\link{prod}()}, \code{\link{sum}()},
\code{\link{any}()}, and \code{\link{all}()}.}
}
The following methods are also defined for all double matrices:
\describe{
\item{expm}{\code{signature(x = "dMatrix")}: computes the
\emph{\dQuote{Matrix Exponential}}, see \code{\link{expm}}.}
}
The following methods are defined for all logical matrices:
\describe{
\item{which}{\code{signature(x = "lsparseMatrix")} and many other
subclasses of \code{"lMatrix"}: as the \pkg{base} function
\code{\link{which}(x, arr.ind)} returns the indices of the
\code{\link{TRUE}} entries in \code{x}; if \code{arr.ind} is true,
as a 2-column matrix of row and column indices. Since \pkg{Matrix}
version 1.2-9, if \code{useNames} is true, as by default, with
\code{\link{dimnames}}, the same as \code{base::which}.}
}
}
%\references{}
% Martin + Doug\author{Douglas Bates \email{bates@stat.wisc.edu}}
\seealso{
The nonzero-pattern matrix class \code{\linkS4class{nMatrix}}, which
can be used to store non-\code{\link{NA}} \code{\link{logical}}
matrices even more compactly.
The numeric matrix classes \code{\linkS4class{dgeMatrix}},
\code{\linkS4class{dgCMatrix}}, and \code{\linkS4class{Matrix}}.
\code{\link{drop0}(x, tol=1e-10)} is sometimes preferable to (and
more efficient than) \code{zapsmall(x, digits=10)}.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
}
showClass("dMatrix")
set.seed(101)
round(Matrix(rnorm(28), 4,7), 2)
M <- Matrix(rlnorm(56, sd=10), 4,14)
(M. <- zapsmall(M))
table(as.logical(M. == 0))
}
Matrix/man/Cholesky-class.Rd 0000644 0001751 0000144 00000017354 14446607050 015502 0 ustar hornik users \name{Cholesky-class}
\title{Dense Cholesky Factorizations}
%
\docType{class}
\keyword{algebra}
\keyword{array}
\keyword{classes}
%
\alias{Cholesky-class}
\alias{pCholesky-class}
%
\alias{coerce,Cholesky,dtrMatrix-method}
\alias{coerce,pCholesky,dtpMatrix-method}
\alias{determinant,Cholesky,logical-method}
\alias{determinant,pCholesky,logical-method}
\alias{diag,Cholesky-method}
\alias{diag,pCholesky-method}
%
\description{
Classes \code{Cholesky} and \code{pCholesky} represent
dense, pivoted Cholesky factorizations of \eqn{n \times n}{n-by-n}
real, symmetric, positive semidefinite matrices \eqn{A},
having the general form
\deqn{P_{1} A P_{1}' = L_{1} D L_{1}' = L L'}{P1 * A * P1' = L1 * D * L1' = L * L'}
or (equivalently)
\deqn{A = P_{1}' L_{1} D L_{1}' P_{1} = P_{1}' L L' P_{1}}{A = P1' * L1 * D * L1' * P1 = P1' * L * L' * P1}
where
\eqn{P_{1}}{P1} is a permutation matrix,
\eqn{L_{1}}{L1} is a unit lower triangular matrix,
\eqn{D} is a non-negative diagonal matrix, and
\eqn{L = L_{1} \sqrt{D}}{L = L1 * sqrt(D)}.
These classes store the entries of the Cholesky factor
\eqn{L} or its transpose \eqn{L'} in a dense format as
a vector of length \eqn{nn}{n*n} (\code{Cholesky}) or
\eqn{n(n+1)/2}{n*(n+1)/2} (\code{pCholesky}), the latter
giving the \dQuote{packed} representation.
}
\section{Slots}{
\describe{
\item{\code{Dim}, \code{Dimnames}}{inherited from virtual class
\code{\linkS4class{MatrixFactorization}}.}
\item{\code{uplo}}{a string, either \code{"U"} or \code{"L"},
indicating which triangle (upper or lower) of the factorized
symmetric matrix was used to compute the factorization and
in turn whether \code{x} stores \eqn{L'} or \eqn{L}.}
\item{\code{x}}{a numeric vector of length \code{n*n}
(\code{Cholesky}) or \code{n*(n+1)/2} (\code{pCholesky}),
where \code{n=Dim[1]}, listing the entries of the Cholesky
factor \eqn{L} or its transpose \eqn{L'} in column-major
order.}
\item{\code{perm}}{a 1-based integer vector of length \code{Dim[1]}
specifying the permutation applied to the rows and columns
of the factorized matrix. \code{perm} of length 0 is valid and
equivalent to the identity permutation, implying no pivoting.}
}
}
\section{Extends}{
Class \code{\linkS4class{CholeskyFactorization}}, directly.
Class \code{\linkS4class{MatrixFactorization}}, by class
\code{\linkS4class{CholeskyFactorization}}, distance 2.
}
\section{Instantiation}{
Objects can be generated directly by calls of the form
\code{new("Cholesky", ...)} or \code{new("pCholesky", ...)},
but they are more typically obtained as the value of
\code{\link{Cholesky}(x)} for \code{x} inheriting from
\code{\linkS4class{dsyMatrix}} or \code{\linkS4class{dspMatrix}}
(often the subclasses of those reserved for positive
semidefinite matrices, namely \code{\linkS4class{dpoMatrix}}
and \code{\linkS4class{dppMatrix}}).
}
\section{Methods}{
\describe{
\item{\code{coerce}}{\code{signature(from = "Cholesky", to = "dtrMatrix")}:
returns a \code{\linkS4class{dtrMatrix}} representing
the Cholesky factor \eqn{L} or its transpose \eqn{L'};
see \sQuote{Note}.}
\item{\code{coerce}}{\code{signature(from = "pCholesky", to = "dtpMatrix")}:
returns a \code{\linkS4class{dtpMatrix}} representing
the Cholesky factor \eqn{L} or its transpose \eqn{L'};
see \sQuote{Note}.}
\item{\code{determinant}}{\code{signature(from = "p?Cholesky", logarithm = "logical")}:
computes the determinant of the factorized matrix \eqn{A}
or its logarithm.}
\item{\code{diag}}{\code{signature(x = "p?Cholesky")}:
returns a numeric vector of length \eqn{n} containing the diagonal
elements of \eqn{D}, which are the squared diagonal elements of
\eqn{L}.}
\item{\code{expand1}}{\code{signature(x = "p?Cholesky")}:
see \code{\link{expand1-methods}}.}
\item{\code{expand2}}{\code{signature(x = "p?Cholesky")}:
see \code{\link{expand2-methods}}.}
\item{\code{solve}}{\code{signature(a = "p?Cholesky", b = .)}:
see \code{\link{solve-methods}}.}
}
}
\note{
In \pkg{Matrix} \code{< 1.6-0}, class \code{Cholesky} extended
\code{\linkS4class{dtrMatrix}} and class \code{pCholesky} extended
\code{\linkS4class{dtpMatrix}}, reflecting the fact that the factor
\eqn{L} is indeed a triangular matrix.
\pkg{Matrix} \code{1.6-0} removed these extensions so that methods
would no longer be inherited from \code{dtrMatrix} and \code{dtpMatrix}.
The availability of such methods gave the wrong impression that
\code{Cholesky} and \code{pCholesky} represent a (singular)
matrix, when in fact they represent an ordered set of matrix factors.
The coercions \code{as(., "dtrMatrix")} and \code{as(., "dtpMatrix")}
are provided for users who understand the caveats.
}
\seealso{
Class \code{\linkS4class{CHMfactor}} for sparse Cholesky factorizations.
Classes \code{\linkS4class{dpoMatrix}} and \code{\linkS4class{dppMatrix}}.
Generic functions \code{\link{Cholesky}},
\code{\link{expand1}} and \code{\link{expand2}}.
}
\references{
The LAPACK source code, including documentation; see
\url{https://netlib.org/lapack/double/dpstrf.f},
\url{https://netlib.org/lapack/double/dpotrf.f}, and
\url{https://netlib.org/lapack/double/dpptrf.f}.
Lucas, C. (2004).
\emph{LAPACK-style codes for level 2 and 3 pivoted Cholesky factorizations}.
LAPACK Working Note, Number 161.
\url{https://www.netlib.org/lapack/lawnspdf/lawn161.pdf}
Golub, G. H., & Van Loan, C. F. (2013).
\emph{Matrix computations} (4th ed.).
Johns Hopkins University Press.
\doi{10.56021/9781421407944}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
library(utils, pos = "package:base", verbose = FALSE)
}
showClass("Cholesky")
set.seed(1)
m <- 30L
n <- 6L
(A <- crossprod(Matrix(rnorm(m * n), m, n)))
## With dimnames, to see that they are propagated :
dimnames(A) <- dn <- rep.int(list(paste0("x", seq_len(n))), 2L)
(ch.A <- Cholesky(A)) # pivoted, by default
str(e.ch.A <- expand2(ch.A, LDL = TRUE), max.level = 2L)
str(E.ch.A <- expand2(ch.A, LDL = FALSE), max.level = 2L)
## Underlying LAPACK representation
(m.ch.A <- as(ch.A, "dtrMatrix")) # which is L', not L, because
A@uplo == "U"
stopifnot(identical(as(m.ch.A, "matrix"), `dim<-`(ch.A@x, ch.A@Dim)))
ae1 <- function(a, b, ...) all.equal(as(a, "matrix"), as(b, "matrix"), ...)
ae2 <- function(a, b, ...) ae1(unname(a), unname(b), ...)
## A ~ P1' L1 D L1' P1 ~ P1' L L' P1 in floating point
stopifnot(exprs = {
identical(names(e.ch.A), c("P1.", "L1", "D", "L1.", "P1"))
identical(names(E.ch.A), c("P1.", "L" , "L." , "P1"))
identical(e.ch.A[["P1"]],
new("pMatrix", Dim = c(n, n), Dimnames = c(list(NULL), dn[2L]),
margin = 2L, perm = invertPerm(ch.A@perm)))
identical(e.ch.A[["P1."]], t(e.ch.A[["P1"]]))
identical(e.ch.A[["L1."]], t(e.ch.A[["L1"]]))
identical(E.ch.A[["L." ]], t(E.ch.A[["L" ]]))
identical(e.ch.A[["D"]], Diagonal(x = diag(ch.A)))
all.equal(E.ch.A[["L"]], with(e.ch.A, L1 \%*\% sqrt(D)))
ae1(A, with(e.ch.A, P1. \%*\% L1 \%*\% D \%*\% L1. \%*\% P1))
ae1(A, with(E.ch.A, P1. \%*\% L \%*\% L. \%*\% P1))
ae2(A[ch.A@perm, ch.A@perm], with(e.ch.A, L1 \%*\% D \%*\% L1.))
ae2(A[ch.A@perm, ch.A@perm], with(E.ch.A, L \%*\% L. ))
})
## Factorization handled as factorized matrix
b <- rnorm(n)
all.equal(det(A), det(ch.A), tolerance = 0)
all.equal(solve(A, b), solve(ch.A, b), tolerance = 0)
## For identical results, we need the _unpivoted_ factorization
## computed by det(A) and solve(A, b)
(ch.A.nopivot <- Cholesky(A, perm = FALSE))
stopifnot(identical(det(A), det(ch.A.nopivot)),
identical(solve(A, b), solve(ch.A.nopivot, b)))
}
Matrix/man/Matrix.Rd 0000644 0001751 0000144 00000011477 14446607050 014062 0 ustar hornik users \name{Matrix}
\title{Construct a Classed Matrix}
%
\keyword{array}
\keyword{utilities}
%
\alias{Matrix}
\description{
Construct a Matrix of a class that inherits from \code{Matrix}.
}
\usage{
Matrix(data=NA, nrow=1, ncol=1, byrow=FALSE, dimnames=NULL,
sparse = NULL, doDiag = TRUE, forceCheck = FALSE)
}
\arguments{
\item{data}{an optional numeric data vector or matrix.}
\item{nrow}{when \code{data} is not a matrix, the desired number of rows}
\item{ncol}{when \code{data} is not a matrix, the desired number of columns}
\item{byrow}{logical. If \code{FALSE} (the default) the matrix is
filled by columns, otherwise the matrix is filled by rows.}
\item{dimnames}{a \code{\link{dimnames}} attribute for the matrix: a
\code{list} of two character components. They are set if not
\code{\link{NULL}} (as per default).}
\item{sparse}{logical or \code{NULL}, specifying if the result should
be sparse or not. By default, it is made sparse when more than half
of the entries are 0.}
\item{doDiag}{logical indicating if a \code{\linkS4class{diagonalMatrix}}
object should be returned when the resulting matrix is diagonal
(\emph{mathematically}). As class \code{\linkS4class{diagonalMatrix}}
\code{\link{extends}} \code{\linkS4class{sparseMatrix}}, this is a
natural default for all values of \code{sparse}.
Otherwise, if \code{doDiag} is false, a dense or sparse (depending on
\code{sparse}) \emph{symmetric} matrix will be returned.}
% MJ: not quite ... if 'dimnames' is asymmetric then the result
% is a triangularMatrix, not a symmetricMatrix ...
\item{forceCheck}{logical indicating if the checks for structure
should even happen when \code{data} is already a \code{"Matrix"}
object.}
}
\value{
Returns matrix of a class that inherits from \code{"Matrix"}.
Only if \code{data} is not a \code{\link{matrix}} and does not already inherit
from class \code{\linkS4class{Matrix}} are the arguments
\code{nrow}, \code{ncol} and \code{byrow} made use of.
}
\details{
If either of \code{nrow} or \code{ncol} is not given, an attempt is
made to infer it from the length of \code{data} and the other
parameter.
Further, \code{Matrix()} makes efforts to keep \code{\link{logical}}
matrices logical, i.e., inheriting from class \code{\linkS4class{lMatrix}},
and to determine specially structured matrices such as symmetric,
triangular or diagonal ones. Note that a \emph{symmetric} matrix also
needs symmetric \code{\link{dimnames}}, e.g., by specifying
\code{dimnames = list(NULL,NULL)}, see the examples.
Most of the time, the function works via a traditional (\emph{full})
\code{\link{matrix}}. However, \code{Matrix(0, nrow,ncol)} directly
constructs an \dQuote{empty} \linkS4class{sparseMatrix}, as does
\code{Matrix(FALSE, *)}.
Although it is sometime possible to mix unclassed matrices (created
with \code{matrix}) with ones of class \code{"Matrix"}, it is much
safer to always use carefully constructed ones of class
\code{"Matrix"}.
}
\seealso{
The classes \code{\linkS4class{Matrix}},
\code{\linkS4class{symmetricMatrix}},
\code{\linkS4class{triangularMatrix}}, and
\code{\linkS4class{diagonalMatrix}}; further,
\code{\link{matrix}}.
Special matrices can be constructed, e.g., via
\code{\link{sparseMatrix}} (sparse), \code{\link{bdiag}}
(block-diagonal), \code{\link{bandSparse}} (banded sparse), or
\code{\link{Diagonal}}.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
Matrix(0, 3, 2) # 3 by 2 matrix of zeros -> sparse
Matrix(0, 3, 2, sparse=FALSE)# -> 'dense'
## 4 cases - 3 different results :
Matrix(0, 2, 2) # diagonal !
Matrix(0, 2, 2, sparse=FALSE)# (ditto)
Matrix(0, 2, 2, doDiag=FALSE)# -> sparse symm. "dsCMatrix"
Matrix(0, 2, 2, sparse=FALSE, doDiag=FALSE)# -> dense symm. "dsyMatrix"
Matrix(1:6, 3, 2) # a 3 by 2 matrix (+ integer warning)
Matrix(1:6 + 1, nrow=3)
## logical ones:
Matrix(diag(4) > 0) # -> "ldiMatrix" with diag = "U"
Matrix(diag(4) > 0, sparse=TRUE) # (ditto)
Matrix(diag(4) >= 0) # -> "lsyMatrix" (of all 'TRUE')
## triangular
l3 <- upper.tri(matrix(,3,3))
(M <- Matrix(l3)) # -> "ltCMatrix"
Matrix(! l3) # -> "ltrMatrix"
as(l3, "CsparseMatrix")# "lgCMatrix"
Matrix(1:9, nrow=3,
dimnames = list(c("a", "b", "c"), c("A", "B", "C")))
(I3 <- Matrix(diag(3)))# identity, i.e., unit "diagonalMatrix"
str(I3) # note 'diag = "U"' and the empty 'x' slot
(A <- cbind(a=c(2,1), b=1:2))# symmetric *apart* from dimnames
Matrix(A) # hence 'dgeMatrix'
(As <- Matrix(A, dimnames = list(NULL,NULL)))# -> symmetric
forceSymmetric(A) # also symmetric, w/ symm. dimnames
stopifnot(is(As, "symmetricMatrix"),
is(Matrix(0, 3,3), "sparseMatrix"),
is(Matrix(FALSE, 1,1), "sparseMatrix"))
}
Matrix/man/Matrix-notyet.Rd 0000644 0001751 0000144 00000001047 14575137654 015405 0 ustar hornik users \name{Matrix-notyet}
\title{Virtual Classes Not Yet Really Implemented and Used}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{Matrix-notyet}
%
\alias{iMatrix-class}
\alias{zMatrix-class}
%
\description{
\code{iMatrix} is the virtual class of all integer
(S4) matrices. It extends the \code{\linkS4class{Matrix}} class directly.
\code{zMatrix} is the virtual class of all \code{\link{complex}}
(S4) matrices. It extends the \code{\linkS4class{Matrix}} class directly.
}
\examples{
showClass("iMatrix")
showClass("zMatrix")
}
Matrix/man/bandSparse.Rd 0000644 0001751 0000144 00000007144 14446607050 014674 0 ustar hornik users \name{bandSparse}
\title{Construct Sparse Banded Matrix from (Sup-/Super-) Diagonals}
%
\keyword{array}
\keyword{utilities}
%
\alias{bandSparse}
%
\description{
Construct a sparse banded matrix by specifying its non-zero sup- and
super-diagonals.
}
\usage{
bandSparse(n, m = n, k, diagonals, symmetric = FALSE,
repr = "C", giveCsparse = (repr == "C"))
}
\arguments{
\item{n,m}{the matrix dimension \eqn{(n,m) = (nrow, ncol)}.}
\item{k}{integer vector of \dQuote{diagonal numbers}, with identical
meaning as in \code{\link{band}(*, k)}, i.e., relative to the main diagonal,
which is \code{k=0}.}
\item{diagonals}{optional list of sub-/super- diagonals; if missing,
the result will be a patter\bold{n} matrix, i.e., inheriting from
class \code{\linkS4class{nMatrix}}.
\code{diagonals} can also be \eqn{n' \times d}{n' x d} matrix, where
\code{d <- length(k)} and \eqn{n' >= min(n,m)}. In that case,
the sub-/super- diagonals are taken from the columns of
\code{diagonals}, where only the first several rows will be used
(typically) for off-diagonals.
}
\item{symmetric}{logical; if true the result will be symmetric
(inheriting from class \code{\linkS4class{symmetricMatrix}}) and
only the upper or lower triangle must be specified (via \code{k} and
\code{diagonals}).}
\item{repr}{\code{\link{character}} string, one of \code{"C"},
\code{"T"}, or \code{"R"}, specifying the sparse \emph{repr}esentation to
be used for the result, i.e., one from the super classes
\code{\linkS4class{CsparseMatrix}}, \code{\linkS4class{TsparseMatrix}}, or
\code{\linkS4class{RsparseMatrix}}.}
\item{giveCsparse}{(\bold{deprecated}, replaced with \code{repr}):
logical indicating if the result should be a
\code{\linkS4class{CsparseMatrix}} or a
\code{\linkS4class{TsparseMatrix}}, where the default was \code{TRUE},
and now is determined from \code{repr}; very often Csparse matrices are
more efficient subsequently, but not always.}
}
% \details{ __needed ?__
%
% }
\value{
a sparse matrix (of \code{\link{class}}
\code{\linkS4class{CsparseMatrix}}) of dimension \eqn{n \times m}{n x m}
with diagonal \dQuote{bands} as specified.
}
%\author{Martin Maechler}
\seealso{
\code{\link{band}}, for \emph{extraction} of matrix bands;
\code{\link{bdiag}}, \code{\link{diag}},
\code{\link{sparseMatrix}},
\code{\link{Matrix}}.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
}
diags <- list(1:30, 10*(1:20), 100*(1:20))
s1 <- bandSparse(13, k = -c(0:2, 6), diag = c(diags, diags[2]), symm=TRUE)
s1
s2 <- bandSparse(13, k = c(0:2, 6), diag = c(diags, diags[2]), symm=TRUE)
stopifnot(identical(s1, t(s2)), is(s1,"dsCMatrix"))
## a pattern Matrix of *full* (sub-)diagonals:
bk <- c(0:4, 7,9)
(s3 <- bandSparse(30, k = bk, symm = TRUE))
## If you want a pattern matrix, but with "sparse"-diagonals,
## you currently need to go via logical sparse:
lLis <- lapply(list(rpois(20, 2), rpois(20, 1), rpois(20, 3))[c(1:3, 2:3, 3:2)],
as.logical)
(s4 <- bandSparse(20, k = bk, symm = TRUE, diag = lLis))
(s4. <- as(drop0(s4), "nsparseMatrix"))
n <- 1e4
bk <- c(0:5, 7,11)
bMat <- matrix(1:8, n, 8, byrow=TRUE)
bLis <- as.data.frame(bMat)
B <- bandSparse(n, k = bk, diag = bLis)
Bs <- bandSparse(n, k = bk, diag = bLis, symmetric=TRUE)
B [1:15, 1:30]
Bs[1:15, 1:30]
## can use a list *or* a matrix for specifying the diagonals:
stopifnot(identical(B, bandSparse(n, k = bk, diag = bMat)),
identical(Bs, bandSparse(n, k = bk, diag = bMat, symmetric=TRUE))
, inherits(B, "dtCMatrix") # triangular!
)
}
Matrix/man/dtpMatrix-class.Rd 0000644 0001751 0000144 00000006342 14446607050 015670 0 ustar hornik users \name{dtpMatrix-class}
\title{Packed Triangular Dense Matrices - "dtpMatrix"}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{dtpMatrix-class}
%
\description{The \code{"dtpMatrix"} class is the class of triangular,
dense, numeric matrices in packed storage. The \code{"dtrMatrix"}
class is the same except in nonpacked storage.}
\section{Objects from the Class}{
Objects can be created by calls of the form \code{new("dtpMatrix",
...)} or by coercion from other classes of matrices.
}
\section{Slots}{
\describe{
\item{\code{uplo}:}{Object of class \code{"character"}. Must be
either "U", for upper triangular, and "L", for lower triangular.}
\item{\code{diag}:}{Object of class \code{"character"}. Must be
either \code{"U"}, for unit triangular (diagonal is all ones), or
\code{"N"}; see \code{\linkS4class{triangularMatrix}}.}
\item{\code{x}:}{Object of class \code{"numeric"}. The numeric
values that constitute the matrix, stored in column-major order.
For a packed square matrix of dimension \eqn{d \times d}{d * d},
\code{length(x)} is of length \eqn{d(d+1)/2} (also when
\code{diag == "U"}!).}
\item{\code{Dim},\code{Dimnames}:}{The dimension (a length-2
\code{"integer"}) and corresponding names (or \code{NULL}),
inherited from the \code{\linkS4class{Matrix}}, see there.}
}
}
\section{Extends}{
Class \code{"ddenseMatrix"}, directly.
Class \code{"triangularMatrix"}, directly.
Class \code{"dMatrix"} and more by class \code{"ddenseMatrix"} etc, see
the examples.
}
\section{Methods}{
\describe{
\item{\%*\%}{\code{signature(x = "dtpMatrix", y = "dgeMatrix")}:
Matrix multiplication; ditto for several other signature
combinations, see \code{showMethods("\%*\%", class = "dtpMatrix")}.}
\item{determinant}{\code{signature(x = "dtpMatrix", logarithm = "logical")}:
the \code{\link{determinant}(x)} trivially is
\code{prod(diag(x))}, but computed on log scale to prevent over-
and underflow.}
\item{diag}{\code{signature(x = "dtpMatrix")}: ... }
\item{norm}{\code{signature(x = "dtpMatrix", type = "character")}: ... }
\item{rcond}{\code{signature(x = "dtpMatrix", norm = "character")}: ... }
\item{solve}{\code{signature(a = "dtpMatrix", b = "...")}:
efficiently using internal backsolve or forwardsolve, see
\code{\link{solve-methods}}.}
\item{t}{\code{signature(x = "dtpMatrix")}: \code{t(x)} remains
a \code{"dtpMatrix"}, lower triangular if \code{x} is upper
triangular, and vice versa.}
}
}
\seealso{
Class \code{\linkS4class{dtrMatrix}}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
showClass("dtrMatrix")
example("dtrMatrix-class", echo=FALSE)
(p1 <- pack(T2))
str(p1)
(pp <- pack(T))
ip1 <- solve(p1)
stopifnot(length(p1@x) == 3, length(pp@x) == 3,
p1 @ uplo == T2 @ uplo, pp @ uplo == T @ uplo,
identical(t(pp), p1), identical(t(p1), pp),
all((l.d <- p1 - T2) == 0), is(l.d, "dtpMatrix"),
all((u.d <- pp - T ) == 0), is(u.d, "dtpMatrix"),
l.d@uplo == T2@uplo, u.d@uplo == T@uplo,
identical(t(ip1), solve(pp)), is(ip1, "dtpMatrix"),
all.equal(as(solve(p1,p1), "diagonalMatrix"), Diagonal(2)))
}
Matrix/man/sparseMatrix.Rd 0000644 0001751 0000144 00000024042 14446607050 015270 0 ustar hornik users \name{sparseMatrix}
\title{General Sparse Matrix Construction from Nonzero Entries}
%
\keyword{array}
\keyword{utilities}
%
\alias{sparseMatrix}
%
\description{
User-friendly construction of sparse matrices (inheriting from
virtual \code{\link{class}} \code{\linkS4class{CsparseMatrix}},
\code{\linkS4class{RsparseMatrix}}, or
\code{\linkS4class{TsparseMatrix}})
from the positions and values of their nonzero entries.
This interface is recommended over direct construction via
calls such as \code{\link{new}("..[CRT]Matrix", ...)}.
}
\usage{
sparseMatrix(i, j, p, x, dims, dimnames,
symmetric = FALSE, triangular = FALSE, index1 = TRUE,
repr = c("C", "R", "T"), giveCsparse,
check = TRUE, use.last.ij = FALSE)
}
\arguments{
\item{i,j}{integer vectors of equal length specifying the positions
(row and column indices) of the nonzero (or non-\code{TRUE}) entries
of the matrix. Note that, when \code{x} is non-missing, the
\eqn{x_k} corresponding to \emph{repeated} pairs \eqn{(i_k,j_k)}
are \emph{added}, for consistency with the definition of class
\code{\linkS4class{TsparseMatrix}}, unless \code{use.last.ij} is
\code{TRUE}, in which case only the \emph{last} such \eqn{x_k} is
used.}
\item{p}{integer vector of pointers, one for each column (or row),
to the initial (zero-based) index of elements in the column (or row).
Exactly one of \code{i}, \code{j}, and \code{p} must be missing.}
\item{x}{optional, typically nonzero values for the matrix entries.
If specified, then the length must equal that of \code{i}
(or \code{j}) or equal 1, in which case \code{x} is recycled as
necessary. If missing, then the result is a \bold{n}onzero pattern
matrix, i.e., inheriting from class \code{\linkS4class{nsparseMatrix}}.}
\item{dims}{optional length-2 integer vector of matrix dimensions.
If missing, then \code{!index1+c(max(i),max(j))} is used.}
\item{dimnames}{optional list of \code{\link{dimnames}}; if missing,
then \code{\link{NULL}} ones are used.}
\item{symmetric}{logical indicating if the resulting matrix should
be symmetric. In that case, \eqn{(i,j,p)} should specify only one
triangle (upper or lower).}
\item{triangular}{logical indicating if the resulting matrix should
be triangular. In that case, \eqn{(i,j,p)} should specify only one
triangle (upper or lower).}
\item{index1}{logical. If \code{TRUE} (the default), then \code{i}
and \code{j} are interpreted as 1-based indices, following the \R
convention. That is, counting of rows and columns starts at 1.
If \code{FALSE}, then they are interpreted as 0-based indices.}
\item{repr}{\code{\link{character}} string, one of \code{"C"},
\code{"R"}, and \code{"T"}, specifying the \bold{repr}esentation
of the sparse matrix result, i.e., specifying one of the virtual
classes \code{\linkS4class{CsparseMatrix}},
\code{\linkS4class{RsparseMatrix}}, and
\code{\linkS4class{TsparseMatrix}}.}
\item{giveCsparse}{(\bold{deprecated}, replaced by \code{repr})
logical indicating if the result should inherit from
\code{\linkS4class{CsparseMatrix}} or
\code{\linkS4class{TsparseMatrix}}.
Note that operations involving \code{CsparseMatrix} are very often
(but not always) more efficient.}
\item{check}{logical indicating whether to check that the result is
formally valid before returning. Do not set to \code{FALSE} unless
you know what you are doing!}
\item{use.last.ij}{logical indicating if, in the case of repeated
(duplicated) pairs \eqn{(i_k,j_k)}, only the last pair should be
used. \code{FALSE} (the default) is consistent with the definiton
of class \code{\linkS4class{TsparseMatrix}}.}
}
\value{
A sparse matrix, by default in compressed sparse column format and
(formally) without symmetric or triangular structure, i.e.,
by default inheriting from both \code{\linkS4class{CsparseMatrix}}
and \code{\linkS4class{generalMatrix}}.
}
\details{ % FIXME: quite a bit of repetition here (and below) ...
Exactly one of the arguments \code{i}, \code{j} and \code{p} must be
missing.
In typical usage, \code{p} is missing, \code{i} and \code{j} are
vectors of positive integers and \code{x} is a numeric vector. These
three vectors, which must have the same length, form the triplet
representation of the sparse matrix.
If \code{i} or \code{j} is missing then \code{p} must be a
non-decreasing integer vector whose first element is zero. It
provides the compressed, or \dQuote{pointer} representation of the row
or column indices, whichever is missing. The expanded form of \code{p},
\code{rep(seq_along(dp),dp)} where \code{dp <- diff(p)}, is used as
the (1-based) row or column indices.
You cannot set both \code{singular} and \code{triangular} to true;
rather use \code{\link{Diagonal}()} (or its alternatives, see there).
The values of \code{i}, \code{j}, \code{p} and \code{index1} are used
to create 1-based index vectors \code{i} and \code{j} from which a
\code{\linkS4class{TsparseMatrix}} is constructed, with numerical
values given by \code{x}, if non-missing. Note that in that case,
when some pairs \eqn{(i_k,j_k)} are repeated (aka
\dQuote{duplicated}), the corresponding \eqn{x_k} are \emph{added}, in
consistency with the definition of the
\code{\linkS4class{TsparseMatrix}} class, unless \code{use.last.ij}
is set to true.
By default, when \code{repr = "C"}, the \code{\linkS4class{CsparseMatrix}}
derived from this triplet form is returned, where \code{repr = "R"} now
allows to directly get an \code{\linkS4class{RsparseMatrix}} and
\code{repr = "T"} leaves the result as \code{\linkS4class{TsparseMatrix}}.
The reason for returning a \code{\linkS4class{CsparseMatrix}} object
instead of the triplet format by default is that the compressed column
form is easier to work with when performing matrix operations. In
particular, if there are no zeros in \code{x} then a
\code{\linkS4class{CsparseMatrix}} is a unique representation of the
sparse matrix.
}
\note{% We say so above (-> {index1}), but some do not read that
You \emph{do} need to use \code{index1 = FALSE} (or add \code{+ 1}
to \code{i} and \code{j}) if you want use the 0-based \code{i} (and
\code{j}) slots from existing sparse matrices.
}
\seealso{\code{\link{Matrix}(*, sparse=TRUE)} for the constructor of
such matrices from a \emph{dense} matrix. That is easier in small
sample, but much less efficient (or impossible) for large matrices,
where something like \code{sparseMatrix()} is needed.
Further \code{\link{bdiag}} and \code{\link{Diagonal}} for (block-)diagonal and
\code{\link{bandSparse}} for banded sparse matrix constructors.
Random sparse matrices via \code{\link{rsparsematrix}()}.
The standard \R \code{\link{xtabs}(*, sparse=TRUE)}, for sparse tables
and \code{\link{sparse.model.matrix}()} for building sparse model
matrices.
Consider \code{\linkS4class{CsparseMatrix}} and similar class
definition help files.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
## simple example
i <- c(1,3:8); j <- c(2,9,6:10); x <- 7 * (1:7)
(A <- sparseMatrix(i, j, x = x)) ## 8 x 10 "dgCMatrix"
summary(A)
str(A) # note that *internally* 0-based row indices are used
(sA <- sparseMatrix(i, j, x = x, symmetric = TRUE)) ## 10 x 10 "dsCMatrix"
(tA <- sparseMatrix(i, j, x = x, triangular= TRUE)) ## 10 x 10 "dtCMatrix"
stopifnot( all(sA == tA + t(tA)) ,
identical(sA, as(tA + t(tA), "symmetricMatrix")))
## dims can be larger than the maximum row or column indices
(AA <- sparseMatrix(c(1,3:8), c(2,9,6:10), x = 7 * (1:7), dims = c(10,20)))
summary(AA)
## i, j and x can be in an arbitrary order, as long as they are consistent
set.seed(1); (perm <- sample(1:7))
(A1 <- sparseMatrix(i[perm], j[perm], x = x[perm]))
stopifnot(identical(A, A1))
## The slots are 0-index based, so
try( sparseMatrix(i=A@i, p=A@p, x= seq_along(A@x)) )
## fails and you should say so: 1-indexing is FALSE:
sparseMatrix(i=A@i, p=A@p, x= seq_along(A@x), index1 = FALSE)
## the (i,j) pairs can be repeated, in which case the x's are summed
(args <- data.frame(i = c(i, 1), j = c(j, 2), x = c(x, 2)))
(Aa <- do.call(sparseMatrix, args))
## explicitly ask for elimination of such duplicates, so
## that the last one is used:
(A. <- do.call(sparseMatrix, c(args, list(use.last.ij = TRUE))))
stopifnot(Aa[1,2] == 9, # 2+7 == 9
A.[1,2] == 2) # 2 was *after* 7
## for a pattern matrix, of course there is no "summing":
(nA <- do.call(sparseMatrix, args[c("i","j")]))
dn <- list(LETTERS[1:3], letters[1:5])
## pointer vectors can be used, and the (i,x) slots are sorted if necessary:
m <- sparseMatrix(i = c(3,1, 3:2, 2:1), p= c(0:2, 4,4,6), x = 1:6, dimnames = dn)
m
str(m)
stopifnot(identical(dimnames(m), dn))
sparseMatrix(x = 2.72, i=1:3, j=2:4) # recycling x
sparseMatrix(x = TRUE, i=1:3, j=2:4) # recycling x, |--> "lgCMatrix"
## no 'x' --> patter*n* matrix:
(n <- sparseMatrix(i=1:6, j=rev(2:7)))# -> ngCMatrix
## an empty sparse matrix:
(e <- sparseMatrix(dims = c(4,6), i={}, j={}))
## a symmetric one:
(sy <- sparseMatrix(i= c(2,4,3:5), j= c(4,7:5,5), x = 1:5,
dims = c(7,7), symmetric=TRUE))
stopifnot(isSymmetric(sy),
identical(sy, ## switch i <-> j {and transpose }
t( sparseMatrix(j= c(2,4,3:5), i= c(4,7:5,5), x = 1:5,
dims = c(7,7), symmetric=TRUE))))
## rsparsematrix() calls sparseMatrix() :
M1 <- rsparsematrix(1000, 20, nnz = 200)
summary(M1)
## pointers example in converting from other sparse matrix representations.
if(requireNamespace("SparseM") &&
packageVersion("SparseM") >= "0.87" &&
nzchar(dfil <- system.file("extdata", "rua_32_ax.rua", package = "SparseM"))) {
X <- SparseM::model.matrix(SparseM::read.matrix.hb(dfil))
XX <- sparseMatrix(j = X@ja, p = X@ia - 1L, x = X@ra, dims = X@dimension)
validObject(XX)
## Alternatively, and even more user friendly :
X. <- as(X, "Matrix") # or also
X2 <- as(X, "sparseMatrix")
stopifnot(identical(XX, X.), identical(X., X2))
}% if
}% example
Matrix/man/coerce-methods-graph.Rd 0000644 0001751 0000144 00000007040 14575137654 016620 0 ustar hornik users \name{coerce-methods-graph}
\title{Conversions "graph" <--> (sparse) Matrix}
%
\docType{methods}
\keyword{methods}
\keyword{utilities}
%
\alias{coerce-methods-graph}
%
\alias{coerce,Matrix,graph-method}
\alias{coerce,Matrix,graphNEL-method}
\alias{coerce,TsparseMatrix,graphNEL-method}
\alias{coerce,graph,CsparseMatrix-method}
\alias{coerce,graph,Matrix-method}
\alias{coerce,graph,RsparseMatrix-method}
\alias{coerce,graph,TsparseMatrix-method}
\alias{coerce,graph,sparseMatrix-method}
\alias{coerce,graphAM,TsparseMatrix-method}
\alias{coerce,graphNEL,TsparseMatrix-method}
%
\alias{T2graph}
\alias{graph2T}
%
\description{
Since 2005, package \pkg{Matrix} has supported coercions to and
from class \code{\link[graph:graph-class]{graph}} from package
\href{https://bioconductor.org/packages/graph/}{\pkg{graph}}.
Since 2013, this functionality has been exposed via functions
\code{T2graph} and \code{graph2T}, which, unlike methods for
\code{\link{as}(from, "")}, support optional arguments.
}
\usage{
graph2T(from, use.weights = )
T2graph(from, need.uniq = !isUniqueT(from), edgemode = NULL)
}
\arguments{
\item{from}{for \code{graph2T()}, an \R object of class
\code{"graph"}; \cr
for \code{T2graph()}, a sparse matrix inheriting from
\code{"\linkS4class{TsparseMatrix}"}.}
\item{use.weights}{logical indicating if weights should be used, i.e.,
equivalently the result will be numeric, i.e. of class
\code{\linkS4class{dgTMatrix}}; otherwise the result will be
\code{\linkS4class{ngTMatrix}} or \code{\linkS4class{nsTMatrix}},
the latter if the graph is undirected. The default looks if there
are weights in the graph, and if any differ from \code{1}, weights
are used.}
\item{need.uniq}{a logical indicating if \code{from} may need to be
internally \dQuote{uniqified}; do not set this and hence rather use
the default, unless you know what you are doing!}
\item{edgemode}{one of \code{NULL}, \code{"directed"}, or
\code{"undirected"}. The default \code{NULL} looks if the matrix is
symmetric and assumes \code{"undirected"} in that case.}
}
\value{
For \code{graph2T()}, a sparse matrix inheriting from
\code{"\linkS4class{TsparseMatrix}"}.
For \code{T2graph()} an \R object of class \code{"graph"}.
}
\seealso{
Package \CRANpkg{igraph}, which provides similar coercions
to and from its class \code{igraph} via functions
\code{graph_from_adjacency_matrix} and \code{as_adjacency_matrix}.
}
\examples{
if(requireNamespace("graph")) {
n4 <- LETTERS[1:4]; dns <- list(n4,n4)
show(a1 <- sparseMatrix(i= c(1:4), j=c(2:4,1), x = 2, dimnames=dns))
show(g1 <- as(a1, "graph")) # directed
unlist(graph::edgeWeights(g1)) # all '2'
show(a2 <- sparseMatrix(i= c(1:4,4), j=c(2:4,1:2), x = TRUE, dimnames=dns))
show(g2 <- as(a2, "graph")) # directed
# now if you want it undirected:
show(g3 <- T2graph(as(a2,"TsparseMatrix"), edgemode="undirected"))
show(m3 <- as(g3,"Matrix"))
show( graph2T(g3) ) # a "pattern Matrix" (nsTMatrix)
\dontshow{
stopifnot(
identical(as(g3,"Matrix"), as(as(a2 + t(a2), "nMatrix"),"symmetricMatrix"))
,
identical(tg3 <- graph2T(g3), graph2T(g3, use.weights=FALSE))
,
identical(as(m3,"TsparseMatrix"), asUniqueT(tg3))
)
}
a. <- sparseMatrix(i=4:1, j=1:4, dimnames=list(n4, n4), repr="T") # no 'x'
show(a.) # "ngTMatrix"
show(g. <- as(a., "graph"))
\dontshow{
stopifnot(graph::edgemode(g.) == "undirected",
graph::numEdges(g.) == 2,
all.equal(as(g., "TsparseMatrix"),
as(a., "symmetricMatrix"))
)
}
}
}
Matrix/man/condest.Rd 0000644 0001751 0000144 00000010427 14521202214 014232 0 ustar hornik users \name{condest}
\title{Compute Approximate CONDition number and 1-Norm of (Large) Matrices}
%
\keyword{algebra}
\keyword{math}
\keyword{utilities}
%
\alias{condest}
\alias{onenormest}
%
\description{
\dQuote{Estimate}, i.e. compute approximately the CONDition number of
a (potentially large, often sparse) matrix \code{A}.
It works by apply a fast \emph{randomized} approximation of the 1-norm,
\code{norm(A,"1")}, through \code{onenormest(.)}.
}
\usage{
condest(A, t = min(n, 5), normA = norm(A, "1"),
silent = FALSE, quiet = TRUE)
onenormest(A, t = min(n, 5), A.x, At.x, n,
silent = FALSE, quiet = silent,
iter.max = 10, eps = 4 * .Machine$double.eps)
}
\arguments{
\item{A}{a square matrix, optional for \code{onenormest()}, where
instead of \code{A}, \code{A.x} and \code{At.x} can be specified,
see there.}
\item{t}{number of columns to use in the iterations.}
\item{normA}{number; (an estimate of) the 1-norm of \code{A}, by
default \code{\link{norm}(A, "1")}; may be replaced by an estimate.}
\item{silent}{logical indicating if warning and (by default)
convergence messages should be displayed.}
\item{quiet}{logical indicating if convergence messages should be
displayed.}
\item{A.x, At.x}{when \code{A} is missing, these two must be given as
functions which compute \code{A \%\% x}, or \code{t(A) \%\% x},
respectively.}
\item{n}{\code{ == nrow(A)}, only needed when \code{A} is not specified.}
\item{iter.max}{maximal number of iterations for the 1-norm estimator.}
\item{eps}{the relative change that is deemed irrelevant.}
}
\details{
\code{\link{condest}()} calls \code{\link{lu}(A)}, and subsequently
\code{onenormest(A.x = , At.x = )} to compute an approximate norm of
the \emph{inverse} of \code{A}, \eqn{A^{-1}}, in a way which
keeps using sparse matrices efficiently when \code{A} is sparse.
Note that \code{onenormest()} uses random vectors and hence
\emph{both} functions' results are random, i.e., depend on the random
seed, see, e.g., \code{\link{set.seed}()}.
}
\value{Both functions return a \code{\link{list}};
\code{condest()} with components,
\item{est}{a number \eqn{> 0}, the estimated (1-norm) condition number
\eqn{\hat\kappa}{k.}; when \eqn{r :=}\code{rcond(A)},
\eqn{1/\hat\kappa \approx r}{1/k. ~= r}.}
\item{v}{the maximal \eqn{A x} column, scaled to norm(v) = 1.
Consequently, \eqn{norm(A v) = norm(A) / est};
when \code{est} is large, \code{v} is an approximate null vector.}
The function \code{onenormest()} returns a list with components,
\item{est}{a number \eqn{> 0}, the estimated \code{norm(A, "1")}.}
\item{v}{0-1 integer vector length \code{n}, with an \code{1} at the index
\code{j} with maximal column \code{A[,j]} in \eqn{A}.}
\item{w}{numeric vector, the largest \eqn{A x} found.}
\item{iter}{the number of iterations used.}
}
\references{
%% See also Tim Davis(2006, p.96):
Nicholas J. Higham and \enc{Françoise}{Francoise} Tisseur (2000).
A Block Algorithm for Matrix 1-Norm Estimation, with an Application
to 1-Norm Pseudospectra.
\emph{SIAM J. Matrix Anal. Appl.} \bold{21}, 4, 1185--1201.
%% OK for ETH, etc., but not free: \doi{10.1137/S0895479899356080}
%% broken on 2022-10-20: \url{https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.7.9804}
William W. Hager (1984).
Condition Estimates.
\emph{SIAM J. Sci. Stat. Comput.} \bold{5}, 311--316.
}
\author{This is based on octave's \code{condest()} and
\code{onenormest()} implementations with original author
Jason Riedy, U Berkeley; translation to \R and
adaption by Martin Maechler.
}
\seealso{
\code{\link{norm}}, \code{\link{rcond}}.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
data(KNex, package = "Matrix")
mtm <- with(KNex, crossprod(mm))
system.time(ce <- condest(mtm))
sum(abs(ce$v)) ## || v ||_1 == 1
## Prove that || A v || = || A || / est (as ||v|| = 1):
stopifnot(all.equal(norm(mtm \%*\% ce$v),
norm(mtm) / ce$est))
## reciprocal
1 / ce$est
system.time(rc <- rcond(mtm)) # takes ca 3 x longer
rc
all.equal(rc, 1/ce$est) # TRUE -- the approximation was good
one <- onenormest(mtm)
str(one) ## est = 12.3
## the maximal column:
which(one$v == 1) # mostly 4, rarely 1, depending on random seed
}
Matrix/man/ngeMatrix-class.Rd 0000644 0001751 0000144 00000003160 14467516513 015653 0 ustar hornik users \name{ngeMatrix-class}
\title{Class "ngeMatrix" of General Dense Nonzero-pattern Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{ngeMatrix-class}
%
\alias{Arith,ngeMatrix,ngeMatrix-method}
\alias{Compare,ngeMatrix,ngeMatrix-method}
\alias{Logic,ngeMatrix,ngeMatrix-method}
%
\description{This is the class of general dense nonzero-pattern
matrices, see \code{\linkS4class{nMatrix}}.
}
\section{Slots}{
\describe{
\item{\code{x}:}{Object of class \code{"logical"}. The logical
values that constitute the matrix, stored in column-major order.}
\item{\code{Dim},\code{Dimnames}:}{The dimension (a length-2
\code{"integer"}) and corresponding names (or \code{NULL}), see the
\code{\linkS4class{Matrix}} class.}
\item{\code{factors}:}{Object of class \code{"list"}. A named
list of factorizations that have been computed for the matrix.}
}
}
\section{Extends}{
Class \code{"ndenseMatrix"}, directly.
Class \code{"lMatrix"}, by class \code{"ndenseMatrix"}.
Class \code{"denseMatrix"}, by class \code{"ndenseMatrix"}.
Class \code{"Matrix"}, by class \code{"ndenseMatrix"}.
Class \code{"Matrix"}, by class \code{"ndenseMatrix"}.
}
\section{Methods}{
Currently, mainly \code{\link{t}()} and coercion methods (for
\code{\link{as}(.)}); use, e.g.,
\code{\link{showMethods}(class="ngeMatrix")} for details.
}
\seealso{
Non-general logical dense matrix classes such as
\code{\linkS4class{ntrMatrix}}, or \code{\linkS4class{nsyMatrix}};
\emph{sparse} logical classes such as \code{\linkS4class{ngCMatrix}}.
}
\examples{
showClass("ngeMatrix")
## "lgeMatrix" is really more relevant
}
Matrix/man/isTriangular-methods.Rd 0000644 0001751 0000144 00000006014 14575137654 016725 0 ustar hornik users \name{isTriangular-methods}
\title{Test whether a Matrix is Triangular or Diagonal}
%
\docType{methods}
\keyword{array}
\keyword{programming}
\keyword{methods}
%
\alias{isTriangular}
\alias{isTriangular-methods}
\alias{isDiagonal}
\alias{isDiagonal-methods}
%
\alias{isTriangular,CsparseMatrix-method}
\alias{isTriangular,RsparseMatrix-method}
\alias{isTriangular,TsparseMatrix-method}
\alias{isTriangular,denseMatrix-method}
\alias{isTriangular,diagonalMatrix-method}
\alias{isTriangular,indMatrix-method}
\alias{isTriangular,matrix-method}
%
\alias{isDiagonal,CsparseMatrix-method}
\alias{isDiagonal,RsparseMatrix-method}
\alias{isDiagonal,TsparseMatrix-method}
\alias{isDiagonal,denseMatrix-method}
\alias{isDiagonal,diagonalMatrix-method}
\alias{isDiagonal,indMatrix-method}
\alias{isDiagonal,matrix-method}
%
\description{
\code{isTriangular} and \code{isDiagonal} test whether their argument
is a triangular or diagonal matrix, respectively. Unlike the analogous
\code{\link{isSymmetric}}, these two functions are generically
from \pkg{Matrix} rather than \code{base}. Hence \pkg{Matrix}
defines methods for traditional matrices of implicit \link{class}
\code{"\link{matrix}"} in addition to matrices inheriting from
virtual class \code{"\linkS4class{Matrix}"}.
By our definition, triangular and diagonal matrices are \emph{square},
i.e., they have the same number of rows and columns.
}
\usage{
isTriangular(object, upper = NA, \dots)
isDiagonal(object)
}
\arguments{
\item{object}{an \R object, typically a matrix.}
\item{upper}{a \link{logical}, either \code{TRUE} or \code{FALSE},
in which case \code{TRUE} is returned only for upper or lower
triangular \code{object}; or otherwise \code{\link{NA}} (the
default), in which case \code{TRUE} is returned for any triangular
\code{object}.}
\item{\dots}{further arguments passed to methods
(currently unused by \pkg{Matrix}).}
}
\value{
A \link{logical}, either \code{TRUE} or \code{FALSE}
(never \code{\link{NA}}).
If \code{object} is triangular and \code{upper} is \code{NA}, then
\code{isTriangular} returns \code{TRUE} with an \link[=attr]{attribute}
\code{kind}, either \code{"U"} or \code{"L"}, indicating that
\code{object} is \bold{u}pper or \bold{l}ower triangular, respectively.
Users should not rely on how \code{kind} is determined for diagonal
matrices, which are both upper and lower triangular.
}
\seealso{
\code{\link{isSymmetric}};
virtual classes \code{"\linkS4class{triangularMatrix}"} and
\code{"\linkS4class{diagonalMatrix}"} and their subclasses.
}
\examples{
isTriangular(Diagonal(4))
## is TRUE: a diagonal matrix is also (both upper and lower) triangular
(M <- Matrix(c(1,2,0,1), 2,2))
isTriangular(M) # TRUE (*and* of formal class "dtrMatrix")
isTriangular(as(M, "generalMatrix")) # still triangular, even if not "formally"
isTriangular(crossprod(M)) # FALSE
isDiagonal(matrix(c(2,0,0,1), 2,2)) # TRUE
## Look at implementations:
showMethods("isTriangular", includeDefs = TRUE)
showMethods("isDiagonal", includeDefs = TRUE)
}
Matrix/man/fastMisc.Rd 0000644 0001751 0000144 00000026245 14503343553 014365 0 ustar hornik users \name{fastMisc}
\title{\dQuote{Low Level} Coercions and Methods}
%
\keyword{utilities}
%
\alias{fastMisc}
% coercions:
\alias{.M2kind}
\alias{.M2gen}
\alias{.M2sym}
\alias{.M2tri}
\alias{.M2diag}
\alias{.M2v}
\alias{.M2m}
\alias{.M2unpacked}
\alias{.M2packed}
\alias{.M2C}
\alias{.M2R}
\alias{.M2T}
\alias{.M2V}
\alias{.m2V}
\alias{.sparse2dense}
\alias{.diag2dense}
\alias{.ind2dense}
\alias{.m2dense}
\alias{.dense2sparse}
\alias{.diag2sparse}
\alias{.ind2sparse}
\alias{.m2sparse}
\alias{.tCRT}
% coercions, predating API finalization, hence no longer documented:
\alias{.CR2RC}
\alias{.CR2T}
\alias{.T2CR}
\alias{.dense2g}
\alias{.dense2kind}
\alias{.dense2m}
\alias{.dense2v}
\alias{.sparse2g}
\alias{.sparse2kind}
\alias{.sparse2m}
\alias{.sparse2v}
\alias{.tCR2RC}
% other direct methods:
\alias{.diag.dsC}
\alias{.solve.dgC.lu}
\alias{.solve.dgC.qr}
\alias{.solve.dgC.chol}
\alias{.updateCHMfactor}
%
\description{
\dQuote{Semi-API} functions used internally by \pkg{Matrix},
often to bypass S4 dispatch and avoid the associated overhead.
These are exported to provide this capability to expert users.
Typical users should continue to rely on S4 generic functions
to dispatch suitable methods, by calling,
e.g., \code{as(., )} for coercions.
}
\usage{
.M2kind(from, kind = ".", sparse = NA)
.M2gen(from, kind = ".")
.M2sym(from, \dots)
.M2tri(from, \dots)
.M2diag(from)
.M2v(from)
.M2m(from)
.M2unpacked(from)
.M2packed(from)
.M2C(from)
.M2R(from)
.M2T(from)
.M2V(from)
.m2V(from, kind = ".")
.sparse2dense(from, packed = FALSE)
.diag2dense(from, kind = ".", shape = "t", packed = FALSE, uplo = "U")
.ind2dense(from, kind = "n")
.m2dense(from, class = ".ge", uplo = "U", diag = "N", trans = FALSE)
.dense2sparse(from, repr = "C")
.diag2sparse(from, kind = ".", shape = "t", repr = "C", uplo = "U")
.ind2sparse(from, kind = "n", repr = ".")
.m2sparse(from, class = ".gC", uplo = "U", diag = "N", trans = FALSE)
.tCRT(x, lazy = TRUE)
.diag.dsC(x, Chx = Cholesky(x, LDL = TRUE), res.kind = "diag")
.solve.dgC.lu (a, b, tol = .Machine$double.eps, check = TRUE)
.solve.dgC.qr (a, b, order = 3L, check = TRUE)
.solve.dgC.chol(a, b, check = TRUE)
.updateCHMfactor(object, parent, mult = 0)
}
\arguments{
\item{from, x, a, b}{a \code{\linkS4class{Matrix}}, matrix, or vector.}
\item{kind}{a string (\code{"."}, \code{","}, \code{"n"}, \code{"l"},
or \code{"d"}) specifying the \dQuote{kind} of the result.
\code{"."} indicates that the kind of \code{from} should be preserved.
\code{","} is equivalent to \code{"z"} if \code{from} is complex
and to \code{"d"} otherwise.
\code{"n"} indicates that the result should inherit from
\code{\linkS4class{nMatrix}} or \code{\linkS4class{nsparseVector}}
(and so on).}
\item{shape}{a string (\code{"."}, \code{"g"}, \code{"s"}, or
\code{"t"}) specifying the \dQuote{shape} of the result. \code{"."}
indicates that the shape of \code{from} should be preserved.
\code{"g"} indicates that the result should inherit from
\code{\linkS4class{generalMatrix}} (and so on).}
\item{repr}{a string (\code{"."}, \code{"C"}, \code{"R"}, or
\code{"T"}) specifying the sparse representation of the result.
\code{"."} is accepted only by \code{.ind2sparse} and indicates
the most efficient representation,
which is \code{"C"} (\code{"R"}) for \code{margin = 2} (\code{1}).
\code{"C"} indicates that the result should inherit from
\code{\linkS4class{CsparseMatrix}} (and so on).}
\item{packed}{a logical indicating if the result should
inherit from \code{\linkS4class{packedMatrix}}
rather than from \code{\linkS4class{unpackedMatrix}}.
It is ignored for \code{from} inheriting from
\code{\linkS4class{generalMatrix}}.}
\item{sparse}{a logical indicating if the result should inherit
from \code{\linkS4class{sparseMatrix}} rather than from
\code{\linkS4class{denseMatrix}}. If \code{NA}, then the result
will be formally sparse if and only if \code{from} is.}
\item{uplo}{a string (\code{"U"} or \code{"L"}) indicating whether
the result (if symmetric or triangular) should store the upper or
lower triangle of \code{from}. The elements of \code{from} in the
opposite triangle are ignored.}
\item{diag}{a string (\code{"N"} or \code{"U"}) indicating whether
the result (if triangular) should be formally nonunit or unit
triangular. In the unit triangular case, the diagonal elements
of \code{from} are ignored.}
\item{trans}{a logical indicating if the result should be a 1-row
matrix rather than a 1-column matrix where \code{from} is a vector
but not a matrix.}
\item{class}{a string whose first three characters specify the class
of the result. It should match the pattern
\code{"^[.nld](ge|sy|tr|sp|tp)"} for \code{.m2dense} and
\code{"^[.nld][gst][CRT]"} for \code{.m2sparse},
where \code{"."} in the first position is equivalent to \code{"l"}
for logical arguments and \code{"d"} for numeric arguments.}
\item{\dots}{optional arguments passed to \code{\link{isSymmetric}}
or \code{\link{isTriangular}}.}
%% .tCRT :
\item{lazy}{a logical indicating if the transpose should be
constructed with minimal allocation, but possibly \emph{without}
preserving representation.}
%% .diag.dsC :
\item{Chx}{optionally, the \code{\link{Cholesky}(x, \dots)}
factorization of \code{x}. If supplied, then \code{x} is unused.}
\item{res.kind}{a string in \code{c("trace", "sumLog", "prod", "min",
"max", "range", "diag", "diagBack")}.}
%% .solve.dgC.* :
\item{tol}{see \code{\link{lu-methods}}.}
\item{order}{see \code{\link{qr-methods}}.}
\item{check}{a logical indicating if the first argument should be
tested for inheritance from \code{\linkS4class{dgCMatrix}} and
coerced if necessary. Set to \code{FALSE} for speed only if it
is known to already inherit from \code{\linkS4class{dgCMatrix}}.}
%% .updateCHMfactor :
\item{object}{a Cholesky factorization inheriting from virtual class
\code{CHMfactor}, almost always the result of a call to generic
function \code{\link{Cholesky}}.}
\item{parent}{an object of class \code{\linkS4class{dsCMatrix}}
or class \code{\linkS4class{dgCMatrix}}.}
\item{mult}{a numeric vector of postive length. Only the first
element is used, and that must be finite.}
}
\details{
Functions with names of the form \code{.2} implement coercions
from virtual class A to the \dQuote{nearest} non-virtual subclass of
virtual class B, where the virtual classes are abbreviated as follows:
\describe{
\item{\code{M}}{\code{\linkS4class{Matrix}}}
\item{\code{V}}{\code{\linkS4class{sparseVector}}}
\item{\code{m}}{matrix}
\item{\code{v}}{vector}
\item{\code{dense}}{\code{\linkS4class{denseMatrix}}}
\item{\code{unpacked}}{\code{\linkS4class{unpackedMatrix}}}
\item{\code{packed}}{\code{\linkS4class{packedMatrix}}}
\item{\code{sparse}}{%
\code{\linkS4class{CsparseMatrix}},
\code{\linkS4class{RsparseMatrix}}, or
\code{\linkS4class{TsparseMatrix}}}
\item{\code{C}}{\code{\linkS4class{CsparseMatrix}}}
\item{\code{R}}{\code{\linkS4class{RsparseMatrix}}}
\item{\code{T}}{\code{\linkS4class{TsparseMatrix}}}
\item{\code{gen}}{\code{\linkS4class{generalMatrix}}}
\item{\code{sym}}{\code{\linkS4class{symmetricMatrix}}}
\item{\code{tri}}{\code{\linkS4class{triangularMatrix}}}
\item{\code{diag}}{\code{\linkS4class{diagonalMatrix}}}
\item{\code{ind}}{\code{\linkS4class{indMatrix}}}
}
Abbreviations should be seen as a guide, rather than as an
exact description of behaviour. Notably, \code{.m2dense},
\code{.m2sparse}, and \code{.m2V} accept vectors that are
not matrices.
\subsection{\code{.tCRT(x)}}{
If \code{lazy = TRUE}, then \code{.tCRT} constructs the transpose
of \code{x} using the most efficient representation,
which for \samp{CRT} is \samp{RCT}. If \code{lazy = FALSE},
then \code{.tCRT} preserves the representation of \code{x},
behaving as the corresponding methods for generic function \code{t}.
}
\subsection{\code{.diag.dsC(x)}}{
\code{.diag.dsC} computes (or uses if \code{Chx} is supplied)
the Cholesky factorization of \code{x} as \eqn{L D L'} in order
to calculate one of several possible statistics from the diagonal
entries of \eqn{D}. See \code{res.kind} under \sQuote{Arguments}.
}
\subsection{\code{.solve.dgC.*(a, b)}}{
\code{.solve.dgC.lu(a, b)} needs a square matrix \code{a}.
\code{.solve.dgC.qr(a, b)} needs a \dQuote{long} matrix \code{a},
with \code{nrow(a) >= ncol(a)}.
\code{.solve.dgC.chol(a, b)} needs a \dQuote{wide} matrix \code{a},
with \code{nrow(a) <= ncol(a)}.
All three may be used to solve sparse linear systems directly.
Only \code{.solve.dgC.qr} and \code{.solve.dgC.chol} be used
to solve sparse \emph{least squares} problems.
}
\subsection{\code{.updateCHMfactor(object, parent, mult)}}{
\code{.updateCHMfactor} updates \code{object} with the result
of Cholesky factorizing
\code{F(parent) + mult[1] * diag(nrow(parent))},
i.e., \code{F(parent)} plus \code{mult[1]} times the identity matrix,
where \code{F = identity} if \code{parent} is a \code{dsCMatrix}
and \code{F = tcrossprod} if \code{parent} is a \code{dgCMatrix}.
The nonzero pattern of \code{F(parent)} must match
that of \code{S} if \code{object = Cholesky(S, \dots)}.
}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
D. <- diag(x = c(1, 1, 2, 3, 5, 8))
D.0 <- Diagonal(x = c(0, 0, 0, 3, 5, 8))
S. <- toeplitz(as.double(1:6))
C. <- new("dgCMatrix", Dim = c(3L, 4L),
p = c(0L, 1L, 1L, 1L, 3L), i = c(1L, 0L, 2L), x = c(-8, 2, 3))
stopifnot(exprs = {
identical(.M2tri (D.), as(D., "triangularMatrix"))
identical(.M2sym (D.), as(D., "symmetricMatrix"))
identical(.M2diag(D.), as(D., "diagonalMatrix"))
identical(.M2kind(C., "l"),
as(C., "lMatrix"))
identical(.M2kind(.sparse2dense(C.), "l"),
as(as(C., "denseMatrix"), "lMatrix"))
identical(.diag2sparse(D.0, ".", "t", "C"),
.dense2sparse(.diag2dense(D.0, ".", "t", TRUE), "C"))
identical(.M2gen(.diag2dense(D.0, ".", "s", FALSE)),
.sparse2dense(.M2gen(.diag2sparse(D.0, ".", "s", "T"))))
identical(S.,
.M2m(.m2sparse(S., ".sR")))
identical(S. * lower.tri(S.) + diag(1, 6L),
.M2m(.m2dense (S., ".tr", "L", "U")))
identical(.M2R(C.), .M2R(.M2T(C.)))
identical(.tCRT(C.), .M2R(t(C.)))
})
A <- tcrossprod(C.)/6 + Diagonal(3, 1/3); A[1,2] <- 3; A
stopifnot(exprs = {
is.numeric( x. <- c(2.2, 0, -1.2) )
all.equal(x., .solve.dgC.lu(A, c(1,0,0), check=FALSE))
all.equal(x., .solve.dgC.qr(A, c(1,0,0), check=FALSE))
})
## Solving sparse least squares:
X <- rbind(A, Diagonal(3)) # design matrix X (for L.S.)
Xt <- t(X) # *transposed* X (for L.S.)
(y <- drop(crossprod(Xt, 1:3)) + c(-1,1)/1000) # small rand.err.
str(solveCh <- .solve.dgC.chol(Xt, y, check=FALSE)) # Xt *is* dgC..
stopifnot(exprs = {
all.equal(solveCh$coef, 1:3, tol = 1e-3)# rel.err ~ 1e-4
all.equal(solveCh$coef, drop(solve(tcrossprod(Xt), Xt \%*\% y)))
all.equal(solveCh$coef, .solve.dgC.qr(X, y, check=FALSE))
})
}
Matrix/man/BunchKaufman-methods.Rd 0000644 0001751 0000144 00000007357 14446607050 016623 0 ustar hornik users \name{BunchKaufman-methods}
\title{Methods for Bunch-Kaufman Factorization}
%
\docType{methods}
\keyword{algebra}
\keyword{array}
\keyword{methods}
%
\alias{BunchKaufman}
\alias{BunchKaufman-methods}
%
\alias{BunchKaufman,dspMatrix-method}
\alias{BunchKaufman,dsyMatrix-method}
\alias{BunchKaufman,matrix-method}
%
\description{
Computes the Bunch-Kaufman factorization of an \eqn{n \times n}{n-by-n}
real, symmetric matrix \eqn{A}, which has the general form
\deqn{A = U D_{U} U' = L D_{L} L'}{A = U * DU * U' = L * DL * L'}
where
\eqn{D_{U}}{DU} and \eqn{D_{L}}{DL} are symmetric, block diagonal
matrices composed of \eqn{b_{U}}{bU} and \eqn{b_{L}}{bL}
\eqn{1 \times 1}{1-by-1} or \eqn{2 \times 2}{2-by-2} diagonal blocks;
\eqn{U = \prod_{k = 1}^{b_{U}} P_{k} U_{k}}{U = prod(Pk * Uk : k = 1,...,bU)}
is the product of \eqn{b_{U}}{bU} row-permuted unit upper triangular
matrices, each having nonzero entries above the diagonal in 1 or 2 columns;
and
\eqn{L = \prod_{k = 1}^{b_{L}} P_{k} L_{k}}{L = prod(Pk * Lk : k = 1,...,bL)}
is the product of \eqn{b_{L}}{bL} row-permuted unit lower triangular
matrices, each having nonzero entries below the diagonal in 1 or 2 columns.
Methods are built on LAPACK routines \code{dsytrf} and \code{dsptrf}.
}
\usage{
BunchKaufman(x, \dots)
\S4method{BunchKaufman}{dsyMatrix}(x, warnSing = TRUE, \dots)
\S4method{BunchKaufman}{dspMatrix}(x, warnSing = TRUE, \dots)
\S4method{BunchKaufman}{matrix}(x, uplo = "U", \dots)
}
\arguments{
\item{x}{a \link[=is.finite]{finite} symmetric matrix or
\code{\linkS4class{Matrix}} to be factorized.
If \code{x} is square but not symmetric, then it will be
\emph{treated} as symmetric; see \code{uplo}.}
\item{warnSing}{a logical indicating if a \link{warning} should
be signaled for singular \code{x}.}
\item{uplo}{a string, either \code{"U"} or \code{"L"},
indicating which triangle of \code{x} should be used
to compute the factorization.}
\item{\dots}{further arguments passed to or from methods.}
}
\value{
An object representing the factorization, inheriting from
virtual class \code{\linkS4class{BunchKaufmanFactorization}}.
The specific class is \code{\linkS4class{BunchKaufman}} unless
\code{x} inherits from virtual class \code{\linkS4class{packedMatrix}},
in which case it is \code{\linkS4class{pBunchKaufman}}.
}
\seealso{
Classes \code{\linkS4class{BunchKaufman}} and
\code{\linkS4class{pBunchKaufman}} and their methods.
Classes \code{\linkS4class{dsyMatrix}} and
\code{\linkS4class{dspMatrix}}.
Generic functions \code{\link{expand1}} and \code{\link{expand2}},
for constructing matrix factors from the result.
Generic functions \code{\link{Cholesky}}, \code{\link{Schur}},
\code{\link{lu}}, and \code{\link{qr}},
for computing other factorizations.
}
\references{
The LAPACK source code, including documentation; see
\url{https://netlib.org/lapack/double/dsytrf.f} and
\url{https://netlib.org/lapack/double/dsptrf.f}.
Golub, G. H., & Van Loan, C. F. (2013).
\emph{Matrix computations} (4th ed.).
Johns Hopkins University Press.
\doi{10.56021/9781421407944}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
showMethods("BunchKaufman", inherited = FALSE)
set.seed(0)
data(CAex, package = "Matrix")
class(CAex) # dgCMatrix
isSymmetric(CAex) # symmetric, but not formally
A <- as(CAex, "symmetricMatrix")
class(A) # dsCMatrix
## Have methods for denseMatrix (unpacked and packed),
## but not yet sparseMatrix ...
\dontrun{
(bk.A <- BunchKaufman(A))
}
(bk.A <- BunchKaufman(as(A, "unpackedMatrix")))
## A ~ U DU U' in floating point
str(e.bk.A <- expand2(bk.A), max.level = 2L)
stopifnot(all.equal(as(A, "matrix"), as(Reduce(`\%*\%`, e.bk.A), "matrix")))
}
Matrix/man/symmetricMatrix-class.Rd 0000644 0001751 0000144 00000006773 14575137654 017140 0 ustar hornik users \name{symmetricMatrix-class}
\title{Virtual Class of Symmetric Matrices in Package Matrix}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{symmetricMatrix-class}
%
\alias{coerce,matrix,symmetricMatrix-method}
\alias{dimnames,symmetricMatrix-method}
\alias{dimnames<-,symmetricMatrix,NULL-method}
\alias{dimnames<-,symmetricMatrix,list-method}
%
\description{
The virtual class of symmetric matrices, \code{"symmetricMatrix"},
from the package \pkg{Matrix} contains numeric and logical, dense and
sparse matrices, e.g., see the examples with the \dQuote{actual}
subclasses.
The main use is in methods (and C functions) that can deal with
all symmetric matrices, and in \code{as(*, "symmetricMatrix")}.
}
% \section{Objects from the Class}{A virtual Class: No objects may be created from it.}
\section{Slots}{
\describe{
\item{\code{Dim, Dimnames}}{inherited from virtual class
\code{\linkS4class{Matrix}}. See comments below about
symmetry of \code{Dimnames}.}
\item{\code{factors}}{a list of
\code{\linkS4class{MatrixFactorization}} objects caching
factorizations of the matrix. Typically, it is initialized
as an empty list and updated \dQuote{automagically} whenever
a factorization is computed.}
\item{\code{uplo}}{a character string, either \code{"U"} or
\code{"L"} indicating that only entries in the upper or lower
triangle are referenced.}
}
}
\section{Extends}{
Class \code{"Matrix"}, directly.
}
\section{Methods}{
\describe{
\item{dimnames}{\code{signature(object = "symmetricMatrix")}:
returns \emph{symmetric} \code{\link{dimnames}}, even when the
\code{Dimnames} slot only has row or column names. This allows to
save storage for large (typically sparse) symmetric matrices.}
\item{isSymmetric}{\code{signature(object = "symmetricMatrix")}:
returns \code{TRUE} trivially.}
}
There's a C function \code{symmetricMatrix_validate()}% in ../src/dsyMatrix.c
called by the internal validity checking functions, and also from
\code{\link{getValidity}(getClass("symmetricMatrix"))}.
}
\section{Validity and \code{\link{dimnames}}}{
The validity checks do not require a symmetric \code{Dimnames} slot,
so it can be \code{list(NULL, )}, e.g., for efficiency.
However, \code{\link{dimnames}()} and other functions and methods
should behave as if the dimnames were symmetric, i.e., with both list
components identical.
}
\seealso{
\code{\link{isSymmetric}} which has efficient methods
(\link{isSymmetric-methods}) for the \pkg{Matrix} classes.
Classes \code{\linkS4class{triangularMatrix}}, and, e.g.,
\code{\linkS4class{dsyMatrix}} for numeric \emph{dense} matrices, or
\code{\linkS4class{lsCMatrix}} for a logical \emph{sparse} matrix class.
}
\examples{
## An example about the symmetric Dimnames:
sy <- sparseMatrix(i= c(2,4,3:5), j= c(4,7:5,5), x = 1:5, dims = c(7,7),
symmetric=TRUE, dimnames = list(NULL, letters[1:7]))
sy # shows symmetrical dimnames
sy@Dimnames # internally only one part is stored
dimnames(sy) # both parts - as sy *is* symmetrical
\dontshow{
local({ nm <- letters[1:7]
stopifnot(identical(dimnames(sy), list( nm, nm)),
identical(sy@Dimnames , list(NULL, nm)))
})
}%dont
showClass("symmetricMatrix")
## The names of direct subclasses:
scl <- getClass("symmetricMatrix")@subclasses
directly <- sapply(lapply(scl, slot, "by"), length) == 0
names(scl)[directly]
## Methods -- applicaple to all subclasses above:
showMethods(classes = "symmetricMatrix")
}
Matrix/man/ldiMatrix-class.Rd 0000644 0001751 0000144 00000007544 14500644730 015653 0 ustar hornik users \name{ldiMatrix-class}
\title{Class "ldiMatrix" of Diagonal Logical Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{ldiMatrix-class}
\alias{ndiMatrix-class} % for now
%
\alias{!,ldiMatrix-method}
\alias{\%\%,ldiMatrix,Matrix-method}
\alias{\%\%,ldiMatrix,ddenseMatrix-method}
\alias{\%\%,ldiMatrix,ldenseMatrix-method}
\alias{\%\%,ldiMatrix,ndenseMatrix-method}
\alias{\%/\%,ldiMatrix,Matrix-method}
\alias{\%/\%,ldiMatrix,ddenseMatrix-method}
\alias{\%/\%,ldiMatrix,ldenseMatrix-method}
\alias{\%/\%,ldiMatrix,ndenseMatrix-method}
\alias{&,ldiMatrix,Matrix-method}
\alias{&,ldiMatrix,ddenseMatrix-method}
\alias{&,ldiMatrix,ldenseMatrix-method}
\alias{&,ldiMatrix,ndenseMatrix-method}
\alias{*,ldiMatrix,Matrix-method}
\alias{*,ldiMatrix,ddenseMatrix-method}
\alias{*,ldiMatrix,ldenseMatrix-method}
\alias{*,ldiMatrix,ndenseMatrix-method}
\alias{/,ldiMatrix,Matrix-method}
\alias{/,ldiMatrix,ddenseMatrix-method}
\alias{/,ldiMatrix,ldenseMatrix-method}
\alias{/,ldiMatrix,ndenseMatrix-method}
\alias{Arith,ldiMatrix,logical-method}
\alias{Arith,ldiMatrix,numeric-method}
\alias{Arith,logical,ldiMatrix-method}
\alias{Arith,numeric,ldiMatrix-method}
\alias{Ops,ANY,ldiMatrix-method}
\alias{Ops,ldiMatrix,ANY-method}
\alias{Ops,ldiMatrix,Matrix-method}
\alias{Ops,ldiMatrix,dMatrix-method}
\alias{Ops,ldiMatrix,ddiMatrix-method}
\alias{Ops,ldiMatrix,ldiMatrix-method}
\alias{Ops,ldiMatrix,ndiMatrix-method}
\alias{Ops,ldiMatrix,logical-method}
\alias{Ops,ldiMatrix,numeric-method}
\alias{Ops,ldiMatrix,sparseMatrix-method}
\alias{which,ldiMatrix-method}
%
\alias{!,ndiMatrix-method}
\alias{\%\%,ndiMatrix,Matrix-method}
\alias{\%\%,ndiMatrix,ddenseMatrix-method}
\alias{\%\%,ndiMatrix,ldenseMatrix-method}
\alias{\%\%,ndiMatrix,ndenseMatrix-method}
\alias{\%/\%,ndiMatrix,Matrix-method}
\alias{\%/\%,ndiMatrix,ddenseMatrix-method}
\alias{\%/\%,ndiMatrix,ldenseMatrix-method}
\alias{\%/\%,ndiMatrix,ndenseMatrix-method}
\alias{&,ndiMatrix,Matrix-method}
\alias{&,ndiMatrix,ddenseMatrix-method}
\alias{&,ndiMatrix,ldenseMatrix-method}
\alias{&,ndiMatrix,ndenseMatrix-method}
\alias{*,ndiMatrix,Matrix-method}
\alias{*,ndiMatrix,Matrix-method}
\alias{*,ndiMatrix,ddenseMatrix-method}
\alias{*,ndiMatrix,ldenseMatrix-method}
\alias{*,ndiMatrix,ndenseMatrix-method}
\alias{/,ndiMatrix,Matrix-method}
\alias{/,ndiMatrix,ddenseMatrix-method}
\alias{/,ndiMatrix,ldenseMatrix-method}
\alias{/,ndiMatrix,ndenseMatrix-method}
\alias{Ops,ndiMatrix,ddiMatrix-method}
\alias{Ops,ndiMatrix,ldiMatrix-method}
\alias{Ops,ndiMatrix,ndiMatrix-method}
\alias{which,ndiMatrix-method}
%
\description{The class \code{"ldiMatrix"} of logical diagonal matrices.
%% FIXME add more
}
\section{Objects from the Class}{
Objects can be created by calls of the form \code{new("ldiMatrix", ...)}
but typically rather via \code{\link{Diagonal}}.
}
\section{Slots}{
\describe{
\item{\code{x}:}{\code{"logical"} vector.}
\item{\code{diag}:}{\code{"character"} string, either "U" or "N",
see \code{\linkS4class{ddiMatrix}}.}
\item{\code{Dim},\code{Dimnames}:}{matrix dimension and
\code{\link{dimnames}}, see the \code{\linkS4class{Matrix}} class
description.}
}
}
\section{Extends}{
Class \code{"\linkS4class{diagonalMatrix}"} and
class \code{"\linkS4class{lMatrix}"}, directly.
Class \code{"\linkS4class{sparseMatrix}"}, by class \code{"diagonalMatrix"}.
}
% \section{Methods}{
% No methods defined with class "ldiMatrix" in the signature.
% }
% \references{ ~put references to the literature/web site here ~ }
\seealso{
Classes \code{\linkS4class{ddiMatrix}} and
\code{\linkS4class{diagonalMatrix}}; function \code{\link{Diagonal}}.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
(lM <- Diagonal(x = c(TRUE,FALSE,FALSE)))
str(lM)#> gory details (slots)
crossprod(lM) # numeric
(nM <- as(lM, "nMatrix"))
crossprod(nM) # pattern sparse
}
Matrix/man/lsparseMatrix-class.Rd 0000644 0001751 0000144 00000015154 14575324114 016553 0 ustar hornik users \name{lsparseMatrix-class}
\title{Sparse logical matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{lsparseMatrix-class}
\alias{lsparseMatrix-classes} % used by package 'enhancerHomologSearch'
\alias{lgCMatrix-class}
\alias{lgRMatrix-class}
\alias{lgTMatrix-class}
\alias{ltCMatrix-class}
\alias{ltRMatrix-class}
\alias{ltTMatrix-class}
\alias{lsCMatrix-class}
\alias{lsRMatrix-class}
\alias{lsTMatrix-class}
% lsparse
\alias{!,lsparseMatrix-method}
\alias{Arith,lsparseMatrix,Matrix-method}
\alias{Logic,lsparseMatrix,ldenseMatrix-method}
\alias{Logic,lsparseMatrix,lsparseMatrix-method}
\alias{Ops,lsparseMatrix,lsparseMatrix-method}
\alias{Ops,lsparseMatrix,nsparseMatrix-method}
\alias{coerce,matrix,lsparseMatrix-method}
\alias{coerce,vector,lsparseMatrix-method}
\alias{which,lsparseMatrix-method}
% lgC
\alias{Arith,lgCMatrix,lgCMatrix-method}
\alias{Logic,lgCMatrix,lgCMatrix-method}
% lgR
% lgT
\alias{Arith,lgTMatrix,lgTMatrix-method}
\alias{Logic,lgTMatrix,lgTMatrix-method}
% ltC
\alias{Logic,ltCMatrix,ltCMatrix-method}
% ltR
% ltT
% lsC
\alias{Logic,lsCMatrix,lsCMatrix-method}
% lsR
% lsT
%
\description{The \code{lsparseMatrix} class is a virtual class
of logical sparse matrices, i.e., sparse matrices with entries
\code{TRUE}, \code{FALSE}, or \code{NA}.
These can be stored in the \dQuote{triplet} form (class
\code{\linkS4class{TsparseMatrix}}, subclasses \code{lgTMatrix},
\code{lsTMatrix}, and \code{ltTMatrix}) or in compressed
column-oriented form (class \code{\linkS4class{CsparseMatrix}},
subclasses \code{lgCMatrix}, \code{lsCMatrix}, and \code{ltCMatrix})
or--\emph{rarely}--in compressed row-oriented form (class
\code{\linkS4class{RsparseMatrix}}, subclasses \code{lgRMatrix},
\code{lsRMatrix}, and \code{ltRMatrix}). The second letter in the
name of these non-virtual classes indicates \code{g}eneral,
\code{s}ymmetric, or \code{t}riangular.
}
\section{Objects from the Class}{
Objects can be created by calls of the form \code{new("lgCMatrix",
...)} and so on. More frequently objects are created by coercion of
a numeric sparse matrix to the logical form, e.g. in an expression
\code{x != 0}.
The logical form is also used in the symbolic analysis phase
of an algorithm involving sparse matrices. Such algorithms often
involve two phases: a symbolic phase wherein the positions of the
non-zeros in the result are determined and a numeric phase wherein the
actual results are calculated. During the symbolic phase only the
positions of the non-zero elements in any operands are of interest,
hence any numeric sparse matrices can be treated as logical sparse
matrices.
}
\details{
Note that triplet stored (\code{\linkS4class{TsparseMatrix}}) matrices
such as \code{lgTMatrix} may contain duplicated pairs of indices
\eqn{(i,j)} as for the corresponding numeric class
\code{\linkS4class{dgTMatrix}} where for such pairs, the corresponding
\code{x} slot entries are added. For logical matrices, the \code{x}
entries corresponding to duplicated index pairs \eqn{(i,j)} are
\dQuote{added} as well if the addition is defined as logical \eqn{or},
i.e., \dQuote{\code{TRUE + TRUE |-> TRUE}} and
\dQuote{\code{TRUE + FALSE |-> TRUE}}.
Note the use of \code{\link{asUniqueT}()} for getting an internally
unique representation without duplicated \eqn{(i,j)} entries.
}
\section{Slots}{
\describe{
\item{\code{x}:}{Object of class \code{"logical"}, i.e., either
\code{TRUE}, \code{\link{NA}}, or \code{FALSE}.}
\item{\code{uplo}:}{Object of class \code{"character"}. Must be
either "U", for upper triangular, and "L", for lower
triangular. Present in the triangular and symmetric classes but not
in the general class.}
\item{\code{diag}:}{Object of class \code{"character"}. Must be
either \code{"U"}, for unit triangular (diagonal is all ones), or
\code{"N"} for non-unit. The implicit diagonal elements are not
explicitly stored when \code{diag} is \code{"U"}. Present in the
triangular classes only.}
\item{\code{p}:}{Object of class \code{"integer"} of pointers, one
for each column (row), to the initial (zero-based) index of elements in
the column. Present in compressed column-oriented and compressed
row-oriented forms only.}
\item{\code{i}:}{Object of class \code{"integer"} of length nnzero
(number of non-zero elements). These are the row numbers for
each TRUE element in the matrix. All other elements are FALSE.
Present in triplet and compressed column-oriented forms only.}
\item{\code{j}:}{Object of class \code{"integer"} of length nnzero
(number of non-zero elements). These are the column numbers for
each TRUE element in the matrix. All other elements are FALSE.
Present in triplet and compressed row-oriented forms only.}
\item{\code{Dim}:}{Object of class \code{"integer"} - the dimensions
of the matrix.}
}
}
\section{Methods}{
\describe{
\item{coerce}{\code{signature(from = "dgCMatrix", to = "lgCMatrix")}}
\item{t}{\code{signature(x = "lgCMatrix")}: returns the transpose
of \code{x}}
\item{which}{\code{signature(x = "lsparseMatrix")}, semantically
equivalent to \pkg{base} function \code{\link{which}(x, arr.ind)};
for details, see the \code{\linkS4class{lMatrix}} class documentation.}
}
}
\seealso{
the class \code{\linkS4class{dgCMatrix}} and \code{\linkS4class{dgTMatrix}}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
(m <- Matrix(c(0,0,2:0), 3,5, dimnames=list(LETTERS[1:3],NULL)))
(lm <- (m > 1)) # lgC
!lm # no longer sparse
stopifnot(is(lm,"lsparseMatrix"),
identical(!lm, m <= 1))
data(KNex, package = "Matrix")
str(mmG.1 <- (KNex $ mm) > 0.1)# "lgC..."
table(mmG.1@x)# however with many ``non-structural zeros''
## from logical to nz_pattern -- okay when there are no NA's :
nmG.1 <- as(mmG.1, "nMatrix") # <<< has "TRUE" also where mmG.1 had FALSE
## from logical to "double"
dmG.1 <- as(mmG.1, "dMatrix") # has '0' and back:
lmG.1 <- as(dmG.1, "lMatrix")
stopifnot(identical(nmG.1, as((KNex $ mm) != 0,"nMatrix")),
validObject(lmG.1),
identical(lmG.1, mmG.1))
class(xnx <- crossprod(nmG.1))# "nsC.."
class(xlx <- crossprod(mmG.1))# "dsC.." : numeric
is0 <- (xlx == 0)
mean(as.vector(is0))# 99.3\% zeros: quite sparse, but
table(xlx@x == 0)# more than half of the entries are (non-structural!) 0
stopifnot(isSymmetric(xlx), isSymmetric(xnx),
## compare xnx and xlx : have the *same* non-structural 0s :
sapply(slotNames(xnx),
function(n) identical(slot(xnx, n), slot(xlx, n))))
}
Matrix/man/expand-methods.Rd 0000644 0001751 0000144 00000023643 14575137654 015547 0 ustar hornik users \name{expand-methods}
\title{Expand Matrix Factorizations}
%
\docType{methods}
\keyword{algebra}
\keyword{array}
\keyword{methods}
%
\alias{expand}
\alias{expand-methods}
\alias{expand1}
\alias{expand1-methods}
\alias{expand2}
\alias{expand2-methods}
%
\alias{expand,CHMfactor-method}
\alias{expand,denseLU-method}
\alias{expand,sparseLU-method}
%
\alias{expand1,BunchKaufman-method}
\alias{expand1,CHMsimpl-method}
\alias{expand1,CHMsuper-method}
\alias{expand1,Cholesky-method}
\alias{expand1,Schur-method}
\alias{expand1,denseLU-method}
\alias{expand1,pBunchKaufman-method}
\alias{expand1,pCholesky-method}
\alias{expand1,sparseLU-method}
\alias{expand1,sparseQR-method}
%
\alias{expand2,BunchKaufman-method}
\alias{expand2,CHMsimpl-method}
\alias{expand2,CHMsuper-method}
\alias{expand2,Cholesky-method}
\alias{expand2,Schur-method}
\alias{expand2,denseLU-method}
\alias{expand2,pBunchKaufman-method}
\alias{expand2,pCholesky-method}
\alias{expand2,sparseLU-method}
\alias{expand2,sparseQR-method}
%
\description{
\code{expand1} and \code{expand2} construct matrix factors from
objects specifying matrix factorizations. Such objects typically
do not store the factors explicitly, employing instead a compact
representation to save memory.
}
\usage{
expand1(x, which, \dots)
expand2(x, \dots)
expand (x, \dots)
}
\arguments{
\item{x}{a matrix factorization, typically inheriting from
virtual class \code{\linkS4class{MatrixFactorization}}.}
\item{which}{a character string indicating a matrix factor.}
\item{\dots}{further arguments passed to or from methods.}
}
\value{
\code{expand1} returns an object inheriting from virtual class
\code{\linkS4class{Matrix}}, representing the factor indicated
by \code{which}, always without row and column names.
\code{expand2} returns a list of factors, typically with names
using conventional notation, as in \code{list(L=, U=)}.
The first and last factors get the row and column names of the
factorized matrix, which are preserved in the \code{Dimnames}
slot of \code{x}.
}
\details{
Methods for \code{expand} are retained only for backwards
compatibility with \pkg{Matrix} \code{< 1.6-0}. New code
should use \code{expand1} and \code{expand2}, whose methods
provide more control and behave more consistently. Notably,
\code{expand2} obeys the rule that the product of the matrix
factors in the returned list should reproduce
(within some tolerance) the factorized matrix,
\emph{including} its \code{dimnames}.
Hence if \code{x} is a matrix and \code{y} is its factorization,
then
\preformatted{ all.equal(as(x, "matrix"), as(Reduce(`\%*\%`, expand2(y)), "matrix"))}
should in most cases return \code{TRUE}.
}
\section{Methods}{
The following table lists methods for \code{expand1} together with
allowed values of argument \code{which}.
\tabular{rl}{
\code{class(x)} \tab \code{which}\cr
\code{\linkS4class{Schur}} \tab \code{c("Q", "T", "Q.")}\cr
\code{\linkS4class{denseLU}} \tab \code{c("P1", "P1.", "L", "U")}\cr
\code{\linkS4class{sparseLU}} \tab \code{c("P1", "P1.", "P2", "P2.", "L", "U")}\cr
\code{\linkS4class{sparseQR}} \tab \code{c("P1", "P1.", "P2", "P2.", "Q", "Q1", "R", "R1")}\cr
\code{\linkS4class{BunchKaufman}}, \code{\linkS4class{pBunchKaufman}} \tab \code{c("U", "DU", "U.", "L", "DL", "L.")}\cr
\code{\linkS4class{Cholesky}}, \code{\linkS4class{pCholesky}} \tab \code{c("P1", "P1.", "L1", "D", "L1.", "L", "L.")}\cr
\code{\linkS4class{CHMsimpl}}, \code{\linkS4class{CHMsimpl}} \tab \code{c("P1", "P1.", "L1", "D", "L1.", "L", "L.")}
}
Methods for \code{expand2} and \code{expand} are described
below. Factor names and classes apply also to \code{expand1}.
\describe{
\item{\code{expand2}}{\code{signature(x = "CHMsimpl")}:
expands the factorization
\eqn{A = P_{1}' L_{1} D L_{1}' P_{1} = P_{1}' L L' P_{1}}{A = P1' * L1 * D * L1' * P1 = P1' * L * L' * P1}
as \code{list(P1., L1, D, L1., P1)} (the default)
or as \code{list(P1., L, L., P1)},
depending on optional logical argument \code{LDL}.
\code{P1} and \code{P1.} are \code{\linkS4class{pMatrix}},
\code{L1}, \code{L1.}, \code{L}, and \code{L.} are
\code{\linkS4class{dtCMatrix}},
and \code{D} is a \code{\linkS4class{ddiMatrix}}.}
\item{\code{expand2}}{\code{signature(x = "CHMsuper")}:
as \code{CHMsimpl}, but the triangular factors are
stored as \code{\linkS4class{dgCMatrix}}.}
\item{\code{expand2}}{\code{signature(x = "p?Cholesky")}:
expands the factorization
\eqn{A = L_{1} D L_{1}' = L L'}{A = L1 * D * L1' = L * L'}
as \code{list(L1, D, L1.)} (the default) or as \code{list(L, L.)},
depending on optional logical argument \code{LDL}.
\code{L1}, \code{L1.}, \code{L}, and \code{L.} are
\code{\linkS4class{dtrMatrix}} or \code{\linkS4class{dtpMatrix}},
and \code{D} is a \code{\linkS4class{ddiMatrix}}.}
\item{\code{expand2}}{\code{signature(x = "p?BunchKaufman")}:
expands the factorization
\eqn{A = U D_{U} U' = L D_{L} L'}{A = U * DU * U' = L * DL * L'}
where
\eqn{U = \prod_{k = 1}^{b_{U}} P_{k} U_{k}}{U = prod(Pk * Uk : k = 1,...,bU)}
and
\eqn{L = \prod_{k = 1}^{b_{L}} P_{k} L_{k}}{L = prod(Pk * Lk : k = 1,...,bL)}
as \code{list(U, DU, U.)} or \code{list(L, DL, L.)},
depending on \code{x@uplo}. If optional argument \code{complete}
is \code{TRUE}, then an unnamed list giving the full expansion
with \eqn{2 b_{U} + 1}{2*bU+1} or \eqn{2 b_{L} + 1}{2*bL+1} matrix
factors is returned instead.
\eqn{P_{k}}{Pk} are represented as \code{\linkS4class{pMatrix}},
\eqn{U_{k}}{Uk} and \eqn{L_{k}}{Lk} are represented as
\code{\linkS4class{dtCMatrix}}, and
\eqn{D_{U}}{DU} and \eqn{D_{L}}{DL} are represented as
\code{\linkS4class{dsCMatrix}}.}
\item{\code{expand2}}{\code{signature(x = "Schur")}:
expands the factorization
\eqn{A = Q T Q'}{A = Q * T * Q'}
as \code{list(Q, T, Q.)}.
\code{Q} and \code{Q.} are \code{x@Q} and \code{t(x@Q)}
modulo \code{Dimnames}, and \code{T} is \code{x@T}.}
\item{\code{expand2}}{\code{signature(x = "sparseLU")}:
expands the factorization
\eqn{A = P_{1}' L U P_{2}'}{A = P1' * L * U * P2'}
as \code{list(P1., L, U, P2.)}.
\code{P1.} and \code{P2.} are \code{\linkS4class{pMatrix}},
and \code{L} and \code{U} are \code{\linkS4class{dtCMatrix}}.}
\item{\code{expand2}}{\code{signature(x = "denseLU")}:
expands the factorization
\eqn{A = P_{1}' L U}{A = P1' * L * U}
as \code{list(P1., L, U)}.
\code{P1.} is a \code{\linkS4class{pMatrix}},
and \code{L} and \code{U} are \code{\linkS4class{dtrMatrix}}
if square and \code{\linkS4class{dgeMatrix}} otherwise.}
\item{\code{expand2}}{\code{signature(x = "sparseQR")}:
expands the factorization
\eqn{A = P_{1}' Q R P_{2}' = P_{1}' Q_{1} R_{1} P_{2}'}{A = P1' * Q * R * P2' = P1' * Q1 * R1 * P2'}
as \code{list(P1., Q, R, P2.)} or \code{list(P1., Q1, R1, P2.)},
depending on optional logical argument \code{complete}.
\code{P1.} and \code{P2.} are \code{\linkS4class{pMatrix}},
\code{Q} and \code{Q1} are \code{\linkS4class{dgeMatrix}},
\code{R} is a \code{\linkS4class{dgCMatrix}},
and \code{R1} is a \code{\linkS4class{dtCMatrix}}.}
\item{\code{expand}}{\code{signature(x = "CHMfactor")}:
as \code{expand2}, but returning \code{list(P, L)}.
\code{expand(x)[["P"]]} and \code{expand2(x)[["P1"]]}
represent the same permutation matrix \eqn{P_{1}}{P1}
but have opposite \code{margin} slots and inverted
\code{perm} slots. The components of \code{expand(x)}
do not preserve \code{x@Dimnames}.}
\item{\code{expand}}{\code{signature(x = "sparseLU")}:
as \code{expand2}, but returning \code{list(P, L, U, Q)}.
\code{expand(x)[["Q"]]} and \code{expand2(x)[["P2."]]}
represent the same permutation matrix \eqn{P_{2}'}{P2'}
but have opposite \code{margin} slots and inverted
\code{perm} slots. \code{expand(x)[["P"]]} represents
the permutation matrix \eqn{P_{1}}{P1} rather than its
transpose \eqn{P_{1}'}{P1'}; it is \code{expand2(x)[["P1."]]}
with an inverted \code{perm} slot. \code{expand(x)[["L"]]}
and \code{expand2(x)[["L"]]} represent the same unit lower
triangular matrix \eqn{L}, but with \code{diag} slot equal
to \code{"N"} and \code{"U"}, respectively.
\code{expand(x)[["L"]]} and \code{expand(x)[["U"]]}
store the \emph{permuted} first and second components of
\code{x@Dimnames} in their \code{Dimnames} slots.}
\item{\code{expand}}{\code{signature(x = "denseLU")}:
as \code{expand2}, but returning \code{list(L, U, P)}.
\code{expand(x)[["P"]]} and \code{expand2(x)[["P1."]]}
are identical modulo \code{Dimnames}. The components
of \code{expand(x)} do not preserve \code{x@Dimnames}.}
}
}
\seealso{
The virtual class \code{\linkS4class{MatrixFactorization}}
of matrix factorizations.
Generic functions \code{\link{Cholesky}}, \code{\link{BunchKaufman}},
\code{\link{Schur}}, \code{\link{lu}}, and \code{\link{qr}} for
\emph{computing} factorizations.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
}
showMethods("expand1", inherited = FALSE)
showMethods("expand2", inherited = FALSE)
set.seed(0)
(A <- Matrix(rnorm(9L, 0, 10), 3L, 3L))
(lu.A <- lu(A))
(e.lu.A <- expand2(lu.A))
stopifnot(exprs = {
is.list(e.lu.A)
identical(names(e.lu.A), c("P1.", "L", "U"))
all(sapply(e.lu.A, is, "Matrix"))
all.equal(as(A, "matrix"), as(Reduce(`\%*\%`, e.lu.A), "matrix"))
})
## 'expand1' and 'expand2' give equivalent results modulo
## dimnames and representation of permutation matrices;
## see also function 'alt' in example("Cholesky-methods")
(a1 <- sapply(names(e.lu.A), expand1, x = lu.A, simplify = FALSE))
all.equal(a1, e.lu.A)
## see help("denseLU-class") and others for more examples
}
Matrix/man/sparseVector.Rd 0000644 0001751 0000144 00000003125 14446607050 015265 0 ustar hornik users \name{sparseVector}
\title{Sparse Vector Construction from Nonzero Entries}
%
\keyword{utilities}
%
\alias{sparseVector}
%
\description{
User friendly construction of sparse vectors,
i.e., objects inheriting from \code{\link{class}}
\code{\linkS4class{sparseVector}}, from indices and values of its
non-zero entries.
}
\details{
zero entries in \code{x} are dropped automatically, analogously as
\code{\link{drop0}()} acts on sparse matrices.
}
\usage{
sparseVector(x, i, length)
}
\arguments{
\item{x}{vector of the non zero entries; may be missing in which case a
\code{"nsparseVector"} will be returned.}
\item{i}{integer vector (of the same length as \code{x}) specifying
the indices of the non-zero (or non-\code{TRUE}) entries of the
sparse vector.}
\item{length}{length of the sparse vector.}
}
\value{
a sparse vector, i.e., inheriting from \code{\link{class}}
\code{\linkS4class{sparseVector}}.
}
\author{Martin Maechler}
\seealso{
\code{\link{sparseMatrix}()} constructor for sparse matrices;
the class \code{\linkS4class{sparseVector}}.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
str(sv <- sparseVector(x = 1:10, i = sample(999, 10), length=1000))
sx <- c(0,0,3, 3.2, 0,0,0,-3:1,0,0,2,0,0,5,0,0)
ss <- as(sx, "sparseVector")
stopifnot(identical(ss,
sparseVector(x = c(2, -1, -2, 3, 1, -3, 5, 3.2),
i = c(15L, 10:9, 3L,12L,8L,18L, 4L), length = 20L)))
(ns <- sparseVector(i= c(7, 3, 2), length = 10))
stopifnot(identical(ns,
new("nsparseVector", length = 10, i = c(2, 3, 7))))
}
Matrix/man/Matrix-deprecated.Rd 0000644 0001751 0000144 00000053016 14576343374 016165 0 ustar hornik users \name{Matrix-deprecated}
\title{Deprecated Functions in Package \pkg{Matrix}}
\alias{Matrix-deprecated}
%
\alias{..2dge}
\alias{.C2nC}
\alias{.SuiteSparse_version}
\alias{.T2Cmat}
\alias{.asmatrix}
\alias{.dense2sy}
\alias{.diag2mat}
\alias{.diag2sT}
\alias{.diag2tT}
\alias{.dsy2dsp}
\alias{.dsy2mat}
\alias{.dxC2mat}
\alias{.m2dgC}
\alias{.m2lgC}
\alias{.m2ngCn}
\alias{.m2ngC}
\alias{.m2ngTn}
\alias{.n2dgT}
\alias{.nC2d}
\alias{.nC2l}
%
\alias{atomicVector-class}
\alias{compMatrix-class}
\alias{number-class}
\alias{replValue-class}
%
\alias{chol2inv,CHMfactor-method}
\alias{coerce,CHMfactor,Matrix-method}
\alias{coerce,CHMfactor,CsparseMatrix-method}
\alias{coerce,CHMfactor,RsparseMatrix-method}
\alias{coerce,CHMfactor,TsparseMatrix-method}
\alias{coerce,CHMfactor,dMatrix-method}
\alias{coerce,CHMfactor,dsparseMatrix-method}
\alias{coerce,CHMfactor,pMatrix-method}
\alias{coerce,CHMfactor,sparseMatrix-method}
\alias{coerce,CHMfactor,triangularMatrix-method}
\alias{coerce,RsparseMatrix,dgeMatrix-method}
\alias{coerce,ddenseMatrix,dgeMatrix-method}
\alias{coerce,ddiMatrix,dgCMatrix-method}
\alias{coerce,ddiMatrix,dgeMatrix-method}
\alias{coerce,ddiMatrix,dtCMatrix-method}
\alias{coerce,dgCMatrix,dgTMatrix-method}
\alias{coerce,dgCMatrix,dgeMatrix-method}
\alias{coerce,dgCMatrix,dsCMatrix-method}
\alias{coerce,dgCMatrix,dtCMatrix-method}
\alias{coerce,dgCMatrix,lgCMatrix-method}
\alias{coerce,dgCMatrix,ngCMatrix-method}
\alias{coerce,dgTMatrix,dgCMatrix-method}
\alias{coerce,dgTMatrix,dgeMatrix-method}
\alias{coerce,dgTMatrix,dsTMatrix-method}
\alias{coerce,dgTMatrix,dtCMatrix-method}
\alias{coerce,dgTMatrix,dtTMatrix-method}
\alias{coerce,dgeMatrix,dgCMatrix-method}
\alias{coerce,dgeMatrix,dgTMatrix-method}
\alias{coerce,dgeMatrix,dsTMatrix-method}
\alias{coerce,dgeMatrix,dspMatrix-method}
\alias{coerce,dgeMatrix,dsyMatrix-method}
\alias{coerce,dgeMatrix,dtrMatrix-method}
\alias{coerce,dgeMatrix,lgeMatrix-method}
\alias{coerce,dsCMatrix,dgCMatrix-method}
\alias{coerce,dsCMatrix,dgTMatrix-method}
\alias{coerce,dsCMatrix,dgeMatrix-method}
\alias{coerce,dsCMatrix,dsRMatrix-method}
\alias{coerce,dsCMatrix,dsTMatrix-method}
\alias{coerce,dsCMatrix,dsyMatrix-method}
\alias{coerce,dsCMatrix,lsCMatrix-method}
\alias{coerce,dsCMatrix,nsCMatrix-method}
\alias{coerce,dsTMatrix,dgTMatrix-method}
\alias{coerce,dsTMatrix,dgeMatrix-method}
\alias{coerce,dsTMatrix,dsCMatrix-method}
\alias{coerce,dsTMatrix,dsyMatrix-method}
\alias{coerce,dsTMatrix,lsTMatrix-method}
\alias{coerce,dspMatrix,dsyMatrix-method}
\alias{coerce,dspMatrix,lspMatrix-method}
\alias{coerce,dsyMatrix,dsCMatrix-method}
\alias{coerce,dsyMatrix,dsTMatrix-method}
\alias{coerce,dsyMatrix,dspMatrix-method}
\alias{coerce,dsyMatrix,lsyMatrix-method}
\alias{coerce,dtCMatrix,dgCMatrix-method}
\alias{coerce,dtCMatrix,dgTMatrix-method}
\alias{coerce,dtCMatrix,dgeMatrix-method}
\alias{coerce,dtCMatrix,dsCMatrix-method}
\alias{coerce,dtCMatrix,dtTMatrix-method}
\alias{coerce,dtCMatrix,dtrMatrix-method}
\alias{coerce,dtCMatrix,ltCMatrix-method}
\alias{coerce,dtCMatrix,ntCMatrix-method}
\alias{coerce,dtTMatrix,dgTMatrix-method}
\alias{coerce,dtTMatrix,dgeMatrix-method}
\alias{coerce,dtTMatrix,dtCMatrix-method}
\alias{coerce,dtTMatrix,dtrMatrix-method}
\alias{coerce,dtpMatrix,dtTMatrix-method}
\alias{coerce,dtpMatrix,dtrMatrix-method}
\alias{coerce,dtpMatrix,ltpMatrix-method}
\alias{coerce,dtrMatrix,dtpMatrix-method}
\alias{coerce,dtrMatrix,ltrMatrix-method}
\alias{coerce,indMatrix,ngTMatrix-method}
\alias{coerce,indMatrix,ngeMatrix-method}
\alias{coerce,lMatrix,dgCMatrix-method}
\alias{coerce,lgCMatrix,dgCMatrix-method}
\alias{coerce,lgCMatrix,lgTMatrix-method}
\alias{coerce,lgCMatrix,lgeMatrix-method}
\alias{coerce,lgCMatrix,ltCMatrix-method}
\alias{coerce,lgTMatrix,dgTMatrix-method}
\alias{coerce,lgTMatrix,lgCMatrix-method}
\alias{coerce,lgTMatrix,lgeMatrix-method}
\alias{coerce,lgTMatrix,lsCMatrix-method}
\alias{coerce,lgTMatrix,ltTMatrix-method}
\alias{coerce,lgeMatrix,dgeMatrix-method}
\alias{coerce,lgeMatrix,lgCMatrix-method}
\alias{coerce,lgeMatrix,lgTMatrix-method}
\alias{coerce,lgeMatrix,lspMatrix-method}
\alias{coerce,lgeMatrix,lsyMatrix-method}
\alias{coerce,lgeMatrix,ltpMatrix-method}
\alias{coerce,lgeMatrix,ltrMatrix-method}
\alias{coerce,lsCMatrix,dsCMatrix-method}
\alias{coerce,lsCMatrix,lgCMatrix-method}
\alias{coerce,lsCMatrix,lgTMatrix-method}
\alias{coerce,lsCMatrix,lsTMatrix-method}
\alias{coerce,lsTMatrix,lgCMatrix-method}
\alias{coerce,lsTMatrix,lgTMatrix-method}
\alias{coerce,lsTMatrix,lsCMatrix-method}
\alias{coerce,lsTMatrix,lsyMatrix-method}
\alias{coerce,lspMatrix,dspMatrix-method}
\alias{coerce,lspMatrix,lgeMatrix-method}
\alias{coerce,lspMatrix,lsyMatrix-method}
\alias{coerce,lsyMatrix,dsyMatrix-method}
\alias{coerce,lsyMatrix,lgeMatrix-method}
\alias{coerce,lsyMatrix,lspMatrix-method}
\alias{coerce,ltCMatrix,lgCMatrix-method}
\alias{coerce,ltCMatrix,ltTMatrix-method}
\alias{coerce,ltTMatrix,dtTMatrix-method}
\alias{coerce,ltTMatrix,lgCMatrix-method}
\alias{coerce,ltTMatrix,lgTMatrix-method}
\alias{coerce,ltTMatrix,ltCMatrix-method}
\alias{coerce,ltTMatrix,ltrMatrix-method}
\alias{coerce,ltpMatrix,dtpMatrix-method}
\alias{coerce,ltpMatrix,lgeMatrix-method}
\alias{coerce,ltpMatrix,ltrMatrix-method}
\alias{coerce,ltrMatrix,dtrMatrix-method}
\alias{coerce,ltrMatrix,lgeMatrix-method}
\alias{coerce,ltrMatrix,ltpMatrix-method}
\alias{coerce,matrix,dgRMatrix-method}
\alias{coerce,matrix,dgTMatrix-method}
\alias{coerce,matrix,dgeMatrix-method}
\alias{coerce,matrix,dsCMatrix-method}
\alias{coerce,matrix,dsTMatrix-method}
\alias{coerce,matrix,dspMatrix-method}
\alias{coerce,matrix,dsyMatrix-method}
\alias{coerce,matrix,dtCMatrix-method}
\alias{coerce,matrix,dtTMatrix-method}
\alias{coerce,matrix,dtpMatrix-method}
\alias{coerce,matrix,dtrMatrix-method}
\alias{coerce,matrix,lgCMatrix-method}
\alias{coerce,matrix,lgTMatrix-method}
\alias{coerce,matrix,lgeMatrix-method}
\alias{coerce,matrix,lsCMatrix-method}
\alias{coerce,matrix,lspMatrix-method}
\alias{coerce,matrix,lsyMatrix-method}
\alias{coerce,matrix,ltCMatrix-method}
\alias{coerce,matrix,ltTMatrix-method}
\alias{coerce,matrix,ltpMatrix-method}
\alias{coerce,matrix,ltrMatrix-method}
\alias{coerce,matrix,ngCMatrix-method}
\alias{coerce,matrix,ngTMatrix-method}
\alias{coerce,matrix,ngeMatrix-method}
\alias{coerce,matrix,nspMatrix-method}
\alias{coerce,matrix,nsyMatrix-method}
\alias{coerce,matrix,ntCMatrix-method}
\alias{coerce,matrix,ntTMatrix-method}
\alias{coerce,matrix,ntpMatrix-method}
\alias{coerce,matrix,ntrMatrix-method}
\alias{coerce,ngCMatrix,dgCMatrix-method}
\alias{coerce,ngCMatrix,lgCMatrix-method}
\alias{coerce,ngCMatrix,ntCMatrix-method}
\alias{coerce,ngTMatrix,dgTMatrix-method}
\alias{coerce,ngTMatrix,lgTMatrix-method}
\alias{coerce,ngTMatrix,lgeMatrix-method}
\alias{coerce,ngTMatrix,ngCMatrix-method}
\alias{coerce,ngTMatrix,ngeMatrix-method}
\alias{coerce,ngTMatrix,ntTMatrix-method}
\alias{coerce,ngeMatrix,dgeMatrix-method}
\alias{coerce,ngeMatrix,lgeMatrix-method}
\alias{coerce,ngeMatrix,ngCMatrix-method}
\alias{coerce,ngeMatrix,ngTMatrix-method}
\alias{coerce,ngeMatrix,nspMatrix-method}
\alias{coerce,ngeMatrix,nsyMatrix-method}
\alias{coerce,ngeMatrix,ntpMatrix-method}
\alias{coerce,ngeMatrix,ntrMatrix-method}
\alias{coerce,nsCMatrix,dsCMatrix-method}
\alias{coerce,nsCMatrix,lsCMatrix-method}
\alias{coerce,nsCMatrix,ngCMatrix-method}
\alias{coerce,nsCMatrix,nsTMatrix-method}
\alias{coerce,nsTMatrix,dsTMatrix-method}
\alias{coerce,nsTMatrix,ngCMatrix-method}
\alias{coerce,nsTMatrix,ngTMatrix-method}
\alias{coerce,nsTMatrix,nsCMatrix-method}
\alias{coerce,nsTMatrix,nsyMatrix-method}
\alias{coerce,nspMatrix,dspMatrix-method}
\alias{coerce,nspMatrix,lspMatrix-method}
\alias{coerce,nspMatrix,ngeMatrix-method}
\alias{coerce,nspMatrix,nsyMatrix-method}
\alias{coerce,nsyMatrix,dsyMatrix-method}
\alias{coerce,nsyMatrix,lsyMatrix-method}
\alias{coerce,nsyMatrix,ngeMatrix-method}
\alias{coerce,nsyMatrix,nspMatrix-method}
\alias{coerce,ntCMatrix,dtCMatrix-method}
\alias{coerce,ntCMatrix,ltCMatrix-method}
\alias{coerce,ntCMatrix,ngCMatrix-method}
\alias{coerce,ntTMatrix,dtTMatrix-method}
\alias{coerce,ntTMatrix,ngCMatrix-method}
\alias{coerce,ntTMatrix,ngTMatrix-method}
\alias{coerce,ntTMatrix,ntCMatrix-method}
\alias{coerce,ntTMatrix,ntrMatrix-method}
\alias{coerce,ntpMatrix,dtpMatrix-method}
\alias{coerce,ntpMatrix,ltpMatrix-method}
\alias{coerce,ntpMatrix,ngeMatrix-method}
\alias{coerce,ntpMatrix,ntrMatrix-method}
\alias{coerce,ntrMatrix,dtrMatrix-method}
\alias{coerce,ntrMatrix,ltrMatrix-method}
\alias{coerce,ntrMatrix,ngeMatrix-method}
\alias{coerce,ntrMatrix,ntpMatrix-method}
\alias{coerce,numLike,dgeMatrix-method}
%
\description{
These functions are provided for compatibility with older versions
of \pkg{Matrix} only and may be defunct as soon as the next release.
}
\usage{
%% ## Deprecated in 1.6-0 ... on second thought, perhaps not yet
%% \S4method{chol2inv}{CHMfactor}(x, ...)
%% \S4method{coerce}{CHMfactor,Matrix}(from, to, strict = TRUE)
%% \S4method{coerce}{CHMfactor,CsparseMatrix}(from, to, strict = TRUE)
%% \S4method{coerce}{CHMfactor,RsparseMatrix}(from, to, strict = TRUE)
%% \S4method{coerce}{CHMfactor,TsparseMatrix}(from, to, strict = TRUE)
%% \S4method{coerce}{CHMfactor,dMatrix}(from, to, strict = TRUE)
%% \S4method{coerce}{CHMfactor,dsparseMatrix}(from, to, strict = TRUE)
%% \S4method{coerce}{CHMfactor,pMatrix}(from, to, strict = TRUE)
%% \S4method{coerce}{CHMfactor,sparseMatrix}(from, to, strict = TRUE)
%% \S4method{coerce}{CHMfactor,triangularMatrix}(from, to, strict = TRUE)
%%
## Deprecated in 1.5-4
..2dge(from)
.C2nC(from, isTri)
.T2Cmat(from, isTri)
.asmatrix(x)
.dense2sy(from, ...)
.diag2mat(from)
.diag2sT(from, uplo = "U", kind = ".", drop0 = TRUE)
.diag2tT(from, uplo = "U", kind = ".", drop0 = TRUE)
.dsy2dsp(from)
.dsy2mat(from, keep.dimnames = TRUE)
.dxC2mat(from, chkUdiag)
.m2dgC(from)
.m2lgC(from)
.m2ngC(from)
.m2ngCn(from, na.is.not.0 = FALSE)
.m2ngTn(from, na.is.not.0 = FALSE)
.n2dgT(from)
.nC2d(from)
.nC2l(from)
## Deprecated in 1.5-0
\S4method{coerce}{RsparseMatrix,dgeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ddenseMatrix,dgeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ddiMatrix,dgCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ddiMatrix,dgeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ddiMatrix,dtCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dgCMatrix,dgTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dgCMatrix,dgeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dgCMatrix,dsCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dgCMatrix,dtCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dgCMatrix,lgCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dgCMatrix,ngCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dgTMatrix,dgCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dgTMatrix,dgeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dgTMatrix,dsTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dgTMatrix,dtCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dgTMatrix,dtTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dgeMatrix,dgCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dgeMatrix,dgTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dgeMatrix,dsTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dgeMatrix,dspMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dgeMatrix,dsyMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dgeMatrix,dtrMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dgeMatrix,lgeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dsCMatrix,dgCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dsCMatrix,dgTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dsCMatrix,dgeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dsCMatrix,dsRMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dsCMatrix,dsTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dsCMatrix,dsyMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dsCMatrix,lsCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dsCMatrix,nsCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dsTMatrix,dgTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dsTMatrix,dgeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dsTMatrix,dsCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dsTMatrix,dsyMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dsTMatrix,lsTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dspMatrix,dsyMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dspMatrix,lspMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dsyMatrix,dsCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dsyMatrix,dsTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dsyMatrix,dspMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dsyMatrix,lsyMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dtCMatrix,dgCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dtCMatrix,dgTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dtCMatrix,dgeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dtCMatrix,dsCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dtCMatrix,dtTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dtCMatrix,dtrMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dtCMatrix,ltCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dtCMatrix,ntCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dtTMatrix,dgTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dtTMatrix,dgeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dtTMatrix,dtCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dtTMatrix,dtrMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dtpMatrix,dtTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dtpMatrix,dtrMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dtpMatrix,ltpMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dtrMatrix,dtpMatrix}(from, to, strict = TRUE)
\S4method{coerce}{dtrMatrix,ltrMatrix}(from, to, strict = TRUE)
\S4method{coerce}{indMatrix,ngTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{indMatrix,ngeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lMatrix,dgCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lgCMatrix,dgCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lgCMatrix,lgTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lgCMatrix,lgeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lgCMatrix,ltCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lgTMatrix,dgTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lgTMatrix,lgCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lgTMatrix,lgeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lgTMatrix,lsCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lgTMatrix,ltTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lgeMatrix,dgeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lgeMatrix,lgCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lgeMatrix,lgTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lgeMatrix,lspMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lgeMatrix,lsyMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lgeMatrix,ltpMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lgeMatrix,ltrMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lsCMatrix,dsCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lsCMatrix,lgCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lsCMatrix,lgTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lsCMatrix,lsTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lsTMatrix,lgCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lsTMatrix,lgTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lsTMatrix,lsCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lsTMatrix,lsyMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lspMatrix,dspMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lspMatrix,lgeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lspMatrix,lsyMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lsyMatrix,dsyMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lsyMatrix,lgeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{lsyMatrix,lspMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ltCMatrix,lgCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ltCMatrix,ltTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ltTMatrix,dtTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ltTMatrix,lgCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ltTMatrix,lgTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ltTMatrix,ltCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ltTMatrix,ltrMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ltpMatrix,dtpMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ltpMatrix,lgeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ltpMatrix,ltrMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ltrMatrix,dtrMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ltrMatrix,lgeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ltrMatrix,ltpMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,dgRMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,dgTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,dgeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,dsCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,dsTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,dspMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,dsyMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,dtCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,dtTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,dtpMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,dtrMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,lgCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,lgTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,lgeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,lsCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,lspMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,lsyMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,ltCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,ltTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,ltpMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,ltrMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,ngCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,ngTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,ngeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,nspMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,nsyMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,ntCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,ntTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,ntpMatrix}(from, to, strict = TRUE)
\S4method{coerce}{matrix,ntrMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ngCMatrix,dgCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ngCMatrix,lgCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ngCMatrix,ntCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ngTMatrix,dgTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ngTMatrix,lgTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ngTMatrix,lgeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ngTMatrix,ngCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ngTMatrix,ngeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ngTMatrix,ntTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ngeMatrix,dgeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ngeMatrix,lgeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ngeMatrix,ngCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ngeMatrix,ngTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ngeMatrix,nspMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ngeMatrix,nsyMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ngeMatrix,ntpMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ngeMatrix,ntrMatrix}(from, to, strict = TRUE)
\S4method{coerce}{nsCMatrix,dsCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{nsCMatrix,lsCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{nsCMatrix,ngCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{nsCMatrix,nsTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{nsTMatrix,dsTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{nsTMatrix,ngCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{nsTMatrix,ngTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{nsTMatrix,nsCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{nsTMatrix,nsyMatrix}(from, to, strict = TRUE)
\S4method{coerce}{nspMatrix,dspMatrix}(from, to, strict = TRUE)
\S4method{coerce}{nspMatrix,lspMatrix}(from, to, strict = TRUE)
\S4method{coerce}{nspMatrix,ngeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{nspMatrix,nsyMatrix}(from, to, strict = TRUE)
\S4method{coerce}{nsyMatrix,dsyMatrix}(from, to, strict = TRUE)
\S4method{coerce}{nsyMatrix,lsyMatrix}(from, to, strict = TRUE)
\S4method{coerce}{nsyMatrix,ngeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{nsyMatrix,nspMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ntCMatrix,dtCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ntCMatrix,ltCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ntCMatrix,ngCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ntTMatrix,dtTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ntTMatrix,ngCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ntTMatrix,ngTMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ntTMatrix,ntCMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ntTMatrix,ntrMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ntpMatrix,dtpMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ntpMatrix,ltpMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ntpMatrix,ngeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ntpMatrix,ntrMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ntrMatrix,dtrMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ntrMatrix,ltrMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ntrMatrix,ngeMatrix}(from, to, strict = TRUE)
\S4method{coerce}{ntrMatrix,ntpMatrix}(from, to, strict = TRUE)
\S4method{coerce}{numLike,dgeMatrix}(from, to, strict = TRUE)
}
\seealso{
\code{\link{Deprecated}},
\code{\link{base-deprecated}},
\code{\link{Matrix-defunct}}
}
\keyword{internal}
\keyword{misc}
Matrix/man/kronecker-methods.Rd 0000644 0001751 0000144 00000005625 14422605232 016232 0 ustar hornik users \name{kronecker-methods}
\title{Methods for Function 'kronecker()' in Package 'Matrix'}
%
\docType{methods}
\keyword{algebra}
\keyword{arith}
\keyword{array}
\keyword{methods}
%
\alias{kronecker}
\alias{kronecker-methods}
%
\alias{kronecker,CsparseMatrix,CsparseMatrix-method}
\alias{kronecker,CsparseMatrix,Matrix-method}
\alias{kronecker,CsparseMatrix,diagonalMatrix-method}
\alias{kronecker,Matrix,matrix-method}
\alias{kronecker,Matrix,vector-method}
\alias{kronecker,RsparseMatrix,Matrix-method}
\alias{kronecker,RsparseMatrix,RsparseMatrix-method}
\alias{kronecker,RsparseMatrix,diagonalMatrix-method}
\alias{kronecker,TsparseMatrix,Matrix-method}
\alias{kronecker,TsparseMatrix,TsparseMatrix-method}
\alias{kronecker,TsparseMatrix,diagonalMatrix-method}
\alias{kronecker,denseMatrix,Matrix-method}
\alias{kronecker,denseMatrix,denseMatrix-method}
\alias{kronecker,diagonalMatrix,CsparseMatrix-method}
\alias{kronecker,diagonalMatrix,Matrix-method}
\alias{kronecker,diagonalMatrix,RsparseMatrix-method}
\alias{kronecker,diagonalMatrix,TsparseMatrix-method}
\alias{kronecker,diagonalMatrix,diagonalMatrix-method}
\alias{kronecker,diagonalMatrix,indMatrix-method}
\alias{kronecker,indMatrix,Matrix-method}
\alias{kronecker,indMatrix,diagonalMatrix-method}
\alias{kronecker,indMatrix,indMatrix-method}
\alias{kronecker,matrix,Matrix-method}
\alias{kronecker,vector,Matrix-method}
%
\description{
Computes Kronecker products for objects inheriting from
\code{"\linkS4class{Matrix}"}.
In order to preserver sparseness, we treat \code{0 * NA} as \code{0},
not as \code{\link{NA}} as usually in \R (and as used for the
\pkg{base} function \code{\link[base]{kronecker}}).
}
\section{Methods}{
\describe{
\item{kronecker}{\code{signature(X = "Matrix", Y = "ANY")} .......}
\item{kronecker}{\code{signature(X = "ANY", Y = "Matrix")} .......}
\item{kronecker}{\code{signature(X = "diagonalMatrix", Y = "ANY")} .......}
\item{kronecker}{\code{signature(X = "sparseMatrix", Y = "ANY")} .......}
\item{kronecker}{\code{signature(X = "TsparseMatrix", Y = "TsparseMatrix")} .......}
\item{kronecker}{\code{signature(X = "dgTMatrix", Y = "dgTMatrix")} .......}
\item{kronecker}{\code{signature(X = "dtTMatrix", Y = "dtTMatrix")} .......}
\item{kronecker}{\code{signature(X = "indMatrix", Y = "indMatrix")} .......}
}
}
\examples{
(t1 <- spMatrix(5,4, x= c(3,2,-7,11), i= 1:4, j=4:1)) # 5 x 4
(t2 <- kronecker(Diagonal(3, 2:4), t1)) # 15 x 12
## should also work with special-cased logical matrices
l3 <- upper.tri(matrix(,3,3))
M <- Matrix(l3)
(N <- as(M, "nsparseMatrix")) # "ntCMatrix" (upper triangular)
N2 <- as(N, "generalMatrix") # (lost "t"riangularity)
MM <- kronecker(M,M)
NN <- kronecker(N,N) # "dtTMatrix" i.e. did keep
NN2 <- kronecker(N2,N2)
stopifnot(identical(NN,MM),
is(NN2, "sparseMatrix"), all(NN2 == NN),
is(NN, "triangularMatrix"))
}
\keyword{methods}
\keyword{array}
Matrix/man/bdiag.Rd 0000644 0001751 0000144 00000007676 14446607050 013672 0 ustar hornik users \name{bdiag}
\title{Construct a Block Diagonal Matrix}
%
\keyword{array}
\keyword{utilities}
%
\alias{bdiag}
\alias{.bdiag}
\description{
Build a block diagonal matrix given several building block matrices.
}
\usage{
bdiag(\dots)
.bdiag(lst)
}
\arguments{
\item{\dots}{individual matrices or a \code{\link{list}} of matrices.}
\item{lst}{non-empty \code{\link{list}} of matrices.}
}
\details{
For non-trivial argument list, \code{bdiag()} calls \code{.bdiag()}.
The latter maybe useful to programmers.
}
\note{This function has been written and is efficient for the case of
relatively few block matrices which are typically sparse themselves.
It is currently \emph{inefficient} for the case of many small dense
block matrices.
For the case of \emph{many} dense \eqn{k \times k}{k * k} matrices,
the \code{bdiag_m()} function in the \sQuote{Examples} is an order of
magnitude faster.
}
\value{
A \emph{sparse} matrix obtained by combining the arguments into a
block diagonal matrix.
The value of \code{bdiag()} inherits from class
\code{\linkS4class{CsparseMatrix}}, whereas
\code{.bdiag()} returns a \code{\linkS4class{TsparseMatrix}}.
}
\author{Martin Maechler, built on a version posted by Berton Gunter to
R-help; earlier versions have been posted by other authors, notably
Scott Chasalow to S-news. Doug Bates's faster implementation builds
on \code{\linkS4class{TsparseMatrix}} objects.
}
\seealso{\code{\link{Diagonal}} for constructing matrices of
class \code{\linkS4class{diagonalMatrix}}, or \code{\link{kronecker}}
which also works for \code{"Matrix"} inheriting matrices.
\code{\link{bandSparse}} constructs a \emph{banded} sparse matrix from
its non-zero sub-/super - diagonals.
Note that other CRAN \R packages have own versions of \code{bdiag()}
which return traditional matrices.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
}
bdiag(matrix(1:4, 2), diag(3))
## combine "Matrix" class and traditional matrices:
bdiag(Diagonal(2), matrix(1:3, 3,4), diag(3:2))
mlist <- list(1, 2:3, diag(x=5:3), 27, cbind(1,3:6), 100:101)
bdiag(mlist)
stopifnot(identical(bdiag(mlist), % <- used to fail in earlier versions
bdiag(lapply(mlist, as.matrix))))
ml <- c(as(matrix((1:24)\%\% 11 == 0, 6,4),"nMatrix"),
rep(list(Diagonal(2, x=TRUE)), 3))
mln <- c(ml, Diagonal(x = 1:3))
stopifnot(is(bdiag(ml), "lsparseMatrix"),% failed in Matrix <= 1.0-2
is(bdiag(mln),"dsparseMatrix") )
## random (diagonal-)block-triangular matrices:
rblockTri <- function(nb, max.ni, lambda = 3) {
.bdiag(replicate(nb, {
n <- sample.int(max.ni, 1)
tril(Matrix(rpois(n * n, lambda = lambda), n, n)) }))
}
(T4 <- rblockTri(4, 10, lambda = 1))
image(T1 <- rblockTri(12, 20))
##' Fast version of Matrix :: .bdiag() -- for the case of *many* (k x k) matrices:
##' @param lmat list(, , ....., ) where each mat_j is a k x k 'matrix'
##' @return a sparse (N*k x N*k) matrix of class \code{"\linkS4class{dgCMatrix}"}.
bdiag_m <- function(lmat) {
## Copyright (C) 2016 Martin Maechler, ETH Zurich
if(!length(lmat)) return(new("dgCMatrix"))
stopifnot(is.list(lmat), is.matrix(lmat[[1]]),
(k <- (d <- dim(lmat[[1]]))[1]) == d[2], # k x k
all(vapply(lmat, dim, integer(2)) == k)) # all of them
N <- length(lmat)
if(N * k > .Machine$integer.max)
stop("resulting matrix too large; would be M x M, with M=", N*k)
M <- as.integer(N * k)
## result: an M x M matrix
new("dgCMatrix", Dim = c(M,M),
## 'i :' maybe there's a faster way (w/o matrix indexing), but elegant?
i = as.vector(matrix(0L:(M-1L), nrow=k)[, rep(seq_len(N), each=k)]),
p = k * 0L:M,
x = as.double(unlist(lmat, recursive=FALSE, use.names=FALSE)))
}
l12 <- replicate(12, matrix(rpois(16, lambda = 6.4), 4, 4),
simplify=FALSE)
dim(T12 <- bdiag_m(l12))# 48 x 48
T12[1:20, 1:20]
}
Matrix/man/KNex.Rd 0000644 0001751 0000144 00000002265 14446607050 013456 0 ustar hornik users \name{KNex}
\title{Koenker-Ng Example Sparse Model Matrix and Response Vector}
%
\docType{data}
\keyword{datasets}
%
\alias{KNex}
%
\description{
A model matrix \code{mm} and corresponding response vector \code{y}
used in an example by Koenker and Ng. The matrix \code{mm} is a sparse
matrix with 1850 rows and 712 columns but only 8758 non-zero entries.
It is a \code{"dgCMatrix"} object. The vector \code{y} is just
\code{\link{numeric}} of length 1850.
}
\usage{data(KNex)}
%\details{}
%\source{}
\references{
Roger Koenker and Pin Ng (2003).
SparseM: A sparse matrix package for R;
\emph{J. of Statistical Software}, \bold{8} (6),
\doi{10.18637/jss.v008.i06}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
data(KNex, package = "Matrix")
class(KNex$mm)
dim(KNex$mm)
image(KNex$mm)
str(KNex)
system.time( # a fraction of a second
sparse.sol <- with(KNex, solve(crossprod(mm), crossprod(mm, y))))
head(round(sparse.sol,3))
## Compare with QR-based solution ("more accurate, but slightly slower"):
system.time(
sp.sol2 <- with(KNex, qr.coef(qr(mm), y) ))
all.equal(sparse.sol, sp.sol2, tolerance = 1e-13) # TRUE
}
Matrix/man/ntrMatrix-class.Rd 0000644 0001751 0000144 00000004331 14467516513 015706 0 ustar hornik users \name{ntrMatrix-class}
\title{Triangular Dense Logical Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{ntrMatrix-class}
\alias{ntpMatrix-class}
%
\description{
The \code{"ntrMatrix"} class is the class of triangular, dense,
logical matrices in nonpacked storage. The \code{"ntpMatrix"} class
is the same except in packed storage.
}
\section{Slots}{
\describe{
\item{\code{x}:}{Object of class \code{"logical"}. The logical
values that constitute the matrix, stored in column-major order.}
\item{\code{uplo}:}{Object of class \code{"character"}. Must be
either "U", for upper triangular, and "L", for lower triangular.}
\item{\code{diag}:}{Object of class \code{"character"}. Must be
either \code{"U"}, for unit triangular (diagonal is all ones), or
\code{"N"}; see \code{\linkS4class{triangularMatrix}}.}
\item{\code{Dim},\code{Dimnames}:}{The dimension (a length-2
\code{"integer"}) and corresponding names (or \code{NULL}), see the
\code{\linkS4class{Matrix}} class.}
\item{\code{factors}:}{Object of class \code{"list"}. A named
list of factorizations that have been computed for the matrix.}
}
}
\section{Extends}{
\code{"ntrMatrix"} extends class \code{"ngeMatrix"}, directly, whereas\cr
\code{"ntpMatrix"} extends class \code{"ndenseMatrix"}, directly.
Both extend Class \code{"triangularMatrix"}, directly,
and class \code{"denseMatrix"}, \code{"lMatrix"} and others,
\emph{in}directly, use \code{\link{showClass}("nsyMatrix")}, e.g., for
details.
}
\section{Methods}{
Currently, mainly \code{\link{t}()} and coercion methods (for
\code{\link{as}(.)}; use, e.g.,
\code{\link{showMethods}(class="ntrMatrix")} for details.
}
\seealso{
Classes \code{\linkS4class{ngeMatrix}}, \code{\linkS4class{Matrix}};
function \code{\link[base]{t}}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
showClass("ntrMatrix")
str(new("ntpMatrix"))
(nutr <- as(upper.tri(matrix(, 4, 4)), "ndenseMatrix"))
str(nutp <- pack(nutr)) # packed matrix: only 10 = 4*(4+1)/2 entries
!nutp # the logical negation (is *not* logical triangular !)
## but this one is:
stopifnot(all.equal(nutp, pack(!!nutp)))
}
Matrix/man/dsyMatrix-class.Rd 0000644 0001751 0000144 00000010143 14565737512 015703 0 ustar hornik users \name{dsyMatrix-class}
\title{Symmetric Dense (Packed or Unpacked) Numeric Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{dsyMatrix-class}
\alias{dspMatrix-class}
%
\alias{coerce,dsyMatrix,corMatrix-method}
\alias{coerce,dsyMatrix,dpoMatrix-method}
\alias{determinant,dsyMatrix,logical-method}
%
\alias{coerce,dspMatrix,copMatrix-method}
\alias{coerce,dspMatrix,dppMatrix-method}
\alias{determinant,dspMatrix,logical-method}
%
\description{
\itemize{
\item The \code{"dsyMatrix"} class is the class of symmetric, dense matrices
in \emph{non-packed} storage and
\item \code{"dspMatrix"} is the class of symmetric dense matrices in
\emph{packed} storage, see \code{\link{pack}()}. Only the upper
triangle or the lower triangle is stored.
}
}
\section{Objects from the Class}{
Objects can be created by calls of the form \code{new("dsyMatrix",
...)} or \code{new("dspMatrix", ...)}, respectively.
}
\section{Slots}{
\describe{
\item{\code{uplo}:}{Object of class \code{"character"}. Must be
either "U", for upper triangular, and "L", for lower triangular.}
\item{\code{x}:}{Object of class \code{"numeric"}. The numeric
values that constitute the matrix, stored in column-major order.}
\item{\code{Dim},\code{Dimnames}:}{The dimension (a length-2
\code{"integer"}) and corresponding names (or \code{NULL}), see the
\code{\linkS4class{Matrix}}.}
\item{\code{factors}:}{Object of class \code{"list"}. A named
list of factorizations that have been computed for the matrix.}
}
}
\section{Extends}{
\code{"dsyMatrix"} extends class \code{"dgeMatrix"}, directly, whereas\cr
\code{"dspMatrix"} extends class \code{"ddenseMatrix"}, directly.
Both extend class \code{"symmetricMatrix"}, directly,
and class \code{"Matrix"} and others, \emph{in}directly, use
\code{\link{showClass}("dsyMatrix")}, e.g., for details.
}
\section{Methods}{
\describe{
\item{norm}{\code{signature(x = "dspMatrix", type = "character")}, or
\code{x = "dsyMatrix"} or \code{type = "missing"}: Computes the
matrix norm of the desired type, see, \code{\link{norm}}.}
\item{rcond}{\code{signature(x = "dspMatrix", type = "character")}, or
\code{x = "dsyMatrix"} or \code{type = "missing"}: Computes the
reciprocal condition number, \code{\link{rcond}()}.}
\item{solve}{\code{signature(a = "dspMatrix", b = "....")}, and}
\item{solve}{\code{signature(a = "dsyMatrix", b = "....")}: \code{x
<- solve(a,b)} solves \eqn{A x = b} for \eqn{x}; see
\code{\link{solve-methods}}.}
\item{t}{\code{signature(x = "dsyMatrix")}: Transpose; swaps from
upper triangular to lower triangular storage, i.e., the uplo slot
from \code{"U"} to \code{"L"} or vice versa, the same as for all
symmetric matrices.}
}
}
%\references{}
\seealso{
The \emph{positive (Semi-)definite} dense (packed or non-packed
numeric matrix classes \code{\linkS4class{dpoMatrix}},
\code{\linkS4class{dppMatrix}} and \code{\linkS4class{corMatrix}},
Classes \code{\linkS4class{dgeMatrix}} and \code{\linkS4class{Matrix}};
\code{\link[base]{solve}}, \code{\link{norm}}, \code{\link{rcond}},
\code{\link[base]{t}}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
## Only upper triangular part matters (when uplo == "U" as per default)
(sy2 <- new("dsyMatrix", Dim = as.integer(c(2,2)), x = c(14, NA,32,77)))
str(t(sy2)) # uplo = "L", and the lower tri. (i.e. NA is replaced).
chol(sy2) #-> "Cholesky" matrix
(sp2 <- pack(sy2)) # a "dspMatrix"
## Coercing to dpoMatrix gives invalid object:
sy3 <- new("dsyMatrix", Dim = as.integer(c(2,2)), x = c(14, -1, 2, -7))
try(as(sy3, "dpoMatrix")) # -> error: not positive definite
\dontshow{
tr <- try(as(sy3, "dpoMatrix"), silent=TRUE)
stopifnot(1 == grep("not a positive definite matrix",
as.character(tr)),
is(sp2, "dspMatrix"))
}
## 4x4 example
m <- matrix(0,4,4); m[upper.tri(m)] <- 1:6
(sym <- m+t(m)+diag(11:14, 4))
(S1 <- pack(sym))
(S2 <- t(S1))
stopifnot(all(S1 == S2)) # equal "seen as matrix", but differ internally :
str(S1)
S2@x
}
Matrix/man/facmul-methods.Rd 0000644 0001751 0000144 00000003735 14575137654 015537 0 ustar hornik users \name{facmul-methods}
\title{Multiplication by Factors from Matrix Factorizations}
%
\docType{methods}
\keyword{arith}
\keyword{array}
\keyword{methods}
%
\alias{facmul}
\alias{facmul-methods}
%
\description{
Multiplies a matrix or vector on the left or right by a factor
from a matrix factorization or its transpose.
}
\usage{
facmul(x, factor, y, trans = FALSE, left = TRUE, \dots)
}
\arguments{
\item{x}{a \code{\linkS4class{MatrixFactorization}} object.}
\item{factor}{a character string indicating a factor in the
factorization represented by \code{x}, typically an element
of \code{names(\link{expand2}(x, \dots))}.}
\item{y}{a matrix or vector to be multiplied on the left or right
by the factor or its transpose.}
\item{trans}{a logical indicating if the transpose of the
factor should be used, rather than the factor itself.}
\item{left}{a logical indicating if the \code{y} should be
multiplied on the left by the factor, rather than on the right.}
\item{\dots}{further arguments passed to or from methods.}
}
\value{
The value of \code{op(M) \%*\% y} or \code{y \%*\% op(M)},
depending on \code{left}, where \code{M} is the factor
(always \emph{without} \code{dimnames}) and \code{op(M)}
is \code{M} or \code{t(M)}, depending on \code{trans}.
}
\details{
\code{facmul} is experimental and currently no methods are
exported from \pkg{Matrix}.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
}
## Conceptually, methods for 'facmul' _would_ behave as follows ...
\dontrun{
n <- 3L
x <- lu(Matrix(rnorm(n * n), n, n))
y <- rnorm(n)
L <- unname(expand2(x)[[nm <- "L"]])
stopifnot(exprs = {
all.equal(facmul(x, nm, y, trans = FALSE, left = TRUE), L \%*\% y)
all.equal(facmul(x, nm, y, trans = FALSE, left = FALSE), y \%*\% L)
all.equal(facmul(x, nm, y, trans = TRUE, left = TRUE), crossprod(L, y))
all.equal(facmul(x, nm, y, trans = TRUE, left = FALSE), tcrossprod(y, L))
})
}
}
Matrix/man/norm-methods.Rd 0000644 0001751 0000144 00000006204 14575137654 015235 0 ustar hornik users \name{norm-methods}
\title{Matrix Norms}
%
\docType{methods}
\keyword{algebra}
\keyword{math}
\keyword{methods}
%
\alias{norm}
\alias{norm-methods}
%
\alias{norm,ANY,missing-method}
\alias{norm,denseMatrix,character-method}
\alias{norm,diagonalMatrix,character-method}
\alias{norm,indMatrix,character-method}
\alias{norm,pMatrix,character-method}
\alias{norm,sparseMatrix,character-method}
%
\description{
Computes a matrix norm of \code{x}, using Lapack for dense matrices.
The norm can be the one (\code{"O"}, or \code{"1"}) norm, the
infinity (\code{"I"}) norm, the Frobenius (\code{"F"}) norm,
the maximum modulus (\code{"M"}) among elements of a matrix, or the
spectral norm or 2-norm (\code{"2"}), as determined by the value of
\code{type}.
}
\usage{
norm(x, type, \dots)
}
\arguments{
\item{x}{
a real or complex matrix.
}
\item{type}{
A character indicating the type of norm desired.
\describe{
\item{\code{"O"}, \code{"o"} or \code{"1"}}{specifies the one norm,
(maximum absolute column sum);}
\item{\code{"I"} or \code{"i"}}{specifies the infinity norm (maximum
absolute row sum);}
\item{\code{"F"} or \code{"f"}}{specifies the Frobenius norm (the
Euclidean norm of \code{x} treated as if it were a vector);}
\item{\code{"M"} or \code{"m"}}{specifies the maximum modulus of
all the elements in \code{x}; and}
\item{\code{"2"}}{specifies the \dQuote{spectral norm} aka \dQuote{2-norm}, which
is the largest singular value (\code{\link{svd}}) of \code{x}.}
}
The default is \code{"O"}. Only the first character of
\code{type[1]} is used.
}
\item{\dots}{further arguments passed to or from other methods.}
}
\value{
A numeric value of class \code{"norm"}, representing the quantity
chosen according to \code{type}.
}
\details{
For dense matrices, the methods eventually call the Lapack functions
\code{dlange}, \code{dlansy}, \code{dlantr}, \code{zlange},
\code{zlansy}, and \code{zlantr}.
}
\seealso{
\code{\link{onenormest}()}, an \emph{approximate} randomized estimate
of the 1-norm condition number, efficient for large sparse matrices.
The \code{\link[base]{norm}()} function from \R's \pkg{base} package.
}
\references{
Anderson, E., et al. (1994).
\emph{LAPACK User's Guide,}
2nd edition, SIAM, Philadelphia.
}
\examples{
x <- Hilbert(9)
norm(x)# = "O" = "1"
stopifnot(identical(norm(x), norm(x, "1")))
norm(x, "I")# the same, because 'x' is symmetric
allnorms <- function(x) {
## norm(NA, "2") did not work until R 4.0.0
do2 <- getRversion() >= "4.0.0" || !anyNA(x)
vapply(c("1", "I", "F", "M", if(do2) "2"), norm, 0, x = x)
}
allnorms(x)
allnorms(Hilbert(10))
i <- c(1,3:8); j <- c(2,9,6:10); x <- 7 * (1:7)
A <- sparseMatrix(i, j, x = x) ## 8 x 10 "dgCMatrix"
(sA <- sparseMatrix(i, j, x = x, symmetric = TRUE)) ## 10 x 10 "dsCMatrix"
(tA <- sparseMatrix(i, j, x = x, triangular= TRUE)) ## 10 x 10 "dtCMatrix"
(allnorms(A) -> nA)
allnorms(sA)
allnorms(tA)
stopifnot(all.equal(nA, allnorms(as(A, "matrix"))),
all.equal(nA, allnorms(tA))) # because tA == rbind(A, 0, 0)
A. <- A; A.[1,3] <- NA
stopifnot(is.na(allnorms(A.))) # gave error
}
Matrix/man/dimScale.Rd 0000644 0001751 0000144 00000003651 14422605232 014324 0 ustar hornik users \name{dimScale}
\title{Scale the Rows and Columns of a Matrix}
%
\keyword{algebra}
\keyword{arith}
\keyword{array}
\keyword{utilities}
%
\alias{dimScale}
\alias{rowScale}
\alias{colScale}
%
\description{
\code{dimScale}, \code{rowScale}, and \code{colScale} implement
\code{D1 \%*\% x \%*\% D2}, \code{D \%*\% x}, and \code{x \%*\% D}
for diagonal matrices \code{D1}, \code{D2}, and \code{D} with
diagonal entries \code{d1}, \code{d2}, and \code{d}, respectively.
Unlike the explicit products, these functions preserve \code{dimnames(x)}
and symmetry where appropriate.
}
\usage{
dimScale(x, d1 = sqrt(1/diag(x, names = FALSE)), d2 = d1)
rowScale(x, d)
colScale(x, d)
}
\arguments{
\item{x}{a matrix, possibly inheriting from virtual class
\code{\linkS4class{Matrix}}.}
\item{d1,d2,d}{numeric vectors giving factors by which to scale
the rows or columns of \code{x}; they are recycled as necessary.}
}
\details{
\code{dimScale(x)} (with \code{d1} and \code{d2} unset) is only
roughly equivalent to \code{\link{cov2cor}(x)}. \code{cov2cor}
sets the diagonal entries of the result to 1 (exactly);
\code{dimScale} does not.
}
\value{
The result of scaling \code{x}, currently always inheriting from
virtual class \code{\linkS4class{dMatrix}}.
It inherits from \code{\linkS4class{triangularMatrix}} if and only
if \code{x} does. In the special case of \code{dimScale(x, d1, d2)}
with identical \code{d1} and \code{d2}, it inherits from
\code{\linkS4class{symmetricMatrix}} if and only if \code{x} does.
}
\author{Mikael Jagan}
\seealso{\code{\link{cov2cor}}}
\examples{
n <- 6L
(x <- forceSymmetric(matrix(1, n, n)))
dimnames(x) <- rep.int(list(letters[seq_len(n)]), 2L)
d <- seq_len(n)
(D <- Diagonal(x = d))
(scx <- dimScale(x, d)) # symmetry and 'dimnames' kept
(mmx <- D \%*\% x \%*\% D) # symmetry and 'dimnames' lost
stopifnot(identical(unname(as(scx, "generalMatrix")), mmx))
rowScale(x, d)
colScale(x, d)
}
Matrix/man/qr-methods.Rd 0000644 0001751 0000144 00000015504 14575234535 014703 0 ustar hornik users \name{qr-methods}
\title{Methods for QR Factorization}
%
\docType{methods}
\keyword{algebra}
\keyword{array}
\keyword{methods}
%
\alias{qr}
\alias{qr-methods}
%
\alias{qr,dgCMatrix-method}
\alias{qr,sparseMatrix-method}
%
\description{
Computes the pivoted QR factorization of an \eqn{m \times n}{m-by-n}
real matrix \eqn{A}, which has the general form
\deqn{P_{1} A P_{2} = Q R}{P1 * A * P2 = Q * R}
or (equivalently)
\deqn{A = P_{1}' Q R P_{2}'}{A = P1' * Q * R * P2'}
where
\eqn{P_{1}}{P1} and \eqn{P_{2}}{P2} are permutation matrices,
\eqn{Q = \prod_{j = 1}^{n} H_{j}}{Q = prod(Hj : j = 1,...,n)}
is an \eqn{m \times m}{m-by-m} orthogonal matrix
equal to the product of \eqn{n} Householder matrices \eqn{H_{j}}{Hj}, and
\eqn{R} is an \eqn{m \times n}{m-by-n} upper trapezoidal matrix.
\code{\linkS4class{denseMatrix}} use the default method implemented
in \pkg{base}, namely \code{\link{qr.default}}. It is built on
LINPACK routine \code{dqrdc} and LAPACK routine \code{dgeqp3}, which
do not pivot rows, so that \eqn{P_{1}}{P1} is an identity matrix.
Methods for \code{\linkS4class{sparseMatrix}} are built on
CXSparse routines \code{cs_sqr} and \code{cs_qr}, which require
\eqn{m \ge n}{m >= n}.
}
\usage{
qr(x, \dots)
\S4method{qr}{dgCMatrix}(x, order = 3L, \dots)
}
\arguments{
\item{x}{a \link[=is.finite]{finite} matrix or
\code{\linkS4class{Matrix}} to be factorized,
satisfying \code{nrow(x) >= ncol(x)} if sparse.}
\item{order}{an integer in \code{0:3} passed to CXSparse routine
\code{cs_sqr}, indicating a strategy for choosing the column
permutation \eqn{P_{2}}{P2}. 0 means no column permutation.
1, 2, and 3 indicate a fill-reducing ordering of \eqn{A + A'},
\eqn{\tilde{A}' \tilde{A}}{A~' * A~}, and \eqn{A' A}{A' * A},
where \eqn{\tilde{A}}{A~} is \eqn{A} with \dQuote{dense} rows
removed.
Do not set to 0 unless you know that the column order of \eqn{A}
is already sensible.}
\item{\dots}{further arguments passed to or from methods.}
}
\value{
An object representing the factorization, inheriting from
virtual S4 class \code{\linkS4class{QR}} or S3 class
\code{\link[base]{qr}}. The specific class is \code{qr}
unless \code{x} inherits from virtual class
\code{\linkS4class{sparseMatrix}}, in which case it is
\code{\linkS4class{sparseQR}}.
}
\details{
If \code{x} is sparse and structurally rank deficient, having
structural rank \eqn{r < n}, then \code{x} is augmented with
\eqn{(n-r)} rows of (partly non-structural) zeros, such that
the augmented matrix has structural rank \eqn{n}.
This augmented matrix is factorized as described above:
\deqn{P_1 A P_2 = P_1 \begin{bmatrix} A_{0} \\ 0 \end{bmatrix} P_2 = Q R}{P1 * A * P2 = P1 * [A0; 0] * P2 = Q * R}
where \eqn{A_0}{A0} denotes the original, user-supplied
\eqn{(m-(n-r)) \times n}{(m-(n-r))-by-n} matrix.
}
\seealso{
Class \code{\linkS4class{sparseQR}} and its methods.
Class \code{\linkS4class{dgCMatrix}}.
Generic function \code{\link[base]{qr}} from \pkg{base},
whose default method \code{qr.default} \dQuote{defines}
the S3 class \code{qr} of dense QR factorizations.
Generic functions \code{\link{expand1}} and \code{\link{expand2}},
for constructing matrix factors from the result.
Generic functions \code{\link{Cholesky}}, \code{\link{BunchKaufman}},
\code{\link{Schur}}, and \code{\link{lu}},
for computing other factorizations.
}
\references{
Davis, T. A. (2006).
\emph{Direct methods for sparse linear systems}.
Society for Industrial and Applied Mathematics.
\doi{10.1137/1.9780898718881}
Golub, G. H., & Van Loan, C. F. (2013).
\emph{Matrix computations} (4th ed.).
Johns Hopkins University Press.
\doi{10.56021/9781421407944}
}
\examples{
showMethods("qr", inherited = FALSE)
## Rank deficient: columns 3 {b2} and 6 {c3} are "extra"
M <- as(cbind(a1 = 1,
b1 = rep(c(1, 0), each = 3L),
b2 = rep(c(0, 1), each = 3L),
c1 = rep(c(1, 0, 0), 2L),
c2 = rep(c(0, 1, 0), 2L),
c3 = rep(c(0, 0, 1), 2L)),
"CsparseMatrix")
rownames(M) <- paste0("r", seq_len(nrow(M)))
b <- 1:6
eps <- .Machine$double.eps
## .... [1] full rank ..................................................
## ===> a least squares solution of A x = b exists
## and is unique _in exact arithmetic_
(A1 <- M[, -c(3L, 6L)])
(qr.A1 <- qr(A1))
stopifnot(exprs = {
rankMatrix(A1) == ncol(A1)
{ d1 <- abs(diag(qr.A1@R)); sum(d1 < max(d1) * eps) == 0L }
rcond(crossprod(A1)) >= eps
all.equal(qr.coef(qr.A1, b), drop(solve(crossprod(A1), crossprod(A1, b))))
all.equal(qr.fitted(qr.A1, b) + qr.resid(qr.A1, b), b)
})
## .... [2] numerically rank deficient with full structural rank .......
## ===> a least squares solution of A x = b does not
## exist or is not unique _in exact arithmetic_
(A2 <- M)
(qr.A2 <- qr(A2))
stopifnot(exprs = {
rankMatrix(A2) == ncol(A2) - 2L
{ d2 <- abs(diag(qr.A2@R)); sum(d2 < max(d2) * eps) == 2L }
rcond(crossprod(A2)) < eps
## 'qr.coef' computes unique least squares solution of "nearby" problem
## Z x = b for some full rank Z ~ A, currently without warning {FIXME} !
tryCatch({ qr.coef(qr.A2, b); TRUE }, condition = function(x) FALSE)
all.equal(qr.fitted(qr.A2, b) + qr.resid(qr.A2, b), b)
})
## .... [3] numerically and structurally rank deficient ................
## ===> factorization of _augmented_ matrix with
## full structural rank proceeds as in [2]
## NB: implementation details are subject to change; see (*) below
A3 <- M
A3[, c(3L, 6L)] <- 0
A3
(qr.A3 <- qr(A3)) # with a warning ... "additional 2 row(s) of zeros"
stopifnot(exprs = {
## sparseQR object preserves the unaugmented dimensions (*)
dim(qr.A3 ) == dim(A3)
dim(qr.A3@V) == dim(A3) + c(2L, 0L)
dim(qr.A3@R) == dim(A3) + c(2L, 0L)
## The augmented matrix remains numerically rank deficient
rankMatrix(A3) == ncol(A3) - 2L
{ d3 <- abs(diag(qr.A3@R)); sum(d3 < max(d3) * eps) == 2L }
rcond(crossprod(A3)) < eps
})
## Auxiliary functions accept and return a vector or matrix
## with dimensions corresponding to the unaugmented matrix (*),
## in all cases with a warning
qr.coef (qr.A3, b)
qr.fitted(qr.A3, b)
qr.resid (qr.A3, b)
## .... [4] yet more examples ..........................................
## By disabling column pivoting, one gets the "vanilla" factorization
## A = Q~ R, where Q~ := P1' Q is orthogonal because P1 and Q are
(qr.A1.pp <- qr(A1, order = 0L)) # partial pivoting
ae1 <- function(a, b, ...) all.equal(as(a, "matrix"), as(b, "matrix"), ...)
ae2 <- function(a, b, ...) ae1(unname(a), unname(b), ...)
stopifnot(exprs = {
length(qr.A1 @q) == ncol(A1)
length(qr.A1.pp@q) == 0L # indicating no column pivoting
ae2(A1[, qr.A1@q + 1L], qr.Q(qr.A1 ) \%*\% qr.R(qr.A1 ))
ae2(A1 , qr.Q(qr.A1.pp) \%*\% qr.R(qr.A1.pp))
})
}
Matrix/man/dsRMatrix-class.Rd 0000644 0001751 0000144 00000005362 14575137654 015645 0 ustar hornik users \name{dsRMatrix-class}
\title{Symmetric Sparse Compressed Row Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{dsRMatrix-class}
%
\alias{determinant,dsRMatrix,logical-method}
%
\description{The \code{dsRMatrix} class is a class of symmetric, sparse
matrices in the compressed, row-oriented format. In this
implementation the non-zero elements in the rows are sorted into
increasing column order.
}
\section{Objects from the Class}{
These \code{"..RMatrix"} classes are currently still mostly unimplemented!
Objects can be created by calls of the form \code{new("dsRMatrix", ...)}.
}
\section{Slots}{
\describe{
\item{\code{uplo}:}{A character object indicating if the upper
triangle (\code{"U"}) or the lower triangle (\code{"L"}) is
stored. At present only the lower triangle form is allowed.}
\item{\code{j}:}{Object of class \code{"integer"} of length
\code{nnzero} (number of non-zero elements). These are the row
numbers for each non-zero element in the matrix.}
\item{\code{p}:}{Object of class \code{"integer"} of pointers, one
for each row, to the initial (zero-based) index of elements in
the row.}
\item{\code{factors}:}{Object of class \code{"list"} - a list
of factorizations of the matrix.}
\item{\code{x}:}{Object of class \code{"numeric"} - the non-zero
elements of the matrix.}
\item{\code{Dim}:}{Object of class \code{"integer"} - the dimensions
of the matrix - must be an integer vector with exactly two
non-negative values.}
\item{\code{Dimnames}:}{List of length two, see \code{\link{Matrix}}.}
}
}
\section{Extends}{
Classes \code{\linkS4class{dsparseMatrix}},
\code{\linkS4class{symmetricMatrix}}, and
\code{\linkS4class{RsparseMatrix}}, directly.
Class \code{"dMatrix"}, by class \code{"dsparseMatrix"};
class \code{"sparseMatrix"}, by classes \code{"dsparseMatrix"} and
\code{"RsparseMatrix"}.
}
\section{Methods}{
\describe{
\item{forceSymmetric}{\code{signature(x = "dsRMatrix", uplo = "missing")}:
a trivial method just returning \code{x}}
\item{forceSymmetric}{\code{signature(x = "dsRMatrix", uplo = "character")}:
if \code{uplo == x@uplo}, this trivially returns \code{x};
otherwise \code{t(x)}.}
}
}
\seealso{
the classes \code{\linkS4class{dgCMatrix}},
\code{\linkS4class{dgTMatrix}}, and \code{\linkS4class{dgeMatrix}}.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
(m0 <- new("dsRMatrix"))
m2 <- new("dsRMatrix", Dim = c(2L,2L),
x = c(3,1), j = c(1L,1L), p = 0:2)
m2
stopifnot(colSums(as(m2, "TsparseMatrix")) == 3:4)
str(m2)
(ds2 <- forceSymmetric(diag(2))) # dsy*
dR <- as(ds2, "RsparseMatrix")
dR # dsRMatrix
}
Matrix/man/wrld_1deg.Rd 0000644 0001751 0000144 00000005312 14447626522 014463 0 ustar hornik users \name{wrld_1deg}
\title{Contiguity Matrix of World One-Degree Grid Cells}
%
\docType{data}
\keyword{datasets}
%
\alias{wrld_1deg}
%
\description{
This matrix gives the contiguities of 15260 one-degree
grid cells of world land areas, using a criterion based
on the great-circle distance between centers.
}
\usage{data(wrld_1deg)}
\format{
A \eqn{15260 \times 15260}{15260-by-15260} sparse, symmetric
matrix of class \code{\linkS4class{dsCMatrix}}, with 55973
nonzero entries.
}
\source{
Shoreline data were read into \R{} from the GSHHS database
using function \code{Rgshhs} from package \CRANpkg{maptools}.
Antarctica was excluded. An approximately one-degree grid
was generated using function \code{Sobj_SpatialGrid}, also
from \CRANpkg{maptools}. Grid cells with centers on land
were identified using the \code{over} method for classes
\code{SpatialPolygons} and \code{SpatialGrid}, defined in
package \CRANpkg{sp}. Neighbours of these were identified
by passing the resulting \code{SpatialPixels} object to
function \code{dnearneigh} from package \CRANpkg{spdep},
using as a cut-off a great-circle distance of \code{sqrt(2)}
kilometers between centers.
Neighbour lists were augmented with row-standardized
(and then symmetrized) spatial weights, using functions
\code{nb2listw} and \code{similar.listw} from packages
\CRANpkg{spdep} and \CRANpkg{spatialreg}.
The resulting \code{listw} object was coerced to class
\code{\linkS4class{dsTMatrix}}
using \code{as_dsTMatrix_listw} from \CRANpkg{spatialreg},
and subsequently to class \code{\linkS4class{dsCMatrix}}.
}
\references{
Ord, J. K. (1975).
Estimation methods for models of spatial interaction.
\emph{Journal of the American Statistical Association},
\emph{70}(349), 120-126.
\doi{10.2307/2285387}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
library(utils, pos = "package:base", verbose = FALSE)
}
data(wrld_1deg, package = "Matrix")
(n <- ncol(wrld_1deg))
I <- .symDiagonal(n)
doExtras <- interactive() || nzchar(Sys.getenv("R_MATRIX_CHECK_EXTRA"))
set.seed(1)
r <- if(doExtras) 20L else 3L
rho <- 1 / runif(r, 0, 0.5)
system.time(MJ0 <- sapply(rho, function(mult)
determinant(wrld_1deg + mult * I, logarithm = TRUE)$modulus))
## Can be done faster by updating the Cholesky factor:
C1 <- Cholesky(wrld_1deg, Imult = 2)
system.time(MJ1 <- sapply(rho, function(mult)
determinant(update(C1, wrld_1deg, mult), sqrt = FALSE)$modulus))
stopifnot(all.equal(MJ0, MJ1))
C2 <- Cholesky(wrld_1deg, super = TRUE, Imult = 2)
system.time(MJ2 <- sapply(rho, function(mult)
determinant(update(C2, wrld_1deg, mult), sqrt = FALSE)$modulus))
stopifnot(all.equal(MJ0, MJ2))
}
Matrix/man/sparseLU-class.Rd 0000644 0001751 0000144 00000010766 14446607050 015457 0 ustar hornik users \name{sparseLU-class}
\title{Sparse LU Factorizations}
%
\docType{class}
\keyword{algebra}
\keyword{array}
\keyword{classes}
%
\alias{sparseLU-class}
%
\alias{determinant,sparseLU,logical-method}
%
\description{
\code{sparseLU} is the class of sparse, row- and column-pivoted
LU factorizations of \eqn{n \times n}{n-by-n} real matrices \eqn{A},
having the general form
\deqn{P_{1} A P_{2} = L U}{P1 * A * P2 = L * U}
or (equivalently)
\deqn{A = P_{1}' L U P_{2}'}{A = P1' * L * U * P2'}
where
\eqn{P_{1}}{P1} and \eqn{P_{2}}{P2} are permutation matrices,
\eqn{L} is a unit lower triangular matrix, and
\eqn{U} is an upper triangular matrix.
}
\section{Slots}{
\describe{
\item{\code{Dim}, \code{Dimnames}}{inherited from virtual class
\code{\linkS4class{MatrixFactorization}}.}
\item{\code{L}}{an object of class \code{\linkS4class{dtCMatrix}},
the unit lower triangular \eqn{L} factor.}
\item{\code{U}}{an object of class \code{\linkS4class{dtCMatrix}},
the upper triangular \eqn{U} factor.}
\item{\code{p}, \code{q}}{0-based integer vectors of length
\code{Dim[1]},
specifying the permutations applied to the rows and columns of
the factorized matrix. \code{q} of length 0 is valid and
equivalent to the identity permutation, implying no column pivoting.
Using \R{} syntax, the matrix \eqn{P_{1} A P_{2}}{P1 * A * P2}
is precisely \code{A[p+1, q+1]}
(\code{A[p+1, ]} when \code{q} has length 0).}
}
}
\section{Extends}{
Class \code{\linkS4class{LU}}, directly.
Class \code{\linkS4class{MatrixFactorization}}, by class
\code{\linkS4class{LU}}, distance 2.
}
\section{Instantiation}{
Objects can be generated directly by calls of the form
\code{new("sparseLU", ...)}, but they are more typically obtained
as the value of \code{\link{lu}(x)} for \code{x} inheriting from
\code{\linkS4class{sparseMatrix}} (often \code{\linkS4class{dgCMatrix}}).
}
\section{Methods}{
\describe{
\item{\code{determinant}}{\code{signature(from = "sparseLU", logarithm = "logical")}:
computes the determinant of the factorized matrix \eqn{A}
or its logarithm.}
\item{\code{expand}}{\code{signature(x = "sparseLU")}:
see \code{\link{expand-methods}}.}
\item{\code{expand1}}{\code{signature(x = "sparseLU")}:
see \code{\link{expand1-methods}}.}
\item{\code{expand2}}{\code{signature(x = "sparseLU")}:
see \code{\link{expand2-methods}}.}
\item{\code{solve}}{\code{signature(a = "sparseLU", b = .)}:
see \code{\link{solve-methods}}.}
}
}
\seealso{
Class \code{\linkS4class{denseLU}} for dense LU factorizations.
Class \code{\linkS4class{dgCMatrix}}.
Generic functions \code{\link{lu}},
\code{\link{expand1}} and \code{\link{expand2}}.
}
\references{
Davis, T. A. (2006).
\emph{Direct methods for sparse linear systems}.
Society for Industrial and Applied Mathematics.
\doi{10.1137/1.9780898718881}
Golub, G. H., & Van Loan, C. F. (2013).
\emph{Matrix computations} (4th ed.).
Johns Hopkins University Press.
\doi{10.56021/9781421407944}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
library(utils, pos = "package:base", verbose = FALSE)
}
showClass("sparseLU")
set.seed(2)
A <- as(readMM(system.file("external", "pores_1.mtx", package = "Matrix")),
"CsparseMatrix")
(n <- A@Dim[1L])
## With dimnames, to see that they are propagated :
dimnames(A) <- dn <- list(paste0("r", seq_len(n)),
paste0("c", seq_len(n)))
(lu.A <- lu(A))
str(e.lu.A <- expand2(lu.A), max.level = 2L)
ae1 <- function(a, b, ...) all.equal(as(a, "matrix"), as(b, "matrix"), ...)
ae2 <- function(a, b, ...) ae1(unname(a), unname(b), ...)
## A ~ P1' L U P2' in floating point
stopifnot(exprs = {
identical(names(e.lu.A), c("P1.", "L", "U", "P2."))
identical(e.lu.A[["P1."]],
new("pMatrix", Dim = c(n, n), Dimnames = c(dn[1L], list(NULL)),
margin = 1L, perm = invertPerm(lu.A@p, 0L, 1L)))
identical(e.lu.A[["P2."]],
new("pMatrix", Dim = c(n, n), Dimnames = c(list(NULL), dn[2L]),
margin = 2L, perm = invertPerm(lu.A@q, 0L, 1L)))
identical(e.lu.A[["L"]], lu.A@L)
identical(e.lu.A[["U"]], lu.A@U)
ae1(A, with(e.lu.A, P1. \%*\% L \%*\% U \%*\% P2.))
ae2(A[lu.A@p + 1L, lu.A@q + 1L], with(e.lu.A, L \%*\% U))
})
## Factorization handled as factorized matrix
b <- rnorm(n)
stopifnot(identical(det(A), det(lu.A)),
identical(solve(A, b), solve(lu.A, b)))
}
Matrix/man/formatSparseM.Rd 0000644 0001751 0000144 00000006731 14422605232 015370 0 ustar hornik users \name{formatSparseM}
\title{Formatting Sparse Numeric Matrices Utilities}
%
\keyword{character}
\keyword{print}
\keyword{utilities}
%
\alias{formatSparseM}
\alias{.formatSparseSimple}
%
\description{
Utilities for formatting sparse numeric matrices in a flexible way.
These functions are used by the \code{\link{format}} and \code{print}
methods for sparse matrices and can be applied as well to standard \R
matrices. Note that \emph{all} arguments but the first are optional.
\code{formatSparseM()} is the main \dQuote{workhorse} of
\code{\link{formatSpMatrix}}, the \code{format} method for sparse
matrices.
\code{.formatSparseSimple()} is a simple helper function, also dealing
with (short/empty) column names construction.
}
\usage{
formatSparseM(x, zero.print = ".", align = c("fancy", "right"),
m = as(x,"matrix"), asLogical=NULL, uniDiag=NULL,
digits=NULL, cx, iN0, dn = dimnames(m))
.formatSparseSimple(m, asLogical=FALSE, digits=NULL,
col.names, note.dropping.colnames = TRUE,
dn=dimnames(m))
}
\arguments{
\item{x}{an \R object inheriting from class \code{\linkS4class{sparseMatrix}}.}
\item{zero.print}{character which should be used for
\emph{structural} zeroes. The default \code{"."} may occasionally
be replaced by \code{" "} (blank); using \code{"0"} would look
almost like \code{print()}ing of non-sparse matrices.}
\item{align}{a string specifying how the \code{zero.print} codes
should be aligned, see \code{\link{formatSpMatrix}}.}
\item{m}{(optional) a (standard \R) \code{\link{matrix}} version of \code{x}.}
\item{asLogical}{should the matrix be formatted as a logical matrix
(or rather as a numeric one); mostly for \code{formatSparseM()}.}
\item{uniDiag}{logical indicating if the diagonal entries of a sparse
unit triangular or unit-diagonal matrix should be formatted as
\code{"I"} instead of \code{"1"} (to emphasize that the 1's are
\dQuote{structural}).}
\item{digits}{significant digits to use for printing, see
\code{\link{print.default}}.}
\item{cx}{(optional) character matrix; a formatted version of \code{x}, still
with strings such as \code{"0.00"} for the zeros.}
\item{iN0}{(optional) integer vector, specifying the location of the
\emph{non}-zeroes of \code{x}.}
\item{col.names, note.dropping.colnames}{see \code{\link{formatSpMatrix}}.}
\item{dn}{\code{\link{dimnames}} to be used; a list (of length two)
with row and column names (or \code{\link{NULL}}).}
}
\seealso{
\code{\link{formatSpMatrix}} which calls \code{formatSparseM()} and is
the \code{\link{format}} method for sparse matrices.\cr
\code{\link{printSpMatrix}} which is used by the (typically
implicitly called) \code{\link{show}} and \code{\link{print}} methods
for sparse matrices.
}
\value{
a character matrix like \code{cx}, where the zeros have been replaced
with (padded versions of) \code{zero.print}.
As this is a \emph{dense} matrix, do not use these functions for
really large (really) sparse matrices!
}
\author{Martin Maechler}
\examples{
m <- suppressWarnings(matrix(c(0, 3.2, 0,0, 11,0,0,0,0,-7,0), 4,9))
fm <- formatSparseM(m)
noquote(fm)
## nice, but this is nicer {with "units" vertically aligned}:
print(fm, quote=FALSE, right=TRUE)
## and "the same" as :
Matrix(m)
## align = "right" is cheaper --> the "." are not aligned:
noquote(f2 <- formatSparseM(m,align="r"))
stopifnot(f2 == fm | m == 0, dim(f2) == dim(m),
(f2 == ".") == (m == 0))
}
Matrix/man/updown-methods.Rd 0000644 0001751 0000144 00000005237 14575137654 015603 0 ustar hornik users \name{updown-methods}
\title{Updating and Downdating Sparse Cholesky Factorizations}
%
\docType{methods}
\keyword{algebra}
\keyword{array}
\keyword{methods}
%
\alias{updown}
\alias{updown-methods}
%
\alias{updown,character,ANY,ANY-method}
\alias{updown,logical,Matrix,CHMfactor-method}
\alias{updown,logical,dgCMatrix,CHMfactor-method}
\alias{updown,logical,dsCMatrix,CHMfactor-method}
\alias{updown,logical,dtCMatrix,CHMfactor-method}
\alias{updown,logical,matrix,CHMfactor-method}
%
\description{
Computes a rank-\eqn{k} update or downdate of a sparse Cholesky
factorization
\deqn{P_{1} A P_{1}' = L_{1} D L_{1}' = L L'}{P1 * A * P1' = L1 * D * L1' = L * L'}
which for some \eqn{k}-column matrix \eqn{C} is the factorization
\deqn{P_{1} (A + s C C') P_{1}' = \tilde{L}_{1} \tilde{D} \tilde{L}_{1}' = \tilde{L} \tilde{L}'}{P1 * (A + s * C * C') * P1' = L~1 * D~ * L~1' = L~ * L~'}
Here, \eqn{s = 1} for an update and \eqn{s = -1} for a downdate.
}
\usage{
updown(update, C, L)
}
\arguments{
\item{update}{a logical (\code{TRUE} or \code{FALSE}) or
character (\code{"+"} or \code{"-"}) indicating if \code{L}
should be updated (or otherwise downdated).}
\item{C}{a \link[=is.finite]{finite} matrix or
\code{\linkS4class{Matrix}} such that
\code{\link{tcrossprod}(C)} has the dimensions of \code{L}.}
\item{L}{an object of class \code{\linkS4class{dCHMsimpl}} or
\code{\linkS4class{dCHMsuper}} specifying a sparse Cholesky
factorization.}
}
\value{
A sparse Cholesky factorization with dimensions matching \code{L},
typically of class \code{\linkS4class{dCHMsimpl}}.
}
\seealso{
Classes
\code{\linkS4class{dCHMsimpl}} and \code{\linkS4class{dCHMsuper}}
and their methods, notably for generic function \code{\link{update}},
which is \emph{not} equivalent to \code{updown(update = TRUE)}.
Generic function \code{\link{Cholesky}}.
}
\author{Initial implementation by Nicholas Nagle, University of Tennessee.}
\references{
Davis, T. A., Hager, W. W. (2001).
Multiple-rank modifications of a sparse Cholesky factorization.
\emph{SIAM Journal on Matrix Analysis and Applications},
\emph{22}(4), 997-1013.
\doi{10.1137/S0895479899357346}
}
\examples{
m <- sparseMatrix(i = c(3, 1, 3:2, 2:1), p = c(0:2, 4, 4, 6), x = 1:6,
dimnames = list(LETTERS[1:3], letters[1:5]))
uc0 <- Cholesky(A <- crossprod(m) + Diagonal(5))
uc1 <- updown("+", Diagonal(5, 1), uc0)
uc2 <- updown("-", Diagonal(5, 1), uc1)
stopifnot(all.equal(uc0, uc2))
\dontshow{
if(FALSE) {
## Hmm: this loses positive definiteness:
uc2 <- updown("-", Diagonal(5, 2), uc0)
image(show(as(uc0, "CsparseMatrix")))
image(show(as(uc2, "CsparseMatrix"))) # severely negative entries
}
}
}
Matrix/man/diagU2N.Rd 0000644 0001751 0000144 00000005467 14446607050 014051 0 ustar hornik users \name{diagU2N}
\title{Transform Triangular Matrices from Unit Triangular to General Triangular and Back}
%
\keyword{array}
\keyword{attribute}
\keyword{utilities}
%
\alias{diagU2N}
\alias{diagN2U}
\alias{.diagU2N}
\alias{.diagN2U}
%
\description{
Transform a triangular matrix \code{x}, i.e., of \code{\link{class}}
\code{\linkS4class{triangularMatrix}},
from (internally!) unit triangular (\dQuote{unitriangular}) to
\dQuote{general} triangular (\code{diagU2N(x)}) or back (\code{diagN2U(x)}).
Note that the latter, \code{diagN2U(x)}, also sets the diagonal to one
in cases where \code{diag(x)} was not all one.
\code{.diagU2N(x)} and \code{.diagN2U(x)} assume \emph{without}
checking that \code{x} is a \code{\linkS4class{triangularMatrix}} with
suitable \code{diag} slot (\code{"U"} and \code{"N"}, respectively),
hence they should be used with care.
}
\usage{
diagU2N(x, cl = getClassDef(class(x)), checkDense = FALSE)
diagN2U(x, cl = getClassDef(class(x)), checkDense = FALSE)
.diagU2N(x, cl = getClassDef(class(x)), checkDense = FALSE)
.diagN2U(x, cl = getClassDef(class(x)), checkDense = FALSE)
}
\arguments{
\item{x}{a \code{\linkS4class{triangularMatrix}}, often sparse.}
\item{cl}{(optional, for speedup only:) class (definition) of \code{x}.}
\item{checkDense}{logical indicating if dense (see
\code{\linkS4class{denseMatrix}}) matrices should be considered at
all; i.e., when false, as per default, the result will be sparse even
when \code{x} is dense.}
}
\details{
The concept of unit triangular matrices with a \code{diag} slot of
\code{"U"} stems from LAPACK.
}
\note{Such internal storage details should rarely be of relevance to the
user. Hence, these functions really are rather \emph{internal}
utilities.
}
\value{
a triangular matrix of the same \code{\link{class}} but with a
different \code{diag} slot. For \code{diagU2N} (semantically) with
identical entries as \code{x}, whereas in \code{diagN2U(x)}, the
off-diagonal entries are unchanged and the diagonal is set to all
\code{1} even if it was not previously.
}
\seealso{
\code{"\linkS4class{triangularMatrix}"},
\code{"\linkS4class{dtCMatrix}"}.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
}
(T <- Diagonal(7) + triu(Matrix(rpois(49, 1/4), 7, 7), k = 1))
(uT <- diagN2U(T)) # "unitriangular"
(t.u <- diagN2U(10*T))# changes the diagonal!
stopifnot(all(T == uT), diag(t.u) == 1,
identical(T, diagU2N(uT)))
T[upper.tri(T)] <- 5 # still "dtC"
T <- diagN2U(as(T,"triangularMatrix"))
dT <- as(T, "denseMatrix") # (unitriangular)
dT.n <- diagU2N(dT, checkDense = TRUE)
sT.n <- diagU2N(dT)
stopifnot(is(dT.n, "denseMatrix"), is(sT.n, "sparseMatrix"),
dT@diag == "U", dT.n@diag == "N", sT.n@diag == "N",
all(dT == dT.n), all(dT == sT.n))
}
Matrix/man/boolmatmult-methods.Rd 0000644 0001751 0000144 00000015751 14575137654 016630 0 ustar hornik users \name{boolmatmult-methods}
\title{Boolean Arithmetic Matrix Products: \code{\%&\%} and Methods}
%
\docType{methods}
\keyword{algebra}
\keyword{array}
\keyword{logic}
\keyword{methods}
%
\alias{\%&\%}
\alias{\%&\%-methods}
\alias{boolmatmult-methods}
%
\alias{\%&\%,ANY,ANY-method}
\alias{\%&\%,ANY,Matrix-method}
\alias{\%&\%,ANY,matrix-method}
\alias{\%&\%,ANY,sparseVector-method}
\alias{\%&\%,ANY,vector-method}
\alias{\%&\%,CsparseMatrix,CsparseMatrix-method}
\alias{\%&\%,CsparseMatrix,RsparseMatrix-method}
\alias{\%&\%,CsparseMatrix,TsparseMatrix-method}
\alias{\%&\%,CsparseMatrix,denseMatrix-method}
\alias{\%&\%,CsparseMatrix,diagonalMatrix-method}
\alias{\%&\%,CsparseMatrix,matrix-method}
\alias{\%&\%,CsparseMatrix,vector-method}
\alias{\%&\%,Matrix,ANY-method}
\alias{\%&\%,Matrix,indMatrix-method}
\alias{\%&\%,Matrix,pMatrix-method}
\alias{\%&\%,Matrix,sparseVector-method}
\alias{\%&\%,RsparseMatrix,CsparseMatrix-method}
\alias{\%&\%,RsparseMatrix,RsparseMatrix-method}
\alias{\%&\%,RsparseMatrix,TsparseMatrix-method}
\alias{\%&\%,RsparseMatrix,denseMatrix-method}
\alias{\%&\%,RsparseMatrix,diagonalMatrix-method}
\alias{\%&\%,RsparseMatrix,matrix-method}
\alias{\%&\%,RsparseMatrix,vector-method}
\alias{\%&\%,TsparseMatrix,CsparseMatrix-method}
\alias{\%&\%,TsparseMatrix,RsparseMatrix-method}
\alias{\%&\%,TsparseMatrix,TsparseMatrix-method}
\alias{\%&\%,TsparseMatrix,denseMatrix-method}
\alias{\%&\%,TsparseMatrix,diagonalMatrix-method}
\alias{\%&\%,TsparseMatrix,matrix-method}
\alias{\%&\%,TsparseMatrix,vector-method}
\alias{\%&\%,denseMatrix,CsparseMatrix-method}
\alias{\%&\%,denseMatrix,RsparseMatrix-method}
\alias{\%&\%,denseMatrix,TsparseMatrix-method}
\alias{\%&\%,denseMatrix,denseMatrix-method}
\alias{\%&\%,denseMatrix,diagonalMatrix-method}
\alias{\%&\%,denseMatrix,matrix-method}
\alias{\%&\%,denseMatrix,vector-method}
\alias{\%&\%,diagonalMatrix,CsparseMatrix-method}
\alias{\%&\%,diagonalMatrix,RsparseMatrix-method}
\alias{\%&\%,diagonalMatrix,TsparseMatrix-method}
\alias{\%&\%,diagonalMatrix,denseMatrix-method}
\alias{\%&\%,diagonalMatrix,diagonalMatrix-method}
\alias{\%&\%,diagonalMatrix,matrix-method}
\alias{\%&\%,diagonalMatrix,vector-method}
\alias{\%&\%,indMatrix,Matrix-method}
\alias{\%&\%,indMatrix,indMatrix-method}
\alias{\%&\%,indMatrix,matrix-method}
\alias{\%&\%,indMatrix,pMatrix-method}
\alias{\%&\%,indMatrix,vector-method}
\alias{\%&\%,matrix,ANY-method}
\alias{\%&\%,matrix,CsparseMatrix-method}
\alias{\%&\%,matrix,RsparseMatrix-method}
\alias{\%&\%,matrix,TsparseMatrix-method}
\alias{\%&\%,matrix,denseMatrix-method}
\alias{\%&\%,matrix,diagonalMatrix-method}
\alias{\%&\%,matrix,indMatrix-method}
\alias{\%&\%,matrix,matrix-method}
\alias{\%&\%,matrix,pMatrix-method}
\alias{\%&\%,matrix,sparseVector-method}
\alias{\%&\%,matrix,vector-method}
\alias{\%&\%,pMatrix,Matrix-method}
\alias{\%&\%,pMatrix,indMatrix-method}
\alias{\%&\%,pMatrix,matrix-method}
\alias{\%&\%,pMatrix,pMatrix-method}
\alias{\%&\%,pMatrix,vector-method}
\alias{\%&\%,sparseVector,ANY-method}
\alias{\%&\%,sparseVector,Matrix-method}
\alias{\%&\%,sparseVector,matrix-method}
\alias{\%&\%,sparseVector,sparseVector-method}
\alias{\%&\%,sparseVector,vector-method}
\alias{\%&\%,vector,ANY-method}
\alias{\%&\%,vector,CsparseMatrix-method}
\alias{\%&\%,vector,RsparseMatrix-method}
\alias{\%&\%,vector,TsparseMatrix-method}
\alias{\%&\%,vector,denseMatrix-method}
\alias{\%&\%,vector,diagonalMatrix-method}
\alias{\%&\%,vector,indMatrix-method}
\alias{\%&\%,vector,matrix-method}
\alias{\%&\%,vector,pMatrix-method}
\alias{\%&\%,vector,sparseVector-method}
\alias{\%&\%,vector,vector-method}
%
\description{
For boolean or \dQuote{patter\bold{n}} matrices, i.e., \R objects of
class \code{\linkS4class{nMatrix}}, it is natural to allow matrix
products using boolean instead of numerical arithmetic.
In package \pkg{Matrix}, we use the binary operator \code{\%&\%} (aka
\dQuote{infix}) function) for this and provide methods for all our
matrices and the traditional \R matrices (see \code{\link{matrix}}).
}
\section{Methods}{
We provide methods for both the \dQuote{traditional} (\R base) matrices
and numeric vectors and conceptually all matrices and
\code{\linkS4class{sparseVector}}s in package \pkg{Matrix}.
\describe{
\item{\code{signature(x = "ANY", y = "ANY")}}{ }
\item{\code{signature(x = "ANY", y = "Matrix")}}{ }
\item{\code{signature(x = "Matrix", y = "ANY")}}{ }
\item{\code{signature(x = "nMatrix", y = "nMatrix")}}{ }
\item{\code{signature(x = "nMatrix", y = "nsparseMatrix")}}{ }
\item{\code{signature(x = "nsparseMatrix", y = "nMatrix")}}{ }
\item{\code{signature(x = "nsparseMatrix", y = "nsparseMatrix")}}{ }
\item{\code{signature(x = "sparseVector", y = "sparseVector")}}{ }
}% {describe}
}% {Methods}
\note{
These boolean arithmetic matrix products had been newly
introduced for \pkg{Matrix} 1.2.0 (March 2015). Its implementation
has still not been tested extensively.
Originally, it was left unspecified how non-structural zeros, i.e., \code{0}'s
as part of the \code{M@x} slot should be treated for numeric
(\code{"\linkS4class{dMatrix}"}) and logical (\code{"\linkS4class{lMatrix}"})
sparse matrices. We now specify that boolean matrix products should behave as if
applied to \code{\link{drop0}(M)}, i.e., as if dropping such zeros from
the matrix before using it.
\cr
Equivalently, for all matrices \code{M}, boolean arithmetic should work as if
applied to \code{M != 0} (or \code{M != FALSE}).
The current implementation ends up coercing both \code{x} and \code{y} to
(virtual) class \code{\linkS4class{nsparseMatrix}} which may be quite inefficient
for dense matrices. A future implementation may well return a matrix
with \bold{different} class, but the \dQuote{same} content, i.e., the
same matrix entries \eqn{m_ij}{m[i,j]}.
}
\seealso{
\code{\link{\%*\%}}, \code{crossprod()}, or \code{\link{tcrossprod}()},
for (regular) matrix product methods.
}
\value{
a pattern matrix, i.e., inheriting from \code{"\linkS4class{nMatrix}"},
or an \code{"\linkS4class{ldiMatrix}"} in case of a diagonal matrix.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
}
set.seed(7)
L <- Matrix(rnorm(20) > 1, 4,5)
(N <- as(L, "nMatrix"))
L. <- L; L.[1:2,1] <- TRUE; L.@x[1:2] <- FALSE; L. # has "zeros" to drop0()
D <- Matrix(round(rnorm(30)), 5,6) # -> values in -1:1 (for this seed)
L \%&\% D
stopifnot(identical(L \%&\% D, N \%&\% D),
all(L \%&\% D == as((L \%*\% abs(D)) > 0, "sparseMatrix")))
## cross products , possibly with boolArith = TRUE :
crossprod(N) # -> sparse patter'n' (TRUE/FALSE : boolean arithmetic)
crossprod(N +0) # -> numeric Matrix (with same "pattern")
stopifnot(all(crossprod(N) == t(N) \%&\% N),
identical(crossprod(N), crossprod(N +0, boolArith=TRUE)),
identical(crossprod(L), crossprod(N , boolArith=FALSE)))
crossprod(D, boolArith = TRUE) # pattern: "nsCMatrix"
crossprod(L, boolArith = TRUE) # ditto
crossprod(L, boolArith = FALSE) # numeric: "dsCMatrix"
}
Matrix/man/macros/ 0000755 0001751 0000144 00000000000 14576343415 013607 5 ustar hornik users Matrix/man/macros/local.Rd 0000644 0001751 0000144 00000001267 14520515200 015154 0 ustar hornik users %% amsmath commands supported since 4.2.2 (PDF), 4.2.0 (HTML)
%% unfortunately commands in #1 really do need 8 escapes ...
\newcommand{\Seqn}{\ifelse{latex}{\Sexpr[results=rd]{if (getRversion() >= "4.2.2") "\\\\\\\\eqn{#1}" else "\\\\\\\\verb{#2}"}}{\ifelse{html}{\Sexpr[results=rd]{if (getRversion() >= "4.2.0") "\\\\\\\\eqn{#1}" else "\\\\\\\\verb{#2}"}}{\Sexpr[results=rd]{"\\\\\\\\eqn{#2}"}}}}
\newcommand{\Sdeqn}{\ifelse{latex}{\Sexpr[results=rd]{if (getRversion() >= "4.2.2") "\\\\\\\\deqn{#1}" else "\\\\\\\\preformatted{#2}"}}{\ifelse{html}{\Sexpr[results=rd]{if (getRversion() >= "4.2.0") "\\\\\\\\deqn{#1}" else "\\\\\\\\preformatted{#2}"}}{\Sexpr[results=rd]{"\\\\\\\\deqn{#2}"}}}}
Matrix/man/colSums-methods.Rd 0000644 0001751 0000144 00000010430 14575137654 015703 0 ustar hornik users \name{colSums-methods}
\title{Form Row and Column Sums and Means}
%
\docType{methods}
\keyword{algebra}
\keyword{arith}
\keyword{array}
\keyword{methods}
%
\alias{colSums}
\alias{colSums-methods}
\alias{colMeans}
\alias{colMeans-methods}
\alias{rowSums}
\alias{rowSums-methods}
\alias{rowMeans}
\alias{rowMeans-methods}
%
\alias{colSums,CsparseMatrix-method}
\alias{colSums,RsparseMatrix-method}
\alias{colSums,TsparseMatrix-method}
\alias{colSums,denseMatrix-method}
\alias{colSums,diagonalMatrix-method}
\alias{colSums,indMatrix-method}
%
\alias{colMeans,CsparseMatrix-method}
\alias{colMeans,RsparseMatrix-method}
\alias{colMeans,TsparseMatrix-method}
\alias{colMeans,denseMatrix-method}
\alias{colMeans,diagonalMatrix-method}
\alias{colMeans,indMatrix-method}
%
\alias{rowSums,CsparseMatrix-method}
\alias{rowSums,RsparseMatrix-method}
\alias{rowSums,TsparseMatrix-method}
\alias{rowSums,denseMatrix-method}
\alias{rowSums,diagonalMatrix-method}
\alias{rowSums,indMatrix-method}
%
\alias{rowMeans,CsparseMatrix-method}
\alias{rowMeans,RsparseMatrix-method}
\alias{rowMeans,TsparseMatrix-method}
\alias{rowMeans,denseMatrix-method}
\alias{rowMeans,diagonalMatrix-method}
\alias{rowMeans,indMatrix-method}
%
\description{
Form row and column sums and means for
objects, for \code{\linkS4class{sparseMatrix}} the result may
optionally be sparse (\code{\linkS4class{sparseVector}}), too.
Row or column names are kept respectively as for \pkg{base} matrices
and \code{\link{colSums}} methods, when the result is
\code{\link{numeric}} vector.
}
\usage{
colSums(x, na.rm = FALSE, dims = 1L, \dots)
rowSums(x, na.rm = FALSE, dims = 1L, \dots)
colMeans(x, na.rm = FALSE, dims = 1L, \dots)
rowMeans(x, na.rm = FALSE, dims = 1L, \dots)
\S4method{colSums}{CsparseMatrix} (x, na.rm = FALSE, dims = 1L,
sparseResult = FALSE, \dots)
\S4method{rowSums}{CsparseMatrix} (x, na.rm = FALSE, dims = 1L,
sparseResult = FALSE, \dots)
\S4method{colMeans}{CsparseMatrix}(x, na.rm = FALSE, dims = 1L,
sparseResult = FALSE, \dots)
\S4method{rowMeans}{CsparseMatrix}(x, na.rm = FALSE, dims = 1L,
sparseResult = FALSE, \dots)
}
\arguments{
\item{x}{a Matrix, i.e., inheriting from \code{\linkS4class{Matrix}}.}
\item{na.rm}{logical. Should missing values (including \code{NaN})
be omitted from the calculations?}
\item{dims}{completely ignored by the \code{Matrix} methods.}
\item{\dots}{potentially further arguments, for method \code{<->}
generic compatibility.}
\item{sparseResult}{logical indicating if the result should be sparse,
i.e., inheriting from class \code{\linkS4class{sparseVector}}. Only
applicable when \code{x} is inheriting from a
\code{\linkS4class{sparseMatrix}} class.}
}
% \details{
% ~~ If necessary, more details than the description above ~~
% }
\value{
returns a numeric vector if \code{sparseResult} is \code{FALSE} as per
default. Otherwise, returns a \code{\linkS4class{sparseVector}}.
\code{\link{dimnames}(x)} are only kept (as \code{\link{names}(v)})
when the resulting \code{v} is \code{\link{numeric}}, since
\code{\link{sparseVector}}s do not have names.
}
%\author{Martin}
\seealso{\code{\link[base]{colSums}} and the
\code{\linkS4class{sparseVector}} classes.
}
\examples{
(M <- bdiag(Diagonal(2), matrix(1:3, 3,4), diag(3:2))) # 7 x 8
colSums(M)
d <- Diagonal(10, c(0,0,10,0,2,rep(0,5)))
MM <- kronecker(d, M)
dim(MM) # 70 80
length(MM@x) # 160, but many are '0' ; drop those:
MM <- drop0(MM)
length(MM@x) # 32
cm <- colSums(MM)
(scm <- colSums(MM, sparseResult = TRUE))
stopifnot(is(scm, "sparseVector"),
identical(cm, as.numeric(scm)))
rowSums (MM, sparseResult = TRUE) # 14 of 70 are not zero
colMeans(MM, sparseResult = TRUE) # 16 of 80 are not zero
## Since we have no 'NA's, these two are equivalent :
stopifnot(identical(rowMeans(MM, sparseResult = TRUE),
rowMeans(MM, sparseResult = TRUE, na.rm = TRUE)),
rowMeans(Diagonal(16)) == 1/16,
colSums(Diagonal(7)) == 1)
## dimnames(x) --> names( ) :
dimnames(M) <- list(paste0("r", 1:7), paste0("V",1:8))
M
colSums(M)
rowMeans(M)
## Assertions :
stopifnot(exprs = {
all.equal(colSums(M),
structure(c(1,1,6,6,6,6,3,2), names = colnames(M)))
all.equal(rowMeans(M),
structure(c(1,1,4,8,12,3,2)/8, names = paste0("r", 1:7)))
})
}
Matrix/man/CsparseMatrix-class.Rd 0000644 0001751 0000144 00000011506 14500445405 016472 0 ustar hornik users \name{CsparseMatrix-class}
\title{Class "CsparseMatrix" of Sparse Matrices in Column-compressed Form}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{CsparseMatrix-class}
%
\alias{Arith,CsparseMatrix,CsparseMatrix-method}
\alias{Arith,CsparseMatrix,numeric-method}
\alias{Arith,numeric,CsparseMatrix-method}
\alias{Compare,CsparseMatrix,CsparseMatrix-method}
\alias{Logic,CsparseMatrix,CsparseMatrix-method}
\alias{coerce,matrix,CsparseMatrix-method}
\alias{coerce,vector,CsparseMatrix-method}
\alias{diag,CsparseMatrix-method}
\alias{diag<-,CsparseMatrix-method}
\alias{t,CsparseMatrix-method}
%
\alias{.validateCsparse}
%
\description{The \code{"CsparseMatrix"} class is the virtual class of
all sparse matrices coded in sorted compressed column-oriented form.
Since it is a virtual class, no objects may be created from it. See
\code{showClass("CsparseMatrix")} for its subclasses.
}
\section{Slots}{
\describe{
\item{\code{i}:}{Object of class \code{"integer"} of length nnzero
(number of non-zero elements). These are the \emph{0-based} row numbers for
each non-zero element in the matrix, i.e., \code{i} must be in
\code{0:(nrow(.)-1)}.}
\item{\code{p}:}{\code{\link{integer}} vector for providing pointers, one
for each column, to the initial (zero-based) index of elements in
the column. \code{.@p} is of length \code{ncol(.) + 1}, with
\code{p[1] == 0} and \code{p[length(p)] == nnzero}, such that in
fact, \code{diff(.@p)} are the number of non-zero elements for
each column.
In other words, \code{m@p[1:ncol(m)]} contains the indices of
those elements in \code{m@x} that are the first elements in the
respective column of \code{m}.
}
\item{\code{Dim}, \code{Dimnames}:}{inherited from
the superclass, see the \code{\linkS4class{sparseMatrix}} class.}
}
}
\section{Extends}{
Class \code{"sparseMatrix"}, directly.
Class \code{"Matrix"}, by class \code{"sparseMatrix"}.
}
\section{Methods}{
\describe{
matrix products \code{\link[=crossprod-methods]{\%*\%}},
\code{\link[=crossprod-methods]{crossprod}()} and \code{tcrossprod()},
several \code{\link{solve}} methods,
and other matrix methods available:
%% The following is generated by promptClass(..) --
%% FIXME: write a script that update all the *-class.Rd files
\item{Arith}{\code{signature(e1 = "CsparseMatrix", e2 = "numeric")}: ... }
\item{Arith}{\code{signature(e1 = "numeric", e2 = "CsparseMatrix")}: ... }
\item{Math}{\code{signature(x = "CsparseMatrix")}: ... }
\item{band}{\code{signature(x = "CsparseMatrix")}: ... }
\item{-}{\code{signature(e1 = "CsparseMatrix", e2 = "numeric")}: ... }
\item{-}{\code{signature(e1 = "numeric", e2 = "CsparseMatrix")}: ... }
\item{+}{\code{signature(e1 = "CsparseMatrix", e2 = "numeric")}: ... }
\item{+}{\code{signature(e1 = "numeric", e2 = "CsparseMatrix")}: ... }
\item{coerce}{\code{signature(from = "CsparseMatrix", to = "TsparseMatrix")}: ... }
\item{coerce}{\code{signature(from = "CsparseMatrix", to = "denseMatrix")}: ... }
\item{coerce}{\code{signature(from = "CsparseMatrix", to = "matrix")}: ... }
\item{coerce}{\code{signature(from = "TsparseMatrix", to = "CsparseMatrix")}: ... }
\item{coerce}{\code{signature(from = "denseMatrix", to = "CsparseMatrix")}: ... }
\item{diag}{\code{signature(x = "CsparseMatrix")}: ... }
\item{gamma}{\code{signature(x = "CsparseMatrix")}: ... }
\item{lgamma}{\code{signature(x = "CsparseMatrix")}: ... }
\item{log}{\code{signature(x = "CsparseMatrix")}: ... }
\item{t}{\code{signature(x = "CsparseMatrix")}: ... }
\item{tril}{\code{signature(x = "CsparseMatrix")}: ... }
\item{triu}{\code{signature(x = "CsparseMatrix")}: ... }
}
}
\note{
All classes extending \code{CsparseMatrix} have a common validity
(see \code{\link{validObject}}) check function. That function
additionally checks the \code{i} slot for each column to contain
increasing row numbers. \cr
In earlier versions of \pkg{Matrix} (\code{<= 0.999375-16}),
\code{\link{validObject}} automatically re-sorted the entries when
necessary, and hence \code{new()} calls with somewhat permuted
\code{i} and \code{x} slots worked, as \code{\link{new}(...)}
(\emph{with} slot arguments) automatically checks the validity.
Now, you have to use \code{\link{sparseMatrix}} to achieve the same
functionality or know how to use \code{.validateCsparse()} to do so.
}
\seealso{
\code{\link{colSums}}, \code{\link{kronecker}}, and other such methods
with own help pages.
Further, the super class of \code{CsparseMatrix},
\code{\linkS4class{sparseMatrix}}, and, e.g.,
class \code{\linkS4class{dgCMatrix}} for the links to other classes.
}
\examples{
getClass("CsparseMatrix")
## The common validity check function (based on C code):
getValidity(getClass("CsparseMatrix"))
}
Matrix/man/dsCMatrix-class.Rd 0000644 0001751 0000144 00000011513 14461513642 015606 0 ustar hornik users \name{dsCMatrix-class}
\title{Numeric Symmetric Sparse (column compressed) Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{dsCMatrix-class}
\alias{dsTMatrix-class}
%
\alias{Arith,dsCMatrix,dsCMatrix-method}
\alias{determinant,dsCMatrix,logical-method}
%
\alias{determinant,dsTMatrix,logical-method}
%
\description{The \code{dsCMatrix} class is a class of symmetric, sparse
numeric matrices in the compressed, \bold{c}olumn-oriented format. In
this implementation the non-zero elements in the columns are sorted
into increasing row order.
The \code{dsTMatrix} class is the class of symmetric, sparse numeric
matrices in \bold{t}riplet format.
}
\section{Objects from the Class}{
Objects can be created by calls of the form \code{new("dsCMatrix",
...)} or \code{new("dsTMatrix", ...)}, or automatically via e.g.,
\code{as(*, "symmetricMatrix")}, or (for \code{dsCMatrix}) also
from \code{\link{Matrix}(.)}.
Creation \dQuote{from scratch} most efficiently happens via
\code{\link{sparseMatrix}(*, symmetric=TRUE)}.
}
\section{Slots}{
\describe{
\item{\code{uplo}:}{A character object indicating if the upper
triangle (\code{"U"}) or the lower triangle (\code{"L"}) is stored.}
\item{\code{i}:}{Object of class \code{"integer"} of length nnZ
(\emph{half} number of non-zero elements). These are the row
numbers for each non-zero element in the lower triangle of the matrix.}
\item{\code{p}:}{(only in class \code{"dsCMatrix"}:) an
\code{\link{integer}} vector for providing pointers, one for each
column, see the detailed description in \code{\linkS4class{CsparseMatrix}}.}
\item{\code{j}:}{(only in class \code{"dsTMatrix"}:) Object of
class \code{"integer"} of length nnZ (as \code{i}). These are the
column numbers for each non-zero element in the lower triangle of
the matrix.}
\item{\code{x}:}{Object of class \code{"numeric"} of length nnZ --
the non-zero elements of the matrix (to be duplicated for full matrix).}
\item{\code{factors}:}{Object of class \code{"list"} - a list
of factorizations of the matrix. }
\item{\code{Dim}:}{Object of class \code{"integer"} - the dimensions
of the matrix - must be an integer vector with exactly two
non-negative values.}
}
}
\section{Extends}{
Both classes extend classes and \code{\linkS4class{symmetricMatrix}}
\code{\linkS4class{dsparseMatrix}} directly;
\code{dsCMatrix} further directly extends
\code{\linkS4class{CsparseMatrix}}, where
\code{dsTMatrix} does \code{\linkS4class{TsparseMatrix}}.
}
\section{Methods}{
\describe{
\item{solve}{\code{signature(a = "dsCMatrix", b = "....")}: \code{x
<- solve(a,b)} solves \eqn{A x = b} for \eqn{x}; see
\code{\link{solve-methods}}.}
\item{chol}{\code{signature(x = "dsCMatrix", pivot = "logical")}:
Returns (and stores) the Cholesky decomposition of \code{x}, see
\code{\link{chol}}.}
\item{Cholesky}{\code{signature(A = "dsCMatrix",...)}:
Computes more flexibly Cholesky decompositions,
see \code{\link{Cholesky}}.}
\item{determinant}{\code{signature(x = "dsCMatrix", logarithm =
"missing")}: Evaluate the determinant of \code{x} on the
logarithm scale. This creates and stores the Cholesky factorization.}
\item{determinant}{\code{signature(x = "dsCMatrix", logarithm =
"logical")}: Evaluate the determinant of \code{x} on the
logarithm scale or not, according to the \code{logarithm}
argument. This creates and stores the Cholesky factorization.}
\item{t}{\code{signature(x = "dsCMatrix")}: Transpose. As for all
symmetric matrices, a matrix for which the upper triangle is
stored produces a matrix for which the lower triangle is stored
and vice versa, i.e., the \code{uplo} slot is swapped, and the row
and column indices are interchanged.}
\item{t}{\code{signature(x = "dsTMatrix")}: Transpose. The
\code{uplo} slot is swapped from \code{"U"} to \code{"L"} or vice
versa, as for a \code{"dsCMatrix"}, see above.}
}
}
%\references{}
%\author{}
%\note{}
\seealso{
Classes \code{\linkS4class{dgCMatrix}}, \code{\linkS4class{dgTMatrix}},
\code{\linkS4class{dgeMatrix}} and those mentioned above.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
mm <- Matrix(toeplitz(c(10, 0, 1, 0, 3)), sparse = TRUE)
mm # automatically dsCMatrix
str(mm)
mT <- as(as(mm, "generalMatrix"), "TsparseMatrix")
## Either
(symM <- as(mT, "symmetricMatrix")) # dsT
(symC <- as(symM, "CsparseMatrix")) # dsC
## or
sT <- Matrix(mT, sparse=TRUE, forceCheck=TRUE) # dsT
sym2 <- as(symC, "TsparseMatrix")
## --> the same as 'symM', a "dsTMatrix"
\dontshow{
stopifnot(identical(sT, symM), identical(sym2, symM),
class(sym2) == "dsTMatrix",
identical(sym2[1,], sT[1,]),
identical(sym2[,2], sT[,2]))
}
}
Matrix/man/KhatriRao.Rd 0000644 0001751 0000144 00000010561 14435451016 014470 0 ustar hornik users \name{KhatriRao}
\title{Khatri-Rao Matrix Product}
%
\keyword{algebra}
\keyword{arith}
\keyword{array}
\keyword{utilities}
%
\alias{KhatriRao}
%
\description{
Computes Khatri-Rao products for any kind of matrices.
The Khatri-Rao product is a column-wise Kronecker product. Originally
introduced by Khatri and Rao (1968), it has many different applications,
see Liu and Trenkler (2008) for a survey. Notably, it is used in
higher-dimensional tensor decompositions, see Bader and Kolda (2008).
}
\usage{
KhatriRao(X, Y = X, FUN = "*", sparseY = TRUE, make.dimnames = FALSE)
}
\arguments{
\item{X,Y}{matrices of with the same number of columns.}
\item{FUN}{the (name of the) \code{\link{function}} to be used for the
column-wise Kronecker products, see \code{\link{kronecker}},
defaulting to the usual multiplication.}
\item{sparseY}{logical specifying if \code{Y} should be coerced and
treated as \code{\linkS4class{sparseMatrix}}. Set this to
\code{FALSE}, e.g., to distinguish structural zeros from zero entries.}
\item{make.dimnames}{logical indicating if the result should inherit
\code{\link{dimnames}} from \code{X} and \code{Y} in a simple way.}
}
%\details{}
\value{
a \code{"\linkS4class{CsparseMatrix}"}, say \code{R}, the Khatri-Rao
product of \code{X} (\eqn{n \times k}{n x k}) and \code{Y} (\eqn{m
\times k}{m x k}), is of dimension \eqn{(n\cdot m) \times k}{(n*m) x k},
where the j-th column, \code{R[,j]} is the kronecker product
\code{\link{kronecker}(X[,j], Y[,j])}.
}
\note{%% TODO? Could make it generic, and have dense and sparse methods
The current implementation is efficient for large sparse matrices.
}
\references{
Khatri, C. G., and Rao, C. Radhakrishna (1968)
Solutions to Some Functional Equations and Their Applications to
Characterization of Probability Distributions.
\emph{Sankhya: Indian J. Statistics, Series A} \bold{30}, 167--180.
Bader, Brett W, and Tamara G Kolda (2008)
Efficient MATLAB Computations with Sparse and Factored Tensors.
\emph{SIAM J. Scientific Computing} \bold{30}, 205--231.
}
\author{
Original by Michael Cysouw, Univ. Marburg;
minor tweaks, bug fixes etc, by Martin Maechler.
}
\seealso{
\code{\link{kronecker}}.
}
\examples{
## Example with very small matrices:
m <- matrix(1:12,3,4)
d <- diag(1:4)
KhatriRao(m,d)
KhatriRao(d,m)
dimnames(m) <- list(LETTERS[1:3], letters[1:4])
KhatriRao(m,d, make.dimnames=TRUE)
KhatriRao(d,m, make.dimnames=TRUE)
dimnames(d) <- list(NULL, paste0("D", 1:4))
KhatriRao(m,d, make.dimnames=TRUE)
KhatriRao(d,m, make.dimnames=TRUE)
dimnames(d) <- list(paste0("d", 10*1:4), paste0("D", 1:4))
(Kmd <- KhatriRao(m,d, make.dimnames=TRUE))
(Kdm <- KhatriRao(d,m, make.dimnames=TRUE))
nm <- as(m, "nsparseMatrix")
nd <- as(d, "nsparseMatrix")
KhatriRao(nm,nd, make.dimnames=TRUE)
KhatriRao(nd,nm, make.dimnames=TRUE)
stopifnot(dim(KhatriRao(m,d)) == c(nrow(m)*nrow(d), ncol(d)))
## border cases / checks:
zm <- nm; zm[] <- FALSE # all FALSE matrix
stopifnot(all(K1 <- KhatriRao(nd, zm) == 0), identical(dim(K1), c(12L, 4L)),
all(K2 <- KhatriRao(zm, nd) == 0), identical(dim(K2), c(12L, 4L)))
d0 <- d; d0[] <- 0; m0 <- Matrix(d0[-1,])
stopifnot(all(K3 <- KhatriRao(d0, m) == 0), identical(dim(K3), dim(Kdm)),
all(K4 <- KhatriRao(m, d0) == 0), identical(dim(K4), dim(Kmd)),
all(KhatriRao(d0, d0) == 0), all(KhatriRao(m0, d0) == 0),
all(KhatriRao(d0, m0) == 0), all(KhatriRao(m0, m0) == 0),
identical(dimnames(KhatriRao(m, d0, make.dimnames=TRUE)), dimnames(Kmd)))
## a matrix with "structural" and non-structural zeros:
m01 <- new("dgCMatrix", i = c(0L, 2L, 0L, 1L), p = c(0L, 0L, 0L, 2L, 4L),
Dim = 3:4, x = c(1, 0, 1, 0))
D4 <- Diagonal(4, x=1:4) # "as" d
DU <- Diagonal(4)# unit-diagonal: uplo="U"
(K5 <- KhatriRao( d, m01))
K5d <- KhatriRao( d, m01, sparseY=FALSE)
K5Dd <- KhatriRao(D4, m01, sparseY=FALSE)
K5Ud <- KhatriRao(DU, m01, sparseY=FALSE)
(K6 <- KhatriRao(diag(3), t(m01)))
K6D <- KhatriRao(Diagonal(3), t(m01))
K6d <- KhatriRao(diag(3), t(m01), sparseY=FALSE)
K6Dd <- KhatriRao(Diagonal(3), t(m01), sparseY=FALSE)
stopifnot(exprs = {
all(K5 == K5d)
identical(cbind(c(7L, 10L), c(3L, 4L)),
which(K5 != 0, arr.ind = TRUE, useNames=FALSE))
identical(K5d, K5Dd)
identical(K6, K6D)
all(K6 == K6d)
identical(cbind(3:4, 1L),
which(K6 != 0, arr.ind = TRUE, useNames=FALSE))
identical(K6d, K6Dd)
})
}
Matrix/man/nsparseMatrix-class.Rd 0000644 0001751 0000144 00000013413 14575324114 016551 0 ustar hornik users \name{nsparseMatrix-class}
\title{Sparse "pattern" Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{nsparseMatrix-class}
\alias{nsparseMatrix-classes} % used by package 'arules'
\alias{ngCMatrix-class}
\alias{ngRMatrix-class}
\alias{ngTMatrix-class}
\alias{ntCMatrix-class}
\alias{ntRMatrix-class}
\alias{ntTMatrix-class}
\alias{nsCMatrix-class}
\alias{nsRMatrix-class}
\alias{nsTMatrix-class}
% nsparse
\alias{!,nsparseMatrix-method}
\alias{-,nsparseMatrix,missing-method}
\alias{Arith,nsparseMatrix,Matrix-method}
\alias{Arith,dsparseMatrix,nsparseMatrix-method}
\alias{Arith,lsparseMatrix,nsparseMatrix-method}
\alias{Arith,nsparseMatrix,dsparseMatrix-method}
\alias{Arith,nsparseMatrix,lsparseMatrix-method}
\alias{Ops,nsparseMatrix,dsparseMatrix-method}
\alias{Ops,nsparseMatrix,lsparseMatrix-method}
\alias{Ops,nsparseMatrix,sparseMatrix-method}
\alias{coerce,matrix,nsparseMatrix-method}
\alias{coerce,nsparseMatrix,indMatrix-method}
\alias{coerce,nsparseMatrix,pMatrix-method}
\alias{coerce,vector,nsparseMatrix-method}
\alias{which,nsparseMatrix-method}
% ngC
% ngR
% ngT
% ntC
% ntR
% ntT
% nsC
% nsR
% nsT
%
\description{The \code{nsparseMatrix} class is a virtual class of sparse
\emph{\dQuote{pattern}} matrices, i.e., binary matrices conceptually
with \code{TRUE}/\code{FALSE} entries. Only the positions of the
elements that are \code{TRUE} are stored.
These can be stored in the \dQuote{triplet} form
(\code{\linkS4class{TsparseMatrix}}, subclasses \code{ngTMatrix},
\code{nsTMatrix}, and \code{ntTMatrix} which really contain pairs, not
triplets) or in compressed column-oriented form (class
\code{\linkS4class{CsparseMatrix}}, subclasses \code{ngCMatrix},
\code{nsCMatrix}, and \code{ntCMatrix}) or--\emph{rarely}--in
compressed row-oriented form (class \code{\linkS4class{RsparseMatrix}},
subclasses \code{ngRMatrix}, \code{nsRMatrix}, and \code{ntRMatrix}).
The second letter in the name of these non-virtual classes indicates
\code{g}eneral, \code{s}ymmetric, or \code{t}riangular.
}
\section{Objects from the Class}{
Objects can be created by calls of the form \code{new("ngCMatrix",
...)} and so on. More frequently objects are created by coercion of
a numeric sparse matrix to the pattern form for use in
the symbolic analysis phase
of an algorithm involving sparse matrices. Such algorithms often
involve two phases: a symbolic phase wherein the positions of the
non-zeros in the result are determined and a numeric phase wherein the
actual results are calculated. During the symbolic phase only the
positions of the non-zero elements in any operands are of interest,
hence numeric sparse matrices can be treated as sparse pattern
matrices.
}
\section{Slots}{
\describe{
\item{\code{uplo}:}{Object of class \code{"character"}. Must be
either "U", for upper triangular, and "L", for lower
triangular. Present in the triangular and symmetric classes but not
in the general class.}
\item{\code{diag}:}{Object of class \code{"character"}. Must be
either \code{"U"}, for unit triangular (diagonal is all ones), or
\code{"N"} for non-unit. The implicit diagonal elements are not
explicitly stored when \code{diag} is \code{"U"}. Present in the
triangular classes only.}
\item{\code{p}:}{Object of class \code{"integer"} of pointers, one
for each column (row), to the initial (zero-based) index of elements in
the column. Present in compressed column-oriented and compressed
row-oriented forms only.}
\item{\code{i}:}{Object of class \code{"integer"} of length nnzero
(number of non-zero elements). These are the row numbers for
each TRUE element in the matrix. All other elements are FALSE.
Present in triplet and compressed column-oriented forms only.}
\item{\code{j}:}{Object of class \code{"integer"} of length nnzero
(number of non-zero elements). These are the column numbers for
each TRUE element in the matrix. All other elements are FALSE.
Present in triplet and compressed row-oriented forms only.}
\item{\code{Dim}:}{Object of class \code{"integer"} - the dimensions
of the matrix.}
}
}
\section{Methods}{
\describe{
\item{coerce}{\code{signature(from = "dgCMatrix", to =
"ngCMatrix")}, and many similar ones; typically you should
coerce to \code{"nsparseMatrix"} (or \code{"nMatrix"}). Note that
coercion to a sparse pattern matrix records all the potential
non-zero entries, i.e., explicit (\dQuote{non-structural}) zeroes
are coerced to \code{TRUE}, not \code{FALSE}, see the example.
}
\item{t}{\code{signature(x = "ngCMatrix")}: returns the transpose
of \code{x}}
\item{which}{\code{signature(x = "lsparseMatrix")}, semantically
equivalent to \pkg{base} function \code{\link{which}(x, arr.ind)};
for details, see the \code{\linkS4class{lMatrix}} class documentation.}
}
}
%\references{}
%\author{}
%\note{}
\seealso{
the class \code{\linkS4class{dgCMatrix}}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
(m <- Matrix(c(0,0,2:0), 3,5, dimnames=list(LETTERS[1:3],NULL)))
## ``extract the nonzero-pattern of (m) into an nMatrix'':
nm <- as(m, "nsparseMatrix") ## -> will be a "ngCMatrix"
str(nm) # no 'x' slot
nnm <- !nm # no longer sparse
## consistency check:
stopifnot(xor(as( nm, "matrix"),
as(nnm, "matrix")))
## low-level way of adding "non-structural zeros" :
nnm <- as(nnm, "lsparseMatrix") # "lgCMatrix"
nnm@x[2:4] <- c(FALSE, NA, NA)
nnm
as(nnm, "nMatrix") # NAs *and* non-structural 0 |---> 'TRUE'
data(KNex, package = "Matrix")
nmm <- as(KNex $ mm, "nMatrix")
str(xlx <- crossprod(nmm))# "nsCMatrix"
stopifnot(isSymmetric(xlx))
image(xlx, main=paste("crossprod(nmm) : Sparse", class(xlx)))
}
Matrix/man/rsparsematrix.Rd 0000644 0001751 0000144 00000006231 14446607050 015512 0 ustar hornik users \name{rsparsematrix}
\title{Random Sparse Matrix}
%
\keyword{array}
\keyword{distribution}
\keyword{utilities}
%
\alias{rsparsematrix}
%
\description{
Generate a random sparse matrix efficiently. The default has rounded
gaussian non-zero entries, and \code{rand.x = NULL} generates random
patter\bold{n} matrices, i.e. inheriting from \code{\linkS4class{nsparseMatrix}}.
}
\usage{
rsparsematrix(nrow, ncol, density, nnz = round(density * maxE),
symmetric = FALSE,
rand.x = function(n) signif(rnorm(n), 2), \dots)
}
\arguments{
\item{nrow, ncol}{number of rows and columns, i.e., the matrix
dimension (\code{\link{dim}}).}
\item{density}{optional number in \eqn{[0,1]}, the density is the
proportion of non-zero entries among all matrix entries. If
specified it determines the default for \code{nnz}, otherwise
\code{nnz} needs to be specified.}
\item{nnz}{number of non-zero entries, for a sparse matrix typically
considerably smaller than \code{nrow*ncol}. Must be specified if
\code{density} is not.}
\item{symmetric}{logical indicating if result should be a matrix of
class \code{\linkS4class{symmetricMatrix}}. Note that in the symmetric
case, \code{nnz} denotes the number of non zero entries of the upper
(or lower) part of the matrix, including the diagonal.}
\item{rand.x}{\code{\link{NULL}} or the random number generator for the \code{x} slot, a
\code{\link{function}} such that \code{rand.x(n)} generates a
numeric vector of length \code{n}. Typical examples are
\code{rand.x = rnorm}, or \code{rand.x = runif}; the default is nice
for didactical purposes.}
\item{\dots}{optionally further arguments passed to
\code{\link{sparseMatrix}()}, notably \code{repr}.}
}
\details{
The algorithm first samples \dQuote{encoded} \eqn{(i,j)}s without
replacement, via one dimensional indices, if not \code{symmetric}
\code{\link{sample.int}(nrow*ncol, nnz)}, then---if \code{rand.x} is
not \code{NULL}---gets \code{x <- rand.x(nnz)} and calls
\code{\link{sparseMatrix}(i=i, j=j, x=x, ..)}. When
\code{rand.x=NULL}, \code{\link{sparseMatrix}(i=i, j=j, ..)} will
return a patter\bold{n} matrix (i.e., inheriting from
\code{\linkS4class{nsparseMatrix}}).
}
\value{
a \code{\linkS4class{sparseMatrix}}, say \code{M} of dimension (nrow,
ncol), i.e., with \code{dim(M) == c(nrow, ncol)}, if \code{symmetric}
is not true, with \code{nzM <- \link{nnzero}(M)} fulfilling
\code{nzM <= nnz} and typically, \code{nzM == nnz}.
}
\author{Martin Maechler}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
}
set.seed(17)# to be reproducible
M <- rsparsematrix(8, 12, nnz = 30) # small example, not very sparse
M
M1 <- rsparsematrix(1000, 20, nnz = 123, rand.x = runif)
summary(M1)
## a random *symmetric* Matrix
(S9 <- rsparsematrix(9, 9, nnz = 10, symmetric=TRUE)) # dsCMatrix
nnzero(S9)# ~ 20: as 'nnz' only counts one "triangle"
## a random patter*n* aka boolean Matrix (no 'x' slot):
(n7 <- rsparsematrix(5, 12, nnz = 10, rand.x = NULL))
## a [T]riplet representation sparseMatrix:
T2 <- rsparsematrix(40, 12, nnz = 99, repr = "T")
head(T2)
}
Matrix/man/Matrix-defunct.Rd 0000644 0001751 0000144 00000001727 14576343374 015517 0 ustar hornik users \name{Matrix-defunct}
\title{Defunct Functions in Package \pkg{Matrix}}
\alias{Matrix-defunct}
%
\alias{cBind}
\alias{rBind}
%
\description{
The functions or variables listed here are no longer part of
\pkg{Matrix} as they are no longer needed.
}
\usage{
## Defunct in 1.3-3
rBind(..., deparse.level = 1)
cBind(..., deparse.level = 1)
}
\details{
These either are stubs reporting that they are defunct, or
have been removed completely (apart from being documented here).
\code{rBind} and \code{cBind} were provided for \R{} versions
older than 3.2.0 as substitutes for the \pkg{base} analogues
\code{rbind} and \code{cbind}, which at that time were not
\dQuote{S4-aware} and so could not be used to vertically or
horizontally concatenate \code{"\linkS4class{Matrix}"} objects
together with traditional matrices and vectors.
}
\seealso{
\code{\link{Defunct}},
\code{\link{base-defunct}},
\code{\link{Matrix-deprecated}}
}
\keyword{internal}
\keyword{misc}
Matrix/man/spMatrix.Rd 0000644 0001751 0000144 00000005727 14467047212 014427 0 ustar hornik users \name{spMatrix}
\title{Sparse Matrix Constructor From Triplet}
%
\keyword{array}
\keyword{utilities}
%
\alias{spMatrix}
%
\description{
User friendly construction of a sparse matrix (inheriting from class
\code{\linkS4class{TsparseMatrix}}) from the triplet representation.
This is much less flexible than \code{\link{sparseMatrix}()} and hence
somewhat \emph{deprecated}.
}
\usage{
spMatrix(nrow, ncol, i = integer(0L), j = integer(0L), x = double(0L))
}
\arguments{
\item{nrow, ncol}{integers specifying the desired number of rows and
columns.}
\item{i,j}{integer vectors of the same length specifying the locations
of the non-zero (or non-\code{TRUE}) entries of the matrix.}
\item{x}{atomic vector of the same length as \code{i} and \code{j},
specifying the values of the non-zero entries.}
}
\value{
A sparse matrix in triplet form, as an \R object inheriting from both
\code{\linkS4class{TsparseMatrix}} and
\code{\linkS4class{generalMatrix}}.
The matrix \eqn{M} will have
\code{M[i[k], j[k]] == x[k]}, for \eqn{k = 1,2,\ldots, n}, where
\code{n = length(i)} and
\code{M[ i', j' ] == 0} for all other pairs \eqn{(i',j')}.
}
\seealso{\code{\link{Matrix}(*, sparse=TRUE)} for the more usual
constructor of such matrices. Then, \code{\link{sparseMatrix}}
is more general and flexible than \code{spMatrix()} and by default
returns a \code{\linkS4class{CsparseMatrix}} which is often slightly
more desirable. Further, \code{\link{bdiag}} and
\code{\link{Diagonal}} for (block-)diagonal matrix constructors.
Consider \code{\linkS4class{TsparseMatrix}} and similar class
definition help files.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
library(utils, pos = "package:base", verbose = FALSE)
}
## simple example
A <- spMatrix(10,20, i = c(1,3:8),
j = c(2,9,6:10),
x = 7 * (1:7))
A # a "dgTMatrix"
summary(A)
str(A) # note that *internally* 0-based indices (i,j) are used
L <- spMatrix(9, 30, i = rep(1:9, 3), 1:27,
(1:27) \%\% 4 != 1)
L # an "lgTMatrix"
## A simplified predecessor of Matrix' rsparsematrix() function :
rSpMatrix <- function(nrow, ncol, nnz,
rand.x = function(n) round(rnorm(nnz), 2))
{
## Purpose: random sparse matrix
## --------------------------------------------------------------
## Arguments: (nrow,ncol): dimension
## nnz : number of non-zero entries
## rand.x: random number generator for 'x' slot
## --------------------------------------------------------------
## Author: Martin Maechler, Date: 14.-16. May 2007
stopifnot((nnz <- as.integer(nnz)) >= 0,
nrow >= 0, ncol >= 0, nnz <= nrow * ncol)
spMatrix(nrow, ncol,
i = sample(nrow, nnz, replace = TRUE),
j = sample(ncol, nnz, replace = TRUE),
x = rand.x(nnz))
}
M1 <- rSpMatrix(100000, 20, nnz = 200)
summary(M1)
}
Matrix/man/is.na-methods.Rd 0000644 0001751 0000144 00000005533 14473267633 015274 0 ustar hornik users \name{is.na-methods}
\title{is.na(), is.finite() Methods for 'Matrix' Objects}
%
\docType{methods}
\keyword{NA}
\keyword{math}
\keyword{programming}
\keyword{methods}
%
\alias{anyNA}
\alias{anyNA-methods}
\alias{is.na}
\alias{is.na-methods}
\alias{is.nan}
\alias{is.nan-methods}
\alias{is.infinite}
\alias{is.infinite-methods}
\alias{is.finite}
\alias{is.finite-methods}
%
\alias{anyNA,denseMatrix-method}
\alias{anyNA,diagonalMatrix-method}
\alias{anyNA,indMatrix-method}
\alias{anyNA,sparseMatrix-method}
\alias{anyNA,sparseVector-method}
%
\alias{is.na,abIndex-method}
\alias{is.na,denseMatrix-method}
\alias{is.na,diagonalMatrix-method}
\alias{is.na,indMatrix-method}
\alias{is.na,sparseMatrix-method}
\alias{is.na,sparseVector-method}
%
\alias{is.nan,denseMatrix-method}
\alias{is.nan,diagonalMatrix-method}
\alias{is.nan,indMatrix-method}
\alias{is.nan,sparseMatrix-method}
\alias{is.nan,sparseVector-method}
%
\alias{is.infinite,abIndex-method}
\alias{is.infinite,denseMatrix-method}
\alias{is.infinite,diagonalMatrix-method}
\alias{is.infinite,indMatrix-method}
\alias{is.infinite,sparseMatrix-method}
\alias{is.infinite,sparseVector-method}
%
\alias{is.finite,abIndex-method}
\alias{is.finite,denseMatrix-method}
\alias{is.finite,diagonalMatrix-method}
\alias{is.finite,indMatrix-method}
\alias{is.finite,sparseMatrix-method}
\alias{is.finite,sparseVector-method}
%
\description{
Methods for generic functions \code{\link{anyNA}()},
\code{\link{is.na}()}, \code{\link{is.nan}()},
\code{\link{is.infinite}()}, and \code{\link{is.finite}()},
for objects inheriting from virtual class
\code{\linkS4class{Matrix}} or \code{\linkS4class{sparseVector}}.
}
\usage{
\S4method{is.na}{denseMatrix}(x)
\S4method{is.na}{sparseMatrix}(x)
\S4method{is.na}{diagonalMatrix}(x)
\S4method{is.na}{indMatrix}(x)
\S4method{is.na}{sparseVector}(x)
## ...
## and likewise for anyNA, is.nan, is.infinite, is.finite
}
\arguments{
\item{x}{an \R object, here a sparse or dense matrix or vector.}
}
\value{
For \code{is.*()}, an \code{\linkS4class{nMatrix}} or
\code{\linkS4class{nsparseVector}} matching the dimensions
of \code{x} and specifying the positions in \code{x} of
(some subset of) \code{\link{NA}}, \code{\link{NaN}},
\code{\link{Inf}}, and \code{-Inf}.
For \code{anyNA}(), \code{TRUE} if \code{x} contains \code{NA}
or \code{NaN} and \code{FALSE} otherwise.
}
\seealso{
\code{\link{NA}}, \code{\link{NaN}}, \code{\link{Inf}}
}
\examples{
(M <- Matrix(1:6, nrow = 4, ncol = 3,
dimnames = list(letters[1:4], LETTERS[1:3])))
stopifnot(!anyNA(M), !any(is.na(M)))
M[2:3, 2] <- NA
(inM <- is.na(M))
stopifnot(anyNA(M), sum(inM) == 2)
(A <- spMatrix(nrow = 10, ncol = 20,
i = c(1, 3:8), j = c(2, 9, 6:10), x = 7 * (1:7)))
stopifnot(!anyNA(A), !any(is.na(A)))
A[2, 3] <- A[1, 2] <- A[5, 5:9] <- NA
(inA <- is.na(A))
stopifnot(anyNA(A), sum(inA) == 1 + 1 + 5)
}
Matrix/man/symmpart-methods.Rd 0000644 0001751 0000144 00000005056 14575137654 016142 0 ustar hornik users \name{symmpart-methods}
\title{Symmetric Part and Skew(symmetric) Part of a Matrix}
%
\docType{methods}
\keyword{algebra}
\keyword{arith}
\keyword{array}
\keyword{methods}
%
\alias{symmpart}
\alias{symmpart-methods}
\alias{skewpart}
\alias{skewpart-methods}
%
\alias{symmpart,CsparseMatrix-method}
\alias{symmpart,RsparseMatrix-method}
\alias{symmpart,TsparseMatrix-method}
\alias{symmpart,denseMatrix-method}
\alias{symmpart,diagonalMatrix-method}
\alias{symmpart,indMatrix-method}
\alias{symmpart,matrix-method}
%
\alias{skewpart,CsparseMatrix-method}
\alias{skewpart,RsparseMatrix-method}
\alias{skewpart,TsparseMatrix-method}
\alias{skewpart,denseMatrix-method}
\alias{skewpart,diagonalMatrix-method}
\alias{skewpart,indMatrix-method}
\alias{skewpart,matrix-method}
%
\description{
\code{symmpart(x)} computes the symmetric part \code{(x + t(x))/2} and
\code{skewpart(x)} the
skew symmetric part \code{(x - t(x))/2} of a square matrix \code{x},
more efficiently for specific Matrix classes.
Note that \code{x == symmpart(x) + skewpart(x)} for all square
matrices -- apart from extraneous \code{\link{NA}} values in the RHS.
}
\usage{
symmpart(x)
skewpart(x)
}
\arguments{
\item{x}{a \emph{square} matrix; either \dQuote{traditional} of class
\code{"matrix"}, or typically, inheriting from the
\code{\linkS4class{Matrix}} class.}
}
\details{
These are generic functions with several methods for different matrix
classes, use e.g., \code{\link{showMethods}(symmpart)} to see them.
If the row and column names differ, the result will use the column
names unless they are (partly) \code{NULL} where the row names are
non-\code{NULL} (see also the examples).
}
\value{
\code{symmpart(x)} returns a symmetric matrix,
inheriting from \code{\linkS4class{symmetricMatrix}}
or \code{\linkS4class{diagonalMatrix}} if \code{x}
inherits from \code{Matrix}.
\code{skewpart(x)} returns a skew-symmetric matrix,
inheriting from \code{\linkS4class{generalMatrix}},
\code{\linkS4class{symmetricMatrix}} or
\code{\linkS4class{diagonalMatrix}} if \code{x}
inherits from \code{Matrix}.
}
\seealso{\code{\link{isSymmetric}}.}
\examples{
m <- Matrix(1:4, 2,2)
symmpart(m)
skewpart(m)
stopifnot(all(m == symmpart(m) + skewpart(m)))
dn <- dimnames(m) <- list(row = c("r1", "r2"), col = c("var.1", "var.2"))
stopifnot(all(m == symmpart(m) + skewpart(m)))
colnames(m) <- NULL
stopifnot(all(m == symmpart(m) + skewpart(m)))
dimnames(m) <- unname(dn)
stopifnot(all(m == symmpart(m) + skewpart(m)))
## investigate the current methods:
showMethods(skewpart, include = TRUE)
}
Matrix/man/generalMatrix-class.Rd 0000644 0001751 0000144 00000002567 14575137654 016536 0 ustar hornik users \name{generalMatrix-class}
\title{Class "generalMatrix" of General Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{generalMatrix-class}
%
\alias{coerce,generalMatrix,packedMatrix-method}
\alias{coerce,matrix,generalMatrix-method}
\alias{coerce,vector,generalMatrix-method}
\alias{dimnames<-,generalMatrix,NULL-method}
\alias{dimnames<-,generalMatrix,list-method}
%
\description{
Virtual class of \dQuote{general} matrices; i.e., matrices
that do not have a known property such as symmetric, triangular, or
diagonal.
}
\section{Objects from the Class}{A virtual Class: No objects may be created from it.}
\section{Slots}{
\describe{
\item{\code{Dim, Dimnames}}{inherited from virtual class
\code{\linkS4class{Matrix}}.}
\item{\code{factors}}{a list of
\code{\linkS4class{MatrixFactorization}} objects caching
factorizations of the matrix. Typically, it is initialized
as an empty list and updated \dQuote{automagically} whenever
a factorization is computed.}
}
}
\section{Extends}{
Class \code{"Matrix"}, directly.
}
% \section{Methods}{
% No methods defined with class "generalMatrix" in the signature.
% }
\seealso{
Virtual classes
\code{\linkS4class{symmetricMatrix}},
\code{\linkS4class{triangularMatrix}}, and
\code{\linkS4class{diagonalMatrix}}.
}
% \examples{
% ##---- Should be DIRECTLY executable !! ----
% }
Matrix/man/packedMatrix-class.Rd 0000644 0001751 0000144 00000004070 14574651323 016330 0 ustar hornik users \name{packedMatrix-class}
\title{Virtual Class \code{"packedMatrix"} of Packed Dense Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{packedMatrix-class}
%
\alias{coerce,matrix,packedMatrix-method}
\alias{cov2cor,packedMatrix-method}
%
\description{
Class \code{"packedMatrix"} is the \emph{virtual} class of dense
symmetric or triangular matrices in "packed" format, storing only
the \code{choose(n+1,2) == n*(n+1)/2} elements of the upper or
lower triangle of an \code{n}-by-\code{n} matrix. It is used to
define common methods for efficient subsetting, transposing, etc.
of its \emph{proper} subclasses: currently \code{"[dln]spMatrix"}
(packed symmetric), \code{"[dln]tpMatrix"} (packed triangular),
and subclasses of these, such as
\code{"\linkS4class{dppMatrix}"}.
}
\section{Slots}{
\describe{
\item{\code{uplo}:}{\code{"character"}; either "U", for upper triangular, and "L", for lower.}
\item{\code{Dim}, \code{Dimnames}:}{as all \code{\linkS4class{Matrix}} objects.}
}
}
\section{Extends}{
Class \code{"\linkS4class{denseMatrix}"}, directly.
Class \code{"\linkS4class{Matrix}"}, by class \code{"denseMatrix"},
distance 2.
}
\section{Methods}{
\describe{
\item{pack}{\code{signature(x = "packedMatrix")}: ... }
\item{unpack}{\code{signature(x = "packedMatrix")}: ... }
\item{isSymmetric}{\code{signature(object = "packedMatrix")}: ... }
\item{isTriangular}{\code{signature(object = "packedMatrix")}: ... }
\item{isDiagonal}{\code{signature(object = "packedMatrix")}: ... }
\item{t}{\code{signature(x = "packedMatrix")}: ... }
\item{diag}{\code{signature(x = "packedMatrix")}: ... }
\item{diag<-}{\code{signature(x = "packedMatrix")}: ... }
}
}
%% \references{
%% }
\author{Mikael Jagan}
%% \note{
%% }
\seealso{
\code{\link{pack}} and \code{\link{unpack}}; its virtual "complement"
\code{"\linkS4class{unpackedMatrix}"}; its proper subclasses
\code{"\linkS4class{dspMatrix}"}, \code{"\linkS4class{ltpMatrix}"}, etc.
}
\examples{
showClass("packedMatrix")
showMethods(classes = "packedMatrix")
}
Matrix/man/is.null.DN.Rd 0000644 0001751 0000144 00000004073 14446607050 014474 0 ustar hornik users \name{is.null.DN}
\title{Are the Dimnames \code{dn} NULL-like ?}
%
\keyword{array}
\keyword{attribute}
\keyword{programming}
\keyword{utilities}
%
\alias{is.null.DN}
%
\description{
Are the \code{\link{dimnames}} \code{dn} \code{\link{NULL}}-like?
\code{is.null.DN(dn)} is less strict than \code{\link{is.null}(dn)},
because it is also true (\code{\link{TRUE}}) when the dimnames
\code{dn} are \dQuote{like} \code{NULL}, or \code{list(NULL,NULL)}, as
they can easily be for the traditional \R matrices
(\code{\link{matrix}}) which have no formal \code{\link{class}}
definition, and hence much freedom in how their \code{\link{dimnames}}
look like.
}
\usage{
is.null.DN(dn)
}
\arguments{
\item{dn}{\code{\link{dimnames}()} of a \code{\link{matrix}}-like \R
object.
}
}
\note{
This function is really to be used on \dQuote{traditional} matrices
rather than those inheriting from \code{\linkS4class{Matrix}}, as
the latter will always have dimnames \code{list(NULL,NULL)} exactly,
in such a case.
}
\value{
\code{\link{logical}} \code{\link{TRUE}} or \code{\link{FALSE}}.
}
%% \details{
%% }
\author{Martin Maechler}
\seealso{
\code{\link{is.null}},
\code{\link{dimnames}}, \code{\link{matrix}}.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
library(utils, pos = "package:base", verbose = FALSE)
}
m1 <- m2 <- m3 <- m4 <- m <-
matrix(round(100 * rnorm(6)), 2, 3)
dimnames(m1) <- list(NULL, NULL)
dimnames(m2) <- list(NULL, character())
dimnames(m3) <- rev(dimnames(m2))
dimnames(m4) <- rep(list(character()),2)
m4 # prints absolutely identically to m
c.o <- capture.output
cm <- c.o(m)
stopifnot(exprs = {
m == m1; m == m2; m == m3; m == m4
identical(cm, c.o(m1)); identical(cm, c.o(m2))
identical(cm, c.o(m3)); identical(cm, c.o(m4))
})
hasNoDimnames <- function(.) is.null.DN(dimnames(.))
stopifnot(exprs = {
hasNoDimnames(m)
hasNoDimnames(m1); hasNoDimnames(m2)
hasNoDimnames(m3); hasNoDimnames(m4)
hasNoDimnames(Matrix(m) -> M)
hasNoDimnames(as(M, "sparseMatrix"))
})
}
Matrix/man/RsparseMatrix-class.Rd 0000644 0001751 0000144 00000004165 14467224234 016523 0 ustar hornik users \name{RsparseMatrix-class}
\title{Class "RsparseMatrix" of Sparse Matrices in Row-compressed Form}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{RsparseMatrix-class}
%
\alias{coerce,matrix,RsparseMatrix-method}
\alias{coerce,vector,RsparseMatrix-method}
\alias{diag,RsparseMatrix-method}
\alias{diag<-,RsparseMatrix-method}
\alias{t,RsparseMatrix-method}
%
\description{The \code{"RsparseMatrix"} class is the virtual class of
all sparse matrices coded in sorted compressed row-oriented form.
Since it is a virtual class, no objects may be created from it. See
\code{showClass("RsparseMatrix")} for its subclasses.
}
\section{Slots}{
\describe{
\item{\code{j}:}{Object of class \code{"integer"} of length \code{nnzero}
(number of non-zero elements). These are the row numbers for
each non-zero element in the matrix.}
\item{\code{p}:}{Object of class \code{"integer"} of pointers, one
for each row, to the initial (zero-based) index of elements in
the row.}
\item{\code{Dim}, \code{Dimnames}:}{inherited from
the superclass, see \code{\linkS4class{sparseMatrix}}.}
}
}
\section{Extends}{
Class \code{"sparseMatrix"}, directly.
Class \code{"Matrix"}, by class \code{"sparseMatrix"}.
}
\section{Methods}{
Originally, \bold{few} methods were defined on purpose, as we
rather use the \code{\linkS4class{CsparseMatrix}} in \pkg{Matrix}.
Then, more methods were added but \emph{beware} that these
typically do \emph{not} return \code{"RsparseMatrix"} results, but
rather Csparse* or Tsparse* ones; e.g., \code{R[i, j] <- v} for an
\code{"RsparseMatrix"} \code{R} works, but after the assignment, \code{R}
is a (triplet) \code{"TsparseMatrix"}.
\describe{
\item{t}{\code{signature(x = "RsparseMatrix")}: ... }
\item{coerce}{\code{signature(from = "RsparseMatrix", to = "CsparseMatrix")}: ... }
\item{coerce}{\code{signature(from = "RsparseMatrix", to = "TsparseMatrix")}: ... }
}
}
\seealso{
its superclass, \code{\linkS4class{sparseMatrix}}, and, e.g., class
\code{\linkS4class{dgRMatrix}} for the links to other classes.
}
\examples{
showClass("RsparseMatrix")
}
Matrix/man/rankMatrix.Rd 0000644 0001751 0000144 00000021036 14516234475 014733 0 ustar hornik users \name{rankMatrix}
\title{Rank of a Matrix}
%
\keyword{algebra}
\keyword{utilities}
%
\alias{rankMatrix}
\alias{qr2rankMatrix}
%
\description{
Compute \sQuote{the} matrix rank, a well-defined functional in theory(*),
somewhat ambiguous in practice. We provide several methods, the
default corresponding to Matlab's definition.
(*) The rank of a \eqn{n \times m}{n x m} matrix \eqn{A}, \eqn{rk(A)},
is the maximal number of linearly independent columns (or rows); hence
\eqn{rk(A) \le min(n,m)}{rk(A) <= min(n,m)}.
}
\usage{
rankMatrix(x, tol = NULL,
method = c("tolNorm2", "qr.R", "qrLINPACK", "qr",
"useGrad", "maybeGrad"),
sval = svd(x, 0, 0)$d, warn.t = TRUE, warn.qr = TRUE)
qr2rankMatrix(qr, tol = NULL, isBqr = is.qr(qr), do.warn = TRUE)
}
\arguments{
\item{x}{numeric matrix, of dimension \eqn{n \times m}{n x m}, say.}
\item{tol}{nonnegative number specifying a (relative,
\dQuote{scalefree}) tolerance for testing of
\dQuote{practically zero} with specific meaning depending on
\code{method}; by default, \code{max(dim(x)) * \link{.Machine}$double.eps}
is according to Matlab's default (for its only method which is our
\code{method="tolNorm2"}).}
\item{method}{a character string specifying the computational method
for the rank, can be abbreviated:
\describe{
\item{\code{"tolNorm2"}:}{the number of singular values
\code{>= tol * max(sval)};}
\item{\code{"qrLINPACK"}:}{for a dense matrix, this is the rank of
\code{\link[base]{qr}(x, tol, LAPACK=FALSE)} (which is
\code{qr(...)$rank});
\cr
This ("qr*", dense) version used to be \emph{the} recommended way to
compute a matrix rank for a while in the past.
For sparse \code{x}, this is equivalent to \code{"qr.R"}.
}
\item{\code{"qr.R"}:}{this is the rank of triangular matrix
\eqn{R}, where \code{qr()} uses LAPACK or a "sparseQR" method
(see \code{\link{qr-methods}}) to compute the decomposition
\eqn{QR}. The rank of \eqn{R} is then defined as the number of
\dQuote{non-zero} diagonal entries \eqn{d_i} of \eqn{R}, and
\dQuote{non-zero}s fulfill
\eqn{|d_i| \ge \mathrm{tol}\cdot\max(|d_i|)}{|d_i| >= tol * max(|d_i|)}.
}
\item{\code{"qr"}:}{is for back compatibility; for dense \code{x},
it corresponds to \code{"qrLINPACK"}, whereas for sparse
\code{x}, it uses \code{"qr.R"}.
For all the "qr*" methods, singular values \code{sval} are not
used, which may be crucially important for a large sparse matrix
\code{x}, as in that case, when \code{sval} is not specified,
the default, computing \code{\link{svd}()} currently coerces
\code{x} to a dense matrix.
}
\item{\code{"useGrad"}:}{considering the \dQuote{gradient} of the
(decreasing) singular values, the index of the \emph{smallest} gap.}
\item{\code{"maybeGrad"}:}{choosing method \code{"useGrad"} only when
that seems \emph{reasonable}; otherwise using \code{"tolNorm2"}.}
%% FIXME say more
}
}
\item{sval}{numeric vector of non-increasing singular values of
\code{x}; typically unspecified and computed from \code{x} when
needed, i.e., unless \code{method = "qr"}.}
\item{warn.t}{logical indicating if \code{rankMatrix()} should warn
when it needs \code{\link{t}(x)} instead of \code{x}. Currently, for
\code{method = "qr"} only, gives a warning by default because the
caller often could have passed \code{t(x)} directly, more efficiently.}
\item{warn.qr}{in the \eqn{QR} cases (i.e., if \code{method} starts with
\code{"qr"}), \code{rankMatrix()} calls
\code{qr2rankMarix(.., do.warn = warn.qr)}, see below.}
%% qr2rankMatrix():
\item{qr}{an \R object resulting from \code{\link{qr}(x,..)}, i.e.,
typically inheriting from \code{\link{class}} \code{"\link{qr}"} or
\code{"\linkS4class{sparseQR}"}.}
\item{isBqr}{\code{\link{logical}} indicating if \code{qr} is resulting
from \pkg{base} \code{\link[base]{qr}()}. (Otherwise, it is typically
from \pkg{Matrix} package sparse \code{\link[Matrix]{qr}}.)}
\item{do.warn}{logical; if true, warn about non-finite diagonal
entries in the \eqn{R} matrix of the \eqn{QR} decomposition.
Do not change lightly!}
}
\details{
\code{qr2rankMatrix()} is typically called from \code{rankMatrix()} for
the \code{"qr"}* \code{method}s, but can be used directly - much more
efficiently in case the \code{qr}-decomposition is available anyway.
}
\note{For large sparse matrices \code{x}, unless you can specify
\code{sval} yourself, currently \code{method = "qr"} may
be the only feasible one, as the others need \code{sval} and call
\code{\link{svd}()} which currently coerces \code{x} to a
\code{\linkS4class{denseMatrix}} which may be very slow or impossible,
depending on the matrix dimensions.
Note that in the case of sparse \code{x}, \code{method = "qr"}, all
non-strictly zero diagonal entries \eqn{d_i} where counted, up to
including \pkg{Matrix} version 1.1-0, i.e., that method implicitly
used \code{tol = 0}, see also the \code{set.seed(42)} example below.
}
\value{
If \code{x} is a matrix of all \code{0} (or of zero dimension), the rank
is zero; otherwise, typically a positive integer in \code{1:min(dim(x))}
with attributes detailing the method used.
There are rare cases where the sparse \eqn{QR} decomposition
\dQuote{fails} in so far as the diagonal entries of \eqn{R}, the
\eqn{d_i} (see above), end with non-finite, typically \code{\link{NaN}}
entries. Then, a warning is signalled (unless \code{warn.qr} /
\code{do.warn} is not true) and \code{NA} (specifically,
\code{\link{NA_integer_}}) is returned.
}
% \references{
% %% ~put references to the literature/web site here ~
% }
\author{Martin Maechler; for the "*Grad" methods building on
suggestions by Ravi Varadhan.
}
\seealso{
\code{\link{qr}}, \code{\link{svd}}.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
}
rankMatrix(cbind(1, 0, 1:3)) # 2
(meths <- eval(formals(rankMatrix)$method))
## a "border" case:
H12 <- Hilbert(12)
rankMatrix(H12, tol = 1e-20) # 12; but 11 with default method & tol.
sapply(meths, function(.m.) rankMatrix(H12, method = .m.))
## tolNorm2 qr.R qrLINPACK qr useGrad maybeGrad
## 11 11 12 12 11 11
## The meaning of 'tol' for method="qrLINPACK" and *dense* x is not entirely "scale free"
rMQL <- function(ex, M) rankMatrix(M, method="qrLINPACK",tol = 10^-ex)
rMQR <- function(ex, M) rankMatrix(M, method="qr.R", tol = 10^-ex)
sapply(5:15, rMQL, M = H12) # result is platform dependent
## 7 7 8 10 10 11 11 11 12 12 12 {x86_64}
sapply(5:15, rMQL, M = 1000 * H12) # not identical unfortunately
## 7 7 8 10 11 11 12 12 12 12 12
sapply(5:15, rMQR, M = H12)
## 5 6 7 8 8 9 9 10 10 11 11
sapply(5:15, rMQR, M = 1000 * H12) # the *same*
\dontshow{
(r12 <- sapply(5:15, rMQR, M = H12))
stopifnot(identical(r12, sapply(5:15, rMQR, M = H12 / 100)),
identical(r12, sapply(5:15, rMQR, M = H12 * 1e5)))
rM1 <- function(ex, M) rankMatrix(M, tol = 10^-ex)
(r12 <- sapply(5:15, rM1, M = H12))
stopifnot(identical(r12, sapply(5:15, rM1, M = H12 / 100)),
identical(r12, sapply(5:15, rM1, M = H12 * 1e5)))
}
## "sparse" case:
M15 <- kronecker(diag(x=c(100,1,10)), Hilbert(5))
sapply(meths, function(.m.) rankMatrix(M15, method = .m.))
#--> all 15, but 'useGrad' has 14.
sapply(meths, function(.m.) rankMatrix(M15, method = .m., tol = 1e-7)) # all 14
## "large" sparse
n <- 250000; p <- 33; nnz <- 10000
L <- sparseMatrix(i = sample.int(n, nnz, replace=TRUE),
j = sample.int(p, nnz, replace=TRUE),
x = rnorm(nnz))
(st1 <- system.time(r1 <- rankMatrix(L))) # warning+ ~1.5 sec (2013)
(st2 <- system.time(r2 <- rankMatrix(L, method = "qr"))) # considerably faster!
r1[[1]] == print(r2[[1]]) ## --> ( 33 TRUE )
\dontshow{
stopifnot(r1[[1]] == 33, 33 == r2[[1]])
if(interactive() || nzchar(Sys.getenv("R_MATRIX_CHECK_EXTRA")))
stopifnot(st2[[1]] < 0.2) # seeing 0.03 (on ~ 2010-hardware; R 3.0.2)
}
## another sparse-"qr" one, which ``failed'' till 2013-11-23:
set.seed(42)
f1 <- factor(sample(50, 1000, replace=TRUE))
f2 <- factor(sample(50, 1000, replace=TRUE))
f3 <- factor(sample(50, 1000, replace=TRUE))
D <- t(do.call(rbind, lapply(list(f1,f2,f3), as, 'sparseMatrix')))
dim(D); nnzero(D) ## 1000 x 150 // 3000 non-zeros (= 2\%)
stopifnot(rankMatrix(D, method='qr') == 148,
rankMatrix(crossprod(D),method='qr') == 148)
## zero matrix has rank 0 :
stopifnot(sapply(meths, function(.m.)
rankMatrix(matrix(0, 2, 2), method = .m.)) == 0)
}
Matrix/man/MatrixFactorization-class.Rd 0000644 0001751 0000144 00000010667 14575137654 017735 0 ustar hornik users \name{MatrixFactorization-class}
\title{Virtual Class "MatrixFactorization" of Matrix Factorizations}
%
\docType{class}
\keyword{algebra}
\keyword{array}
\keyword{classes}
%
\alias{MatrixFactorization-class}
%
\alias{BunchKaufmanFactorization-class}
\alias{CholeskyFactorization-class}
\alias{SchurFactorization-class}
\alias{LU-class}
\alias{QR-class}
%
\alias{determinant,MatrixFactorization,missing-method}
\alias{dim,MatrixFactorization-method}
\alias{dimnames,MatrixFactorization-method}
\alias{dimnames<-,MatrixFactorization,NULL-method}
\alias{dimnames<-,MatrixFactorization,list-method}
\alias{length,MatrixFactorization-method}
\alias{show,MatrixFactorization-method}
\alias{unname,MatrixFactorization-method}
%
\alias{show,BunchKaufmanFactorization-method}
\alias{show,CholeskyFactorization-method}
\alias{show,SchurFactorization-method}
\alias{show,LU-method}
\alias{show,QR-method}
%
\description{
\code{MatrixFactorization} is the virtual class of
factorizations of \eqn{m \times n}{m-by-n} matrices \eqn{A},
having the general form
\deqn{P_{1} A P_{2} = A_{1} \cdots A_{p}}{P1 * A * P2 = A1 * ... * Ap}
or (equivalently)
\deqn{A = P_{1}' A_{1} \cdots A_{p} P_{2}'}{A = P1' * A1 * ... * Ap * P2'}
where \eqn{P_{1}}{P1} and \eqn{P_{2}}{P2} are permutation matrices.
Factorizations requiring symmetric \eqn{A} have the constraint
\eqn{P_{2} = P_{1}'}{P2 = P1'}, and factorizations without row
or column pivoting have the constraints
\eqn{P_{1} = I_{m}}{P1 = Im} and \eqn{P_{2} = I_{n}}{P2 = In},
where \eqn{I_{m}}{Im} and \eqn{I_{n}}{In} are the
\eqn{m \times m}{m-by-m} and \eqn{n \times n}{n-by-n} identity matrices.
\code{CholeskyFactorization}, \code{BunchKaufmanFactorization},
\code{SchurFactorization}, \code{LU}, and \code{QR} are the virtual
subclasses of \code{MatrixFactorization} containing all Cholesky,
Bunch-Kaufman, Schur, LU, and QR factorizations, respectively.
}
\section{Slots}{
\describe{
\item{\code{Dim}}{an integer vector of length 2 giving the
dimensions of the factorized matrix.}
\item{\code{Dimnames}}{a list of length 2 preserving the
\code{dimnames} of the factorized matrix. Each element
must be \code{NULL} or a character vector of length equal
to the corresponding element of \code{Dim}.}
}
}
\section{Methods}{
\describe{
\item{\code{determinant}}{\code{signature(x = "MatrixFactorization", logarithm = "missing")}:
sets \code{logarithm = TRUE} and recalls the generic function.}
\item{\code{dim}}{\code{signature(x = "MatrixFactorization")}:
returns \code{x@Dim}.}
\item{\code{dimnames}}{\code{signature(x = "MatrixFactorization")}:
returns \code{x@Dimnames}.}
\item{\code{dimnames<-}}{\code{signature(x = "MatrixFactorization", value = "NULL")}:
returns \code{x} with \code{x@Dimnames} set to \code{list(NULL, NULL)}.}
\item{\code{dimnames<-}}{\code{signature(x = "MatrixFactorization", value = "list")}:
returns \code{x} with \code{x@Dimnames} set to \code{value}.}
\item{\code{length}}{\code{signature(x = "MatrixFactorization")}:
returns \code{prod(x@Dim)}.}
\item{\code{show}}{\code{signature(object = "MatrixFactorization")}:
prints the internal representation of the factorization using
\code{\link{str}}.}
\item{\code{solve}}{\code{signature(a = "MatrixFactorization", b = .)}:
see \code{\link{solve-methods}}.}
\item{\code{unname}}{\code{signature(obj = "MatrixFactorization")}:
returns \code{obj} with \code{obj@Dimnames} set to
\code{list(NULL, NULL)}.}
}
}
\seealso{
Classes extending \code{CholeskyFactorization}, namely
\code{\linkS4class{Cholesky}}, \code{\linkS4class{pCholesky}},
and \code{\linkS4class{CHMfactor}}.
Classes extending \code{BunchKaufmanFactorization}, namely
\code{\linkS4class{BunchKaufman}} and \code{\linkS4class{pBunchKaufman}}.
Classes extending \code{SchurFactorization}, namely
\code{\linkS4class{Schur}}.
Classes extending \code{LU}, namely
\code{\linkS4class{denseLU}} and \code{\linkS4class{sparseLU}}.
Classes extending \code{QR}, namely \code{\linkS4class{sparseQR}}.
Generic functions \code{\link{Cholesky}}, \code{\link{BunchKaufman}},
\code{\link{Schur}}, \code{\link{lu}}, and \code{\link{qr}} for
\emph{computing} factorizations.
Generic functions \code{\link{expand1}} and \code{\link{expand2}}
for constructing matrix factors from \code{MatrixFactorization}
objects.
}
\examples{
showClass("MatrixFactorization")
}
Matrix/man/Schur-class.Rd 0000644 0001751 0000144 00000007601 14446607050 014777 0 ustar hornik users \name{Schur-class}
\title{Schur Factorizations}
%
\docType{class}
\keyword{algebra}
\keyword{array}
\keyword{classes}
%
\alias{Schur-class}
%
\alias{determinant,Schur,logical-method}
%
\description{
\code{Schur} is the class of Schur factorizations of
\eqn{n \times n}{n-by-n} real matrices \eqn{A},
having the general form
\deqn{A = Q T Q'}{A = Q * T * Q'}
where
\eqn{Q} is an orthogonal matrix and
\eqn{T} is a block upper triangular matrix with
\eqn{1 \times 1}{1-by-1} or \eqn{2 \times 2}{2-by-2} diagonal blocks
specifying the real and complex conjugate eigenvalues of \eqn{A}.
The column vectors of \eqn{Q} are the Schur vectors of \eqn{A},
and \eqn{T} is the Schur form of \eqn{A}.
The Schur factorization generalizes the spectral decomposition
of normal matrices \eqn{A}, whose Schur form is block diagonal,
to arbitrary square matrices.
}
\section{Slots}{
\describe{
\item{\code{Dim}, \code{Dimnames}}{inherited from virtual class
\code{\linkS4class{MatrixFactorization}}.}
\item{\code{Q}}{an orthogonal matrix,
inheriting from virtual class \code{\linkS4class{Matrix}}.}
\item{\code{T}}{a block upper triangular matrix,
inheriting from virtual class \code{\linkS4class{Matrix}}.
The diagonal blocks have dimensions 1-by-1 or 2-by-2.}
\item{\code{EValues}}{a numeric or complex vector containing
the eigenvalues of the diagonal blocks of \code{T}, which are
the eigenvalues of \code{T} and consequently of the factorized
matrix.}
}
}
\section{Extends}{
Class \code{\linkS4class{SchurFactorization}}, directly.
Class \code{\linkS4class{MatrixFactorization}}, by class
\code{\linkS4class{SchurFactorization}}, distance 2.
}
\section{Instantiation}{
Objects can be generated directly by calls of the form
\code{new("Schur", ...)}, but they are more typically obtained
as the value of \code{\link{Schur}(x)} for \code{x} inheriting from
\code{\linkS4class{Matrix}} (often \code{\linkS4class{dgeMatrix}}).
}
\section{Methods}{
\describe{
\item{\code{determinant}}{\code{signature(from = "Schur", logarithm = "logical")}:
computes the determinant of the factorized matrix \eqn{A}
or its logarithm.}
\item{\code{expand1}}{\code{signature(x = "Schur")}:
see \code{\link{expand1-methods}}.}
\item{\code{expand2}}{\code{signature(x = "Schur")}:
see \code{\link{expand2-methods}}.}
\item{\code{solve}}{\code{signature(a = "Schur", b = .)}:
see \code{\link{solve-methods}}.}
}
}
\details{
The matrix \eqn{A} and its Schur form \eqn{T} are \emph{similar}
and thus have the same spectrum. The eigenvalues are computed
trivially as the eigenvalues of the diagonal blocks of \eqn{T}.
}
\seealso{
Class \code{\linkS4class{dgeMatrix}}.
Generic functions \code{\link{Schur}},
\code{\link{expand1}} and \code{\link{expand2}}.
}
\references{
The LAPACK source code, including documentation; see
\url{https://netlib.org/lapack/double/dgees.f}.
Golub, G. H., & Van Loan, C. F. (2013).
\emph{Matrix computations} (4th ed.).
Johns Hopkins University Press.
\doi{10.56021/9781421407944}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
library(utils, pos = "package:base", verbose = FALSE)
}
showClass("Schur")
set.seed(0)
n <- 4L
(A <- Matrix(rnorm(n * n), n, n))
## With dimnames, to see that they are propagated :
dimnames(A) <- list(paste0("r", seq_len(n)),
paste0("c", seq_len(n)))
(sch.A <- Schur(A))
str(e.sch.A <- expand2(sch.A), max.level = 2L)
## A ~ Q T Q' in floating point
stopifnot(exprs = {
identical(names(e.sch.A), c("Q", "T", "Q."))
all.equal(A, with(e.sch.A, Q \%*\% T \%*\% Q.))
})
## Factorization handled as factorized matrix
b <- rnorm(n)
stopifnot(all.equal(det(A), det(sch.A)),
all.equal(solve(A, b), solve(sch.A, b)))
## One of the non-general cases:
Schur(Diagonal(6L))
}
Matrix/man/subscript-methods.Rd 0000644 0001751 0000144 00000004735 14575137654 016307 0 ustar hornik users \name{subscript-methods}
\title{Methods for "[": Extraction or Subsetting in Package 'Matrix'}
%
\docType{methods}
\keyword{array}
\keyword{methods}
%
\alias{[}
\alias{[-methods}
\alias{subscript-methods}
%
\alias{[,Matrix,ANY,NULL,ANY-method}
\alias{[,Matrix,NULL,ANY,ANY-method}
\alias{[,Matrix,NULL,NULL,ANY-method}
\alias{[,Matrix,index,index,logical-method}
\alias{[,Matrix,index,index,missing-method}
\alias{[,Matrix,index,missing,logical-method}
\alias{[,Matrix,index,missing,missing-method}
\alias{[,Matrix,lMatrix,missing,missing-method}
\alias{[,Matrix,matrix,missing,missing-method}
\alias{[,Matrix,missing,index,logical-method}
\alias{[,Matrix,missing,index,missing-method}
\alias{[,Matrix,missing,missing,logical-method}
\alias{[,Matrix,missing,missing,missing-method}
\alias{[,Matrix,nMatrix,missing,missing-method}
\alias{[,abIndex,index,ANY,ANY-method}
\alias{[,sparseVector,NULL,ANY,ANY-method}
\alias{[,sparseVector,index,missing,missing-method}
\alias{[,sparseVector,lsparseVector,missing,missing-method}
\alias{[,sparseVector,missing,missing,missing-method}
\alias{[,sparseVector,nsparseVector,missing,missing-method}
%
\description{
Methods for \code{"["}, i.e., extraction or subsetting mostly of
matrices, in package \pkg{Matrix}.
}
\section{Methods}{
There are more than these:
\describe{
\item{x = "Matrix", i = "missing", j = "missing", drop= "ANY"}{ ... }
\item{x = "Matrix", i = "numeric", j = "missing", drop= "missing"}{ ... }
\item{x = "Matrix", i = "missing", j = "numeric", drop= "missing"}{ ... }
\item{x = "dsparseMatrix", i = "missing", j = "numeric", drop= "logical"}{ ... }
\item{x = "dsparseMatrix", i = "numeric", j = "missing", drop= "logical"}{ ... }
\item{x = "dsparseMatrix", i = "numeric", j = "numeric", drop= "logical"}{ ... }
}
}
\seealso{
\code{\link{[<--methods}} for sub\emph{assign}ment to \code{"Matrix"}
objects.
\code{\link{Extract}} about the standard extraction.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
library(utils, pos = "package:base", verbose = FALSE)
}
% regression tests are in ../tests/indexing.R
str(m <- Matrix(round(rnorm(7*4),2), nrow = 7))
stopifnot(identical(m, m[]))
m[2, 3] # simple number
m[2, 3:4] # simple numeric of length 2
m[2, 3:4, drop=FALSE] # sub matrix of class 'dgeMatrix'
## rows or columns only:
m[1,] # first row, as simple numeric vector
m[,1:2] # sub matrix of first two columns
showMethods("[", inherited = FALSE)
}
Matrix/man/rleDiff-class.Rd 0000644 0001751 0000144 00000002637 14422605232 015264 0 ustar hornik users \name{rleDiff-class}
\title{Class "rleDiff" of rle(diff(.)) Stored Vectors}
%
\docType{class}
\keyword{classes}
%
\alias{rleDiff-class}
\alias{show,rleDiff-method}
%
\description{
Class \code{"rleDiff"} is for compactly storing long vectors
which mainly consist of \emph{linear} stretches. For such a vector
\code{x}, \code{\link{diff}(x)} consists of \emph{constant} stretches
and is hence well compressable via \code{\link{rle}()}.
}
\section{Objects from the Class}{
Objects can be created by calls of the form \code{new("rleDiff", ...)}.
Currently experimental, see below.
}
\section{Slots}{
\describe{
\item{\code{first}:}{A single number (of class \code{"numLike"},
a class union of \code{"numeric"} and \code{"logical"}).}
\item{\code{rle}:}{Object of class \code{"rle"}, basically a
\code{\link{list}} with components \code{"lengths"} and
\code{"values"}, see \code{\link{rle}()}. As this is used to
encode potentially huge index vectors, \code{lengths} may be of
type \code{\link{double}} here.}
}
}
\section{Methods}{
There is a simple \code{\link{show}} method only.% currently
}
\note{
This is currently an \emph{experimental} auxiliary class
for the class \code{\linkS4class{abIndex}}, see there.
}
\seealso{
\code{\link{rle}}, \code{\linkS4class{abIndex}}.
}
\examples{
showClass("rleDiff")
ab <- c(abIseq(2, 100), abIseq(20, -2))
ab@rleD # is "rleDiff"
}
Matrix/man/triangularMatrix-class.Rd 0000644 0001751 0000144 00000005130 14422605232 017235 0 ustar hornik users \name{triangularMatrix-class}
\title{Virtual Class of Triangular Matrices in Package Matrix}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{triangularMatrix-class}
%
\alias{Arith,triangularMatrix,diagonalMatrix-method}
\alias{Compare,triangularMatrix,diagonalMatrix-method}
\alias{Logic,triangularMatrix,diagonalMatrix-method}
\alias{coerce,matrix,triangularMatrix-method}
\alias{determinant,triangularMatrix,logical-method}
%
\description{
The virtual class of triangular matrices,\code{"triangularMatrix"},
the package \pkg{Matrix} contains \emph{square} (\code{\link{nrow} ==
\link{ncol}}) numeric and logical, dense and sparse matrices, e.g.,
see the examples.
A main use of the virtual class is in methods (and C functions) that
can deal with all triangular matrices.
}
% \section{Objects from the Class}{A virtual Class: No objects may be created from it.}
\section{Slots}{
\describe{
\item{\code{uplo}:}{String (of class \code{"character"}). Must be
either "U", for upper triangular, and "L", for lower triangular.}
\item{\code{diag}:}{String (of class \code{"character"}). Must be
either \code{"U"}, for unit triangular (diagonal is all ones), or
\code{"N"} for non-unit. The diagonal elements are not
accessed internally when \code{diag} is \code{"U"}. For
\code{\linkS4class{denseMatrix}} classes, they need to be
allocated though, such that the length of the \code{x} slot does not
depend on \code{diag}.}
\item{\code{Dim}, \code{Dimnames}:}{The dimension (a length-2
\code{"integer"}) and corresponding names (or \code{NULL}),
inherited from the \code{\linkS4class{Matrix}}, see there.}
}
}
\section{Extends}{
Class \code{"Matrix"}, directly.
}
\section{Methods}{
There's a C function \code{triangularMatrix_validity()}
called by the internal validity checking functions.
Currently, \code{\link{Schur}}, \code{\link{isSymmetric}} and
\code{as()} (i.e. \code{\link{coerce}}) have methods with
\code{triangularMatrix} in their signature.
}
\seealso{
\code{\link{isTriangular}()} for testing any matrix for triangularity;
classes \code{\linkS4class{symmetricMatrix}}, and, e.g.,
\code{\linkS4class{dtrMatrix}} for numeric \emph{dense} matrices, or
\code{\linkS4class{ltCMatrix}} for a logical \emph{sparse} matrix
subclass of \code{"triangularMatrix"}.
}
\examples{
showClass("triangularMatrix")
## The names of direct subclasses:
scl <- getClass("triangularMatrix")@subclasses
directly <- sapply(lapply(scl, slot, "by"), length) == 0
names(scl)[directly]
(m <- matrix(c(5,1,0,3), 2))
as(m, "triangularMatrix")
}
Matrix/man/invertPerm.Rd 0000644 0001751 0000144 00000007201 14575137654 014752 0 ustar hornik users \name{invertPerm}
\title{Utilities for Permutation Vectors}
%
\keyword{utilities}
%
\alias{invertPerm}
\alias{signPerm}
\alias{isPerm}
\alias{asPerm}
\alias{invPerm}
%
\description{
\code{invertPerm} and \code{signPerm} compute the inverse and sign
of a length-\code{n} permutation vector. \code{isPerm} tests
if a length-\code{n} integer vector is a valid permutation vector.
\code{asPerm} coerces a length-\code{m} transposition vector to a
length-\code{n} permutation vector, where \code{m <= n}.
}
\usage{
invertPerm(p, off = 1L, ioff = 1L)
signPerm(p, off = 1L)
isPerm(p, off = 1L)
asPerm(pivot, off = 1L, ioff = 1L, n = length(pivot))
invPerm(p, zero.p = FALSE, zero.res = FALSE)
}
\arguments{
\item{p}{an integer vector of length \code{n}.}
\item{pivot}{an integer vector of length \code{m}.}
\item{off}{an integer offset, indicating that \code{p} is
a permutation of \code{off+0:(n-1)} or that \code{pivot}
contains \code{m} values sampled with replacement from
\code{off+0:(n-1)}.}
\item{ioff}{an integer offset, indicating that the result
should be a permutation of \code{ioff+0:(n-1)}.}
\item{n}{a integer greater than or equal to \code{m},
indicating the length of the result. Transpositions
are applied to a permutation vector vector initialized
as \code{seq_len(n)}.}
\item{zero.p}{a logical. Equivalent to \code{off=0} if \code{TRUE}
and \code{off=1} if \code{FALSE}.}
\item{zero.res}{a logical. Equivalent to \code{ioff=0} if \code{TRUE}
and \code{ioff=1} if \code{FALSE}.}
}
\details{
\code{invertPerm(p, off, ioff=1)} is equivalent to
\code{\link{order}(p)} or \code{\link{sort.list}(p)}
for all values of \code{off}. For the default value
\code{off=1}, it returns the value of \code{p} after
\code{p[p] <- seq_along(p)}.
\code{invPerm} is a simple wrapper around \code{invertPerm},
retained for backwards compatibility.
}
\value{
By default, i.e., with \code{off=1} and \code{ioff=1}:
\code{invertPerm(p)} returns an integer vector of length
\code{length(p)} such that \code{p[invertPerm(p)]}
and \code{invertPerm(p)[p]} are both \code{seq_along(p)},
i.e., the identity permutation.
\code{signPerm(p)} returns 1 if \code{p} is an even permutation
and \code{-1} otherwise (i.e., if \code{p} is odd).
\code{isPerm(p)} returns \code{TRUE} if \code{p} is a
permutation of \code{seq_along(p)} and \code{FALSE} otherwise.
\code{asPerm(pivot)} returns the result of transposing elements
\code{i} and \code{pivot[i]} of a permutation vector initialized
as \code{seq_len(n)}, for \code{i} in \code{seq_along(pivot)}.
}
\seealso{
Class \code{\linkS4class{pMatrix}} of permutation matrices.
}
\examples{
p <- sample(10L) # a random permutation vector
ip <- invertPerm(p)
s <- signPerm(p)
## 'p' and 'ip' are indeed inverses:
stopifnot(exprs = {
isPerm(p)
isPerm(ip)
identical(s, 1L) || identical(s, -1L)
identical(s, signPerm(ip))
identical(p[ip], 1:10)
identical(ip[p], 1:10)
identical(invertPerm(ip), p)
})
## Product of transpositions (1 2)(2 1)(4 3)(6 8)(10 1) = (3 4)(6 8)(1 10)
pivot <- c(2L, 1L, 3L, 3L, 5L, 8L, 7L, 8L, 9L, 1L)
q <- asPerm(pivot)
stopifnot(exprs = {
identical(q, c(10L, 2L, 4L, 3L, 5L, 8L, 7L, 6L, 9L, 1L))
identical(q[q], seq_len(10L)) # because the permutation is odd:
signPerm(q) == -1L
})
invPerm # a less general version of 'invertPerm'
\dontshow{
stopifnot(exprs = {
identical(isPerm(0L), FALSE)
identical(signPerm(1:2), 1L)
identical(signPerm(2:1), -1L)
identical(invertPerm(c(3, 1:2)), c(2:3, 1L)) # 'p' of type "double",
tryCatch(invPerm(NA), error = function(e) TRUE) # was a segfault
})
}
}
Matrix/man/BunchKaufman-class.Rd 0000644 0001751 0000144 00000015356 14446607050 016263 0 ustar hornik users \name{BunchKaufman-class}
\title{Dense Bunch-Kaufman Factorizations}
%
\docType{class}
\keyword{algebra}
\keyword{array}
\keyword{classes}
%
\alias{BunchKaufman-class}
\alias{pBunchKaufman-class}
%
\alias{coerce,BunchKaufman,dtrMatrix-method}
\alias{coerce,pBunchKaufman,dtpMatrix-method}
\alias{determinant,BunchKaufman,logical-method}
\alias{determinant,pBunchKaufman,logical-method}
%
\description{
Classes \code{BunchKaufman} and \code{pBunchKaufman} represent
Bunch-Kaufman factorizations of \eqn{n \times n}{n-by-n} real,
symmetric matrices \eqn{A}, having the general form
\deqn{A = U D_{U} U' = L D_{L} L'}{A = U * DU * U' = L * DL * L'}
where
\eqn{D_{U}}{DU} and \eqn{D_{L}}{DL} are symmetric, block diagonal
matrices composed of \eqn{b_{U}}{bU} and \eqn{b_{L}}{bL}
\eqn{1 \times 1}{1-by-1} or \eqn{2 \times 2}{2-by-2} diagonal blocks;
\eqn{U = \prod_{k = 1}^{b_{U}} P_{k} U_{k}}{U = prod(Pk * Uk : k = 1,...,bU)}
is the product of \eqn{b_{U}}{bU} row-permuted unit upper triangular
matrices, each having nonzero entries above the diagonal in 1 or 2 columns;
and
\eqn{L = \prod_{k = 1}^{b_{L}} P_{k} L_{k}}{L = prod(Pk * Lk : k = 1,...,bL)}
is the product of \eqn{b_{L}}{bL} row-permuted unit lower triangular
matrices, each having nonzero entries below the diagonal in 1 or 2 columns.
These classes store the nonzero entries of the
\eqn{2 b_{U} + 1}{2*bU+1} or \eqn{2 b_{L} + 1}{2*bL+1} factors,
which are individually sparse,
in a dense format as a vector of length
\eqn{nn}{n*n} (\code{BunchKaufman}) or
\eqn{n(n+1)/2}{n*(n+1)/2} (\code{pBunchKaufman}),
the latter giving the \dQuote{packed} representation.
}
\section{Slots}{
\describe{
\item{\code{Dim}, \code{Dimnames}}{inherited from virtual class
\code{\linkS4class{MatrixFactorization}}.}
\item{\code{uplo}}{a string, either \code{"U"} or \code{"L"},
indicating which triangle (upper or lower) of the factorized
symmetric matrix was used to compute the factorization and
in turn how the \code{x} slot is partitioned.}
\item{\code{x}}{a numeric vector of length \code{n*n}
(\code{BunchKaufman}) or \code{n*(n+1)/2} (\code{pBunchKaufman}),
where \code{n=Dim[1]}.
The details of the representation are specified by the manual
for LAPACK routines \code{dsytrf} and \code{dsptrf}.}
\item{\code{perm}}{an integer vector of length \code{n=Dim[1]}
specifying row and column interchanges as described in the manual
for LAPACK routines \code{dsytrf} and \code{dsptrf}.}
}
}
\section{Extends}{
Class \code{\linkS4class{BunchKaufmanFactorization}}, directly.
Class \code{\linkS4class{MatrixFactorization}}, by class
\code{\linkS4class{BunchKaufmanFactorization}}, distance 2.
}
\section{Instantiation}{
Objects can be generated directly by calls of the form
\code{new("BunchKaufman", ...)} or \code{new("pBunchKaufman", ...)},
but they are more typically obtained as the value of
\code{\link{BunchKaufman}(x)} for \code{x} inheriting from
\code{\linkS4class{dsyMatrix}} or \code{\linkS4class{dspMatrix}}.
}
\section{Methods}{
\describe{
\item{\code{coerce}}{\code{signature(from = "BunchKaufman", to = "dtrMatrix")}:
returns a \code{\linkS4class{dtrMatrix}}, useful for inspecting
the internal representation of the factorization; see \sQuote{Note}.}
\item{\code{coerce}}{\code{signature(from = "pBunchKaufman", to = "dtpMatrix")}:
returns a \code{\linkS4class{dtpMatrix}}, useful for inspecting
the internal representation of the factorization; see \sQuote{Note}.}
\item{\code{determinant}}{\code{signature(from = "p?BunchKaufman", logarithm = "logical")}:
computes the determinant of the factorized matrix \eqn{A}
or its logarithm.}
\item{\code{expand1}}{\code{signature(x = "p?BunchKaufman")}:
see \code{\link{expand1-methods}}.}
\item{\code{expand2}}{\code{signature(x = "p?BunchKaufman")}:
see \code{\link{expand2-methods}}.}
\item{\code{solve}}{\code{signature(a = "p?BunchKaufman", b = .)}:
see \code{\link{solve-methods}}.}
}
}
\note{
In \pkg{Matrix} \code{< 1.6-0}, class \code{BunchKaufman} extended
\code{\linkS4class{dtrMatrix}} and class \code{pBunchKaufman} extended
\code{\linkS4class{dtpMatrix}}, reflecting the fact that the internal
representation of the factorization is fundamentally triangular:
there are \eqn{n(n+1)/2}{n*(n+1)/2} \dQuote{parameters}, and these
can be arranged systematically to form an \eqn{n \times n}{n-by-n}
triangular matrix.
\pkg{Matrix} \code{1.6-0} removed these extensions so that methods
would no longer be inherited from \code{dtrMatrix} and \code{dtpMatrix}.
The availability of such methods gave the wrong impression that
\code{BunchKaufman} and \code{pBunchKaufman} represent a (singular)
matrix, when in fact they represent an ordered set of matrix factors.
The coercions \code{as(., "dtrMatrix")} and \code{as(., "dtpMatrix")}
are provided for users who understand the caveats.
}
\seealso{
Class \code{\linkS4class{dsyMatrix}} and its packed counterpart.
Generic functions \code{\link{BunchKaufman}},
\code{\link{expand1}}, and \code{\link{expand2}}.
}
\references{
The LAPACK source code, including documentation; see
\url{https://netlib.org/lapack/double/dsytrf.f} and
\url{https://netlib.org/lapack/double/dsptrf.f}.
Golub, G. H., & Van Loan, C. F. (2013).
\emph{Matrix computations} (4th ed.).
Johns Hopkins University Press.
\doi{10.56021/9781421407944}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
library(utils, pos = "package:base", verbose = FALSE)
}
showClass("BunchKaufman")
set.seed(1)
n <- 6L
(A <- forceSymmetric(Matrix(rnorm(n * n), n, n)))
## With dimnames, to see that they are propagated :
dimnames(A) <- rep.int(list(paste0("x", seq_len(n))), 2L)
(bk.A <- BunchKaufman(A))
str(e.bk.A <- expand2(bk.A, complete = FALSE), max.level = 2L)
str(E.bk.A <- expand2(bk.A, complete = TRUE), max.level = 2L)
## Underlying LAPACK representation
(m.bk.A <- as(bk.A, "dtrMatrix"))
stopifnot(identical(as(m.bk.A, "matrix"), `dim<-`(bk.A@x, bk.A@Dim)))
## Number of factors is 2*b+1, b <= n, which can be nontrivial ...
(b <- (length(E.bk.A) - 1L) \%/\% 2L)
ae1 <- function(a, b, ...) all.equal(as(a, "matrix"), as(b, "matrix"), ...)
ae2 <- function(a, b, ...) ae1(unname(a), unname(b), ...)
## A ~ U DU U', U := prod(Pk Uk) in floating point
stopifnot(exprs = {
identical(names(e.bk.A), c("U", "DU", "U."))
identical(e.bk.A[["U" ]], Reduce(`\%*\%`, E.bk.A[seq_len(b)]))
identical(e.bk.A[["U."]], t(e.bk.A[["U"]]))
ae1(A, with(e.bk.A, U \%*\% DU \%*\% U.))
})
## Factorization handled as factorized matrix
b <- rnorm(n)
stopifnot(identical(det(A), det(bk.A)),
identical(solve(A, b), solve(bk.A, b)))
}
Matrix/man/sparseQR-class.Rd 0000644 0001751 0000144 00000031552 14575234535 015464 0 ustar hornik users \name{sparseQR-class}
\title{Sparse QR Factorizations}
%
\docType{class}
\keyword{algebra}
\keyword{array}
\keyword{classes}
\keyword{utilities}
%
\alias{sparseQR-class}
%
\alias{determinant,sparseQR,logical-method}
\alias{qr.Q,sparseQR-method}
\alias{qr.R,sparseQR-method}
\alias{qr.X,sparseQR-method}
\alias{qr.coef,sparseQR,Matrix-method}
\alias{qr.coef,sparseQR,dgeMatrix-method}
\alias{qr.coef,sparseQR,matrix-method}
\alias{qr.coef,sparseQR,vector-method}
\alias{qr.fitted,sparseQR,Matrix-method}
\alias{qr.fitted,sparseQR,dgeMatrix-method}
\alias{qr.fitted,sparseQR,matrix-method}
\alias{qr.fitted,sparseQR,vector-method}
\alias{qr.qty,sparseQR,Matrix-method}
\alias{qr.qty,sparseQR,dgeMatrix-method}
\alias{qr.qty,sparseQR,matrix-method}
\alias{qr.qty,sparseQR,vector-method}
\alias{qr.qy,sparseQR,Matrix-method}
\alias{qr.qy,sparseQR,dgeMatrix-method}
\alias{qr.qy,sparseQR,matrix-method}
\alias{qr.qy,sparseQR,vector-method}
\alias{qr.resid,sparseQR,Matrix-method}
\alias{qr.resid,sparseQR,dgeMatrix-method}
\alias{qr.resid,sparseQR,matrix-method}
\alias{qr.resid,sparseQR,vector-method}
%
\alias{qrR}
%
\description{
\code{sparseQR} is the class of sparse, row- and column-pivoted
QR factorizations of \eqn{m \times n}{m-by-n} (\eqn{m \ge n}{m >= n})
real matrices, having the general form
\deqn{P_1 A P_2 = Q R = \begin{bmatrix} Q_1 & Q_2 \end{bmatrix} \begin{bmatrix} R_1 \\ 0 \end{bmatrix} = Q_1 R_1}{P1 * A * P2 = Q * R = [Q1, Q2] * [R1; 0] = Q1 * R1}
or (equivalently)
\deqn{A = P_1' Q R P_2' = P_1' \begin{bmatrix} Q_1 & Q_2 \end{bmatrix} \begin{bmatrix} R_1 \\ 0 \end{bmatrix} P_2' = P_1' Q_1 R_1 P_2'}{A = P1' * Q * R * P2' = P1' * [Q1, Q2] * [R1; 0] * P2' = P1' * Q1 * R1 * P2'}
where
\eqn{P_1}{P1} and \eqn{P_2}{P2} are permutation matrices,
\eqn{Q = \prod_{j = 1}^{n} H_j}{Q = prod(Hj : j = 1,...,n)}
is an \eqn{m \times m}{m-by-m} orthogonal matrix
(\eqn{Q_1}{Q1} contains the first \eqn{n} column vectors)
equal to the product of \eqn{n} Householder matrices \eqn{H_j}{Hj}, and
\eqn{R} is an \eqn{m \times n}{m-by-n} upper trapezoidal matrix
(\eqn{R_1}{R1} contains the first \eqn{n} row vectors and is
upper \emph{triangular}).
}
\usage{
qrR(qr, complete = FALSE, backPermute = TRUE, row.names = TRUE)
}
\arguments{
\item{qr}{an object of class \code{\linkS4class{sparseQR}},
almost always the result of a call to generic function \code{qr}
with sparse \code{x}.}
\item{complete}{a logical indicating if \eqn{R} should be returned
instead of \eqn{R_1}{R1}.}
\item{backPermute}{a logical indicating if \eqn{R} or \eqn{R_1}{R1}
should be multiplied on the right by \eqn{P_2'}{P2'}.}
\item{row.names}{a logical indicating if \code{dimnames(qr)[1]}
should be propagated unpermuted to the result.
If \code{complete = FALSE}, then only the first \eqn{n} names are kept.}
}
\section{Slots}{
\describe{
\item{\code{Dim}, \code{Dimnames}}{inherited from virtual class
\code{\linkS4class{MatrixFactorization}}.}
\item{\code{beta}}{a numeric vector of length \code{Dim[2]},
used to construct Householder matrices; see \code{V} below.}
\item{\code{V}}{an object of class \code{\linkS4class{dgCMatrix}}
with \code{Dim[2]} columns. The number of rows \code{nrow(V)}
is at least \code{Dim[1]} and at most \code{Dim[1]+Dim[2]}.
\code{V} is lower trapezoidal, and its column vectors generate the
Householder matrices \eqn{H_j}{Hj} that compose the orthogonal
\eqn{Q} factor. Specifically, \eqn{H_j}{Hj} is constructed as
\code{diag(Dim[1]) - beta[j] * tcrossprod(V[, j])}.}
\item{\code{R}}{an object of class \code{\linkS4class{dgCMatrix}}
with \code{nrow(V)} rows and \code{Dim[2]} columns.
\code{R} is the upper trapezoidal \eqn{R} factor.}
\item{\code{p}, \code{q}}{0-based integer vectors of length
\code{nrow(V)} and \code{Dim[2]}, respectively,
specifying the permutations applied to the rows and columns of
the factorized matrix. \code{q} of length 0 is valid and
equivalent to the identity permutation, implying no column pivoting.
Using \R{} syntax, the matrix \eqn{P_1 A P_2}{P1 * A * P2}
is precisely \code{A[p+1, q+1]}
(\code{A[p+1, ]} when \code{q} has length 0).}
}
}
\section{Extends}{
Class \code{\linkS4class{QR}}, directly.
Class \code{\linkS4class{MatrixFactorization}}, by class
\code{\linkS4class{QR}}, distance 2.
}
\section{Instantiation}{
Objects can be generated directly by calls of the form
\code{new("sparseQR", ...)}, but they are more typically obtained
as the value of \code{\link{qr}(x)} for \code{x} inheriting from
\code{\linkS4class{sparseMatrix}} (often \code{\linkS4class{dgCMatrix}}).
}
\section{Methods}{
\describe{
\item{\code{determinant}}{\code{signature(from = "sparseQR", logarithm = "logical")}:
computes the determinant of the factorized matrix \eqn{A}
or its logarithm.}
\item{\code{expand1}}{\code{signature(x = "sparseQR")}:
see \code{\link{expand1-methods}}.}
\item{\code{expand2}}{\code{signature(x = "sparseQR")}:
see \code{\link{expand2-methods}}.}
\item{\code{qr.Q}}{\code{signature(qr = "sparseQR")}:
returns as a \code{\linkS4class{dgeMatrix}} either
\eqn{P_1' Q}{P1' * Q} or \eqn{P_1' Q_1}{P1' * Q1},
depending on optional argument \code{complete}. The default
is \code{FALSE}, indicating \eqn{P_1' Q_1}{P1' * Q1}.}
\item{\code{qr.R}}{\code{signature(qr = "sparseQR")}:
\code{qrR} returns \eqn{R}, \eqn{R_1}{R1},
\eqn{R P2'}{R * P2'}, or \eqn{R_1 P2'}{R1 * P2'},
depending on optional arguments \code{complete} and
\code{backPermute}. The default in both cases is \code{FALSE},
indicating \eqn{R_1}{R1}, for compatibility with \pkg{base}.
The class of the result in that case is
\code{\linkS4class{dtCMatrix}}. In the other three cases,
it is \code{\linkS4class{dgCMatrix}}.}
\item{\code{qr.X}}{\code{signature(qr = "sparseQR")}:
returns \eqn{A} as a \code{\linkS4class{dgeMatrix}},
by default. If \eqn{m > n} and optional argument
\code{ncol} is greater than \eqn{n}, then the result
is augmented with \eqn{P_1' Q J}{P1 * Q * J}, where
\eqn{J} is composed of columns \eqn{(n+1)} through
\code{ncol} of the \eqn{m \times m}{m-by-m} identity matrix.}
\item{\code{qr.coef}}{\code{signature(qr = "sparseQR", y = .)}:
returns as a \code{\linkS4class{dgeMatrix}} or vector
the result of multiplying \code{y} on the left by
\eqn{P_2 R_1^{-1} Q_1' P_1}{P2 * R1^{-1} * Q1' * P1}.}
\item{\code{qr.fitted}}{\code{signature(qr = "sparseQR", y = .)}:
returns as a \code{\linkS4class{dgeMatrix}} or vector
the result of multiplying \code{y} on the left by
\eqn{P_1' Q_1 Q_1' P_1}{P1' * Q1 * Q1' * P1}.}
\item{\code{qr.resid}}{\code{signature(qr = "sparseQR", y = .)}:
returns as a \code{\linkS4class{dgeMatrix}} or vector
the result of multiplying \code{y} on the left by
\eqn{P_1' Q_2 Q_2' P_1}{P1' * Q2 * Q2' * P1}.}
\item{\code{qr.qty}}{\code{signature(qr = "sparseQR", y = .)}:
returns as a \code{\linkS4class{dgeMatrix}} or vector
the result of multiplying \code{y} on the left by
\eqn{Q' P_1}{Q' * P1}.}
\item{\code{qr.qy}}{\code{signature(qr = "sparseQR", y = .)}:
returns as a \code{\linkS4class{dgeMatrix}} or vector
the result of multiplying \code{y} on the left by
\eqn{P_1' Q}{P1' * Q}.}
\item{\code{solve}}{\code{signature(a = "sparseQR", b = .)}:
see \code{\link{solve-methods}}.}
}
}
\details{
The method for \code{qr.Q} does not return \eqn{Q} but rather the
(also orthogonal) product \eqn{P_1' Q}{P1' * Q}. This behaviour
is algebraically consistent with the \pkg{base} implementation
(see \code{\link[base]{qr}}), which can be seen by noting that
\code{qr.default} in \pkg{base} does not pivot rows, constraining
\eqn{P_1}{P1} to be an identity matrix. It follows that
\code{qr.Q(qr.default(x))} also returns \eqn{P_1' Q}{P1' * Q}.
Similarly, the methods for \code{qr.qy} and \code{qr.qty} multiply
on the left by \eqn{P_1' Q}{P1' * Q} and \eqn{Q' P_1}{Q' * P1}
rather than \eqn{Q} and \eqn{Q'}.
It is wrong to expect the values of \code{qr.Q} (or \code{qr.R},
\code{qr.qy}, \code{qr.qty}) computed from \dQuote{equivalent}
sparse and dense factorizations
(say, \code{qr(x)} and \code{qr(as(x, "matrix"))} for \code{x}
of class \code{\linkS4class{dgCMatrix}}) to compare equal.
The underlying factorization algorithms are quite different,
notably as they employ different pivoting strategies,
and in general the factorization is not unique even for fixed
\eqn{P_1}{P1} and \eqn{P_2}{P2}.
On the other hand, the values of \code{qr.X}, \code{qr.coef},
\code{qr.fitted}, and \code{qr.resid} are well-defined, and
in those cases the sparse and dense computations \emph{should}
compare equal (within some tolerance).
The method for \code{qr.R} is a simple wrapper around \code{qrR},
but not back-permuting by default and never giving row names.
It did not support \code{backPermute = TRUE} until \pkg{Matrix}
\code{1.6-0}, hence code needing the back-permuted result should
call \code{qrR} if \pkg{Matrix} \code{>= 1.6-0} is not known.
}
\seealso{
Class \code{\linkS4class{dgCMatrix}}.
Generic function \code{\link[base]{qr}} from \pkg{base},
whose default method \code{qr.default} \dQuote{defines}
the S3 class \code{qr} of dense QR factorizations.
\code{\link{qr-methods}} for methods defined in \pkg{Matrix}.
Generic functions \code{\link{expand1}} and \code{\link{expand2}}.
The many auxiliary functions for QR factorizations:
\code{\link{qr.Q}}, \code{\link{qr.R}}, \code{\link{qr.X}},
\code{\link{qr.coef}}, \code{\link{qr.fitted}}, \code{\link{qr.resid}},
\code{\link{qr.qty}}, \code{\link{qr.qy}}, and \code{\link{qr.solve}}.
}
\references{
Davis, T. A. (2006).
\emph{Direct methods for sparse linear systems}.
Society for Industrial and Applied Mathematics.
\doi{10.1137/1.9780898718881}
Golub, G. H., & Van Loan, C. F. (2013).
\emph{Matrix computations} (4th ed.).
Johns Hopkins University Press.
\doi{10.56021/9781421407944}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
library(utils, pos = "package:base", verbose = FALSE)
}
showClass("sparseQR")
set.seed(2)
m <- 300L
n <- 60L
A <- rsparsematrix(m, n, 0.05)
## With dimnames, to see that they are propagated :
dimnames(A) <- dn <- list(paste0("r", seq_len(m)),
paste0("c", seq_len(n)))
(qr.A <- qr(A))
str(e.qr.A <- expand2(qr.A, complete = FALSE), max.level = 2L)
str(E.qr.A <- expand2(qr.A, complete = TRUE), max.level = 2L)
t(sapply(e.qr.A, dim))
t(sapply(E.qr.A, dim))
## Horribly inefficient, but instructive :
slowQ <- function(V, beta) {
d <- dim(V)
Q <- diag(d[1L])
if(d[2L] > 0L) {
for(j in d[2L]:1L) {
cat(j, "\n", sep = "")
Q <- Q - (beta[j] * tcrossprod(V[, j])) \%*\% Q
}
}
Q
}
ae1 <- function(a, b, ...) all.equal(as(a, "matrix"), as(b, "matrix"), ...)
ae2 <- function(a, b, ...) ae1(unname(a), unname(b), ...)
## A ~ P1' Q R P2' ~ P1' Q1 R1 P2' in floating point
stopifnot(exprs = {
identical(names(e.qr.A), c("P1.", "Q1", "R1", "P2."))
identical(names(E.qr.A), c("P1.", "Q" , "R" , "P2."))
identical(e.qr.A[["P1."]],
new("pMatrix", Dim = c(m, m), Dimnames = c(dn[1L], list(NULL)),
margin = 1L, perm = invertPerm(qr.A@p, 0L, 1L)))
identical(e.qr.A[["P2."]],
new("pMatrix", Dim = c(n, n), Dimnames = c(list(NULL), dn[2L]),
margin = 2L, perm = invertPerm(qr.A@q, 0L, 1L)))
identical(e.qr.A[["R1"]], triu(E.qr.A[["R"]][seq_len(n), ]))
identical(e.qr.A[["Q1"]], E.qr.A[["Q"]][, seq_len(n)] )
identical(E.qr.A[["R"]], qr.A@R)
## ae1(E.qr.A[["Q"]], slowQ(qr.A@V, qr.A@beta))
ae1(crossprod(E.qr.A[["Q"]]), diag(m))
ae1(A, with(e.qr.A, P1. \%*\% Q1 \%*\% R1 \%*\% P2.))
ae1(A, with(E.qr.A, P1. \%*\% Q \%*\% R \%*\% P2.))
ae2(A.perm <- A[qr.A@p + 1L, qr.A@q + 1L], with(e.qr.A, Q1 \%*\% R1))
ae2(A.perm , with(E.qr.A, Q \%*\% R ))
})
## More identities
b <- rnorm(m)
stopifnot(exprs = {
ae1(qrX <- qr.X (qr.A ), A)
ae2(qrQ <- qr.Q (qr.A ), with(e.qr.A, P1. \%*\% Q1))
ae2( qr.R (qr.A ), with(e.qr.A, R1))
ae2(qrc <- qr.coef (qr.A, b), with(e.qr.A, solve(R1 \%*\% P2., t(qrQ)) \%*\% b))
ae2(qrf <- qr.fitted(qr.A, b), with(e.qr.A, tcrossprod(qrQ) \%*\% b))
ae2(qrr <- qr.resid (qr.A, b), b - qrf)
ae2(qrq <- qr.qy (qr.A, b), with(E.qr.A, P1. \%*\% Q \%*\% b))
ae2(qr.qty(qr.A, qrq), b)
})
## Sparse and dense computations should agree here
qr.Am <- qr(as(A, "matrix")) # <=> qr.default(A)
stopifnot(exprs = {
ae2(qrX, qr.X (qr.Am ))
ae2(qrc, qr.coef (qr.Am, b))
ae2(qrf, qr.fitted(qr.Am, b))
ae2(qrr, qr.resid (qr.Am, b))
})
}
Matrix/man/CAex.Rd 0000644 0001751 0000144 00000002503 14446607050 013424 0 ustar hornik users \name{CAex}
\title{Albers' example Matrix with "Difficult" Eigen Factorization}
%
\docType{data}
\keyword{datasets}
%
\alias{CAex}
%
\description{
An example of a sparse matrix for which \code{\link{eigen}()} seemed
to be difficult, an unscaled version of this has been posted to the
web, accompanying an E-mail to R-help
(\url{https://stat.ethz.ch/mailman/listinfo/r-help}), by
Casper J Albers, Open University, UK.
}
\usage{data(CAex)}
\format{
This is a \eqn{72 \times 72}{72 * 72} symmetric matrix with 216
non-zero entries in five bands, stored as sparse matrix of class
\code{\linkS4class{dgCMatrix}}.
}
\details{
Historical note (2006-03-30):
In earlier versions of \R, \code{\link{eigen}(CAex)} fell into an
infinite loop whereas \code{\link{eigen}(CAex, EISPACK=TRUE)} had been okay.
}
% \source{}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
data(CAex, package = "Matrix")
str(CAex) # of class "dgCMatrix"
image(CAex)# -> it's a simple band matrix with 5 bands
## and the eigen values are basically 1 (42 times) and 0 (30 x):
zapsmall(ev <- eigen(CAex, only.values=TRUE)$values)
## i.e., the matrix is symmetric, hence
sCA <- as(CAex, "symmetricMatrix")
## and
stopifnot(class(sCA) == "dsCMatrix",
as(sCA, "matrix") == as(CAex, "matrix"))
}
Matrix/man/index-class.Rd 0000644 0001751 0000144 00000001274 14575137654 015035 0 ustar hornik users \name{index-class}
\title{Virtual Class \dQuote{index} of Index Vectors}
%
\docType{class}
\keyword{classes}
%
\alias{index-class}
%
\description{
Class \code{index} is a virtual class designating index vectors,
or \dQuote{subscripts}, for (possibly named) vectors and arrays.
It is typically used in signatures of methods for the subscript
and subassignment operators, namely \code{[} and \code{[<-}.
It is implemented as a \emph{union} of the atomic vector classes
\code{\linkS4class{numeric}}, \code{\linkS4class{logical}},
and \code{\linkS4class{character}}.
}
\seealso{
\code{\link{[}}, \code{\link{[-methods}}, and
\code{\link{[<--methods}}.
}
\examples{
showClass("index")
}
Matrix/man/denseMatrix-class.Rd 0000644 0001751 0000144 00000003430 14500445405 016165 0 ustar hornik users \name{denseMatrix-class}
\title{Virtual Class "denseMatrix" of All Dense Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{denseMatrix-class}
%
\alias{-,denseMatrix,missing-method}
\alias{Math,denseMatrix-method}
\alias{Summary,denseMatrix-method}
\alias{coerce,ANY,denseMatrix-method}
\alias{coerce,matrix,denseMatrix-method}
\alias{coerce,vector,denseMatrix-method}
\alias{diag,denseMatrix-method}
\alias{diag<-,denseMatrix-method}
\alias{diff,denseMatrix-method}
\alias{dim<-,denseMatrix-method}
\alias{log,denseMatrix-method}
\alias{mean,denseMatrix-method}
\alias{rep,denseMatrix-method}
\alias{show,denseMatrix-method}
\alias{t,denseMatrix-method}
%
\description{This is the virtual class of all dense (S4) matrices.
It partitions into two subclasses
\code{\linkS4class{packedMatrix}} and
\code{\linkS4class{unpackedMatrix}}.
Alternatively into the (currently) three subclasses
\code{\linkS4class{ddenseMatrix}},
\code{\linkS4class{ldenseMatrix}}, and
\code{\linkS4class{ndenseMatrix}}.
\code{denseMatrix} is (hence) the direct superclass of these (\eqn{2+3 = 5}) classes.
}
\section{Extends}{
class \code{"Matrix"} directly.
}
\section{Slots}{
exactly those of its superclass \code{"\linkS4class{Matrix}"}, i.e.,
\code{"Dim"} and \code{"Dimnames"}.
}
%
\section{Methods}{
Use \code{\link{showMethods}(class = "denseMatrix", where =
"package:Matrix")} for an overview of methods.
Extraction (\code{"["}) methods,
see \code{\link{[-methods}}.%-> ./Xtrct-methods.Rd
}
\seealso{
\code{\link{colSums}}, \code{\link{kronecker}}, and other such methods
with own help pages.
Its superclass \code{\linkS4class{Matrix}}, and main subclasses,
\code{\linkS4class{ddenseMatrix}} and \code{\linkS4class{sparseMatrix}}.
}
\examples{
showClass("denseMatrix")
}
Matrix/man/ltrMatrix-class.Rd 0000644 0001751 0000144 00000004221 14467516513 015702 0 ustar hornik users \name{ltrMatrix-class}
\title{Triangular Dense Logical Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{ltrMatrix-class}
\alias{ltpMatrix-class}
%
\description{
The \code{"ltrMatrix"} class is the class of triangular, dense,
logical matrices in nonpacked storage. The \code{"ltpMatrix"} class
is the same except in packed storage.
}
\section{Slots}{
\describe{
\item{\code{x}:}{Object of class \code{"logical"}. The logical
values that constitute the matrix, stored in column-major order.}
\item{\code{uplo}:}{Object of class \code{"character"}. Must be
either "U", for upper triangular, and "L", for lower triangular.}
\item{\code{diag}:}{Object of class \code{"character"}. Must be
either \code{"U"}, for unit triangular (diagonal is all ones), or
\code{"N"}; see \code{\linkS4class{triangularMatrix}}.}
\item{\code{Dim},\code{Dimnames}:}{The dimension (a length-2
\code{"integer"}) and corresponding names (or \code{NULL}), see the
\code{\linkS4class{Matrix}} class.}
\item{\code{factors}:}{Object of class \code{"list"}. A named
list of factorizations that have been computed for the matrix.}
}
}
\section{Extends}{
Both extend classes \code{"\linkS4class{ldenseMatrix}"} and
\code{"\linkS4class{triangularMatrix}"}, directly; further, class
\code{"Matrix"}, \code{"\linkS4class{lMatrix}"} and others,
\emph{in}directly. Use \code{\link{showClass}("ltrMatrix")}, e.g.,
for details.
}
\section{Methods}{
Currently, mainly \code{\link{t}()} and coercion methods (for
\code{\link{as}(.)}; use, e.g.,
\code{\link{showMethods}(class="ltrMatrix")} for details.
}
\seealso{
Classes \code{\linkS4class{lgeMatrix}}, \code{\linkS4class{Matrix}};
function \code{\link[base]{t}}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
showClass("ltrMatrix")
str(new("ltpMatrix"))
(lutr <- as(upper.tri(matrix(, 4, 4)), "ldenseMatrix"))
str(lutp <- pack(lutr)) # packed matrix: only 10 = 4*(4+1)/2 entries
!lutp # the logical negation (is *not* logical triangular !)
## but this one is:
stopifnot(all.equal(lutp, pack(!!lutp)))
}
Matrix/man/USCounties.Rd 0000644 0001751 0000144 00000004212 14447626522 014652 0 ustar hornik users \name{USCounties}
\title{Contiguity Matrix of U.S. Counties}
%
\docType{data}
\keyword{datasets}
%
\alias{USCounties}
%
\description{
This matrix gives the contiguities of 3111 U.S. counties,
using the queen criterion of at least one shared vertex
or edge.
}
\usage{data(USCounties)}
\format{
A \eqn{3111 \times 3111}{3111-by-3111} sparse, symmetric
matrix of class \code{\linkS4class{dsCMatrix}}, with 9101
nonzero entries.
}
\source{
GAL lattice file \file{usc_q.GAL}
(retrieved in 2008 from
\file{http://sal.uiuc.edu/weights/zips/usc.zip}
with permission from Luc Anselin for use and distribution)
was read into \R{} using function \code{read.gal}
from package \CRANpkg{spdep}.
Neighbour lists were augmented with row-standardized
(and then symmetrized) spatial weights, using functions
\code{nb2listw} and \code{similar.listw} from packages
\CRANpkg{spdep} and \CRANpkg{spatialreg}.
The resulting \code{listw} object was coerced to class
\code{\linkS4class{dsTMatrix}}
using \code{as_dsTMatrix_listw} from \CRANpkg{spatialreg},
and subsequently to class \code{\linkS4class{dsCMatrix}}.
}
\references{
Ord, J. K. (1975).
Estimation methods for models of spatial interaction.
\emph{Journal of the American Statistical Association},
\emph{70}(349), 120-126.
\doi{10.2307/2285387}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
library(utils, pos = "package:base", verbose = FALSE)
}
data(USCounties, package = "Matrix")
(n <- ncol(USCounties))
I <- .symDiagonal(n)
set.seed(1)
r <- 50L
rho <- 1 / runif(r, 0, 0.5)
system.time(MJ0 <- sapply(rho, function(mult)
determinant(USCounties + mult * I, logarithm = TRUE)$modulus))
## Can be done faster by updating the Cholesky factor:
C1 <- Cholesky(USCounties, Imult = 2)
system.time(MJ1 <- sapply(rho, function(mult)
determinant(update(C1, USCounties, mult), sqrt = FALSE)$modulus))
stopifnot(all.equal(MJ0, MJ1))
C2 <- Cholesky(USCounties, super = TRUE, Imult = 2)
system.time(MJ2 <- sapply(rho, function(mult)
determinant(update(C2, USCounties, mult), sqrt = FALSE)$modulus))
stopifnot(all.equal(MJ0, MJ2))
}
Matrix/man/lgeMatrix-class.Rd 0000644 0001751 0000144 00000003617 14467516513 015660 0 ustar hornik users \name{lgeMatrix-class}
\title{Class "lgeMatrix" of General Dense Logical Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{lgeMatrix-class}
%
\alias{Arith,lgeMatrix,lgeMatrix-method}
\alias{Compare,lgeMatrix,lgeMatrix-method}
\alias{Logic,lgeMatrix,lgeMatrix-method}
%
\description{This is the class of general dense \code{\link{logical}}
matrices.
}
\section{Slots}{
\describe{
\item{\code{x}:}{Object of class \code{"logical"}. The logical
values that constitute the matrix, stored in column-major order.}
\item{\code{Dim},\code{Dimnames}:}{The dimension (a length-2
\code{"integer"}) and corresponding names (or \code{NULL}), see the
\code{\linkS4class{Matrix}} class.}
\item{\code{factors}:}{Object of class \code{"list"}. A named
list of factorizations that have been computed for the matrix.}
}
}
\section{Extends}{
Class \code{"ldenseMatrix"}, directly.
Class \code{"lMatrix"}, by class \code{"ldenseMatrix"}.
Class \code{"denseMatrix"}, by class \code{"ldenseMatrix"}.
Class \code{"Matrix"}, by class \code{"ldenseMatrix"}.
Class \code{"Matrix"}, by class \code{"ldenseMatrix"}.
}
\section{Methods}{
Currently, mainly \code{\link{t}()} and coercion methods (for
\code{\link{as}(.)}); use, e.g.,
\code{\link{showMethods}(class="lgeMatrix")} for details.
}
\seealso{
Non-general logical dense matrix classes such as
\code{\linkS4class{ltrMatrix}}, or \code{\linkS4class{lsyMatrix}};
\emph{sparse} logical classes such as \code{\linkS4class{lgCMatrix}}.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
library(utils, pos = "package:base", verbose = FALSE)
}
showClass("lgeMatrix")
str(new("lgeMatrix"))
set.seed(1)
(lM <- Matrix(matrix(rnorm(28), 4,7) > 0))# a simple random lgeMatrix
set.seed(11)
(lC <- Matrix(matrix(rnorm(28), 4,7) > 0))# a simple random lgCMatrix
as(lM, "CsparseMatrix")
}
Matrix/man/nMatrix-class.Rd 0000644 0001751 0000144 00000005550 14500445405 015331 0 ustar hornik users \name{nMatrix-class}
\title{Class "nMatrix" of Non-zero Pattern Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{nMatrix-class}
%
\alias{Arith,logical,nMatrix-method}
\alias{Arith,nMatrix,logical-method}
\alias{Arith,nMatrix,numeric-method}
\alias{Arith,numeric,nMatrix-method}
\alias{Compare,logical,nMatrix-method}
\alias{Compare,nMatrix,logical-method}
\alias{Compare,nMatrix,nMatrix-method}
\alias{Compare,nMatrix,numeric-method}
\alias{Compare,numeric,nMatrix-method}
\alias{Logic,logical,nMatrix-method}
\alias{Logic,nMatrix,Matrix-method}
\alias{Logic,nMatrix,logical-method}
\alias{Logic,nMatrix,nMatrix-method}
\alias{Logic,nMatrix,numeric-method}
\alias{Logic,nMatrix,sparseVector-method}
\alias{Logic,numeric,nMatrix-method}
\alias{Ops,nMatrix,dMatrix-method}
\alias{Ops,nMatrix,lMatrix-method}
\alias{Ops,nMatrix,nMatrix-method}
\alias{Ops,nMatrix,numeric-method}
\alias{Ops,numeric,nMatrix-method}
\alias{coerce,matrix,nMatrix-method}
\alias{coerce,vector,nMatrix-method}
%
\description{
The \code{nMatrix} class is the virtual \dQuote{mother} class of all
\emph{\bold{n}on-zero pattern} (or simply \emph{patter\bold{n}})
matrices in the \pkg{Matrix} package.
}
%\section{Objects from the Class}{A virtual Class: No objects may be
% created from it.
%}
\section{Slots}{
Common to \emph{all} matrix object in the package:
\describe{
\item{\code{Dim}:}{Object of class \code{"integer"} - the dimensions
of the matrix - must be an integer vector with exactly two
non-negative values.}
\item{\code{Dimnames}:}{list of length two; each component
containing NULL or a \code{\link{character}} vector length
equal the corresponding \code{Dim} element.}
}
}
\section{Methods}{
\describe{
\item{coerce}{\code{signature(from = "matrix", to = "nMatrix")}:
Note that these coercions (must) coerce \code{\link{NA}}s to
non-zero, hence conceptually \code{TRUE}.
This is particularly important when
\code{\linkS4class{sparseMatrix}} objects are coerced to
\code{"nMatrix"} and hence to \code{\linkS4class{nsparseMatrix}}.
}
}
--- --- ---
Additional methods contain group methods, such as
\describe{
\item{Ops}{\code{signature(e1 = "nMatrix", e2 = "....")}, \dots}
\item{Arith}{\code{signature(e1 = "nMatrix", e2 = "....")}, \dots}
\item{Compare}{\code{signature(e1 = "nMatrix", e2 = "....")}, \dots}
\item{Logic}{\code{signature(e1 = "nMatrix", e2 = "....")}, \dots}
\item{Summary}{\code{signature(x = "nMatrix", "....")}, \dots}
}
}
\seealso{
The classes \code{\linkS4class{lMatrix}},
\code{\linkS4class{nsparseMatrix}}, and the mother class,
\code{\linkS4class{Matrix}}.
}
\examples{
getClass("nMatrix")
L3 <- Matrix(upper.tri(diag(3)))
L3 # an "ltCMatrix"
as(L3, "nMatrix") # -> ntC*
## similar, not using Matrix()
as(upper.tri(diag(3)), "nMatrix")# currently "ngTMatrix"
}
Matrix/man/nsyMatrix-class.Rd 0000644 0001751 0000144 00000004322 14467516513 015714 0 ustar hornik users \name{nsyMatrix-class}
\title{Symmetric Dense Nonzero-Pattern Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{nsyMatrix-class}
\alias{nspMatrix-class}
%
\description{
The \code{"nsyMatrix"} class is the class of symmetric, dense nonzero-pattern
matrices in non-packed storage and \code{"nspMatrix"} is the class of
of these in packed storage. Only the upper triangle or the
lower triangle is stored.
}
\section{Objects from the Class}{
Objects can be created by calls of the form \code{new("nsyMatrix", ...)}.
}
\section{Slots}{
\describe{
\item{\code{uplo}:}{Object of class \code{"character"}. Must be
either "U", for upper triangular, and "L", for lower triangular.}
\item{\code{x}:}{Object of class \code{"logical"}. The logical
values that constitute the matrix, stored in column-major order.}
\item{\code{Dim},\code{Dimnames}:}{The dimension (a length-2
\code{"integer"}) and corresponding names (or \code{NULL}), see the
\code{\linkS4class{Matrix}} class.}
\item{\code{factors}:}{Object of class \code{"list"}. A named
list of factorizations that have been computed for the matrix.}
}
}
\section{Extends}{
\code{"nsyMatrix"} extends class \code{"ngeMatrix"}, directly, whereas\cr
\code{"nspMatrix"} extends class \code{"ndenseMatrix"}, directly.
Both extend class \code{"symmetricMatrix"}, directly,
and class \code{"Matrix"} and others, \emph{in}directly, use
\code{\link{showClass}("nsyMatrix")}, e.g., for details.
}
\section{Methods}{
Currently, mainly \code{\link{t}()} and coercion methods (for
\code{\link{as}(.)}; use, e.g.,
\code{\link{showMethods}(class="nsyMatrix")} for details.
}
%\references{}
%\author{}
\seealso{
\code{\linkS4class{ngeMatrix}}, \code{\linkS4class{Matrix}},
\code{\link[base]{t}}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
(s0 <- new("nsyMatrix"))
(M2 <- Matrix(c(TRUE, NA, FALSE, FALSE), 2, 2)) # logical dense (ltr)
(sM <- M2 & t(M2)) # -> "lge"
class(sM <- as(sM, "nMatrix")) # -> "nge"
(sM <- as(sM, "symmetricMatrix")) # -> "nsy"
str(sM <- as(sM, "packedMatrix")) # -> "nsp", i.e., packed symmetric
}
Matrix/man/ddiMatrix-class.Rd 0000644 0001751 0000144 00000006241 14500644730 015634 0 ustar hornik users \name{ddiMatrix-class}
\title{Class "ddiMatrix" of Diagonal Numeric Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{ddiMatrix-class}
%
\alias{\%\%,ddiMatrix,Matrix-method}
\alias{\%\%,ddiMatrix,ddenseMatrix-method}
\alias{\%\%,ddiMatrix,ldenseMatrix-method}
\alias{\%\%,ddiMatrix,ndenseMatrix-method}
\alias{\%/\%,ddiMatrix,Matrix-method}
\alias{\%/\%,ddiMatrix,ddenseMatrix-method}
\alias{\%/\%,ddiMatrix,ldenseMatrix-method}
\alias{\%/\%,ddiMatrix,ndenseMatrix-method}
\alias{&,ddiMatrix,Matrix-method}
\alias{&,ddiMatrix,ddenseMatrix-method}
\alias{&,ddiMatrix,ldenseMatrix-method}
\alias{&,ddiMatrix,ndenseMatrix-method}
\alias{*,ddiMatrix,Matrix-method}
\alias{*,ddiMatrix,ddenseMatrix-method}
\alias{*,ddiMatrix,ldenseMatrix-method}
\alias{*,ddiMatrix,ndenseMatrix-method}
\alias{/,ddiMatrix,Matrix-method}
\alias{/,ddiMatrix,ddenseMatrix-method}
\alias{/,ddiMatrix,ldenseMatrix-method}
\alias{/,ddiMatrix,ndenseMatrix-method}
\alias{Arith,ddiMatrix,logical-method}
\alias{Arith,ddiMatrix,numeric-method}
\alias{Arith,logical,ddiMatrix-method}
\alias{Arith,numeric,ddiMatrix-method}
\alias{Ops,ANY,ddiMatrix-method}
\alias{Ops,ddiMatrix,ANY-method}
\alias{Ops,ddiMatrix,Matrix-method}
\alias{Ops,ddiMatrix,dMatrix-method}
\alias{Ops,ddiMatrix,ddiMatrix-method}
\alias{Ops,ddiMatrix,ldiMatrix-method}
\alias{Ops,ddiMatrix,ndiMatrix-method}
\alias{Ops,ddiMatrix,logical-method}
\alias{Ops,ddiMatrix,numeric-method}
\alias{Ops,ddiMatrix,sparseMatrix-method}
%
\description{The class \code{"ddiMatrix"} of numerical diagonal matrices.
%% FIXME add more
Note that diagonal matrices now extend \emph{\code{sparseMatrix}}, whereas
they did extend dense matrices earlier.% up to early summer 2008.
}
\section{Objects from the Class}{
Objects can be created by calls of the form \code{new("ddiMatrix", ...)}
but typically rather via \code{\link{Diagonal}}.
}
\section{Slots}{
\describe{
\item{\code{x}:}{numeric vector. For an \eqn{n \times n}{n * n}
matrix, the \code{x} slot is of length \eqn{n} or \code{0},
depending on the \code{diag} slot:}
\item{\code{diag}:}{\code{"character"} string, either \code{"U"} or
\code{"N"} where \code{"U"} denotes unit-diagonal, i.e., identity
matrices.}
\item{\code{Dim},\code{Dimnames}:}{matrix dimension and
\code{\link{dimnames}}, see the \code{\linkS4class{Matrix}} class
description.}
}
}
\section{Extends}{
Class \code{"\linkS4class{diagonalMatrix}"}, directly.
Class \code{"\linkS4class{dMatrix}"}, directly.
Class \code{"\linkS4class{sparseMatrix}"}, indirectly, see
\code{\link{showClass}("ddiMatrix")}.
}
\section{Methods}{
\describe{
\item{\%*\%}{\code{signature(x = "ddiMatrix", y = "ddiMatrix")}: ... }
}
}
\seealso{
Class \code{\linkS4class{diagonalMatrix}} and function \code{\link{Diagonal}}.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
(d2 <- Diagonal(x = c(10,1)))
str(d2)
## slightly larger in internal size:
str(as(d2, "sparseMatrix"))
M <- Matrix(cbind(1,2:4))
M \%*\% d2 #> `fast' multiplication
chol(d2) # trivial
stopifnot(is(cd2 <- chol(d2), "ddiMatrix"),
all.equal(cd2@x, c(sqrt(10),1)))
}
Matrix/man/TsparseMatrix-class.Rd 0000644 0001751 0000144 00000005542 14467224234 016525 0 ustar hornik users \name{TsparseMatrix-class}
\title{Class "TsparseMatrix" of Sparse Matrices in Triplet Form}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{TsparseMatrix-class}
%
\alias{coerce,matrix,TsparseMatrix-method}
\alias{coerce,vector,TsparseMatrix-method}
\alias{diag,TsparseMatrix-method}
\alias{diag<-,TsparseMatrix-method}
\alias{t,TsparseMatrix-method}
%
\description{The \code{"TsparseMatrix"} class is the virtual class of
all sparse matrices coded in triplet form. Since it is a virtual class,
no objects may be created from it. See
\code{showClass("TsparseMatrix")} for its subclasses.
}
\section{Slots}{
\describe{
\item{\code{Dim}, \code{Dimnames}:}{from the \code{"\linkS4class{Matrix}"} class,}
\item{\code{i}:}{Object of class \code{"integer"} - the row indices
of non-zero entries \emph{in 0-base}, i.e., must be in
\code{0:(nrow(.)-1)}.}
\item{\code{j}:}{Object of class \code{"integer"} - the column
indices of non-zero entries. Must be the same length as slot
\code{i} and \emph{0-based} as well, i.e., in
\code{0:(ncol(.)-1)}. For numeric Tsparse matrices, \code{(i,j)}
pairs can occur more than once, see \code{\linkS4class{dgTMatrix}}.
}
}
}
\section{Extends}{
Class \code{"sparseMatrix"}, directly.
Class \code{"Matrix"}, by class \code{"sparseMatrix"}.
}
\section{Methods}{
Extraction (\code{"["}) methods, see
\code{\link{[-methods}}.%-> ./Xtrct-methods.Rd
}
\note{
Most operations with sparse matrices are performed using the
compressed, column-oriented or \code{\linkS4class{CsparseMatrix}}
representation. The triplet representation is convenient for
creating a sparse matrix or for reading and writing such
matrices. Once it is created, however, the matrix is generally
coerced to a \code{\linkS4class{CsparseMatrix}} for further
operations.
Note that all \code{new(.)}, \code{\link{spMatrix}} and
\code{\link{sparseMatrix}(*, repr="T")} constructors
for \code{"TsparseMatrix"} classes implicitly add (i.e., \dQuote{sum up})
\eqn{x_k}'s that belong to identical \eqn{(i_k, j_k)} pairs, see, the
example below, or also \code{"\linkS4class{dgTMatrix}"}.
For convenience, methods for some operations such as \code{\%*\%}
and \code{crossprod} are defined for
\code{\linkS4class{TsparseMatrix}} objects. These methods simply
coerce the \code{\linkS4class{TsparseMatrix}} object to a
\code{\linkS4class{CsparseMatrix}} object then perform the
operation.
}
% \author{Martin Maechler}
\seealso{
its superclass, \code{\linkS4class{sparseMatrix}}, and the
\code{\linkS4class{dgTMatrix}} class, for the links to other classes.
}
\examples{
showClass("TsparseMatrix")
## or just the subclasses' names
names(getClass("TsparseMatrix")@subclasses)
T3 <- spMatrix(3,4, i=c(1,3:1), j=c(2,4:2), x=1:4)
T3 # only 3 non-zero entries, 5 = 1+4 !
\dontshow{stopifnot(nnzero(T3) == 3)}
}
Matrix/man/rcond-methods.Rd 0000644 0001751 0000144 00000012223 14575137654 015365 0 ustar hornik users \name{rcond-methods}
\title{Estimate the Reciprocal Condition Number}
%
\docType{methods}
\keyword{algebra}
\keyword{math}
\keyword{methods}
%
\alias{rcond}
\alias{rcond-methods}
%
\alias{rcond,ANY,missing-method}
\alias{rcond,denseMatrix,character-method}
\alias{rcond,diagonalMatrix,character-method}
\alias{rcond,indMatrix,character-method}
\alias{rcond,pMatrix,character-method}
\alias{rcond,sparseMatrix,character-method}
%
\usage{
rcond(x, norm, \dots)
\S4method{rcond}{sparseMatrix,character}(x, norm, useInv=FALSE, \dots)
}
\description{
Estimate the reciprocal of the condition number of a matrix.
This is a generic function with several methods, as seen by
\code{\link{showMethods}(rcond)}.
}
\arguments{
\item{x}{an \R object that inherits from the \code{Matrix} class.}
\item{norm}{character string indicating the type of norm to be used in
the estimate. The default is \code{"O"} for the 1-norm (\code{"O"} is
equivalent to \code{"1"}). For sparse matrices, when \code{useInv=TRUE},
\code{norm} can be any of the \code{kind}s allowed for \code{\link{norm}};
otherwise, the other possible value is \code{"I"} for the infinity
norm, see also \code{\link{norm}}.
}
\item{useInv}{logical (or \code{"Matrix"} containing
\code{\link{solve}(x)}). If not false, compute the reciprocal
condition number as \eqn{1/(\|x\| \cdot \|x^{-1}\|)}{1/(||x|| * ||x^(-1)||)},
where \eqn{x^{-1}}{x^(-1)} is the inverse of \eqn{x}, \code{solve(x)}.
This may be an efficient alternative (only) in situations where
\code{solve(x)} is fast (or known), e.g., for (very) sparse or
triangular matrices.
Note that the \emph{result} may differ depending on \code{useInv},
as per default, when it is false, an \emph{approximation} is
computed.
}
\item{\dots}{further arguments passed to or from other methods.}
}
\value{
An estimate of the reciprocal condition number of \code{x}.
}
\section{BACKGROUND}{
The condition number of a regular (square) matrix is the product of
the \code{\link{norm}} of the matrix and the norm of its inverse (or
pseudo-inverse).
More generally, the condition number is defined (also for
non-square matrices \eqn{A}) as
\deqn{\kappa(A) = \frac{\max_{\|v\| = 1} \|A v\|}{\min_{\|v\| = 1} \|A v\|}.}{%
kappa(A) = (max_(||v|| = 1; || Av ||)) /(min_(||v|| = 1; || Av ||)).}
Whenever \code{x} is \emph{not} a square matrix, in our method
definitions, this is typically computed via \code{rcond(qr.R(qr(X)), ...)}
where \code{X} is \code{x} or \code{t(x)}.
The condition number takes on values between 1 and infinity,
inclusive, and can be viewed as a factor by which errors in solving
linear systems with this matrix as coefficient matrix could be
magnified.
\code{rcond()} computes the \emph{reciprocal} condition number
\eqn{1/\kappa} with values in \eqn{[0,1]} and can be viewed as a
scaled measure of how close a matrix is to being rank deficient (aka
\dQuote{singular}).
Condition numbers are usually estimated, since exact computation is
costly in terms of floating-point operations. An (over) estimate of
reciprocal condition number is given, since by doing so overflow is
avoided. Matrices are well-conditioned if the reciprocal condition
number is near 1 and ill-conditioned if it is near zero.
}
\seealso{
\code{\link{norm}}, \code{\link[base]{kappa}()} from package
\pkg{base} computes an \emph{approximate} condition number of a
\dQuote{traditional} matrix, even non-square ones, with respect to the
\eqn{p=2} (Euclidean) \code{\link{norm}}.
\code{\link[base]{solve}}.
\code{\link{condest}}, a newer \emph{approximate} estimate of
the (1-norm) condition number, particularly efficient for large sparse
matrices.
}
\references{
Golub, G., and Van Loan, C. F. (1989).
\emph{Matrix Computations,}
2nd edition, Johns Hopkins, Baltimore.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
}
x <- Matrix(rnorm(9), 3, 3)
rcond(x)
## typically "the same" (with more computational effort):
1 / (norm(x) * norm(solve(x)))
rcond(Hilbert(9)) # should be about 9.1e-13
## For non-square matrices:
rcond(x1 <- cbind(1,1:10))# 0.05278
rcond(x2 <- cbind(x1, 2:11))# practically 0, since x2 does not have full rank
## sparse
(S1 <- Matrix(rbind(0:1,0, diag(3:-2))))
rcond(S1)
m1 <- as(S1, "denseMatrix")
all.equal(rcond(S1), rcond(m1))
## wide and sparse
rcond(Matrix(cbind(0, diag(2:-1))))
## Large sparse example ----------
m <- Matrix(c(3,0:2), 2,2)
M <- bdiag(kronecker(Diagonal(2), m), kronecker(m,m))
36*(iM <- solve(M)) # still sparse
MM <- kronecker(Diagonal(10), kronecker(Diagonal(5),kronecker(m,M)))
dim(M3 <- kronecker(bdiag(M,M),MM)) # 12'800 ^ 2
if(interactive()) ## takes about 2 seconds if you have >= 8 GB RAM
system.time(r <- rcond(M3))
## whereas this is *fast* even though it computes solve(M3)
system.time(r. <- rcond(M3, useInv=TRUE))
if(interactive()) ## the values are not the same
c(r, r.) # 0.05555 0.013888
## for all 4 norms available for sparseMatrix :
cbind(rr <- sapply(c("1","I","F","M"),
function(N) rcond(M3, norm=N, useInv=TRUE)))
\dontshow{stopifnot(all.equal(r., 1/72, tolerance=1e-12))}
}
Matrix/man/isSymmetric-methods.Rd 0000644 0001751 0000144 00000007611 14467101201 016550 0 ustar hornik users \name{isSymmetric-methods}
\title{Methods for Function 'isSymmetric' in Package 'Matrix'}
%
\docType{methods}
\keyword{array}
\keyword{programming}
\keyword{methods}
%
\alias{isSymmetric}
\alias{isSymmetric-methods}
%
\alias{isSymmetric,CsparseMatrix-method}
\alias{isSymmetric,RsparseMatrix-method}
\alias{isSymmetric,TsparseMatrix-method}
\alias{isSymmetric,denseMatrix-method}
\alias{isSymmetric,diagonalMatrix-method}
\alias{isSymmetric,indMatrix-method}
% tolerating numerical fuzz for [dz]Matrix:
\alias{isSymmetric,dgCMatrix-method}
\alias{isSymmetric,dgRMatrix-method}
\alias{isSymmetric,dgTMatrix-method}
\alias{isSymmetric,dgeMatrix-method}
\alias{isSymmetric,dtCMatrix-method}
\alias{isSymmetric,dtRMatrix-method}
\alias{isSymmetric,dtTMatrix-method}
\alias{isSymmetric,dtpMatrix-method}
\alias{isSymmetric,dtrMatrix-method}
%
\description{
\code{isSymmetric} tests whether its argument is a symmetric square
matrix, by default tolerating some numerical fuzz and requiring
symmetric \code{[dD]imnames} in addition to symmetry in the
mathematical sense. \code{isSymmetric} is a generic function in
\pkg{base}, which has a \link[=isSymmetric]{method} for traditional
matrices of implicit \code{\link{class}} \code{"\link{matrix}"}.
Methods are defined here for various proper and virtual classes
in \pkg{Matrix}, so that \code{isSymmetric} works for all objects
inheriting from virtual class \code{"\linkS4class{Matrix}"}.
}
\usage{
\S4method{isSymmetric}{denseMatrix}(object, checkDN = TRUE, \dots)
\S4method{isSymmetric}{CsparseMatrix}(object, checkDN = TRUE, \dots)
\S4method{isSymmetric}{RsparseMatrix}(object, checkDN = TRUE, \dots)
\S4method{isSymmetric}{TsparseMatrix}(object, checkDN = TRUE, \dots)
\S4method{isSymmetric}{diagonalMatrix}(object, checkDN = TRUE, \dots)
\S4method{isSymmetric}{indMatrix}(object, checkDN = TRUE, \dots)
\S4method{isSymmetric}{dgeMatrix}(object, checkDN = TRUE, tol = 100 * .Machine$double.eps, tol1 = 8 * tol, \dots)
\S4method{isSymmetric}{dgCMatrix}(object, checkDN = TRUE, tol = 100 * .Machine$double.eps, \dots)
}
\arguments{
\item{object}{a \code{"Matrix"}.}
\item{checkDN}{a \link{logical} indicating whether symmetry of the
\code{Dimnames} \link{slot} of \code{object} should be checked.}
\item{tol, tol1}{numerical tolerances allowing \emph{approximate}
symmetry of numeric (rather than logical) matrices. See also
\code{\link{isSymmetric.matrix}}.}
\item{\dots}{further arguments passed to methods
(typically methods for \code{\link{all.equal}}).}
}
\value{
A \link{logical}, either \code{TRUE} or \code{FALSE}
(never \code{\link{NA}}).
}
\details{
The \code{Dimnames} \link{slot} of \code{object}, say \code{dn},
is considered to be symmetric if and only if
\itemize{
\item \code{dn[[1]]} and \code{dn[[2]]} are identical \emph{or}
one is \code{NULL}; \emph{and}
\item \code{ndn <- names(dn)} is \code{NULL} \emph{or}
\code{ndn[1]} and \code{ndn[2]} are identical \emph{or}
one is the empty string \code{""}.
}
Hence \code{list(a=nms, a=nms)} is considered to be \emph{symmetric},
and so too are \code{list(a=nms, NULL)} and \code{list(NULL, a=nms)}.
Note that this definition is \emph{looser} than that employed by
\code{\link{isSymmetric.matrix}}, which requires \code{dn[1]} and
\code{dn[2]} to be identical, where \code{dn} is the \code{dimnames}
\link[=attr]{attribute} of a traditional matrix.
}
\seealso{
\code{\link{forceSymmetric}};
\code{\link{symmpart}} and \code{\link{skewpart}};
virtual class \code{"\linkS4class{symmetricMatrix}"} and its subclasses.
}
\examples{
isSymmetric(Diagonal(4)) # TRUE of course
M <- Matrix(c(1,2,2,1), 2,2)
isSymmetric(M) # TRUE (*and* of formal class "dsyMatrix")
isSymmetric(as(M, "generalMatrix")) # still symmetric, even if not "formally"
isSymmetric(triu(M)) # FALSE
## Look at implementations:
showMethods("isSymmetric", includeDefs = TRUE) # includes S3 generic from base
}
Matrix/man/pMatrix-class.Rd 0000644 0001751 0000144 00000012206 14545303537 015337 0 ustar hornik users \name{pMatrix-class}
\title{Permutation matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{pMatrix-class}
%
\alias{coerce,matrix,pMatrix-method}
\alias{coerce,numeric,pMatrix-method}
\alias{determinant,pMatrix,logical-method}
\alias{t,pMatrix-method}
%
\description{
The \code{pMatrix} class is the class of \emph{permutation} matrices,
stored as 1-based integer permutation vectors. A permutation
matrix is a square matrix whose rows \emph{and} columns are all
standard unit vectors. It follows that permutation matrices are
a special case of \emph{index} matrices (hence \code{pMatrix}
is defined as a direct subclass of \code{\linkS4class{indMatrix}}).
Multiplying a matrix on the left by a permutation matrix is
equivalent to permuting its rows. Analogously, multiplying a
matrix on the right by a permutation matrix is equivalent to
permuting its columns. Indeed, such products are implemented in
\pkg{Matrix} as indexing operations; see \sQuote{Details} below.
}
\section{Objects from the Class}{
Objects can be created explicitly with calls of the form
\code{new("pMatrix", ...)}, but they are more commonly created
by coercing 1-based integer index vectors, with calls of the
form \code{as(., "pMatrix")}; see \sQuote{Methods} below.
}
\section{Slots}{
\describe{
\item{\code{margin},\code{perm}}{inherited from superclass
\code{\linkS4class{indMatrix}}. Here, \code{perm} is an
integer vector of length \code{Dim[1]} and a permutation
of \code{1:Dim[1]}.}
\item{\code{Dim},\code{Dimnames}}{inherited from virtual
superclass \code{\linkS4class{Matrix}}.}
}
}
\section{Extends}{
Class \code{"\linkS4class{indMatrix}"}, directly.
}
\section{Methods}{
\describe{
\item{\code{\%*\%}}{\code{signature(x = "pMatrix", y = "Matrix")}
and others listed by \code{showMethods("\%*\%", classes = "pMatrix")}:
matrix products implemented where appropriate as indexing operations.}
\item{\code{coerce}}{\code{signature(from = "numeric", to = "pMatrix")}:
supporting typical \code{pMatrix} construction from a vector
of positive integers, specifically a permutation of \code{1:n}.
Row permutation is assumed.}
\item{t}{\code{signature(x = "pMatrix")}:
the transpose, which is a \code{pMatrix} with identical
\code{perm} but opposite \code{margin}. Coincides with
the inverse, as permutation matrices are orthogonal.}
\item{solve}{\code{signature(a = "pMatrix", b = "missing")}:
the inverse permutation matrix, which is a \code{pMatrix}
with identical \code{perm} but opposite \code{margin}.
Coincides with the transpose, as permutation matrices are
orthogonal. See \code{showMethods("solve", classes = "pMatrix")}
for more signatures.}
\item{determinant}{\code{signature(x = "pMatrix", logarithm = "logical")}:
always returning 1 or -1, as permutation matrices are orthogonal.
In fact, the result is exactly the \emph{sign} of the permutation.}
}
}
\details{
By definition, a permutation matrix is both a row index matrix
and a column index matrix. However, the \code{perm} slot of
a \code{pMatrix} cannot be used interchangeably as a row index
vector and column index vector. If \code{margin=1}, then
\code{perm} is a row index vector, and the corresponding column
index vector can be computed as \code{\link{invPerm}(perm)}, i.e.,
by inverting the permutation. Analogously, if \code{margin=2},
then \code{perm} and \code{invPerm(perm)} are column and row
index vectors, respectively.
Given an \code{n}-by-\code{n} row permutation matrix \code{P}
with \code{perm} slot \code{p} and a matrix \code{M} with
conformable dimensions, we have
\tabular{lclcl}{
\eqn{P M} \tab = \tab \code{P \%*\% M} \tab = \tab \code{M[p, ]}\cr
\eqn{M P} \tab = \tab \code{M \%*\% P} \tab = \tab \code{M[, i(p)]}\cr
\eqn{P'M} \tab = \tab \code{crossprod(P, M)} \tab = \tab \code{M[i(p), ]}\cr
\eqn{MP'} \tab = \tab \code{tcrossprod(M, P)} \tab = \tab \code{M[, p]}\cr
\eqn{P'P} \tab = \tab \code{crossprod(P)} \tab = \tab \code{Diagonal(n)}\cr
\eqn{PP'} \tab = \tab \code{tcrossprod(P)} \tab = \tab \code{Diagonal(n)}
}
where \code{i := invPerm}.
}
\seealso{
Superclass \code{\linkS4class{indMatrix}} of index matrices,
for many inherited methods; \code{\link{invPerm}}, for computing
inverse permutation vectors.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
}
(pm1 <- as(as.integer(c(2,3,1)), "pMatrix"))
t(pm1) # is the same as
solve(pm1)
pm1 \%*\% t(pm1) # check that the transpose is the inverse
stopifnot(all(diag(3) == as(pm1 \%*\% t(pm1), "matrix")),
is.logical(as(pm1, "matrix")))
set.seed(11)
## random permutation matrix :
(p10 <- as(sample(10),"pMatrix"))
## Permute rows / columns of a numeric matrix :
(mm <- round(array(rnorm(3 * 3), c(3, 3)), 2))
mm \%*\% pm1
pm1 \%*\% mm
try(as(as.integer(c(3,3,1)), "pMatrix"))# Error: not a permutation
as(pm1, "TsparseMatrix")
p10[1:7, 1:4] # gives an "ngTMatrix" (most economic!)
## row-indexing of a keeps it as an :
p10[1:3, ]
}
Matrix/man/mat2triplet.Rd 0000644 0001751 0000144 00000004556 14473555676 015105 0 ustar hornik users \name{mat2triplet}
\title{Map Matrix to its Triplet Representation}
%
\keyword{array}
\keyword{utilities}
%
\alias{mat2triplet}
%
\description{
From an \R object coercible to \code{"\linkS4class{TsparseMatrix}"},
typically a (sparse) matrix, produce its triplet representation which may
collapse to a \dQuote{Duplet} in the case of binary aka pattern, such as
\code{"\linkS4class{nMatrix}"} objects.
}
\usage{
mat2triplet(x, uniqT = FALSE)
}
\arguments{
\item{x}{any \R object for which \code{as(x, "\linkS4class{TsparseMatrix}")}
works; typically a \code{\link{matrix}} of one of the \pkg{Matrix}
package matrices.}
\item{uniqT}{\code{\link{logical}} indicating if the triplet
representation should be \sQuote{unique} in the sense of
\code{\link{asUniqueT}(byrow=FALSE)}.}
}
\value{
A \code{\link{list}}, typically with three components,
\item{i}{vector of row indices for all non-zero entries of \code{x}}
\item{i}{vector of columns indices for all non-zero entries of \code{x}}
\item{x}{vector of all non-zero entries of \code{x}; exists \bold{only}
when \code{as(x, "TsparseMatrix")} is \bold{not} a
\code{"\linkS4class{nsparseMatrix}"}.}
Note that the \code{\link{order}} of the entries is determined by the
coercion to \code{"\linkS4class{TsparseMatrix}"} and hence typically
with increasing \code{j} (and increasing \code{i} within ties of \code{j}).
}
\note{
The \code{mat2triplet()} utility was created to be a more efficient and
more predictable substitute for \code{\link{summary}()}.
UseRs have wrongly expected the latter to return a data frame with
columns \code{i} and \code{j} which however is wrong for a
\code{"\linkS4class{diagonalMatrix}"}.
}
\seealso{
The \code{summary()} method for \code{"sparseMatrix"},
\code{\link{summary,sparseMatrix-method}}.
\code{mat2triplet()} is conceptually the \emph{inverse} function of
\code{\link{spMatrix}} and (one case of) \code{\link{sparseMatrix}}.
}
\examples{% ../R/sparseMatrix.R
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
mat2triplet # simple definition
i <- c(1,3:8); j <- c(2,9,6:10); x <- 7 * (1:7)
(Ax <- sparseMatrix(i, j, x = x)) ## 8 x 10 "dgCMatrix"
str(trA <- mat2triplet(Ax))
stopifnot(i == sort(trA$i), sort(j) == trA$j, x == sort(trA$x))
D <- Diagonal(x=4:2)
summary(D)
str(mat2triplet(D))
}
Matrix/man/sparseMatrix-class.Rd 0000644 0001751 0000144 00000013504 14500445405 016367 0 ustar hornik users \name{sparseMatrix-class}
\title{Virtual Class "sparseMatrix" --- Mother of Sparse Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{sparseMatrix-class}
%
\alias{-,sparseMatrix,missing-method}
\alias{Math,sparseMatrix-method}
\alias{Ops,numeric,sparseMatrix-method}
\alias{Ops,sparseMatrix,ddiMatrix-method}
\alias{Ops,sparseMatrix,ldiMatrix-method}
\alias{Ops,sparseMatrix,nsparseMatrix-method}
\alias{Ops,sparseMatrix,numeric-method}
\alias{Ops,sparseMatrix,sparseMatrix-method}
\alias{Summary,sparseMatrix-method}
\alias{coerce,ANY,sparseMatrix-method}
\alias{coerce,factor,sparseMatrix-method}
\alias{coerce,matrix,sparseMatrix-method}
\alias{coerce,vector,sparseMatrix-method}
\alias{cov2cor,sparseMatrix-method}
\alias{diff,sparseMatrix-method}
\alias{dim<-,sparseMatrix-method}
\alias{format,sparseMatrix-method}
\alias{log,sparseMatrix-method}
\alias{mean,sparseMatrix-method}
\alias{print,sparseMatrix-method}
\alias{rep,sparseMatrix-method}
\alias{show,sparseMatrix-method}
\alias{summary,sparseMatrix-method}
%
\alias{print.sparseMatrix} % spoof, only so that users find this topic
%
\description{Virtual Mother Class of All Sparse Matrices}
\section{Slots}{
\describe{
\item{\code{Dim}:}{Object of class \code{"integer"} - the dimensions
of the matrix - must be an integer vector with exactly two
non-negative values.}
\item{\code{Dimnames}:}{a list of length two - inherited from class
\code{Matrix}, see \code{\linkS4class{Matrix}}.}
}
}
\section{Extends}{
Class \code{"Matrix"}, directly.
}
\section{Methods}{
\describe{
\item{show}{\code{(object = "sparseMatrix")}: The
\code{\link{show}} method for sparse matrices prints
\emph{\dQuote{structural}} zeroes as \code{"."} using
\code{\link{printSpMatrix}()} which allows further customization.}
\item{print}{\code{signature(x = "sparseMatrix")}, ....\cr
The \code{\link{print}} method for sparse matrices by default is the
same as \code{show()} but can be called with extra optional
arguments, see \code{\link{printSpMatrix}()}.}
\item{format}{\code{signature(x = "sparseMatrix")}, ....\cr
The \code{\link{format}} method for sparse matrices, see
\code{\link{formatSpMatrix}()} for details such as the extra
optional arguments.}
\item{summary}{\code{(object = "sparseMatrix", uniqT=FALSE)}: Returns
an object of S3 class \code{"sparseSummary"} which is basically a
\code{\link{data.frame}} with columns \code{(i,j,x)} (or just
\code{(i,j)} for \code{\linkS4class{nsparseMatrix}} class objects)
with the stored (typically non-zero) entries. The
\code{\link{print}} method resembles Matlab's way of printing
sparse matrices, and also the MatrixMarket format, see
\code{\link{writeMM}}.}
\item{cbind2}{\code{(x = *, y = *)}: several methods for binding
matrices together, column-wise, see the basic \code{\link{cbind}}
and \code{\link{rbind}} functions.\cr
Note that the result will typically be sparse, even when one
argument is dense and larger than the sparse one.
}
\item{rbind2}{\code{(x = *, y = *)}: binding matrices together
row-wise, see \code{cbind2} above.}
\item{determinant}{\code{(x = "sparseMatrix", logarithm=TRUE)}:
\code{\link{determinant}()} methods for sparse matrices typically
work via \code{\link{Cholesky}} or \code{\link{lu}} decompositions.}
\item{diag}{\code{(x = "sparseMatrix")}: extracts the diagonal of a
sparse matrix.}
\item{dim<-}{\code{signature(x = "sparseMatrix", value = "ANY")}:
allows to \emph{reshape} a sparse matrix to a sparse matrix with
the same entries but different dimensions. \code{value} must be of
length two and fulfill \code{prod(value) == prod(dim(x))}.}
\item{coerce}{\code{signature(from = "factor", to = "sparseMatrix")}:
Coercion of a factor to \code{"sparseMatrix"} produces the matrix
of indicator \bold{rows} stored as an object of class
\code{"dgCMatrix"}. To obtain columns representing the interaction
of the factor and a numeric covariate, replace the \code{"x"} slot
of the result by the numeric covariate then take the transpose.
Missing values (\code{\link{NA}}) from the factor are translated
to columns of all \code{0}s.}
}
See also \code{\link{colSums}}, \code{\link{norm}},
... %% FIXME
for methods with separate help pages.
}
\seealso{
\code{\link{sparseMatrix}}, and its references, such as
\code{\link{xtabs}(*, sparse=TRUE)}, or
\code{\link{sparse.model.matrix}()},
for constructing sparse matrices.
\code{\link{T2graph}} for conversion of \code{"graph"} objects
(package \pkg{graph}) to and from sparse matrices.
}
\note{
In method selection for multiplication operations (i.e. \code{\%*\%}
and the two-argument form of \code{\link[base]{crossprod}})
the sparseMatrix class takes precedence in the sense that if one
operand is a sparse matrix and the other is any type of dense matrix
then the dense matrix is coerced to a \code{dgeMatrix} and the
appropriate sparse matrix method is used.
}
%\author{Martin}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
showClass("sparseMatrix") ## and look at the help() of its subclasses
M <- Matrix(0, 10000, 100)
M[1,1] <- M[2,3] <- 3.14
M ## show(.) method suppresses printing of the majority of rows
data(CAex, package = "Matrix")
dim(CAex) # 72 x 72 matrix
determinant(CAex) # works via sparse lu(.)
## factor -> t( ) :
(fact <- gl(5, 3, 30, labels = LETTERS[1:5]))
(Xt <- as(fact, "sparseMatrix")) # indicator rows
## missing values --> all-0 columns:
f.mis <- fact
i.mis <- c(3:5, 17)
is.na(f.mis) <- i.mis
Xt != (X. <- as(f.mis, "sparseMatrix")) # differ only in columns 3:5,17
stopifnot(all(X.[,i.mis] == 0), all(Xt[,-i.mis] == X.[,-i.mis]))
}
Matrix/man/ndenseMatrix-class.Rd 0000644 0001751 0000144 00000004353 14500644730 016352 0 ustar hornik users \name{ndenseMatrix-class}
\title{Virtual Class "ndenseMatrix" of Dense Logical Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{ndenseMatrix-class}
%
\alias{!,ndenseMatrix-method}
\alias{&,ndenseMatrix,ddiMatrix-method}
\alias{&,ndenseMatrix,ldiMatrix-method}
\alias{&,ndenseMatrix,ndiMatrix-method}
\alias{*,ndenseMatrix,ddiMatrix-method}
\alias{*,ndenseMatrix,ldiMatrix-method}
\alias{*,ndenseMatrix,ndiMatrix-method}
\alias{Ops,ndenseMatrix,ndenseMatrix-method}
\alias{^,ndenseMatrix,ddiMatrix-method}
\alias{^,ndenseMatrix,ldiMatrix-method}
\alias{^,ndenseMatrix,ndiMatrix-method}
\alias{coerce,matrix,ndenseMatrix-method}
\alias{coerce,vector,ndenseMatrix-method}
\alias{which,ndenseMatrix-method}
%
\description{
\code{ndenseMatrix} is the virtual class of all dense \bold{l}ogical
(S4) matrices. It extends both \code{\linkS4class{denseMatrix}}
and \code{\linkS4class{lMatrix}} directly.
}
\section{Slots}{
\describe{
\item{\code{x}:}{logical vector containing the entries of the matrix.}
\item{\code{Dim}, \code{Dimnames}:}{see \code{\linkS4class{Matrix}}.}
}
}
\section{Extends}{
Class \code{"nMatrix"}, directly.
Class \code{"denseMatrix"}, directly.
Class \code{"Matrix"}, by class \code{"nMatrix"}.
Class \code{"Matrix"}, by class \code{"denseMatrix"}.
}
\section{Methods}{
\describe{
\item{\%*\%}{\code{signature(x = "nsparseMatrix", y = "ndenseMatrix")}: ... }
\item{\%*\%}{\code{signature(x = "ndenseMatrix", y = "nsparseMatrix")}: ... }
\item{crossprod}{\code{signature(x = "nsparseMatrix", y = "ndenseMatrix")}: ... }
\item{crossprod}{\code{signature(x = "ndenseMatrix", y = "nsparseMatrix")}: ... }
\item{as.vector}{\code{signature(x = "ndenseMatrix", mode = "missing")}: ...}
\item{diag}{\code{signature(x = "ndenseMatrix")}: extracts the
diagonal as for all matrices, see the generic \code{\link{diag}()}.}
\item{which}{\code{signature(x = "ndenseMatrix")}, semantically
equivalent to \pkg{base} function \code{\link{which}(x, arr.ind)};
for details, see the \code{\linkS4class{lMatrix}} class documentation.}
}
}
\seealso{
Class \code{\linkS4class{ngeMatrix}} and the other subclasses.
}
\examples{
showClass("ndenseMatrix")
as(diag(3) > 0, "ndenseMatrix")# -> "nge"
}
Matrix/man/unpackedMatrix-class.Rd 0000644 0001751 0000144 00000003775 14574651323 016706 0 ustar hornik users \name{unpackedMatrix-class}
\title{Virtual Class \code{"unpackedMatrix"} of Unpacked Dense Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{unpackedMatrix-class}
%
\alias{coerce,matrix,unpackedMatrix-method}
\alias{coerce,vector,unpackedMatrix-method}
\alias{cov2cor,unpackedMatrix-method}
%
\description{
Class \code{"unpackedMatrix"} is the \emph{virtual} class of dense
matrices in "unpacked" format, storing all \code{m*n} elements of
an \code{m}-by-\code{n} matrix. It is used to define common methods
for efficient subsetting, transposing, etc. of its \emph{proper}
subclasses: currently \code{"[dln]geMatrix"} (unpacked general),
\code{"[dln]syMatrix"} (unpacked symmetric), \code{"[dln]trMatrix"}
(unpacked triangular), and subclasses of these, such as
\code{"\linkS4class{dpoMatrix}"}.
}
\section{Slots}{
\describe{
\item{\code{Dim}, \code{Dimnames}:}{as all \code{\linkS4class{Matrix}} objects.}
}
}
\section{Extends}{
Class \code{"\linkS4class{denseMatrix}"}, directly.
Class \code{"\linkS4class{Matrix}"}, by class \code{"denseMatrix"},
distance 2.
}
\section{Methods}{
\describe{
\item{pack}{\code{signature(x = "unpackedMatrix")}: ... }
\item{unpack}{\code{signature(x = "unpackedMatrix")}: ... }
\item{isSymmetric}{\code{signature(object = "unpackedMatrix")}: ... }
\item{isTriangular}{\code{signature(object = "unpackedMatrix")}: ... }
\item{isDiagonal}{\code{signature(object = "unpackedMatrix")}: ... }
\item{t}{\code{signature(x = "unpackedMatrix")}: ... }
\item{diag}{\code{signature(x = "unpackedMatrix")}: ... }
\item{diag<-}{\code{signature(x = "unpackedMatrix")}: ... }
}
}
%% \references{
%% }
\author{Mikael Jagan}
%% \note{
%% }
\seealso{
\code{\link{pack}} and \code{\link{unpack}}; its virtual "complement"
\code{"\linkS4class{packedMatrix}"}; its proper subclasses
\code{"\linkS4class{dsyMatrix}"}, \code{"\linkS4class{ltrMatrix}"}, etc.
}
\examples{
showClass("unpackedMatrix")
showMethods(classes = "unpackedMatrix")
}
Matrix/man/indMatrix-class.Rd 0000644 0001751 0000144 00000017353 14545303537 015662 0 ustar hornik users \name{indMatrix-class}
\title{Index Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{indMatrix-class}
%
\alias{!,indMatrix-method}
\alias{-,indMatrix,missing-method}
\alias{Math,indMatrix-method}
\alias{Summary,indMatrix-method}
\alias{coerce,indMatrix,pMatrix-method}
\alias{coerce,list,indMatrix-method}
\alias{coerce,matrix,indMatrix-method}
\alias{coerce,numeric,indMatrix-method}
\alias{determinant,indMatrix,logical-method}
\alias{diag,indMatrix-method}
\alias{diag<-,indMatrix-method}
\alias{log,indMatrix-method}
\alias{t,indMatrix-method}
\alias{which,indMatrix-method}
%
\description{
The \code{indMatrix} class is the class of row and column
\emph{index} matrices, stored as 1-based integer index vectors.
A row (column) index matrix is a matrix whose rows (columns)
are standard unit vectors. Such matrices are useful
when mapping observations to discrete sets of covariate values.
Multiplying a matrix on the left by a row index matrix is
equivalent to indexing its rows, i.e., sampling the rows
\dQuote{with replacement}. Analogously, multiplying a matrix
on the right by a column index matrix is equivalent to
indexing its columns. Indeed, such products are implemented in
\pkg{Matrix} as indexing operations; see \sQuote{Details} below.
A matrix whose rows \emph{and} columns are standard unit vectors
is called a \emph{permutation} matrix. This special case is
designated by the \code{\linkS4class{pMatrix}} class, a direct
subclass of \code{indMatrix}.
}
\section{Objects from the Class}{
Objects can be created explicitly with calls of the form
\code{new("indMatrix", ...)}, but they are more commonly created
by coercing 1-based integer index vectors, with calls of the
form \code{as(., "indMatrix")}; see \sQuote{Methods} below.
}
\section{Slots}{
\describe{
\item{\code{margin}}{an integer, either 1 or 2, specifying
whether the matrix is a row (1) or column (2) index.}
\item{\code{perm}}{a 1-based integer index vector, i.e.,
a vector of length \code{Dim[margin]} with elements
taken from \code{1:Dim[1+margin\%\%2]}.}
\item{\code{Dim},\code{Dimnames}}{inherited from virtual
superclass \code{\linkS4class{Matrix}}.}
}
}
\section{Extends}{
Classes \code{"\linkS4class{sparseMatrix}"} and
\code{"\linkS4class{generalMatrix}"}, directly.
}
\section{Methods}{
\describe{
\item{\code{\%*\%}}{\code{signature(x = "indMatrix", y = "Matrix")}
and others listed by \code{showMethods("\%*\%", classes = "indMatrix")}:
matrix products implemented where appropriate as indexing operations.}
\item{\code{coerce}}{\code{signature(from = "numeric", to = "indMatrix")}:
supporting typical \code{indMatrix} construction from
a vector of positive integers. Row indexing is assumed.}
\item{\code{coerce}}{\code{signature(from = "list", to = "indMatrix")}:
supporting \code{indMatrix} construction for row \emph{and}
column indexing, including index vectors of length 0 and
index vectors whose maximum is less than the number of rows
or columns being indexed.}
\item{\code{coerce}}{\code{signature(from = "indMatrix", to = "matrix")}:
coercion to a traditional \code{\link{matrix}} of \link{logical} type,
with \code{FALSE} and \code{TRUE} in place of 0 and 1.}
\item{\code{t}}{\code{signature(x = "indMatrix")}:
the transpose, which is an \code{indMatrix} with identical
\code{perm} but opposite \code{margin}.}
\item{\code{rowSums},\code{rowMeans},\code{colSums},\code{colMeans}}{\code{signature(x = "indMatrix")}:
row and column sums and means.}
\item{\code{rbind2},\code{cbind2}}{\code{signature(x = "indMatrix", y = "indMatrix")}:
row-wise catenation of two row index matrices with equal numbers
of columns and column-wise catenation of two column index matrices
with equal numbers of rows.}
\item{kronecker}{\code{signature(X = "indMatrix", Y = "indMatrix")}:
Kronecker product of two row index matrices or two column index
matrices, giving the row or column index matrix corresponding to
their \dQuote{interaction}.}
}
}
\author{Fabian Scheipl at \file{uni-muenchen.de}, building on the existing class
\code{\linkS4class{pMatrix}} after a nice hike's conversation with
Martin Maechler. Methods for \code{\link{crossprod}(x, y)} and
\code{\link{kronecker}(x, y)} with both arguments inheriting from
\code{indMatrix} were made considerably faster thanks to a suggestion
by Boris Vaillant. Diverse tweaks by Martin Maechler and
Mikael Jagan, notably the latter's implementation of \code{margin},
prior to which the \code{indMatrix} class was designated only for
row index matrices.
}
\details{
The transpose of an index matrix is an index matrix with identical
\code{perm} but opposite \code{margin}. Hence the transpose of a
row index matrix is a column index matrix, and vice versa.
The cross product of a row index matrix \code{R} and itself is a
diagonal matrix whose diagonal entries are the the number of entries
in each column of \code{R}.
Given a row index matrix \code{R} with \code{perm} slot \code{p},
a column index matrix \code{C} with \code{perm} slot \code{q},
and a matrix \code{M} with conformable dimensions, we have
\tabular{lclcl}{
\eqn{R M} \tab = \tab \code{R \%*\% M} \tab = \tab \code{M[p, ]}\cr
\eqn{M C} \tab = \tab \code{M \%*\% C} \tab = \tab \code{M[, q]}\cr
\eqn{C'M} \tab = \tab \code{crossprod(C, M)} \tab = \tab \code{M[q, ]}\cr
\eqn{MR'} \tab = \tab \code{tcrossprod(M, R)} \tab = \tab \code{M[, p]}\cr
\eqn{R'R} \tab = \tab \code{crossprod(R)} \tab = \tab \code{Diagonal(x=tabulate(p, ncol(R)))}\cr
\eqn{CC'} \tab = \tab \code{tcrossprod(C)} \tab = \tab \code{Diagonal(x=tabulate(q, nrow(C)))}
}
Operations on index matrices that result in index matrices will
accordingly return an \code{indMatrix}. These include products
of two column index matrices and (equivalently) column-indexing
of a column index matrix (when dimensions are not dropped).
Most other operations on \code{indMatrix} treat them as sparse
nonzero pattern matrices (i.e., inheriting from virtual class
\code{\linkS4class{nsparseMatrix}}). Hence vector-valued subsets
of \code{indMatrix}, such as those given by \code{\link{diag}},
are always of type \code{"\link{logical}"}.
}
\seealso{
Subclass \code{\linkS4class{pMatrix}} of permutation matrices,
a special case of index matrices; virtual class
\code{\linkS4class{nMatrix}} of nonzero pattern matrices,
and its subclasses.
}
\examples{
p1 <- as(c(2,3,1), "pMatrix")
(sm1 <- as(rep(c(2,3,1), e=3), "indMatrix"))
stopifnot(all(sm1 == p1[rep(1:3, each=3),]))
## row-indexing of a turns it into an :
class(p1[rep(1:3, each=3),])
set.seed(12) # so we know '10' is in sample
## random index matrix for 30 observations and 10 unique values:
(s10 <- as(sample(10, 30, replace=TRUE),"indMatrix"))
## Sample rows of a numeric matrix :
(mm <- matrix(1:10, nrow=10, ncol=3))
s10 \%*\% mm
set.seed(27)
IM1 <- as(sample(1:20, 100, replace=TRUE), "indMatrix")
IM2 <- as(sample(1:18, 100, replace=TRUE), "indMatrix")
(c12 <- crossprod(IM1,IM2))
## same as cross-tabulation of the two index vectors:
stopifnot(all(c12 - unclass(table(IM1@perm, IM2@perm)) == 0))
# 3 observations, 4 implied values, first does not occur in sample:
as(2:4, "indMatrix")
# 3 observations, 5 values, first and last do not occur in sample:
as(list(2:4, 5), "indMatrix")
as(sm1, "nMatrix")
s10[1:7, 1:4] # gives an "ngTMatrix" (most economic!)
s10[1:4, ] # preserves "indMatrix"-class
I1 <- as(c(5:1,6:4,7:3), "indMatrix")
I2 <- as(7:1, "pMatrix")
(I12 <- rbind(I1, I2))
stopifnot(is(I12, "indMatrix"),
identical(I12, rbind(I1, I2)),
colSums(I12) == c(2L,2:4,4:2))
}
Matrix/man/dgRMatrix-class.Rd 0000644 0001751 0000144 00000003547 14422605232 015613 0 ustar hornik users \name{dgRMatrix-class}
\title{Sparse Compressed, Row-oriented Numeric Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{dgRMatrix-class}
%
\alias{determinant,dgRMatrix,logical-method}
%
\description{The \code{dgRMatrix} class is a class of sparse numeric
matrices in the compressed, sparse, row-oriented format. In this
implementation the non-zero elements in the rows are sorted into
increasing column order.
\bold{Note:} The column-oriented sparse classes, e.g.,
\code{\linkS4class{dgCMatrix}}, are preferred and better supported in
the \pkg{Matrix} package.
}
\section{Objects from the Class}{
Objects can be created by calls of the form \code{new("dgRMatrix", ...)}.
}
\section{Slots}{
\describe{
\item{\code{j}:}{Object of class \code{"integer"} of length nnzero
(number of non-zero elements). These are the column numbers for
each non-zero element in the matrix.}
\item{\code{p}:}{Object of class \code{"integer"} of pointers, one
for each row, to the initial (zero-based) index of elements in
the row.}
\item{\code{x}:}{Object of class \code{"numeric"} - the non-zero
elements of the matrix.}
\item{\code{Dim}:}{Object of class \code{"integer"} - the dimensions
of the matrix.}
}
}
\section{Methods}{
\describe{
\item{diag}{\code{signature(x = "dgRMatrix")}: returns the diagonal
of \code{x}}
\item{dim}{\code{signature(x = "dgRMatrix")}: returns the dimensions
of \code{x}}
\item{image}{\code{signature(x = "dgRMatrix")}: plots an image of
\code{x} using the \code{\link[lattice]{levelplot}} function}
}
}
\seealso{
the \code{\linkS4class{RsparseMatrix}} class, the virtual class of all
sparse compressed \bold{r}ow-oriented matrices, with its methods.
The \code{\linkS4class{dgCMatrix}} class (\bold{c}olumn compressed
sparse) is really preferred.
}
Matrix/man/CHMfactor-class.Rd 0000644 0001751 0000144 00000033355 14575234535 015535 0 ustar hornik users \name{CHMfactor-class}
\title{Sparse Cholesky Factorizations}
%
\docType{class}
\keyword{algebra}
\keyword{array}
\keyword{classes}
\keyword{programming}
\keyword{utilities}
%
\alias{CHMfactor-class}
\alias{CHMsimpl-class}
\alias{CHMsuper-class}
\alias{dCHMsimpl-class}
\alias{dCHMsuper-class}
\alias{nCHMsimpl-class}
\alias{nCHMsuper-class}
%
\alias{coerce,CHMsimpl,dtCMatrix-method}
\alias{coerce,CHMsuper,dgCMatrix-method}
\alias{determinant,CHMfactor,logical-method}
\alias{diag,CHMfactor-method}
\alias{update,CHMfactor-method}
%
\alias{isLDL}
%
\description{
\code{CHMfactor} is the virtual class of sparse Cholesky
factorizations of \eqn{n \times n}{n-by-n} real, symmetric
matrices \eqn{A}, having the general form
\deqn{P_1 A P_1' = L_1 D L_1' \overset{D_{jj} \ge 0}{=} L L'}{P1 * A * P1' = L1 * D * L1' [ = L * L' ]}
or (equivalently)
\deqn{A = P_1' L_1 D L_1' P_1 \overset{D_{jj} \ge 0}{=} P_1' L L' P_1}{A = P1' L1 * D * L1' * P1 [ = P1' * L * L' * P1 ]}
where
\eqn{P_1}{P1} is a permutation matrix,
\eqn{L_1}{L1} is a unit lower triangular matrix,
\eqn{D} is a diagonal matrix, and
\eqn{L = L_1 \sqrt{D}}{L = L1 * sqrt(D)}.
The second equalities hold only for positive semidefinite \eqn{A},
for which the diagonal entries of \eqn{D} are non-negative
and \eqn{\sqrt{D}}{sqrt(D)} is well-defined.
The implementation of class \code{CHMfactor} is based on
CHOLMOD's C-level \code{cholmod_factor_struct}. Virtual
subclasses \code{CHMsimpl} and \code{CHMsuper} separate
the simplicial and supernodal variants. These have nonvirtual
subclasses \code{[dn]CHMsimpl} and \code{[dn]CHMsuper},
where prefix \samp{d} and prefix \samp{n} are reserved
for numeric and symbolic factorizations, respectively.
}
\usage{
isLDL(x)
}
\arguments{
\item{x}{an object inheriting from virtual class \code{CHMfactor},
almost always the result of a call to generic function
\code{\link{Cholesky}}.}
}
\value{
\code{isLDL(x)} returns \code{TRUE} or \code{FALSE}:
\code{TRUE} if \code{x} stores the lower triangular entries
of \eqn{L_1-I+D}{L1-I+D},
\code{FALSE} if \code{x} stores the lower triangular entries
of \eqn{L}.
}
\section{Slots}{
Of \code{CHMfactor}:
\describe{
\item{\code{Dim}, \code{Dimnames}}{inherited from virtual class
\code{\linkS4class{MatrixFactorization}}.}
\item{\code{colcount}}{an integer vector of length \code{Dim[1]}
giving an \emph{estimate} of the number of nonzero entries in
each column of the lower triangular Cholesky factor.
If symbolic analysis was performed prior to factorization,
then the estimate is exact.}
\item{\code{perm}}{a 0-based integer vector of length \code{Dim[1]}
specifying the permutation applied to the rows and columns
of the factorized matrix. \code{perm} of length 0 is valid and
equivalent to the identity permutation, implying no pivoting.}
\item{\code{type}}{an integer vector of length 6 specifying
details of the factorization. The elements correspond to
members \code{ordering}, \code{is_ll}, \code{is_super},
\code{is_monotonic}, \code{maxcsize}, and \code{maxesize}
of the original \code{cholmod_factor_struct}.
Simplicial and supernodal factorizations are distinguished
by \code{is_super}. Simplicial factorizations do not use
\code{maxcsize} or \code{maxesize}. Supernodal factorizations
do not use \code{is_ll} or \code{is_monotonic}.}
}
Of \code{CHMsimpl} (all unused by \code{nCHMsimpl}): % FIXME
\describe{
\item{\code{nz}}{an integer vector of length \code{Dim[1]}
giving the number of nonzero entries in each column of the
lower triangular Cholesky factor. There is at least one
nonzero entry in each column, because the diagonal elements
of the factor are stored explicitly.}
\item{\code{p}}{an integer vector of length \code{Dim[1]+1}.
Row indices of nonzero entries in column \code{j} of the
lower triangular Cholesky factor are obtained as
\code{i[p[j]+seq_len(nz[j])]+1}.}
\item{\code{i}}{an integer vector of length greater than or equal
to \code{sum(nz)} containing the row indices of nonzero entries
in the lower triangular Cholesky factor. These are grouped by
column and sorted within columns, but the columns themselves
need not be ordered monotonically. Columns may be overallocated,
i.e., the number of elements of \code{i} reserved for column
\code{j} may exceed \code{nz[j]}.}
\item{\code{prv}, \code{nxt}}{integer vectors of length
\code{Dim[1]+2} indicating the order in which the columns of
the lower triangular Cholesky factor are stored in \code{i}
and \code{x}.
Starting from \code{j <- Dim[1]+2},
the recursion \code{j <- nxt[j+1]+1} traverses the columns
in forward order and terminates when \code{nxt[j+1] = -1}.
Starting from \code{j <- Dim[1]+1},
the recursion \code{j <- prv[j+1]+1} traverses the columns
in backward order and terminates when \code{prv[j+1] = -1}.}
}
Of \code{dCHMsimpl}:
\describe{
\item{\code{x}}{a numeric vector parallel to \code{i} containing
the corresponding nonzero entries of the lower triangular
Cholesky factor \eqn{L} \emph{or} (if and only if \code{type[2]}
is 0) of the lower triangular matrix \eqn{L_1-I+D}{L1-I+D}.}
}
Of \code{CHMsuper}:
\describe{
\item{\code{super}, \code{pi}, \code{px}}{integer vectors of
length \code{nsuper+1}, where \code{nsuper} is the number of
supernodes. \code{super[j]+1} is the index of the leftmost
column of supernode \code{j}. The row indices of supernode
\code{j} are obtained as \code{s[pi[j]+seq_len(pi[j+1]-pi[j])]+1}.
The numeric entries of supernode \code{j} are obtained as
\code{x[px[j]+seq_len(px[j+1]-px[j])]+1} (if slot \code{x}
is available).}
\item{\code{s}}{an integer vector of length greater than or equal
to \code{Dim[1]} containing the row indices of the supernodes.
\code{s} may contain duplicates, but not within a supernode,
where the row indices must be increasing.}
}
Of \code{dCHMsuper}:
\describe{
\item{\code{x}}{a numeric vector of length less than or equal to
\code{prod(Dim)} containing the numeric entries of the supernodes.}
}
}
\section{Extends}{
Class \code{\linkS4class{MatrixFactorization}}, directly.
}
\section{Instantiation}{
Objects can be generated directly by calls of the form
\code{new("dCHMsimpl", ...)}, etc., but \code{dCHMsimpl} and
\code{dCHMsuper} are more typically obtained as the value of
\code{\link{Cholesky}(x, ...)} for \code{x} inheriting from
\code{\linkS4class{sparseMatrix}}
(often \code{\linkS4class{dsCMatrix}}).
There is currently no API outside of calls to \code{\link{new}}
for generating \code{nCHMsimpl} and \code{nCHMsuper}. These
classes are vestigial and may be formally deprecated in a future
version of \pkg{Matrix}.
}
\section{Methods}{
\describe{
\item{\code{coerce}}{\code{signature(from = "CHMsimpl", to = "dtCMatrix")}:
returns a \code{\linkS4class{dtCMatrix}} representing
the lower triangular Cholesky factor \eqn{L} \emph{or}
the lower triangular matrix \eqn{L_1-I+D}{L1-I+D},
the latter if and only if \code{from@type[2]} is 0.}
\item{\code{coerce}}{\code{signature(from = "CHMsuper", to = "dgCMatrix")}:
returns a \code{\linkS4class{dgCMatrix}} representing
the lower triangular Cholesky factor \eqn{L}. Note that,
for supernodes spanning two or more columns, the supernodal
algorithm by design stores non-structural zeros above
the main diagonal, hence \code{\linkS4class{dgCMatrix}} is
indeed more appropriate than \code{\linkS4class{dtCMatrix}}
as a coercion target.}
\item{\code{determinant}}{\code{signature(from = "CHMfactor", logarithm = "logical")}:
behaves according to an optional argument \code{sqrt}.
If \code{sqrt = FALSE}, then this method computes the determinant
of the factorized matrix \eqn{A} or its logarithm.
If \code{sqrt = TRUE}, then this method computes the determinant
of the factor \eqn{L = L_1 sqrt(D)}{L = L1 * sqrt(D)} or
its logarithm, giving \code{NaN} for the modulus when \eqn{D}
has negative diagonal elements. For backwards compatibility,
the default value of \code{sqrt} is \code{TRUE}, but that can
be expected change in a future version of \pkg{Matrix}, hence
defensive code will always set \code{sqrt} (to \code{TRUE},
if the code must remain backwards compatible with \pkg{Matrix}
\code{< 1.6-0}). Calls to this method not setting \code{sqrt}
may warn about the pending change. The warnings can be disabled
with \code{\link{options}(Matrix.warnSqrtDefault = 0)}.}
\item{\code{diag}}{\code{signature(x = "CHMfactor")}:
returns a numeric vector of length \eqn{n} containing the diagonal
elements of \eqn{D}, which (\emph{if} they are all non-negative)
are the squared diagonal elements of \eqn{L}.}
\item{\code{expand}}{\code{signature(x = "CHMfactor")}:
see \code{\link{expand-methods}}.}
\item{\code{expand1}}{\code{signature(x = "CHMsimpl")}:
see \code{\link{expand1-methods}}.}
\item{\code{expand1}}{\code{signature(x = "CHMsuper")}:
see \code{\link{expand1-methods}}.}
\item{\code{expand2}}{\code{signature(x = "CHMsimpl")}:
see \code{\link{expand2-methods}}.}
\item{\code{expand2}}{\code{signature(x = "CHMsuper")}:
see \code{\link{expand2-methods}}.}
\item{\code{image}}{\code{signature(x = "CHMfactor")}:
see \code{\link{image-methods}}.}
\item{\code{nnzero}}{\code{signature(x = "CHMfactor")}:
see \code{\link{nnzero-methods}}.}
\item{\code{solve}}{\code{signature(a = "CHMfactor", b = .)}:
see \code{\link{solve-methods}}.}
\item{\code{update}}{\code{signature(object = "CHMfactor")}:
returns a copy of \code{object} with the same nonzero pattern
but with numeric entries updated according to additional
arguments \code{parent} and \code{mult}, where \code{parent}
is (coercible to) a \code{\linkS4class{dsCMatrix}} or a
\code{\linkS4class{dgCMatrix}} and \code{mult} is a numeric
vector of positive length.
\cr
The numeric entries are updated with those of the Cholesky
factor of \code{F(parent) + mult[1] * I}, i.e.,
\code{F(parent)} plus \code{mult[1]} times the identity matrix,
where \code{F = \link{identity}} for symmetric \code{parent}
and \code{F = \link{tcrossprod}} for other \code{parent}.
The nonzero pattern of \code{F(parent)} must match
that of \code{S} if \code{object = Cholesky(S, ...)}.}
\item{\code{updown}}{\code{signature(update = ., C = ., object = "CHMfactor")}:
see \code{\link{updown-methods}}.}
}
}
\seealso{
Class \code{\linkS4class{dsCMatrix}}.
Generic functions \code{\link{Cholesky}}, \code{\link{updown}},
\code{\link{expand1}} and \code{\link{expand2}}.
}
\references{
The CHOLMOD source code; see
\url{https://github.com/DrTimothyAldenDavis/SuiteSparse},
notably the header file \file{CHOLMOD/Include/cholmod.h}
defining \code{cholmod_factor_struct}.
Chen, Y., Davis, T. A., Hager, W. W., & Rajamanickam, S. (2008).
Algorithm 887: CHOLMOD, supernodal sparse Cholesky factorization
and update/downdate.
\emph{ACM Transactions on Mathematical Software},
\emph{35}(3), Article 22, 1-14.
\doi{10.1145/1391989.1391995}
Amestoy, P. R., Davis, T. A., & Duff, I. S. (2004).
Algorithm 837: AMD, an approximate minimum degree ordering algorithm.
\emph{ACM Transactions on Mathematical Software},
\emph{17}(4), 886-905.
\doi{10.1145/1024074.1024081}
Golub, G. H., & Van Loan, C. F. (2013).
\emph{Matrix computations} (4th ed.).
Johns Hopkins University Press.
\doi{10.56021/9781421407944}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
library(utils, pos = "package:base", verbose = FALSE)
}
showClass("dCHMsimpl")
showClass("dCHMsuper")
set.seed(2)
m <- 1000L
n <- 200L
M <- rsparsematrix(m, n, 0.01)
A <- crossprod(M)
## With dimnames, to see that they are propagated :
dimnames(A) <- dn <- rep.int(list(paste0("x", seq_len(n))), 2L)
(ch.A <- Cholesky(A)) # pivoted, by default
str(e.ch.A <- expand2(ch.A, LDL = TRUE), max.level = 2L)
str(E.ch.A <- expand2(ch.A, LDL = FALSE), max.level = 2L)
ae1 <- function(a, b, ...) all.equal(as(a, "matrix"), as(b, "matrix"), ...)
ae2 <- function(a, b, ...) ae1(unname(a), unname(b), ...)
## A ~ P1' L1 D L1' P1 ~ P1' L L' P1 in floating point
stopifnot(exprs = {
identical(names(e.ch.A), c("P1.", "L1", "D", "L1.", "P1"))
identical(names(E.ch.A), c("P1.", "L" , "L." , "P1"))
identical(e.ch.A[["P1"]],
new("pMatrix", Dim = c(n, n), Dimnames = c(list(NULL), dn[2L]),
margin = 2L, perm = invertPerm(ch.A@perm, 0L, 1L)))
identical(e.ch.A[["P1."]], t(e.ch.A[["P1"]]))
identical(e.ch.A[["L1."]], t(e.ch.A[["L1"]]))
identical(E.ch.A[["L." ]], t(E.ch.A[["L" ]]))
identical(e.ch.A[["D"]], Diagonal(x = diag(ch.A)))
all.equal(E.ch.A[["L"]], with(e.ch.A, L1 \%*\% sqrt(D)))
ae1(A, with(e.ch.A, P1. \%*\% L1 \%*\% D \%*\% L1. \%*\% P1))
ae1(A, with(E.ch.A, P1. \%*\% L \%*\% L. \%*\% P1))
ae2(A[ch.A@perm + 1L, ch.A@perm + 1L], with(e.ch.A, L1 \%*\% D \%*\% L1.))
ae2(A[ch.A@perm + 1L, ch.A@perm + 1L], with(E.ch.A, L \%*\% L. ))
})
## Factorization handled as factorized matrix
## (in some cases only optionally, depending on arguments)
b <- rnorm(n)
stopifnot(identical(det(A), det(ch.A, sqrt = FALSE)),
identical(solve(A, b), solve(ch.A, b, system = "A")))
u1 <- update(ch.A, A , mult = sqrt(2))
u2 <- update(ch.A, t(M), mult = sqrt(2)) # updating with crossprod(M), not M
stopifnot(all.equal(u1, u2, tolerance = 1e-14))
}
Matrix/man/sparse.model.matrix.Rd 0000644 0001751 0000144 00000014533 14446607050 016511 0 ustar hornik users \name{sparse.model.matrix}
\title{Construct Sparse Design / Model Matrices}
%
\keyword{array}
\keyword{models}
\keyword{utilities}
%
\alias{sparse.model.matrix}
\alias{fac2sparse}
\alias{fac2Sparse}
%
\description{Construct a sparse model or \dQuote{design} matrix,
from a formula and data frame (\code{sparse.model.matrix}) or a single
factor (\code{fac2sparse}).
The \code{fac2[Ss]parse()} functions are utilities, also used
internally in the principal user level function
\code{sparse.model.matrix()}.
}
\usage{
sparse.model.matrix(object, data = environment(object),
contrasts.arg = NULL, xlev = NULL, transpose = FALSE,
drop.unused.levels = FALSE, row.names = TRUE,
sep = "", verbose = FALSE, \dots)
fac2sparse(from, to = c("d", "l", "n"),
drop.unused.levels = TRUE, repr = c("C", "R", "T"), giveCsparse)
fac2Sparse(from, to = c("d", "l", "n"),
drop.unused.levels = TRUE, repr = c("C", "R", "T"), giveCsparse,
factorPatt12, contrasts.arg = NULL)
}
\arguments{
\item{object}{an object of an appropriate class. For the default
method, a model formula or terms object.}
\item{data}{a data frame created with \code{\link{model.frame}}. If
another sort of object, \code{model.frame} is called first.}
\item{contrasts.arg}{\describe{
\item{for \code{sparse.model.matrix()}:}{A list, whose entries are
contrasts suitable for input to the \code{\link{contrasts}}
replacement function and whose names are the names of columns
of \code{data} containing \code{\link{factor}}s.}
\item{for \code{fac2Sparse()}:}{character string or \code{NULL} or
(coercable to) \code{"\linkS4class{sparseMatrix}"}, specifying the
contrasts to be applied to the factor levels.}
}}
\item{xlev}{to be used as argument of \code{\link{model.frame}} if
\code{data} has no \code{"terms"} attribute.}
\item{transpose}{logical indicating if the \emph{transpose} should be
returned; if the transposed is used anyway, setting \code{transpose = TRUE}
is more efficient.}
\item{drop.unused.levels}{should factors have unused levels dropped?
The default for \code{sparse.model.matrix} has been changed to
\code{FALSE}, 2010-07, for compatibility with \R's standard (dense)
\code{\link{model.matrix}()}.}
\item{row.names}{logical indicating if row names should be used.}
\item{sep}{\code{\link{character}} string passed to \code{\link{paste}()}
when constructing column names from the variable name and its levels.}
\item{verbose}{logical or integer indicating if (and how much)
progress output should be printed.}
\item{\dots}{further arguments passed to or from other methods.}
\item{from}{(for \code{fac2sparse()}:) a \code{\link{factor}}.}
\item{to}{a character indicating the \dQuote{kind} of sparse matrix to
be returned. The default, \code{"d"} is for \code{\link{double}}.}
\item{giveCsparse}{\bold{deprecated}, replaced with \code{repr}; logical indicating if
the result must be a \code{\linkS4class{CsparseMatrix}}.}
\item{repr}{\code{\link{character}} string, one of \code{"C"},
\code{"T"}, or \code{"R"}, specifying the sparse \emph{repr}esentation to
be used for the result, i.e., one from the super classes
\code{\linkS4class{CsparseMatrix}}, \code{\linkS4class{TsparseMatrix}}, or
\code{\linkS4class{RsparseMatrix}}.}
\item{factorPatt12}{logical vector, say \code{fp}, of length two;
when \code{fp[1]} is true, return \dQuote{contrasted} \code{t(X)};
when \code{fp[2]} is true, the original (\dQuote{dummy})
\code{t(X)}, i.e, the result of \code{\link{fac2sparse}()}.}
}
\value{
a sparse matrix, extending \code{\linkS4class{CsparseMatrix}} (for
\code{fac2sparse()} if \code{repr = "C"} as per default; a
\code{\linkS4class{TsparseMatrix}} or \code{\linkS4class{RsparseMatrix}}, otherwise).
For \code{fac2Sparse()}, a \code{\link{list}} of length two, both
components with the corresponding transposed model matrix, where the
corresponding \code{factorPatt12} is true.
\code{fac2sparse()}, the basic workhorse of
\code{sparse.model.matrix()}, returns the \emph{transpose}
(\code{\link{t}}) of the model matrix.
}
\note{
\code{model.Matrix(sparse = TRUE)} from package \CRANpkg{MatrixModels}
may be nowadays be preferable to \code{sparse.model.matrix},
as \code{model.Matrix} returns an object of class \code{modelMatrix}
with additional slots \code{assign} and \code{contrasts} relating to
the model variables.
}
\author{Doug Bates and Martin Maechler, with initial suggestions from Tim
Hesterberg.
}
\seealso{
\code{\link{model.matrix}} in package \pkg{stats}, part of base \R{}.
\code{model.Matrix} in package \CRANpkg{MatrixModels}; see \sQuote{Note}.
\code{as(f, "sparseMatrix")} (see \code{coerce(from = "factor", ..)}
in the class doc \linkS4class{sparseMatrix}) produces the
\emph{transposed} sparse model matrix for a single factor \code{f}
(and \emph{no} contrasts).
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
}
dd <- data.frame(a = gl(3,4), b = gl(4,1,12))# balanced 2-way
options("contrasts") # the default: "contr.treatment"
sparse.model.matrix(~ a + b, dd)
sparse.model.matrix(~ -1+ a + b, dd)# no intercept --> even sparser
sparse.model.matrix(~ a + b, dd, contrasts = list(a="contr.sum"))
sparse.model.matrix(~ a + b, dd, contrasts = list(b="contr.SAS"))
## Sparse method is equivalent to the traditional one :
stopifnot(all(sparse.model.matrix(~ a + b, dd) ==
Matrix(model.matrix(~ a + b, dd), sparse=TRUE)),
all(sparse.model.matrix(~0 + a + b, dd) ==
Matrix(model.matrix(~0 + a + b, dd), sparse=TRUE)))
%% many more and tougher examples ---> ../tests/spModel.matrix.R
(ff <- gl(3,4,, c("X","Y", "Z")))
fac2sparse(ff) # 3 x 12 sparse Matrix of class "dgCMatrix"
##
## X 1 1 1 1 . . . . . . . .
## Y . . . . 1 1 1 1 . . . .
## Z . . . . . . . . 1 1 1 1
## can also be computed via sparse.model.matrix():
f30 <- gl(3,0 )
f12 <- gl(3,0, 12)
stopifnot(
all.equal(t( fac2sparse(ff) ),
sparse.model.matrix(~ 0+ff),
tolerance = 0, check.attributes=FALSE),
is(M <- fac2sparse(f30, drop= TRUE),"CsparseMatrix"), dim(M) == c(0, 0),
is(M <- fac2sparse(f30, drop=FALSE),"CsparseMatrix"), dim(M) == c(3, 0),
is(M <- fac2sparse(f12, drop= TRUE),"CsparseMatrix"), dim(M) == c(0,12),
is(M <- fac2sparse(f12, drop=FALSE),"CsparseMatrix"), dim(M) == c(3,12)
)
}
Matrix/man/dgTMatrix-class.Rd 0000644 0001751 0000144 00000006510 14473555676 015634 0 ustar hornik users \name{dgTMatrix-class}
\title{Sparse matrices in triplet form}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{dgTMatrix-class}
%
\alias{+,dgTMatrix,dgTMatrix-method}
\alias{determinant,dgTMatrix,logical-method}
%
\description{The \code{"dgTMatrix"} class is the class of sparse
matrices stored as (possibly redundant) triplets. The internal
representation is not at all unique, contrary to the one for class
\code{\linkS4class{dgCMatrix}}.
}
\section{Objects from the Class}{
Objects can be created by calls of the form
\code{new("dgTMatrix", ...)}, but more typically via
\code{\link{spMatrix}()} or \code{\link{sparseMatrix}(*, repr = "T")}.
}
\section{Slots}{
\describe{
\item{\code{i}:}{\code{\link{integer}} row indices of non-zero
entries \emph{in 0-base}, i.e., must be in \code{0:(nrow(.)-1)}.}
\item{\code{j}:}{\code{\link{integer}} column indices of non-zero
entries. Must be the same length as slot \code{i} and
\emph{0-based} as well, i.e., in \code{0:(ncol(.)-1)}.}
\item{\code{x}:}{\code{\link{numeric}} vector - the (non-zero)
entry at position \code{(i,j)}. Must be the same length as slot
\code{i}. If an index pair occurs more than once, the corresponding
values of slot \code{x} are added to form the element of the matrix.}
\item{\code{Dim}:}{Object of class \code{"integer"} of length 2 -
the dimensions of the matrix.}
}
}
\section{Methods}{
\describe{
\item{+}{\code{signature(e1 = "dgTMatrix", e2 = "dgTMatrix")}}
\item{image}{\code{signature(x = "dgTMatrix")}: plots an image of
\code{x} using the \code{\link[lattice]{levelplot}} function}
\item{t}{\code{signature(x = "dgTMatrix")}: returns the transpose of
\code{x}}
}
}
%\references{}
%\author{}
\note{Triplet matrices are a convenient form in which to construct sparse
matrices after which they can be coerced to
\code{\linkS4class{dgCMatrix}} objects.
Note that both \code{new(.)} and \code{\link{spMatrix}} constructors
for \code{"dgTMatrix"} (and other \code{"\linkS4class{TsparseMatrix}"}
classes) implicitly add \eqn{x_k}'s that belong to identical
\eqn{(i_k, j_k)} pairs.
However this means that a matrix typically can be stored in more than
one possible \code{"\linkS4class{TsparseMatrix}"} representations.
Use \code{\link{asUniqueT}()} in order to ensure uniqueness of the
internal representation of such a matrix.
}
\seealso{
Class \code{\linkS4class{dgCMatrix}} or the superclasses
\code{\linkS4class{dsparseMatrix}} and
\code{\linkS4class{TsparseMatrix}}; \code{\link{asUniqueT}}.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
m <- Matrix(0+1:28, nrow = 4)
m[-3,c(2,4:5,7)] <- m[ 3, 1:4] <- m[1:3, 6] <- 0
(mT <- as(m, "TsparseMatrix"))
str(mT)
mT[1,]
mT[4, drop = FALSE]
stopifnot(identical(mT[lower.tri(mT)],
m [lower.tri(m) ]))
mT[lower.tri(mT,diag=TRUE)] <- 0
mT
## Triplet representation with repeated (i,j) entries
## *adds* the corresponding x's:
T2 <- new("dgTMatrix",
i = as.integer(c(1,1,0,3,3)),
j = as.integer(c(2,2,4,0,0)), x=10*1:5, Dim=4:5)
str(T2) # contains (i,j,x) slots exactly as above, but
T2 ## has only three non-zero entries, as for repeated (i,j)'s,
## the corresponding x's are "implicitly" added
stopifnot(nnzero(T2) == 3)
}
Matrix/man/diagonalMatrix-class.Rd 0000644 0001751 0000144 00000011040 14500445405 016641 0 ustar hornik users \name{diagonalMatrix-class}
\title{Class "diagonalMatrix" of Diagonal Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{diagonalMatrix-class}
%
\alias{-,diagonalMatrix,missing-method}
\alias{Math,diagonalMatrix-method}
\alias{Ops,diagonalMatrix,triangularMatrix-method}
\alias{Summary,diagonalMatrix-method}
\alias{coerce,diagonalMatrix,symmetricMatrix-method}
\alias{coerce,diagonalMatrix,triangularMatrix-method}
\alias{coerce,matrix,diagonalMatrix-method}
\alias{determinant,diagonalMatrix,logical-method}
\alias{diag,diagonalMatrix-method}
\alias{diag<-,diagonalMatrix-method}
\alias{log,diagonalMatrix-method}
\alias{print,diagonalMatrix-method}
\alias{show,diagonalMatrix-method}
\alias{summary,diagonalMatrix-method}
\alias{t,diagonalMatrix-method}
%
\description{
Class "diagonalMatrix" is the virtual class of all diagonal matrices.
}
\section{Objects from the Class}{A virtual Class: No objects may be
created from it.}
\section{Slots}{
\describe{
\item{\code{diag}:}{\code{\link{character}} string, either \code{"U"} or
\code{"N"}, where \code{"U"} means \sQuote{unit-diagonal}.}
\item{\code{Dim}:}{matrix dimension, and}
\item{\code{Dimnames}:}{the \code{\link{dimnames}}, a
\code{\link{list}}, see the \code{\linkS4class{Matrix}} class
description. Typically \code{list(NULL,NULL)} for diagonal matrices.}
}
}
\section{Extends}{
Class \code{"\linkS4class{sparseMatrix}"}, directly.
}
\section{Methods}{
These are just a subset of the signature for which defined methods.
Currently, there are (too) many explicit methods defined in order to
ensure efficient methods for diagonal matrices.
\describe{
\item{coerce}{\code{signature(from = "matrix", to = "diagonalMatrix")}: ... }
\item{coerce}{\code{signature(from = "Matrix", to = "diagonalMatrix")}: ... }
\item{coerce}{\code{signature(from = "diagonalMatrix", to = "generalMatrix")}: ... }
\item{coerce}{\code{signature(from = "diagonalMatrix", to = "triangularMatrix")}: ... }
\item{coerce}{\code{signature(from = "diagonalMatrix", to = "nMatrix")}: ... }
\item{coerce}{\code{signature(from = "diagonalMatrix", to = "matrix")}: ... }
\item{coerce}{\code{signature(from = "diagonalMatrix", to = "sparseVector")}: ... }
\item{t}{\code{signature(x = "diagonalMatrix")}: ... }
\cr and many more methods
\item{solve}{\code{signature(a = "diagonalMatrix", b, ...)}: is
trivially implemented, of course; see also \code{\link{solve-methods}}.}
\item{which}{\code{signature(x = "nMatrix")}, semantically
equivalent to \pkg{base} function \code{\link{which}(x, arr.ind)}.}
\item{"Math"}{\code{signature(x = "diagonalMatrix")}: all these
group methods return a \code{"diagonalMatrix"}, apart from
\code{\link{cumsum}()} etc which return a \emph{vector} also for
\pkg{base} \code{\link{matrix}}.}
\item{*}{\code{signature(e1 = "ddiMatrix", e2="denseMatrix")}:
arithmetic and other operators from the \code{\link[=S4groupGeneric]{Ops}}
group have a few dozen explicit method definitions, in order to
keep the results \emph{diagonal} in many cases, including the following:}
\item{/}{\code{signature(e1 = "ddiMatrix", e2="denseMatrix")}:
the result is from class \code{\linkS4class{ddiMatrix}} which is
typically very desirable. Note that when \code{e2} contains
off-diagonal zeros or \code{\link{NA}}s, we implicitly use \eqn{0 / x = 0}, hence
differing from traditional \R arithmetic (where \eqn{0 / 0
\mapsto \mbox{NaN}}{0/0 |-> NaN}), in order to preserve sparsity.}
\item{summary}{\code{(object = "diagonalMatrix")}: Returns
an object of S3 class \code{"diagSummary"} which is the summary of
the vector \code{object@x} plus a simple heading, and an
appropriate \code{\link{print}} method.}
}
}
\seealso{
\code{\link{Diagonal}()} as constructor of these matrices, and
\code{\link{isDiagonal}}.
\code{\linkS4class{ddiMatrix}} and \code{\linkS4class{ldiMatrix}} are
\dQuote{actual} classes extending \code{"diagonalMatrix"}.
}
\examples{
I5 <- Diagonal(5)
D5 <- Diagonal(x = 10*(1:5))
## trivial (but explicitly defined) methods:
stopifnot(identical(crossprod(I5), I5),
identical(tcrossprod(I5), I5),
identical(crossprod(I5, D5), D5),
identical(tcrossprod(D5, I5), D5),
identical(solve(D5), solve(D5, I5)),
all.equal(D5, solve(solve(D5)), tolerance = 1e-12)
)
solve(D5)# efficient as is diagonal
# an unusual way to construct a band matrix:
rbind2(cbind2(I5, D5),
cbind2(D5, I5))
}
Matrix/man/dgeMatrix-class.Rd 0000644 0001751 0000144 00000006660 14500445405 015636 0 ustar hornik users \name{dgeMatrix-class}
\title{Class "dgeMatrix" of Dense Numeric (S4 Class) Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{dgeMatrix-class}
%
\alias{Arith,dgeMatrix,dgeMatrix-method}
\alias{Arith,dgeMatrix,logical-method}
\alias{Arith,dgeMatrix,numeric-method}
\alias{Arith,dgeMatrix,sparseVector-method}
\alias{Arith,logical,dgeMatrix-method}
\alias{Arith,numeric,dgeMatrix-method}
\alias{determinant,dgeMatrix,logical-method}
%
\description{A general numeric dense matrix in the S4 Matrix
representation. \code{dgeMatrix} is the \emph{\dQuote{standard}}
class for dense numeric matrices in the \pkg{Matrix} package.
}
\section{Objects from the Class}{
Objects can be created by calls of the form \code{new("dgeMatrix", ...)}
or, more commonly, by coercion from the \code{Matrix} class (see
\linkS4class{Matrix}) or by \code{\link{Matrix}(..)}.
}
\section{Slots}{
\describe{
\item{\code{x}:}{Object of class \code{"numeric"} - the numeric
values contained in the matrix, in column-major order.}
\item{\code{Dim}:}{Object of class \code{"integer"} - the dimensions
of the matrix - must be an integer vector with exactly two
non-negative values.}
\item{\code{Dimnames}:}{a list of length two - inherited from class
\code{\linkS4class{Matrix}}.}
\item{\code{factors}:}{Object of class \code{"list"} - a list
of factorizations of the matrix.}
}
}
\section{Methods}{
The are group methods (see, e.g., \code{\link{Arith}})
\describe{
\item{Arith}{\code{signature(e1 = "dgeMatrix", e2 = "dgeMatrix")}: ... }
\item{Arith}{\code{signature(e1 = "dgeMatrix", e2 = "numeric")}: ... }
\item{Arith}{\code{signature(e1 = "numeric", e2 = "dgeMatrix")}: ... }
\item{Math}{\code{signature(x = "dgeMatrix")}: ... }
\item{Math2}{\code{signature(x = "dgeMatrix", digits = "numeric")}: ...}
}
matrix products \code{\link[=crossprod-methods]{\%*\%}},
\code{\link[=crossprod-methods]{crossprod}()} and \code{tcrossprod()},
several \code{\link{solve}} methods,
and other matrix methods available:
\describe{
\item{Schur}{\code{signature(x = "dgeMatrix", vectors = "logical")}: ... }
\item{Schur}{\code{signature(x = "dgeMatrix", vectors = "missing")}: ... }
\item{chol}{\code{signature(x = "dgeMatrix")}: see \code{\link{chol}}.}
\item{colMeans}{\code{signature(x = "dgeMatrix")}: columnwise means (averages)}
\item{colSums}{\code{signature(x = "dgeMatrix")}: columnwise sums}
\item{diag}{\code{signature(x = "dgeMatrix")}: ... }
\item{dim}{\code{signature(x = "dgeMatrix")}: ... }
\item{dimnames}{\code{signature(x = "dgeMatrix")}: ... }
\item{eigen}{\code{signature(x = "dgeMatrix", only.values= "logical")}: ...}
\item{eigen}{\code{signature(x = "dgeMatrix", only.values= "missing")}: ...}
\item{norm}{\code{signature(x = "dgeMatrix", type = "character")}: ... }
\item{norm}{\code{signature(x = "dgeMatrix", type = "missing")}: ... }
\item{rcond}{\code{signature(x = "dgeMatrix", norm = "character")}
or \code{norm = "missing"}:
the reciprocal condition number, \code{\link{rcond}()}.}
\item{rowMeans}{\code{signature(x = "dgeMatrix")}: rowwise means (averages)}
\item{rowSums}{\code{signature(x = "dgeMatrix")}: rowwise sums}
\item{t}{\code{signature(x = "dgeMatrix")}: matrix transpose}
}
}
\seealso{
Classes \code{\linkS4class{Matrix}},
\code{\linkS4class{dtrMatrix}}, and \code{\linkS4class{dsyMatrix}}.
}
%\examples{}
Matrix/man/lu-methods.Rd 0000644 0001751 0000144 00000014343 14575137654 014705 0 ustar hornik users \name{lu-methods}
\title{Methods for LU Factorization}
%
\docType{methods}
\keyword{algebra}
\keyword{array}
\keyword{methods}
%
\alias{lu}
\alias{lu-methods}
%
\alias{lu,denseMatrix-method}
\alias{lu,diagonalMatrix-method}
\alias{lu,dgCMatrix-method}
\alias{lu,dgRMatrix-method}
\alias{lu,dgTMatrix-method}
\alias{lu,dgeMatrix-method}
\alias{lu,dsCMatrix-method}
\alias{lu,dsRMatrix-method}
\alias{lu,dsTMatrix-method}
\alias{lu,dspMatrix-method}
\alias{lu,dsyMatrix-method}
\alias{lu,dtCMatrix-method}
\alias{lu,dtRMatrix-method}
\alias{lu,dtTMatrix-method}
\alias{lu,dtpMatrix-method}
\alias{lu,dtrMatrix-method}
\alias{lu,matrix-method}
\alias{lu,sparseMatrix-method}
%
\description{
Computes the pivoted LU factorization of an \eqn{m \times n}{m-by-n}
real matrix \eqn{A}, which has the general form
\deqn{P_{1} A P_{2} = L U}{P1 * A * P2 = L * U}
or (equivalently)
\deqn{A = P_{1}' L U P_{2}'}{A = P1' * L * U * P2'}
where
\eqn{P_{1}}{P1} is an \eqn{m \times m}{m-by-m} permutation matrix,
\eqn{P_{2}}{P2} is an \eqn{n \times n}{n-by-n} permutation matrix,
\eqn{L} is an \eqn{m \times \min(m,n)}{m-by-min(m,n)}
unit lower trapezoidal matrix, and
\eqn{U} is a \eqn{\min(m,n) \times n}{min(m,n)-by-n}
upper trapezoidal matrix.
Methods for \code{\linkS4class{denseMatrix}} are built on
LAPACK routine \code{dgetrf}, which does not permute columns,
so that \eqn{P_{2}}{P2} is an identity matrix.
Methods for \code{\linkS4class{sparseMatrix}} are built on
CXSparse routine \code{cs_lu}, which requires \eqn{m = n},
so that \eqn{L} and \eqn{U} are triangular matrices.
}
\usage{
lu(x, \dots)
\S4method{lu}{dgeMatrix}(x, warnSing = TRUE, \dots)
\S4method{lu}{dgCMatrix}(x, errSing = TRUE, order = NA_integer_,
tol = 1, \dots)
\S4method{lu}{dsyMatrix}(x, cache = TRUE, \dots)
\S4method{lu}{dsCMatrix}(x, cache = TRUE, \dots)
\S4method{lu}{matrix}(x, \dots)
}
\arguments{
\item{x}{a \link[=is.finite]{finite} matrix or
\code{\linkS4class{Matrix}} to be factorized,
which must be square if sparse.}
\item{warnSing}{a logical indicating if a \link{warning} should
be signaled for singular \code{x}. Used only by methods for
dense matrices.}
\item{errSing}{a logical indicating if an \link[=stop]{error} should
be signaled for singular \code{x}. Used only by methods for
sparse matrices.}
\item{order}{an integer in \code{0:3} passed to CXSparse routine
\code{cs_sqr}, indicating a strategy for choosing the column
permutation \eqn{P_{2}}{P2}. 0 means no column permutation.
1, 2, and 3 indicate a fill-reducing ordering of \eqn{A + A'},
\eqn{\tilde{A}' \tilde{A}}{A~' * A~}, and \eqn{A' A}{A' * A},
where \eqn{\tilde{A}}{A~} is \eqn{A} with \dQuote{dense} rows
removed.
\code{NA} (the default) is equivalent to 2 if \code{tol == 1}
and 1 otherwise.
Do not set to 0 unless you know that the column order of \eqn{A}
is already sensible.}
\item{tol}{a number. The original pivot element is used
if its absolute value exceeds \code{tol * a},
where \code{a} is the maximum in absolute value of the
other possible pivot elements.
Set \code{tol < 1} only if you know what you are doing.}
\item{cache}{a logical indicating if the result should be
cached in \code{x@factors[["LU"]]}. Note that
caching is experimental and that only methods for classes
extending \code{\linkS4class{generalMatrix}} or
\code{\linkS4class{symmetricMatrix}} will have this argument.}
\item{\dots}{further arguments passed to or from methods.}
}
\value{
An object representing the factorization, inheriting from
virtual class \code{\linkS4class{LU}}. The specific class
is \code{\linkS4class{denseLU}} unless \code{x} inherits
from virtual class \code{\linkS4class{sparseMatrix}},
in which case it is \code{\linkS4class{sparseLU}}.
}
\details{
What happens when \code{x} is determined to be near-singular
differs by method. The method for class \code{\linkS4class{dgeMatrix}}
completes the factorization, warning if \code{warnSing = TRUE}
and in any case returning a valid \code{\linkS4class{denseLU}}
object. Users of this method can detect singular \code{x} with
a suitable warning handler; see \code{\link{tryCatch}}.
In contrast, the method for class \code{\linkS4class{dgCMatrix}}
abandons further computation, throwing an error if \code{errSing = TRUE}
and otherwise returning \code{NA}. Users of this method can
detect singular \code{x} with an error handler or by setting
\code{errSing = FALSE} and testing for a formal result with
\code{is(., "sparseLU")}.
}
\seealso{
Classes \code{\linkS4class{denseLU}} and
\code{\linkS4class{sparseLU}} and their methods.
Classes \code{\linkS4class{dgeMatrix}} and
\code{\linkS4class{dgCMatrix}}.
Generic functions \code{\link{expand1}} and \code{\link{expand2}},
for constructing matrix factors from the result.
Generic functions \code{\link{Cholesky}}, \code{\link{BunchKaufman}},
\code{\link{Schur}}, and \code{\link{qr}},
for computing other factorizations.
}
\references{
The LAPACK source code, including documentation; see
\url{https://netlib.org/lapack/double/dgetrf.f}.
Davis, T. A. (2006).
\emph{Direct methods for sparse linear systems}.
Society for Industrial and Applied Mathematics.
\doi{10.1137/1.9780898718881}
Golub, G. H., & Van Loan, C. F. (2013).
\emph{Matrix computations} (4th ed.).
Johns Hopkins University Press.
\doi{10.56021/9781421407944}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
library(utils, pos = "package:base", verbose = FALSE)
}
showMethods("lu", inherited = FALSE)
set.seed(0)
## ---- Dense ----------------------------------------------------------
(A1 <- Matrix(rnorm(9L), 3L, 3L))
(lu.A1 <- lu(A1))
(A2 <- round(10 * A1[, -3L]))
(lu.A2 <- lu(A2))
## A ~ P1' L U in floating point
str(e.lu.A2 <- expand2(lu.A2), max.level = 2L)
stopifnot(all.equal(A2, Reduce(`\%*\%`, e.lu.A2)))
## ---- Sparse ---------------------------------------------------------
A3 <- as(readMM(system.file("external/pores_1.mtx", package = "Matrix")),
"CsparseMatrix")
(lu.A3 <- lu(A3))
## A ~ P1' L U P2' in floating point
str(e.lu.A3 <- expand2(lu.A3), max.level = 2L)
stopifnot(all.equal(A3, Reduce(`\%*\%`, e.lu.A3)))
}
Matrix/man/coerce-methods-SparseM.Rd 0000644 0001751 0000144 00000005014 14575137654 017070 0 ustar hornik users \name{coerce-methods-SparseM}
\title{Sparse Matrix Coercion from and to those from package \pkg{SparseM}}
%
\docType{methods}
\keyword{methods}
%
\alias{coerce-methods-SparseM}
%
\alias{coerce,Matrix,matrix.coo-method}
\alias{coerce,Matrix,matrix.csc-method}
\alias{coerce,Matrix,matrix.csr-method}
\alias{coerce,dgCMatrix,matrix.csc-method}
\alias{coerce,dgRMatrix,matrix.csr-method}
\alias{coerce,dgTMatrix,matrix.coo-method}
%
\alias{coerce,matrix.coo,CsparseMatrix-method}
\alias{coerce,matrix.coo,Matrix-method}
\alias{coerce,matrix.coo,RsparseMatrix-method}
\alias{coerce,matrix.coo,TsparseMatrix-method}
\alias{coerce,matrix.coo,dgCMatrix-method}
\alias{coerce,matrix.coo,dgTMatrix-method}
\alias{coerce,matrix.coo,sparseMatrix-method}
%
\alias{coerce,matrix.csc,CsparseMatrix-method}
\alias{coerce,matrix.csc,Matrix-method}
\alias{coerce,matrix.csc,RsparseMatrix-method}
\alias{coerce,matrix.csc,TsparseMatrix-method}
\alias{coerce,matrix.csc,dgCMatrix-method}
\alias{coerce,matrix.csc,sparseMatrix-method}
%
\alias{coerce,matrix.csr,CsparseMatrix-method}
\alias{coerce,matrix.csr,Matrix-method}
\alias{coerce,matrix.csr,RsparseMatrix-method}
\alias{coerce,matrix.csr,TsparseMatrix-method}
\alias{coerce,matrix.csr,dgCMatrix-method}
\alias{coerce,matrix.csr,dgRMatrix-method}
\alias{coerce,matrix.csr,sparseMatrix-method}
%
\description{
Methods for coercion from and to sparse matrices from package \pkg{SparseM}
are provided here, for ease of porting functionality to the
\pkg{Matrix} package, and comparing functionality of the two
packages. All these work via the usual \code{\link{as}(., "")}
coercion, \preformatted{ as(from, Class)
}%pre
}
\section{Methods}{
\describe{
\item{from = "matrix.csr", to = "dgRMatrix"}{ ... }
\item{from = "matrix.csc", to = "dgCMatrix"}{ ... }
\item{from = "matrix.coo", to = "dgTMatrix"}{ ... }
\item{from = "dgRMatrix", to = "matrix.csr"}{ ... }
\item{from = "dgCMatrix", to = "matrix.csc"}{ ... }
\item{from = "dgTMatrix", to = "matrix.coo"}{ ... }
\item{from = "Matrix", to = "matrix.csr"}{ ... }
\item{from = "matrix.csr", to = "dgCMatrix"}{ ... }
\item{from = "matrix.coo", to = "dgCMatrix"}{ ... }
\item{from = "matrix.csr", to = "Matrix"}{ ... }
\item{from = "matrix.csc", to = "Matrix"}{ ... }
\item{from = "matrix.coo", to = "Matrix"}{ ... }
}
}
\seealso{
The documentation in CRAN package \CRANpkg{SparseM}, such as
\code{\link[SparseM]{SparseM.ontology}}, and one important class,
\code{\link[SparseM:matrix.csr-class]{matrix.csr}}.
}
Matrix/man/dpoMatrix-class.Rd 0000644 0001751 0000144 00000014257 14565737512 015700 0 ustar hornik users \name{dpoMatrix-class}
\title{Positive Semi-definite Dense (Packed | Non-packed) Numeric Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{dpoMatrix-class}
\alias{dppMatrix-class}
\alias{corMatrix-class}
\alias{copMatrix-class}
%
\alias{Arith,dpoMatrix,logical-method}
\alias{Arith,dpoMatrix,numeric-method}
\alias{Arith,logical,dpoMatrix-method}
\alias{Arith,numeric,dpoMatrix-method}
\alias{Ops,dpoMatrix,logical-method}
\alias{Ops,dpoMatrix,numeric-method}
\alias{Ops,logical,dpoMatrix-method}
\alias{Ops,numeric,dpoMatrix-method}
\alias{coerce,dpoMatrix,corMatrix-method}
\alias{coerce,dpoMatrix,dppMatrix-method}
\alias{coerce,matrix,dpoMatrix-method}
\alias{determinant,dpoMatrix,logical-method}
%
\alias{Arith,dppMatrix,logical-method}
\alias{Arith,dppMatrix,numeric-method}
\alias{Arith,logical,dppMatrix-method}
\alias{Arith,numeric,dppMatrix-method}
\alias{Ops,dppMatrix,logical-method}
\alias{Ops,dppMatrix,numeric-method}
\alias{Ops,logical,dppMatrix-method}
\alias{Ops,numeric,dppMatrix-method}
\alias{coerce,dppMatrix,copMatrix-method}
\alias{coerce,dppMatrix,dpoMatrix-method}
\alias{coerce,matrix,dppMatrix-method}
\alias{determinant,dppMatrix,logical-method}
%
\alias{coerce,corMatrix,copMatrix-method}
\alias{coerce,matrix,corMatrix-method}
%
\alias{coerce,copMatrix,corMatrix-method}
\alias{coerce,matrix,copMatrix-method}
%
\description{
\itemize{
\item The \code{"dpoMatrix"} class is the class of
positive-semidefinite symmetric matrices in nonpacked storage.
\item The \code{"dppMatrix"} class is the same except in packed
storage. Only the upper triangle or the lower triangle is
required to be available.
\item The \code{"corMatrix"} and \code{"copMatrix"} classes
represent correlation matrices. They extend \code{"dpoMatrix"}
and \code{"dppMatrix"}, respectively, with an additional slot
\code{sd} allowing restoration of the original covariance matrix.
}
}
\section{Objects from the Class}{Objects can be created by calls of the
form \code{new("dpoMatrix", ...)} or from \code{crossprod} applied to
an \code{"dgeMatrix"} object.}
\section{Slots}{
\describe{
\item{\code{uplo}:}{Object of class \code{"character"}. Must be
either "U", for upper triangular, and "L", for lower triangular.}
\item{\code{x}:}{Object of class \code{"numeric"}. The numeric
values that constitute the matrix, stored in column-major order.}
\item{\code{Dim}:}{Object of class \code{"integer"}. The dimensions
of the matrix which must be a two-element vector of non-negative
integers.}
\item{\code{Dimnames}:}{inherited from class \code{"Matrix"}}
\item{\code{factors}:}{Object of class \code{"list"}. A named
list of factorizations that have been computed for the matrix.}
\item{\code{sd}:}{(for \code{"corMatrix"} and \code{"copMatrix"})
a \code{\link{numeric}} vector of length \code{n} containing the
(original) \eqn{\sqrt{var(.)}}{sqrt(var(.))} entries which allow
reconstruction of a covariance matrix from the correlation matrix.}
}
}
\section{Extends}{
Class \code{"dsyMatrix"}, directly.\cr
Classes \code{"dgeMatrix"}, \code{"symmetricMatrix"}, and many more
by class \code{"dsyMatrix"}.
}
\section{Methods}{
\describe{
\item{chol}{\code{signature(x = "dpoMatrix")}:
Returns (and stores) the Cholesky decomposition of \code{x}, see
\code{\link{chol}}.}
\item{determinant}{\code{signature(x = "dpoMatrix")}:
Returns the \code{\link{determinant}} of \code{x}, via
\code{chol(x)}, see above.}
\item{rcond}{\code{signature(x = "dpoMatrix", norm = "character")}:
Returns (and stores) the reciprocal of the condition number of
\code{x}. The \code{norm} can be \code{"O"} for the
one-norm (the default) or \code{"I"} for the infinity-norm. For
symmetric matrices the result does not depend on the norm.}
\item{solve}{\code{signature(a = "dpoMatrix", b = "....")}, and}
\item{solve}{\code{signature(a = "dppMatrix", b = "....")} work
via the Cholesky composition, see also the Matrix \code{\link{solve-methods}}.}
\item{Arith}{\code{signature(e1 = "dpoMatrix", e2 = "numeric")} (and
quite a few other signatures): The result of (\dQuote{elementwise}
defined) arithmetic operations is typically \emph{not}
positive-definite anymore. The only exceptions, currently, are
multiplications, divisions or additions with \emph{positive}
\code{length(.) == 1} numbers (or \code{\link{logical}}s).}
}
}
%\references{}
%\author{}
\note{Currently the validity methods for these classes such as
\code{\link{getValidity}(getClass("dpoMatrix"))} for efficiency reasons
only check the diagonal entries of the matrix -- they may not be negative.
This is only necessary but not sufficient for a symmetric matrix to be
positive semi-definite.
A more reliable (but often more expensive) check for positive
semi-definiteness would look at the signs of \code{diag(\link{BunchKaufman}(.))}
(with some tolerance for very small negative values), and for (strict)
positive definiteness at something like
\code{!inherits(tryCatch(chol(.), error=identity), "error")} .
Indeed, when \emph{coercing} to these classes, a version
of \code{\link{Cholesky}()} or \code{\link{chol}()} is
typically used, e.g., see \code{selectMethod("coerce",
c(from="dsyMatrix", to="dpoMatrix"))} .
}
\seealso{
Classes \code{\linkS4class{dsyMatrix}} and \code{\linkS4class{dgeMatrix}};
further, \code{\link{Matrix}}, \code{\link{rcond}},
\code{\link[base]{chol}}, \code{\link[base]{solve}}, \code{\link{crossprod}}.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
h6 <- Hilbert(6)
rcond(h6)
str(h6)
h6 * 27720 # is ``integer''
solve(h6)
str(hp6 <- pack(h6))
### Note that as(*, "corMatrix") *scales* the matrix
(ch6 <- as(h6, "corMatrix"))
stopifnot(all.equal(as(h6 * 27720, "dsyMatrix"), round(27720 * h6),
tolerance = 1e-14),
all.equal(ch6@sd^(-2), 2*(1:6)-1,
tolerance = 1e-12))
chch <- Cholesky(ch6, perm = FALSE)
stopifnot(identical(chch, ch6@factors$Cholesky),
all(abs(crossprod(as(chch, "dtrMatrix")) - ch6) < 1e-10))
}
Matrix/man/abIndex-class.Rd 0000644 0001751 0000144 00000010272 14461513642 015263 0 ustar hornik users \name{abIndex-class}
\title{Class "abIndex" of Abstract Index Vectors}
%
\docType{class}
\keyword{classes}
%
\alias{abIndex-class}
\alias{seqMat-class} % not yet documented {unexported}
%
\alias{Arith,abIndex,abIndex-method}
\alias{Arith,abIndex,numLike-method}
\alias{Arith,numLike,abIndex-method}
\alias{Ops,ANY,abIndex-method}
\alias{Ops,abIndex,ANY-method}
\alias{Ops,abIndex,abIndex-method}
\alias{Summary,abIndex-method}
\alias{as.integer,abIndex-method}
\alias{as.numeric,abIndex-method}
\alias{as.vector,abIndex-method}
\alias{coerce,abIndex,integer-method}
\alias{coerce,abIndex,numeric-method}
\alias{coerce,abIndex,seqMat-method}
\alias{coerce,abIndex,vector-method}
\alias{coerce,logical,abIndex-method}
\alias{coerce,numeric,abIndex-method}
\alias{drop,abIndex-method}
\alias{length,abIndex-method}
\alias{show,abIndex-method}
%
\alias{coerce,numeric,seqMat-method}
\alias{coerce,seqMat,abIndex-method}
\alias{coerce,seqMat,numeric-method}
%
\description{
The \code{"abIndex"} \code{\link{class}}, short for \dQuote{Abstract
Index Vector}, is used for dealing with large index vectors more
efficiently, than using integer (or \code{\link{numeric}}) vectors of
the kind \code{2:1000000} or \code{c(0:1e5, 1000:1e6)}.
Note that the current implementation details are subject to change,
and if you consider working with these classes, please contact the
package maintainers (\code{packageDescription("Matrix")$Maintainer}).
}
\section{Objects from the Class}{
Objects can be created by calls of the form \code{new("abIndex", ...)},
but more easily and typically either by \code{as(x, "abIndex")} where
\code{x} is an integer (valued) vector, or directly by
\code{\link{abIseq}()} and combination \code{\link{c}(...)} of such.
}
\section{Slots}{
\describe{
\item{\code{kind}:}{a \code{\link{character}} string,
one of \code{("int32", "double", "rleDiff")}, denoting the
internal structure of the abIndex object.}
\item{\code{x}:}{Object of class \code{"numLike"}; is
used (i.e., not of length \code{0}) only iff the object is \emph{not}
compressed, i.e., currently exactly when \code{kind != "rleDiff"}.}
\item{\code{rleD}:}{object of class \code{"\linkS4class{rleDiff}"},
used for compression via \code{\link{rle}}.}
}
}
\section{Methods}{
\describe{
\item{as.numeric, as.integer, as.vector}{\code{signature(x = "abIndex")}: ... }
\item{[}{\code{signature(x = "abIndex", i = "index", j = "ANY", drop = "ANY")}: ... }
\item{coerce}{\code{signature(from = "numeric", to = "abIndex")}: ... }
\item{coerce}{\code{signature(from = "abIndex", to = "numeric")}: ... }
\item{coerce}{\code{signature(from = "abIndex", to = "integer")}: ... }
\item{length}{\code{signature(x = "abIndex")}: ... }
\item{Ops}{\code{signature(e1 = "numeric", e2 = "abIndex")}: These
and the following arithmetic and logic operations are
\bold{not yet implemented}; see \code{\link[methods]{Ops}} for a
list of these (S4) group methods.}
\item{Ops}{\code{signature(e1 = "abIndex", e2 = "abIndex")}: ... }
\item{Ops}{\code{signature(e1 = "abIndex", e2 = "numeric")}: ... }
\item{Summary}{\code{signature(x = "abIndex")}: ... }
\item{show}{\code{("abIndex")}: simple \code{\link{show}} method,
building on \code{show()}.}
\item{is.na}{\code{("abIndex")}: works analogously to regular vectors.}
\item{is.finite, is.infinite}{\code{("abIndex")}: ditto.}
}
}
\note{
This is currently experimental and not yet used for our own code.
Please contact us (\code{packageDescription("Matrix")$Maintainer}),
if you plan to make use of this class.
Partly builds on ideas and code from Jens Oehlschlaegel,
as implemented (around 2008, in the GPL'ed part of) package \pkg{ff}.
}
%\author{Martin Maechler}
\seealso{
\code{\link{rle}} (\pkg{base}) which is used here;
\code{\link{numeric}}% ... FIXME
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
showClass("abIndex")
ii <- c(-3:40, 20:70)
str(ai <- as(ii, "abIndex"))# note
ai # -> show() method
%% FIXME: add / exchange with ../tests/abIndex-tsts.R
stopifnot(identical(-3:20,
as(abIseq1(-3,20), "vector")))
}
Matrix/man/nearPD.Rd 0000644 0001751 0000144 00000020647 14446607050 013766 0 ustar hornik users \name{nearPD}
\title{Nearest Positive Definite Matrix}
%
\keyword{algebra}
\keyword{array}
\keyword{utilities}
%
\alias{nearPD}
%
\description{
Compute the nearest positive definite matrix to an approximate
one, typically a correlation or variance-covariance matrix.
}
\usage{
nearPD(x, corr = FALSE, keepDiag = FALSE, base.matrix = FALSE,
do2eigen = TRUE, doSym = FALSE,
doDykstra = TRUE, only.values = FALSE,
ensureSymmetry = !isSymmetric(x),
eig.tol = 1e-06, conv.tol = 1e-07, posd.tol = 1e-08,
maxit = 100, conv.norm.type = "I", trace = FALSE)
}
\arguments{
\item{x}{numeric \eqn{n \times n}{n * n} approximately positive
definite matrix, typically an approximation to a correlation or
covariance matrix. If \code{x} is not symmetric (and
\code{ensureSymmetry} is not false), \code{\link{symmpart}(x)} is used.}
\item{corr}{logical indicating if the matrix should be a
\emph{correlation} matrix.}
\item{keepDiag}{logical, generalizing \code{corr}: if \code{TRUE}, the
resulting matrix should have the same diagonal
(\code{\link{diag}(x)}) as the input matrix.}
\item{base.matrix}{logical indicating if the resulting \code{mat}
component should be a \pkg{base} \code{\link{matrix}} or (by default) a
\code{\linkS4class{Matrix}} of class \code{\linkS4class{dpoMatrix}}.}
\item{do2eigen}{logical indicating if a
\code{\link[sfsmisc]{posdefify}()} eigen step should be applied to
the result of the Higham algorithm.}
\item{doSym}{logical indicating if \code{X <- (X + t(X))/2} should be
done, after \code{X <- tcrossprod(Qd, Q)}; some doubt if this is necessary.}
\item{doDykstra}{logical indicating if Dykstra's correction should be
used; true by default. If false, the algorithm is basically the
direct fixpoint iteration
\eqn{Y_k = P_U(P_S(Y_{k-1}))}{Y(k) = P_U(P_S(Y(k-1)))}.}
\item{only.values}{logical; if \code{TRUE}, the result is just the
vector of eigenvalues of the approximating matrix.}
\item{ensureSymmetry}{logical; by default, \code{\link{symmpart}(x)}
is used whenever \code{\link{isSymmetric}(x)} is not true. The user
can explicitly set this to \code{TRUE} or \code{FALSE}, saving the
symmetry test. \emph{Beware} however that setting it \code{FALSE}
for an \bold{a}symmetric input \code{x}, is typically nonsense!}
\item{eig.tol}{defines relative positiveness of eigenvalues compared
to largest one, \eqn{\lambda_1}. Eigenvalues \eqn{\lambda_k} are
treated as if zero when \eqn{\lambda_k / \lambda_1 \le eig.tol}.}
\item{conv.tol}{convergence tolerance for Higham algorithm.}
\item{posd.tol}{tolerance for enforcing positive definiteness (in the
final \code{posdefify} step when \code{do2eigen} is \code{TRUE}).}
\item{maxit}{maximum number of iterations allowed.}
\item{conv.norm.type}{convergence norm type (\code{\link{norm}(*,
type)}) used for Higham algorithm. The default is \code{"I"}
(infinity), for reasons of speed (and back compatibility); using
\code{"F"} is more in line with Higham's proposal.}
\item{trace}{logical or integer specifying if convergence monitoring
should be traced.}
}
\details{
This implements the algorithm of Higham (2002), and then (if
\code{do2eigen} is true) forces positive definiteness using code from
\code{\link[sfsmisc]{posdefify}}. The algorithm of Knol and ten
Berge (1989) (not implemented here) is more general in that it
allows constraints to (1) fix some rows (and columns) of the matrix and
(2) force the smallest eigenvalue to have a certain value.
Note that setting \code{corr = TRUE} just sets \code{diag(.) <- 1}
within the algorithm.
Higham (2002) uses Dykstra's correction, but the version by Jens
\enc{Oehlschlägel}{Oehlschlaegel} did not use it (accidentally),
and still gave reasonable results; this simplification, now only
used if \code{doDykstra = FALSE},
was active in \code{nearPD()} up to Matrix version 0.999375-40.
}
\value{
If \code{only.values = TRUE}, a numeric vector of eigenvalues of the
approximating matrix;
Otherwise, as by default, an S3 object of \code{\link{class}}
\code{"nearPD"}, basically a list with components
\item{mat}{a matrix of class \code{\linkS4class{dpoMatrix}}, the
computed positive-definite matrix.}
\item{eigenvalues}{numeric vector of eigenvalues of \code{mat}.}
\item{corr}{logical, just the argument \code{corr}.}
\item{normF}{the Frobenius norm (\code{\link{norm}(x-X, "F")}) of the
difference between the original and the resulting matrix.}
\item{iterations}{number of iterations needed.}
\item{converged}{logical indicating if iterations converged.}
}
\references{%% more in /u/maechler/R/Pkgs/sfsmisc/man/posdefify.Rd
Cheng, Sheung Hun and Higham, Nick (1998)
A Modified Cholesky Algorithm Based on a Symmetric Indefinite Factorization;
\emph{SIAM J. Matrix Anal.\ Appl.}, \bold{19}, 1097--1110.
Knol DL, ten Berge JMF (1989)
Least-squares approximation of an improper correlation matrix by a
proper one.
\emph{Psychometrika} \bold{54}, 53--61.
Higham, Nick (2002)
Computing the nearest correlation matrix - a problem from finance;
\emph{IMA Journal of Numerical Analysis} \bold{22}, 329--343.
}
\author{
Jens \enc{Oehlschlägel}{Oehlschlaegel} donated a first version.
Subsequent changes by the Matrix package authors.
}
\seealso{A first version of this (with non-optional \code{corr=TRUE})
has been available as \code{\link[sfsmisc]{nearcor}()}; and
more simple versions with a similar purpose
\code{\link[sfsmisc]{posdefify}()}, both from package \pkg{sfsmisc}.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library( stats, pos = "package:base", verbose = FALSE)
library( graphics, pos = "package:base", verbose = FALSE)
library(grDevices, pos = "package:base", verbose = FALSE)
library( utils, pos = "package:base", verbose = FALSE)
}
## Higham(2002), p.334f - simple example
A <- matrix(1, 3,3); A[1,3] <- A[3,1] <- 0
n.A <- nearPD(A, corr=TRUE, do2eigen=FALSE)
n.A[c("mat", "normF")]
n.A.m <- nearPD(A, corr=TRUE, do2eigen=FALSE, base.matrix=TRUE)$mat
stopifnot(exprs = { #=--------------
all.equal(n.A$mat[1,2], 0.760689917)
all.equal(n.A$normF, 0.52779033, tolerance=1e-9)
all.equal(n.A.m, unname(as.matrix(n.A$mat)), tolerance = 1e-15)# seen rel.d.= 1.46e-16
})
set.seed(27)
m <- matrix(round(rnorm(25),2), 5, 5)
m <- m + t(m)
diag(m) <- pmax(0, diag(m)) + 1
(m <- round(cov2cor(m), 2))
str(near.m <- nearPD(m, trace = TRUE))
round(near.m$mat, 2)
norm(m - near.m$mat) # 1.102 / 1.08
if(requireNamespace("sfsmisc")) {
m2 <- sfsmisc::posdefify(m) # a simpler approach
norm(m - m2) # 1.185, i.e., slightly "less near"
}
round(nearPD(m, only.values=TRUE), 9)
## A longer example, extended from Jens' original,
## showing the effects of some of the options:
pr <- Matrix(c(1, 0.477, 0.644, 0.478, 0.651, 0.826,
0.477, 1, 0.516, 0.233, 0.682, 0.75,
0.644, 0.516, 1, 0.599, 0.581, 0.742,
0.478, 0.233, 0.599, 1, 0.741, 0.8,
0.651, 0.682, 0.581, 0.741, 1, 0.798,
0.826, 0.75, 0.742, 0.8, 0.798, 1),
nrow = 6, ncol = 6)
nc. <- nearPD(pr, conv.tol = 1e-7) # default
nc.$iterations # 2
nc.1 <- nearPD(pr, conv.tol = 1e-7, corr = TRUE)
nc.1$iterations # 11 / 12 (!)
ncr <- nearPD(pr, conv.tol = 1e-15)
str(ncr)# still 2 iterations
ncr.1 <- nearPD(pr, conv.tol = 1e-15, corr = TRUE)
ncr.1 $ iterations # 27 / 30 !
ncF <- nearPD(pr, conv.tol = 1e-15, conv.norm = "F")
stopifnot(all.equal(ncr, ncF))# norm type does not matter at all in this example
## But indeed, the 'corr = TRUE' constraint did ensure a better solution;
## cov2cor() does not just fix it up equivalently :
norm(pr - cov2cor(ncr$mat)) # = 0.09994
norm(pr - ncr.1$mat) # = 0.08746 / 0.08805
### 3) a real data example from a 'systemfit' model (3 eq.):
(load(system.file("external", "symW.rda", package="Matrix"))) # "symW"
dim(symW) # 24 x 24
class(symW)# "dsCMatrix": sparse symmetric
if(dev.interactive()) image(symW)
EV <- eigen(symW, only=TRUE)$values
summary(EV) ## looking more closely {EV sorted decreasingly}:
tail(EV)# all 6 are negative
EV2 <- eigen(sWpos <- nearPD(symW)$mat, only=TRUE)$values
stopifnot(EV2 > 0)
if(requireNamespace("sfsmisc")) {
plot(pmax(1e-3,EV), EV2, type="o", log="xy", xaxt="n", yaxt="n")
for(side in 1:2) sfsmisc::eaxis(side)
} else
plot(pmax(1e-3,EV), EV2, type="o", log="xy")
abline(0, 1, col="red3", lty=2)
}
Matrix/man/Cholesky-methods.Rd 0000644 0001751 0000144 00000036544 14575234535 016051 0 ustar hornik users \name{Cholesky-methods}
\title{Methods for Cholesky Factorization}
%
\docType{methods}
\keyword{algebra}
\keyword{array}
\keyword{methods}
\concept{Choleski} % alternate English spelling
%
\alias{Cholesky}
\alias{Cholesky-methods}
%
\alias{Cholesky,ddiMatrix-method}
\alias{Cholesky,diagonalMatrix-method}
\alias{Cholesky,dsCMatrix-method}
\alias{Cholesky,dsRMatrix-method}
\alias{Cholesky,dsTMatrix-method}
\alias{Cholesky,dspMatrix-method}
\alias{Cholesky,dsyMatrix-method}
\alias{Cholesky,generalMatrix-method}
\alias{Cholesky,matrix-method}
\alias{Cholesky,symmetricMatrix-method}
\alias{Cholesky,triangularMatrix-method}
%
\description{
Computes the pivoted Cholesky factorization of an
\eqn{n \times n}{n-by-n} real, symmetric matrix \eqn{A},
which has the general form
\deqn{P_1 A P_1' = L_1 D L_1' \overset{D_{jj} \ge 0}{=} L L'}{P1 * A * P1' = L1 * D * L1' [ = L * L' ]}
or (equivalently)
\deqn{A = P_1' L_1 D L_1' P_1 \overset{D_{jj} \ge 0}{=} P_1' L L' P_1}{A = P1' L1 * D * L1' * P1 [ = P1' * L * L' * P1 ]}
where
\eqn{P_1}{P1} is a permutation matrix,
\eqn{L_1}{L1} is a unit lower triangular matrix,
\eqn{D} is a diagonal matrix, and
\eqn{L = L_1 \sqrt{D}}{L = L1 * sqrt(D)}.
The second equalities hold only for positive semidefinite \eqn{A},
for which the diagonal entries of \eqn{D} are non-negative
and \eqn{\sqrt{D}}{sqrt(D)} is well-defined.
Methods for \code{\linkS4class{denseMatrix}} are built on
LAPACK routines \code{dpstrf}, \code{dpotrf}, and \code{dpptrf}.
The latter two do not permute rows or columns,
so that \eqn{P_1}{P1} is an identity matrix.
Methods for \code{\linkS4class{sparseMatrix}} are built on
CHOLMOD routines \code{cholmod_analyze} and \code{cholmod_factorize_p}.
}
\usage{
Cholesky(A, \dots)
\S4method{Cholesky}{dsyMatrix}(A, perm = TRUE, tol = -1, \dots)
\S4method{Cholesky}{dspMatrix}(A, \dots)
\S4method{Cholesky}{dsCMatrix}(A, perm = TRUE, LDL = !super, super = FALSE,
Imult = 0, \dots)
\S4method{Cholesky}{ddiMatrix}(A, \dots)
\S4method{Cholesky}{generalMatrix}(A, uplo = "U", \dots)
\S4method{Cholesky}{triangularMatrix}(A, uplo = "U", \dots)
\S4method{Cholesky}{matrix}(A, uplo = "U", \dots)
}
\arguments{
\item{A}{a \link[=is.finite]{finite}, symmetric matrix or
\code{\linkS4class{Matrix}} to be factorized. If \code{A}
is square but not symmetric, then it will be \emph{treated}
as symmetric; see \code{uplo}.
Methods for dense \code{A} require positive definiteness
when \code{perm = FALSE} and positive semidefiniteness
when \code{perm = TRUE}.
Methods for sparse \code{A} require positive definiteness
when \code{LDL = TRUE} and nonzero leading principal minors
(after pivoting) when \code{LDL = FALSE}.
Methods for sparse, \emph{diagonal} \code{A} are an exception,
requiring positive semidefiniteness unconditionally.}
\item{perm}{a logical indicating if the rows and columns
of \eqn{A} should be pivoted. Methods for sparse \code{A}
employ the approximate minimum degree (AMD) algorithm
in order to reduce fill-in, i.e., without regard for
numerical stability.
Pivoting for sparsity may introduce nonpositive leading
principal minors, causing the factorization to fail, in
which case it may be necessary to set \code{perm = FALSE}.}
\item{tol}{a \link[=is.finite]{finite} numeric tolerance,
used only if \code{perm = TRUE}.
The factorization algorithm stops if the pivot is less than
or equal to \code{tol}. Negative \code{tol} is equivalent
to \code{nrow(A) * .Machine$double.eps * max(diag(A))}.}
\item{LDL}{a logical indicating if the simplicial factorization
should be computed as
\eqn{P_1' L_1 D L_1' P_1}{P1' * L1 * D * L1' * P1},
such that the result stores the lower triangular entries
of \eqn{L_1-I+D}{L1-I+D}.
The alternative is \eqn{P_1' L L' P_1}{P1' * L * L' * P1},
such that the result stores the lower triangular entries
of \eqn{L = L_1 \sqrt{D}}{L = L1 * sqrt(D)}. This argument
is ignored if \code{super = TRUE} (or if \code{super = NA}
and the supernodal algorithm is chosen), as the supernodal
code does not yet support the \code{LDL = TRUE} variant.}
\item{super}{a logical indicating if the factorization should
use the supernodal algorithm. The alternative is the simplicial
algorithm. Setting \code{super = NA} leaves the choice to
a CHOLMOD-internal heuristic.}
\item{Imult}{a \link[=is.finite]{finite} number. The matrix
that is factorized is \code{A + Imult * diag(nrow(A))},
i.e., \code{A} plus \code{Imult} times the identity matrix.
This argument is useful for symmetric, indefinite \code{A},
as \code{Imult > max(rowSums(abs(A)) - diag(abs(A)))} ensures
that \code{A + Imult * diag(nrow(A))} is diagonally dominant.
(Symmetric, diagonally dominant matrices are positive definite.)}
\item{uplo}{a string, either \code{"U"} or \code{"L"},
indicating which triangle of \code{A} should be used
to compute the factorization. The default is \code{"U"},
even for lower triangular \code{A}, to be consistent with
\code{\link[base]{chol}} from \pkg{base}.}
\item{\dots}{further arguments passed to or from methods.}
}
\value{
An object representing the factorization, inheriting from
virtual class \code{\linkS4class{CholeskyFactorization}}.
For a traditional matrix \code{A}, the specific class is
\code{\linkS4class{Cholesky}}.
For \code{A} inheriting from
\code{\linkS4class{unpackedMatrix}},
\code{\linkS4class{packedMatrix}}, and
\code{\linkS4class{sparseMatrix}},
the specific class is
\code{\linkS4class{Cholesky}},
\code{\linkS4class{pCholesky}}, and
\code{\linkS4class{dCHMsimpl}} or \code{\linkS4class{dCHMsuper}},
respectively.
}
\details{
Note that the result of a call to \code{Cholesky} inherits
from \code{\linkS4class{CholeskyFactorization}} but not
\code{\linkS4class{Matrix}}. Users who just want a matrix
should consider using \code{\link{chol}}, whose methods are
simple wrappers around \code{Cholesky} returning just the
upper triangular Cholesky factor \eqn{L'},
typically as a \code{\linkS4class{triangularMatrix}}.
However, a more principled approach would be to construct
factors as needed from the \code{CholeskyFactorization} object,
e.g., with \code{\link{expand1}(x, "L")}, if \code{x} is the
object.
The behaviour of \code{Cholesky(A, perm = TRUE)} for dense \code{A}
is somewhat exceptional, in that it expects \emph{without} checking
that \code{A} is positive semidefinite. By construction, if \eqn{A}
is positive semidefinite and the exact algorithm encounters a zero
pivot, then the unfactorized trailing submatrix is the zero matrix,
and there is nothing left to do. Hence when the finite precision
algorithm encounters a pivot less than \code{tol}, it signals a
warning instead of an error and zeros the trailing submatrix in
order to guarantee that \eqn{P' L L' P}{P' * L * L' * P} is positive
semidefinite even if \eqn{A} is not. It follows that one way to
test for positive semidefiniteness of \eqn{A} in the event of a
warning is to analyze the error
\deqn{\frac{\lVert A - P' L L' P \rVert}{\lVert A \rVert}\,.}{norm(A - P' * L * L' * P) / norm(A).}
See the examples and LAPACK Working Note (\dQuote{LAWN}) 161
for details.
}
\seealso{
Classes \code{\linkS4class{Cholesky}}, \code{\linkS4class{pCholesky}},
\code{\linkS4class{dCHMsimpl}} and \code{\linkS4class{dCHMsuper}}
and their methods.
Classes \code{\linkS4class{dpoMatrix}}, \code{\linkS4class{dppMatrix}},
and \code{\linkS4class{dsCMatrix}}.
Generic function \code{\link{chol}},
for obtaining the upper triangular Cholesky factor \eqn{L'} as a
matrix or \code{\linkS4class{Matrix}}.
Generic functions \code{\link{expand1}} and \code{\link{expand2}},
for constructing matrix factors from the result.
Generic functions \code{\link{BunchKaufman}}, \code{\link{Schur}},
\code{\link{lu}}, and \code{\link{qr}},
for computing other factorizations.
}
\references{
The LAPACK source code, including documentation; see
\url{https://netlib.org/lapack/double/dpstrf.f},
\url{https://netlib.org/lapack/double/dpotrf.f}, and
\url{https://netlib.org/lapack/double/dpptrf.f}.
The CHOLMOD source code; see
\url{https://github.com/DrTimothyAldenDavis/SuiteSparse},
notably the header file \file{CHOLMOD/Include/cholmod.h}
defining \code{cholmod_factor_struct}.
Lucas, C. (2004).
\emph{LAPACK-style codes for level 2 and 3 pivoted Cholesky factorizations}.
LAPACK Working Note, Number 161.
\url{https://www.netlib.org/lapack/lawnspdf/lawn161.pdf}
Chen, Y., Davis, T. A., Hager, W. W., & Rajamanickam, S. (2008).
Algorithm 887: CHOLMOD, supernodal sparse Cholesky factorization
and update/downdate.
\emph{ACM Transactions on Mathematical Software},
\emph{35}(3), Article 22, 1-14.
\doi{10.1145/1391989.1391995}
Amestoy, P. R., Davis, T. A., & Duff, I. S. (2004).
Algorithm 837: AMD, an approximate minimum degree ordering algorithm.
\emph{ACM Transactions on Mathematical Software},
\emph{17}(4), 886-905.
\doi{10.1145/1024074.1024081}
Golub, G. H., & Van Loan, C. F. (2013).
\emph{Matrix computations} (4th ed.).
Johns Hopkins University Press.
\doi{10.56021/9781421407944}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
library(utils, pos = "package:base", verbose = FALSE)
}
showMethods("Cholesky", inherited = FALSE)
set.seed(0)
## ---- Dense ----------------------------------------------------------
## .... Positive definite ..............................................
n <- 6L
(A1 <- crossprod(Matrix(rnorm(n * n), n, n)))
(ch.A1.nopivot <- Cholesky(A1, perm = FALSE))
(ch.A1 <- Cholesky(A1))
stopifnot(exprs = {
length(ch.A1@perm) == ncol(A1)
isPerm(ch.A1@perm)
is.unsorted(ch.A1@perm) # typically not the identity permutation
length(ch.A1.nopivot@perm) == 0L
})
## A ~ P1' L D L' P1 ~ P1' L L' P1 in floating point
str(e.ch.A1 <- expand2(ch.A1, LDL = TRUE), max.level = 2L)
str(E.ch.A1 <- expand2(ch.A1, LDL = FALSE), max.level = 2L)
stopifnot(exprs = {
all.equal(as(A1, "matrix"), as(Reduce(`\%*\%`, e.ch.A1), "matrix"))
all.equal(as(A1, "matrix"), as(Reduce(`\%*\%`, E.ch.A1), "matrix"))
})
## .... Positive semidefinite but not positive definite ................
A2 <- A1
A2[1L, ] <- A2[, 1L] <- 0
A2
try(Cholesky(A2, perm = FALSE)) # fails as not positive definite
ch.A2 <- Cholesky(A2) # returns, with a warning and ...
A2.hat <- Reduce(`\%*\%`, expand2(ch.A2, LDL = FALSE))
norm(A2 - A2.hat, "2") / norm(A2, "2") # 7.670858e-17
## .... Not positive semidefinite ......................................
A3 <- A1
A3[1L, ] <- A3[, 1L] <- -1
A3
try(Cholesky(A3, perm = FALSE)) # fails as not positive definite
ch.A3 <- Cholesky(A3) # returns, with a warning and ...
A3.hat <- Reduce(`\%*\%`, expand2(ch.A3, LDL = FALSE))
norm(A3 - A3.hat, "2") / norm(A3, "2") # 1.781568
## Indeed, 'A3' is not positive semidefinite, but 'A3.hat' _is_
ch.A3.hat <- Cholesky(A3.hat)
A3.hat.hat <- Reduce(`\%*\%`, expand2(ch.A3.hat, LDL = FALSE))
norm(A3.hat - A3.hat.hat, "2") / norm(A3.hat, "2") # 1.777944e-16
## ---- Sparse ---------------------------------------------------------
## Really just three cases modulo permutation :
##
## type factorization minors of P1 A P1'
## 1 simplicial P1 A P1' = L1 D L1' nonzero
## 2 simplicial P1 A P1' = L L ' positive
## 3 supernodal P1 A P2' = L L ' positive
data(KNex, package = "Matrix")
A4 <- crossprod(KNex[["mm"]])
ch.A4 <-
list(pivoted =
list(simpl1 = Cholesky(A4, perm = TRUE, super = FALSE, LDL = TRUE),
simpl0 = Cholesky(A4, perm = TRUE, super = FALSE, LDL = FALSE),
super0 = Cholesky(A4, perm = TRUE, super = TRUE )),
unpivoted =
list(simpl1 = Cholesky(A4, perm = FALSE, super = FALSE, LDL = TRUE),
simpl0 = Cholesky(A4, perm = FALSE, super = FALSE, LDL = FALSE),
super0 = Cholesky(A4, perm = FALSE, super = TRUE )))
ch.A4
s <- simplify2array
rapply2 <- function(object, f, ...) rapply(object, f, , , how = "list", ...)
s(rapply2(ch.A4, isLDL))
s(m.ch.A4 <- rapply2(ch.A4, expand1, "L")) # giving L = L1 sqrt(D)
## By design, the pivoted and simplicial factorizations
## are more sparse than the unpivoted and supernodal ones ...
s(rapply2(m.ch.A4, object.size))
## Which is nicely visualized by lattice-based methods for 'image'
inm <- c("pivoted", "unpivoted")
jnm <- c("simpl1", "simpl0", "super0")
for(i in 1:2)
for(j in 1:3)
print(image(m.ch.A4[[c(i, j)]], main = paste(inm[i], jnm[j])),
split = c(j, i, 3L, 2L), more = i * j < 6L)
simpl1 <- ch.A4[[c("pivoted", "simpl1")]]
stopifnot(exprs = {
length(simpl1@perm) == ncol(A4)
isPerm(simpl1@perm, 0L)
is.unsorted(simpl1@perm) # typically not the identity permutation
})
## One can expand with and without D regardless of isLDL(.),
## but "without" requires L = L1 sqrt(D), which is conditional
## on min(diag(D)) >= 0, hence "with" is the default
isLDL(simpl1)
stopifnot(min(diag(simpl1)) >= 0)
str(e.ch.A4 <- expand2(simpl1, LDL = TRUE), max.level = 2L) # default
str(E.ch.A4 <- expand2(simpl1, LDL = FALSE), max.level = 2L)
stopifnot(exprs = {
all.equal(E.ch.A4[["L" ]], e.ch.A4[["L1" ]] \%*\% sqrt(e.ch.A4[["D"]]))
all.equal(E.ch.A4[["L."]], sqrt(e.ch.A4[["D"]]) \%*\% e.ch.A4[["L1."]])
all.equal(A4, as(Reduce(`\%*\%`, e.ch.A4), "symmetricMatrix"))
all.equal(A4, as(Reduce(`\%*\%`, E.ch.A4), "symmetricMatrix"))
})
## The "same" permutation matrix with "alternate" representation
## [i, perm[i]] {margin=1} <-> [invertPerm(perm)[j], j] {margin=2}
alt <- function(P) {
P@margin <- 1L + !(P@margin - 1L) # 1 <-> 2
P@perm <- invertPerm(P@perm)
P
}
## Expansions are elegant but inefficient (transposes are redundant)
## hence programmers should consider methods for 'expand1' and 'diag'
stopifnot(exprs = {
identical(expand1(simpl1, "P1"), alt(e.ch.A4[["P1"]]))
identical(expand1(simpl1, "L"), E.ch.A4[["L"]])
identical(Diagonal(x = diag(simpl1)), e.ch.A4[["D"]])
})
## chol(A, pivot = value) is a simple wrapper around
## Cholesky(A, perm = value, LDL = FALSE, super = FALSE),
## returning L' = sqrt(D) L1' _but_ giving no information
## about the permutation P1
selectMethod("chol", "dsCMatrix")
stopifnot(all.equal(chol(A4, pivot = TRUE), E.ch.A4[["L."]]))
## Now a symmetric matrix with positive _and_ negative eigenvalues,
## hence _not_ positive semidefinite
A5 <- new("dsCMatrix",
Dim = c(7L, 7L),
p = c(0:1, 3L, 6:7, 10:11, 15L),
i = c(0L, 0:1, 0:3, 2:5, 3:6),
x = c(1, 6, 38, 10, 60, 103, -4, 6, -32, -247, -2, -16, -128, -2, -67))
(ev <- eigen(A5, only.values = TRUE)$values)
(t.ev <- table(factor(sign(ev), -1:1))) # the matrix "inertia"
ch.A5 <- Cholesky(A5)
isLDL(ch.A5)
(d.A5 <- diag(ch.A5)) # diag(D) is partly negative
## Sylvester's law of inertia holds here, but not in general
## in finite precision arithmetic
stopifnot(identical(table(factor(sign(d.A5), -1:1)), t.ev))
try(expand1(ch.A5, "L")) # unable to compute L = L1 sqrt(D)
try(expand2(ch.A5, LDL = FALSE)) # ditto
try(chol(A5, pivot = TRUE)) # ditto
## The default expansion is "square root free" and still works here
str(e.ch.A5 <- expand2(ch.A5, LDL = TRUE), max.level = 2L)
stopifnot(all.equal(A5, as(Reduce(`\%*\%`, e.ch.A5), "symmetricMatrix")))
## Version of the SuiteSparse library, which includes CHOLMOD
Mv <- Matrix.Version()
Mv[["suitesparse"]]
}
Matrix/man/band-methods.Rd 0000644 0001751 0000144 00000010064 14575137654 015165 0 ustar hornik users \name{band-methods}
\title{Extract bands of a matrix}
%
\docType{methods}
\keyword{array}
\keyword{methods}
%
\alias{band}
\alias{band-methods}
\alias{triu}
\alias{triu-methods}
\alias{tril}
\alias{tril-methods}
%
\alias{band,CsparseMatrix-method}
\alias{band,RsparseMatrix-method}
\alias{band,TsparseMatrix-method}
\alias{band,denseMatrix-method}
\alias{band,diagonalMatrix-method}
\alias{band,indMatrix-method}
\alias{band,matrix-method}
\alias{triu,CsparseMatrix-method}
\alias{triu,RsparseMatrix-method}
\alias{triu,TsparseMatrix-method}
\alias{triu,denseMatrix-method}
\alias{triu,diagonalMatrix-method}
\alias{triu,indMatrix-method}
\alias{triu,matrix-method}
\alias{tril,CsparseMatrix-method}
\alias{tril,RsparseMatrix-method}
\alias{tril,TsparseMatrix-method}
\alias{tril,denseMatrix-method}
\alias{tril,diagonalMatrix-method}
\alias{tril,indMatrix-method}
\alias{tril,matrix-method}
%
\description{
Return the matrix obtained by setting to zero elements below a diagonal
(\code{triu}), above a diagonal (\code{tril}), or outside of a general
band (\code{band}).
}
\usage{
band(x, k1, k2, \dots)
triu(x, k = 0L, \dots)
tril(x, k = 0L, \dots)
}
\arguments{
\item{x}{a matrix-like object}
\item{k,k1,k2}{integers specifying the diagonals that are not set to
zero, \code{k1 <= k2}. These are interpreted relative to the main
diagonal, which is \code{k = 0}.
Positive and negative values of \code{k} indicate
diagonals above and below the main diagonal, respectively.}
\item{\dots}{optional arguments passed to methods, currently unused
by package \pkg{Matrix}.}
}
\details{
\code{triu(x, k)} is equivalent to \code{band(x, k, dim(x)[2])}.
Similarly,
\code{tril(x, k)} is equivalent to \code{band(x, -dim(x)[1], k)}.
}
\value{
An object of a suitable matrix class, inheriting from
\code{\linkS4class{triangularMatrix}} where appropriate.
It inherits from \code{\linkS4class{sparseMatrix}} if
and only if \code{x} does.
}
\section{Methods}{
\describe{
\item{x = "CsparseMatrix"}{method for compressed, sparse,
column-oriented matrices.}
\item{x = "RsparseMatrix"}{method for compressed, sparse,
row-oriented matrices.}
\item{x = "TsparseMatrix"}{method for sparse matrices in
triplet format.}
\item{x = "diagonalMatrix"}{method for diagonal matrices.}
\item{x = "denseMatrix"}{method for dense matrices in
packed or unpacked format.}
\item{x = "matrix"}{method for traditional matrices
of implicit class \code{\link{matrix}}.}
}
}
\seealso{
\code{\link{bandSparse}} for the \emph{construction} of a
banded sparse matrix directly from its non-zero diagonals.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
}
## A random sparse matrix :
set.seed(7)
m <- matrix(0, 5, 5)
m[sample(length(m), size = 14)] <- rep(1:9, length=14)
(mm <- as(m, "CsparseMatrix"))
tril(mm) # lower triangle
tril(mm, -1) # strict lower triangle
triu(mm, 1) # strict upper triangle
band(mm, -1, 2) # general band
(m5 <- Matrix(rnorm(25), ncol = 5))
tril(m5) # lower triangle
tril(m5, -1) # strict lower triangle
triu(m5, 1) # strict upper triangle
band(m5, -1, 2) # general band
(m65 <- Matrix(rnorm(30), ncol = 5)) # not square
triu(m65) # result not "dtrMatrix" unless square
(sm5 <- crossprod(m65)) # symmetric
band(sm5, -1, 1)# "dsyMatrix": symmetric band preserves symmetry property
as(band(sm5, -1, 1), "sparseMatrix")# often preferable
(sm <- round(crossprod(triu(mm/2)))) # sparse symmetric ("dsC*")
band(sm, -1,1) # remains "dsC", *however*
band(sm, -2,1) # -> "dgC"
%% Problem is the underlying cholmod_band() which really does symmetric
%% banding *only* *if* the matrix is cholmod-symmetric i.e. 'stype != 0'
%%
\dontshow{ ## this uses special methods
(x.x <- crossprod(mm))
tril(x.x)
xx <- tril(x.x) + triu(x.x, 1) ## the same as x.x (but stored differently):
txx <- t(as(xx, "symmetricMatrix"))
stopifnot(identical(triu(x.x), t(tril(x.x))),
identical(class(x.x), class(txx)),
identical(as(x.x, "generalMatrix"), as(txx, "generalMatrix")))
}
}
Matrix/man/Schur-methods.Rd 0000644 0001751 0000144 00000006734 14575137654 015356 0 ustar hornik users \name{Schur-methods}
\title{Methods for Schur Factorization}
%
\docType{methods}
\keyword{algebra}
\keyword{array}
\keyword{methods}
%
\alias{Schur}
\alias{Schur-methods}
%
\alias{Schur,dgeMatrix-method}
\alias{Schur,diagonalMatrix-method}
\alias{Schur,dsyMatrix-method}
\alias{Schur,generalMatrix-method}
\alias{Schur,matrix-method}
\alias{Schur,symmetricMatrix-method}
\alias{Schur,triangularMatrix-method}
%
\description{
Computes the Schur factorization of an \eqn{n \times n}{n-by-n}
real matrix \eqn{A}, which has the general form
\deqn{A = Q T Q'}{A = Q * T * Q'}
where
\eqn{Q} is an orthogonal matrix and
\eqn{T} is a block upper triangular matrix with
\eqn{1 \times 1}{1-by-1} and \eqn{2 \times 2}{2-by-2} diagonal blocks
specifying the real and complex conjugate eigenvalues of \eqn{A}.
The column vectors of \eqn{Q} are the Schur vectors of \eqn{A},
and \eqn{T} is the Schur form of \eqn{A}.
Methods are built on LAPACK routine \code{dgees}.
}
\usage{
Schur(x, vectors = TRUE, \dots)
}
\arguments{
\item{x}{a \link[=is.finite]{finite} square matrix or
\code{\linkS4class{Matrix}} to be factorized.}
\item{vectors}{a logical. If \code{TRUE} (the default),
then Schur vectors are computed in addition to the Schur form.}
\item{\dots}{further arguments passed to or from methods.}
}
\value{
An object representing the factorization, inheriting
from virtual class \code{\linkS4class{SchurFactorization}}
if \code{vectors = TRUE}. Currently, the specific class
is always \code{\linkS4class{Schur}} in that case.
%% FIXME? no other factorization behaves this way:
An exception is if \code{x} is a traditional matrix,
in which case the result is a named list containing
\code{Q}, \code{T}, and \code{EValues} slots of the
\code{\linkS4class{Schur}} object.
If \code{vectors = FALSE}, then the result is the same
named list but without \code{Q}.
}
\seealso{
Class \code{\linkS4class{Schur}} and its methods.
Class \code{\linkS4class{dgeMatrix}}.
Generic functions \code{\link{expand1}} and \code{\link{expand2}},
for constructing matrix factors from the result.
Generic functions \code{\link{Cholesky}}, \code{\link{BunchKaufman}},
\code{\link{lu}}, and \code{\link{qr}},
for computing other factorizations.
}
\references{
The LAPACK source code, including documentation; see
\url{https://netlib.org/lapack/double/dgees.f}.
Golub, G. H., & Van Loan, C. F. (2013).
\emph{Matrix computations} (4th ed.).
Johns Hopkins University Press.
\doi{10.56021/9781421407944}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
library(utils, pos = "package:base", verbose = FALSE)
}
showMethods("Schur", inherited = FALSE)
set.seed(0)
Schur(Hilbert(9L)) # real eigenvalues
(A <- Matrix(round(rnorm(25L, sd = 100)), 5L, 5L))
(sch.A <- Schur(A)) # complex eigenvalues
## A ~ Q T Q' in floating point
str(e.sch.A <- expand2(sch.A), max.level = 2L)
stopifnot(all.equal(A, Reduce(`\%*\%`, e.sch.A)))
(e1 <- eigen(sch.A@T, only.values = TRUE)$values)
(e2 <- eigen( A , only.values = TRUE)$values)
(e3 <- sch.A@EValues)
stopifnot(exprs = {
all.equal(e1, e2, tolerance = 1e-13)
all.equal(e1, e3[order(Mod(e3), decreasing = TRUE)], tolerance = 1e-13)
identical(Schur(A, vectors = FALSE),
list(T = sch.A@T, EValues = e3))
identical(Schur(as(A, "matrix")),
list(Q = as(sch.A@Q, "matrix"),
T = as(sch.A@T, "matrix"), EValues = e3))
})
}
Matrix/man/dtCMatrix-class.Rd 0000644 0001751 0000144 00000010611 14446607050 015605 0 ustar hornik users \name{dtCMatrix-class}
\title{Triangular, (compressed) sparse column matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{dtCMatrix-class}
\alias{dtTMatrix-class}
%
\alias{Arith,dtCMatrix,dtCMatrix-method}
%
\description{The \code{"dtCMatrix"} class is a class of triangular, sparse
matrices in the compressed, column-oriented format. In this
implementation the non-zero elements in the columns are sorted into
increasing row order.
The \code{"dtTMatrix"} class is a class of triangular, sparse matrices
in triplet format.
}
\section{Objects from the Class}{
Objects can be created by calls of the form \code{new("dtCMatrix",
...)} or calls of the form \code{new("dtTMatrix", ...)},
but more typically automatically via \code{\link{Matrix}()}
or coercions such as \code{as(x, "triangularMatrix")}.
}
\section{Slots}{
\describe{
\item{\code{uplo}:}{Object of class \code{"character"}. Must be
either "U", for upper triangular, and "L", for lower triangular.}
\item{\code{diag}:}{Object of class \code{"character"}. Must be
either \code{"U"}, for unit triangular (diagonal is all ones), or
\code{"N"}; see \code{\linkS4class{triangularMatrix}}.}
\item{\code{p}:}{(only present in \code{"dtCMatrix"}:) an
\code{\link{integer}} vector for providing pointers, one for each
column, see the detailed description in \code{\linkS4class{CsparseMatrix}}.}
\item{\code{i}:}{Object of class \code{"integer"} of length nnzero
(number of non-zero elements). These are the row numbers for
each non-zero element in the matrix.}
\item{\code{j}:}{Object of class \code{"integer"} of length nnzero
(number of non-zero elements). These are the column numbers for
each non-zero element in the matrix. (Only present in the
\code{dtTMatrix} class.)}
\item{\code{x}:}{Object of class \code{"numeric"} - the non-zero
elements of the matrix.}
\item{\code{Dim},\code{Dimnames}:}{The dimension (a length-2
\code{"integer"}) and corresponding names (or \code{NULL}),
inherited from the \code{\linkS4class{Matrix}}, see there.}
}
}
\section{Extends}{
Class \code{"dgCMatrix"}, directly.
Class \code{"triangularMatrix"}, directly.
Class \code{"dMatrix"}, \code{"sparseMatrix"}, and more by class
\code{"dgCMatrix"} etc, see the examples.
}
\section{Methods}{
\describe{
\item{solve}{\code{signature(a = "dtCMatrix", b = "....")}:
sparse triangular solve (aka \dQuote{backsolve} or
\dQuote{forwardsolve}), see \code{\link{solve-methods}}.}
\item{t}{\code{signature(x = "dtCMatrix")}: returns the transpose of
\code{x}}
\item{t}{\code{signature(x = "dtTMatrix")}: returns the transpose of
\code{x}}
}
}
%\references{}
%\author{}
%\note{}
\seealso{
Classes \code{\linkS4class{dgCMatrix}}, \code{\linkS4class{dgTMatrix}},
\code{\linkS4class{dgeMatrix}}, and \code{\linkS4class{dtrMatrix}}.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
showClass("dtCMatrix")
showClass("dtTMatrix")
t1 <- new("dtTMatrix", x= c(3,7), i= 0:1, j=3:2, Dim= as.integer(c(4,4)))
t1
## from 0-diagonal to unit-diagonal {low-level step}:
tu <- t1 ; tu@diag <- "U"
tu
(cu <- as(tu, "CsparseMatrix"))
str(cu)# only two entries in @i and @x
stopifnot(cu@i == 1:0,
all(2 * symmpart(cu) == Diagonal(4) + forceSymmetric(cu)))
t1[1,2:3] <- -1:-2
diag(t1) <- 10*c(1:2,3:2)
t1 # still triangular
(it1 <- solve(t1))
t1. <- solve(it1)
all(abs(t1 - t1.) < 10 * .Machine$double.eps)
## 2nd example
U5 <- new("dtCMatrix", i= c(1L, 0:3), p=c(0L,0L,0:2, 5L), Dim = c(5L, 5L),
x = rep(1, 5), diag = "U")
U5
(iu <- solve(U5)) # contains one '0'
validObject(iu2 <- solve(U5, Diagonal(5)))# failed in earlier versions
I5 <- iu \%*\% U5 # should equal the identity matrix
i5 <- iu2 \%*\% U5
m53 <- matrix(1:15, 5,3, dimnames=list(NULL,letters[1:3]))
asDiag <- function(M) as(drop0(M), "diagonalMatrix")
stopifnot(
all.equal(Diagonal(5), asDiag(I5), tolerance=1e-14) ,
all.equal(Diagonal(5), asDiag(i5), tolerance=1e-14) ,
identical(list(NULL, dimnames(m53)[[2]]), dimnames(solve(U5, m53)))
)
\dontshow{%
i5. <- I5; colnames(i5.) <- LETTERS[11:15]
M53 <- as(m53, "denseMatrix")
stopifnot(
identical((dns <- dimnames(solve(i5., M53))),
dimnames(solve(as.matrix(i5.), as.matrix(M53)))) ,
identical(dns, dimnames(solve(i5., as.matrix(M53))))
)
}%dont
}
Matrix/man/matmult-methods.Rd 0000644 0001751 0000144 00000036666 14575137654 015764 0 ustar hornik users \name{matmult-methods}
\title{Matrix (Cross) Products (of Transpose)}
%
\docType{methods}
\keyword{algebra}
\keyword{arith}
\keyword{array}
%
\alias{\%*\%}
\alias{\%*\%-methods}
\alias{crossprod}
\alias{crossprod-methods}
\alias{tcrossprod}
\alias{tcrossprod-methods}
\alias{matmult-methods}
% %*%
\alias{\%*\%,ANY,Matrix-method}
\alias{\%*\%,ANY,sparseVector-method}
\alias{\%*\%,CsparseMatrix,CsparseMatrix-method}
\alias{\%*\%,CsparseMatrix,RsparseMatrix-method}
\alias{\%*\%,CsparseMatrix,TsparseMatrix-method}
\alias{\%*\%,CsparseMatrix,denseMatrix-method}
\alias{\%*\%,CsparseMatrix,diagonalMatrix-method}
\alias{\%*\%,CsparseMatrix,matrix-method}
\alias{\%*\%,CsparseMatrix,vector-method}
\alias{\%*\%,Matrix,ANY-method}
\alias{\%*\%,Matrix,indMatrix-method}
\alias{\%*\%,Matrix,pMatrix-method}
\alias{\%*\%,Matrix,sparseVector-method}
\alias{\%*\%,RsparseMatrix,CsparseMatrix-method}
\alias{\%*\%,RsparseMatrix,RsparseMatrix-method}
\alias{\%*\%,RsparseMatrix,TsparseMatrix-method}
\alias{\%*\%,RsparseMatrix,denseMatrix-method}
\alias{\%*\%,RsparseMatrix,diagonalMatrix-method}
\alias{\%*\%,RsparseMatrix,matrix-method}
\alias{\%*\%,RsparseMatrix,vector-method}
\alias{\%*\%,TsparseMatrix,CsparseMatrix-method}
\alias{\%*\%,TsparseMatrix,RsparseMatrix-method}
\alias{\%*\%,TsparseMatrix,TsparseMatrix-method}
\alias{\%*\%,TsparseMatrix,denseMatrix-method}
\alias{\%*\%,TsparseMatrix,diagonalMatrix-method}
\alias{\%*\%,TsparseMatrix,matrix-method}
\alias{\%*\%,TsparseMatrix,vector-method}
\alias{\%*\%,denseMatrix,CsparseMatrix-method}
\alias{\%*\%,denseMatrix,RsparseMatrix-method}
\alias{\%*\%,denseMatrix,TsparseMatrix-method}
\alias{\%*\%,denseMatrix,denseMatrix-method}
\alias{\%*\%,denseMatrix,diagonalMatrix-method}
\alias{\%*\%,denseMatrix,matrix-method}
\alias{\%*\%,denseMatrix,vector-method}
\alias{\%*\%,diagonalMatrix,CsparseMatrix-method}
\alias{\%*\%,diagonalMatrix,RsparseMatrix-method}
\alias{\%*\%,diagonalMatrix,TsparseMatrix-method}
\alias{\%*\%,diagonalMatrix,denseMatrix-method}
\alias{\%*\%,diagonalMatrix,diagonalMatrix-method}
\alias{\%*\%,diagonalMatrix,matrix-method}
\alias{\%*\%,diagonalMatrix,vector-method}
\alias{\%*\%,indMatrix,Matrix-method}
\alias{\%*\%,indMatrix,indMatrix-method}
\alias{\%*\%,indMatrix,matrix-method}
\alias{\%*\%,indMatrix,pMatrix-method}
\alias{\%*\%,indMatrix,vector-method}
\alias{\%*\%,matrix,CsparseMatrix-method}
\alias{\%*\%,matrix,RsparseMatrix-method}
\alias{\%*\%,matrix,TsparseMatrix-method}
\alias{\%*\%,matrix,denseMatrix-method}
\alias{\%*\%,matrix,diagonalMatrix-method}
\alias{\%*\%,matrix,indMatrix-method}
\alias{\%*\%,matrix,pMatrix-method}
\alias{\%*\%,matrix,sparseVector-method}
\alias{\%*\%,pMatrix,Matrix-method}
\alias{\%*\%,pMatrix,indMatrix-method}
\alias{\%*\%,pMatrix,matrix-method}
\alias{\%*\%,pMatrix,pMatrix-method}
\alias{\%*\%,pMatrix,vector-method}
\alias{\%*\%,sparseVector,ANY-method}
\alias{\%*\%,sparseVector,Matrix-method}
\alias{\%*\%,sparseVector,matrix-method}
\alias{\%*\%,sparseVector,sparseVector-method}
\alias{\%*\%,sparseVector,vector-method}
\alias{\%*\%,vector,CsparseMatrix-method}
\alias{\%*\%,vector,RsparseMatrix-method}
\alias{\%*\%,vector,TsparseMatrix-method}
\alias{\%*\%,vector,denseMatrix-method}
\alias{\%*\%,vector,diagonalMatrix-method}
\alias{\%*\%,vector,indMatrix-method}
\alias{\%*\%,vector,pMatrix-method}
\alias{\%*\%,vector,sparseVector-method}
% crossprod
\alias{crossprod,ANY,Matrix-method}
\alias{crossprod,ANY,sparseVector-method}
\alias{crossprod,CsparseMatrix,CsparseMatrix-method}
\alias{crossprod,CsparseMatrix,RsparseMatrix-method}
\alias{crossprod,CsparseMatrix,TsparseMatrix-method}
\alias{crossprod,CsparseMatrix,denseMatrix-method}
\alias{crossprod,CsparseMatrix,diagonalMatrix-method}
\alias{crossprod,CsparseMatrix,matrix-method}
\alias{crossprod,CsparseMatrix,missing-method}
\alias{crossprod,CsparseMatrix,vector-method}
\alias{crossprod,Matrix,ANY-method}
\alias{crossprod,Matrix,indMatrix-method}
\alias{crossprod,Matrix,pMatrix-method}
\alias{crossprod,Matrix,sparseVector-method}
\alias{crossprod,RsparseMatrix,CsparseMatrix-method}
\alias{crossprod,RsparseMatrix,RsparseMatrix-method}
\alias{crossprod,RsparseMatrix,TsparseMatrix-method}
\alias{crossprod,RsparseMatrix,denseMatrix-method}
\alias{crossprod,RsparseMatrix,diagonalMatrix-method}
\alias{crossprod,RsparseMatrix,matrix-method}
\alias{crossprod,RsparseMatrix,missing-method}
\alias{crossprod,RsparseMatrix,vector-method}
\alias{crossprod,TsparseMatrix,CsparseMatrix-method}
\alias{crossprod,TsparseMatrix,RsparseMatrix-method}
\alias{crossprod,TsparseMatrix,TsparseMatrix-method}
\alias{crossprod,TsparseMatrix,denseMatrix-method}
\alias{crossprod,TsparseMatrix,diagonalMatrix-method}
\alias{crossprod,TsparseMatrix,matrix-method}
\alias{crossprod,TsparseMatrix,missing-method}
\alias{crossprod,TsparseMatrix,vector-method}
\alias{crossprod,denseMatrix,CsparseMatrix-method}
\alias{crossprod,denseMatrix,RsparseMatrix-method}
\alias{crossprod,denseMatrix,TsparseMatrix-method}
\alias{crossprod,denseMatrix,denseMatrix-method}
\alias{crossprod,denseMatrix,diagonalMatrix-method}
\alias{crossprod,denseMatrix,matrix-method}
\alias{crossprod,denseMatrix,missing-method}
\alias{crossprod,denseMatrix,vector-method}
\alias{crossprod,diagonalMatrix,CsparseMatrix-method}
\alias{crossprod,diagonalMatrix,RsparseMatrix-method}
\alias{crossprod,diagonalMatrix,TsparseMatrix-method}
\alias{crossprod,diagonalMatrix,denseMatrix-method}
\alias{crossprod,diagonalMatrix,diagonalMatrix-method}
\alias{crossprod,diagonalMatrix,matrix-method}
\alias{crossprod,diagonalMatrix,missing-method}
\alias{crossprod,diagonalMatrix,vector-method}
\alias{crossprod,indMatrix,Matrix-method}
\alias{crossprod,indMatrix,matrix-method}
\alias{crossprod,indMatrix,missing-method}
\alias{crossprod,indMatrix,vector-method}
\alias{crossprod,matrix,CsparseMatrix-method}
\alias{crossprod,matrix,RsparseMatrix-method}
\alias{crossprod,matrix,TsparseMatrix-method}
\alias{crossprod,matrix,denseMatrix-method}
\alias{crossprod,matrix,diagonalMatrix-method}
\alias{crossprod,matrix,indMatrix-method}
\alias{crossprod,matrix,pMatrix-method}
\alias{crossprod,matrix,sparseVector-method}
\alias{crossprod,pMatrix,missing-method}
\alias{crossprod,pMatrix,pMatrix-method}
\alias{crossprod,sparseVector,ANY-method}
\alias{crossprod,sparseVector,Matrix-method}
\alias{crossprod,sparseVector,matrix-method}
\alias{crossprod,sparseVector,missing-method}
\alias{crossprod,sparseVector,sparseVector-method}
\alias{crossprod,sparseVector,vector-method}
\alias{crossprod,vector,CsparseMatrix-method}
\alias{crossprod,vector,RsparseMatrix-method}
\alias{crossprod,vector,TsparseMatrix-method}
\alias{crossprod,vector,denseMatrix-method}
\alias{crossprod,vector,diagonalMatrix-method}
\alias{crossprod,vector,indMatrix-method}
\alias{crossprod,vector,pMatrix-method}
\alias{crossprod,vector,sparseVector-method}
% tcrossprod
\alias{tcrossprod,ANY,Matrix-method}
\alias{tcrossprod,ANY,sparseVector-method}
\alias{tcrossprod,CsparseMatrix,CsparseMatrix-method}
\alias{tcrossprod,CsparseMatrix,RsparseMatrix-method}
\alias{tcrossprod,CsparseMatrix,TsparseMatrix-method}
\alias{tcrossprod,CsparseMatrix,denseMatrix-method}
\alias{tcrossprod,CsparseMatrix,diagonalMatrix-method}
\alias{tcrossprod,CsparseMatrix,matrix-method}
\alias{tcrossprod,CsparseMatrix,missing-method}
\alias{tcrossprod,CsparseMatrix,vector-method}
\alias{tcrossprod,Matrix,ANY-method}
\alias{tcrossprod,Matrix,indMatrix-method}
\alias{tcrossprod,Matrix,sparseVector-method}
\alias{tcrossprod,RsparseMatrix,CsparseMatrix-method}
\alias{tcrossprod,RsparseMatrix,RsparseMatrix-method}
\alias{tcrossprod,RsparseMatrix,TsparseMatrix-method}
\alias{tcrossprod,RsparseMatrix,denseMatrix-method}
\alias{tcrossprod,RsparseMatrix,diagonalMatrix-method}
\alias{tcrossprod,RsparseMatrix,matrix-method}
\alias{tcrossprod,RsparseMatrix,missing-method}
\alias{tcrossprod,RsparseMatrix,vector-method}
\alias{tcrossprod,TsparseMatrix,CsparseMatrix-method}
\alias{tcrossprod,TsparseMatrix,RsparseMatrix-method}
\alias{tcrossprod,TsparseMatrix,TsparseMatrix-method}
\alias{tcrossprod,TsparseMatrix,denseMatrix-method}
\alias{tcrossprod,TsparseMatrix,diagonalMatrix-method}
\alias{tcrossprod,TsparseMatrix,matrix-method}
\alias{tcrossprod,TsparseMatrix,missing-method}
\alias{tcrossprod,TsparseMatrix,vector-method}
\alias{tcrossprod,denseMatrix,CsparseMatrix-method}
\alias{tcrossprod,denseMatrix,RsparseMatrix-method}
\alias{tcrossprod,denseMatrix,TsparseMatrix-method}
\alias{tcrossprod,denseMatrix,denseMatrix-method}
\alias{tcrossprod,denseMatrix,diagonalMatrix-method}
\alias{tcrossprod,denseMatrix,matrix-method}
\alias{tcrossprod,denseMatrix,missing-method}
\alias{tcrossprod,denseMatrix,vector-method}
\alias{tcrossprod,diagonalMatrix,CsparseMatrix-method}
\alias{tcrossprod,diagonalMatrix,RsparseMatrix-method}
\alias{tcrossprod,diagonalMatrix,TsparseMatrix-method}
\alias{tcrossprod,diagonalMatrix,denseMatrix-method}
\alias{tcrossprod,diagonalMatrix,diagonalMatrix-method}
\alias{tcrossprod,diagonalMatrix,matrix-method}
\alias{tcrossprod,diagonalMatrix,missing-method}
\alias{tcrossprod,diagonalMatrix,vector-method}
\alias{tcrossprod,indMatrix,Matrix-method}
\alias{tcrossprod,indMatrix,matrix-method}
\alias{tcrossprod,indMatrix,missing-method}
\alias{tcrossprod,indMatrix,vector-method}
\alias{tcrossprod,matrix,CsparseMatrix-method}
\alias{tcrossprod,matrix,RsparseMatrix-method}
\alias{tcrossprod,matrix,TsparseMatrix-method}
\alias{tcrossprod,matrix,denseMatrix-method}
\alias{tcrossprod,matrix,diagonalMatrix-method}
\alias{tcrossprod,matrix,indMatrix-method}
\alias{tcrossprod,matrix,sparseVector-method}
\alias{tcrossprod,pMatrix,Matrix-method}
\alias{tcrossprod,pMatrix,matrix-method}
\alias{tcrossprod,pMatrix,missing-method}
\alias{tcrossprod,pMatrix,pMatrix-method}
\alias{tcrossprod,pMatrix,vector-method}
\alias{tcrossprod,sparseVector,ANY-method}
\alias{tcrossprod,sparseVector,Matrix-method}
\alias{tcrossprod,sparseVector,matrix-method}
\alias{tcrossprod,sparseVector,missing-method}
\alias{tcrossprod,sparseVector,sparseVector-method}
\alias{tcrossprod,sparseVector,vector-method}
\alias{tcrossprod,vector,CsparseMatrix-method}
\alias{tcrossprod,vector,RsparseMatrix-method}
\alias{tcrossprod,vector,TsparseMatrix-method}
\alias{tcrossprod,vector,denseMatrix-method}
\alias{tcrossprod,vector,diagonalMatrix-method}
\alias{tcrossprod,vector,indMatrix-method}
\alias{tcrossprod,vector,sparseVector-method}
%
\description{
The basic matrix product, \code{\%*\%} is implemented for all our
\code{\linkS4class{Matrix}} and also for
\code{\linkS4class{sparseVector}} classes, fully analogously to \R's
base \code{matrix} and vector objects.
The functions \code{\link{crossprod}} and \code{\link{tcrossprod}} are
matrix products or \dQuote{cross products}, ideally implemented
efficiently without computing \code{\link{t}(.)}'s unnecessarily.
They also return \code{\linkS4class{symmetricMatrix}} classed
matrices when easily detectable, e.g., in \code{crossprod(m)}, the one
argument case.
\code{tcrossprod()} takes the cross-product of the transpose of a matrix.
\code{tcrossprod(x)} is formally equivalent to, but faster than, the
call \code{x \%*\% t(x)}, and so is \code{tcrossprod(x, y)} instead of
\code{x \%*\% t(y)}.
\emph{Boolean} matrix products are computed via either
\code{\link{\%&\%}} or \code{boolArith = TRUE}.
}
\usage{
\S4method{\%*\%}{CsparseMatrix,diagonalMatrix}(x, y)
\S4method{crossprod}{CsparseMatrix,diagonalMatrix}(x, y = NULL, boolArith = NA, \dots)
## .... and for many more signatures
\S4method{tcrossprod}{TsparseMatrix,missing}(x, y = NULL, boolArith = NA, \dots)
## .... and for many more signatures
}
\arguments{
\item{x}{a matrix-like object}
\item{y}{a matrix-like object, or for \code{[t]crossprod()}
\code{NULL} (by default); the latter case is formally equivalent to
\code{y = x}.}
\item{boolArith}{\code{\link{logical}}, i.e., \code{NA}, \code{TRUE},
or \code{FALSE}. If true the result is (coerced to) a pattern
matrix, i.e., \code{"\linkS4class{nMatrix}"}, unless there are
\code{NA} entries and the result will be a
\code{"\linkS4class{lMatrix}"}. If false the result is (coerced to)
numeric. When \code{NA}, currently the default, the
result is a pattern matrix when \code{x} and \code{y} are
\code{"\linkS4class{nsparseMatrix}"} and numeric otherwise.}
\item{\dots}{potentially more arguments passed to and from methods.}
}
\details{
For some classes in the \code{Matrix} package, such as
\code{\linkS4class{dgCMatrix}}, it is much faster to calculate the
cross-product of the transpose directly instead of calculating the
transpose first and then its cross-product.
\code{boolArith = TRUE} for regular (\dQuote{non cross}) matrix
products, \code{\%*\%} cannot be specified. Instead, we provide the
\code{\link{\%&\%}} operator for \emph{boolean} matrix products.
}
\note{
\code{boolArith = TRUE}, \code{FALSE} or \code{NA} has been newly
introduced for \pkg{Matrix} 1.2.0 (March 2015). Its implementation
has still not been tested extensively. Notably the behaviour for
sparse matrices with \code{x} slots containing extra zeros had not been
documented previously, see the \code{\link{\%&\%}} help page.
Currently, \code{boolArith = TRUE} is implemented via
\code{\linkS4class{CsparseMatrix}} coercions which may be quite
inefficient for dense matrices. Contributions for efficiency
improvements are welcome.
}
\value{
A \code{\linkS4class{Matrix}} object, in the one argument case
of an appropriate \emph{symmetric} matrix class, i.e., inheriting from
\code{\linkS4class{symmetricMatrix}}.
}
\section{Methods}{
\describe{
\item{\%*\%}{\code{signature(x = "dgeMatrix", y = "dgeMatrix")}:
Matrix multiplication; ditto for several other signature
combinations, see \code{showMethods("\%*\%", class = "dgeMatrix")}.}
\item{\%*\%}{\code{signature(x = "dtrMatrix", y = "matrix")} and other
signatures (use \code{showMethods("\%*\%", class="dtrMatrix")}):
matrix multiplication. Multiplication of (matching) triangular
matrices now should remain triangular (in the sense of class
\linkS4class{triangularMatrix}).}
\item{crossprod}{\code{signature(x = "dgeMatrix", y = "dgeMatrix")}:
ditto for several other signatures, use
\code{showMethods("crossprod", class = "dgeMatrix")}, matrix
crossproduct, an efficient version of \code{t(x) \%*\% y}.}
\item{crossprod}{\code{signature(x = "CsparseMatrix", y = "missing")}
returns \code{t(x) \%*\% x} as an \code{dsCMatrix} object.}
\item{crossprod}{\code{signature(x = "TsparseMatrix", y = "missing")}
returns \code{t(x) \%*\% x} as an \code{dsCMatrix} object.}
\item{crossprod,tcrossprod}{\code{signature(x = "dtrMatrix", y =
"matrix")} and other signatures, see \code{"\%*\%"} above.}
}%{describe}
}
\seealso{
\code{\link[base]{tcrossprod}} in \R's base, and
\code{\link{crossprod}} and \code{\link{\%*\%}}.
\pkg{Matrix} package \code{\link{\%&\%}} for boolean matrix product
methods.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
library(utils, pos = "package:base", verbose = FALSE)
}
## A random sparse "incidence" matrix :
m <- matrix(0, 400, 500)
set.seed(12)
m[runif(314, 0, length(m))] <- 1
mm <- as(m, "CsparseMatrix")
object.size(m) / object.size(mm) # smaller by a factor of > 200
## tcrossprod() is very fast:
system.time(tCmm <- tcrossprod(mm))# 0 (PIII, 933 MHz)
system.time(cm <- crossprod(t(m))) # 0.16
system.time(cm. <- tcrossprod(m)) # 0.02
stopifnot(cm == as(tCmm, "matrix"))
## show sparse sub matrix
tCmm[1:16, 1:30]
}
Matrix/man/nnzero-methods.Rd 0000644 0001751 0000144 00000006520 14575137654 015576 0 ustar hornik users \name{nnzero-methods}
\title{The Number of Non-Zero Values of a Matrix}
%
\docType{methods}
\keyword{array}
\keyword{logic}
\keyword{methods}
%
\alias{nnzero}
\alias{nnzero-methods}
%
\alias{nnzero,ANY-method}
\alias{nnzero,CHMfactor-method}
\alias{nnzero,denseMatrix-method}
\alias{nnzero,diagonalMatrix-method}
\alias{nnzero,indMatrix-method}
\alias{nnzero,sparseMatrix-method}
\alias{nnzero,vector-method}
%
\description{
Returns the number of non-zero values of a numeric-like \R object, and
in particular an object \code{x} inheriting from class
\code{\linkS4class{Matrix}}.
}
\usage{
nnzero(x, na.counted = NA)
}
\arguments{
\item{x}{an \R object, typically inheriting from class
\code{\linkS4class{Matrix}} or \code{\link{numeric}}.}
\item{na.counted}{a \code{\link{logical}} describing how
\code{\link{NA}}s should be counted. There are three possible
settings for \code{na.counted}:
\describe{
\item{TRUE}{\code{NA}s \emph{are} counted as non-zero (since
\dQuote{they are not zero}).}
\item{NA}{(default)the result will be \code{NA} if there are \code{NA}'s in
\code{x} (since \dQuote{NA's are not known, i.e., \emph{may be} zero}).}
\item{FALSE}{\code{NA}s are \emph{omitted} from \code{x} before
the non-zero entries are counted.}
}
For sparse matrices, you may often want to use \code{na.counted = TRUE}.
}
}
% \details{
% }
\section{Methods}{
\describe{
\item{\code{signature(x = "ANY")}}{the default method for
non-\code{\linkS4class{Matrix}} class objects, simply counts the
number \code{0}s in \code{x}, counting \code{NA}'s depending on
the \code{na.counted} argument, see above.}
\item{\code{signature(x = "denseMatrix")}}{conceptually the same as
for traditional \code{\link{matrix}} objects, care has to be taken
for \code{"\linkS4class{symmetricMatrix}"} objects.}
\item{\code{signature(x = "diagonalMatrix")}, and
\code{signature(x = "indMatrix")}}{fast simple methods for these
special \code{"sparseMatrix"} classes.}
\item{\code{signature(x = "sparseMatrix")}}{typically, the most
interesting method, also carefully taking
\code{"\linkS4class{symmetricMatrix}"} objects into account.}
}
}
\value{
the number of non zero entries in \code{x} (typically
\code{\link{integer}}).
Note that for a \emph{symmetric} sparse matrix \code{S} (i.e., inheriting from
class \code{\linkS4class{symmetricMatrix}}), \code{nnzero(S)} is
typically \emph{twice} the \code{length(S@x)}.
}
%\author{Martin}
\seealso{The \code{\linkS4class{Matrix}} class also has a
\code{\link{length}} method; typically, \code{length(M)} is much
larger than \code{nnzero(M)} for a sparse matrix M, and the latter is
a better indication of the \emph{size} of \code{M}.
\code{\link{drop0}}, \code{\link{zapsmall}}.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
m <- Matrix(0+1:28, nrow = 4)
m[-3,c(2,4:5,7)] <- m[ 3, 1:4] <- m[1:3, 6] <- 0
(mT <- as(m, "TsparseMatrix"))
nnzero(mT)
(S <- crossprod(mT))
nnzero(S)
str(S) # slots are smaller than nnzero()
stopifnot(nnzero(S) == sum(as.matrix(S) != 0))# failed earlier
data(KNex, package = "Matrix")
M <- KNex$mm
class(M)
dim(M)
length(M); stopifnot(length(M) == prod(dim(M)))
nnzero(M) # more relevant than length
## the above are also visible from
str(M)
}
Matrix/man/abIseq.Rd 0000644 0001751 0000144 00000003567 14422605232 014015 0 ustar hornik users \name{abIseq}
\title{Sequence Generation of "abIndex", Abstract Index Vectors}
%
\keyword{manip}
\keyword{utilities}
%
\alias{abIseq}
\alias{abIseq1}
%
\alias{c.abIndex}
%
\description{
Generation of abstract index vectors, i.e., objects of class
\code{"\linkS4class{abIndex}"}.
\code{abIseq()} is designed to work entirely like \code{\link{seq}},
but producing \code{"abIndex"} vectors.\cr
\code{abIseq1()} is its basic building block, where
\code{abIseq1(n,m)} corresponds to \code{n:m}.
\code{c(x, ...)} will return an \code{"abIndex"} vector, when \code{x}
is one.
}
\usage{
abIseq1(from = 1, to = 1)
abIseq (from = 1, to = 1, by = ((to - from)/(length.out - 1)),
length.out = NULL, along.with = NULL)
\method{c}{abIndex}(\dots)
}
\arguments{
\item{from, to}{the starting and (maximal) end value of the sequence.}
\item{by}{number: increment of the sequence.}
\item{length.out}{desired length of the sequence. A
non-negative number, which for \code{seq} and \code{seq.int} will be
rounded up if fractional.}
\item{along.with}{take the length from the length of this argument.}
\item{\dots}{in general an arbitrary number of \R objects; here,
when the first is an \code{"\linkS4class{abIndex}"} vector, these
arguments will be concatenated to a new \code{"abIndex"} object.}
}
%\author{Martin Maechler}
% \details{
% }
\value{
An abstract index vector, i.e., object of class
\code{"\linkS4class{abIndex}"}.
}
% \references{
% %% ~put references to the literature/web site here ~
% }
\seealso{
the class \code{\linkS4class{abIndex}} documentation;
\code{\link{rep2abI}()} for another constructor;
\code{\link{rle}} (\pkg{base}).
}
\examples{
stopifnot(identical(-3:20,
as(abIseq1(-3,20), "vector")))
try( ## (arithmetic) not yet implemented
abIseq(1, 50, by = 3)
)
%% FIXME: add / exchange with ../tests/abIndex-tsts.R
}
Matrix/man/image-methods.Rd 0000644 0001751 0000144 00000016036 14446607050 015335 0 ustar hornik users \name{image-methods}
\title{Methods for image() in Package 'Matrix'}
%
\docType{methods}
\keyword{hplot}
\keyword{methods}
%
\alias{image}
\alias{image-methods}
%
\alias{image,ANY-method}
\alias{image,CHMfactor-method}
\alias{image,Matrix-method}
\alias{image,dgTMatrix-method}
%
\description{
Methods for function \code{\link[graphics]{image}} in package
\pkg{Matrix}. An image of a matrix simply color codes all matrix
entries and draws the \eqn{n\times m}{n x m} matrix using an
\eqn{n\times m}{n x m} grid of (colored) rectangles.
The \pkg{Matrix} package \code{image} methods are based on
\code{\link[lattice]{levelplot}()} from package \pkg{lattice}; hence
these methods return an \dQuote{object} of class \code{"trellis"},
producing a graphic when (auto-) \code{\link{print}()}ed.
}
\usage{ % want \usage{} since we have many "surprising arguments"
\S4method{image}{dgTMatrix}(x,
xlim = c(1, di[2]),
ylim = c(di[1], 1), aspect = "iso",
sub = sprintf("Dimensions: \%d x \%d", di[1], di[2]),
xlab = "Column", ylab = "Row", cuts = 15,
useRaster = FALSE,
useAbs = NULL, colorkey = !useAbs,
col.regions = NULL,
lwd = NULL, border.col = NULL, \dots)
}
\arguments{
\item{x}{a Matrix object, i.e., fulfilling \code{\link{is}(x, "Matrix")}.}
\item{xlim, ylim}{x- and y-axis limits; may be used to \dQuote{zoom
into} matrix. Note that \eqn{x,y} \dQuote{feel reversed}:
\code{ylim} is for the rows (= 1st index) and \code{xlim} for the
columns (= 2nd index). For convenience, when the limits are integer
valued, they are both extended by \code{0.5}; also, \code{ylim} is
always used decreasingly.}
\item{aspect}{aspect ratio specified as number (y/x) or string;
see \code{\link[lattice]{levelplot}}.}
\item{sub, xlab, ylab}{axis annotation with sensible defaults;
see \code{\link{plot.default}}.}
\item{cuts}{number of levels the range of matrix values would be
divided into.}
\item{useRaster}{logical indicating if raster graphics should be used
(instead of the tradition rectangle vector drawing). If true,
\code{\link[lattice]{panel.levelplot.raster}} (from \pkg{lattice}
package) is used, and the colorkey is also done via rasters, see
also \code{\link[lattice]{levelplot}} and possibly
\code{\link[grid]{grid.raster}}.
Note that using raster graphics may often be faster, but can be slower,
depending on the matrix dimensions and the graphics device (dimensions).}
\item{useAbs}{logical indicating if \code{\link{abs}(x)} should be
shown; if \code{TRUE}, the former (implicit) default, the default
\code{col.regions} will be \code{\link{grey}} colors (and no
\code{colorkey} drawn). The default is \code{FALSE} unless the
matrix has no negative entries.}
\item{colorkey}{logical indicating if a color key aka \sQuote{legend}
should be produced. Default is to draw one, unless \code{useAbs} is
true. You can also specify a \code{\link{list}}, see
\code{\link[lattice]{levelplot}}, such as\code{list(raster=TRUE)} in
the case of rastering.}
\item{col.regions}{vector of gradually varying colors; see
\code{\link[lattice]{levelplot}}.}
\item{lwd}{(only used when \code{useRaster} is false:) non-negative
number or \code{NULL} (default), specifying the line-width of the
rectangles of each non-zero matrix entry (drawn by
\code{\link[grid]{grid.rect}}). The default depends on the matrix
dimension and the device size.}
\item{border.col}{color for the border of each rectangle. \code{NA}
means no border is drawn. When \code{NULL} as by default,
\code{border.col <- if(lwd < .01) NA else NULL} is used.
Consider using an opaque color instead of \code{NULL} which
corresponds to \code{grid::\link[grid]{get.gpar}("col")}.}
\item{\dots}{further arguments passed to methods and
\code{\link[lattice]{levelplot}}, notably \code{at} for specifying
(possibly non equidistant) cut values for dividing the matrix
values (superseding \code{cuts} above).}% FIXME? example *using* at=..
}
\section{Methods}{
All methods currently end up calling the method for the
\code{\linkS4class{dgTMatrix}} class.
Use \code{showMethods(image)} to list them all.
}
\value{
as all \pkg{lattice} graphics functions, \code{image()}
returns a \code{"trellis"} object, effectively the result of
\code{\link[lattice]{levelplot}()}.
}
\seealso{
\code{\link[lattice]{levelplot}}, and
\code{\link[lattice]{print.trellis}} from package \pkg{lattice}.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(grDevices, pos = "package:base", verbose = FALSE)
library( utils, pos = "package:base", verbose = FALSE)
}
showMethods(image)
## And if you want to see the method definitions:
showMethods(image, includeDefs = TRUE, inherited = FALSE)
\dontshow{ % warnings should not happen here, notably when print()
op <- options(warn = 2)
}
data(CAex, package = "Matrix")
image(CAex, main = "image(CAex)") -> imgC; imgC
stopifnot(!is.null(leg <- imgC$legend), is.list(leg$right)) # failed for 2 days ..
image(CAex, useAbs=TRUE, main = "image(CAex, useAbs=TRUE)")
cCA <- Cholesky(crossprod(CAex), Imult = .01)
## See ?print.trellis --- place two image() plots side by side:
print(image(cCA, main="Cholesky(crossprod(CAex), Imult = .01)"),
split=c(x=1,y=1,nx=2, ny=1), more=TRUE)
print(image(cCA, useAbs=TRUE),
split=c(x=2,y=1,nx=2,ny=1))
data(USCounties, package = "Matrix")
image(USCounties)# huge
image(sign(USCounties))## just the pattern
# how the result looks, may depend heavily on
# the device, screen resolution, antialiasing etc
# e.g. x11(type="Xlib") may show very differently than cairo-based
## Drawing borders around each rectangle;
# again, viewing depends very much on the device:
image(USCounties[1:400,1:200], lwd=.1)
## Using (xlim,ylim) has advantage : matrix dimension and (col/row) indices:
image(USCounties, c(1,200), c(1,400), lwd=.1)
image(USCounties, c(1,300), c(1,200), lwd=.5 )
image(USCounties, c(1,300), c(1,200), lwd=.01)
## These 3 are all equivalent :
(I1 <- image(USCounties, c(1,100), c(1,100), useAbs=FALSE))
I2 <- image(USCounties, c(1,100), c(1,100), useAbs=FALSE, border.col=NA)
I3 <- image(USCounties, c(1,100), c(1,100), useAbs=FALSE, lwd=2, border.col=NA)
stopifnot(all.equal(I1, I2, check.environment=FALSE),
all.equal(I2, I3, check.environment=FALSE))
## using an opaque border color
image(USCounties, c(1,100), c(1,100), useAbs=FALSE, lwd=3, border.col = adjustcolor("skyblue", 1/2))
\dontshow{options(op)}
if(interactive() || nzchar(Sys.getenv("R_MATRIX_CHECK_EXTRA"))) {
## Using raster graphics: For PDF this would give a 77 MB file,
## however, for such a large matrix, this is typically considerably
## *slower* (than vector graphics rectangles) in most cases :
if(doPNG <- !dev.interactive())
png("image-USCounties-raster.png", width=3200, height=3200)
image(USCounties, useRaster = TRUE) # should not suffer from anti-aliasing
if(doPNG)
dev.off()
## and now look at the *.png image in a viewer you can easily zoom in and out
}#only if(doExtras)
}
Matrix/man/sparseVector-class.Rd 0000644 0001751 0000144 00000024540 14575137654 016407 0 ustar hornik users \name{sparseVector-class}
\title{Sparse Vector Classes}
%
\docType{class}
\keyword{classes}
\keyword{manip}
%
\alias{sparseVector-class}
\alias{nsparseVector-class}
\alias{lsparseVector-class}
\alias{isparseVector-class}
\alias{dsparseVector-class}
\alias{zsparseVector-class}
% sparse
\alias{!,sparseVector-method}
\alias{Arith,sparseVector,ddenseMatrix-method}
\alias{Arith,sparseVector,dgeMatrix-method}
\alias{Arith,sparseVector,sparseVector-method}
\alias{Logic,sparseVector,dMatrix-method}
\alias{Logic,sparseVector,lMatrix-method}
\alias{Logic,sparseVector,nMatrix-method}
\alias{Logic,sparseVector,sparseVector-method}
\alias{Math,sparseVector-method}
\alias{Math2,sparseVector-method}
\alias{Ops,ANY,sparseVector-method}
\alias{Ops,sparseVector,ANY-method}
\alias{Ops,sparseVector,Matrix-method}
\alias{Ops,sparseVector,sparseVector-method}
\alias{Ops,sparseVector,vector-method}
\alias{Ops,vector,sparseVector-method}
\alias{Summary,sparseVector-method}
\alias{as.array,sparseVector-method}
\alias{as.complex,sparseVector-method}
\alias{as.integer,sparseVector-method}
\alias{as.logical,sparseVector-method}
\alias{as.matrix,sparseVector-method}
\alias{as.numeric,sparseVector-method}
\alias{as.vector,sparseVector-method}
\alias{coerce,ANY,sparseVector-method}
\alias{coerce,matrix,sparseVector-method}
\alias{coerce,sparseVector,CsparseMatrix-method}
\alias{coerce,sparseVector,Matrix-method}
\alias{coerce,sparseVector,RsparseMatrix-method}
\alias{coerce,sparseVector,TsparseMatrix-method}
\alias{coerce,sparseVector,denseMatrix-method}
\alias{coerce,sparseVector,dsparseVector-method}
\alias{coerce,sparseVector,generalMatrix-method}
\alias{coerce,sparseVector,isparseVector-method}
\alias{coerce,sparseVector,lsparseVector-method}
\alias{coerce,sparseVector,nsparseVector-method}
\alias{coerce,sparseVector,sparseMatrix-method}
\alias{coerce,sparseVector,unpackedMatrix-method}
\alias{coerce,sparseVector,zsparseVector-method}
\alias{coerce,vector,dsparseVector-method}
\alias{coerce,vector,isparseVector-method}
\alias{coerce,vector,lsparseVector-method}
\alias{coerce,vector,nsparseVector-method}
\alias{coerce,vector,sparseVector-method}
\alias{coerce,vector,zsparseVector-method}
\alias{diff,sparseVector-method}
\alias{dim<-,sparseVector-method}
\alias{head,sparseVector-method}
\alias{initialize,sparseVector-method}
\alias{length,sparseVector-method}
\alias{log,sparseVector-method}
\alias{mean,sparseVector-method}
\alias{rep,sparseVector-method}
\alias{show,sparseVector-method}
\alias{sort,sparseVector-method}
\alias{t,sparseVector-method}
\alias{tail,sparseVector-method}
\alias{toeplitz,sparseVector-method}
\alias{zapsmall,sparseVector-method}
% nsparse
\alias{!,nsparseVector-method}
\alias{which,nsparseVector-method}
% lsparse
\alias{!,lsparseVector-method}
\alias{Logic,lsparseVector,lsparseVector-method}
\alias{which,lsparseVector-method}
% isparse
% dsparse
\alias{-,dsparseVector,missing-method}
\alias{Arith,dsparseVector,dsparseVector-method}
% zsparse
%
\alias{c.sparseVector}
%
\description{Sparse Vector Classes: The virtual mother class
\code{"sparseVector"} has the five actual daughter classes
\code{"dsparseVector"}, \code{"isparseVector"},
\code{"lsparseVector"}, \code{"nsparseVector"}, and
\code{"zsparseVector"}, where we've mainly implemented methods for
the \code{d*}, \code{l*} and \code{n*} ones.
}
\section{Slots}{
\describe{
\item{\code{length}:}{class \code{"numeric"} - the \code{\link{length}}
of the sparse vector. Note that \code{"numeric"} can be
considerably larger than the maximal \code{"integer"},
\code{\link{.Machine}$integer.max}, on purpose.}
\item{\code{i}:}{class \code{"numeric"} - the (1-based) indices of
the non-zero entries. Must \emph{not} be \code{NA} and strictly
sorted increasingly.
Note that \code{"integer"} is \dQuote{part of} \code{"numeric"},
and can (and often will) be used for non-huge sparseVectors.}
\item{\code{x}:}{(for all but \code{"nsparseVector"}):
the non-zero entries. This is of class \code{"numeric"} for class
\code{"dsparseVector"}, \code{"logical"} for class
\code{"lsparseVector"}, etc.}
}
}
\section{Methods}{
\describe{
\item{length}{\code{signature(x = "sparseVector")}: simply extracts
the \code{length} slot.}
\item{show}{\code{signature(object = "sparseVector")}: The
\code{\link{show}} method for sparse vectors prints
\emph{\dQuote{structural}} zeroes as \code{"."} using the
non-exported \code{prSpVector} function which allows further
customization such as replacing \code{"."} by \code{" "} (blank).
Note that \code{\link{options}(max.print)} will influence how many
entries of large sparse vectors are printed at all.}
\item{as.vector}{\code{signature(x = "sparseVector", mode = "character")}
coerces sparse vectors to \dQuote{regular}, i.e., atomic vectors.
This is the same as \code{as(x, "vector")}.}
\item{as}{..: see \code{coerce} below}
\item{coerce}{\code{signature(from = "sparseVector", to = "sparseMatrix")}, and}
\item{coerce}{\code{signature(from = "sparseMatrix", to = "sparseVector")},
etc: coercions to and from sparse matrices (\code{\linkS4class{sparseMatrix}}) are
provided and work analogously as in standard \R, i.e., a vector is
coerced to a 1-column matrix.}
\item{dim<-}{\code{signature(x = "sparseVector", value = "integer")}
coerces a sparse vector to a sparse Matrix, i.e., an object
inheriting from \code{\linkS4class{sparseMatrix}}, of the
appropriate dimension.}
\item{head}{\code{signature(x = "sparseVector")}: as with \R's
(package \pkg{util}) \code{\link{head}}, \code{head(x,n)} (for
\eqn{n >= 1}) is equivalent to \code{x[1:n]}, but here can be much
more efficient, see the example.}
\item{tail}{\code{signature(x = "sparseVector")}: analogous to
\code{\link{head}}, see above.}
\item{toeplitz}{\code{signature(x = "sparseVector")}: as
\code{\link[stats]{toeplitz}(x)}, produce the \eqn{n \times n}
Toeplitz matrix from \code{x}, where \code{n = length(x)}.}
\item{rep}{\code{signature(x = "sparseVector")} repeat \code{x},
with the same argument list \code{(x, times, length.out, each,
...)} as the default method for rep().}
\item{which}{\code{signature(x = "nsparseVector")} and}
\item{which}{\code{signature(x = "lsparseVector")} return the
indices of the non-zero entries (which is trivial for sparse vectors).}
\item{Ops}{\code{signature(e1 = "sparseVector", e2 = "*")}: define
arithmetic, compare and logic operations, (see
\code{\link[=S4groupGeneric]{Ops}}).}
\item{Summary}{\code{signature(x = "sparseVector")}: define
all the \code{\link[=S4groupGeneric]{Summary}} methods.}
\item{is.na, is.finite, is.infinite}{\code{(x = "sparseVector")}, and}
\item{is.na, is.finite, is.infinite}{\code{(x = "nsparseVector")}:
return \code{\link{logical}} or \code{"nsparseVector"} of the same
length as \code{x}, indicating if/where \code{x} is
\code{\link{NA}} (or \code{NaN}), finite or infinite, entirely
analogously to the corresponding base \R functions.}
\item{zapsmall}{\code{signature(x = "sparseVectors")}: typically used for
numeric sparse vector: \code{\link{round}()} entries
such that (relatively) very small entries become zero exactly.}
}
\code{c.sparseVector()} is an S3 method for all
\code{"sparseVector"}s, but automatic dispatch only happens for the
first argument, so it is useful also as regular \R function, see the
examples.
}
\seealso{
\code{\link{sparseVector}()} for friendly construction of sparse
vectors (apart from \code{as(*, "sparseVector")}).
}
%\author{Martin}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
getClass("sparseVector")
getClass("dsparseVector")
sx <- c(0,0,3, 3.2, 0,0,0,-3:1,0,0,2,0,0,5,0,0)
(ss <- as(sx, "sparseVector"))
ix <- as.integer(round(sx))
(is <- as(ix, "sparseVector")) ## an "isparseVector" (!)
(ns <- sparseVector(i= c(7, 3, 2), length = 10)) # "nsparseVector"
## rep() works too:
(ri <- rep(is, length.out= 25))
## Using `dim<-` as in base R :
r <- ss
dim(r) <- c(4,5) # becomes a sparse Matrix:
r
## or coercion (as as.matrix() in base R):
as(ss, "Matrix")
stopifnot(all(ss == print(as(ss, "CsparseMatrix"))))
## currently has "non-structural" FALSE -- printing as ":"
(lis <- is & FALSE)
(nn <- is[is == 0]) # all "structural" FALSE
## NA-case
sN <- sx; sN[4] <- NA
(svN <- as(sN, "sparseVector"))
v <- as(c(0,0,3, 3.2, rep(0,9),-3,0,-1, rep(0,20),5,0),
"sparseVector")
v <- rep(rep(v, 50), 5000)
set.seed(1); v[sample(v@i, 1e6)] <- 0
str(v)
% Formal class 'dsparseVector' [package "Matrix"] with 3 slots
% ..@ x : num [1:250000] 3.2 -1 -3 3 5 3.2 -3 3 -1 5 ...
% ..@ length: int 9500000
% ..@ i : int [1:250000] 4 16 52 155 189 194 204 231 244 265 ...
system.time(for(i in 1:4) hv <- head(v, 1e6))
## user system elapsed
## 0.033 0.000 0.032
system.time(for(i in 1:4) h2 <- v[1:1e6])
## user system elapsed
## 1.317 0.000 1.319
stopifnot(identical(hv, h2),
identical(is | FALSE, is != 0),
validObject(svN), validObject(lis), as.logical(is.na(svN[4])),
identical(is^2 > 0, is & TRUE),
all(!lis), !any(lis), length(nn@i) == 0, !any(nn), all(!nn),
sum(lis) == 0, !prod(lis), range(lis) == c(0,0))
## create and use the t(.) method:
t(x20 <- sparseVector(c(9,3:1), i=c(1:2,4,7), length=20))
(T20 <- toeplitz(x20))
stopifnot(is(T20, "symmetricMatrix"), is(T20, "sparseMatrix"),
identical(unname(as.matrix(T20)),
toeplitz(as.vector(x20))))
## c() method for "sparseVector" - also available as regular function
(c1 <- c(x20, 0,0,0, -10*x20))
(c2 <- c(ns, is, FALSE))
(c3 <- c(ns, !ns, TRUE, NA, FALSE))
(c4 <- c(ns, rev(ns)))
## here, c() would produce a list {not dispatching to c.sparseVector()}
(c5 <- c.sparseVector(0,0, x20))
## checking (consistency)
.v <- as.vector
.s <- function(v) as(v, "sparseVector")
stopifnot(exprs = {
all.equal(c1, .s(c(.v(x20), 0,0,0, -10*.v(x20))), tol = 0)
all.equal(c2, .s(c(.v(ns), .v(is), FALSE)), tol = 0)
all.equal(c3, .s(c(.v(ns), !.v(ns), TRUE, NA, FALSE)), tol = 0)
all.equal(c4, .s(c(.v(ns), rev(.v(ns)))), tol = 0,
check.class = FALSE)
all.equal(c5, .s(c(0,0, .v(x20))), tol = 0)
})
}
Matrix/man/dgCMatrix-class.Rd 0000644 0001751 0000144 00000005105 14446607050 015572 0 ustar hornik users \name{dgCMatrix-class}
\title{Compressed, sparse, column-oriented numeric matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{dgCMatrix-class}
\alias{Arith,dgCMatrix,dgCMatrix-method}
\alias{Arith,dgCMatrix,logical-method}
\alias{Arith,dgCMatrix,numeric-method}
\alias{Arith,logical,dgCMatrix-method}
\alias{Arith,numeric,dgCMatrix-method}
\alias{coerce,matrix,dgCMatrix-method}
\alias{determinant,dgCMatrix,logical-method}
%
\description{The \code{dgCMatrix} class is a class of sparse numeric
matrices in the compressed, sparse, column-oriented format. In this
implementation the non-zero elements in the columns are sorted into
increasing row order. \code{dgCMatrix} is the
\emph{\dQuote{standard}} class for sparse numeric matrices in the
\pkg{Matrix} package.
}
\section{Objects from the Class}{
Objects can be created by calls of the form \code{new("dgCMatrix",
...)}, more typically via \code{as(*, "CsparseMatrix")} or similar.
Often however, more easily via \code{\link{Matrix}(*, sparse = TRUE)},
or most efficiently via \code{\link{sparseMatrix}()}.
}
\section{Slots}{
\describe{
\item{\code{x}:}{Object of class \code{"numeric"} - the non-zero
elements of the matrix.}
\item{\dots}{all other slots are inherited from the superclass
\code{"\linkS4class{CsparseMatrix}"}.
}
}
}
\section{Methods}{
Matrix products (e.g., \link{crossprod-methods}), and (among other)
\describe{
\item{coerce}{\code{signature(from = "matrix", to = "dgCMatrix")}}
\item{diag}{\code{signature(x = "dgCMatrix")}: returns the diagonal
of \code{x}}
\item{dim}{\code{signature(x = "dgCMatrix")}: returns the dimensions
of \code{x}}
\item{image}{\code{signature(x = "dgCMatrix")}: plots an image of
\code{x} using the \code{\link[lattice]{levelplot}} function}
\item{solve}{\code{signature(a = "dgCMatrix", b = "...")}:
see \code{\link{solve-methods}}, notably the extra argument
\code{sparse}.}
\item{lu}{\code{signature(x = "dgCMatrix")}: computes the LU
decomposition of a square \code{dgCMatrix} object}
}
}
%\references{}
%\author{}
%\note{}
\seealso{
Classes \code{\linkS4class{dsCMatrix}},
\code{\linkS4class{dtCMatrix}}, \code{\link{lu}}
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(utils, pos = "package:base", verbose = FALSE)
}
(m <- Matrix(c(0,0,2:0), 3,5))
str(m)
m[,1]
\dontshow{## regression test: this must give a validity-check error:
stopifnot(inherits(try(new("dgCMatrix", i = 0:1, p = 0:2,
x = c(2,3), Dim = 3:4)),
"try-error"))
}
}
Matrix/man/dsparseMatrix-class.Rd 0000644 0001751 0000144 00000002525 14500445405 016534 0 ustar hornik users \name{dsparseMatrix-class}
\title{Virtual Class "dsparseMatrix" of Numeric Sparse Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{dsparseMatrix-class}
%
\alias{Arith,dsparseMatrix,logical-method}
\alias{Arith,dsparseMatrix,numeric-method}
\alias{Arith,logical,dsparseMatrix-method}
\alias{Arith,numeric,dsparseMatrix-method}
\alias{Ops,dsparseMatrix,nsparseMatrix-method}
\alias{coerce,matrix,dsparseMatrix-method}
\alias{coerce,vector,dsparseMatrix-method}
%
\description{The Class \code{"dsparseMatrix"} is the virtual (super) class of
all numeric sparse matrices.
}
\section{Slots}{
\describe{
\item{\code{Dim}:}{the matrix dimension, see class \code{"\linkS4class{Matrix}"}.}
\item{\code{Dimnames}:}{see the \code{"Matrix"} class.}
\item{\code{x}:}{a \code{\link{numeric}} vector containing the
(non-zero) matrix entries.}
}
}
\section{Extends}{
Class \code{"dMatrix"} and \code{"sparseMatrix"}, directly.\cr
Class \code{"Matrix"}, by the above classes.
}
% \section{Methods}{
% No methods defined with class "dsparseMatrix" in the signature.
% }
%%\author{Martin}
\seealso{
the documentation of the (non virtual) sub classes, see
\code{showClass("dsparseMatrix")}; in particular,
\linkS4class{dgTMatrix}, \linkS4class{dgCMatrix}, and
\linkS4class{dgRMatrix}.
}
\examples{
showClass("dsparseMatrix")
}
Matrix/man/asUniqueT.Rd 0000644 0001751 0000144 00000006254 14575137654 014544 0 ustar hornik users \name{asUniqueT}
\title{Standardize a Sparse Matrix in Triplet Format}
%
\keyword{array}
\keyword{logic}
\keyword{manip}
\keyword{utilities}
%
\alias{anyDuplicatedT}
\alias{isUniqueT}
\alias{asUniqueT}
\alias{aggregateT}
%
\alias{uniqTsparse}
%
\description{
Detect or standardize a \code{\linkS4class{TsparseMatrix}} with
unsorted or duplicated \eqn{(i,j)} pairs.
}
\usage{
anyDuplicatedT(x, \dots)
isUniqueT(x, byrow = FALSE, isT = is(x, "TsparseMatrix"))
asUniqueT(x, byrow = FALSE, isT = is(x, "TsparseMatrix"))
aggregateT(x)
}
\arguments{
\item{x}{an \R{} object. \code{anyDuplicatedT} and \code{aggregateT}
require \code{x} inheriting from \code{\linkS4class{TsparseMatrix}}.
\code{asUniqueT} requires \code{x} inheriting from
\code{\linkS4class{Matrix}} and coerces \code{x}
to \code{\linkS4class{TsparseMatrix}} if necessary.}
\item{\dots}{optional arguments passed to the default method for
generic function \code{\link{anyDuplicated}}.}
\item{byrow}{a logical indicating if \code{x} should be sorted
by row then by column.}
\item{isT}{a logical indicating if \code{x} inherits from virtual
class \code{\linkS4class{TsparseMatrix}}.}
}
\value{
\code{anyDuplicatedT(x)} returns the index of the first duplicated
\eqn{(i,j)} pair in \code{x} (0 if there are no duplicated pairs).
\code{isUniqueT(x)} returns \code{TRUE} if \code{x} is a
\code{\linkS4class{TsparseMatrix}} with sorted, nonduplicated
\eqn{(i,j)} pairs and \code{FALSE} otherwise.
\code{asUniqueT(x)} returns the unique
\code{\linkS4class{TsparseMatrix}} representation of \code{x} with
sorted, nonduplicated \eqn{(i,j)} pairs. Values corresponding to
identical \eqn{(i,j)} pairs are aggregated by addition, where in the
logical case \dQuote{addition} refers to logical OR.
\code{aggregateT(x)} aggregates without sorting.
}
\seealso{Virtual class \code{\linkS4class{TsparseMatrix}}.}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
library(utils, pos = "package:base", verbose = FALSE)
}
example("dgTMatrix-class", echo=FALSE)
## -> 'T2' with (i,j,x) slots of length 5 each
T2u <- asUniqueT(T2)
stopifnot(## They "are" the same (and print the same):
all.equal(T2, T2u, tol=0),
## but not internally:
anyDuplicatedT(T2) == 2,
anyDuplicatedT(T2u) == 0,
length(T2 @x) == 5,
length(T2u@x) == 3)
isUniqueT(T2 ) # FALSE
isUniqueT(T2u) # TRUE
T3 <- T2u
T3[1, c(1,3)] <- 10; T3[2, c(1,5)] <- 20
T3u <- asUniqueT(T3)
str(T3u) # sorted in 'j', and within j, sorted in i
stopifnot(isUniqueT(T3u))
## Logical l.TMatrix and n.TMatrix :
(L2 <- T2 > 0)
validObject(L2u <- asUniqueT(L2))
(N2 <- as(L2, "nMatrix"))
validObject(N2u <- asUniqueT(N2))
stopifnot(N2u@i == L2u@i, L2u@i == T2u@i, N2@i == L2@i, L2@i == T2@i,
N2u@j == L2u@j, L2u@j == T2u@j, N2@j == L2@j, L2@j == T2@j)
# now with a nasty NA [partly failed in Matrix 1.1-5]:
L.0N <- L.1N <- L2
L.0N@x[1:2] <- c(FALSE, NA)
L.1N@x[1:2] <- c(TRUE, NA)
validObject(L.0N)
validObject(L.1N)
(m.0N <- as.matrix(L.0N))
(m.1N <- as.matrix(L.1N))
stopifnot(identical(10L, which(is.na(m.0N))), !anyNA(m.1N))
symnum(m.0N)
symnum(m.1N)
}
Matrix/man/MatrixClass.Rd 0000644 0001751 0000144 00000002214 14422605232 015027 0 ustar hornik users \name{MatrixClass}
\title{The Matrix (Super-) Class of a Class}
%
\keyword{utilities}
%
\alias{MatrixClass}
\description{
Return the (maybe super-)\code{\link{class}} of class \code{cl} from
package \pkg{Matrix}, returning \code{\link{character}(0)} if there is none.
}
\usage{
MatrixClass(cl, cld = getClassDef(cl), ...Matrix = TRUE,
dropVirtual = TRUE, ...)
}
\arguments{
\item{cl}{string, class name}
\item{cld}{its class definition}
\item{...Matrix}{\code{\link{logical}} indicating if the result must be of
pattern \code{"[dlniz]..Matrix"} where the first letter "[dlniz]"
denotes the content kind.}
\item{dropVirtual}{\code{\link{logical}} indicating if virtual classes
are included or not.}% ?? (FIXME) -- example
\item{\dots}{further arguments are passed to
\code{\link{.selectSuperClasses}()}.}
}
\value{
a \code{\link{character}} string
}
\author{Martin Maechler, 24 Mar 2009}
%% \details{
%% }
\seealso{
\code{\linkS4class{Matrix}}, the mother of all \pkg{Matrix} classes.
}
\examples{
mkA <- setClass("A", contains="dgCMatrix")
(A <- mkA())
stopifnot(identical(
MatrixClass("A"),
"dgCMatrix"))
}
Matrix/man/Diagonal.Rd 0000644 0001751 0000144 00000011223 14446607050 014321 0 ustar hornik users \name{Diagonal}
\title{Construct a Diagonal Matrix}
%
\keyword{array}
\keyword{utilities}
%
\alias{Diagonal}
\alias{.sparseDiagonal}
\alias{.trDiagonal}
\alias{.symDiagonal}
%
\description{
Construct a formally diagonal \code{\linkS4class{Matrix}},
i.e., an object inheriting from virtual class
\code{\linkS4class{diagonalMatrix}}
(or, if desired, a \emph{mathematically} diagonal
\code{\linkS4class{CsparseMatrix}}).
}
\usage{
Diagonal(n, x = NULL, names = FALSE)
.sparseDiagonal(n, x = NULL, uplo = "U", shape = "t", unitri = TRUE, kind, cols)
.trDiagonal(n, x = NULL, uplo = "U", unitri = TRUE, kind)
.symDiagonal(n, x = NULL, uplo = "U", kind)
}
\arguments{
\item{n}{integer indicating the dimension of the (square) matrix.
If missing, then \code{length(x)} is used.}
\item{x}{numeric or logical vector listing values for the diagonal
entries, to be recycled as necessary. If \code{NULL} (the default),
then the result is a unit diagonal matrix. \code{.sparseDiagonal()}
and friends ignore non-\code{NULL} \code{x} when \code{kind = "n"}.}
\item{names}{either \code{\link{logical}} \code{TRUE} or \code{FALSE} or
then a \code{\link{character}} vector of \code{\link{length}}
\code{n}. If true \emph{and} \code{\link{names}(x)} is not
\code{NULL}, use that as both row and column names for the resulting
matrix. When a character vector, use it for both dimnames.}
\item{uplo}{one of \code{c("U","L")}, specifying the \code{uplo} slot
of the result if the result is formally triangular of symmetric.}
\item{shape}{one of \code{c("t","s","g")}, indicating if the result
should be formally triangular, symmetric, or \dQuote{general}.
The result will inherit from virtual class
\code{\linkS4class{triangularMatrix}},
\code{\linkS4class{symmetricMatrix}}, or
\code{\linkS4class{generalMatrix}}, respectively.}
\item{unitri}{logical indicating if a formally triangular result with
ones on the diagonal should be formally \emph{unit} triangular, i.e.,
with \code{diag} slot equal to \code{"U"} rather than \code{"N"}.}
\item{kind}{one of \code{c("d","l","n")}, indicating the \dQuote{mode}
of the result: numeric, logical, or pattern.
The result will inherit from virtual class
\code{\linkS4class{dsparseMatrix}},
\code{\linkS4class{lsparseMatrix}}, or
\code{\linkS4class{nsparseMatrix}}, respectively.
Values other than \code{"n"} are ignored when \code{x} is
non-\code{NULL}; in that case the mode is determined by
\code{\link{typeof}(x)}.}
\item{cols}{optional integer vector with values in \code{0:(n-1)},
indexing columns of the specified diagonal matrix. If specified,
then the result is (mathematically) \code{D[, cols+1]} rather
than \code{D}, where \code{D = Diagonal(n, x)}, and it is always
\dQuote{general} (i.e., \code{shape} is ignored).}
}
\value{
\code{Diagonal()} returns an object inheriting from virtual class
\code{\linkS4class{diagonalMatrix}}.
\code{.sparseDiagonal()} returns a \code{\linkS4class{CsparseMatrix}}
representation of \code{Diagonal(n, x)} or, if \code{cols} is given,
of \code{Diagonal(n, x)[, cols+1]}. The precise class of the result
depends on \code{shape} and \code{kind}.
\code{.trDiagonal()} and \code{.symDiagonal()} are simple wrappers,
for \code{.sparseDiagonal(shape = "t")} and
\code{.sparseDiagonal(shape = "s")}, respectively.
\code{.sparseDiagonal()} exists primarily to leverage efficient
C-level methods available for \code{CsparseMatrix}.
}
\author{Martin Maechler}
\seealso{the generic function \code{\link{diag}} for \emph{extraction}
of the diagonal from a matrix works for all \dQuote{Matrices}.
\code{\link{bandSparse}} constructs a \emph{banded} sparse matrix from
its non-zero sub-/super - diagonals. \code{\link{band}(A)} returns a
band matrix containing some sub-/super - diagonals of \code{A}.
\code{\link{Matrix}} for general matrix construction;
further, class \code{\linkS4class{diagonalMatrix}}.
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
}
Diagonal(3)
Diagonal(x = 10^(3:1))
Diagonal(x = (1:4) >= 2)#-> "ldiMatrix"
## Use Diagonal() + kronecker() for "repeated-block" matrices:
M1 <- Matrix(0+0:5, 2,3)
(M <- kronecker(Diagonal(3), M1))
(S <- crossprod(Matrix(rbinom(60, size=1, prob=0.1), 10,6)))
(SI <- S + 10*.symDiagonal(6)) # sparse symmetric still
stopifnot(is(SI, "dsCMatrix"))
(I4 <- .sparseDiagonal(4, shape="t"))# now (2012-10) unitriangular
stopifnot(I4@diag == "U", all(I4 == diag(4)))
\dontshow{% checking some "unit-diagonality":
L <- Diagonal(5, TRUE)
stopifnot(L@diag == "U", identical(L, Diagonal(5) > 0))
}
}
Matrix/man/subassign-methods.Rd 0000644 0001751 0000144 00000013252 14575137654 016261 0 ustar hornik users \name{subassign-methods}
\title{Methods for "[<-" - Assigning to Subsets for 'Matrix'}
%
\docType{methods}
\keyword{array}
\keyword{methods}
%
\alias{[<-}
\alias{[<--methods}
\alias{subassign-methods}
%
\alias{[<-,CsparseMatrix,Matrix,missing,replValue-method}
\alias{[<-,CsparseMatrix,index,index,replValue-method}
\alias{[<-,CsparseMatrix,index,index,sparseVector-method}
\alias{[<-,CsparseMatrix,index,missing,replValue-method}
\alias{[<-,CsparseMatrix,index,missing,sparseVector-method}
\alias{[<-,CsparseMatrix,matrix,missing,replValue-method}
\alias{[<-,CsparseMatrix,missing,index,replValue-method}
\alias{[<-,CsparseMatrix,missing,index,sparseVector-method}
\alias{[<-,Matrix,ANY,ANY,ANY-method}
\alias{[<-,Matrix,ANY,ANY,Matrix-method}
\alias{[<-,Matrix,ANY,ANY,matrix-method}
\alias{[<-,Matrix,ANY,missing,Matrix-method}
\alias{[<-,Matrix,ANY,missing,matrix-method}
\alias{[<-,Matrix,ldenseMatrix,missing,replValue-method}
\alias{[<-,Matrix,lsparseMatrix,missing,replValue-method}
\alias{[<-,Matrix,matrix,missing,replValue-method}
\alias{[<-,Matrix,missing,ANY,Matrix-method}
\alias{[<-,Matrix,missing,ANY,matrix-method}
\alias{[<-,Matrix,ndenseMatrix,missing,replValue-method}
\alias{[<-,Matrix,nsparseMatrix,missing,replValue-method}
\alias{[<-,RsparseMatrix,index,index,replValue-method}
\alias{[<-,RsparseMatrix,index,index,sparseVector-method}
\alias{[<-,RsparseMatrix,index,missing,replValue-method}
\alias{[<-,RsparseMatrix,index,missing,sparseVector-method}
\alias{[<-,RsparseMatrix,matrix,missing,replValue-method}
\alias{[<-,RsparseMatrix,missing,index,replValue-method}
\alias{[<-,RsparseMatrix,missing,index,sparseVector-method}
\alias{[<-,TsparseMatrix,Matrix,missing,replValue-method}
\alias{[<-,TsparseMatrix,index,index,replValue-method}
\alias{[<-,TsparseMatrix,index,index,sparseVector-method}
\alias{[<-,TsparseMatrix,index,missing,replValue-method}
\alias{[<-,TsparseMatrix,index,missing,sparseVector-method}
\alias{[<-,TsparseMatrix,matrix,missing,replValue-method}
\alias{[<-,TsparseMatrix,missing,index,replValue-method}
\alias{[<-,TsparseMatrix,missing,index,sparseVector-method}
\alias{[<-,denseMatrix,index,index,replValue-method}
\alias{[<-,denseMatrix,index,missing,replValue-method}
\alias{[<-,denseMatrix,matrix,missing,replValue-method}
\alias{[<-,denseMatrix,missing,index,replValue-method}
\alias{[<-,denseMatrix,missing,missing,ANY-method}
\alias{[<-,diagonalMatrix,index,index,replValue-method}
\alias{[<-,diagonalMatrix,index,index,sparseMatrix-method}
\alias{[<-,diagonalMatrix,index,index,sparseVector-method}
\alias{[<-,diagonalMatrix,index,missing,replValue-method}
\alias{[<-,diagonalMatrix,index,missing,sparseMatrix-method}
\alias{[<-,diagonalMatrix,index,missing,sparseVector-method}
\alias{[<-,diagonalMatrix,matrix,missing,replValue-method}
\alias{[<-,diagonalMatrix,missing,index,replValue-method}
\alias{[<-,diagonalMatrix,missing,index,sparseMatrix-method}
\alias{[<-,diagonalMatrix,missing,index,sparseVector-method}
\alias{[<-,diagonalMatrix,missing,missing,ANY-method}
\alias{[<-,indMatrix,index,index,ANY-method}
\alias{[<-,indMatrix,index,missing,ANY-method}
\alias{[<-,indMatrix,missing,index,ANY-method}
\alias{[<-,indMatrix,missing,missing,ANY-method}
\alias{[<-,sparseMatrix,ANY,ANY,sparseMatrix-method}
\alias{[<-,sparseMatrix,ANY,missing,sparseMatrix-method}
\alias{[<-,sparseMatrix,missing,ANY,sparseMatrix-method}
\alias{[<-,sparseMatrix,missing,missing,ANY-method}
\alias{[<-,sparseVector,index,missing,ANY-method}
\alias{[<-,sparseVector,sparseVector,missing,ANY-method}
%
\description{
Methods for \code{"[<-"}, i.e., extraction or subsetting mostly of
matrices, in package \pkg{Matrix}.
\bold{Note}: Contrary to standard \code{\link{matrix}} assignment in
base \R, in \code{x[..] <- val} it is typically an \bold{error} (see
\code{\link{stop}}) when the \link{type} or \code{\link{class}} of
\code{val} would require the class of \code{x} to be changed, e.g.,
when \code{x} is logical, say \code{"lsparseMatrix"}, and \code{val}
is numeric.
In other cases, e.g., when \code{x} is a \code{"nsparseMatrix"} and
\code{val} is not \code{TRUE} or \code{FALSE}, a warning is signalled,
and \code{val} is \dQuote{interpreted} as \code{\link{logical}}, and
(logical) \code{\link{NA}} is interpreted as \code{TRUE}.
}
\section{Methods}{
There are \emph{many many} more than these:
\describe{
\item{x = "Matrix", i = "missing", j = "missing", value= "ANY"}{
is currently a simple fallback method implementation which ensures
\dQuote{readable} error messages.}
\item{x = "Matrix", i = "ANY", j = "ANY", value= "ANY"}{ currently
gives an error }
\item{x = "denseMatrix", i = "index", j = "missing", value= "numeric"}{ ... }
\item{x = "denseMatrix", i = "index", j = "index", value= "numeric"}{ ... }
\item{x = "denseMatrix", i = "missing", j = "index", value= "numeric"}{ ... }
}
}
\seealso{
%% ./Xtrct-methods.Rd:
\code{\link{[-methods}} for subsetting \code{"Matrix"} objects; the
\code{\linkS4class{index}} class;
\code{\link{Extract}} about the standard subset assignment (and extraction).
}
\examples{
\dontshow{ % for R_DEFAULT_PACKAGES=NULL
library(stats, pos = "package:base", verbose = FALSE)
}
%% Note that ./Xtrct-methods.Rd has the indexing ones
set.seed(101)
(a <- m <- Matrix(round(rnorm(7*4),2), nrow = 7))
a[] <- 2.2 # <<- replaces **every** entry
a
## as do these:
a[,] <- 3 ; a[TRUE,] <- 4
m[2, 3] <- 3.14 # simple number
m[3, 3:4]<- 3:4 # simple numeric of length 2
## sub matrix assignment:
m[-(4:7), 3:4] <- cbind(1,2:4) #-> upper right corner of 'm'
m[3:5, 2:3] <- 0
m[6:7, 1:2] <- Diagonal(2)
m
## rows or columns only:
m[1,] <- 10
m[,2] <- 1:7
m[-(1:6), ] <- 3:0 # not the first 6 rows, i.e. only the 7th
as(m, "sparseMatrix")
}
Matrix/man/expm-methods.Rd 0000644 0001751 0000144 00000005065 14575137654 015237 0 ustar hornik users \name{expm-methods}
\title{Matrix Exponential}
%
\docType{methods}
\keyword{array}
\keyword{math}
\keyword{methods}
%
\alias{expm}
\alias{expm-methods}
%
\alias{expm,Matrix-method}
\alias{expm,dMatrix-method}
\alias{expm,ddiMatrix-method}
\alias{expm,dgeMatrix-method}
\alias{expm,dspMatrix-method}
\alias{expm,dsparseMatrix-method}
\alias{expm,dsyMatrix-method}
\alias{expm,dtpMatrix-method}
\alias{expm,dtrMatrix-method}
\alias{expm,matrix-method}
%
\description{
Compute the exponential of a matrix.
}
\usage{
expm(x)
}
\arguments{
\item{x}{a matrix, typically inheriting from the
\code{\linkS4class{dMatrix}} class.}
}
\details{
The exponential of a matrix is defined as the infinite Taylor
series \code{expm(A) = I + A + A^2/2! + A^3/3! + ...} (although this is
definitely not the way to compute it). The method for the
\code{dgeMatrix} class uses Ward's diagonal Pade' approximation with
three step preconditioning, a recommendation from
Moler & Van Loan (1978) \dQuote{Nineteen dubious ways\dots}.
}
\value{
The matrix exponential of \code{x}.
}
\references{
\url{https://en.wikipedia.org/wiki/Matrix_exponential}
Cleve Moler and Charles Van Loan (2003)
Nineteen dubious ways to compute the exponential of a matrix,
twenty-five years later. \emph{SIAM Review} \bold{45}, 1, 3--49.
\doi{10.1137/S00361445024180}
\emph{for historical reference mostly:}\cr
Moler, C. and Van Loan, C. (1978)
Nineteen dubious ways to compute the exponential of a matrix.
\emph{SIAM Review} \bold{20}, 4, 801--836.
\doi{10.1137/1020098}
%% MM: Till we have something better, this is quite good:
Eric W. Weisstein et al. (1999) \emph{Matrix Exponential}.
From MathWorld, \url{https://mathworld.wolfram.com/MatrixExponential.html}
}
\author{This is a translation of the implementation of the corresponding
Octave function contributed to the Octave project by
A. Scottedward Hodel \email{A.S.Hodel@Eng.Auburn.EDU}. A bug in there
has been fixed by Martin Maechler.
}
%\note{}
\seealso{
Package \CRANpkg{expm}, which provides newer (in some cases
faster, more accurate) algorithms for computing the matrix
exponential via its own (non-generic) function \code{expm()}.
\pkg{expm} also implements \code{logm()}, \code{sqrtm()}, etc.
Generic function \code{\link{Schur}}.
}
\examples{
(m1 <- Matrix(c(1,0,1,1), ncol = 2))
(e1 <- expm(m1)) ; e <- exp(1)
stopifnot(all.equal(e1@x, c(e,0,e,e), tolerance = 1e-15))
(m2 <- Matrix(c(-49, -64, 24, 31), ncol = 2))
(e2 <- expm(m2))
(m3 <- Matrix(cbind(0,rbind(6*diag(3),0))))# sparse!
(e3 <- expm(m3)) # upper triangular
}
Matrix/DESCRIPTION 0000644 0001751 0000144 00000006333 14612713766 013264 0 ustar hornik users Package: Matrix
Version: 1.7-0
VersionNote: do also bump src/version.h, inst/include/Matrix/version.h
Date: 2024-03-16
Priority: recommended
Title: Sparse and Dense Matrix Classes and Methods
Description: A rich hierarchy of sparse and dense matrix classes,
including general, symmetric, triangular, and diagonal matrices
with numeric, logical, or pattern entries. Efficient methods for
operating on such matrices, often wrapping the 'BLAS', 'LAPACK',
and 'SuiteSparse' libraries.
License: GPL (>= 2) | file LICENCE
URL: https://Matrix.R-forge.R-project.org
BugReports: https://R-forge.R-project.org/tracker/?atid=294&group_id=61
Contact: Matrix-authors@R-project.org
Authors@R:
c(person("Douglas", "Bates", role = "aut",
comment = c(ORCID = "0000-0001-8316-9503")),
person("Martin", "Maechler", role = c("aut", "cre"),
email = "mmaechler+Matrix@gmail.com",
comment = c(ORCID = "0000-0002-8685-9910")),
person("Mikael", "Jagan", role = "aut",
comment = c(ORCID = "0000-0002-3542-2938")),
person("Timothy A.", "Davis", role = "ctb",
comment = c(ORCID = "0000-0001-7614-6899",
"SuiteSparse libraries",
"collaborators listed in dir(system.file(\"doc\", \"SuiteSparse\", package=\"Matrix\"), pattern=\"License\", full.names=TRUE, recursive=TRUE)")),
person("George", "Karypis", role = "ctb",
comment = c(ORCID = "0000-0003-2753-1437",
"METIS library",
"Copyright: Regents of the University of Minnesota")),
person("Jason", "Riedy", role = "ctb",
comment = c(ORCID = "0000-0002-4345-4200",
"GNU Octave's condest() and onenormest()",
"Copyright: Regents of the University of California")),
person("Jens", "Oehlschlägel", role = "ctb",
comment = "initial nearPD()"),
person("R Core Team", role = "ctb",
comment = "base R's matrix implementation"))
Depends: R (>= 4.4.0), methods
Imports: grDevices, graphics, grid, lattice, stats, utils
Suggests: MASS, datasets, sfsmisc, tools
Enhances: SparseM, graph
LazyData: no
LazyDataNote: not possible, since we use data/*.R and our S4 classes
BuildResaveData: no
Encoding: UTF-8
NeedsCompilation: yes
Packaged: 2024-03-19 17:15:14 UTC; maechler
Author: Douglas Bates [aut] (),
Martin Maechler [aut, cre] (),
Mikael Jagan [aut] (),
Timothy A. Davis [ctb] (,
SuiteSparse libraries, collaborators listed in
dir(system.file("doc", "SuiteSparse", package="Matrix"),
pattern="License", full.names=TRUE, recursive=TRUE)),
George Karypis [ctb] (, METIS
library, Copyright: Regents of the University of Minnesota),
Jason Riedy [ctb] (, GNU
Octave's condest() and onenormest(), Copyright: Regents of the
University of California),
Jens Oehlschlägel [ctb] (initial nearPD()),
R Core Team [ctb] (base R's matrix implementation)
Maintainer: Martin Maechler
Repository: CRAN
Date/Publication: 2024-04-26 12:03:02 UTC
Matrix/build/ 0000755 0001751 0000144 00000000000 14576344040 012642 5 ustar hornik users Matrix/build/vignette.rds 0000644 0001751 0000144 00000000636 14576344040 015206 0 ustar hornik users SAO0!ň %!f{`hډ&bczh=i:+\rj1s\+GlpF莮5|'KzA8Ϡ1R~ã,*f,XcGlnsQ0q~& @uٹ⇦?D(RP',YlL#TeCL\U?g
QqE's-v˼ݰeF
nɜve!U3YÇZlP^,u",0a $65w7QKQh{g;
xv|UWp~
EUvCwBbؼ{"ʠ5'z0 -
Y*cQ7eiu|f3
cJreFTwi Matrix/build/partial.rdb 0000644 0001751 0000144 00000000074 14576343417 014777 0 ustar hornik users b```b`a 00 FN ͚Zd@$ $7 Matrix/tests/ 0000755 0001751 0000144 00000000000 14576344041 012706 5 ustar hornik users Matrix/tests/matr-exp.R 0000644 0001751 0000144 00000005355 14507035046 014572 0 ustar hornik users ## for R_DEFAULT_PACKAGES=NULL :
library(stats)
library(Matrix)
## Matrix Exponential
source(system.file("test-tools.R", package = "Matrix"))
## e ^ 0 = 1 - for matrices:
assert.EQ.mat(expm(Matrix(0, 3,3)), diag(3), tol = 0)# exactly
## e ^ diag(.) = diag(e ^ .):
assert.EQ.mat(expm(as(diag(-1:4), "generalMatrix")), diag(exp(-1:4)))
set.seed(1)
rE <- replicate(100,
{ x <- rlnorm(12)
relErr(as(expm(as(diag(x), "generalMatrix")),
"matrix"),
diag(exp(x))) })
stopifnot(mean(rE) < 1e-15,
max(rE) < 1e-14)
summary(rE)
## Some small matrices
m1 <- Matrix(c(1,0,1,1), ncol = 2)
e1 <- expm(m1)
assert.EQ.mat(e1, cbind(c(exp(1),0), exp(1)))
(p1 <- pack(m1))
stopifnot(exprs = {
is(p1, "dtpMatrix")
all.equal(pack(e1), expm(p1), tolerance = 2e-15)# failed in Matrix 1.6.1
})
m2 <- Matrix(c(-49, -64, 24, 31), ncol = 2)
e2 <- expm(m2)
## The true matrix exponential is 'te2':
e_1 <- exp(-1)
e_17 <- exp(-17)
te2 <- rbind(c(3*e_17 - 2*e_1, -3/2*e_17 + 3/2*e_1),
c(4*e_17 - 4*e_1, -2 *e_17 + 3 *e_1))
assert.EQ.mat(e2, te2, tol = 1e-13)
## See the (average relative) difference:
all.equal(as(e2,"matrix"), te2, tolerance = 0) # 2.22e-14 {was 1.48e-14} on "lynne"
(dsp <- pack(crossprod(matrix(-2:3, 2,3))))
stopifnot(all(abs(expm(dsp) - expm(as.matrix(dsp))) <= 0.5)) # failed badly in Matrix 1.6.1
## The ``surprising identity'' det(exp(A)) == exp( tr(A) )
## or log det(exp(A)) == tr(A) :
stopifnot(all.equal(c(determinant(e2)$modulus), sum(diag(m2))))
## a very simple nilpotent one:
(m3 <- Matrix(cbind(0,rbind(6*diag(3),0))))# sparse
stopifnot(all(m3 %*% m3 %*% m3 %*% m3 == 0))# <-- m3 "^" 4 == 0
e3 <- expm(m3)
E3 <- expm(Matrix(m3, sparse=FALSE))
s3 <- symmpart(m3) # dsCMatrix
es3 <- expm(s3)
e3. <- rbind(c(1,6,18,36),
c(0,1, 6,18),
c(0,0, 1, 6),
c(0,0, 0, 1))
stopifnot(is(e3, "triangularMatrix"),
is(es3, "symmetricMatrix"),
identical(e3, E3),
identical(as.mat(e3), e3.),
all.equal(as(es3,"generalMatrix"),
expm(as(s3,"generalMatrix")))
)
## This used to be wrong {bug in octave-origin code}:
M6 <- Matrix(c(0, -2, 0, 0, 0, 0,
10, 0, 0, 0,10,-2,
0, 0, 0, 0,-2, 0,
0, 10,-2,-2,-2,10,
0, 0, 0, 0, 0, 0,
10, 0, 0, 0, 0, 0), 6, 6)
exp.M6 <- expm(M6)
as(exp.M6, "sparseMatrix")# prints a bit more nicely
stopifnot(all.equal(t(exp.M6),
expm(t(M6)), tolerance = 1e-12),
all.equal(exp.M6[,3], c(0,0,1,0,-2,0), tolerance = 1e-12),
all.equal(exp.M6[,5], c(0,0,0,0, 1,0), tolerance = 1e-12),
all(exp.M6[3:4, c(1:2,5:6)] == 0)
)
cat('Time elapsed: ', proc.time(),'\n') # for ``statistical reasons''
Matrix/tests/Class+Meth.R 0000644 0001751 0000144 00000036222 14575137654 015005 0 ustar hornik users library(Matrix)
source(system.file("test-tools.R", package = "Matrix"))# identical3(),
# further checkMatrix(), etc
if(interactive()) options(error = recover)
options(warn=1)# show as they happen
cat("doExtras:",doExtras,"\n")
setClass("myDGC", contains = "dgCMatrix")
(M <- new("myDGC", as(Matrix(c(-2:4, rep(0,9)), 4), "CsparseMatrix")))
stopifnot(exprs = {
M[-4L, 2L] == 2:4
MatrixClass( "myDGC") == "dgCMatrix"
MatrixClass( "dpoMatrix") == "dsyMatrix"
MatrixClass( "dppMatrix") == "dspMatrix"
MatrixClass( "corMatrix") == "dsyMatrix"
MatrixClass( "copMatrix") == "dspMatrix"
identical(MatrixClass("indMatrix"), character(0L))
identical(MatrixClass( "pMatrix"), character(0L))
})
## [matrix-Bugs][6182] Coercion method doesn't work on child class
## Bugs item #6182, at 2015-09-01 17:49 by Vitalie Spinu
setClass("A", contains = "ngCMatrix")
ngc <- as(as(as(diag(3), "CsparseMatrix"), "generalMatrix"), "nMatrix")
validObject(dd <- as(ngc, "dMatrix")) # fine
A. <- as(ngc, "A")
stopifnot(identical(as(A., "dMatrix"), dd))
## as(.) coercion failed in Matrix <= 1.2.3
stopifnot(all( abs(A.)# failed too
== diag(3)))
d <- Diagonal(3)
(dC <- as(d, "CsparseMatrix")) # "dtCMatrix" (unitriangular)
(dgC <- as(dC, "generalMatrix"))
stopifnot(exprs = {
is(dgC, "dgCMatrix") # was wrong in Matrix 1.3.2
## identical(dgC, as(dC, "dgCMatrix")) # deprecated
identical(dC , new("dtCMatrix", p = rep(0L, 4), Dim = c(3L, 3L), diag = "U"))
identical(dC , diagN2U(as(dgC, "triangularMatrix")))
})
setClass("posDef", contains = "dspMatrix")
N <- as(crossprod(M) + Diagonal(4), "packedMatrix")
(N <- new("posDef", N))
stopifnot(is(N[1:2, 1:2], "symmetricMatrix"))
#### Automatically display the class inheritance structure
#### possibly augmented with methods
allCl <- getClasses("package:Matrix")
cat("actual and virtual classes:\n")
tt <- table( isVirt <- sapply(allCl, isVirtualClass) )
names(tt) <- c('"actual"', "virtual")
tt
## The "actual" Matrix classes:
aCl <- allCl[!isVirt]
(aMcl <- aCl[grep("Matrix$", aCl)]) # length 48
aMc2 <- aCl[sapply(aCl, extends, class2 = "Matrix")]
stopifnot(all( aMcl %in% aMc2 ))
aMc2[!(aMc2 %in% aMcl)] ## only 4 : p?Cholesky & p?BunchKaufman
## Really nice would be to construct an inheritance graph and display
## it. Following things are computational variations on the theme..
## We use a version of canCoerce() that works with two *classes* instead of
## canCoerce <- function (object, Class)
classCanCoerce <- function (class1, class2)
{
extends(class1, class2) ||
!is.null(selectMethod("coerce", optional = TRUE,
signature = c(from = class1, to = class2),
useInherited = c(from = TRUE, to = FALSE)))
}
.dq <- function(ch) paste0('"', ch, '"')
.subclasses <- function(cnam) {
cd <- getClass(cnam)
unique(c(cd@className, unlist(lapply(names(cd@subclasses), .subclasses))))
}
for(n in allCl) {
if(isVirtualClass(n))
cat("Virtual class", .dq(n),"\n")
else {
cat("\"Actual\" class", .dq(n),":\n")
x <- new(n)
if(doExtras) for(m in allCl)
if(classCanCoerce(n,m)) {
ext <- extends(n, m)
if(ext) {
cat(sprintf(" extends %20s %20s \n", "", .dq(m)))
} else {
cat(sprintf(" can coerce: %20s -> %20s: ", .dq(n), .dq(m)))
tt <- try(as(x, m), silent = TRUE)
if(inherits(tt, "try-error")) {
cat("\t *ERROR* !!\n")
} else {
cat("as() ok; validObject: ")
vo <- validObject(tt, test = TRUE)
cat(if(isTRUE(vo)) "ok" else paste("OOOOOOPS:", vo), "\n")
}
}
}
cat("---\n")
}
}
cat('Time elapsed: ', proc.time(),'\n') # for the above "part I"
if(doExtras && !interactive()) { # don't want to see on source()
cat("All classes in the 'Matrix' package:\n")
for(cln in allCl) {
cat("\n-----\n\nClass", dQuote(cln),":\n ",
paste(rep("~",nchar(cln)),collapse=''),"\n")
## A smarter version would use getClass() instead of showClass(),
## build the "graph" and only then display.
##
showClass(cln)
}
cat("\n\n")
## One could extend the `display' by using (something smarter than)
## are the "coerce" methods showing more than the 'Extends' output above?
cat("All (S4) methods in the 'Matrix' package:\n")
showMethods(where="package:Matrix")
} # end{non-interactive}
## 1-indexing instead of 0-indexing for direct "dgT" should give error:
ii <- as.integer(c(1,2,2))
jj <- as.integer(c(1,1,3))
assertError(new("dgTMatrix", i=ii, j=jj, x= 10*(1:3), Dim=2:3))
assertError(new("dgTMatrix", i=ii, j=jj - 1:1, x= 10*(1:3), Dim=2:3))
assertError(new("dgTMatrix", i=ii - 1:1, j=jj, x= 10*(1:3), Dim=2:3))
(mm <- new("dgTMatrix", i=ii - 1:1, j=jj - 1:1, x= 10*(1:3), Dim=2:3))
validObject(mm)
### Sparse Logical:
m <- Matrix(c(0,0,2:0), 3,5)
mT <- as(mC <- as(m, "CsparseMatrix"), "TsparseMatrix")
stopifnot(identical(as(mT,"CsparseMatrix"), mC))
(mC. <- as(mT[1:2, 2:3], "CsparseMatrix"))
(mlC <- as(mC. , "lMatrix"))
as(mlC, "triangularMatrix")
if(!doExtras && !interactive()) q("no") ## (saving testing time)
### Test all classes: validObject(new( * )) should be fulfilled -----------
## need stoplist for now:
Rcl.struc <- c("gR", "sR", "tR")
(dR.classes <- paste0(paste0("d", Rcl.struc[Rcl.struc != "gR"]), "Matrix"))
(.R.classes <- paste0(sort(outer(c("l", "n"), Rcl.struc, paste0)), "Matrix"))
# have only stub implementation
Mat.MatFact <- c("Cholesky", "pCholesky",
"BunchKaufman", "pBunchKaufman")##, "LDL"
##FIXME maybe move to ../../MatrixModels/tests/ :
## (modmat.classes <- .subclasses("modelMatrix"))
no.t.etc <- c(.R.classes, dR.classes, Mat.MatFact)#, modmat.classes)
no.t.classes <- c(no.t.etc) # no t() available
no.norm.classes <- no.t.classes
not.Ops <- NULL # "Ops", e.g. "+" fails
not.coerce1 <- no.t.etc # not coercable from "dgeMatrix"
not.coerce2 <- no.t.etc # not coercable from "matrix"
tstMatrixClass <-
function(cl, mM = Matrix(c(2,1,1,2) + 0, 2,2,
dimnames=rep( list(c("A","B")), 2)), # dimnames: *symmetric*
mm = as(mM, "matrix"), recursive = TRUE, offset = 0)
{
## Purpose: Test 'Matrix' class {and do this for all of them}
## ----------------------------------------------------------------------
## Arguments: cl: class object of a class that extends "Matrix"
## mM: a "Matrix"-matrix which will be coerced to class 'cl'
## mm: a S3-matrix which will be coerced to class 'cl'
## ----------------------------------------------------------------------
## Author: Martin Maechler
## from pkg sfsmisc :
bl.string <- function(no) sprintf("%*s", no, "")
## Compute a few things only once :
mM <- as(as(as(mM, "unpackedMatrix"), "generalMatrix"), "dMatrix") # dge
trm <- mm; trm[lower.tri(mm)] <- 0
## not yet used:
## summList <- lapply(getGroupMembers("Summary"), get,
## envir = asNamespace("Matrix"))
if(recursive)
cList <- character(0)
extraValid <- function(m, cl = class(m)) {
sN <- slotNames(cl)
sN <- sN[sN != "factors"]
for(nm in sN)
if(!is.null(a <- attributes(slot(m, nm))))
stop(sprintf("slot '%s' with %d attributes, named: ",
nm, length(a)), paste(names(a), collapse=", "))
invisible(TRUE)
}
## This is the recursive function
dotestMat <- function(cl, offset)
{
cat. <- function(...) cat(bl.string(offset), ...)
clNam <- cl@subClass
deprecated <- grepl("^[dln](ge|tr|sy|tp|sp|[gts][CRT])Matrix$", clNam)
cat("\n==>")
cat.(clNam)
##---------
clD <- getClassDef(clNam)
if(isVirtualClass(clD)) {
cat(" - is virtual\n")
if(recursive) {
cat.("----- begin{class :", clNam, "}----new subclasses----\n")
for(ccl in clD@subclasses) {
cclN <- ccl@subClass
if(cclN %in% cList)
cat.(cclN,": see above\n")
else {
cList <<- c(cList, cclN)
dotestMat(ccl, offset = offset + 3)
}
}
cat.("----- end{class :", clNam, "}---------------------\n")
}
} else { ## --- actual class ---
genC <- extends(clD, "generalMatrix")
symC <- extends(clD, "symmetricMatrix")
triC <- extends(clD, "triangularMatrix")
diaC <- extends(clD, "diagonalMatrix")
indC <- extends(clD, "indMatrix")
if(!(genC || symC || triC || diaC || indC))
stop("does not extend one of 'general', 'symmetric', 'triangular', 'diagonal', 'ind'")
sparseC <- extends(clD, "sparseMatrix")
denseC <- extends(clD, "denseMatrix")
if(!(sparseC || denseC))
stop("does not extend either 'sparse' or 'dense'")
cat("; new(*): ")
m <- new(clNam) ; cat("ok; ")
m0 <- matrix(,0,0)
if(canCoerce(m0, clNam)) {
cat("; canCoerce(matrix(,0,0), *) => as(m0, <.>): ")
m0. <-
if(deprecated)
eval(Matrix:::.as.via.virtual(
"matrix", clNam, quote(m0)))
else as(m0, clNam)
if(.hasSlot(m, "diag") && .hasSlot(m0., "diag") &&
identical(m@diag, "N") && identical(m0.@diag, "U"))
## tolerate as(0-by-0, .) formally having unit diagonal
m0.@diag <- "N"
stopifnot(Qidentical(m, m0.)); cat("ok; ")
}
is_p <- extends(clD, "indMatrix")
is_cor <- extends(clD, "corMatrix") || extends(clD, "copMatrix")
## ^^^ has diagonal divided out
if(canCoerce(mm, clNam)) { ## replace 'm' by `non-empty' version
cat("canCoerce(mm, *) ")
m0 <- {
if(triC) trm
else if(is_p)
mm == 1 # logical *and* "true" permutation
else mm
}
if(extends(clD, "lMatrix") ||
extends(clD, "nMatrix"))
storage.mode(m0) <- "logical"
else if(extends(clD, "zMatrix"))
storage.mode(m0) <- "complex"
validObject(m) ## validity of trivial 'm' before replacing
m <-
if(deprecated)
eval(Matrix:::.as.via.virtual(
"matrix", clNam, quote(m0)))
else as(m0, clNam)
if(is_cor)
m0 <- cov2cor(m0)
} else {
m0 <- vector(Matrix:::.type.kind[Matrix:::.M.kind(m)])
dim(m0) <- c(0L,0L)
}
## m0 is the 'matrix' version of our 'Matrix' m
m. <- m0 ##m. <- if(is_p) as.integer(m0) else m0
EQ <- if(is_cor) all.equal else identical
stopifnot(EQ(m0[FALSE], m[FALSE])
, EQ(m.[TRUE], m[TRUE])
, if(length(m) >= 2) EQ(m.[2:1], m[2:1]) else TRUE)
if(all(dim(m) > 0)) { ## matrix(0,0,0)[FALSE,] is invalid too
m00 <- m[FALSE,FALSE]
m.. <- m[TRUE , TRUE]
stopifnot(dim(m00) == c(0L,0L),
dim(m..) == dim(m))
## not yet , class(m00) == clNam , identical(m.. , m)
}
cat("valid: ", validObject(m), extraValid(m, clNam),"\n")
## This can only work as long as 'm' has no NAs :
## not yet -- have version in not.Ops below
## once we have is.na():
## stopifnot(all(m == m | is.na(m))) ## check all() and "==" [Compare]
## if(any(m != m && !is.na(m)))
show(m)
## coerce to 'matrix'
m.m <- as(m, "matrix")
##=========##
checkMatrix(m, m.m,
##=========##
do.t= !(clNam %in% no.t.classes),
doNorm= !(clNam %in% no.norm.classes),
doOps = all(clNam != not.Ops),
doCoerce = all(clNam != not.coerce1),
catFUN = cat.)
### FIXME: organize differently :
### 1) produce 'mM' and 'mm' for the other cases,
### 2) use identical code for all cases
if(is(m, "dMatrix") &&
(is(m, "generalMatrix") || is(m, "symmetricMatrix"))) {
if(any(clNam == not.coerce1))
cat.("not coercable_1\n")
else if(canCoerce(mM, clNam)) {
m2 <-
if(deprecated)
eval(Matrix:::.as.via.virtual(
class(mM), clNam, quote(mM)))
else as(mM, clNam)
cat("valid:", validObject(m2), "\n")
if(!is_cor) ## as.vector()
stopifnot(as.vector(m2) == as.vector(mM))
cat.("[cr]bind2():"); mm2 <- cbind2(m2,m2)
stopifnot(dim(rbind2(m2,m2)) == 2:1 * dim(mM)); cat(" ok")
if(genC && class(mm2) == clNam) ## non-square matrix when "allowed"
m2 <- mm2
dd <- diag(m2)
cat("; `diag<-` ")
diag(m2) <- 10*dd
stopifnot(is_cor || identical(dd, diag(mM)),
identical(10*dd, diag(m2))); cat("ok ")
}
## if(all(clNam != not.coerce2)) {
if(canCoerce("matrix", clNam)) {
cat.("as(matrix, ): ")
m3 <-
if(deprecated)
eval(Matrix:::.as.via.virtual(
"matrix", clNam, quote(mm)))
else as(mm, clNam)
cat("valid:", validObject(m3), "\n")
} else cat.(" not coerceable from \"matrix\"\n")
## }
}
## else { ... no happens in tstMatrix() above .. }
## if(is(m, "denseMatrix")) {
## ## .........
## cat.("as dsparse* ")
## msp <- as(m, "dsparseMatrix")
## cat.("; valid coercion: ", validObject(msp), "\n")
## } else if(is(m, "sparseMatrix")) {
## } else cat.("-- not dense nor sparse -- should not happen(!?)\n")
if(is(m, "dsparseMatrix")) {
if(any(clNam == not.coerce1))
cat.("not coercable_1\n")
else {
## make sure we can coerce to dgT* -- needed, e.g. for "image"
cat.("as dgT* ")
mgT <- eval(Matrix:::.as.via.virtual(
class(m), "dgTMatrix", quote(m)))
cat(sprintf("; valid dgT* coercion: %s\n",
validObject(mgT)))
}
}
}
} # end{dotestMat}
for(scl in getClass(cl)@subclasses)
dotestMat(scl, offset + 1)
}
## in case we want to make progress:
## codetools::checkUsage(tstMatrixClass, all=TRUE)
tstMatrixClass("Matrix")
if(FALSE)## or just a sub class
tstMatrixClass("triangularMatrix")
cat('Time elapsed: ', proc.time(),'\n') # for ``statistical reasons''
if(!interactive()) warnings()
Matrix/tests/dtpMatrix.R 0000644 0001751 0000144 00000004273 14444520706 015011 0 ustar hornik users ### triangular packed
## for R_DEFAULT_PACKAGES=NULL :
library(stats)
library(utils)
library(Matrix)
source(system.file("test-tools.R", package = "Matrix"))# identical3() etc
cp6 <- as(Cholesky(H6 <- Hilbert(6), perm = FALSE), "dtrMatrix")
(tp6 <- as(cp6, "packedMatrix"))
round(tp6, 3)## round() is "Math2" group method
1/tp6 ## "Arith" group : gives 'dgeMatrix'
str(tp6)
## arithmetic with a mix of dimnames / no dimnames
tp <- tp6; dimnames(tp) <- list(LETTERS[1:6], letters[11:16])
## as.matrix() --> "logical" matrix
stopifnot(as.matrix(tp - tp6 == tp6 - tp),
as.matrix(0 == tp - tp6),
identical(as(tp6,"CsparseMatrix"),
as(cp6,"CsparseMatrix")))
stopifnot(validObject(tp6),
all.equal(tp6 %*% diag(6), as(tp6, "generalMatrix")),
validObject(tp6. <- diag(6) %*% tp6),
identical(t(tt6 <- t(tp6)), tp6),
tp6@uplo == "U" && tt6@uplo == "L")
all.equal(as(tp6.,"matrix"),
as(tp6, "matrix"), tolerance= 1e-15)
dH6 <- determinant(H6)
D. <- determinant(tp6)
rc <- rcond(tp6)
stopifnot(all.equal(dH6$modulus, determinant(as.matrix(H6))$modulus),
is.all.equal3(c(D.$modulus), c(dH6$modulus) / 2, -19.883103353),
all.equal(rc, 1.791511257e-4),
all.equal(norm(tp6, "I") , 2.45),
all.equal(norm(tp6, "1") , 1),
all.equal(norm(tp6, "F") , 1.37047826623)
)
object.size(tp6)
object.size(as(tp6, "unpackedMatrix"))
object.size(as(tp6, "matrix"))
D6 <- as(diag(6), "generalMatrix")
ge6 <- as(tp6, "generalMatrix")
stopifnot(all.equal(D6 %*% tp6, ge6),
all.equal(tp6 %*% D6, ge6))
## larger case
RNGversion("3.6.0")# future proof
set.seed(123)
rl <- new("dtpMatrix", uplo="L", diag="N", Dim = c(1000L, 1000L),
x = rnorm(500*1001))
validObject(rl)
str(rl)
sapply(c("I", "1", "F"), function(type) norm(rl, type=type))
rcond(rl)# 0 !
stopifnot(all.equal(as(rl %*% diag(1000),"matrix"),
as(rl, "matrix")))
object.size(rl) ## 4 MB
object.size(as(rl, "unpackedMatrix"))# 8 MB
object.size(as(rl, "matrix"))# ditto
print(drl <- determinant(rl), digits = 12)
stopifnot(all.equal(c(drl$modulus), -638.257312422))
cat('Time elapsed: ', proc.time(),'\n') # for ``statistical reasons''
Matrix/tests/dpo-test.R 0000644 0001751 0000144 00000014407 14467053122 014572 0 ustar hornik users ### Testing positive definite matrices
## for R_DEFAULT_PACKAGES=NULL :
library(stats)
library(utils)
library(Matrix)
source(system.file("test-tools.R", package = "Matrix"))# identical3() etc
cat("doExtras:",doExtras,"\n")
h9 <- Hilbert(9)
stopifnot(c(0,0) == dim(Hilbert(0)),
c(9,9) == dim(h9),
identical(h9@factors, list()))
str(h9)# no 'factors' 32b: -96.73694669 2.08e-8
assert.EQ.(c(determinant(h9)$modulus), -96.7369487, tol = 8e-8)
## 64b: -96.73695078 2.15e-8 then 6.469e-8
## determinant() now working via chol(): ==> h9 now has factorization
stopifnot(names(h9@factors) == "Cholesky",
identical(ch9 <- Cholesky(h9, perm = FALSE), h9@factors$Cholesky))
str(f9 <- as(ch9, "dtrMatrix"))
round(f9, 3) ## round() preserves 'triangular' !
stopifnot(all.equal(rcond(h9), 9.0938e-13),
all.equal(rcond(f9), 9.1272e-7, tolerance = 1e-6))# more precision fails
options(digits=4)
(cf9 <- crossprod(f9))# looks the same as h9 :
assert.EQ.mat(h9, as(cf9,"matrix"), tol=1e-15)
h9. <- round(h9, 2) # dpo->dsy
h9p <- pack(h9)
ch9p <- Cholesky(h9p, perm = FALSE)
stopifnot(identical(ch9p, h9p@factors$pCholesky),
identical(names(h9p@factors), c("Cholesky", "pCholesky")))
h4 <- h9.[1:4, 1:4] # this and the next
h9.[1,1] <- 10 # had failed in 0.995-14
h9p[1,1] <- 10
stopifnotValid(h9., "symmetricMatrix")
stopifnotValid(h9p, "symmetricMatrix")
stopifnotValid(h4, "symmetricMatrix")
h9p[1,2] <- 99
stopifnot(class(h9p) == "dgeMatrix", h9p[1,1:2] == c(10,99))
str(h9p <- as(h9, "dppMatrix"))# {again}
h6 <- h9[1:6,1:6]
stopifnot(all(h6 == Hilbert(6)), length(h6@factors) == 0)
stopifnotValid(th9p <- t(h9p), "dppMatrix")
stopifnotValid(h9p@factors$Cholesky,"Cholesky")
H6 <- as(h6, "packedMatrix")
pp6 <- as(H6, "dppMatrix")
po6 <- as(pp6, "dpoMatrix")
hs <- as(h9p, "dspMatrix")
stopifnot(names(H6@factors) == "pCholesky",
names(pp6@factors) == "pCholesky",
names(hs@factors) == "Cholesky") # for now
chol(hs) # and that is cached in 'hs' too :
stopifnot(names(hs@factors) %in% c("Cholesky","pCholesky"),
all.equal(h9, crossprod(as(hs@factors$pCholesky, "dtpMatrix")),
tolerance = 1e-13),
all.equal(h9, crossprod(as(hs@factors$ Cholesky, "dtrMatrix")),
tolerance = 1e-13))
hs@x <- 1/h9p@x # is not pos.def. anymore
validObject(hs) # "but" this does not check
stopifnot(diag(hs) == seq(1, by = 2, length.out = 9))
s9 <- solve(h9p, seq(nrow(h9p)))
signif(t(s9)/10000, 4)# only rounded numbers are platform-independent
(I9 <- h9p %*% s9)
m9 <- as.matrix(1:9)
stopifnot(all.equal(m9, as(I9, "matrix"), tolerance = 2e-9))
### Testing nearPD() --- this is partly in ../man/nearPD.Rd :
pr <- Matrix(c(1, 0.477, 0.644, 0.478, 0.651, 0.826,
0.477, 1, 0.516, 0.233, 0.682, 0.75,
0.644, 0.516, 1, 0.599, 0.581, 0.742,
0.478, 0.233, 0.599, 1, 0.741, 0.8,
0.651, 0.682, 0.581, 0.741, 1, 0.798,
0.826, 0.75, 0.742, 0.8, 0.798, 1),
nrow = 6, ncol = 6)
nL <-
list(r = nearPD(pr, conv.tol = 1e-7), # default
r.1 = nearPD(pr, conv.tol = 1e-7, corr = TRUE),
rs = nearPD(pr, conv.tol = 1e-7, doDykstra=FALSE),
rs1 = nearPD(pr, conv.tol = 1e-7, doDykstra=FALSE, corr = TRUE),
rH = nearPD(pr, conv.tol = 1e-15),
rH.1= nearPD(pr, conv.tol = 1e-15, corr = TRUE))
sapply(nL, `[`, c("iterations", "normF"))
allnorms <- function(d) vapply(c("1","I","F","M","2"),
norm, x = d, double(1))
## "F" and "M" distances are larger for the (corr=TRUE) constrained:
100 * sapply(nL, function(rr) allnorms((pr - rr $ mat)))
## But indeed, the 'corr = TRUE' constraint yield a better solution,
## if you need the constraint : cov2cor() does not just fix it up :
100 * (nn <- sapply(nL, function(rr) allnorms((pr - cov2cor(rr $ mat)))))
stopifnot(
all.equal(nn["1",],
c(r =0.0999444286984696, r.1= 0.0880468666522317,
rs=0.0999444286984702, rs1= 0.0874614179943388,
rH=0.0999444286984696, rH.1=0.0880468927726625),
tolerance=1e-9))
nr <- nL $rH.1 $mat
stopifnot(
all.equal(nr[lower.tri(nr)],
c(0.4877861230299, 0.6429309061748, 0.4904554299278, 0.6447150779852,
0.8082100656035, 0.514511537243, 0.2503412693503, 0.673249718642,
0.7252316891977, 0.5972811755863, 0.5818673040157, 0.7444549621769,
0.7308954865819, 0.7713984381710, 0.8124321235679),
tolerance = 1e-9))
showProc.time()
suppressWarnings(RNGversion("3.5.0")); set.seed(27)
m9 <- h9 + rnorm(9^2)/1000 ; m9 <- (m9 + t(m9))/2
nm9 <- nearPD(m9)
showProc.time()
nRep <- if(doExtras) 50 else 4
CPU <- 0
for(M in c(5, 12))
for(i in 1:nRep) {
m <- matrix(round(rnorm(M^2),2), M, M)
m <- m + t(m)
diag(m) <- pmax(0, diag(m)) + 1
m <- cov2cor(m)
CPU <- CPU + system.time(n.m <- nearPD(m, base.matrix=TRUE))[1]
X <- n.m$mat
stopifnot(all.equal(X, (X + t(X))/2, tolerance = 8*.Machine$double.eps),
all.equal(eigen(n.m$mat, only.values=TRUE)$values,
n.m$eigenvalues, tolerance = 4e-8))
}
cat('Time elapsed for ',nRep, 'nearPD(): ', CPU,'\n')
showProc.time()
## cov2cor()
m <- diag(6:1) %*% as(pr,"matrix") %*% diag(6:1) # so we can "vector-index"
m[upper.tri(m)] <- 0
ltm <- which(lower.tri(m))
ne <- length(ltm)
set.seed(17)
m[ltm[sample(ne, 3/4*ne)]] <- 0
m <- (m + t(m))/2 # now is a covariance matrix with many 0 entries
(spr <- Matrix(m))
cspr <- cov2cor(spr)
ev <- eigen(cspr, only.values = TRUE)$values
stopifnot(is(spr, "dsCMatrix"),
is(cspr,"dsCMatrix"),
all.equal(ev, c(1.5901626099, 1.1902658504, 1, 1,
0.80973414959, 0.40983739006), tolerance=1e-10))
x <- c(2,1,1,2)
mM <- Matrix(x, 2,2, dimnames=rep( list(c("A","B")), 2))# dsy
mM
stopifnot(length(mM@factors)== 0)
(po <- as(mM, "dpoMatrix")) # still has dimnames
mm <- as(mM, "matrix")
msy <- as(mm, "symmetricMatrix")
stopifnot(Qidentical(mM, msy),
length(mM @factors)== 1,
length(msy@factors)== 0)
c1 <- as(mm, "corMatrix")
c2 <- as(mM, "corMatrix")
c3 <- as(po, "corMatrix")
(co.x <- matrix(x/2, 2,2))
checkMatrix(c1)
assert.EQ.mat(c1, co.x)
assert.EQ.mat(c2, co.x) # failed in Matrix 0.999375-9, because of
## the wrong automatic "dsyMatrix" -> "corMatrix" coerce method
stopifnot(identical(dimnames(c1), dimnames(mM)),
all.equal(c1, c3, tolerance =1e-15))
showProc.time()
Matrix/tests/Simple.R 0000644 0001751 0000144 00000171646 14535165176 014306 0 ustar hornik users #### Currently a collection of simple tests
## (since 'Matrix' takes long to load, rather have fewer source files!)
## for R_DEFAULT_PACKAGES=NULL :
library(methods)
library(stats)
library(utils)
##-------- *BEFORE* attaching Matrix: --------------------------------
str(Matrix::Matrix)# -> load the namespace
T <- new("ngTMatrix", i=0L, j=2L, Dim = c(2L,6L))
T
as(T, "CsparseMatrix")
## gave Error in asMethod(object) : could not find function ".M.classEnv"
## from 0.999375-23 to *-25
## another even shorter version of this:
n <- new("dgCMatrix")
n
## this:
m <- Matrix::Matrix(cbind(1,0,diag(x=2:4)))
m
mt <- m + table(gl(3,5), gl(5,3))# failed in Matrix <= 1.2.9
mt
stopifnot(is(mt, "sparseMatrix"))
##--------------------------------------------------------------------
library(Matrix)
source(system.file("test-tools.R", package = "Matrix"))# identical3() etc
if(interactive()) {
options(error = recover, Matrix.verbose = TRUE, warn = 1)
} else options( Matrix.verbose = TRUE, warn = 1)
# ^^^^^^ to show Matrix.msg()s
(Mv <- Matrix.Version())
stopifnot(identical(packageVersion("Matrix"), Mv[["package"]]))
### Matrix() ''smartness''
(d40 <- Matrix( diag(4)))
(z4 <- Matrix(0*diag(4)))
(o4 <- Matrix(1+diag(4)))
(tr <- Matrix(cbind(1,0:1)))
(M4 <- Matrix(m4 <- cbind(0,rbind(6*diag(3),0))))
dM4 <- Matrix(M4, sparse = FALSE)
d4. <- diag(4); dimnames(d4.) <- dns <- rep(list(LETTERS[1:4]), 2)
d4a <- diag(4); dimnames(d4a) <- dna <- list(LETTERS[1:4], letters[1:4])# "a"symmetric
m1a <- matrix(0, dimnames=list("A","b"))# "a"symmetric
d4di<- as(d4., "diagonalMatrix")
d4da<- as(d4a, "diagonalMatrix")
d4d <- as(d4., "denseMatrix")
d4aS <- Matrix(d4a, sparse=TRUE, doDiag=FALSE)
d1aS <- Matrix(m1a, sparse=TRUE, doDiag=FALSE)
stopifnot(exprs = {
identical(d4di@x, numeric()) # was "named" unnecessarily
identical(dimnames(d4 <- Matrix(d4.)), dns)
identical4(d40, Matrix(diag(4)), unname(d4), unname(d4da))
identical3(d4, as(d4., "Matrix"), as(d4., "diagonalMatrix"))
is(d4aS, "dtCMatrix") # not "dsC*", as asymmetric dimnames
is(d4d, "denseMatrix")
identical(dimnames(d4T <- as(d4., "TsparseMatrix")), dns) # failed till 2019-09-xx
## identical(d4T, as(d4., "dsTMatrix")) # deprecated
})
showProc.time()
class(mN <- Matrix(NA, 3,4)) # NA *is* logical
validObject(Matrix(NA))
bd4 <- bdiag(M4,dM4,M4)
stopifnotValid(o4, "dsyMatrix")
stopifnotValid(M4, "dtCMatrix")
stopifnot(validObject(dM4), validObject(mN),
identical(bdiag(M4), bdiag(dM4)),
identical(bd4@p, c(0L,0:3,3:6,6:9)),
identical(bd4@i, c(0:2, 4:6, 8:10)), bd4@x == 6
)
assert.EQ.mat(dM4, m4)
assert.EQ.mat(M4^M4, m4^m4)
assert.EQ.mat(mN, matrix(NA, 3,4))
assert.EQ.mat(bdiag(diag(4)), diag(4))
sL <- Matrix(, 3,4, sparse=TRUE)# -> "lgC"
trS <- Matrix(tr, sparse=TRUE)# failed in 0.9975-11
stopifnotValid(d4, "diagonalMatrix"); stopifnotValid(z4, "diagonalMatrix")
stopifnotValid(tr, "triangularMatrix"); stopifnotValid(trS, "triangularMatrix")
stopifnot(all(is.na(sL@x)), ## not yet: all(is.na(sL)),
!any(sL, na.rm=TRUE), all(!sL, na.rm=TRUE),
validObject(Matrix(c(NA,0), 4, 3, byrow = TRUE)),
validObject(Matrix(c(NA,0), 4, 4)))
stopifnotValid(Matrix(c(NA,0,0,0), 4, 4), "sparseMatrix")
I <- i1 <- I1 <- Diagonal(1)
## TODO? stopifnot(identical(I, Matrix(1, sparse=TRUE))) # doDiag=TRUE default
I1[1,1] <- i1[1, ] <- I [ ,1] <- NA
stopifnot(identical3(I,i1,I1))
image(d4) # gave infinite recursion
## Steve Walker, Mar 12, 2014:
n <- 7
(M <- triu(Matrix(seq_len(n^2), n, sparse=TRUE)))
im <- image(M) # was not an n-by-n image plot
stopifnot(n == diff(sort(im$y.limits)))
## ylimits were too small (by 1 on each side)
## Image of *empty* sparseMatrix (has failed in spite of claim in r3282 | 2018-08-20)
(Z <- Matrix(0, 11, 22)) # empty "dgCMatrix"
Z0 <- Z; Z0[1,1] <- 1; Z0@x <- 0 ## is also all 0, but not "empty"
stopifnot(all(Z == Z0))
image(Z)
## gave Error in seq.default(zrng[1], zrng[2], length.out = cuts + 2) : 'from' must be a finite number
image(Z, useAbs=FALSE) # gave *different* Error in seq.int... : 'length.out' must be ...
image(Z0,useAbs=FALSE) # (ditto)
image(Z0) # had worked previously already
showProc.time()
assertError( Matrix(factor(letters)) )
n.lsec <- length(.leap.seconds)# 27 (2017-07)
mlp <- matrix(.leap.seconds)## 27 x 1 numeric matrix
Mlp <- Matrix(.leap.seconds)
stopifnot(identical(dim(Mlp), c(n.lsec, 1L)))
assert.EQ.mat(Mlp, mlp)
lt.leap.seconds <- .LS <- as.POSIXlt(.leap.seconds, tz = "GMT") # GMT => sparse HMS
.LS <- unclass(.LS); .LS <- .LS[setdiff(names(.LS), "zone")]
# "zone" is character (not there for GMT/UTC in R <= 4.2.x)
(matLS <- data.matrix(data.frame(.LS)))
stopifnot(inherits(MLp <- as(matLS, "Matrix"), "sparseMatrix"),
is.EQ.mat(MLp, matLS))
printSpMatrix(MLp, col.names = TRUE) # nice sparse dgC* w/ col.names
(mLp <- matrix(lt.leap.seconds))## prints fine as 27 x 1 matrix of dates (internally is list+dim)
##
E <- rep(c(TRUE,NA,TRUE), length.out=8)
F <- new("nsparseVector", length = 8L, i = c(2L, 5L, 8L))
e <- as(E, "sparseVector"); f <- as(F,"lsparseVector")
Fv <- as.vector(F, "any") # failed in Matrix <= 1.2.0, and base::as.vector(.) failed too:
stopifnot(E | as.vector(F), identical(E | F, F | E),
all(e | f), all(E | F), # <- failed Ops.spv.spv
identical(Fv, base::as.vector(F)),
is.logical(Fv), which(Fv) == c(2,5,8))
F[-8:-1] # was partly "illegal" (length = 0 is ok; nnz '3' is not)
F.ineg <- lapply(1:8, function(k) F[-8:-k])
F.pos <- lapply(1:8, function(k) F[seq_len(k-1)])
F.vec <- lapply(1:8, function(k) Fv[seq_len(k-1)])
str(F.vec, vec.len=8)
(nT <- vapply(F.vec, sum, 1L)) # == 0 0 1 1 1 2 2 2
str(whichT <- lapply(F.vec, which))
i.lengths <- function(L) vapply(L, function(.) length(.@i), 1L)
stopifnot(exprs = {
identical(lengths(F.vec), 0:7)
identical(lengths(F.ineg), 0:7)
identical(lengths(F.pos), 0:7)
identical(i.lengths(F.pos), nT)
identical(i.lengths(F.ineg), nT) # failed before 2018-03-19
identical(lapply(F.pos, slot, "i"), whichT)
identical(lapply(F.ineg, slot, "i"), whichT) # failed before 2018-03-19
})
## Here, sparseVector '[' is really wrong:
SV <- new("nsparseVector", length = 30L,
i = c(1L, 8L, 9L, 12L, 13L, 18L, 21L, 22L))
NI <- -c(1:5, 7:10, 12:16, 18:27, 29,30)
sv <- SV[1:14]; ni <- -(1:14)[-c(6,11)] # smaller example
selectMethod("[", c("nsparseVector","index","missing","missing"))# the culprit
if(FALSE)
trace("[", browser, signature=c("nsparseVector","index","missing","missing"))
stopifnot(
SV[NI] == as.vector(SV)[NI] ## badly failed before 2018-03-19
,
sv[ni] == as.vector(sv)[ni] ## ditto
)
if(FALSE)
untrace("[", signature=c("nsparseVector","index","missing","missing"))
dT <- new("dgTMatrix",
i = c(1:2,1:2), j=rep(1:2, each=2), Dim = c(4L, 4L), x = c(1, 1, NA, 2))
dt <- new("dtTMatrix", i = 0:3, j = 0:3, Dim = c(4L, 4L), x = c(1,0,0,0),
uplo = "U", diag = "N")
c1 <- as(dT, "CsparseMatrix")
c2 <- as(dt, "CsparseMatrix")
isValid(lc <- c1 > c2,"lgCMatrix")
isValid(lt <- dT > dt,"lgCMatrix")
stopifnot(identical(lc,lt))
## Versions of Diagonal()
dD <- Diagonal(x = 5:1)
sD <- .symDiagonal(5, 5:1)
tD <- .trDiagonal (5, 5:1) # x= had failed for both
stopifnot(all(sD == dD)
, all(tD == dD)
, identical(sD, .symDiagonal(x = 5:1))
, identical(tD, .sparseDiagonal(x=5:1))
, identical(tD, .trDiagonal (x = 5:1)))# 'n' now has default
M <- Diagonal(4); M[1,2] <- 2 ; M
cM <- crossprod(M) # >> as_cholmod_l_triplet(): could not reallocate for internal diagU2N()
stopifnot(identical(cM, tcrossprod(t(M))))
S.na <- spMatrix(3, 4, c(1,2,3), c(2,3,3), c(NA,1,0))
(S.na <- S.na - 2 * S.na)
(L <- S.na != 0)
(Ln0 <- S.na != rep(0, prod(dim(L))))
.Lm0 <- S.na != Matrix(0, 3, 4)
stopifnot(Q.eq(L, Ln0), identical(Ln0, .Lm0)); rm(Ln0, .Lm0)
showProc.time()
### Unit-diagonal and unitriangular {methods need diagU2N() or similar}
I <- Diagonal(3)
(T <- as(I,"TsparseMatrix")) # unitriangular
(C <- as(I,"CsparseMatrix")) # (ditto)
lT <- as(T,"lMatrix")
lC <- as(C,"lMatrix")
stopifnot(
identical((n0 <- I != 0), Diagonal(3, TRUE)), I@diag == "U",
identical(n0, I & TRUE), identical(n0, I | FALSE),
identical(n0, TRUE & I), identical(n0, FALSE | I),
all(n0 == !(I == 0)), all(I == n0), identical(n0 == I, I == n0)
,
identical4(lT, as(Diagonal(3, x=TRUE),"TsparseMatrix"), T & TRUE, TRUE & T),
identical4(lC, as(Diagonal(3, x=TRUE),"CsparseMatrix"), C & TRUE, TRUE & C),
identical3(lT, T | FALSE, FALSE | T),
identical3(lC, C | FALSE, FALSE | C),
TRUE)
I[,1] <- NA; I[2,2] <- NA ; I[3,] <- NaN
stopifnotValid(I, "sparseMatrix")
I # gave error in printSpMatrix() - because of R bug in format.info()
L <- spMatrix(9, 30, i = rep(1:9, 3), 1:27, (1:27) %% 4 != 1)
M <- drop0(crossprod(L))
diag(M) <- diag(M) + 5 # to make it pos.def.
M. <- M[1:12,1:12] # small ex
N3 <- as(Matrix(upper.tri(diag(3))), "nMatrix")
stopifnotValid(bdN <- bdiag(N3, N3),"nsparseMatrix")
stopifnot(identical(L, L == TRUE), ## used to give infinite recursion
all(drop0((0 - L) != 0) == drop0(L)))
L[sample(length(L), 10)] <- NA
ll <- as(L,"logical")
stopifnot(all.equal(mean(L, na.rm=TRUE),
mean(ll, na.rm=TRUE), tolerance=1e-14),
all.equal(mean(L, na.rm=TRUE, trim=1/4),# <- with a warning
mean(ll, na.rm=TRUE, trim=1/4), tolerance=1e-14))
## Examples where is.na(.) was wrong:
validObject(sc <- new("dsCMatrix", i=as.integer(c(0,0:1,1:2,0:1,3)), Dim=c(4L,4L),
p = c(0L,1L,3L,5L,8L), x = c(0,NA,NA,0:1,0,NA,1)))
validObject(gc <- as(sc, "generalMatrix"))
stopifnot(isSymmetric(M), isSymmetric(M.),
is(bdiag(M., M.),"symmetricMatrix"),
is(bdN, "triangularMatrix"),
all(sc == gc | (is.na(sc) & is.na(gc))),
all.equal(N3,N3),
identical(all.equal(N3, t(N3)), all.equal.raw(1:6, 2:7)), # == "6 element mismatches"
all((bdN != t(bdN)) == (bdN + t(bdN))), # != failed to work...
!any((0+bdN) > bdN), # o
!any(bdN != (0+bdN)), # o
length(grep("Length", all.equal(M., (vM <- as.vector(M.))))) > 0,
identical(M., (M2 <- Matrix(vM, 12,12))),
all.equal(M., M2, tolerance =0)
)
Filter(function(.) inherits(get(.), "symmetricMatrix"), ls())
## [1] "M" "M." "M2" "cM" "d4T" "d4d" "o4" "sD" "sc"
cc <- kronecker(cM, Diagonal(x = c(10,1)))
dimnames(cc) <- list(NULL, cn <- letters[1:ncol(cc)])
stopifnotValid(cc, "dsCMatrix")
(tt <- as(cc, "TsparseMatrix")) # shows *symmetric* dimnames
stopifnot(identical3( cc @Dimnames, tt @Dimnames, list(NULL, cn)),
## t() does not reverse 'Dimnames' slot for symmetricMatrix
identical3(t(cc)@Dimnames, t(tt)@Dimnames, list(NULL, cn)),
identical3(dimnames(cc), dimnames(tt), list(cn, cn))) # now symmetric!
stopifnot(identical3(dimnames(cc),
dimnames(as(cc, "generalMatrix")), ## should fixup dimnames to *symmetric*
dimnames(as(tt, "generalMatrix"))))
## --> .Call(Csparse_symmetric_to_general, from)
mat <- as(cc, "matrix") ## --> should fixup dimnames to *symmetric*
mat # should print *symmetric* dimnames
stopifnot(identical3(dimnames(cc), dimnames(mat), dimnames(as(tt, "matrix"))))
selectMethod(coerce, c("dsCMatrix", "denseMatrix"))
dmat <- as(cc, "denseMatrix") ## --> gave Error (!!) in Matrix 1.1-5
stopifnot(identical3(tt@Dimnames, dmat@Dimnames, list(NULL, cn)))
dmat # should print *symmetric* dimnames (not modifying dmat as it did intermittently)
stopifnot(identical(dmat@Dimnames, list(NULL, cn)))
ttdm <- as(tt, "denseMatrix")
stopifnot(identical(dmat, ttdm),
identical(dimnames(cc), dimnames(dmat)),
## coercing back should give original :
identical(cc, as(dmat, "sparseMatrix")),
identical(asUniqueT(tt), as(ttdm, "TsparseMatrix")))
## MM: now *if* cc is "truly symmetric", these dimnames should be, too:
d5 <- cn[1:5]; dnm5 <- list(d5,d5)
stopifnot(identical(dimnames( cc [1:5, 1:5]), dnm5),
identical(dimnames(t(cc)[1:5, 1:5]), dnm5))
## large sparse ones: these now directly "go sparse":
str(m0 <- Matrix(0, nrow=100, ncol = 1000))
str(l0 <- Matrix(FALSE, nrow=100, ncol = 200))
stopifnot(all(!l0),
identical(FALSE, any(l0)))
if(!interactive()) warnings()
## really large {length() is beyond R's limits}:
op <- options(warn = 2) # warnings (e.g. integer overflow!) become errors:
n <- 50000L
stopifnot(n^2 > .Machine$integer.max)
## had integer overflow in index constructions:
x <- 1:n
D <- Diagonal(n, x=x[n:1])
summary(D)# special method
summary(D != 0)
stopifnot(identical(x*D, (Dx <- D*x)),
identical(D != 0, as(D, "lMatrix")),
identical(Dx, local({d <- D; d@x <- d@x * x; d})))
Lrg <- new("dgTMatrix", Dim = c(n,n))
l0 <- as(as(Lrg, "lMatrix"), "CsparseMatrix") # lgC
d0 <- as(l0, "dMatrix")
showProc.time()
if(FALSE) { #_____________________ FIXME: Should use cholmod_l_*() everywhere (?)____
## problem in Csparse_to_dense :
dl0 <- as(l0, "denseMatrix")
dd0 <- as(d0, "denseMatrix")
## currently, both give --- Error in asMethod(object) :
## Cholmod error 'problem too large' at file ../Core/cholmod_dense.c, line 105
##--> And there it is 'Int_max' ==> ../src/CHOLMOD/Include/cholmod_internal.h
## defines 'Int_max' and does that depending of "mode", and
## MM thinks we should use the "DLONG" mode now -- for 64-bit integers!
## ==> Then Int_max := SuiteSparse_long_max := LONG_MAX
## (the latter from ../src/SuiteSparse_config/SuiteSparse_config.h )
## ==> use cholmod_l_ instead of cholmod_ in *many places*
##
## check they are ok
stopifnot(identical(dim(dl0), c(n,n)), identical(dim(dd0), c(n,n)),
!any(dl0), all(dd0 == 0))
rm(dl0, dd0)# too large to keep in memory and pass to checkMatrix()
}
diag(Lrg[2:9,1:8]) <- 1:8
## ==: Lrg[2:9,1:8] <- `diag<-`(Lrg[2:9,1:8], 1:8)
options(warn = 1) # Matrix 1.5-0 (Sep 2022): we now warn when lots of memory is used
(memGB <- Sys.memGB("MemFree")) # from test-tools-1.R, only works with /proc/*
system.time( # ~10 sec. __vv__
e1 <- if(doExtras && is.finite(memGB) && memGB > 30) { # need around 18 GB
try(Lrg == Lrg)
## had Cholmod error 'problem too large' at file ../Core/cholmod_dense.c, line 105
## (error message almost ok)
}) # now works, taking 42.7 sec on ada-20 w/ 504 GB;
if(is(e1, "Matrix")) object.size(e1) # 10000001176 bytes
system.time( # ~10 sec. __vv__
e2 <- if(doExtras && is.finite(memGB) && memGB > 30) { # need around 18 GB
try(!Lrg) # now *works* on 64-bit machines with enough RAM
## and immediately errors if LONG_VECTORs are not available
}) ## when it works, see
## Warning in .sparse2dense(x) : sparse->dense coercion: allocating vector of size 9.3 GiB
## user system elapsed
## 6.812 10.744 17.612
str(e2) # error, NULL or "worked" (=> 50000 x 50000 lgeMatrix)
ina <- is.na(Lrg)# "all FALSE"
stopifnot(if(inherits(e1, "try-error")) grepl("too large", e1)
else is.null(e1) ||
(is(e1, "denseMatrix") && is(e1, "lMatrix")),
if(inherits(e2, "try-error")) grep("too large", e2) == 1
else is.null(e2) || length(e2@x) == n^2,
!any(ina))# <- gave warning previously
stopifnot(suppressWarnings(any(Lrg)))# (double -> logical warning)
rm(e1, e2)# too large...
## Matrix bug #6610, did segfault
system.time({ # ... sec __vv__
## FIXME: reproducible example (not using 'MatrixModels' which triggers) "Out of memory" etc
})
showProc.time()
RNGversion("3.6.0")# future proof
if(doExtras && is.finite(memGB) && memGB > 49) withAutoprint({
cat("computing SM .. \n")
showSys.time(m <- matrix(0, 3e6, 1024))
## user system elapsed
## 2.475 10.688 13.196 (faster in past ??)
set.seed(1); inot0 <- unique(sort(c(1, length(m), sample(length(m), 20))))
ai0 <- arrayInd(inot0, .dim=dim(m), useNames=FALSE)
showSys.time(m[inot0] <- 1:22)
## user system elapsed
## 5.931 11.184 17.162
showSys.time(SM <- as(m, "sparseMatrix")) # ~ 8 sec
## gave 'Error in asMethod(object) : negative length vectors are not allowed'
## now works - via C matrix_to_Csparse()
showSys.time(n0.m <- c(m) != 0) # logical (full, base R) matrix, 12 GB
## user system elapsed
## 14.901 10.789 25.776
try( ## _FIXME_ in R: Error ... long vectors not supported yet
in0.m <- which(n0.m)
)
## DONE: now very fast! [previously did coerce the whole matrix to dense first !]
subS <- SM[inot0]
selectMethod("[", c("dgCMatrix","numeric","missing","missing"))# -> .M.vectorSub(x,i)
## Directly via arrayInd(), is *FAST*:
subSij <- SM[ai0]
stopifnot(subS == 1:22, identical(subS, subSij))
cat(" [Ok]\n")
rm(m)
str(SM)
## checking SM:
TM <- as(SM, "TsparseMatrix")
stopifnot(as.matrix(summary(TM)) == cbind(ai0, 1:22))
## cleanup:
rm(SM, TM)
})
showProc.time()
## Constructing *packed* dense symmetric (dsp*) | triangular (dtp*) Matrices:
if(doExtras && is.finite(memGB) && memGB > 35) withAutoprint({
m <- as.integer(2^16) ## = 65536
showSys.time(x <- rep(as.numeric(1:100), length.out=m*(m+1)/2))
## user system elapsed
## 6.028 8.964 15.074
gc()
object.size(x) # 17'180'131'368 bytes: ~ 17 GB
mat <- new("dspMatrix", x = x, Dim = c(m, m)) # failed with
## long vectors not supported yet: ../../src/include/Rinlinedfuns.h:...
validObject(mat)
mat <- new("dtpMatrix", x = x, Dim = c(m, m)) # failed .......
validObject(mat)
## cleanup
rm(mat)
})
showProc.time()
options(warn = 2)# warnings => errors
## with dimnames:
v <- c(a=1, b=2:3)
m <- as.matrix(v)
(M <- as(v, "denseMatrix") )
stopifnot(identical(dimnames(m), list(c("a", "b1", "b2"), NULL)),
inherits(M, "dgeMatrix"),
identical(dimnames(M), dimnames(m)))
## dimnames(.) of symmpart() / skewpart() :
ns <- c("symmpart", "skewpart", "forceSymmetric")
symFUNs <- setNames(lapply(ns, get), ns); rm(ns)
chkSS <- function(m) {
r <- lapply(symFUNs, function(fn) fn(m))
m0 <- as(m, "matrix")
r0 <- lapply(symFUNs, function(fn) fn(m0))
stopifnotValid(fS <- r [["forceSymmetric"]], "symmetricMatrix")
stopifnotValid(fS0 <- r0[["forceSymmetric"]], "symmetricMatrix")
dnms <- dimnames(m)
d.sy <- dimnames(r[["symmpart"]])
id <- if(is.null(dnms[[2]]) && !is.null(dnms[[1]])) 1 else 2
stopifnot(identical(d.sy, dnms[c(id,id)]),
identical(d.sy, dimnames(r [["skewpart"]])),
if(identical(dnms, list(NULL, NULL)))
is.null(dimnames(r0[["skewpart"]]))
else identical(d.sy, dimnames(r0[["skewpart"]])),
all(m == with(r, symmpart + skewpart)),
all(m0 == with(r0, symmpart + skewpart)),
identical(dS <- dimnames(fS), dimnames(fS0)),
identical(dS[1], dS[2]))
}
cat(sprintf("chkSS() {valid %s} for a list of matrices:\n",
paste(paste0(names(symFUNs), "()"), collapse=", ")))
L <- list(M1 = Matrix(1:4, 2,2),
M2 = Matrix(c(0, rep(1:0, 3),0:1), 3,3))
L$M3 <- pack(as(forceSymmetric(L$M2), "denseMatrix"))
stopifnotValid(L$M3, "dspMatrix")
for(m in L) {
cat("\n---\nm:\n"); show(m)
chkSS(m)
dn <- list(row = paste0("r", 1:nrow(m)), col = paste0("var.", 1:ncol(m)))
dimnames(m) <- dn ; chkSS(m)
colnames(m) <- NULL ; chkSS(m)
dimnames(m) <- unname(dn) ; chkSS(m)
}
m. <- matrix(c(0, 0, 2:0), 3, 5)
dimnames(m.) <- list(LETTERS[1:3], letters[1:5])
(m0 <- m <- Matrix(m.))
m@Dimnames[[2]] <- m@Dimnames[[1]]
## not valid anymore:
(val <- validObject(m, test=TRUE)); stopifnot(is.character(val))
dm <- as(m0, "denseMatrix"); rm(m)
stopifnot(all.equal(rcond(dm), rcond(m.), tolerance = 1e-14),
##^^^^^^^ dm and m. are both dense, interestingly small differences
## show in at least one case of optimized BLAS
all.equal(rcond(dm), 0.4899474520656),
## show() had revealed a bug in C:
identical(capture.output(show(as(m0, "RsparseMatrix")))[-(1:2)],
gsub("0", ".", capture.output(show(m.))[-1])))
m.1 <- m.; dimnames(m.1) <- list(row=NULL, col=NULL)
M.1 <- Matrix(m.1, sparse=TRUE)
show(M.1)# had bug in .formatSparseSimple()
showProc.time()
###-- Sparse Triangular :
g5 <- new("dgCMatrix", Dim = c(5L, 5L),
x = c(10, 1, 3, 10, 1, 10, 1, 10, 10),
i = c(0L,2L,4L, 1L, 3L,2L,4L, 3L, 4L),
p = c(0L, 3L, 5L, 7:9))
t5 <- as(g5, "triangularMatrix") # fine
stopifnot(class(t5) == "dtCMatrix",
identical(t5, tril(g5)))
## This is really a regression test for 'methods::selectMethod()'
## Maybe move to R once 'Matrix' is recommended
sm <- selectMethod(coerce, c("dgCMatrix", "triangularMatrix"), verbose=TRUE)
stopifnot(identical(sm(g5), t5))
dimnames(t5) <- list(row=paste0("r",1:5), col=paste0("C.",1:5))
s5 <- symmpart(t5) # gave an error
showProc.time()
(t1 <- new("dtTMatrix", x= c(3,7), i= 0:1, j=3:2,
Dim= as.integer(c(4,4))))
## Diagonal o Sparse
I4 <- Diagonal(4)
D4 <- Diagonal(4, x=1:4)
validObject(t1)
validObject(t2 <- t1 + I4)
validObject(tt2 <- t(t1) + I4)
validObject(t1c <- as(t1, "CsparseMatrix"))
validObject(t2c <- as(t2, "CsparseMatrix"))
stopifnotValid(2 * I4, "diagonalMatrix")
stopifnotValid(D4 * 3, "diagonalMatrix")
stopifnotValid(I4 / 5, "diagonalMatrix")
stopifnotValid(D4 / 2, "diagonalMatrix")
stopifnotValid(t1c + I4,"triangularMatrix")
stopifnotValid(t2c + I4,"triangularMatrix")
stopifnot(identical(t1, t(t(t1))),
identical(t1c, t(t(t1c))),
c(class(t2), class(t1c), class(t2c), class(tt2)) == "dtCMatrix",
identical(t(tt2), t2))
assert.EQ.mat(t1, as(t1c, "matrix"))
D4. <- D4 * (A4 <- Matrix(1:4, 4,4))
D4p <- A4 + D4
Lg1 <- D4 > 0 & D4 > 1
nLg <- !Lg1
nnLg <- !nLg
D4m <- D4 * 4:1
assert.EQ.mat(D4., diag(x= (1:4)^2))
assert.EQ.mat(D4p, diag(x= (1:4)) + (1:4))
assert.EQ.mat(D4m, diag(x=c(4,6,6,4)))
assert.EQ.mat(Lg1, diag(x= c(FALSE, rep(TRUE,3))))
stopifnot(is(Lg1, "diagonalMatrix"), is(D4m, "diagonalMatrix"),
is(D4., "diagonalMatrix"),
is(nLg, "generalMatrix"), is(nnLg, "generalMatrix"),
identical3(Lg1,
Matrix(nnLg, forceCheck = TRUE),
as(nnLg, "diagonalMatrix")),
all(Lg1 != (!Lg1)))
## tri[lu]()
td3 <- triu(diag(3)); stopifnot(is(td3, "triangularMatrix"), td3@uplo == "U")
Ld3 <- tril(diag(3)); stopifnot(is(Ld3, "triangularMatrix"), Ld3@uplo == "L")
## the latter did fail till 2014-12-20
D3 <- Diagonal(3)
stopifnot(identical3(D3, tril(D3), triu(D3)))
## methods were missing
showProc.time()
## as(, ) :
str(cls <- names(getClass("Matrix")@subclasses))# all Matrix classes
## Matrix >= 1.4.2 : (basically) only coerce to virtual classes:
table(isVirt <- vapply(cls, isVirtualClass, NA))
for(cl in cls[isVirt])
if(canCoerce(I4, cl)) {
cat(cl,":")
M <- as(I4, cl)
M. <- as(D4, cl)
stopifnot(diag(4) == as(M,"matrix"),
if(is(cl,"dMatrix")) diag(x=1:4) == as(M.,"matrix") else TRUE)
cat(" [Ok]\n")
}
s4 <- as(D4,"sparseMatrix")
v <- c(11,2,2,12); s4[2:3,2:3] <- v; validObject(s4)
s4. <- D4; s4.[2:3,2:3] <- v; validObject(s4.)
stopifnot(all(s4 == s4.))
## now assign symmetrically to symmetricMatrix
s4 <- as(as(D4,"sparseMatrix"),"symmetricMatrix")
s4[2:3,2:3] <- v
validObject(s4)
stopifnot(is(s4,"symmetricMatrix"))
assert.EQ.mat(s4, as(s4.,"matrix"),tol=0)
## lower-triangular unit-diagonal
L <- new("dtCMatrix", i = 1L, p = c(0:1, 1L), Dim = c(2L, 2L),
x = 0.5, uplo = "L", diag = "U")
stopifnot(range(L) == 0:1, all.equal(mean(L), 5/8))
## from 0-diagonal to unit-diagonal triangular {low-level step}:
tu <- t1 ; tu@diag <- "U"
tu
validObject(cu <- as(tu, "CsparseMatrix")) # still unitriangular
validObject(cnu <- diagU2N(cu))# <- testing diagU2N
validObject(tt <- as(cu, "TsparseMatrix"))
tu. <- tt ## validObject(tu. <- as(cu, "dtTMatrix"))
stopifnot(exprs = { ## NOT: identical(tu, tu.), # since T* is not unique!
identical(cu, as(tt, "CsparseMatrix"))
length(cnu@i) == length(cu@i) + nrow(cu)
identical(cu, diagN2U(cnu)) # <- testing diagN2U
all(cu >= 0, na.rm = TRUE)
all(cu >= 0)
any(cu >= 7)
})
validObject(tcu <- t(cu))
validObject(ttu <- t(tu))
validObject(ltu <- as(ttu, "lMatrix"))
validObject(ldtu <- as(ltu, "denseMatrix"))
validObject(Cltu <- as(ltu, "CsparseMatrix"))
stopifnot(identical(asCsp(ttu > 0), asCsp(ltu)),
all(ltu == as(ttu > 0,"denseMatrix")))
ltu - (ttu > 0) # failed
assert.EQ.mat(cu, as(tu,"matrix"), tol=0)
assert.EQ.mat(cnu, as(tu,"matrix"), tol=0)
showProc.time()
C <- suppressWarnings(Matrix(c(0,1,0,0), 5,5)) + Diagonal(5)
(tU <- diagN2U(tril(C))) # dtC Unitriangular
ntU <- as(tU, "nMatrix")
nT <- as(ntU, "TsparseMatrix")
R <- as(tU, "RsparseMatrix")
Tt <- diagU2N(R) # used to accidentally drop the diag.
stopifnot(R@x == c(1,1,1), diag(Tt) == 1)
lcu <- new("ltCMatrix", Dim = c(4L, 4L), i = c(0:1, 0L), p = c(0L, 0:3),
x = c(TRUE, FALSE, FALSE), uplo = "U", diag = "U")
(lTu <- as(lcu,"TsparseMatrix"))# prints wrongly (in Matrix 0.999375-31)
stopifnot(identical3(rowSums(lcu), rowSums(lTu), rowSums(drop0(lcu))))
(ncu <- as(lcu, "nMatrix"))# -- gives the "pattern" of lcu, i.e. FALSE are *there*
ncn <- diagU2N(ncu)
(cncn <- crossprod(ncn))# works -> "nsCMatrix"
stopifnot(identical(ncu, as(lcu,"nsparseMatrix")),
identical(rowSums(ncu), c(3:1, 1L)),
Q.eq(ncn, ncu),
Q.eq(crossprod(drop0(lcu)), crossprod(lcu)),# crossprod works -> "dsCMatrix"
identical(crossprod(ncu), cncn),
Q.eq(cncn, t(ncu) %&% ncu)) #used to seg.fault
U <- new("dtCMatrix", Dim = c(6L, 6L),
i = c(0:1, 0L, 2:3, 1L, 4L),
p = c(0L,0L,0L, 2:3, 5L, 7L),
x = rep.int(-0.5, 7), diag = "U")
validObject(U)
U. <- solve(iU <- solve(U))#-> gave segmentation fault
stopifnot(validObject(U), ## had a case where solve(U) modified U !
validObject(iU),
validObject(U.),
## no rounding error, since have iU@x * 8 is integer :
identical(U, diagN2U(drop0(U.))))
showProc.time()
## o (of length > 1):
stopifnotValid(tm <- tu * 1:8, "sparseMatrix")
stopifnot(identical4(tm, cu * 1:8, 1:8 * cu, 1:8 * tu))
cu[1,2] <- tu[1,2] <- NA
mu <- as(tu,"matrix")
stopifnotValid(cu, "CsparseMatrix"); stopifnotValid(cu, "triangularMatrix")
stopifnotValid(tu, "TsparseMatrix"); stopifnotValid(tu, "triangularMatrix")
stopifnot(identical(cu * 1:8, tu * 1:8), # but are no longer triangular
identical(cu > .1, as(tu > .1, "CsparseMatrix")),
all(cu >= 0, na.rm=TRUE), !all(cu >= 1), is.na(all(tu >= 0)),
## Csparse_drop: preserves triangularity incl diag="U"
## ^^^^^^^^^^^^ now using more general R_sparse_drop0
identical(cu, .Call(Matrix:::R_sparse_drop0, cu, 0.))
)
assert.EQ.mat(cu * 1:8, mu * 1:8)
ina <- is.na(as(cu,"matrix"))
## These 3 were each different (2008-03) !!
stopifnot(all(ina == is.na(cu)),
all(ina == is.na(as(cu,"generalMatrix"))),
all(ina == as(is.na(as(cu,"matrix")),"nMatrix")))
set.seed(7)
xx <- rpois(10, 50)
Samp <- function(n,size) sample(n, size, replace=TRUE)
Tn <- sparseMatrix(i=Samp(8, 50), j=Samp(9,50), x=xx, repr = "T")
Tn
stopifnot(xx == Tn@x,
max(xx) < max(Tn), 0 == min(Tn),
(sT <- sum(Tn)) == sum(colSums(Tn)), sT == sum(Tn@x),
range(Tn) == range(as(Tn, "CsparseMatrix")))
## tu. is diag "U", but tu2 not:
tu2 <- as(as(tu., "generalMatrix"), "triangularMatrix")
assert.EQ.mat(cu, mu, tol=0)
stopifnot(identical3(cu[cu > 1], tu [tu > 1], mu [mu > 1]),
identical3(cu <= 1, tu <= 1, as(mu <= 1, "lMatrix")),# all lgeMatrix
identical3(cu[cu <= 1], tu[tu <= 1], mu[mu <= 1]),
identical3(cu , triu(cu ), t(t(cu))),
identical3(tu , triu(tu ), t(t(tu))),
identical3(tu., triu(tu.), t(t(tu.))),
identical(tu2, triu(tu2)),
identical(tcu , tril(tcu)),
identical(ttu , tril(ttu)),
identical(t(tu), tril(t(tu)))
)
assert.EQ.mat(triu(cu), as(triu(as(cu, "matrix")), "matrix"))
for(k in -1:1)
assert.EQ.mat(tril(cu,k), as(tril(as(cu, "matrix"), k), "matrix"))
(dtr <- Matrix(local({m <- diag(2); m[1,2] <- 3;m})))
identical(dtr, triu(dtr))
assert.EQ.mat(tril(dtr), diag(2))
(t4 <- new("dgTMatrix", i = 3:0, j = 0:3, x = rep(1,4), Dim = as.integer(c(4,4))))
c4 <- as(t4, "CsparseMatrix")
## the same but "dsT" (symmetric)
suppressWarnings(M <- Matrix(c(0, rep(c(0,0:1),4)), 4,4))# warning:.. length [13] is not ..multiple
tt <- as(M, "TsparseMatrix")
stopifnot(all.equal(triu(t4) + tril(t4), c4),
all.equal(triu(tt) + tril(tt), c4))
showProc.time()
###-- Numeric Dense: Crossprod & Solve
set.seed(123)
mm. <- mm <- Matrix(rnorm(500 * 150), ncol = 150)
stopifnot(validObject(mm))
xpx <- crossprod(mm)
stopifnot(identical(mm, mm.))# once upon a time, mm was altered by crossprod()
stopifnotValid(xpx, "dpoMatrix")
str(mm) # 'dge*"
str(xpx)# 'dpo*"
xpy <- crossprod(mm, rnorm(500))
res <- solve(xpx, xpy)
str(xpx)# now with Cholesky factor
stopifnot(validObject(xpx),
validObject(xpy),
validObject(res))
stopifnot(all.equal(xpx %*% res, xpy, tolerance = 1e-12))
lp <- xpx >= 1
slp <- as(lp, "sparseMatrix")
ltlp <- lp[ lower.tri(lp) ]
sltlp <- slp[ lower.tri(slp) ]
dim(ij <- which(lower.tri(lp), arr.ind = TRUE))
ss <- slp[ij] # now fast (!)
stopifnot(identical4(lp[ij], ltlp, sltlp, as(lp, "matrix")[ij]),
identical(ss, sltlp),
isValid(lp, "lsyMatrix"), lp@uplo == "U")
showProc.time()
###-- more solve() methods {was ./solve.R }
## first for "dgeMatrix" and all kinds of RHS :
(m6 <- 1 + as(diag(0:5), "generalMatrix"))
rcond(m6)
I6 <- as(diag(6), "generalMatrix")
stopifnot(all.equal(I6, m6 %*% solve(m6)),
all.equal(I6, solve(m6) %*% m6) )
(i6 <- solve(m6, Matrix(1:6)))
stopifnot(identical(i6, as(cbind(c(-4, rep(1,5))), "generalMatrix")),
identical(drop(i6), solve(m6, 1:6)),
identical(i6, solve(m6, matrix(1:6))),
identical(i6, solve(m6, matrix(c(1,2,3,4,5,6))))
)
## solve()
(m <- t1+ t(t1) + Diagonal(4))
i.m <- solve(as.mat(m))
I1 <- m %*% i.m
o4 <- diag(I1)
im <- solve(m)# is now sparse {not yet}
(I2 <- m %*% im)
(ms <- as(m, "symmetricMatrix"))
## solve(, ):
s.mm <- solve(m,m)
s.mms <- solve(m, ms)
## these now work "fully-sparse"
s.ms2 <- solve(ms, ms)
s.msm <- solve(ms, m)
I4c <- as(Matrix(diag(4),sparse=TRUE), "generalMatrix")
stopifnot(isValid(im, "Matrix"), isValid(I2, "Matrix"), class(I4c) == "dgCMatrix",
all.equal(I1, as(I2,"denseMatrix"), tolerance = 1e-14),
all.equal(diag(4), as.mat(I2), tolerance = 1e-12),
all.equal(s.mm, I2, tolerance = 1e-14),
all.equal(s.mms, I2, tolerance = 1e-14),
all.equal(s.ms2, s.msm, tolerance = 4e-15),
all.equal(s.ms2, I4c , tolerance = 4e-15),
abs(o4 - 1) < 1e-14)
image(T125 <- kronecker(kronecker(t5,t5),t5),
main = paste("T125:",class(T125)))
dim(T3k <- kronecker(t5,kronecker(T125, t5)))
system.time(IT3 <- solve(T3k))# incredibly fast
I. <- drop0(zapsmall(IT3 %*% T3k))
I.. <- diagN2U(I.)
I <- Diagonal(5^5)
stopifnotValid(IT3, "dtCMatrix")
stopifnot(## something like the equivalent of all(I. == Diagonal(3125)) :
identical(as(I., "diagonalMatrix"), I),
identical(as(I..,"diagonalMatrix"), I)
)
showProc.time()
## printSpMatrix() ; "suppressing (columns | rows) .." {and do it correctly!}
IT3
op0 <- options(width = 70, max.print = 1000)
T125[-(1:50),] ## suppression ... is it correctly done?
## Still buggy -- FIXME: see ../TODO --- even if we'd require max.print >= 5 or so
for(mm in 1:21) {
options(max.print=mm)
cat("----------\n\nmax.print=",mm,":\n", sep="")
cat("\n>> U: ") ; show(U)
cat("\n>> slp: ") ; show(slp)
}
options(op0)# revert to max.print = 1000
###-- row- and column operations {was ./rowcolOps.R }
set.seed(321)
(m1 <- round(Matrix(rnorm(25), 5), 2))
m1k <- Matrix(round(rnorm(1000), 2), 50, 20)
m.m <- as(m1k, "matrix")
stopifnot(all.equal(colMeans(m1k), colMeans(m.m)),
all.equal(colSums (m1k), colSums (m.m)),
all.equal(rowMeans(m1k), rowMeans(m.m)),
all.equal(rowSums (m1k), rowSums (m.m)),
all.equal(colMeans(m1k, na.rm=TRUE), colMeans(m.m, na.rm=TRUE)),
all.equal(colSums (m1k, na.rm=TRUE), colSums (m.m, na.rm=TRUE)),
all.equal(rowMeans(m1k, na.rm=TRUE), rowMeans(m.m, na.rm=TRUE)),
all.equal(rowSums (m1k, na.rm=TRUE), rowSums (m.m, na.rm=TRUE)) )
###-- kronecker for nonsparse uses Matrix(.):
stopifnotValid(kr <- kronecker(m1, m6), "Matrix")
assert.EQ.mat(kr,
kronecker(as(m1, "matrix"),
as(m6, "matrix")), tol = 0)
## sparse:
(kt1 <- kronecker(t1, tu))
kt2 <- kronecker(t1c, cu)
stopifnot(identical(as(kt1, "CsparseMatrix"), kt2))
ktf <- kronecker(as(t1, "matrix"), as(tu, "matrix"))
if(FALSE) # FIXME? our kronecker treats "0 * NA" as "0" for structural-0
assert.EQ.mat(kt2, ktf, tol= 0)
(cs1 <- colSums(kt1))
NA.or.True <- function(x) is.na(x) | x
eq <- (cs1 == colSums(as(kt1, "matrix")))
stopifnot(NA.or.True(eq), identical(is.na(eq), is.na(cs1)))
nt1 <- as(kt1, "nMatrix") # no NA's anymore
(ng1 <- as(as(nt1, "generalMatrix"),"CsparseMatrix")) # ngC
dg1 <- as(ng1, "dMatrix")# dgC
lt1 <- kt1 > 5
nt1 <- as(lt1, "nMatrix")
(colSums(nt1, sparseResult = TRUE))
(colSums(kt1, sparseResult = TRUE)) # dsparse, with NA
(colSums(lt1, sparseResult = TRUE)) # isparse, with NA
(colSums(lt1, sparseResult = TRUE, na.rm = TRUE))
(colSums(nt1, sparseResult = TRUE)) # isparse, no NA
## check correct sparseness of both:
for(M in list(kt1, nt1, ng1, dg1, lt1, nt1)) {
m <- as(M, "matrix")
for(na.rm in c(FALSE,TRUE)) {
cs <- colSums(M, na.rm = na.rm)
cs. <- colSums(M, na.rm = na.rm, sparseResult = TRUE)
rs <- rowSums(M, na.rm = na.rm)
rs. <- rowSums(M, na.rm = na.rm, sparseResult = TRUE)
stopifnotValid(cs., "sparseVector")
stopifnotValid(rs., "sparseVector")
stopifnot(identical(cs, as(cs., "vector")),
identical(rs, as(rs., "vector")),
{eq <- cs == colSums(m, na.rm = na.rm) ; ineq <- is.na(eq)
all(ineq | eq) && identical(ineq, is.na(cs)) },
{eq <- rs == rowSums(m, na.rm = na.rm) ; ineq <- is.na(eq)
all(ineq | eq) && identical(ineq, is.na(rs)) } )
}
}
i1 <- cs. == 1
cs2 <- cs.
cs2[i1] <- 0 # failed in *-31 !!
## now *index* with a NA-sparseVector :
i2 <- i1 ; i2[3] <- NA ; li2 <- as.logical(i2)
cs3 <- cs. ; cs3 [i2] <- 0
v3 <- as(cs.,"vector"); v3[li2] <- 0
cs4 <- cs. ; cs4[li2] <- 0
stopifnot(length(i1@x) == 2, identical(li2, as(i2,"vector")),
identical(cs3, cs4),
cs3 == v3, all(as(v3, "sparseVector") == cs3)
## indexing simple "numeric" with sparseVector:
## see 'R_FIXME' in ../R/sparseVector.R
## , identical(v3[i2], v3[li2])
## TODO:
## sub-assigning into simple "numeric" with sparseVector index:
)
showProc.time()
M <- Matrix(c(2:0,1),2); M. <- as(M, "sparseMatrix")
(N <- as(crossprod(kronecker(diag(2), M)) > 0,
"nMatrix"))
(L. <- as(N,"lMatrix"))
stopifnot(identical(N, as(L.,"nMatrix")),
identical(kronecker( c(1,0), M),
kronecker(cbind(1:0), M)))
assert.EQ.mat(kronecker(M, c(1,0,0)),
kronecker(as(M, "matrix"), c(1,0,0)))
## coercion from "dpo" or "dsy"
xx <- as(xpx, "dsyMatrix")
stopifnot(isSymmetric(xxS <- as(xx, "sparseMatrix")),
isSymmetric(xpxS <- as(xpx, "sparseMatrix")))
tm <- matrix(0, 8,8)
tm[cbind(c(1,1,2,7,8),
c(3,6,4,8,8))] <- c(2,-30,15,20,80)
(tM <- Matrix(tm)) ## dtC
(mM <- Matrix(m <- (tm + t(tm)))) ## dsC
mT <- as(mM, "TsparseMatrix")
gC <- as(as(mT, "generalMatrix"), "CsparseMatrix")
lT <- as(Matrix(TRUE, 2, 2), "TsparseMatrix")
## Check that mT, lT, and gC print properly :
pr.mT <- capture.output(mT)
pr.lT <- capture.output(lT)[-(1:2)]
nn <- unlist(strsplit(gsub(" +\\.", "", sub("^....", "", pr.mT[-(1:2)])), " "))
stopifnot(as.numeric(nn[nn != ""]) == m[m != 0],
identical(1:2, grep("|", pr.lT, fixed=TRUE)),
identical(pr.lT, capture.output(as(lT, "nMatrix"))[-(1:2)]),
capture.output(gC)[-1] == pr.mT[-1])
assert.EQ.mat(tM, tm, tol=0)
assert.EQ.mat(gC, m, tol=0)
assert.EQ.mat(mT, m, tol=0)
stopifnotValid(mM, "dsCMatrix")
stopifnotValid(tM, "dtCMatrix")
stopifnot(identical(mT, as(mM, "TsparseMatrix"))
, identical(gC, as(mM, "generalMatrix"))
## coercions general <-> symmetric
, identical(as(mM. <- as(mM, "generalMatrix"), "symmetricMatrix"), mM)
, identical(as(as(mM., "TsparseMatrix"), "symmetricMatrix"), mT)
, identical(as(as(tM, "generalMatrix"),"triangularMatrix"), tM)
, identical(tM + Diagonal(8), tMD <- Diagonal(8) + tM)
)
stopifnotValid(tMD, "dtCMatrix")
eM <- eigen(mM) # works thanks to base::as.matrix hack in ../R/zzz.R
stopifnot(all.equal(eM$values,
{ v <- c(162.462112512353, 30.0665927567458)
c(v, 15, 0, 0, 160-v[1], -15, -v[2])}, tolerance=1e-14))
##--- symmetric -> pos.def. needs valid test:
m5 <- Matrix(diag(5) - 1)
assertError(as(m5, "dpoMatrix"))# not pos.definite!
pm5 <- as(m5, "packedMatrix") # packed
assertError(as(pm5, "dppMatrix"))# not pos.definite!
sm <- as(Matrix(diag(5) + 1), "packedMatrix")
pm <- as(sm,"dpoMatrix")## gave infinite recursion (for a day or so)
pp <- as(pm,"dppMatrix")
x <- round(100 * crossprod(Matrix(runif(25),5)))
D <- Diagonal(5, round(1000*runif(5)))
px <- pack(x)
stopifnot(is(x, "dsyMatrix"), is(px, "dspMatrix"), is(D, "ddiMatrix"))
class(x+D)#--> now "dsyMatrix"
stopifnot(is(x+D, "symmetricMatrix"),
is(D+px, "dspMatrix"),
identical(x+D, D+x), identical(px+D, D+px), identical(pack(x-D), px-D))
tx <- tril(x)
ptx <- pack(tx)
stopifnot(is(tx, "dtrMatrix"), is(ptx, "dtpMatrix"),
is(t(tx), "dtrMatrix"), is(t(ptx), "dtpMatrix"),
is(D + tx, "dtrMatrix"), is(tx + D, "dtrMatrix"),
is(ptx + D, "dtpMatrix"), is(D + ptx, "dtpMatrix"))
showProc.time()
###-- dense nonzero pattern:
class(m <- Matrix(TRUE,2,2)) # lsy
isValid(n <- as(m, "nMatrix"), "nsyMatrix")
## 1)
as(n,"CsparseMatrix") # used to give CHOLMOD error: invalid xtype...
ls2 <- as(m, "CsparseMatrix") # works fine
## and really 'm' and 'n' are interally slot identical (!!!)
as(n,"sparseMatrix")
as(m,"sparseMatrix")
### -- now when starting with nsparse :
nT <- new("ngTMatrix",
i = as.integer(c(0, 1, 0)),
j = as.integer(c(0, 0, 1)), Dim = as.integer(c(2,2)))
(nC <- as(nT, "CsparseMatrix"))
str(nC)# of course, no 'x' slot
tt <- as(nT,"denseMatrix") # nge (was lge "wrongly")
stopifnot(is(tt,"ngeMatrix"),
identical(as(tt, "lMatrix"),
as(as(nT, "lMatrix"), "denseMatrix")))
tt
as(nC,"denseMatrix")
showProc.time()
###-- sparse nonzero pattern : ----------
(nkt <- as(as(as(kt1, "CsparseMatrix"), "generalMatrix"), "nMatrix"))# ok
dkt <- as(nkt, "denseMatrix")
(clt <- crossprod(nkt))
stopifnotValid(nkt, "ngCMatrix")
stopifnotValid(clt, "nsCMatrix")
suppressWarnings(crossprod(clt)) ## warning "crossprod() of symmetric ..."
## a Csparse with *repeated* entry is not valid!
assertError(new("ngCMatrix", p = c(0L,2L), i = c(0L,0L), Dim = 2:1))
### "d" <-> "l" for (symmetric) sparse : --------------------------------------
data(KNex, package = "Matrix")
mm <- KNex$mm
xpx <- crossprod(mm)
## extract nonzero pattern
nxpx <- as(xpx, "nMatrix")
show(nxpx) ## now ok, since subsetting works
r <- nxpx[1:2,]
lmm <- as(mm, "lMatrix")
nmm <- as(lmm, "nMatrix")
xlx <- crossprod(lmm)
x.x <- crossprod(nmm)
## now A = lxpx and B = xlx should be close, but not quite the same
## since = 0 is well possible when x!=0 and y!=0 .
## However, A[i,j] != 0 ==> B[i,j] != 0:
A <- as(as(nxpx, "lMatrix"), "TsparseMatrix")
B <- as(as(xlx, "lMatrix"), "TsparseMatrix")
ij <- function(a) a@i + ncol(a) * a@j
stopifnot(all(ij(A) %in% ij(B)))
l3 <- upper.tri(matrix(,3,3))
validObject(c3 <- as(l3, "CsparseMatrix"))
stopifnotValid(c3, "lMatrix")# lgC
(M <- Matrix(l3))
stopifnotValid(M, "ltCMatrix")
stopifnotValid(M2 <- M %x% M, "triangularMatrix") # is "dtT" (why not "dtC" ?)
stopifnot(dim(M2) == c(9,9), identical(M2, kronecker(M,M)))
M3 <- M %x% M2 #ok
(cM3 <- colSums(M3, sparseResult=TRUE))
identical(as.vector(cM3),
as(rev(rowSums(M3, sparseResult=TRUE)), "vector"))
M. <- M2 %x% M # gave infinite recursion
## diagonal, sparse & interactions
stopifnotValid(as(Diagonal(3), "TsparseMatrix"), "TsparseMatrix")
stopifnotValid(X <- Diagonal(7) + 1.5 * tM[1:7,1:7], "sparseMatrix")
stopifnotValid(X, "triangularMatrix")
stopifnotValid(XX <- X - chol(crossprod(X)), "triangularMatrix")
X
XX
XX <- as(drop0(XX), "symmetricMatrix")
stopifnot(identical(XX, Matrix(0, nrow(X), ncol(X), doDiag=FALSE)))
M <- Matrix(m., sparse = FALSE)
(sM <- Matrix(m.))
class(dlM <- M >= 1)
stopifnot(identical(dlM, !(M < 1)))
stopifnotValid(sM, "sparseMatrix")
stopifnotValid(dlM, "denseMatrix")
(lM <- as(dlM, "sparseMatrix"))
lM2 <- as(dlM, "CsparseMatrix") #-> now ok
lM0 <- .dense2sparse(dlM, "C")
stopifnot(identical3(lM, lM2, lM0))
selectMethod("coerce", c("lgeMatrix", "CsparseMatrix"),
useInherited = c(from = TRUE, to = FALSE))
ms0 <- Matrix(c(0,1,1,0), 2,2)
ms <- as(ms0, "TsparseMatrix")
cs <- as(ms, "CsparseMatrix")
ll <- as(ms, "lMatrix")
lt <- as(ll, "generalMatrix")
nn <- as(cs, "nsparseMatrix")
l2 <- as(cs, "lsparseMatrix")
nt <- triu(nn)
n3 <- as(nt, "lsparseMatrix")
da <- nt + t(nt)
dm <- nt * t(nt) + da
##
mnt <- as(nt, "matrix")
m <- rbind(v <- 2:3)
assert.EQ.mat(nt %*% v, mnt %*% v)
assert.EQ.mat(v %*% nt, v %*% mnt)
assert.EQ.mat( crossprod(nt, v), crossprod(mnt,v))
assert.EQ.mat( crossprod(v, nt), crossprod(v,mnt))
assert.EQ.mat(tcrossprod(v, nt), tcrossprod(v,mnt))
assert.EQ.mat(tcrossprod(nt, m), tcrossprod(mnt, m))
##
stopifnotValid(ms, "dsTMatrix")
stopifnot(as(ms0,"matrix") == as(ll, "matrix"), # coercing num |-> log
as(lt, "matrix") == as(ll, "matrix"),
identical(ms, as(ll, "dMatrix")),
identical4(as(ll, "CsparseMatrix"), as(cs, "lMatrix"),# lsC*
as(nn, "lsparseMatrix"), l2),
identical3(da, dm, as(cs, "generalMatrix")), # dgC*
identical(as(da, "lMatrix"), as(lt, "CsparseMatrix")) # lgC*
)
## Dense *packed* ones:
s4 <- as(D4, "symmetricMatrix")
sp <- as(s4, "packedMatrix")
tp <- triu(sp)
tpL <- tril(sp)
(spL <- t(sp))
stopifnot(sp @uplo=="U", tp @uplo=="U",
spL@uplo=="L", tpL@uplo=="L")
## band():
n <- 4 ; m <- 6
r1 <- Matrix(1:24, n,m)
validObject(M1 <- band(r1, 0,0))
(M1 <- as(M1, "sparseMatrix"))
r2 <- Matrix(1:18, 3, 6)
stopifnot(identical(M1, bandSparse(n,m, k=0, diagonals = list(diag(r1)))),
identical(band(r2, 0,4),
band(r2, 0,3) + band(r2, 4,4)))
s1 <- as(r1, "sparseMatrix") # such that band(s1) is sparse, too
for(k1 in (-n):m)
for(k2 in k1:m) {
stopifnotValid(br1 <- band(r1, k1,k2), "ddenseMatrix")
stopifnotValid(bs1 <- band(s1, k1,k2), "CsparseMatrix")
stopifnot(all(r1 == s1))
}
showProc.time()
## large dimensions -- gave integer overflow
## R-forge bug 6743 by Ariel Paulson
## https://r-forge.r-project.org/tracker/?func=detail&atid=294&aid=6743&group_id=61
n <- 47000
stopifnotValid(Mn <- sparseMatrix(i = rep(1:6, 2), dims = c(n,n),
j = c(1L,4L, 6:8, 10:12, 16:19)), "nsparseMatrix")
stopifnotValid(M <- as(Mn, "dMatrix"), "dgCMatrix")
dim(M) # 47000 47000
i <- 46341
stopifnotValid(bM <- band(M, i, i ), "dtCMatrix")
## gave Error in if (sqr && k1 * k2 >= 0) ....
## In addition: Warning message:
## In k1 * k2 : NAs produced by integer overflow
x <- 1:999
bM2 <- bandSparse(n, k=i+(0:3), diagonals = list(x,10*x,32*x,5*x), symmetric=TRUE)
stopifnotValid(bM2, "dsCMatrix")
stopifnotValid(bb2 <- band(bM2, k1=i-2, k2=i+5), "dtCMatrix")
stopifnotValid(b0 <- band(bM2, -1000, 1000), "dsCMatrix")
stopifnotValid(b0a <- band(bM2, -1000, 1001), "dgCMatrix")
(id <- nrow(M)-i)# 659
colN <- colSums(bM2 != 0)
stopifnot(exprs = {
identical(bb2, triu(bM2))
identical(b0 @x, numeric(0))
identical(b0a@x, numeric(0))
identical(bM2, band(bM2, -(i+3), i+3))
assert.EQ(as(bM2, "generalMatrix"),
band(bM2, -(i+3), i+11), showOnly = TRUE)
colN == { cN <- c(1:3, rep(4L, id-3)); c(rev(cN), rep(0L, i-id), cN)}
})
showProc.time()
## some of these failed before Matrix 1.4.0 (Oct.7, 2021)
D. <- Diagonal(x= c(-2,3:4)); D.[lower.tri(D.)] <- 1:3 ; D.
D0 <- Diagonal(x= 0:3); D0[upper.tri(D0)] <- 1:6 ; D0
stopifnot(all.equal(list(modulus = structure(24, logarithm = FALSE), sign = -1L),
unclass(determinant(D.,FALSE)), tolerance=1e-15),
det(Matrix(0,1)) == 0,
all.equal(list(modulus = structure(0, logarithm = FALSE), sign = 1L),
unclass(determinant(D0,FALSE)), tolerance=0)
)
### More sparseVector checks: -------------------------------
validObject(new("isparseVector"))
R <- sv <- as(D4, "sparseVector")
## dim() <- (n1,n2) --> sparse Matrix :
dim(R) <- dim(D4)
stopifnotValid(sv,"sparseVector")
stopifnotValid(R, "sparseMatrix")
stopifnot(identical(D4, as(R, "diagonalMatrix")))
iv <- c(rep(0, 5), 3, 0,0,7,0,0,0)
sv <- as(iv, "sparseVector")
sv. <- as(as.integer(iv), "sparseVector")
## Note: Method with signature "numeric#sparseVector" chosen ...
(sv2 <- as(sv, "isparseVector")) ## gave error
as(sv, "zsparseVector")
stopifnot(identical(sv., sv2),
identical( Matrix(sv, 3,4, byrow=TRUE),
t(Matrix(sv, 4,3))))
options(warn = 0)# no longer error
## "Large" sparse:
n <- 100000
m <- 50000 ; nnz <- 47
M <- spMatrix(n, m,
i = sample(n, nnz, replace = TRUE),
j = sample(m, nnz, replace = TRUE),
x = round(rnorm(nnz),1))
validObject(Mv <- as(M, "sparseVector"))
validObject(Dv <- as(Diagonal(60000), "sparseVector"))
validObject(LD <- Diagonal(60000, TRUE))
validObject(Lv <- as(LD, "sparseVector"))
Dm <- Dv; dim(Dm) <- c(180000L, 20000L)
stopifnot(!doExtras || isValid(Md <- M * rowSums(M, sparseResult=TRUE), "sparseMatrix"),
LD@diag == "U",
isValid(Dm, "sparseMatrix"),
identical(Dv, as(Dm, "sparseVector")))
p. <- new("dtCMatrix", i = c(2:3, 2L), p = c(0L, 2:3, 3L, 3L),
Dim = c(4L, 4L), x = rep(-0.5, 3), uplo = "L", diag = "U")
assert.EQ.mat(solve(solve(p.)), as(p., "matrix"))
dimnames(p.)[[1]] <- paste(1:4)
ii <- is.na(p.)
stopifnot(all(!ii), !any(as(ii, "denseMatrix")))# used to fail
lst <- ls()
table(istri <- sapply(lst, function(.) is(get(.),"triangularMatrix")))
table(triC <- sapply(lst[istri], function(.) class(get(.))))
table(uniC <- sapply(lst[istri], function(.) get(.)@diag == "U"))
lsUtr <- lst[istri][uniC]
(di <- sapply(lsUtr, function(.) dim(get(.))))
## TODO: use %*%, crossprod(), .. on all those 4 x 4 -- and check "triangular rules"
assertError(new("ltrMatrix", Dim = c(2L,2L), x=TRUE))# gave "illegal" object w/o error
assertError(new("ntrMatrix", Dim = c(2L,2L)))# dito
showProc.time()# == "stats"
cat("doExtras:",doExtras,"\n")
if(doExtras) {
cat("checkMatrix() of all: \n---------\n")
Sys.setlocale("LC_COLLATE", "C") # to keep ls() reproducible
for(nm in setdiff(ls(), "d4da")) { # FIXME: checkMatrix(d4da)
if(is(.m <- get(nm), "Matrix")) {
cat("\n", rep("-",nchar(nm)),"\n",nm, ":\n", sep='')
checkMatrix(.m)
}
}
showProc.time()
}
## in any case, test
d4d.2 <- .dense2sparse(!!d4da, "C") ## <<- did wrongly make dimnames symmetric
l4da <- as(d4da, "lMatrix")
assert.EQ.Mat(l4da, as(l4da,"CsparseMatrix"))
dtr <- tr4 <- triu(Matrix(1:16, 4,4))
dtr@x[Matrix:::indTri(4, upper=FALSE, diag=FALSE)] <- 100*(-3:2)
stopifnot(all.equal(dtr, tr4), # because are same *as* simple matrices
dtr@x[1:4] == c(1, -(3:1)*100),
range(tr4) == c(0,16),
range(dtr) == c(0,16)) # <- failed
## new("nsyMatrix") + new("lgeMatrix") # failed
cln <- sort(outer(c("l","n"), paste0(c("ge","sy"), "Matrix"), paste0))
dim(c.c <- as.matrix(expand.grid(cln, cln, KEEP.OUT.ATTRS=FALSE))) # 16 x 2
## clTry <- function(expr) class(tryCatch(expr, error=identity))[[1]]
## '+' [Arith] failed -- now fixed
cbind(c.c, Res = apply(c.c, 1, function(x) class(new(x[1]) + new(x[2]))))
## '<' [Compare] works fine
cbind(c.c, Res = apply(c.c, 1, function(x) class(new(x[1]) < new(x[2]))))
if(!interactive()) warnings()
## R-forge matrix-Bugs [#6708] (2021-02-25, by David Cortes):
sVec <- sparseVector(c(1,exp(1),pi), c(1,3,7), length=9)
vec <- c(1, 0, exp(1), 0, 0, 0, pi, 0, 0)
stopifnot(identical(as.matrix(sVec), as.matrix(vec)),
identical(as.array (sVec), as.array (vec)))
## R-forge matrix-Bugs [#6656] (2020-02-05, by Chun Fung (Jackson) Kwok (kcf.jackson)
## (*is* a bug, but not in kronecker etc, but rather in Arith / Ops)
dC <- sparseMatrix(i=1:4, j=1:4, x=5:2, triangular = TRUE)
(dT <- as(dC, "TsparseMatrix"))
stopifnot(identical(--dC, dC),
identical(--dT, dT)
)
## both - gave : Error .... 'factors' is not a slot in class "dtTMatrix"
## R PR#18250 - by Mikael Jagan
nm2 <- c("a","b")
x <- new("dspMatrix", x = c(3,2,1), Dim = c(2L,2L), Dimnames = list(nm2, NULL))
dn <- list(nm2,nm2)
stopifnotValid(x. <- unpack(x), "dsyMatrix")
validObject( y <- as(x , "generalMatrix") )
validObject( y. <- as(x., "generalMatrix") )
stopifnotValid( l <- x > 0, "lspMatrix")
stopifnotValid( l. <- unpack(l), "lsyMatrix")
stopifnotValid( lg <- as(l, "generalMatrix"), "lgeMatrix")
stopifnotValid( lg2<- as(l.,"generalMatrix"), "lgeMatrix")
stopifnot(exprs = {
identical(dimnames(x ), dn)
identical(dimnames(x.), dn)
identical(dimnames(y ), dn) # was wrong
identical(dimnames(y.), dn) # was wrong
identical(dimnames(l ), dn)
identical(dimnames(l.), dn)
identical(dimnames(lg), dn) # was wrong
identical(lg, lg2)
## even more cases (?)
})
showProc.time()
dn4 <- list(letters[1:4], LETTERS[1:4])
(D4n <- `dimnames<-`(D4, dn4))
m4 <- as(D4n, "matrix")
stopifnot(identical(dimnames(m4), dn4), Q.eq(D4n, m4, superclasses=NULL))
## as(, "matrix") had lost dimnames before
s24 <- new("dgCMatrix", Dim = c(2L, 4L), p = integer(5L))
triu(s24, k = 4L) # was an error
tril(s24, k = 4L) # was an error
## band(, -k, k) used isSymmetric(tol > 0) to test
## for symmetry of the result, and forcing symmetry lost information
s44 <- new("dgCMatrix", Dim = c(4L, 4L), p = c(0L, 0L, 1L, 1L, 1L),
i = 0L, x = .Machine$double.xmin)
(bs44 <- band(s44, -1L, 1L))
stopifnot(identical(s44, bs44))
l0.u <- new("ltrMatrix", diag = "U")
!l0.u # was an error
n11 <- new("ngeMatrix", Dim = c(1L, 1L), x = NA)
nn11 <- !n11 # did not respect NA<=>TRUE
stopifnot(is(nn11, "ngeMatrix"), identical(nn11@x, FALSE))
## coercions preserving mathematical equality ought to preserve 'factors' slot;
## though currently only for sparse->sparse and dense->dense
mC <- as(as(Diagonal(x = rlnorm(5)), "CsparseMatrix"), "symmetricMatrix")
stopifnot(identical(mC@factors, list()))
chol(mC)
mR <- as(mC, "RsparseMatrix")
mT <- as(mR, "TsparseMatrix")
stopifnot(!identical(mTf <- mT@factors, list()),
identical(mTf, mR@factors),
identical(mTf, mC@factors))
## overallocated l.T should follow usual logic ... NA || TRUE -> TRUE, etc.
lT. <- lT0 <- lT1 <-
new("lgTMatrix", Dim = c(1L, 1L), i = c(0L, 0L), j = c(0L, 0L),
x = c(NA, NA))
lT0@x[1L] <- FALSE
lT1@x[1L] <- TRUE
stopifnot(identical(as.vector(lT.), NA),
identical(as.vector(lT0), NA),
identical(as.vector(lT1), TRUE),
identical(as(lT1, "CsparseMatrix")@x, TRUE),
identical(as(lT1, "dMatrix")@x, 1))
## various is.na(), anyNA(), which() bugs in Matrix <= 1.4-1
.nge <- new("ngeMatrix", Dim = c(2L, 2L), x = rep.int(NA, 4L))
.dtr <- new("dtrMatrix", Dim = c(2L, 2L), x = c(NA, 1, 2, Inf), diag = "U")
.dsy <- new("dsyMatrix", Dim = c(2L, 2L), x = c(1, NA, 2, 3))
stopifnot(!any(is.na(.nge)),
!any(is.na(.dtr)),
!any(is.infinite(.dtr)),
!any(is.na(.dsy)),
!anyNA(.nge),
!anyNA(.dtr),
!anyNA(.dsy),
identical(which(.nge), 1:4))
## various `dim<-`() bugs in Matrix <= 1.4-1
.dgR <- new("dgRMatrix", Dim = c(2L, 2L), p = integer(3L))
assertError(`dim<-`(.dgR, -x@Dim)) # had yielded an invalid object
stopifnot(is(`dim<-`(.dgR, c(4L, 1L)), "RsparseMatrix")) # was TsparseMatrix
## symmpart() was not a dMatrix or a symmetricMatrix;
## symmpart() did not get symmetrized 'Dimnames'
.ldi.sp <- symmpart(new("ldiMatrix", Dim = c(1L, 1L), Dimnames = list("a", "b"),
x = TRUE))
stopifnot(is(.ldi.sp, "dMatrix"),
is(.ldi.sp, "diagonalMatrix"),
Matrix:::isSymmetricDN(.ldi.sp@Dimnames))
## as.vector(), etc. must do NA->TRUE
stopifnot(identical(as.vector(.nge), rep.int(TRUE, 4L)),
identical(as.logical(.nge), rep.int(TRUE, 4L)),
identical(as.double(.nge), rep.int(1, 4L)),
identical(as(.nge, "vector"), rep.int(TRUE, 4L)),
identical(as(.nge, "matrix"), array(TRUE, .nge@Dim)),
identical(as(.nge, "dMatrix")@x, rep.int(1, 4L)),
identical(nnzero(.nge), 4L))
## symmpart() and skewpart() have been documented
## as returning matrix, _not_ Matrix
z0 <- matrix((-2)^(0:3), 2L, 2L)
z1 <- symmpart(z0)
z2 <- skewpart(z0)
stopifnot(!isS4(z1), is.matrix(z1), !isS4(z2), is.matrix(z2))
## various Matrix() bugs in Matrix <= 1.4-1
.d0 <- new("ddiMatrix", Dim = c(1L, 1L), Dimnames = list("A", "B"), diag = "U")
.d1 <- Matrix(`dimnames<-`(diag(1), list("A", "B")), doDiag = TRUE)
.s0 <- new("dsyMatrix", Dim = c(1L, 1L), Dimnames = list("B", "B"), x = 1)
.s1 <- Matrix(.d0, doDiag = FALSE)
stopifnot(identical(.d1, .d0),
identical(.s1, .s0),
identical(Matrix(sparseVector(1, 1L, 3L)),
new("dgTMatrix", Dim = c(3L, 1L), i = 0L, j = 0L, x = 1)),
identical(Matrix(new("dgeMatrix"), sparse= TRUE, forceCheck=FALSE),
new("dgCMatrix")),
identical(Matrix(new("dgCMatrix"), sparse=FALSE, forceCheck=FALSE),
new("dgeMatrix")),
identical(Matrix(table(1)), Matrix(1)),
identical(Matrix(table(1, 1, 1)), Matrix(1)),
grepl("too long",
vapply(alist(Matrix(0, 0.5, ), Matrix(0, , 0.5),
Matrix(0, 0.0, ), Matrix(0, , 0.0)),
function(e) conditionMessage(assertError(eval(e))[[1L]]),
"")))
## From: Mikael Jagan , 16 Aug 2022
validObject(x <- new("dtrMatrix", Dim = c(2L, 2L), diag = "U", x = double(4L)))
x == 0 -> L
x > 2 -> L. # ditto
## gave Error in validObject(.Object) :
## invalid class "ltrMatrix" object: length of x slot != prod(Dim)
stopifnot(all(L == ((1:4) != 2)),
all(L. == diag(2)))
## 'Same' with "Logic" instead of "Compare":
x & FALSE -> L.
## gave Error in validObject(.Object) : invalid class "ltrMatrix" object
stopifnot(all(L. == diag(2)))
validObject(y <- new("dgCMatrix", Dim = c(0L, 6L), p = integer(7L)))
y == c(0, 0) -> L2
y == rep(0,6)-> L6
## gave Error in validObject(*): invalid class "lgCMatrix" object: slot p ...
stopifnot(identical(L2, L6), is(L2, "lgCMatrix"), identical(dim(L2), c(0L, 6L)))
## .. "Logic" instead of "Compare":
y & c(FALSE, FALSE) -> L2
## gave Error in validObject(*): invalid class "lgCMatrix" object: slot p ...
stopifnot(identical(L2, L6), is(L2, "lgCMatrix"), identical(dim(L2), c(0L, 6L)))
## Briefly wrong between 1.4-1 and 1.5-0
x.inf <- new("dgCMatrix", Dim = c(2L, 3L),
p = c(0:2, 2L), i = 0:1, x = c(-Inf, Inf))
stopifnot(identical(is.infinite(x.inf), as(abs(x.inf) == Inf, "nMatrix")))
showProc.time()
## C-level bugs in 1.5-0, detected by full CRAN (incl. ASAN) check
as(new("dgTMatrix"), "CsparseMatrix") # out-of-bounds access
as(seq_len(10000), "pMatrix") # segfault
## %*% gave b %*% a prior to Matrix 1.5-2
set.seed(163006)
for(i in 1:6) {
x <- as(sample.int(10L), "pMatrix")
y <- as(sample.int(10L), "pMatrix")
stopifnot(as(x %*% y, "matrix") == as(x, "matrix") %*% as(y, "matrix"))
}
## %*% forgot to set 'Dim' briefly prior to 1.5-2
x <- new("indMatrix", Dim = c(5L, 3L),
perm = sample.int(3L, size = 5L, replace = TRUE))
y <- new("indMatrix", Dim = c(3L, 9L),
perm = sample.int(9L, size = 3L, replace = TRUE))
validObject(x %*% y)
stopifnot(all(tril(y, -1) == 0)) # was wrong in Matrix 1.5-x
## dimScale(x) (i.e., with 'd1' missing) did not work in 1.5-2;
## same with dimScale() ...
set.seed(3054)
V <- matrix(rlnorm(16L), 4L, 4L)
stopifnot(all.equal(as(dimScale(V), "matrix"), cov2cor(V)))
## Diagonal(n, x, names=TRUE) must recycle 'x' _and_ its names
p <- 6L
a0 <- c(a = 0)
stopifnot(identical(unname(nD <- Diagonal(n = p, x = a0, names = TRUE)),
Diagonal(n = p, x = a0, names = FALSE)),
identical(nD, Diagonal(n = p, x = rep(a0, p), names = TRUE)))
## Diagonal(n, names=) should also get 'Dimnames'
stopifnot(identical(Diagonal(1L, names = "a")@Dimnames, list("a", "a")))
## Diagonal(x=, names = TRUE) should get list(NULL, NULL)
stopifnot(identical(Diagonal(x = a0[0L], names = TRUE)@Dimnames,
list(NULL, NULL)))
## names were forgotten prior to 1.5-3
d1 <- Diagonal(1L, names = "b")
stopifnot(identical(colSums(d1), c(b = 1)),
identical(rowMeans(as(d1, "indMatrix")), c(b = 1)))
## na.rm was ignored prior to 1.5-3
d1 <- Diagonal(x = NaN)
stopifnot(identical(colSums(d1), NaN),
identical(colSums(d1, na.rm = TRUE), 0),
identical(rowMeans(d1), NaN),
identical(rowMeans(d1, na.rm = TRUE), NaN))
## Matrix bug #6810
library(Matrix)
x <- as(matrix(c(FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE), 4L, 2L),
"RsparseMatrix")
stopifnot(identical(which(x), seq_along(x)[as.vector(!is.na(x) & x)]),
identical(which(x, arr.ind = TRUE, useNames = FALSE),
arrayInd(which(x), dim(x), dimnames(x), useNames = FALSE)))
## drop0(give.Csparse = FALSE)
R <- new("dtRMatrix", Dim = c(6L, 6L), p = 0:6, j = 0:5, x = 0+0:5)
T <- as(as(R, "TsparseMatrix"), "symmetricMatrix")
for(tol in 0+0:5) {
i.tol <- R@x > tol
stopifnot(exprs = {
identical(drop0(R, tol = tol, give.Csparse = FALSE),
new("dtRMatrix", Dim = c(6L, 6L),
p = c(0L, cumsum(i.tol)), j = R@j[i.tol], x = R@x[i.tol]))
identical(drop0(T, tol = tol, give.Csparse = FALSE),
new("dsTMatrix", Dim = c(6L, 6L),
i = R@j[i.tol], j = R@j[i.tol], x = R@x[i.tol]))
})
}
## No-op for pattern-like sparse matrices:
i1 <- new("indMatrix", Dim = c(6L, 8L), margin = 1L,
perm = sample.int(8L, size = 6L, replace = TRUE))
i1.s <- as(i1, "nsparseMatrix")
i1.d <- as(i1, "ndenseMatrix")
stopifnot(exprs = {
identical(drop0(i1 , give.Csparse = FALSE), i1)
identical(drop0(i1.s, give.Csparse = FALSE), i1.s)
identical(drop0(i1.d, give.Csparse = FALSE), as(i1.d, "CsparseMatrix"))
})
## Setting diagonal elements of non-square RsparseMatrix produced
## an invalid object
x <- new("dgRMatrix", Dim = c(1L, 2L), p = c(0L, 0L))
diag(x) <- 1
validObject(x)
## Subassigning double to logical briefly did not change class
x <- new("lgeMatrix", Dim = c(2L, 3L), x = logical(6L))
y <- new("dgeMatrix", Dim = c(2L, 3L), x = replace(double(6L), 1L, 1))
x[1L, 1L] <- 1
stopifnot(identical(x, y))
## as(, "Matrix") was briefly a error (invalid type "list")
stopifnot(identical(as(data.frame(a = 1:2, b = 3:4), "Matrix"),
new("dgeMatrix", x = as.double(1:4),
Dim = c(2L, 2L), Dimnames = list(NULL, c("a", "b")))))
## tri[ul](<.t[rp]Matrix>) was often wrong at least in 1.6-1
u <- new("dtrMatrix", Dim = c(8L, 8L), x = as.double(seq_len(64L)))
stopifnot(identical(triu(u, 1L), triu(as(u, "generalMatrix"), 1L)))
## more tril()/triu() woes {introduced after 2021; present till 1.6-4}
for(n in 0:7) {
cat("n = ", n,"\n----\n")
##TODO: for(m in pmax(0, n-3):(n+3)) {
for(m in pmax(0, n-3):(n+3)) { #-- n x m matrix
cat(" m = ", m,": using k's in ", (-n),":", m, "\n", sep="")
symm <- (m == n)
mn2 <- (mn <- m*n) %/% 2
ma <- array(seq_len(mn) - mn2 - 1/2, dim = c(n, m))
if(symm) ma <- crossprod(ma) # crossprod() to be symmetric
dM <- as(as(ma, "denseMatrix"), "generalMatrix")
sM <- as(as(ma, "CsparseMatrix"), "generalMatrix")
for(k in (-n):m) {
trum <- triuChk(ma,k); trlm <- trilChk(ma, k)
trud <- triuChk(dM,k); trld <- trilChk(dM, k)
trus <- triuChk(sM,k); trls <- trilChk(sM, k)
if(symm) {
assert.EQ( trum, t(tril(ma,-k)))
assert.EQ.mat(trud, as.mat(t(tril(dM,-k))))
assert.EQ.mat(trus, as.mat(t(tril(sM,-k))))
}
stopifnot(exprs = {
## matrix
identical(trlm, band(ma, -n, k))
identical(trum, band(ma, k, m))
inherits(trum, "denseMatrix") # "dge" / "dtr" ...
## denseMatrix
identical(trld, band(dM, -n, k))
identical(trud, band(dM, k, m))
inherits(trud, "denseMatrix")
assert.EQ.Mat(trud, trum, giveRE=TRUE)
## sparseMatrix
identical(trls, band(sM, -n, k))
identical(trus, band(sM, k, m))
inherits(trus, "sparseMatrix")
assert.EQ.Mat(trus, trum, giveRE=TRUE)
})
}
}
}
## Platform - and other such info -- so we find it in old saved outputs
.libPaths()
SysI <- Sys.info()
structure(Sys.info()[c(4,5,1:3)], class="simple.list")
sessionInfo()
c(Matrix = packageDescription("Matrix")$Built)
if(SysI[["sysname"]] == "Linux" && requireNamespace("sfsmisc")) local({
nn <- names(.Sc <- sfsmisc::Sys.cpuinfo())
nn <- names(.Sc <- .Sc[!grepl("^flags", nn)])
print(.Sc[ grep("\\.[0-9]+$", nn, invert=TRUE) ])
})
showProc.time()
Matrix/tests/symmDN.R 0000644 0001751 0000144 00000014426 14503206514 014237 0 ustar hornik users ## These are tests related to the centralization (since r~3454) of various
## methods for symmetrizing the (possibly asymmetric) 'Dimnames' of symmetric
## matrices.
library(Matrix)
if (interactive()) {
options(Matrix.verbose = TRUE, warn = 1, error = recover)
} else {
options(Matrix.verbose = TRUE, warn = 1)
}
## For getting and setting '[dD]imnames' on '[mM]atrix'
DN <- function(x) {
if (is(x, "Matrix")) {
x@Dimnames
} else {
dimnames(x)
}
}
`DN<-` <- function(x, value) {
if (is(x, "Matrix")) {
x@Dimnames <- value
} else {
dimnames(x) <- value
}
x
}
## SDN1(dn) is documented to behave as SDN2(dn, NULL)
SDN1 <- Matrix:::symDN
SDN2 <- function(dn, uplo = NULL) {
J <-
if (is.null(uplo)) {
if (!is.null(dn[[1L]]) && is.null(dn[[2L]])) 1L else 2L
} else {
if (uplo == "U") 2L else 1L
}
rep(dn[J], 2L)
}
## isSDN1(dn) is documented to behave as isSDN2(dn)
isSDN1 <- Matrix:::isSymmetricDN
isSDN2 <- function(dn) {
(is.null(ndn <- names(dn)) || !all(nzchar(ndn)) || ndn[1L] == ndn[2L]) &&
(is.null(rn <- dn[[1L]]) || is.null(cn <- dn[[2L]]) ||
isTRUE(all(rn == cn | (is.na(rn) & is.na(cn)))))
}
## Various possible (a)symmetries of 'Dimnames'
n <- 4L
rn <- letters[seq_len(n)]
cn <- LETTERS[seq_len(n)]
ldn <- list(list(rn, rn),
list(rn, cn),
list(rn, NULL),
list(NULL, cn),
list(NULL, NULL),
list(x = rn, rn),
list(x = rn, cn),
list(x = rn, NULL),
list(x = NULL, cn),
list(x = NULL, NULL),
list(rn, y = rn),
list(rn, y = cn),
list(rn, y = NULL),
list(NULL, y = cn),
list(NULL, y = NULL),
list(x = rn, y = rn),
list(x = rn, y = cn),
list(x = rn, y = NULL),
list(x = NULL, y = cn),
list(x = NULL, y = NULL))
## 'matrix' and _most_ 'd..Matrix' ...
## zero matrices are fine for the purpose of testing handling of 'Dimnames'
lM <- c(list(matrix(0, n, n),
new("ddiMatrix", x = double(n), Dim = c(n, n)),
new("dgeMatrix", x = double(n * n), Dim = c(n, n))),
.mapply(new,
expand.grid(Class = c("dsyMatrix", "dtrMatrix"),
uplo = c("U", "L"),
stringsAsFactors = FALSE),
list(x = double(n * n), Dim = c(n, n))),
.mapply(new,
expand.grid(Class = c("dspMatrix", "dtpMatrix"),
uplo = c("U", "L"),
stringsAsFactors = FALSE),
list(x = double((n * (n + 1L)) %/% 2L), Dim = c(n, n))),
list(new("dgCMatrix", x = double(0L), Dim = c(n, n),
i = integer(0L), p = rep.int(0L, n + 1L))),
.mapply(new,
expand.grid(Class = c("dsCMatrix", "dtCMatrix"),
uplo = c("U", "L"),
stringsAsFactors = FALSE),
list(x = double(0L), Dim = c(n, n),
i = integer(0L), p = rep.int(0L, n + 1L))))
## A few dense symmetric matrices, which are _not_ symmetricMatrix
## and whose symmetry (in the sense of 'isSymmetric') should depend
## only on their 'Dimnames' slot
.d <- diag(n)
.lM <- list(new("dgeMatrix",
x = as.vector(.d), Dim = c(n, n)),
new("ltrMatrix",
x = as.vector(.d != 0), Dim = c(n, n), uplo = "U"),
new("ntpMatrix",
x = .d[upper.tri(.d, TRUE)] != 0, Dim = c(n, n), uplo = "U"))
.iS <- function(M, dn) {
M@Dimnames <- dn
isSymmetric(M, tol = 0, checkDN = TRUE)
}
for (dn in ldn) {
stopifnot(identical(sdn <- SDN1(dn), SDN2(dn)),
(isdn <- isSDN1(dn)) == isSDN2(dn),
vapply(.lM, .iS, NA, dn = dn) == isdn)
for (M in lM) {
DN(M) <- dn
if (is.s <- is(M, "symmetricMatrix")) {
## 'dimnames' should symmetrize
stopifnot(identical(dimnames(M), sdn))
}
if (is.s && !identical(dn[1L], dn[2L])) {
## Methods for 'symmetricMatrix' assume symmetric 'Dimnames'
## for efficiency ... should they?
next
}
stopifnot(identical(DN(forceSymmetric(M)), sdn),
identical(DN(symmpart(M)), sdn),
identical(DN(skewpart(M)), sdn))
## others?
}
}
## r3459: allowing initialization with typeof(Dimnames[[i]]) != "character"
## ... nothing to do with symmetry, but here for now ...
stopifnot(identical(new("dgeMatrix", x = as.double(1:4), Dim = c(2L, 2L),
Dimnames = list(1:2, as.factor(3:4))),
new("dgeMatrix", x = as.double(1:4), Dim = c(2L, 2L),
Dimnames = list(c("1", "2"), c("3", "4")))))
stopifnot(vapply(ldn, isSDN1, NA) == vapply(ldn, isSDN2, NA))
## cov2cor(), dimScale() etc -- matrix-Bugs [#6783] 2022-10-23 by Ben Bolker
"https://r-forge.r-project.org/tracker/?func=detail&atid=294&aid=6783&group_id=61"
## base R vs Matrix cov2cor()
m <- diag(1:3)
dimnames(m) <- adn <- list(LETTERS[1:3], letters[1:3]) # MM: *a*symmetric dimnames ..
Md <- as(m, "denseMatrix")
Ms <- as(m, "sparseMatrix")
stopifnot(exprs = {
identical(adn, dimnames(cov2cor(m)))
identical((dn2 <- rep(adn[2], 2)), dimnames(ms <- forceSymmetric(m))) # a b c for *both* rows & cols
identical( dn2, dimnames(cMd <- cov2cor(Md)))
identical( dn2, dimnames(cMs <- cov2cor(Ms))) # gave error in Matrix <= 1.5-1
all.equal(as(cMd, "sparseMatrix"), cMs, tolerance=1e-15) # see even tol=0
})
dns <- rep(list(letters[1:3]), 2)
m <- matrix(1:9, 3, dimnames = dns); m <- (m+t(m))/2 + 2*diag(3) # to be pos.def.
m
(cm <- cov2cor(m))
(cM <- cov2cor(M <- as(m, "denseMatrix")))
stopifnot(exprs = {
identical(dns, dimnames(cm))
inherits(cM, "dpoMatrix")
identical(dns, dimnames(cM))
inherits((cS <- cov2cor(S <- as(m, "sparseMatrix"))), "dsCMatrix")
identical(dns, dimnames(cS))
all.equal(cS, dimScale(S))
all.equal(as(cM, "sparseMatrix"), cS,
tolerance=2e-15) # see even tol=0
all.equal(as(cM, "dpoMatrix"), as(dimScale(M), "dpoMatrix"),
tolerance=2e-15) # seen 1.665e-16
})
cat("Time elapsed:", proc.time(), "\n") # "stats"
Matrix/tests/indexing.R 0000644 0001751 0000144 00000140043 14563762457 014653 0 ustar hornik users #### For both 'Extract' ("[") and 'Replace' ("[<-") Method testing
#### aka subsetting and subassignment
#### ~~~~~~~~~~ ~~~~~~~~~~~~~
## for R_DEFAULT_PACKAGES=NULL :
library(stats)
library(utils)
if(interactive()) {
options(error = recover, warn = 1)
} else if(FALSE) { ## MM / developer testing *manually* :
options(error = recover, Matrix.verbose = 2, warn = 1)
} else {
options( Matrix.verbose = 2, warn = 1)
}
## Matrix.verbose = .. (*before* loading 'Matrix' pkg)
## ==> will also show method dispath ambiguity messages: getOption("ambiguousMethodSelection")
#### suppressPackageStartupMessages(...) as we have an *.Rout.save to Rdiff against
suppressPackageStartupMessages(library(Matrix))
source(system.file("test-tools.R", package = "Matrix"), keep.source = FALSE)
##-> identical3() etc
cat("doExtras:",doExtras,"\n")
if(exists("Sys.setLanguage", mode="function"))
Sys.setLanguage("en")
englishMsgs <- (lang <- Sys.getenv("LANGUAGE")) %in% c("en", "C")
cat(sprintf("LANGUAGE env.: '%s'; englishMsgs: %s\n",
lang, englishMsgs))
### Dense Matrices
m <- Matrix(1:28 +0, nrow = 7)
validObject(m)
stopifnot(identical(m, m[]),
identical(m[2, 3], 16), # simple number
identical(m[2, 3:4], c(16,23)), # simple numeric of length 2
identical(m[NA,NA], as(Matrix(NA, 7,4), "dMatrix")))
m[2, 3:4, drop=FALSE] # sub matrix of class 'dgeMatrix'
m[-(4:7), 3:4] # ditto; the upper right corner of 'm'
## rows or columns only:
m[1,] # first row, as simple numeric vector
m[,2] # 2nd column
m[,1:2] # sub matrix of first two columns
m[-(1:6),, drop=FALSE] # not the first 6 rows, i.e. only the 7th
m[integer(0),] #-> 0 x 4 Matrix
m[2:4, numeric(0)] #-> 3 x 0 Matrix
## logical indexing
stopifnot(identical(m[2,3], m[(1:nrow(m)) == 2, (1:ncol(m)) == 3]),
identical(m[2,], m[(1:nrow(m)) == 2, ]),
identical(m[,3:4], m[, (1:4) >= 3]))
## dimnames indexing:
mn <- m
dimnames(mn) <- list(paste("r",letters[1:nrow(mn)],sep=""),
LETTERS[1:ncol(mn)])
checkMatrix(mn)
mn["rd", "D"]
msr <- ms <- as(mn,"sparseMatrix")
mnr <- mn
v <- rev(as(ms, "vector"))
mnr[] <- v
msr[] <- v # [<- "sparse" -- not very sensical; did fail w/o a message
z <- msr; z[] <- 0
zz <- as(array(0, dim(z)), "sparseMatrix")
a.m <- as(mnr,"matrix")
stopifnot(identical(mn["rc", "D"], mn[3,4]), mn[3,4] == 24,
identical(mn[, "A"], mn[,1]), mn[,1] == 1:7,
identical(mn[c("re", "rb"), "B"], mn[c(5,2), 2]),
identical(ms["rc", "D"], ms[3,4]), ms[3,4] == 24,
identical(ms[, "A"], ms[,1]), ms[,1] == 1:7,
identical(ms[ci <- c("re", "rb"), "B"], ms[c(5,2), 2]),
identical(rownames(mn[ci, ]), ci),
identical(rownames(ms[ci, ]), ci),
identical(colnames(mn[,cj <- c("B","D")]), cj),
identical(colnames(ms[,cj]), cj),
identical(a.m, as(msr,"matrix")),
identical(unname(z), zz),
identical(a.m, array(v, dim=dim(mn), dimnames=dimnames(mn)))
)
showProc.time()
## Bug found thanks to Timothy Mak, Feb 3, 2017:
## sparseMatrix logical indexing with (partial) NA:
a.m <- as(mn,"matrix")
assert.EQ(as(ms,"matrix"), a.m) # incl. dimnames
iN4 <- c(NA, TRUE, FALSE, TRUE)
assert.EQ(as(mn[,iN4],"matrix"), a.m[,iN4]) # (incl. dimnames)
##assert.EQ(as.matrix(ms[,iN4]), a.m[,iN4]) # ms[, ] fails still : _FIXME_
try(ms[,iN4])
try(ms[,iN4] <- 100) ## <- segfaulted in Matrix <= 1.2-8 (!)
## R-forge Matrix bug #2556: Subsetting a sparse matrix did remove names(dimnames(.)) :
m44 <- matrix(1:16, 4, 4, dimnames=list(row=c('a','b','c','d'), col=c('x','y','z','w')))
## Dense matrix: ------------------------------------------
a <- Matrix(m44)
identical(
dimnames(m44[,FALSE, drop=FALSE]),
dimnames( a[,FALSE, drop=FALSE]))
chk.ndn <- function(a, a0=m44)
stopifnot(identical(names(dimnames(a)), names(dimnames(a0))))
i <- 1:2
chk.ndn(a[i,]); chk.ndn(a[i, i])
## Sparse matrix: -----------------------------------------
s <- as(a %% 3 == 1, "sparseMatrix")
ts <- as(s,"TsparseMatrix")
b <- sparseMatrix(i=1:3, j=rep(2,3), dims=c(4,4), dimnames=dimnames(s))
tb <- as(b,"TsparseMatrix")
stopifnot(identical5(
dimnames(a), dimnames(s), dimnames(ts),
dimnames(b), dimnames(tb)))
chk.ndn(b [i, i]); chk.ndn(b [i, ])
chk.ndn(s [i, i]); chk.ndn(s [i, ])
chk.ndn(tb[i, i]); chk.ndn(tb[i, ])
chk.ndn(ts[i, i]); chk.ndn(ts[i, ])
chk.ndn( b[ , 1, drop=FALSE]); chk.ndn( s[i, 2, drop=FALSE])
chk.ndn(tb[ , 1, drop=FALSE]); chk.ndn(ts[i, 2, drop=FALSE])
L0 <- logical(0)
stopifnot(exprs = {
identical(dim(b[,L0]), c(4L, 0L))
identical(dim(b[L0,]), c(0L, 4L)) # failed till 2019-09-x
})
## Printing sparse colnames:
ms[sample(28, 20)] <- 0
ms <- t(rbind2(ms, 3*ms))
cnam1 <- capture.output(show(ms))[2] ; op <- options("sparse.colnames" = "abb3")
cnam2 <- capture.output(show(ms))[2] ; options(op) # revert
stopifnot(## sparse printing
grep("^ +$", cnam1) == 1, # cnam1 is empty
identical(cnam2,
paste(" ", paste(rep(rownames(mn), 2), collapse=" "))))
mo <- m
m[2,3] <- 100
m[1:2, 4] <- 200
m[, 1] <- -1
m[1:3,]
m. <- as(m, "matrix")
## m[ cbind(i,j) ] indexing:
iN <- ij <- cbind(1:6, 2:3)
iN[2:3,] <- iN[5,2] <- NA
stopifnot(identical(m[ij], m.[ij]),
identical(m[iN], m.[iN]))
## testing operations on logical Matrices rather more than indexing:
g10 <- m [ m > 10 ]
stopifnot(18 == length(g10))
stopifnot(10 == length(m[ m <= 10 ]))
sel <- (20 < m) & (m < 150)
sel.<- (20 < m.)& (m.< 150)
nsel <-(20 >= m) | (m >= 150)
(ssel <- as(sel, "sparseMatrix"))
stopifnot(is(sel, "lMatrix"), is(ssel, "lsparseMatrix"),
identical3(as.mat(sel.), as.mat(sel), as.mat(ssel)),
identical3(!sel, !ssel, nsel), # ! is typically dense
identical3(m[ sel], m[ ssel], as(m, "matrix")[as( ssel, "matrix")]),
identical3(m[!sel], m[!ssel], as(m, "matrix")[as(!ssel, "matrix")])
)
showProc.time()
## more sparse Matrices --------------------------------------
##' @title Check sparseMatrix sub-assignment m[i,j] <- v
##' @param ms sparse Matrix
##' @param mm its [traditional matrix]-equivalent
##' @param k (approximate) length of index vectors (i,j)
##' @param n.uniq (approximate) number of unique values in i,j
##' @param vRNG function(n) for random 'v' generation
##' @param show logical; if TRUE, it will not stop on error
##' @return
##' @author Martin Maechler
chkAssign <- function(ms, mm = as(ms, "matrix"),
k = min(20,dim(mm)), n.uniq = k %/% 3,
vRNG = { if(is.numeric(mm) || is.complex(mm))
function(n) rpois(n,lambda= 0.75)# <- about 47% zeros
else ## logical
function(n) runif(n) > 0.8 }, ## 80% zeros
showOnly=FALSE)
{
stopifnot(is(ms,"sparseMatrix"))
d <- dim(ms)
s1 <- function(n) sample(n, pmin(n, pmax(1, rpois(1, n.uniq))))
i <- sample(s1(d[1]), k/2+ rpois(1, k/2), replace = TRUE)
j <- sample(s1(d[2]), k/2+ rpois(1, k/2), replace = TRUE)
assert.EQ.mat(ms[i,j], mm[i,j])
ms2 <- ms. <- ms; mm. <- mm # save
## now sub*assign* to these repeated indices, and then compare -----
v <- vRNG(length(i) * length(j))
mm[i,j] <- v
ms[i,j] <- v
## useful to see (ii,ij), but confusing R/ESS when additionally debugging:
## if(!showOnly && interactive()) { op <- options(error = recover); on.exit(options(op)) }
assert.EQ.mat(ms, mm, showOnly=showOnly)
## vector indexing m[cbind(i,j)] == m[i + N(j-1)] , N = nrow(.)
ii <- seq_len(min(length(i), length(j)))
i <- i[ii]
j <- j[ii]
ij <- cbind(i, j)
ii <- i + nrow(ms)*(j - 1)
ord.i <- order(ii)
iio <- ii[ord.i]
ui <- unique(iio) # compare these with :
neg.ii <- - setdiff(seq_len(prod(d)), ii)
stopifnot(identical(mm[ii], mm[ij]),
identical(ms.[ui], ms.[neg.ii]),
ms.[ij] == mm.[ii], ## M[ cbind(i,j) ] was partly broken; now checking
ms.[ii] == mm.[ii])
v <- v[seq_len(length(i))]
if(is(ms,"nMatrix")) v <- as.logical(v) # !
mm.[ij] <- v
ms.[ii] <- v
nodup <- (length(ui) == length(ii)) ## <==> ! anyDuplicated(iio)
if(nodup) { cat("[-]") # rare, unfortunately
ms2[neg.ii] <- v[ord.i]
stopifnot(identical(ms2, ms.))
}
assert.EQ.mat(ms., mm., showOnly=showOnly)
} ##{chkAssign}
## Get duplicated index {because these are "hard" (and rare)
getDuplIndex <- function(n, k) {
repeat {
i <- sample(n, k, replace=TRUE) # 3 4 6 9 2 9 : 9 is twice
if(anyDuplicated(i)) break
}
i
}
suppressWarnings(RNGversion("3.5.0")); set.seed(101)
m <- 1:800
m[sample(800, 600)] <- 0
m0 <- Matrix(m, nrow = 40)
m1 <- add.simpleDimnames(m0)
for(kind in c("n", "l", "d")) {
for(m in list(m0,m1)) { ## -- with and without dimnames -------------------------
kClass <-paste0(kind, "Matrix" )
Ckind <- paste0(kind, "gCMatrix")
Tkind <- paste0(kind, "gTMatrix")
str(mC <- as(as(as(m, kClass), "CsparseMatrix"), "generalMatrix")) # was as(m, Ckind) deprecated
#was mT <- as(as(as(m, kClass), "TsparseMatrix"), Tkind))
str(mT <- as(as(as(m, kClass), "generalMatrix"), "TsparseMatrix"))
mm <- as(mC, "matrix") # also logical or double
IDENT <- if(kind == "n") function(x,y) Q.eq2(x,y, tol=0) else identical
stopifnot(exprs = {
identical(mT, as(mC, "TsparseMatrix"))
identical(mC, as(mT, "CsparseMatrix")) # was Ckind; now deprecated
Qidentical(mC[0,0], new(Ckind)) # M..3 Csp..4
Qidentical(mT[0,0], new(Tkind)) # "
identical(unname(mT[0,]), new(Tkind, Dim = c(0L,ncol(m))))# M.3 T.4 C.4
identical(unname(mT[,0]), new(Tkind, Dim = c(nrow(m),0L)))# M.3 C.4
is.null(cat("IDENT():\n"))
IDENT(mC[0,], as(mT[FALSE,], "CsparseMatrix")) # M.3 C.4 M.3 + Tsp..4 Csp..4 | as(., Ckind) deprecated
IDENT(mC[,0], as(mT[,FALSE], "CsparseMatrix")) # M.3 C.4 M.3 C.4 | as(., Ckind) deprecated
is.null(cat("sapply(..):\n"))
sapply(pmin(min(dim(mC)), c(0:2, 5:10)),
function(k) {i <- seq_len(k); all(mC[i,i] == mT[i,i])})
})
cat("ok\n")
show(mC[,1])
show(mC[1:2,])
show(mC[7, drop = FALSE])
assert.EQ.mat(mC[1:2,], mm[1:2,])
assert.EQ.mat(mC[0,], mm[0,])
assert.EQ.mat(mC[,FALSE], mm[,FALSE])
##
## *repeated* (aka 'duplicated') indices - did not work at all ...
i <- pmin(nrow(mC), rep(8:10,2))
j <- c(2:4, 4:3)
assert.EQ.mat(mC[i,], mm[i,])
assert.EQ.mat(mC[,j], mm[,j])
## FIXME? assert.EQ.mat(mC[,NA], mm[,NA]) -- mC[,NA] is all 0 "instead" of all NA
## MM currently thinks we should NOT allow [ ]
assert.EQ.mat(mC[i, 2:1], mm[i, 2:1])
assert.EQ.mat(mC[c(4,1,2:1), j], mm[c(4,1,2:1), j])
assert.EQ.mat(mC[i,j], mm[i,j])
##
## set.seed(7)
op <- options(Matrix.verbose = FALSE)
cat(" for(): ")
for(n in 1:(if(doExtras) 50 else 5)) { # (as chkAssign() is random)
chkAssign(mC, mm)
chkAssign(mC[-3,-2], mm[-3,-2])
cat(".")
}
options(op)
cat(sprintf("\n[Ok]%s\n\n", strrep("-", 64)))
}
cat(sprintf("\nok( %s )\n== ###%s\n\n", kind, strrep("=", 70)))
}## end{for}---------------------------------------------------------------
showProc.time()
if(doExtras) {### {was ./AAA_index.R, MM-only}
## an nsparse-example
A <- Matrix(c(rep(c(1,0,0),2), rep(c(2,0),7), c(0,0,2), rep(0,4)), 3,9)
i <- c(3,1:2)
j <- c(3, 5, 9, 5, 9)
vv <- logical(length(i)*length(j)); vv[6:9] <- TRUE
print(An <- as(A,"nMatrix")); an <- as(An, "matrix")
assert.EQ.mat(An, an)
An[i, j] <- vv
an[i, j] <- vv
assert.EQ.mat(An, an)## error
if(!all(An == an)) show(drop0(An - an))
## all are +1
options("Matrix.subassign.verbose" = TRUE)# output from C
An <- as(A,"nMatrix"); An[i, j] <- vv
## and compare with this:
Al <- as(A,"lMatrix"); Al[i, j] <- vv
options("Matrix.subassign.verbose" = FALSE)
##--- An interesting not small not large example for M[i,j] <- v ------------
##
M <- Matrix(c(1, rep(0,7), 1:4), 3,4)
N0 <- kronecker(M,M)
mkN1 <- function(M) {
stopifnot(length(d <- dim(M)) == 2)
isC <- is(M,"CsparseMatrix")
M[,d[2]] <- c(0,2,0)
N <- kronecker(diag(x=1:2), M)## remains sparse if 'M' is
if(isC) N <- as(N, "CsparseMatrix")
diag(N[-1,]) <- -2
N[9,] <- 1:4 # is recycled
N[,12] <- -7:-9 # ditto
N
}
show(N1 <- t(N <- mkN1(N0))) # transpose {for display reasons}
C1 <- t(C <- mkN1(as(N0,"CsparseMatrix")))
stopifnot(all(C == N))
assert.EQ.mat(C, mkN1(as(N0, "matrix")))
C. <- C1
show(N <- N1) ; n <- as(N, "matrix"); str(N)
sort(i <- c(6,8,19,11,21,20,10,7,12,9,5,18,17,22,13))## == c(5:13, 17:22))
sort(j <- c(3,8,6,15,10,4,14,13,16,2,11,17,7,5))## == c(2:8, 10:11, 13:17)
val <- v.l <- 5*c(0,6,0,7,0,0,8:9, 0,0)
show(spv <- as(val, "sparseVector")); str(spv)
n [i,j] <- v.l
N [i,j] <- val# is recycled, too
C.[i,j] <- val
assert.EQ.mat(N,n) ; stopifnot(all(C. == N))
## and the same *again*:
n [i,j] <- v.l
N [i,j] <- val
C.[i,j] <- val
assert.EQ.mat(N,n)
stopifnot(all(C. == N))
print(load(system.file("external", "symA.rda", package="Matrix"))) # "As"
stopifnotValid(As, "dsCMatrix"); stopifnot(identical(As@factors, list()))
R. <- drop0(chol(As))
stopifnot(exprs = {
1:32 == sort(diag(R.)) ## !
R.@x > 0
R.@x == as.integer(R.@x)## so it is an integer-valued chol-decomp !
## shows that (1) As is *not* singular (2) the matrix is not random
all.equal(crossprod(R.), As, tolerance=1e-15)
})
print(summary(evA <- eigen(As, only.values=TRUE)$values))
print(tail(evA)) ## largest three ~= 10^7, smallest two *negative*
print(rcond(As)) # 1.722 e-21 == very bad !
##-> this *is* a border line case, i.e. very close to singular !
## and also determinant(.) is rather random here!
cc0 <- Cholesky(As)# no problem
try({
cc <- Cholesky(As, super=TRUE)
## gives --on 32-bit only--
## Cholmod error 'matrix not positive definite' at file:../Supernodal/t_cholmod_super_numeric.c, line 613
ecc <- expand(cc)
L.P <- with(ecc, crossprod(L,P)) ## == L'P
## crossprod(L.P) == (L'P)' L'P == P'LL'P
stopifnot( all.equal(crossprod(L.P), As) )
})
##---- end{ eigen( As ) -----------
} ## only if(doExtras)
##---- Symmetric indexing of symmetric Matrix ----------
m. <- mC
m.[, c(2, 7:12)] <- 0
stopifnotValid(S <- crossprod(add.simpleDimnames(m.) %% 100), "dsCMatrix")
ss <- as(S, "matrix")
ds <- as(S, "denseMatrix")
## NA-indexing of *dense* Matrices: should work as traditionally
assert.EQ.mat(ds[NA,NA], ss[NA,NA])
assert.EQ.mat(ds[NA, ], ss[NA,])
assert.EQ.mat(ds[ ,NA], ss[,NA])
T <- as(S, "TsparseMatrix")
stopifnot(identical(ds[2 ,NA], ss[2,NA]),
identical(ds[NA, 1], ss[NA, 1]),
identical(S, as(T, "CsparseMatrix")) )
## non-repeated indices:
i <- c(7:5, 2:4);assert.EQ.mat(T[i,i], ss[i,i])
## NA in indices -- check that we get a helpful error message:
i[2] <- NA
er <- tryCatch(T[i,i], error = function(e)e)
if(englishMsgs)
stopifnot(as.logical(grep("indices.*sparse Matrices", er$message)))
N <- nrow(T)
set.seed(11)
for(n in 1:(if(doExtras) 50 else 3)) {
i <- sample(N, max(2, sample(N,1)), replace = FALSE)
validObject(Tii <- T[i,i]) ; tTi <- t(T)[i,i]
stopifnot(is(Tii, "dsTMatrix"), # remained symmetric Tsparse
is(tTi, "dsTMatrix"), # may not be identical when *sorted* differently
identical(as(t(Tii),"CsparseMatrix"), as(tTi,"CsparseMatrix")))
assert.EQ.mat(Tii, ss[i,i])
}
b <- diag(1:2)[,c(1,1,2,2)]
cb <- crossprod(b)
cB <- crossprod(Matrix(b, sparse=TRUE))
a <- matrix(0, 6, 6)
a[1:4, 1:4] <- cb
A1 <- A2 <- Matrix(0, 6, 6)#-> ddiMatrix
A1[1:4, 1:4] <- cb
A2[1:4, 1:4] <- cB
assert.EQ.mat(A1, a)# indeed
## "must": symmetric and sparse, i.e., ds*Matrix:
stopifnot(identical(A1, A2), is(A1, "dsCMatrix"))
## repeated ones ``the challenge'' (to do smartly):
j <- c(4, 4, 9, 12, 9, 4, 17, 3, 18, 4, 12, 18, 4, 9)
assert.EQ.mat(T[j,j], ss[j,j])
## and another two sets (a, A) & (a., A.) :
a <- matrix(0, 6,6)
a[upper.tri(a)] <- (utr <- c(2, 0,-1, 0,0,5, 7,0,0,0, 0,0,-2,0,8))
ta <- t(a); ta[upper.tri(a)] <- utr; a <- t(ta)
diag(a) <- c(0,3,0,4,6,0)
A <- as(Matrix(a), "TsparseMatrix")
A. <- A
diag(A.) <- 10 * (1:6)
a. <- as(A., "matrix")
## More testing {this was not working for a long time..}
set.seed(1)
for(n in 1:(if(doExtras) 100 else 6)) {
i <- sample(1:nrow(A), 3+2*rpois(1, lambda=3), replace=TRUE)
Aii <- A[i,i]
A.ii <- A.[i,i]
stopifnot(class(Aii) == class(A),
class(A.ii) == class(A.))
assert.EQ.mat(Aii , a [i,i])
assert.EQ.mat(A.ii, a.[i,i])
assert.EQ.mat(T[i,i], ss[i,i])
}
showProc.time()
stopifnot(all.equal(mC[,3], mm[,3]),
identical(mC[ij], mC[ij + 0.4]),
identical(mC[ij], mm[ij]),
identical(mC[iN], mm[iN]))
## out of bound indexing must be detected:
assertError(mC[cbind(ij[,1] - 5, ij[,2])])
assertError(mC[cbind(ij[,1], ij[,2] + ncol(mC))])
assert.EQ.mat(mC[7, , drop=FALSE], mm[7, , drop=FALSE])
identical (mC[7, drop=FALSE], mm[7, drop=FALSE]) # *vector* indexing
stopifnot(dim(mC[numeric(0), ]) == c(0,20), # used to give warnings
dim(mC[, integer(0)]) == c(40,0),
identical(mC[, integer(0)], mC[, FALSE]))
validObject(print(mT[,c(2,4)]))
stopifnot(all.equal(mT[2,], mm[2,]),
## row or column indexing in combination with t() :
Q.C.identical(mT[2,], t(mT)[,2]),
Q.C.identical(mT[-2,], t(t(mT)[,-2])),
Q.C.identical(mT[c(2,5),], t(t(mT)[,c(2,5)])) )
assert.EQ.mat(mT[4,, drop = FALSE], mm[4,, drop = FALSE])
stopifnot(identical3(mm[,1], mC[,1], mT[,1]),
identical3(mm[3,], mC[3,], mT[3,]),
identical3(mT[2,3], mC[2,3], 0),
identical(mT[], mT),
identical4( mm[c(3,7), 2:4], as.mat( m[c(3,7), 2:4]),
as.mat(mT[c(3,7), 2:4]), as.mat(mC[c(3,7), 2:4]))
)
x.x <- crossprod(mC)
stopifnot(class(x.x) == "dsCMatrix",
class(x.x. <- round(x.x / 10000)) == "dsCMatrix",
identical(x.x[cbind(2:6, 2:6)],
diag(x.x[2:6, 2:6], names=FALSE)))
head(x.x.) # Note the *non*-structural 0's printed as "0"
tail(x.x., -3) # all but the first three lines
lx.x <- as(as(x.x, "lMatrix"), "symmetricMatrix") # FALSE only for "structural" 0
(l10 <- lx.x[1:10, 1:10])# "lsC"
(l3 <- lx.x[1:3, ])
m.x <- as.mat(x.x) # as.mat() *drops* (NULL,NULL) dimnames
stopifnot(class(l10) == "lsCMatrix", # symmetric indexing -> symmetric !
identical(as.mat(lx.x), m.x != 0),
identical(as.logical(lx.x), as.logical(m.x)),
identical(as.mat(l10), m.x[1:10, 1:10] != 0),
identical(as.mat(l3 ), m.x[1:3, ] != 0)
)
##-- Sub*assignment* with repeated / duplicated index:
A <- Matrix(0,4,3) ; A[c(1,2,1), 2] <- 1 ; A
B <- A; B[c(1,2,1), 2] <- 1:3; B; B. <- B
B.[3,] <- rbind(4:2)
## change the diagonal and the upper and lower subdiagonal :
diag(B.) <- 10 * diag(B.)
diag(B.[,-1]) <- 5* diag(B.[,-1])
diag(B.[-1,]) <- 4* diag(B.[-1,]) ; B.
C <- B.; C[,2] <- C[,2]; C[1,] <- C[1,]; C[2:3,2:1] <- C[2:3,2:1]
stopifnot(identical(unname(as(A, "matrix")),
local({a <- matrix(0,4,3); a[c(1,2,1), 2] <- 1 ; a})),
identical(unname(as(B, "matrix")),
local({a <- matrix(0,4,3); a[c(1,2,1), 2] <- 1:3; a})),
identical(C, drop0(B.)))
## [] <- v failed in the past
T <- as(C,"TsparseMatrix"); C. <- C
T[T>0] <- 21
C[C>0] <- 21
a. <- local({a <- as(C., "matrix"); a[a>0] <- 21; a})
assert.EQ.mat(C, a.)
stopifnot(identical(C, as(T, "CsparseMatrix")))
## used to fail
n <- 5 ## or much larger
sm <- new("dsTMatrix", i=1L, j=1L, Dim=as.integer(c(n,n)), x = 1)
(cm <- as(sm, "CsparseMatrix"))
sm[2,]
stopifnot(sm[2,] == c(0:1, rep.int(0,ncol(sm)-2)),
sm[2,] == cm[2,],
sm[,3] == sm[3,],
all(sm[,-(1:3)] == t(sm[-(1:3),])), # all()
all(sm[,-(1:3)] == 0)
)
showProc.time()
##--- "nsparse*" sub-assignment :----------
M <- Matrix(c(1, rep(0,7), 1:4), 3,4)
N0 <- kronecker(M,M)
Nn <- as(N0, "nMatrix"); nn <- as(Nn,"matrix")
(Nn00 <- Nn0 <- Nn); nn00 <- nn0 <- nn
set.seed(1)
Nn0 <- Nn00; nn0 <- nn00
for(i in 1:(if(doExtras) 200 else 25)) {
Nn <- Nn0
nn <- nn0
i. <- getDuplIndex(nrow(N0), 6)
j. <- getDuplIndex(ncol(N0), 4)
vv <- sample(c(FALSE,TRUE),
length(i.)*length(j.), replace=TRUE)
cat(",")
Nn[i., j.] <- vv
nn[i., j.] <- vv
assert.EQ.mat(Nn, nn)
if(!all(Nn == nn)) {
cat("i=",i,":\n i. <- "); dput(i.)
cat("j. <- "); dput(j.)
cat("which(vv): "); dput(which(vv))
cat("Difference matrix:\n")
show(drop0(Nn - nn))
}
cat("k")
## sub-assign double precision to logical sparseMatrices: now *with* warning:
## {earlier: gave *no* warning}:
assertWarning(Nn[1:2,] <- -pi)
assertWarning(Nn[, 5] <- -pi)
assertWarning(Nn[2:4, 5:8] <- -pi)
stopifnotValid(Nn,"nsparseMatrix")
##
cat(".")
if(i %% 10 == 0) cat("\n")
if(i == 100) {
Nn0 <- as(Nn0, "CsparseMatrix")
cat("Now: class", class(Nn0)," :\n~~~~~~~~~~~~~~~~~\n")
}
}
showProc.time()
Nn <- Nn0
## Check that NA is interpreted as TRUE (with a warning), for "nsparseMatrix":
assertWarning(Nn[ii <- 3 ] <- NA); stopifnot(isValid(Nn,"nsparseMatrix"), Nn[ii])
assertWarning(Nn[ii <- 22:24] <- NA); stopifnot(isValid(Nn,"nsparseMatrix"), Nn[ii])
assertWarning(Nn[ii <- -(1:99)] <- NA); stopifnot(isValid(Nn,"nsparseMatrix"), Nn[ii])
assertWarning(Nn[ii <- 3:4 ] <- c(0,NA))
stopifnot(isValid(Nn,"nsparseMatrix"), Nn[ii] == 0:1)
assertWarning(Nn[ii <- 25:27] <- c(0,1,NA))
stopifnot(isValid(Nn,"nsparseMatrix"), Nn[ii] == c(FALSE,TRUE,TRUE))
m0 <- Diagonal(5)
stopifnot(identical(m0[2,], m0[,2]),
identical(m0[,1], c(1,0,0,0,0)))
### Diagonal -- Sparse:
(m1 <- as(m0, "TsparseMatrix")) # dtTMatrix unitriangular
(m2 <- as(m0, "CsparseMatrix")) # dtCMatrix unitriangular
m1g <- as(m1, "generalMatrix")
tr1 <- as(m1, "denseMatrix") # dtrMatrix unitriangular
stopifnotValid(m1g, "dgTMatrix")
diag(tr1) <- 100
stopifnot(diag(tr1) == 100)# failed when 'diag<-' did not recycle
assert.EQ.mat(m2[1:3,], diag(5)[1:3,])
assert.EQ.mat(m2[,c(4,1)], diag(5)[,c(4,1)])
stopifnot(identical(m2[1:3,], as(m1[1:3,], "CsparseMatrix")),
identical(asUniqueT(m1[, c(4,2)]),
asUniqueT(m2[, c(4,2)]))
)## failed in 0.9975-11
## 0-dimensional diagonal - subsetting ----------------------------
## before that diagU2N() etc for 0-dim. dtC*:
m0. <- m00 <- matrix(numeric(),0,0)
tC0.<- new("dtCMatrix")
tC0 <- new("dtCMatrix", diag="U")
(gC0 <- new("dgCMatrix")) # 0 x 0
D0 <- Diagonal(0)
stopifnot(exprs = {
identical(m0., as(tC0, "matrix")) # failed: Cholmod error 'invalid xtype' ..
identical(numeric(), as(tC0, "numeric"))# "
identical(numeric(), tC0[ 0 ])# --> .M.vectorSub(x, i) failed in as(., "matrix")
identical(m00[TRUE ], tC0[TRUE ])# (worked already)
identical(m00[FALSE], tC0[FALSE])# ditto
##
identical(D0, D0[0,0]) # used to fail --> subCsp_ij (..)
identical(gC0, D0[, 0]) # (ditto) --> subCsp_cols(..)
identical(gC0, D0[0, ]) # " --> subCsp_rows(..)
identical(D0, D0[,]) # (worked already)
identical(m00[ 0 ], D0[ 0 ] )# ditto
identical(m00[TRUE ], D0[TRUE ])# "
identical(m00[FALSE], D0[FALSE])# "
##
identical(tC0, tC0[0,0]) # failed --> subCsp_ij (..)
identical(gC0, tC0[ ,0]) # " --> subCsp_cols(..)
identical(gC0, tC0[0, ]) # " --> subCsp_rows(..)
identical(tC0, tC0[,]) # (worked already)
## vector indexing
})
expr <- quote({ ## FIXME -- both 'TRUE' and 'FALSE' should fail "out of bound",etc
D0[TRUE, TRUE ]
D0[ , TRUE ]
D0[TRUE, ] # worked but should *NOT*
tC0[TRUE, TRUE ]
tC0[ , TRUE ]
tC0[TRUE, ] # worked but should *NOT*
##
D0[FALSE,FALSE] # fails --> subCsp_ij(..) -> intI()
D0[ ,FALSE] # ditto ............
D0[FALSE, ] # ditto
tC0[FALSE,FALSE] # "
tC0[FALSE, ] # "
tC0[ ,FALSE] # "
})
EE <- lapply(expr[-1], function(e)
list(expr = e,
r = tryCatch(eval(e), error = identity)))
exR <- lapply(EE, `[[`, "r")
stopifnot(exprs = {
vapply(exR, inherits, logical(1), what = "error")
!englishMsgs ||
unique( vapply(exR, `[[`, "", "message")
) == "logical subscript too long"
})
(uTr <- new("dtTMatrix", Dim = c(3L,3L), diag="U"))
uTr[1,] <- 0
assert.EQ.mat(uTr, cbind(0, rbind(0,diag(2))))
M <- m0; M[1,] <- 0
Z <- m0; Z[] <- 0; z <- array(0, dim(M))
stopifnot(identical(M, Diagonal(x=c(0, rep(1,4)))),
all(Z == 0), Qidentical(as(Z, "matrix"), z))
M <- m0; M[,3] <- 3 ; M ; stopifnot(is(M, "sparseMatrix"), M[,3] == 3)
checkMatrix(M)
M <- m0; M[1:3, 3] <- 0 ;M
T <- m0; T[1:3, 3] <- 10
stopifnot(identical(M, Diagonal(x=c(1,1, 0, 1,1))),
isValid(T, "triangularMatrix"), identical(T[,3], c(10,10,10,0,0)))
M <- m1; M[1,] <- 0 ; M ; assert.EQ.mat(M, diag(c(0,rep(1,4))), tol=0)
M <- m1; M[,3] <- 3 ; stopifnot(is(M,"sparseMatrix"), M[,3] == 3)
Z <- m1; Z[] <- 0
checkMatrix(M)
M <- m1; M[1:3, 3] <- 0 ;M
assert.EQ.mat(M, diag(c(1,1, 0, 1,1)), tol=0)
T <- m1; T[1:3, 3] <- 10; checkMatrix(T)
stopifnot(is(T, "triangularMatrix"), identical(T[,3], c(10,10,10,0,0)),
Qidentical(as(Z, "matrix"), z))
M <- m2; M[1,] <- 0 ; M ; assert.EQ.mat(M, diag(c(0,rep(1,4))), tol=0)
M <- m2; M[,3] <- 3 ; stopifnot(is(M,"sparseMatrix"), M[,3] == 3)
checkMatrix(M)
Z <- m2; Z[] <- 0
M <- m2; M[1:3, 3] <- 0 ;M
assert.EQ.mat(M, diag(c(1,1, 0, 1,1)), tol=0)
T <- m2; T[1:3, 3] <- 10; checkMatrix(T)
stopifnot(is(T, "dtCMatrix"), identical(T[,3], c(10,10,10,0,0)),
Qidentical(as(Z, "matrix"), z))
showProc.time()
## "Vector indices" -------------------
asLogical <- function(x) {
stopifnot(is.atomic(x))
storage.mode(x) <- "logical"
x
}
.iniDiag.example <- expression({
D <- Diagonal(6)
M <- as(D,"generalMatrix") # was "dge", now "dgC"
d <- as(D,"unpackedMatrix") # "dtr" (unitri)
m <- as(D,"matrix")
s <- as(D,"TsparseMatrix"); N <- as(s,"nMatrix")
S <- as(s,"CsparseMatrix"); C <- as(S,"nMatrix")
})
eval(.iniDiag.example)
i <- c(3,1,6); v <- c(10,15,20)
## (logical,value) which both are recycled:
L <- c(TRUE, rep(FALSE,8)) ; z <- c(50,99)
## vector subassignment, both with integer & logical
## these now work correctly {though not very efficiently; hence warnings}
m[i] <- v # the role model: only first column is affected
M[i] <- v; assert.EQ.mat(M,m) # dgC
D[i] <- v; assert.EQ.mat(D,m) # ddi -> dtC (new! 2019-07; was dgT)
s[i] <- v; assert.EQ.mat(s,m) # dtT -> dgT
S[i] <- v; assert.EQ.mat(S,m); S # dtC -> dtT -> dgT -> dgC
m.L <- asLogical(m) ; assertWarning(
C[i] <- v, verbose=TRUE) # warning: C is nMatrix, v not T/F
assert.EQ.mat(C,m.L); validObject(C); assertWarning(
N[i] <- v, verbose=TRUE)
assert.EQ.mat(N,m.L); validObject(N)
stopifnot(identical(D, as(as(s, "triangularMatrix"), "CsparseMatrix")))
## logical *vector* indexing
eval(.iniDiag.example)
m[L] <- z; m.L <- asLogical(m)
M[L] <- z; assert.EQ.mat(M,m)
D[L] <- z; assert.EQ.mat(D,m)
s[L] <- z; assert.EQ.mat(s,m)
S[L] <- z; assert.EQ.mat(S,m) ; S ; assertWarning(
C[L] <- z, verbose=TRUE); assert.EQ.mat(C,m.L) ; assertWarning(
N[L] <- z, verbose=TRUE); assert.EQ.mat(N,m.L)
## indexing [i] vs [i,] --- now ok
eval(.iniDiag.example)
stopifnot(identical5(m[i], M[i], D[i], s[i], S[i]), identical3(as.logical(m[i]), C[i], N[i]),
identical5(m[L], M[L], D[L], s[L], S[L]), identical3(as.logical(m[L]), C[L], N[L]))
## bordercase ' drop = .' *vector* indexing {failed till 2009-04-..)
stopifnot(identical5(m[i,drop=FALSE], M[i,drop=FALSE], D[i,drop=FALSE],
s[i,drop=FALSE], S[i,drop=FALSE]),
identical3(as.logical(m[i,drop=FALSE]),
C[i,drop=FALSE], N[i,drop=FALSE]))
stopifnot(identical5(m[L,drop=FALSE], M[L,drop=FALSE], D[L,drop=FALSE],
s[L,drop=FALSE], S[L,drop=FALSE]),
identical3(as.logical(m[L,drop=FALSE]),
C[L,drop=FALSE], N[L,drop=FALSE]))
## using L for row-indexing should give an error
assertError(m[L,]); assertError(m[L,, drop=FALSE])
## these did not signal an error, upto (including) 0.999375-30:
assertError(s[L,]); assertError(s[L,, drop=FALSE])
assertError(S[L,]); assertError(S[L,, drop=FALSE])
assertError(N[L,]); assertError(N[L,, drop=FALSE])
## row indexing:
assert.EQ.mat(D[i,], m[i,])
assert.EQ.mat(M[i,], m[i,])
assert.EQ.mat(s[i,], m[i,])
assert.EQ.mat(S[i,], m[i,])
assert.EQ.mat(C[i,], asLogical(m[i,]))
assert.EQ.mat(N[i,], asLogical(m[i,]))
## column indexing:
assert.EQ.mat(D[,i], m[,i])
assert.EQ.mat(M[,i], m[,i])
assert.EQ.mat(s[,i], m[,i])
assert.EQ.mat(S[,i], m[,i])
assert.EQ.mat(C[,i], asLogical(m[,i]))
assert.EQ.mat(N[,i], asLogical(m[,i]))
### --- negative indices ----------
## 1) negative *vector* indexing
eval(.iniDiag.example)
i <- -(2:30)
stopifnot(identical5(m[i], M[i], D[i], s[i], S[i]),
identical3(as.logical(m[i]), C[i], N[i]))
## negative vector subassignment :
v <- seq_along(m[i])
m[i] <- v; m.L <- asLogical(m)
M[i] <- v; assert.EQ.mat(M,m) # dge
D[i] <- v; assert.EQ.mat(D,m) # ddi -> dtT -> dgT
s[i] <- v; assert.EQ.mat(s,m) # dtT -> dgT
S[i] <- v; assert.EQ.mat(S,m); S ; assertWarning( # dtC -> dtT -> dgT -> dgC
N[i] <- v, verbose=TRUE)
assert.EQ.mat(N,m.L); N ; assertWarning(
C[i] <- v, verbose=TRUE)
assert.EQ.mat(C,m.L); C #
options(warn = 2) #----------------------# NO WARNINGS from here -----------------
## =====================
## 2) negative [i,j] indices
mc <- mC[1:5, 1:7]
mt <- mT[1:5, 1:7]
## sub matrix
assert.EQ.mat(mC[1:2, 0:3], mm[1:2, 0:3]) # test 0-index
stopifnot(identical(mc[-(3:5), 0:2], mC[1:2, 0:2]),
identical(mt[-(3:5), 0:2], mT[1:2, 0:2]),
identical(mC[2:3, 4], mm[2:3, 4]))
assert.EQ.mat(mC[1:2,], mm[1:2,])
## sub vector
stopifnot(identical4(mc[-(1:4), ], mC[5, 1:7],
mt[-(1:4), ], mT[5, 1:7]))
stopifnot(identical4(mc[-(1:4), -(2:4)], mC[5, c(1,5:7)],
mt[-(1:4), -(2:4)], mT[5, c(1,5:7)]))
## mixing of negative and positive must give error
assertError(mT[-1:1,])
showProc.time()
## Sub *Assignment* ---- now works (partially):
mt0 <- mt
nt <- as(mt, "nMatrix")
mt[1, 4] <- -99
mt[2:3, 1:6] <- 0
mt
m2 <- mt+mt
m2[1,4] <- -200
m2[c(1,3), c(5:6,2)] <- 1:6
stopifnot(m2[1,4] == -200,
as.vector(m2[c(1,3), c(5:6,2)]) == 1:6)
mt[,3] <- 30
mt[2:3,] <- 250
mt[1:5 %% 2 == 1, 3] <- 0
mt[3:1, 1:7 > 5] <- 0
mt
tt <- as(mt,"matrix")
ii <- c(0,2,5)
jj <- c(2:3,5)
tt[ii, jj] <- 1:6 # 0 is just "dropped"
mt[ii, jj] <- 1:6
assert.EQ.mat(mt, tt)
mt[1:5, 2:6]
as((mt0 - mt)[1:5,], "dsparseMatrix")# [1,5] and lines 2:3
mt[c(2,4), ] <- 0; stopifnot(as(mt[c(2,4), ],"matrix") == 0)
mt[2:3, 4:7] <- 33
checkMatrix(mt)
mt
mc[1,4] <- -99 ; stopifnot(mc[1,4] == -99)
mc[1,4] <- 00 ; stopifnot(mc[1,4] == 00)
mc[1,4] <- -99 ; stopifnot(mc[1,4] == -99)
mc[1:2,4:3] <- 4:1; stopifnot(as(mc[1:2,4:3], "matrix") == 4:1)
mc[-1, 3] <- -2:1 # 0 should not be entered; 'value' recycled
mt[-1, 3] <- -2:1
stopifnot(mc@x != 0, mt@x != 0,
mc[-1,3] == -2:1, mt[-1,3] == -2:1) ## failed earlier
mc0 <- mc
mt0 <- as(mc0, "TsparseMatrix")
m0 <- as(mc0, "matrix")
set.seed(1); options(Matrix.verbose = FALSE)
for(i in 1:(if(doExtras) 50 else 4)) {
mc <- mc0; mt <- mt0 ; m <- m0
ev <- 1:5 %% 2 == round(runif(1))# 0 or 1
j <- sample(ncol(mc), 1 + round(runif(1)))
nv <- rpois(sum(ev) * length(j), lambda = 1)
mc[ev, j] <- nv
m[ev, j] <- nv
mt[ev, j] <- nv
if(i %% 10 == 1) print(mc[ev,j, drop = FALSE])
stopifnot(as.vector(mc[ev, j]) == nv, ## failed earlier...
as.vector(mt[ev, j]) == nv)
validObject(mc) ; assert.EQ.mat(mc, m)
validObject(mt) ; assert.EQ.mat(mt, m)
}
showProc.time()
options(Matrix.verbose = TRUE)
mc # no longer has non-structural zeros
mc[ii, jj] <- 1:6
mc[c(2,5), c(3,5)] <- 3.2
checkMatrix(mc)
m. <- mc
mc[4,] <- 0
mc
S <- as(Diagonal(5),"TsparseMatrix")
H <- Hilbert(9)
Hc <- as(round(H, 3), "CsparseMatrix")# a sparse matrix with no 0 ...
(trH <- tril(Hc[1:5, 1:5]))
stopifnot(is(trH, "triangularMatrix"), trH@uplo == "L",
is(S, "triangularMatrix"))
## triangular assignment
## the slick (but inefficient in case of sparse!) way to assign sub-diagonals:
## equivalent to tmp <- `diag<-`(S[,-1], -2:1); S[,-1] <- tmp
## which dispatches to (x="TsparseMatrix", i="missing",j="index", value="replValue")
diag(S[,-1]) <- -2:1 # used to give a wrong warning
S <- as(S,"triangularMatrix")
assert.EQ.mat(S, local({s <- diag(5); diag(s[,-1]) <- -2:1; s}))
trH[c(1:2,4), c(2:3,5)] <- 0 # gave an *error* upto Jan.2008
trH[ lower.tri(trH) ] <- 0 # ditto, because of callNextMethod()
m <- Matrix(0+1:28, nrow = 4)
m[-3,c(2,4:5,7)] <- m[ 3, 1:4] <- m[1:3, 6] <- 0
mT <- as(m, "TsparseMatrix")
stopifnot(identical(mT[lower.tri(mT)],
m [lower.tri(m) ]))
lM <- upper.tri(mT, diag=TRUE)
mT[lM] <- 0
m[lM] <- 0
assert.EQ.mat(mT, as(m,"matrix"))
mT[lM] <- -1:0
m[lM] <- -1:0
assert.EQ.mat(mT, as(m,"matrix"))
(mT <- drop0(mT))
i <- c(1:2, 4, 6:7); j <- c(2:4,6)
H[i,j] <- 0
(H. <- round(as(H, "sparseMatrix"), 3)[ , 2:7])
Hc. <- Hc
Hc.[i,j] <- 0 ## now "works", but setting "non-structural" 0s
stopifnot(as(Hc.[i,j], "matrix") == 0)
Hc.[, 1:6]
## an example that failed for a long time
sy3 <- new("dsyMatrix", Dim = as.integer(c(2, 2)), x = c(14, -1, 2, -7))
checkMatrix(dm <- kronecker(Diagonal(2), sy3))# now sparse with new kronecker
dm <- Matrix(as(dm, "matrix"))# -> "dsyMatrix"
(s2 <- as(dm, "sparseMatrix"))
checkMatrix(st <- as(s2, "TsparseMatrix"))
stopifnot(is(s2, "symmetricMatrix"),
is(st, "symmetricMatrix"))
checkMatrix(s.32 <- st[1:3,1:2]) ## 3 x 2 - and *not* dsTMatrix
checkMatrix(s2.32 <- s2[1:3,1:2])
I <- c(1,4:3)
stopifnot(is(s2.32, "generalMatrix"),
is(s.32, "generalMatrix"),
identical(as.mat(s.32), as.mat(s2.32)),
identical3(dm[1:3,-1], asD(s2[1:3,-1]), asD(st[1:3,-1])),
identical4(2, dm[4,3], s2[4,3], st[4,3]),
identical3(diag(dm), diag(s2), diag(st)),
is((cI <- s2[I,I]), "dsCMatrix"),
is((tI <- st[I,I]), "dsTMatrix"),
identical4(as.mat(dm)[I,I], as.mat(dm[I,I]), as.mat(tI), as.mat(cI))
)
## now sub-assign and check for consistency
## symmetric subassign should keep symmetry
st[I,I] <- 0; checkMatrix(st); stopifnot(is(st,"symmetricMatrix"))
s2[I,I] <- 0; checkMatrix(s2); stopifnot(is(s2,"symmetricMatrix"))
##
m <- as.mat(st)
m[2:1,2:1] <- 4:1
st[2:1,2:1] <- 4:1
s2[2:1,2:1] <- 4:1
stopifnot(identical(m, as.mat(st)),
1:4 == as.vector(s2[1:2,1:2]),
identical(m, as.mat(s2)))
## now a slightly different situation for 's2' (had bug)
s2 <- as(dm, "sparseMatrix")
s2[I,I] <- 0; diag(s2)[2:3] <- -(1:2)
stopifnot(is(s2,"symmetricMatrix"), diag(s2) == c(0:-2,0))
t2 <- as(s2, "TsparseMatrix")
m <- as.mat(s2)
s2[2:1,2:1] <- 4:1
t2[2:1,2:1] <- 4:1
m[2:1,2:1] <- 4:1
assert.EQ.mat(t2, m)
assert.EQ.mat(s2, m)
## and the same (for a different s2 !)
s2[2:1,2:1] <- 4:1
t2[2:1,2:1] <- 4:1
assert.EQ.mat(t2, m)# ok
assert.EQ.mat(s2, m)# failed in 0.9975-8
showProc.time()
## sub-assign RsparseMatrix -- Matrix bug [#6709] by David Cortes
## https://r-forge.r-project.org/tracker/?func=detail&atid=294&aid=6709&group_id=61
## simplified by MM
X <- new("dgCMatrix", i = c(0L,3L), p = c(0L,2L,2L,2L), x = c(100, -20), Dim = c(12L,3L))
R <- as(X, "RsparseMatrix")
T <- as(R, "TsparseMatrix")
T[, 2] <- 22 # works fine
R[, 2] <- 22 # failed, as it called replTmat() giving narg() == 3
## now R is Tsparse (as documented on ../man/RsparseMatrix-class.Rd),
identical(R, T) ## but as this may change, rather R & T should have the same *content*
assert.EQ.Mat(R, T)
## m[cbind(i,j)] <- value: (2-column matrix subassignment): -------------------------
m.[ cbind(3:5, 1:3) ] <- 1:3
stopifnot(m.[3,1] == 1, m.[4,2] == 2)
nt. <- nt ; nt[rbind(2:3, 3:4, c(3,3))] <- FALSE
s. <- m. ; m.[cbind(3,4:6)] <- 0 ## assigning 0 where there *is* 0 ..
stopifnot(identical(nt.,nt), ## should not have changed
identical(s., m.))
x.x[ cbind(2:6, 2:6)] <- 12:16
stopifnot(isValid(x.x, "dsCMatrix"),
12:16 == as.mat(x.x)[cbind(2:6, 2:6)])
(ne1 <- (mc - m.) != 0)
stopifnot(identical(ne1, 0 != abs(mc - m.)))
(ge <- m. >= mc) # contains "=" -> result is dense
ne. <- mc != m. # was wrong (+ warning)
stopifnot(identical(!(m. < mc), m. >= mc),
identical(m. < mc, as(!ge, "sparseMatrix")),
identical(ne., drop0(ne1)))
d6 <- Diagonal(6)
ii <- c(1:2, 4:5)
d6[cbind(ii,ii)] <- 7*ii
stopifnot(is(d6, "ddiMatrix"), identical(d6, Diagonal(x=c(7*1:2,1,7*4:5,1))))
sclass <- function(obj) as.vector(class(obj)) # as.v*(): drop attr(*,"package")
show2cls <- function(C,D, chr = "")
cat(sprintf("%s & %s%s: %s %s\n",
deparse(substitute(C)), deparse(substitute(D)), chr,
sclass(C), sclass(D)))
for(j in 2:6) { ## even and odd j used to behave differently
cat("j = ", j, ":\n-------\n")
M <- Matrix(0, j,j); m <- matrix(0, j,j)
T <- as(M, "TsparseMatrix")
TG <- as(T, "generalMatrix")
G <- as(M, "generalMatrix"); show2cls(TG, G)
stopifnot(is(TG, "TsparseMatrix"),
is(G, "CsparseMatrix"))
id <- cbind(1:j,1:j)
i2 <- cbind(1:j,j:1)
m[id] <- 1:j
M[id] <- 1:j
T[id] <- 1:j ; show2cls(M, T,' ("diag")')
stopifnot(is(M, "diagonalMatrix"), # since 2019-07 // FIXME (?!) for j=1
is(T,"triangularMatrix"), isDiagonal(T)) # was "symmetricMatrix"
G[id] <- 1:j
TG[id]<- 1:j
m[i2] <- 10
M[i2] <- 10
T[i2] <- 10 ; show2cls(M, T,' ("symm")')
G[i2] <- 10
TG[i2]<- 10
##
assert.EQ.mat(M, m)
assert.EQ.mat(T, m)
assert.EQ.mat(G, m)
assert.EQ.mat(TG,m)
}
## drop, triangular, ...
(M3 <- Matrix(upper.tri(matrix(, 3, 3)))) # ltC; indexing used to fail
T3 <- as(M3, "TsparseMatrix")
stopifnot(identical(drop(M3), M3),
identical4(drop(M3[,2, drop = FALSE]), M3[,2, drop = TRUE],
drop(T3[,2, drop = FALSE]), T3[,2, drop = TRUE]),
is(T3, "triangularMatrix"),
!is(T3[,2, drop=FALSE], "triangularMatrix")
)
(T6 <- as(as(as(kronecker(Matrix(c(0,0,1,0),2,2), t(T3)),
"lMatrix"), "triangularMatrix"), "TsparseMatrix"))
T6[1:4, -(1:3)] # failed (trying to coerce back to ltTMatrix)
stopifnot(identical(T6[1:4, -(1:3)][2:3, -3],
spMatrix(2,2, i=c(1,2,2), j=c(1,1,2), x=rep(TRUE,3))))
M <- Diagonal(4); M[1,2] <- 2
M. <- as(M, "CsparseMatrix")
(R <- as(M., "RsparseMatrix"))
(Ms <- symmpart(M.))
Rs <- as(Ms, "RsparseMatrix")
stopifnot(isValid(M, "triangularMatrix"),
isValid(M.,"triangularMatrix"),
isValid(Ms, "dsCMatrix"),
isValid(R, "dtRMatrix"),
isValid(Rs, "dsRMatrix") )
stopifnot(dim(M[2:3, FALSE]) == c(2,0),
dim(R[2:3, FALSE]) == c(2,0),
identical(M [2:3,TRUE], M [2:3,]),
identical(M.[2:3,TRUE], M.[2:3,]),
identical(R [2:3,TRUE], R [2:3,]),
dim(R[FALSE, FALSE]) == c(0,0))
n <- 50000L
Lrg <- new("dgTMatrix", Dim = c(n,n))
diag(Lrg) <- 1:n
dLrg <- as(Lrg, "diagonalMatrix")
stopifnot(identical(Diagonal(x = 1:n), dLrg))
diag(dLrg) <- 1 + diag(dLrg)
Clrg <- as(Lrg,"CsparseMatrix")
Ctrg <- as(Clrg, "triangularMatrix")
diag(Ctrg) <- 1 + diag(Ctrg)
stopifnot(identical(Diagonal(x = 1+ 1:n), dLrg),
identical(Ctrg, as(dLrg,"CsparseMatrix")))
cc <- capture.output(show(dLrg))# show() used to error for large n
showProc.time()
## FIXME: "dspMatrix" (symmetric *packed*) not going via "matrix"
## Large Matrix indexing / subassignment
## ------------------------------------- (from ex. by Imran Rashid)
n <- 7000000
m <- 100000
nnz <- 20000
op <- options(Matrix.verbose = 2, warn = 1)
set.seed(12)
f <- sparseMatrix(i = sample(n, size=nnz, replace=TRUE),
j = sample(m, size=nnz, replace=TRUE))
str(f)
dim(f) # 6999863 x 99992
prod(dim(f)) # 699930301096 == 699'930'301'096 (~ 700'000 millions)
str(thisCol <- f[,5000])# logi [~ 7 mio....]
sv <- as(thisCol, "sparseVector")
str(sv) ## "empty" !
validObject(spCol <- f[,5000, drop=FALSE]) # "empty" [n x 1] ngCmatrix
##
## *not* identical(): as(spCol, "sparseVector")@length is "double"prec:
stopifnot(all.equal(as(spCol, "sparseVector"),
as(sv, "nsparseVector"), tolerance=0))
if(interactive())
selectMethod("[<-", c("ngCMatrix", "missing","numeric", "logical"))
# -> replCmat() in ../R/Csparse.R
f[,5762] <- thisCol # now "fine" and fast thanks to replCmat() --> replCmat4()
fx <- sparseMatrix(i = sample(n, size=nnz, replace=TRUE),
j = sample(m, size=nnz, replace=TRUE),
x = round(10*rnorm(nnz)))
class(fx)## dgCMatrix
fx[,6000] <- (tC <- rep(thisCol, length.out=nrow(fx)))# fine
thCol <- fx[,2000]
fx[,5762] <- thCol# fine
stopifnot(is(f, "ngCMatrix"), is(fx, "dgCMatrix"),
identical(thisCol, f[,5762]),# perfect
identical(as.logical(fx[,6000]), tC),
identical(thCol, fx[,5762]))
showProc.time()
options(op)# revert
##
if(doExtras) {#-----------------------------------------------------------------
cat("checkMatrix() of all: \n---------\n")
Sys.setlocale("LC_COLLATE", "C")# to keep ls() reproducible
for(nm in ls()) if(is(.m <- get(nm), "Matrix")) {
cat(nm, "\n")
checkMatrix(.m, verbose = FALSE
, doDet = nm != "As" ## <- "As" almost singular <=> det() "ill posed"
)
}
showProc.time()
}#--------------end if(doExtras) -----------------------------------------------
## Bugs found by Peter Ralph
n <- 17
x <- Matrix(0, n,n) # "ddiMatrix" now
## x must have at least three nonzero entries
x[1,1] <- x[2,1:2] <- 1.; class(x) # "dtC"
x0 <- x <- as(x,"generalMatrix") # if x is dgCMatrix, no error
##
z <- matrix(x) # <== not the "Matrix way": a (n, 1) matrix
z[1] <- 0
x[1:n, 1:n] <- as(z, "sparseVector")
## gave Error: ... invalid subscript type 'S4'
x2 <- x
dim(zC <- as(z, "CsparseMatrix"))
x <- x0
x[] <- zC # did fail, then gave warning.
x1 <- x
##
x <- x0
x[] <- as(zC, "sparseVector") # did fail, too
x2 <- x
stopifnot(identical(x1,x2))
x <- as(x0, "matrix")
x[] <- z
assert.EQ.mat(x1, x)
i <- 4:7
x1 <- x0; x1[cbind(i, i+10)] <- i^2
x2 <- x0; x2[cbind(i, i+10)] <- as(i^2, "matrix")
## failed: nargs() = 4 ... please report
class(x1) # was "dgT", now "dgC"
stopifnot(isValid(x1, class(x1)), identical(x1, x2))
showProc.time()
## check valid indexing (using *random* indices, often duplicated):
chk_dsp_ind <- function(sv, n=512, negI = FALSE, verbose=FALSE) {
stopifnot(inherits(sv, "dsparseVector"), n >= 1)
d <- length(sv)
## lambda=2 ==> aiming for short 'i' {easier to work with}
P <- rpois(n, lambda = if(negI) 5 else 2)
for(i in seq_len(n)) {
I <-
if(negI) { # negative indices: 2 are, 4 neither ... always "valid" !!
k <- max(4L, d - max(1L, P[i]))
if(verbose) cat(sprintf("size=k = %2d: ", k))
- sort(sample.int(d, size=k))# replace=FALSE
}
else
sample.int(d, size=1L+P[i], replace=TRUE)
##
validObject(ss <- sv[I]) # Error if not true
}
invisible()
}
s <- as(c(3,5,6), "sparseVector")
set.seed(11); chk_dsp_ind(s)
set.seed(3)
(s2 <- as(rsparsematrix(ncol=1, nrow=37, density=1/4),"sparseVector"))
(s3 <- as(rsparsematrix(ncol=1, nrow=64, density=1/4),"sparseVector"))
set.seed(1)
chk_dsp_ind(s2)
chk_dsp_ind(s3)
##
set.seed(47)
## system.time(e.N2 <- chk_dsp_ind(s2, negI=TRUE, verbose=TRUE))
chk_dsp_ind(s2, negI=TRUE)
chk_dsp_ind(s3, negI=TRUE)
iv <- c(rep(0,100), 3, 0,0,7,0,0,0)
sv0 <- sv <- as(iv, "sparseVector")
sv.0 <- sv. <- as(as.integer(iv), "sparseVector")
stopifnot(canCoerce("integer", "sparseVector"))
sv2 <- as(sv, "isparseVector")
stopifnot(validObject(sv), validObject(sv2), identical(sv., sv2),
sv == sv.)
n0 <- sv. != 0 # -> is "lsparseV.."
sv [n0] <- sv [n0]
sv.[n0] <- sv.[n0] # gave error
stopifnot(identical(sv , sv0),
identical(sv., sv.0))
sv [3:7] <- 0
sv.[3:7] <- 0L
stopifnot(identical(sv , sv0), identical(sv., sv.0))
sv [2:4] <- 2:4
sv.[2:4] <- 2:4
stopifnot(which(sv != 0) == (which(sv. != 0) -> in0),
in0 == c(2:4, 101L, 104L))
sv [2:6] <- 0L
sv.[2:6] <- 0L
stopifnot(identical(sv , sv0), identical(sv., sv.0))
## the next six *all* gave an error -- but should be no-op's:
for(vv in list(sv, sv.0))
for(ind in list(0, FALSE, logical(length(vv))))
vv[ind] <- NA
stopifnot(identical(sv , sv0), identical(sv., sv.0))
## [i] <- val -- failed to resort @i sometimes: (R-forge Matrix bug #6659)
y1 <- sparseVector(1:3, 13:15, 16)
y2 <- sparseVector(1:6, c(5, 6, 7, 9, 14, 15), 16)
i <- 1:16*12 # 12 24 36 ... 192
x <- sparseVector(numeric(1), 1, length=200)
x[i] <- y1 ; validObject(x[i]) # TRUE
N <- x[i] + y2 ; validObject( N ) # TRUE
x[i] <- N ## <== bug was here ..
validObject(x)
## gave 'Error' invalid .."dsparseVector".. 'i' must be sorted strictly increasingly
stopifnot(all.equal(x[i] , y1+y2, tolerance=0),
x[i] == y1+y2)
showProc.time()
if(!interactive()) warnings()
## [matrix-Bugs][#6720] Subsetting with empty indices does not drop -- 17 Apr 2021, by David Cortes
## https://r-forge.r-project.org/tracker/?func=detail&atid=294&aid=6720&group_id=61
## extended by MM to all versions of "empty" :
x <- c(1,8)
(m1 <- rbind(x))
m1[] # remains matrix
m1[,,drop=FALSE] # ditto
m1[,] # [1] 1 2 -- drops (as default drop=TRUE !)
## Sparse Matrix and actually *any* Matrix-extending class did not work
(M1 <- as(m1, "denseMatrix")) # "dgeMatrix"
S1 <- as(m1, "CsparseMatrix")
R1 <- as(m1, "RsparseMatrix")
stopifnot(exprs = {
identical(M1[], M1) # remains
identical(S1[], S1) # remains
identical(R1[], R1) # remains
identical(M1[,,drop=FALSE], M1) # ditto
identical(S1[,,drop=FALSE], S1) # "
identical(R1[,,drop=FALSE], R1) # "
## but drop=TRUE which is the *default* much be obeyed (also for *empty* (i,j):
identical(m1[,], x)
identical(M1[,], x) # should drop, but did not
identical(S1[,], x) # "
identical(R1[,], x) # "
identical(m1[,,drop=TRUE], x)
identical(M1[,,drop=TRUE], x) # should drop, but did not
identical(S1[,,drop=TRUE], x) # "
identical(R1[,,drop=TRUE], x) # "
})
## [matrix-Bugs][#6721] Assignment to 'dgRMatrix' with missing index takes only first element
## MM: This has been fixed already!
X <- rbind(0, 1:3, 0, c(0,1,0))
Rx <- as(X, "RsparseMatrix")
Cx <- as(X, "CsparseMatrix")
X [2,] <- 0
Cx[2,] <- 0
Rx[2,] <- 0
stopifnot(all(Cx == X),
all(Rx == X))
## [matrix-Bugs][#6745] show()
## NB: is from a bug in head(*); *only* applies to *empty* sparseV: length(x@i) == 0
op <- options(max.print=999)
( s0 <- sparseVector(i=integer(), length=2^33)) # show -> head() failed in Matrix <= 1.3-*
(xs0 <- sparseVector(i=integer(), length=2^33, x = numeric()))# ditto
options(op); tail(s0) ; tail(xs0) # (always worked)
## *related* bug in `[` --> needed to fix intIv() for such large sparseVectors
stopifnot(exprs = {
identical(s0[length(s0) - 3:0], # gave Error in if (any(i < 0L)) { : missing value ....
new("nsparseVector", i=integer(), length=4L))
identical(xs0[length(s0) - 3:0], # gave Error ..
new("dsparseVector", i=integer(), length=4L))
})
## Yielded an invalid object in Matrix <= 1.4-1, instead of throwing error
llc04 <- new("dgCMatrix", Dim = c(4L, 0L))
c40 <- new("dgCMatrix", Dim = c(0L, 4L), p = integer(5L))
assertError(c04[1L, ] <- 1)
assertError(c40[, 1L] <- 1)
## Indexing with nMatrix rather than lMatrix
set.seed(3601)
gC <- rsparsematrix(6, 6, 0.6)
gC@x[sample.int(length(gC@x), 6L)] <- NA
ni <- is.na(gC)
li <- as(ni, "lMatrix")
stopifnot(identical(gC[ ni], gC[ li]),
identical(gC[!ni], gC[!li]))
## Dispatch thinko in Matrix <= 1.5-4
R0 <- R. <-
new("dgRMatrix",
Dim = c(12L, 12L),
p = c(0L, 0L, 4L, 5L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 16L),
j = c(0L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 7L, 8L, 4L, 7L, 9L, 9L, 10L, 11L),
x = as.double(1:16))
R.[1:2, ] <- R.[1:2, ] # was an error
stopifnot(identical(R0, as(R., "RsparseMatrix")))
## Didn't drop dimensions ...
stopifnot(identical(t(as(1:6,"CsparseMatrix"))[TRUE, ], as.double(1:6)))
## Was briefly wrong prior to Matrix 1.6-0
set.seed(0)
S <- new("dsyMatrix", Dim = c(4L, 4L), x = rnorm(16L))
Sii <- S[4:1, 4:1]
stopifnot(exprs = {
is(Sii, "dsyMatrix")
Sii@uplo == "L"
identical(as(Sii, "matrix"), as(S, "matrix")[4:1, 4:1])
})
## Bug #6839: regression in <.s[CT]Matrix>[] in Matrix 1.6-z
x <- new("dsCMatrix", Dim = c(4L, 4L),
p = cumsum(0:4), i = sequence(1:4) - 1L, x = as.double(1:10))
i <- c(TRUE, FALSE)
xi <- as(x, "matrix")[i]
for(cl in paste0(c("C", "R", "T"), "sparseMatrix"))
stopifnot(identical(as(x, cl)[i], xi))
Matrix/tests/other-pkgs.R 0000644 0001751 0000144 00000011464 14473555676 015140 0 ustar hornik users ####--------- Test interfaces to other non-standard Packages ---------------
## for R_DEFAULT_PACKAGES=NULL :
library(grDevices)
library(stats)
library(utils)
library(Matrix)
source(system.file("test-tools.R", package = "Matrix"))# identical3() etc
MatrixRversion <- pkgRversion("Matrix")
###-- 1) 'graph' (from Bioconductor) ---------------------------
###-- == ======= ---------------------------
if(requireNamespace("graph")) {
if(packageVersion("graph") <= "1.10.2") {
## graph 1.10.x for x <= 2 had too many problems as(, "matrix")
cat("Version of 'graph' is too old --- no tests done here!\n")
} else if(pkgRversion("graph") != MatrixRversion) {
cat(sprintf("The R version (%s) of 'graph' installation differs from the Matrix one (%s)\n",
pkgRversion("graph"), MatrixRversion))
} else { ## do things
if(doPdf <- !dev.interactive(orNone = TRUE))
pdf("other-pkgs-graph.pdf")
## 0) Simplest non-trivial graph: has no weights:
g0 <- graph::graphNEL(paste(1:2), edgeL=list("1"="2"), "directed")
m0 <- as(g0, "Matrix")
stopifnot(is(m0,"ngCMatrix"), dim(m0) == c(2,2), which(m0) == 3)
g. <- as(m0, "graph") ## failed in Matrix <= 1.1-0
m. <- as(g., "Matrix")
stopifnot( identical(m., m0) ) ## but (g0, g.) differ: the latter has '1' weights
## 1) undirected
V <- LETTERS[1:4]
edL <- vector("list", length=4)
names(edL) <- V
## 1a) unweighted
for(i in 1:4)
edL[[i]] <- list(edges = 5-i)
gR <- new("graphNEL", nodes=V, edgeL=edL)
str(graph::edges(gR))
sm.g <- as(gR, "sparseMatrix")
str(sm.g) ## dgC: TODO: want 'ds.' (symmetric)
validObject(sm.g)
show( sm.g )## (incl colnames !)
## 1b) weighted
set.seed(123)
for(i in 1:4)
edL[[i]] <- list(edges = 5-i, weights=runif(1))
gRw <- new("graphNEL", nodes=V, edgeL=edL)
str(graph::edgeWeights(gRw))
sm.gw <- as(gRw, "sparseMatrix")
str(sm.gw) ## *numeric* dgCMatrix
validObject(sm.gw)
show( sm.gw )## U[0,1] numbers in anti-diagonal
## 2) directed
gU <- gR; graph::edgemode(gU) <- "directed"
sgU <- as(gU, "sparseMatrix")
str(sgU) ## 'dgC'
validObject(sgU)
show( sgU )
## Reverse : sparseMatrix -> graph
sm.g[1,2] <- TRUE
gmg <- as(sm.g, "graph")
validObject(gmg2 <- as(sm.g, "graphNEL"))
gmgw <- as(sm.gw, "graph")
validObject(gmgw2 <- as(sm.gw, "graphNEL"))
gmgU <- as(sgU, "graph")
validObject(gmgU2 <- as(sgU, "graphNEL"))
stopifnot(identical(gmg, gmg2),
identical(gmgw, gmgw2),
identical(gmgU, gmgU2))
data(CAex, package = "Matrix")
cc <- crossprod(CAex)
## work around bug in 'graph': diagonal must be empty:
diag(cc) <- 0; cc <- drop0(cc)
image(cc)
gg <- as(cc, "graph")
## Don't run on CRAN and don't trigger 'R CMD check' :
if(doExtras && match.fun("requireNamespace")("Rgraphviz"))
get("plot", asNamespace("Rgraphviz"), mode = "function")(gg, "circo")
stopifnot(all.equal(graph::edgeMatrix(gg),
rbind(from = c(rep(1:24, each=2), 25:48),
to = c(rbind(25:48,49:72), 49:72))))
if(doPdf)
dev.off()
} # {else}
} # end{graph}
###-- 2) 'SparseM' ---------------------------------------------
###-- == ========= ---------------------------------------------
if(requireNamespace("SparseM")) {
if(pkgRversion("SparseM") != MatrixRversion) {
cat(sprintf("The R version (%s) of 'SparseM' installation differs from the Matrix one (%s)\n",
pkgRversion("SparseM"), MatrixRversion))
} else { ## do things
set.seed(1)
a <- round(rnorm(5*4), 2)
a[abs(a) < 0.7] <- 0
A <- matrix(a,5,4)
print(M <- Matrix(A))
stopifnot(
validObject(A.csr <- SparseM::as.matrix.csr(A)),
validObject(At.csr <- SparseM::as.matrix.csr(t(A))),
validObject(A.csc <- SparseM::as.matrix.csc(A)),
identical(At.csr, t(A.csr)),
identical(A, as.matrix(A.csr)),
identical(A.csr, as(M, "matrix.csr")),
identical(A.csc, as(M, "matrix.csc")),
identical3(M, as(A.csr, "CsparseMatrix"), as(A.csr, "dgCMatrix")),
identical(t(M), as(At.csr, "CsparseMatrix"))
)
## More tests, notably for triplets
A.coo <- SparseM::as.matrix.coo(A)
str(T <- as(M, "TsparseMatrix")) # has 'j' sorted
str(T. <- as(A.coo, "TsparseMatrix")) # has 'i' sorted
T3 <- as(as(T, "matrix.coo"), "Matrix") # dgT
M3 <- as(A.csr, "Matrix") # dgC
M4 <- as(A.csc, "Matrix") # dgC
M5 <- as(as(M, "matrix.coo"), "Matrix") # dgT
stopifnot(identical4(asUniqueT(T ), asUniqueT(T.),
asUniqueT(T3), asUniqueT(M5)),
identical3(M, M3, M4))
} # {else}
} # end{SparseM}
Matrix/tests/dg_Matrix.R 0000644 0001751 0000144 00000007016 14473555676 014771 0 ustar hornik users ## for R_DEFAULT_PACKAGES=NULL :
library(stats)
library(utils)
library(Matrix)
source(system.file("test-tools.R", package = "Matrix"))
data(KNex, package = "Matrix")
mm <- KNex$mm
stopifnot(##is(mm) == c("dgCMatrix", "dMatrix", "Matrix"),
dim(mm) == (dm <- c(1850, 712)),
identical(dimnames(mm), list(NULL,NULL)))
str(mm)
tmm <- t(mm)
str(tmm)
str(mTm <- crossprod(mm))
mmT <- crossprod(tmm)
mmT. <- tcrossprod(mm)
stopifnot(all.equal(mmT, mmT.))
## Previously these were not the same
## Should be the same but not quite: even length( * @ x ) differs!
##str(mmT, max=2)# much larger than mTm (i.e less sparse)
##str(mmT., max=2)# x slot is currently slightly larger --> improve tcrossprod()?
##system.time(ae <- all.equal(as(mmT.,"matrix"), as(mmT,"matrix"), tolerance = 1e-14))
## 4-5 seconds on a 850 MHz, P III
##stopifnot(ae)
stopifnot(validObject(tmm), dim(tmm) == dm[2:1],
validObject(mTm), dim(mTm) == dm[c(2,2)],
validObject(mmT), dim(mmT) == dm[c(1,1)],
identical(as(tmm, "matrix"), t(as(mm, "matrix"))))
## from a bug report by Guissepe Ragusa
RNGversion("3.6.0")# future proof
set.seed(101)
for(i in 1:10) {
A <- matrix(rnorm(400), nrow = 100, ncol = 4)
A[A < +1] <- 0 ; Am <- A
Acsc <- as(Am, "CsparseMatrix")
A <- as(Am, "unpackedMatrix")
b <- matrix(rnorm(400), nrow = 4, ncol = 100)
B <- as(b, "unpackedMatrix")
assert.EQ.mat(A %*% B, Am %*% b)
assert.EQ.mat(B %*% A, b %*% Am)
stopifnot(identical(A, as(Acsc, "unpackedMatrix")),
identical(Acsc, as(A, "CsparseMatrix")),
is.all.equal4(A %*% B, Acsc %*% B,
A %*% b, Acsc %*% b),
is.all.equal4(b %*% A, b %*% Acsc,
B %*% A, B %*% Acsc))
}
###--- dgTMatrix {was ./dgTMatrix.R } -------
### Use ``non-unique'' versions of dgTMatrix objects
N <- 200
set.seed(1)
i <- as.integer(round(runif (N, 0, 100)))
j <- as.integer(3* rpois (N, lambda=15))
x <- round(rnorm(N), 2)
which(duplicated(cbind(i,j))) # 8 index pairs are duplicated
m1 <- new("dgTMatrix", Dim = c(max(i)+1:1, max(j)+1:1), i = i, j = j, x = x)
mc <- as(m1, "CsparseMatrix")
m2 <- as(mc, "TsparseMatrix")## the same as 'm1' but without duplicates
stopifnot(!isTRUE(all.equal.default(m1, m2)),
all.equal(as(m1,"matrix"), as(m2,"matrix"), tolerance =1e-15),
all.equal(crossprod(m1), crossprod(m2), tolerance =1e-15),
identical(mc, as(m2, "CsparseMatrix")))
### -> uniq* functions now in ../R/Auxiliaries.R
(t2 <- system.time(um2 <- asUniqueT(m1)))
stopifnot(identical(m2,um2))
### -> error/warning condition for solve() of a singular matrix (Barry Rowlingson)
(M <- Matrix(0+ 1:16, ncol = 4))
assertError(solve(M), verbose=TRUE)## ".. computationally singular" + warning + caches LU
assertError(solve(t(M)))
options(warn=2) # no more warnings allowed from here
lum <- lu(M, warnSing=FALSE)
stopifnot(is(fLU <- M@factors[["denseLU"]], "MatrixFactorization"),
identical(lum, fLU))
(e.lu <- expand(fLU))
M2 <- with(e.lu, P %*% L %*% U)
assert.EQ.mat(M2, as(M, "matrix"))
## now the sparse LU :
M. <- as(M,"sparseMatrix")
tt <- try(solve(M.)) # less nice: factor is *not* cached
## use a non-singular one:
M1 <- M. + 0.5*Diagonal(nrow(M.))
luM1 <- lu(M1)
d1 <- determinant(as(M1,"denseMatrix"))
stopifnot(identical(luM1, M1@factors[["sparseLU~"]]),
diag(luM1@L) == 1,# L is *unit*-triangular
all.equal(log(-prod(diag(luM1@U))), c(d1$modulus)))
cat('Time elapsed: ', proc.time(),'\n') # for ``statistical reasons''
Matrix/tests/indexing.Rout.save 0000644 0001751 0000144 00000277027 14563762457 016355 0 ustar hornik users
R version 4.3.2 Patched (2024-02-13 r85897) -- "Eye Holes"
Copyright (C) 2024 The R Foundation for Statistical Computing
Platform: aarch64-apple-darwin22.6.0 (64-bit)
R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.
R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.
Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.
> #### For both 'Extract' ("[") and 'Replace' ("[<-") Method testing
> #### aka subsetting and subassignment
> #### ~~~~~~~~~~ ~~~~~~~~~~~~~
>
> ## for R_DEFAULT_PACKAGES=NULL :
> library(stats)
> library(utils)
>
> if(interactive()) {
+ options(error = recover, warn = 1)
+ } else if(FALSE) { ## MM / developer testing *manually* :
+ options(error = recover, Matrix.verbose = 2, warn = 1)
+ } else {
+ options( Matrix.verbose = 2, warn = 1)
+ }
> ## Matrix.verbose = .. (*before* loading 'Matrix' pkg)
> ## ==> will also show method dispath ambiguity messages: getOption("ambiguousMethodSelection")
>
> #### suppressPackageStartupMessages(...) as we have an *.Rout.save to Rdiff against
> suppressPackageStartupMessages(library(Matrix))
>
> source(system.file("test-tools.R", package = "Matrix"), keep.source = FALSE)
Loading required package: tools
> ##-> identical3() etc
> cat("doExtras:",doExtras,"\n")
doExtras: FALSE
> if(exists("Sys.setLanguage", mode="function"))
+ Sys.setLanguage("en")
> englishMsgs <- (lang <- Sys.getenv("LANGUAGE")) %in% c("en", "C")
> cat(sprintf("LANGUAGE env.: '%s'; englishMsgs: %s\n",
+ lang, englishMsgs))
LANGUAGE env.: 'en'; englishMsgs: TRUE
>
> ### Dense Matrices
>
> m <- Matrix(1:28 +0, nrow = 7)
> validObject(m)
[1] TRUE
> stopifnot(identical(m, m[]),
+ identical(m[2, 3], 16), # simple number
+ identical(m[2, 3:4], c(16,23)), # simple numeric of length 2
+ identical(m[NA,NA], as(Matrix(NA, 7,4), "dMatrix")))
>
> m[2, 3:4, drop=FALSE] # sub matrix of class 'dgeMatrix'
1 x 2 Matrix of class "dgeMatrix"
[,1] [,2]
[1,] 16 23
> m[-(4:7), 3:4] # ditto; the upper right corner of 'm'
3 x 2 Matrix of class "dgeMatrix"
[,1] [,2]
[1,] 15 22
[2,] 16 23
[3,] 17 24
>
> ## rows or columns only:
> m[1,] # first row, as simple numeric vector
[1] 1 8 15 22
> m[,2] # 2nd column
[1] 8 9 10 11 12 13 14
> m[,1:2] # sub matrix of first two columns
7 x 2 Matrix of class "dgeMatrix"
[,1] [,2]
[1,] 1 8
[2,] 2 9
[3,] 3 10
[4,] 4 11
[5,] 5 12
[6,] 6 13
[7,] 7 14
> m[-(1:6),, drop=FALSE] # not the first 6 rows, i.e. only the 7th
1 x 4 Matrix of class "dgeMatrix"
[,1] [,2] [,3] [,4]
[1,] 7 14 21 28
> m[integer(0),] #-> 0 x 4 Matrix
0 x 4 Matrix of class "dgeMatrix"
[,1] [,2] [,3] [,4]
> m[2:4, numeric(0)] #-> 3 x 0 Matrix
3 x 0 Matrix of class "dgeMatrix"
[1,]
[2,]
[3,]
>
> ## logical indexing
> stopifnot(identical(m[2,3], m[(1:nrow(m)) == 2, (1:ncol(m)) == 3]),
+ identical(m[2,], m[(1:nrow(m)) == 2, ]),
+ identical(m[,3:4], m[, (1:4) >= 3]))
>
> ## dimnames indexing:
> mn <- m
> dimnames(mn) <- list(paste("r",letters[1:nrow(mn)],sep=""),
+ LETTERS[1:ncol(mn)])
> checkMatrix(mn)
norm(m [7 x 4]) : 1 I F M ok
Summary: ok
2*m =?= m+m: identical
m >= m for all: ok
m < m for none: ok
> mn["rd", "D"]
[1] 25
> msr <- ms <- as(mn,"sparseMatrix")
> mnr <- mn
> v <- rev(as(ms, "vector"))
> mnr[] <- v
> msr[] <- v # [<- "sparse" -- not very sensical; did fail w/o a message
replCmat[x,i,j,..,val] : nargs()=3; missing (i,j) = (0,1)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> z <- msr; z[] <- 0
> zz <- as(array(0, dim(z)), "sparseMatrix")
> a.m <- as(mnr,"matrix")
> stopifnot(identical(mn["rc", "D"], mn[3,4]), mn[3,4] == 24,
+ identical(mn[, "A"], mn[,1]), mn[,1] == 1:7,
+ identical(mn[c("re", "rb"), "B"], mn[c(5,2), 2]),
+ identical(ms["rc", "D"], ms[3,4]), ms[3,4] == 24,
+ identical(ms[, "A"], ms[,1]), ms[,1] == 1:7,
+ identical(ms[ci <- c("re", "rb"), "B"], ms[c(5,2), 2]),
+ identical(rownames(mn[ci, ]), ci),
+ identical(rownames(ms[ci, ]), ci),
+ identical(colnames(mn[,cj <- c("B","D")]), cj),
+ identical(colnames(ms[,cj]), cj),
+ identical(a.m, as(msr,"matrix")),
+ identical(unname(z), zz),
+ identical(a.m, array(v, dim=dim(mn), dimnames=dimnames(mn)))
+ )
> showProc.time()
Time (user system elapsed): 0.164 0.007 0.171
>
> ## Bug found thanks to Timothy Mak, Feb 3, 2017:
> ## sparseMatrix logical indexing with (partial) NA:
> a.m <- as(mn,"matrix")
> assert.EQ(as(ms,"matrix"), a.m) # incl. dimnames
> iN4 <- c(NA, TRUE, FALSE, TRUE)
> assert.EQ(as(mn[,iN4],"matrix"), a.m[,iN4]) # (incl. dimnames)
> ##assert.EQ(as.matrix(ms[,iN4]), a.m[,iN4]) # ms[, ] fails still : _FIXME_
> try(ms[,iN4])
Error in ..subscript.2ary(x, l[[1L]], l[[2L]], drop = drop[1L]) :
NA subscripts in x[i,j] not supported for 'x' inheriting from sparseMatrix
> try(ms[,iN4] <- 100) ## <- segfaulted in Matrix <= 1.2-8 (!)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
Error in intI(i, n = di[margin], dn = dn[[margin]], give.dn = FALSE) :
'NA' indices are not (yet?) supported for sparse Matrices
>
> ## R-forge Matrix bug #2556: Subsetting a sparse matrix did remove names(dimnames(.)) :
> m44 <- matrix(1:16, 4, 4, dimnames=list(row=c('a','b','c','d'), col=c('x','y','z','w')))
> ## Dense matrix: ------------------------------------------
> a <- Matrix(m44)
> identical(
+ dimnames(m44[,FALSE, drop=FALSE]),
+ dimnames( a[,FALSE, drop=FALSE]))
[1] TRUE
> chk.ndn <- function(a, a0=m44)
+ stopifnot(identical(names(dimnames(a)), names(dimnames(a0))))
> i <- 1:2
> chk.ndn(a[i,]); chk.ndn(a[i, i])
> ## Sparse matrix: -----------------------------------------
> s <- as(a %% 3 == 1, "sparseMatrix")
> ts <- as(s,"TsparseMatrix")
> b <- sparseMatrix(i=1:3, j=rep(2,3), dims=c(4,4), dimnames=dimnames(s))
> tb <- as(b,"TsparseMatrix")
> stopifnot(identical5(
+ dimnames(a), dimnames(s), dimnames(ts),
+ dimnames(b), dimnames(tb)))
>
> chk.ndn(b [i, i]); chk.ndn(b [i, ])
> chk.ndn(s [i, i]); chk.ndn(s [i, ])
> chk.ndn(tb[i, i]); chk.ndn(tb[i, ])
> chk.ndn(ts[i, i]); chk.ndn(ts[i, ])
> chk.ndn( b[ , 1, drop=FALSE]); chk.ndn( s[i, 2, drop=FALSE])
> chk.ndn(tb[ , 1, drop=FALSE]); chk.ndn(ts[i, 2, drop=FALSE])
>
> L0 <- logical(0)
> stopifnot(exprs = {
+ identical(dim(b[,L0]), c(4L, 0L))
+ identical(dim(b[L0,]), c(0L, 4L)) # failed till 2019-09-x
+ })
>
> ## Printing sparse colnames:
> ms[sample(28, 20)] <- 0
replCmat[x,i,j,..,val] : nargs()=3; missing (i,j) = (0,1)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> ms <- t(rbind2(ms, 3*ms))
> cnam1 <- capture.output(show(ms))[2] ; op <- options("sparse.colnames" = "abb3")
[[ suppressing 14 column names 'ra', 'rb', 'rc' ... ]]
> cnam2 <- capture.output(show(ms))[2] ; options(op) # revert
> stopifnot(## sparse printing
+ grep("^ +$", cnam1) == 1, # cnam1 is empty
+ identical(cnam2,
+ paste(" ", paste(rep(rownames(mn), 2), collapse=" "))))
>
> mo <- m
> m[2,3] <- 100
> m[1:2, 4] <- 200
> m[, 1] <- -1
> m[1:3,]
3 x 4 Matrix of class "dgeMatrix"
[,1] [,2] [,3] [,4]
[1,] -1 8 15 200
[2,] -1 9 100 200
[3,] -1 10 17 24
>
> m. <- as(m, "matrix")
>
> ## m[ cbind(i,j) ] indexing:
> iN <- ij <- cbind(1:6, 2:3)
> iN[2:3,] <- iN[5,2] <- NA
> stopifnot(identical(m[ij], m.[ij]),
+ identical(m[iN], m.[iN]))
>
> ## testing operations on logical Matrices rather more than indexing:
> g10 <- m [ m > 10 ]
> stopifnot(18 == length(g10))
> stopifnot(10 == length(m[ m <= 10 ]))
> sel <- (20 < m) & (m < 150)
> sel.<- (20 < m.)& (m.< 150)
> nsel <-(20 >= m) | (m >= 150)
> (ssel <- as(sel, "sparseMatrix"))
7 x 4 sparse Matrix of class "lgCMatrix"
[1,] . . . .
[2,] . . | .
[3,] . . . |
[4,] . . . |
[5,] . . . |
[6,] . . . |
[7,] . . | |
> stopifnot(is(sel, "lMatrix"), is(ssel, "lsparseMatrix"),
+ identical3(as.mat(sel.), as.mat(sel), as.mat(ssel)),
+ identical3(!sel, !ssel, nsel), # ! is typically dense
+ identical3(m[ sel], m[ ssel], as(m, "matrix")[as( ssel, "matrix")]),
+ identical3(m[!sel], m[!ssel], as(m, "matrix")[as(!ssel, "matrix")])
+ )
> showProc.time()
Time (user system elapsed): 0.044 0.001 0.045
>
> ## more sparse Matrices --------------------------------------
>
> ##' @title Check sparseMatrix sub-assignment m[i,j] <- v
> ##' @param ms sparse Matrix
> ##' @param mm its [traditional matrix]-equivalent
> ##' @param k (approximate) length of index vectors (i,j)
> ##' @param n.uniq (approximate) number of unique values in i,j
> ##' @param vRNG function(n) for random 'v' generation
> ##' @param show logical; if TRUE, it will not stop on error
> ##' @return
> ##' @author Martin Maechler
> chkAssign <- function(ms, mm = as(ms, "matrix"),
+ k = min(20,dim(mm)), n.uniq = k %/% 3,
+ vRNG = { if(is.numeric(mm) || is.complex(mm))
+ function(n) rpois(n,lambda= 0.75)# <- about 47% zeros
+ else ## logical
+ function(n) runif(n) > 0.8 }, ## 80% zeros
+ showOnly=FALSE)
+ {
+ stopifnot(is(ms,"sparseMatrix"))
+ d <- dim(ms)
+ s1 <- function(n) sample(n, pmin(n, pmax(1, rpois(1, n.uniq))))
+ i <- sample(s1(d[1]), k/2+ rpois(1, k/2), replace = TRUE)
+ j <- sample(s1(d[2]), k/2+ rpois(1, k/2), replace = TRUE)
+ assert.EQ.mat(ms[i,j], mm[i,j])
+ ms2 <- ms. <- ms; mm. <- mm # save
+ ## now sub*assign* to these repeated indices, and then compare -----
+ v <- vRNG(length(i) * length(j))
+ mm[i,j] <- v
+ ms[i,j] <- v
+ ## useful to see (ii,ij), but confusing R/ESS when additionally debugging:
+ ## if(!showOnly && interactive()) { op <- options(error = recover); on.exit(options(op)) }
+ assert.EQ.mat(ms, mm, showOnly=showOnly)
+ ## vector indexing m[cbind(i,j)] == m[i + N(j-1)] , N = nrow(.)
+ ii <- seq_len(min(length(i), length(j)))
+ i <- i[ii]
+ j <- j[ii]
+ ij <- cbind(i, j)
+ ii <- i + nrow(ms)*(j - 1)
+ ord.i <- order(ii)
+ iio <- ii[ord.i]
+ ui <- unique(iio) # compare these with :
+ neg.ii <- - setdiff(seq_len(prod(d)), ii)
+ stopifnot(identical(mm[ii], mm[ij]),
+ identical(ms.[ui], ms.[neg.ii]),
+ ms.[ij] == mm.[ii], ## M[ cbind(i,j) ] was partly broken; now checking
+ ms.[ii] == mm.[ii])
+ v <- v[seq_len(length(i))]
+ if(is(ms,"nMatrix")) v <- as.logical(v) # !
+ mm.[ij] <- v
+ ms.[ii] <- v
+ nodup <- (length(ui) == length(ii)) ## <==> ! anyDuplicated(iio)
+ if(nodup) { cat("[-]") # rare, unfortunately
+ ms2[neg.ii] <- v[ord.i]
+ stopifnot(identical(ms2, ms.))
+ }
+ assert.EQ.mat(ms., mm., showOnly=showOnly)
+ } ##{chkAssign}
>
> ## Get duplicated index {because these are "hard" (and rare)
> getDuplIndex <- function(n, k) {
+ repeat {
+ i <- sample(n, k, replace=TRUE) # 3 4 6 9 2 9 : 9 is twice
+ if(anyDuplicated(i)) break
+ }
+ i
+ }
>
> suppressWarnings(RNGversion("3.5.0")); set.seed(101)
> m <- 1:800
> m[sample(800, 600)] <- 0
> m0 <- Matrix(m, nrow = 40)
> m1 <- add.simpleDimnames(m0)
> for(kind in c("n", "l", "d")) {
+ for(m in list(m0,m1)) { ## -- with and without dimnames -------------------------
+ kClass <-paste0(kind, "Matrix" )
+ Ckind <- paste0(kind, "gCMatrix")
+ Tkind <- paste0(kind, "gTMatrix")
+ str(mC <- as(as(as(m, kClass), "CsparseMatrix"), "generalMatrix")) # was as(m, Ckind) deprecated
+ #was mT <- as(as(as(m, kClass), "TsparseMatrix"), Tkind))
+ str(mT <- as(as(as(m, kClass), "generalMatrix"), "TsparseMatrix"))
+ mm <- as(mC, "matrix") # also logical or double
+ IDENT <- if(kind == "n") function(x,y) Q.eq2(x,y, tol=0) else identical
+ stopifnot(exprs = {
+ identical(mT, as(mC, "TsparseMatrix"))
+ identical(mC, as(mT, "CsparseMatrix")) # was Ckind; now deprecated
+ Qidentical(mC[0,0], new(Ckind)) # M..3 Csp..4
+ Qidentical(mT[0,0], new(Tkind)) # "
+ identical(unname(mT[0,]), new(Tkind, Dim = c(0L,ncol(m))))# M.3 T.4 C.4
+ identical(unname(mT[,0]), new(Tkind, Dim = c(nrow(m),0L)))# M.3 C.4
+ is.null(cat("IDENT():\n"))
+ IDENT(mC[0,], as(mT[FALSE,], "CsparseMatrix")) # M.3 C.4 M.3 + Tsp..4 Csp..4 | as(., Ckind) deprecated
+ IDENT(mC[,0], as(mT[,FALSE], "CsparseMatrix")) # M.3 C.4 M.3 C.4 | as(., Ckind) deprecated
+ is.null(cat("sapply(..):\n"))
+ sapply(pmin(min(dim(mC)), c(0:2, 5:10)),
+ function(k) {i <- seq_len(k); all(mC[i,i] == mT[i,i])})
+ })
+ cat("ok\n")
+ show(mC[,1])
+ show(mC[1:2,])
+ show(mC[7, drop = FALSE])
+ assert.EQ.mat(mC[1:2,], mm[1:2,])
+ assert.EQ.mat(mC[0,], mm[0,])
+ assert.EQ.mat(mC[,FALSE], mm[,FALSE])
+ ##
+ ## *repeated* (aka 'duplicated') indices - did not work at all ...
+ i <- pmin(nrow(mC), rep(8:10,2))
+ j <- c(2:4, 4:3)
+ assert.EQ.mat(mC[i,], mm[i,])
+ assert.EQ.mat(mC[,j], mm[,j])
+ ## FIXME? assert.EQ.mat(mC[,NA], mm[,NA]) -- mC[,NA] is all 0 "instead" of all NA
+ ## MM currently thinks we should NOT allow [ ]
+ assert.EQ.mat(mC[i, 2:1], mm[i, 2:1])
+ assert.EQ.mat(mC[c(4,1,2:1), j], mm[c(4,1,2:1), j])
+ assert.EQ.mat(mC[i,j], mm[i,j])
+ ##
+ ## set.seed(7)
+ op <- options(Matrix.verbose = FALSE)
+ cat(" for(): ")
+ for(n in 1:(if(doExtras) 50 else 5)) { # (as chkAssign() is random)
+ chkAssign(mC, mm)
+ chkAssign(mC[-3,-2], mm[-3,-2])
+ cat(".")
+ }
+ options(op)
+ cat(sprintf("\n[Ok]%s\n\n", strrep("-", 64)))
+ }
+ cat(sprintf("\nok( %s )\n== ###%s\n\n", kind, strrep("=", 70)))
+ }## end{for}---------------------------------------------------------------
Formal class 'ngCMatrix' [package "Matrix"] with 5 slots
..@ i : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
..@ p : int [1:21] 0 8 22 28 37 41 50 63 71 81 ...
..@ Dim : int [1:2] 40 20
..@ Dimnames:List of 2
.. ..$ : NULL
.. ..$ : NULL
..@ factors : list()
Formal class 'ngTMatrix' [package "Matrix"] with 5 slots
..@ i : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
..@ j : int [1:200] 0 0 0 0 0 0 0 0 1 1 ...
..@ Dim : int [1:2] 40 20
..@ Dimnames:List of 2
.. ..$ : NULL
.. ..$ : NULL
..@ factors : list()
IDENT():
sapply(..):
ok
[1] FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE TRUE
[13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE
[25] TRUE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
[37] FALSE TRUE TRUE FALSE
2 x 20 sparse Matrix of class "ngCMatrix"
[1,] . . . | . . | . . . . | . . | . | . . .
[2,] . | . . . | . . . . . . | | . . . . | .
[1] TRUE
for(): .....
[Ok]----------------------------------------------------------------
Formal class 'ngCMatrix' [package "Matrix"] with 5 slots
..@ i : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
..@ p : int [1:21] 0 8 22 28 37 41 50 63 71 81 ...
..@ Dim : int [1:2] 40 20
..@ Dimnames:List of 2
.. ..$ : chr [1:40] "r1" "r2" "r3" "r4" ...
.. ..$ : chr [1:20] "c1" "c2" "c3" "c4" ...
..@ factors : list()
Formal class 'ngTMatrix' [package "Matrix"] with 5 slots
..@ i : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
..@ j : int [1:200] 0 0 0 0 0 0 0 0 1 1 ...
..@ Dim : int [1:2] 40 20
..@ Dimnames:List of 2
.. ..$ : chr [1:40] "r1" "r2" "r3" "r4" ...
.. ..$ : chr [1:20] "c1" "c2" "c3" "c4" ...
..@ factors : list()
IDENT():
sapply(..):
ok
r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13
FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE TRUE FALSE
r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 r26
FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE TRUE FALSE
r27 r28 r29 r30 r31 r32 r33 r34 r35 r36 r37 r38 r39
FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE
r40
FALSE
2 x 20 sparse Matrix of class "ngCMatrix"
[[ suppressing 20 column names 'c1', 'c2', 'c3' ... ]]
r1 . . . | . . | . . . . | . . | . | . . .
r2 . | . . . | . . . . . . | | . . . . | .
[1] TRUE
for(): .....
[Ok]----------------------------------------------------------------
ok( n )
== ###======================================================================
Formal class 'lgCMatrix' [package "Matrix"] with 6 slots
..@ i : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
..@ p : int [1:21] 0 8 22 28 37 41 50 63 71 81 ...
..@ Dim : int [1:2] 40 20
..@ Dimnames:List of 2
.. ..$ : NULL
.. ..$ : NULL
..@ x : logi [1:200] TRUE TRUE TRUE TRUE TRUE TRUE ...
..@ factors : list()
Formal class 'lgTMatrix' [package "Matrix"] with 6 slots
..@ i : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
..@ j : int [1:200] 0 0 0 0 0 0 0 0 1 1 ...
..@ Dim : int [1:2] 40 20
..@ Dimnames:List of 2
.. ..$ : NULL
.. ..$ : NULL
..@ x : logi [1:200] TRUE TRUE TRUE TRUE TRUE TRUE ...
..@ factors : list()
IDENT():
sapply(..):
ok
[1] FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE TRUE
[13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE
[25] TRUE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
[37] FALSE TRUE TRUE FALSE
2 x 20 sparse Matrix of class "lgCMatrix"
[1,] . . . | . . | . . . . | . . | . | . . .
[2,] . | . . . | . . . . . . | | . . . . | .
[1] TRUE
for(): .....
[Ok]----------------------------------------------------------------
Formal class 'lgCMatrix' [package "Matrix"] with 6 slots
..@ i : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
..@ p : int [1:21] 0 8 22 28 37 41 50 63 71 81 ...
..@ Dim : int [1:2] 40 20
..@ Dimnames:List of 2
.. ..$ : chr [1:40] "r1" "r2" "r3" "r4" ...
.. ..$ : chr [1:20] "c1" "c2" "c3" "c4" ...
..@ x : logi [1:200] TRUE TRUE TRUE TRUE TRUE TRUE ...
..@ factors : list()
Formal class 'lgTMatrix' [package "Matrix"] with 6 slots
..@ i : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
..@ j : int [1:200] 0 0 0 0 0 0 0 0 1 1 ...
..@ Dim : int [1:2] 40 20
..@ Dimnames:List of 2
.. ..$ : chr [1:40] "r1" "r2" "r3" "r4" ...
.. ..$ : chr [1:20] "c1" "c2" "c3" "c4" ...
..@ x : logi [1:200] TRUE TRUE TRUE TRUE TRUE TRUE ...
..@ factors : list()
IDENT():
sapply(..):
ok
r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13
FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE TRUE FALSE
r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 r26
FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE TRUE FALSE
r27 r28 r29 r30 r31 r32 r33 r34 r35 r36 r37 r38 r39
FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE
r40
FALSE
2 x 20 sparse Matrix of class "lgCMatrix"
[[ suppressing 20 column names 'c1', 'c2', 'c3' ... ]]
r1 . . . | . . | . . . . | . . | . | . . .
r2 . | . . . | . . . . . . | | . . . . | .
[1] TRUE
for(): .....
[Ok]----------------------------------------------------------------
ok( l )
== ###======================================================================
Formal class 'dgCMatrix' [package "Matrix"] with 6 slots
..@ i : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
..@ p : int [1:21] 0 8 22 28 37 41 50 63 71 81 ...
..@ Dim : int [1:2] 40 20
..@ Dimnames:List of 2
.. ..$ : NULL
.. ..$ : NULL
..@ x : num [1:200] 3 7 12 22 25 30 38 39 42 45 ...
..@ factors : list()
Formal class 'dgTMatrix' [package "Matrix"] with 6 slots
..@ i : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
..@ j : int [1:200] 0 0 0 0 0 0 0 0 1 1 ...
..@ Dim : int [1:2] 40 20
..@ Dimnames:List of 2
.. ..$ : NULL
.. ..$ : NULL
..@ x : num [1:200] 3 7 12 22 25 30 38 39 42 45 ...
..@ factors : list()
IDENT():
sapply(..):
ok
[1] 0 0 3 0 0 0 7 0 0 0 0 12 0 0 0 0 0 0 0 0 0 22 0 0 25
[26] 0 0 0 0 30 0 0 0 0 0 0 0 38 39 0
2 x 20 sparse Matrix of class "dgCMatrix"
[1,] . . . 121 . . 241 . . . . 441 . . 561 . 641 . . .
[2,] . 42 . . . 202 . . . . . . 482 522 . . . . 722 .
[1] 7
for(): .....
[Ok]----------------------------------------------------------------
Formal class 'dgCMatrix' [package "Matrix"] with 6 slots
..@ i : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
..@ p : int [1:21] 0 8 22 28 37 41 50 63 71 81 ...
..@ Dim : int [1:2] 40 20
..@ Dimnames:List of 2
.. ..$ : chr [1:40] "r1" "r2" "r3" "r4" ...
.. ..$ : chr [1:20] "c1" "c2" "c3" "c4" ...
..@ x : num [1:200] 3 7 12 22 25 30 38 39 42 45 ...
..@ factors : list()
Formal class 'dgTMatrix' [package "Matrix"] with 6 slots
..@ i : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
..@ j : int [1:200] 0 0 0 0 0 0 0 0 1 1 ...
..@ Dim : int [1:2] 40 20
..@ Dimnames:List of 2
.. ..$ : chr [1:40] "r1" "r2" "r3" "r4" ...
.. ..$ : chr [1:20] "c1" "c2" "c3" "c4" ...
..@ x : num [1:200] 3 7 12 22 25 30 38 39 42 45 ...
..@ factors : list()
IDENT():
sapply(..):
ok
r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 r16 r17 r18 r19 r20
0 0 3 0 0 0 7 0 0 0 0 12 0 0 0 0 0 0 0 0
r21 r22 r23 r24 r25 r26 r27 r28 r29 r30 r31 r32 r33 r34 r35 r36 r37 r38 r39 r40
0 22 0 0 25 0 0 0 0 30 0 0 0 0 0 0 0 38 39 0
2 x 20 sparse Matrix of class "dgCMatrix"
[[ suppressing 20 column names 'c1', 'c2', 'c3' ... ]]
r1 . . . 121 . . 241 . . . . 441 . . 561 . 641 . . .
r2 . 42 . . . 202 . . . . . . 482 522 . . . . 722 .
[1] 7
for(): .....
[Ok]----------------------------------------------------------------
ok( d )
== ###======================================================================
> showProc.time()
Time (user system elapsed): 0.21 0.008 0.218
>
> if(doExtras) {### {was ./AAA_index.R, MM-only}
+ ## an nsparse-example
+ A <- Matrix(c(rep(c(1,0,0),2), rep(c(2,0),7), c(0,0,2), rep(0,4)), 3,9)
+ i <- c(3,1:2)
+ j <- c(3, 5, 9, 5, 9)
+ vv <- logical(length(i)*length(j)); vv[6:9] <- TRUE
+
+ print(An <- as(A,"nMatrix")); an <- as(An, "matrix")
+ assert.EQ.mat(An, an)
+ An[i, j] <- vv
+ an[i, j] <- vv
+ assert.EQ.mat(An, an)## error
+ if(!all(An == an)) show(drop0(An - an))
+ ## all are +1
+
+ options("Matrix.subassign.verbose" = TRUE)# output from C
+ An <- as(A,"nMatrix"); An[i, j] <- vv
+ ## and compare with this:
+ Al <- as(A,"lMatrix"); Al[i, j] <- vv
+ options("Matrix.subassign.verbose" = FALSE)
+
+ ##--- An interesting not small not large example for M[i,j] <- v ------------
+ ##
+ M <- Matrix(c(1, rep(0,7), 1:4), 3,4)
+ N0 <- kronecker(M,M)
+ mkN1 <- function(M) {
+ stopifnot(length(d <- dim(M)) == 2)
+ isC <- is(M,"CsparseMatrix")
+ M[,d[2]] <- c(0,2,0)
+ N <- kronecker(diag(x=1:2), M)## remains sparse if 'M' is
+ if(isC) N <- as(N, "CsparseMatrix")
+ diag(N[-1,]) <- -2
+ N[9,] <- 1:4 # is recycled
+ N[,12] <- -7:-9 # ditto
+ N
+ }
+
+ show(N1 <- t(N <- mkN1(N0))) # transpose {for display reasons}
+ C1 <- t(C <- mkN1(as(N0,"CsparseMatrix")))
+ stopifnot(all(C == N))
+ assert.EQ.mat(C, mkN1(as(N0, "matrix")))
+
+ C. <- C1
+ show(N <- N1) ; n <- as(N, "matrix"); str(N)
+ sort(i <- c(6,8,19,11,21,20,10,7,12,9,5,18,17,22,13))## == c(5:13, 17:22))
+ sort(j <- c(3,8,6,15,10,4,14,13,16,2,11,17,7,5))## == c(2:8, 10:11, 13:17)
+ val <- v.l <- 5*c(0,6,0,7,0,0,8:9, 0,0)
+ show(spv <- as(val, "sparseVector")); str(spv)
+
+ n [i,j] <- v.l
+ N [i,j] <- val# is recycled, too
+ C.[i,j] <- val
+ assert.EQ.mat(N,n) ; stopifnot(all(C. == N))
+ ## and the same *again*:
+ n [i,j] <- v.l
+ N [i,j] <- val
+ C.[i,j] <- val
+ assert.EQ.mat(N,n)
+ stopifnot(all(C. == N))
+
+ print(load(system.file("external", "symA.rda", package="Matrix"))) # "As"
+ stopifnotValid(As, "dsCMatrix"); stopifnot(identical(As@factors, list()))
+ R. <- drop0(chol(As))
+ stopifnot(exprs = {
+ 1:32 == sort(diag(R.)) ## !
+ R.@x > 0
+ R.@x == as.integer(R.@x)## so it is an integer-valued chol-decomp !
+ ## shows that (1) As is *not* singular (2) the matrix is not random
+ all.equal(crossprod(R.), As, tolerance=1e-15)
+ })
+ print(summary(evA <- eigen(As, only.values=TRUE)$values))
+ print(tail(evA)) ## largest three ~= 10^7, smallest two *negative*
+ print(rcond(As)) # 1.722 e-21 == very bad !
+ ##-> this *is* a border line case, i.e. very close to singular !
+ ## and also determinant(.) is rather random here!
+ cc0 <- Cholesky(As)# no problem
+ try({
+ cc <- Cholesky(As, super=TRUE)
+ ## gives --on 32-bit only--
+ ## Cholmod error 'matrix not positive definite' at file:../Supernodal/t_cholmod_super_numeric.c, line 613
+ ecc <- expand(cc)
+ L.P <- with(ecc, crossprod(L,P)) ## == L'P
+ ## crossprod(L.P) == (L'P)' L'P == P'LL'P
+ stopifnot( all.equal(crossprod(L.P), As) )
+ })
+ ##---- end{ eigen( As ) -----------
+
+ } ## only if(doExtras)
>
>
> ##---- Symmetric indexing of symmetric Matrix ----------
> m. <- mC
> m.[, c(2, 7:12)] <- 0
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
> stopifnotValid(S <- crossprod(add.simpleDimnames(m.) %% 100), "dsCMatrix")
> ss <- as(S, "matrix")
> ds <- as(S, "denseMatrix")
> ## NA-indexing of *dense* Matrices: should work as traditionally
> assert.EQ.mat(ds[NA,NA], ss[NA,NA])
> assert.EQ.mat(ds[NA, ], ss[NA,])
> assert.EQ.mat(ds[ ,NA], ss[,NA])
> T <- as(S, "TsparseMatrix")
> stopifnot(identical(ds[2 ,NA], ss[2,NA]),
+ identical(ds[NA, 1], ss[NA, 1]),
+ identical(S, as(T, "CsparseMatrix")) )
>
> ## non-repeated indices:
> i <- c(7:5, 2:4);assert.EQ.mat(T[i,i], ss[i,i])
> ## NA in indices -- check that we get a helpful error message:
> i[2] <- NA
> er <- tryCatch(T[i,i], error = function(e)e)
> if(englishMsgs)
+ stopifnot(as.logical(grep("indices.*sparse Matrices", er$message)))
>
> N <- nrow(T)
> set.seed(11)
> for(n in 1:(if(doExtras) 50 else 3)) {
+ i <- sample(N, max(2, sample(N,1)), replace = FALSE)
+ validObject(Tii <- T[i,i]) ; tTi <- t(T)[i,i]
+ stopifnot(is(Tii, "dsTMatrix"), # remained symmetric Tsparse
+ is(tTi, "dsTMatrix"), # may not be identical when *sorted* differently
+ identical(as(t(Tii),"CsparseMatrix"), as(tTi,"CsparseMatrix")))
+ assert.EQ.mat(Tii, ss[i,i])
+ }
>
> b <- diag(1:2)[,c(1,1,2,2)]
> cb <- crossprod(b)
> cB <- crossprod(Matrix(b, sparse=TRUE))
> a <- matrix(0, 6, 6)
> a[1:4, 1:4] <- cb
> A1 <- A2 <- Matrix(0, 6, 6)#-> ddiMatrix
> A1[1:4, 1:4] <- cb
replCmat[x,i,j,..,val] : nargs()=4;
> A2[1:4, 1:4] <- cB
replCmat[x,i,j,..,val] : nargs()=4;
> assert.EQ.mat(A1, a)# indeed
> ## "must": symmetric and sparse, i.e., ds*Matrix:
> stopifnot(identical(A1, A2), is(A1, "dsCMatrix"))
>
> ## repeated ones ``the challenge'' (to do smartly):
> j <- c(4, 4, 9, 12, 9, 4, 17, 3, 18, 4, 12, 18, 4, 9)
> assert.EQ.mat(T[j,j], ss[j,j])
> ## and another two sets (a, A) & (a., A.) :
> a <- matrix(0, 6,6)
> a[upper.tri(a)] <- (utr <- c(2, 0,-1, 0,0,5, 7,0,0,0, 0,0,-2,0,8))
> ta <- t(a); ta[upper.tri(a)] <- utr; a <- t(ta)
> diag(a) <- c(0,3,0,4,6,0)
> A <- as(Matrix(a), "TsparseMatrix")
> A. <- A
> diag(A.) <- 10 * (1:6)
> a. <- as(A., "matrix")
> ## More testing {this was not working for a long time..}
> set.seed(1)
> for(n in 1:(if(doExtras) 100 else 6)) {
+ i <- sample(1:nrow(A), 3+2*rpois(1, lambda=3), replace=TRUE)
+ Aii <- A[i,i]
+ A.ii <- A.[i,i]
+ stopifnot(class(Aii) == class(A),
+ class(A.ii) == class(A.))
+ assert.EQ.mat(Aii , a [i,i])
+ assert.EQ.mat(A.ii, a.[i,i])
+ assert.EQ.mat(T[i,i], ss[i,i])
+ }
> showProc.time()
Time (user system elapsed): 0.055 0.002 0.056
>
> stopifnot(all.equal(mC[,3], mm[,3]),
+ identical(mC[ij], mC[ij + 0.4]),
+ identical(mC[ij], mm[ij]),
+ identical(mC[iN], mm[iN]))
> ## out of bound indexing must be detected:
> assertError(mC[cbind(ij[,1] - 5, ij[,2])])
> assertError(mC[cbind(ij[,1], ij[,2] + ncol(mC))])
>
> assert.EQ.mat(mC[7, , drop=FALSE], mm[7, , drop=FALSE])
> identical (mC[7, drop=FALSE], mm[7, drop=FALSE]) # *vector* indexing
[1] TRUE
>
> stopifnot(dim(mC[numeric(0), ]) == c(0,20), # used to give warnings
+ dim(mC[, integer(0)]) == c(40,0),
+ identical(mC[, integer(0)], mC[, FALSE]))
> validObject(print(mT[,c(2,4)]))
40 x 2 sparse Matrix of class "dgTMatrix"
c2 c4
r1 . 121
r2 42 .
r3 . .
r4 . .
r5 45 .
r6 . .
r7 . .
r8 . 128
r9 . 129
r10 50 .
r11 . .
r12 52 132
r13 . 133
r14 . .
r15 55 .
r16 . .
r17 . .
r18 . 138
r19 . .
r20 . .
r21 . 141
r22 . 142
r23 63 .
r24 . .
r25 65 .
r26 . .
r27 67 .
r28 68 .
r29 . .
r30 . .
r31 71 .
r32 72 .
r33 . .
r34 74 .
r35 . .
r36 76 .
r37 . .
r38 . .
r39 . 159
r40 80 .
[1] TRUE
> stopifnot(all.equal(mT[2,], mm[2,]),
+ ## row or column indexing in combination with t() :
+ Q.C.identical(mT[2,], t(mT)[,2]),
+ Q.C.identical(mT[-2,], t(t(mT)[,-2])),
+ Q.C.identical(mT[c(2,5),], t(t(mT)[,c(2,5)])) )
> assert.EQ.mat(mT[4,, drop = FALSE], mm[4,, drop = FALSE])
> stopifnot(identical3(mm[,1], mC[,1], mT[,1]),
+ identical3(mm[3,], mC[3,], mT[3,]),
+ identical3(mT[2,3], mC[2,3], 0),
+ identical(mT[], mT),
+ identical4( mm[c(3,7), 2:4], as.mat( m[c(3,7), 2:4]),
+ as.mat(mT[c(3,7), 2:4]), as.mat(mC[c(3,7), 2:4]))
+ )
>
> x.x <- crossprod(mC)
> stopifnot(class(x.x) == "dsCMatrix",
+ class(x.x. <- round(x.x / 10000)) == "dsCMatrix",
+ identical(x.x[cbind(2:6, 2:6)],
+ diag(x.x[2:6, 2:6], names=FALSE)))
> head(x.x.) # Note the *non*-structural 0's printed as "0"
6 x 20 sparse Matrix of class "dgCMatrix"
[[ suppressing 20 column names 'c1', 'c2', 'c3' ... ]]
c1 1 0 . 1 . 1 1 3 . 3 2 1 6 1 . 2 4 6 5 1
c2 0 6 2 1 3 5 7 5 12 14 14 9 11 16 12 13 17 19 19 10
c3 . 2 6 . 4 2 5 3 8 12 5 16 9 11 23 . . 6 7 7
c4 1 1 . 17 . 8 10 13 8 6 18 18 29 35 14 8 25 10 19 21
c5 . 3 4 . 14 4 10 . . 29 8 9 19 11 11 . . 26 26 16
c6 1 5 2 8 4 42 5 19 14 9 8 10 42 56 50 27 29 32 64 16
> tail(x.x., -3) # all but the first three lines
17 x 20 sparse Matrix of class "dgCMatrix"
[[ suppressing 20 column names 'c1', 'c2', 'c3' ... ]]
c4 1 1 . 17 . 8 10 13 8 6 18 18 29 35 14 8 25 10 19 21
c5 . 3 4 . 14 4 10 . . 29 8 9 19 11 11 . . 26 26 16
c6 1 5 2 8 4 42 5 19 14 9 8 10 42 56 50 27 29 32 64 16
c7 1 7 5 10 10 5 87 14 9 31 77 47 79 43 28 17 67 110 36 121
c8 3 5 3 13 . 19 14 70 10 24 37 13 59 62 34 19 58 21 64 44
c9 . 12 8 8 . 14 9 10 116 41 58 33 33 72 78 43 69 72 75 25
c10 3 14 12 6 29 9 31 24 41 167 69 56 99 44 70 24 105 82 85 32
c11 2 14 5 18 8 8 77 37 58 69 267 80 86 139 49 105 194 119 122 129
c12 1 9 16 18 9 10 47 13 33 56 80 194 70 77 81 . 90 32 . 106
c13 6 11 9 29 19 42 79 59 33 99 86 70 324 157 55 . 69 142 144 155
c14 1 16 11 35 11 56 43 62 72 44 139 77 157 375 123 102 145 39 196 81
c15 . 12 23 14 11 50 28 34 78 70 49 81 55 123 368 71 112 41 41 86
c16 2 13 . 8 . 27 17 19 43 24 105 . . 102 71 233 124 44 139 .
c17 4 17 . 25 . 29 67 58 69 105 194 90 69 145 112 124 523 141 245 100
c18 6 19 6 10 26 32 110 21 72 82 119 32 142 39 41 44 141 497 104 111
c19 5 19 7 19 26 64 36 64 75 85 122 . 144 196 41 139 245 104 542 55
c20 1 10 7 21 16 16 121 44 25 32 129 106 155 81 86 . 100 111 55 541
>
> lx.x <- as(as(x.x, "lMatrix"), "symmetricMatrix") # FALSE only for "structural" 0
> (l10 <- lx.x[1:10, 1:10])# "lsC"
10 x 10 sparse Matrix of class "lsCMatrix"
[[ suppressing 10 column names 'c1', 'c2', 'c3' ... ]]
c1 | | . | . | | | . |
c2 | | | | | | | | | |
c3 . | | . | | | | | |
c4 | | . | . | | | | |
c5 . | | . | | | . . |
c6 | | | | | | | | | |
c7 | | | | | | | | | |
c8 | | | | . | | | | |
c9 . | | | . | | | | |
c10 | | | | | | | | | |
> (l3 <- lx.x[1:3, ])
3 x 20 sparse Matrix of class "lgCMatrix"
[[ suppressing 20 column names 'c1', 'c2', 'c3' ... ]]
c1 | | . | . | | | . | | | | | . | | | | |
c2 | | | | | | | | | | | | | | | | | | | |
c3 . | | . | | | | | | | | | | | . . | | |
> m.x <- as.mat(x.x) # as.mat() *drops* (NULL,NULL) dimnames
> stopifnot(class(l10) == "lsCMatrix", # symmetric indexing -> symmetric !
+ identical(as.mat(lx.x), m.x != 0),
+ identical(as.logical(lx.x), as.logical(m.x)),
+ identical(as.mat(l10), m.x[1:10, 1:10] != 0),
+ identical(as.mat(l3 ), m.x[1:3, ] != 0)
+ )
>
> ##-- Sub*assignment* with repeated / duplicated index:
> A <- Matrix(0,4,3) ; A[c(1,2,1), 2] <- 1 ; A
replCmat[x,i,j,..,val] : nargs()=4;
4 x 3 sparse Matrix of class "dgCMatrix"
[1,] . 1 .
[2,] . 1 .
[3,] . . .
[4,] . . .
> B <- A; B[c(1,2,1), 2] <- 1:3; B; B. <- B
replCmat[x,i,j,..,val] : nargs()=4;
4 x 3 sparse Matrix of class "dgCMatrix"
[1,] . 3 .
[2,] . 2 .
[3,] . . .
[4,] . . .
> B.[3,] <- rbind(4:2)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
> ## change the diagonal and the upper and lower subdiagonal :
> diag(B.) <- 10 * diag(B.)
> diag(B.[,-1]) <- 5* diag(B.[,-1])
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
> diag(B.[-1,]) <- 4* diag(B.[-1,]) ; B.
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
4 x 3 sparse Matrix of class "dgCMatrix"
[1,] . 15 .
[2,] . 20 .
[3,] 4 12 20
[4,] . . .
> C <- B.; C[,2] <- C[,2]; C[1,] <- C[1,]; C[2:3,2:1] <- C[2:3,2:1]
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4;
> stopifnot(identical(unname(as(A, "matrix")),
+ local({a <- matrix(0,4,3); a[c(1,2,1), 2] <- 1 ; a})),
+ identical(unname(as(B, "matrix")),
+ local({a <- matrix(0,4,3); a[c(1,2,1), 2] <- 1:3; a})),
+ identical(C, drop0(B.)))
> ## [] <- v failed in the past
> T <- as(C,"TsparseMatrix"); C. <- C
> T[T>0] <- 21
.TM.repl.i.mat(): "lMatrix" case ...
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> C[C>0] <- 21
.TM.repl.i.mat(): "lMatrix" case ...
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> a. <- local({a <- as(C., "matrix"); a[a>0] <- 21; a})
> assert.EQ.mat(C, a.)
> stopifnot(identical(C, as(T, "CsparseMatrix")))
>
> ## used to fail
> n <- 5 ## or much larger
> sm <- new("dsTMatrix", i=1L, j=1L, Dim=as.integer(c(n,n)), x = 1)
> (cm <- as(sm, "CsparseMatrix"))
5 x 5 sparse Matrix of class "dsCMatrix"
[1,] . . . . .
[2,] . 1 . . .
[3,] . . . . .
[4,] . . . . .
[5,] . . . . .
> sm[2,]
[1] 0 1 0 0 0
> stopifnot(sm[2,] == c(0:1, rep.int(0,ncol(sm)-2)),
+ sm[2,] == cm[2,],
+ sm[,3] == sm[3,],
+ all(sm[,-(1:3)] == t(sm[-(1:3),])), # all()
+ all(sm[,-(1:3)] == 0)
+ )
> showProc.time()
Time (user system elapsed): 0.049 0.003 0.053
>
> ##--- "nsparse*" sub-assignment :----------
> M <- Matrix(c(1, rep(0,7), 1:4), 3,4)
> N0 <- kronecker(M,M)
> Nn <- as(N0, "nMatrix"); nn <- as(Nn,"matrix")
> (Nn00 <- Nn0 <- Nn); nn00 <- nn0 <- nn
9 x 16 sparse Matrix of class "ngCMatrix"
[1,] | . . | . . . . . . . . | . . |
[2,] . . . | . . . . . . . . . . . |
[3,] . . | | . . . . . . . . . . | |
[4,] . . . . . . . . . . . . | . . |
[5,] . . . . . . . . . . . . . . . |
[6,] . . . . . . . . . . . . . . | |
[7,] . . . . . . . . | . . | | . . |
[8,] . . . . . . . . . . . | . . . |
[9,] . . . . . . . . . . | | . . | |
>
> set.seed(1)
> Nn0 <- Nn00; nn0 <- nn00
> for(i in 1:(if(doExtras) 200 else 25)) {
+ Nn <- Nn0
+ nn <- nn0
+ i. <- getDuplIndex(nrow(N0), 6)
+ j. <- getDuplIndex(ncol(N0), 4)
+ vv <- sample(c(FALSE,TRUE),
+ length(i.)*length(j.), replace=TRUE)
+ cat(",")
+ Nn[i., j.] <- vv
+ nn[i., j.] <- vv
+ assert.EQ.mat(Nn, nn)
+ if(!all(Nn == nn)) {
+ cat("i=",i,":\n i. <- "); dput(i.)
+ cat("j. <- "); dput(j.)
+ cat("which(vv): "); dput(which(vv))
+ cat("Difference matrix:\n")
+ show(drop0(Nn - nn))
+ }
+ cat("k")
+ ## sub-assign double precision to logical sparseMatrices: now *with* warning:
+ ## {earlier: gave *no* warning}:
+ assertWarning(Nn[1:2,] <- -pi)
+ assertWarning(Nn[, 5] <- -pi)
+ assertWarning(Nn[2:4, 5:8] <- -pi)
+ stopifnotValid(Nn,"nsparseMatrix")
+ ##
+ cat(".")
+ if(i %% 10 == 0) cat("\n")
+ if(i == 100) {
+ Nn0 <- as(Nn0, "CsparseMatrix")
+ cat("Now: class", class(Nn0)," :\n~~~~~~~~~~~~~~~~~\n")
+ }
+ }
,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.
,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.
,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.,replCmat[x,i,j,..,val] : nargs()=4;
kreplCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
replCmat[x,i,j,..,val] : nargs()=4;
.> showProc.time()
Time (user system elapsed): 0.056 0.001 0.058
> Nn <- Nn0
> ## Check that NA is interpreted as TRUE (with a warning), for "nsparseMatrix":
> assertWarning(Nn[ii <- 3 ] <- NA); stopifnot(isValid(Nn,"nsparseMatrix"), Nn[ii])
replCmat[x,i,j,..,val] : nargs()=3; missing (i,j) = (0,1)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> assertWarning(Nn[ii <- 22:24] <- NA); stopifnot(isValid(Nn,"nsparseMatrix"), Nn[ii])
replCmat[x,i,j,..,val] : nargs()=3; missing (i,j) = (0,1)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> assertWarning(Nn[ii <- -(1:99)] <- NA); stopifnot(isValid(Nn,"nsparseMatrix"), Nn[ii])
replCmat[x,i,j,..,val] : nargs()=3; missing (i,j) = (0,1)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> assertWarning(Nn[ii <- 3:4 ] <- c(0,NA))
replCmat[x,i,j,..,val] : nargs()=3; missing (i,j) = (0,1)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> stopifnot(isValid(Nn,"nsparseMatrix"), Nn[ii] == 0:1)
> assertWarning(Nn[ii <- 25:27] <- c(0,1,NA))
replCmat[x,i,j,..,val] : nargs()=3; missing (i,j) = (0,1)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> stopifnot(isValid(Nn,"nsparseMatrix"), Nn[ii] == c(FALSE,TRUE,TRUE))
>
> m0 <- Diagonal(5)
> stopifnot(identical(m0[2,], m0[,2]),
+ identical(m0[,1], c(1,0,0,0,0)))
> ### Diagonal -- Sparse:
> (m1 <- as(m0, "TsparseMatrix")) # dtTMatrix unitriangular
5 x 5 sparse Matrix of class "dtTMatrix" (unitriangular)
[1,] I . . . .
[2,] . I . . .
[3,] . . I . .
[4,] . . . I .
[5,] . . . . I
> (m2 <- as(m0, "CsparseMatrix")) # dtCMatrix unitriangular
5 x 5 sparse Matrix of class "dtCMatrix" (unitriangular)
[1,] I . . . .
[2,] . I . . .
[3,] . . I . .
[4,] . . . I .
[5,] . . . . I
> m1g <- as(m1, "generalMatrix")
> tr1 <- as(m1, "denseMatrix") # dtrMatrix unitriangular
> stopifnotValid(m1g, "dgTMatrix")
> diag(tr1) <- 100
> stopifnot(diag(tr1) == 100)# failed when 'diag<-' did not recycle
> assert.EQ.mat(m2[1:3,], diag(5)[1:3,])
> assert.EQ.mat(m2[,c(4,1)], diag(5)[,c(4,1)])
> stopifnot(identical(m2[1:3,], as(m1[1:3,], "CsparseMatrix")),
+ identical(asUniqueT(m1[, c(4,2)]),
+ asUniqueT(m2[, c(4,2)]))
+ )## failed in 0.9975-11
>
> ## 0-dimensional diagonal - subsetting ----------------------------
> ## before that diagU2N() etc for 0-dim. dtC*:
> m0. <- m00 <- matrix(numeric(),0,0)
> tC0.<- new("dtCMatrix")
> tC0 <- new("dtCMatrix", diag="U")
> (gC0 <- new("dgCMatrix")) # 0 x 0
0 x 0 sparse Matrix of class "dgCMatrix"
<0 x 0 matrix>
> D0 <- Diagonal(0)
> stopifnot(exprs = {
+ identical(m0., as(tC0, "matrix")) # failed: Cholmod error 'invalid xtype' ..
+ identical(numeric(), as(tC0, "numeric"))# "
+ identical(numeric(), tC0[ 0 ])# --> .M.vectorSub(x, i) failed in as(., "matrix")
+ identical(m00[TRUE ], tC0[TRUE ])# (worked already)
+ identical(m00[FALSE], tC0[FALSE])# ditto
+ ##
+ identical(D0, D0[0,0]) # used to fail --> subCsp_ij (..)
+ identical(gC0, D0[, 0]) # (ditto) --> subCsp_cols(..)
+ identical(gC0, D0[0, ]) # " --> subCsp_rows(..)
+ identical(D0, D0[,]) # (worked already)
+ identical(m00[ 0 ], D0[ 0 ] )# ditto
+ identical(m00[TRUE ], D0[TRUE ])# "
+ identical(m00[FALSE], D0[FALSE])# "
+ ##
+ identical(tC0, tC0[0,0]) # failed --> subCsp_ij (..)
+ identical(gC0, tC0[ ,0]) # " --> subCsp_cols(..)
+ identical(gC0, tC0[0, ]) # " --> subCsp_rows(..)
+ identical(tC0, tC0[,]) # (worked already)
+ ## vector indexing
+ })
>
> expr <- quote({ ## FIXME -- both 'TRUE' and 'FALSE' should fail "out of bound",etc
+ D0[TRUE, TRUE ]
+ D0[ , TRUE ]
+ D0[TRUE, ] # worked but should *NOT*
+ tC0[TRUE, TRUE ]
+ tC0[ , TRUE ]
+ tC0[TRUE, ] # worked but should *NOT*
+ ##
+ D0[FALSE,FALSE] # fails --> subCsp_ij(..) -> intI()
+ D0[ ,FALSE] # ditto ............
+ D0[FALSE, ] # ditto
+ tC0[FALSE,FALSE] # "
+ tC0[FALSE, ] # "
+ tC0[ ,FALSE] # "
+ })
> EE <- lapply(expr[-1], function(e)
+ list(expr = e,
+ r = tryCatch(eval(e), error = identity)))
> exR <- lapply(EE, `[[`, "r")
> stopifnot(exprs = {
+ vapply(exR, inherits, logical(1), what = "error")
+ !englishMsgs ||
+ unique( vapply(exR, `[[`, "", "message")
+ ) == "logical subscript too long"
+ })
>
>
> (uTr <- new("dtTMatrix", Dim = c(3L,3L), diag="U"))
3 x 3 sparse Matrix of class "dtTMatrix" (unitriangular)
[1,] I . .
[2,] . I .
[3,] . . I
> uTr[1,] <- 0
.. replTmat(x,i,j,v): nargs()= 4; cl.(x)=dtTMatrix; len.(value)=1; missing (i,j) = (0,1)
> assert.EQ.mat(uTr, cbind(0, rbind(0,diag(2))))
>
> M <- m0; M[1,] <- 0
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
> Z <- m0; Z[] <- 0; z <- array(0, dim(M))
> stopifnot(identical(M, Diagonal(x=c(0, rep(1,4)))),
+ all(Z == 0), Qidentical(as(Z, "matrix"), z))
> M <- m0; M[,3] <- 3 ; M ; stopifnot(is(M, "sparseMatrix"), M[,3] == 3)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
5 x 5 sparse Matrix of class "dgCMatrix"
[1,] 1 . 3 . .
[2,] . 1 3 . .
[3,] . . 3 . .
[4,] . . 3 1 .
[5,] . . 3 . 1
> checkMatrix(M)
Compare -- "dgCMatrix" != "dgCMatrix" :
norm(m [5 x 5]) : 1 I F M ok
Summary: ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: identical
m >= m for all: ok
m < m for none: Compare -- "dgCMatrix" < "dgCMatrix" :
ok
symmpart(m) + skewpart(m) == m: ok; determinant(): ok
> M <- m0; M[1:3, 3] <- 0 ;M
replCmat[x,i,j,..,val] : nargs()=4;
5 x 5 diagonal matrix of class "ddiMatrix"
[,1] [,2] [,3] [,4] [,5]
[1,] 1 . . . .
[2,] . 1 . . .
[3,] . . 0 . .
[4,] . . . 1 .
[5,] . . . . 1
> T <- m0; T[1:3, 3] <- 10
replCmat[x,i,j,..,val] : nargs()=4;
> stopifnot(identical(M, Diagonal(x=c(1,1, 0, 1,1))),
+ isValid(T, "triangularMatrix"), identical(T[,3], c(10,10,10,0,0)))
>
> M <- m1; M[1,] <- 0 ; M ; assert.EQ.mat(M, diag(c(0,rep(1,4))), tol=0)
.. replTmat(x,i,j,v): nargs()= 4; cl.(x)=dtTMatrix; len.(value)=1; missing (i,j) = (0,1)
5 x 5 sparse Matrix of class "dtTMatrix"
[1,] . . . . .
[2,] . 1 . . .
[3,] . . 1 . .
[4,] . . . 1 .
[5,] . . . . 1
> M <- m1; M[,3] <- 3 ; stopifnot(is(M,"sparseMatrix"), M[,3] == 3)
.. replTmat(x,i,j,v): nargs()= 4; cl.(x)=dtTMatrix; len.(value)=1; missing (i,j) = (1,0)
M[i,j] <- v : coercing symmetric M[] into non-symmetric
> Z <- m1; Z[] <- 0
> checkMatrix(M)
Compare -- "dgCMatrix" != "dgCMatrix" :
norm(m [5 x 5]) : 1 I F M ok
Summary: ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: ok
m >= m for all: ok
m < m for none: Compare -- "dgCMatrix" < "dgCMatrix" :
ok
symmpart(m) + skewpart(m) == m: ok; determinant(): ok
> M <- m1; M[1:3, 3] <- 0 ;M
.. replTmat(x,i,j,v): nargs()= 4; cl.(x)=dtTMatrix; len.(value)=1;
5 x 5 sparse Matrix of class "dtTMatrix"
[1,] 1 . . . .
[2,] . 1 . . .
[3,] . . . . .
[4,] . . . 1 .
[5,] . . . . 1
> assert.EQ.mat(M, diag(c(1,1, 0, 1,1)), tol=0)
> T <- m1; T[1:3, 3] <- 10; checkMatrix(T)
.. replTmat(x,i,j,v): nargs()= 4; cl.(x)=dtTMatrix; len.(value)=1;
Compare -- "dtCMatrix" != "dtCMatrix" :
norm(m [5 x 5]) : 1 I F M ok
Summary: ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: identical
m >= m for all: ok
m < m for none: Compare -- "dtCMatrix" < "dtCMatrix" :
ok
symmpart(m) + skewpart(m) == m: ok; determinant(): ok
.TM.repl.i.mat(): drop 'matrix' case ...
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class dtTMatrix to dgTMatrix
as(mm., "triangularMatrix"): valid: TRUE
> stopifnot(is(T, "triangularMatrix"), identical(T[,3], c(10,10,10,0,0)),
+ Qidentical(as(Z, "matrix"), z))
>
> M <- m2; M[1,] <- 0 ; M ; assert.EQ.mat(M, diag(c(0,rep(1,4))), tol=0)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (0,1)
5 x 5 sparse Matrix of class "dtCMatrix"
[1,] . . . . .
[2,] . 1 . . .
[3,] . . 1 . .
[4,] . . . 1 .
[5,] . . . . 1
> M <- m2; M[,3] <- 3 ; stopifnot(is(M,"sparseMatrix"), M[,3] == 3)
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
> checkMatrix(M)
Compare -- "dgCMatrix" != "dgCMatrix" :
norm(m [5 x 5]) : 1 I F M ok
Summary: ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: identical
m >= m for all: ok
m < m for none: Compare -- "dgCMatrix" < "dgCMatrix" :
ok
symmpart(m) + skewpart(m) == m: ok; determinant(): ok
> Z <- m2; Z[] <- 0
> M <- m2; M[1:3, 3] <- 0 ;M
replCmat[x,i,j,..,val] : nargs()=4;
5 x 5 sparse Matrix of class "dtCMatrix"
[1,] 1 . . . .
[2,] . 1 . . .
[3,] . . . . .
[4,] . . . 1 .
[5,] . . . . 1
> assert.EQ.mat(M, diag(c(1,1, 0, 1,1)), tol=0)
> T <- m2; T[1:3, 3] <- 10; checkMatrix(T)
replCmat[x,i,j,..,val] : nargs()=4;
Compare -- "dtCMatrix" != "dtCMatrix" :
norm(m [5 x 5]) : 1 I F M ok
Summary: ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: identical
m >= m for all: ok
m < m for none: Compare -- "dtCMatrix" < "dtCMatrix" :
ok
symmpart(m) + skewpart(m) == m: ok; determinant(): ok
.TM.repl.i.mat(): drop 'matrix' case ...
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class dtTMatrix to dgTMatrix
as(mm., "triangularMatrix"): valid: TRUE
> stopifnot(is(T, "dtCMatrix"), identical(T[,3], c(10,10,10,0,0)),
+ Qidentical(as(Z, "matrix"), z))
> showProc.time()
Time (user system elapsed): 0.178 0.003 0.18
>
>
> ## "Vector indices" -------------------
> asLogical <- function(x) {
+ stopifnot(is.atomic(x))
+ storage.mode(x) <- "logical"
+ x
+ }
> .iniDiag.example <- expression({
+ D <- Diagonal(6)
+ M <- as(D,"generalMatrix") # was "dge", now "dgC"
+ d <- as(D,"unpackedMatrix") # "dtr" (unitri)
+ m <- as(D,"matrix")
+ s <- as(D,"TsparseMatrix"); N <- as(s,"nMatrix")
+ S <- as(s,"CsparseMatrix"); C <- as(S,"nMatrix")
+ })
> eval(.iniDiag.example)
> i <- c(3,1,6); v <- c(10,15,20)
> ## (logical,value) which both are recycled:
> L <- c(TRUE, rep(FALSE,8)) ; z <- c(50,99)
>
> ## vector subassignment, both with integer & logical
> ## these now work correctly {though not very efficiently; hence warnings}
> m[i] <- v # the role model: only first column is affected
> M[i] <- v; assert.EQ.mat(M,m) # dgC
replCmat[x,i,j,..,val] : nargs()=3; missing (i,j) = (0,1)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> D[i] <- v; assert.EQ.mat(D,m) # ddi -> dtC (new! 2019-07; was dgT)
replCmat[x,i,j,..,val] : nargs()=3; missing (i,j) = (0,1)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> s[i] <- v; assert.EQ.mat(s,m) # dtT -> dgT
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class dtTMatrix to dgTMatrix
> S[i] <- v; assert.EQ.mat(S,m); S # dtC -> dtT -> dgT -> dgC
replCmat[x,i,j,..,val] : nargs()=3; missing (i,j) = (0,1)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class dtTMatrix to dgTMatrix
6 x 6 sparse Matrix of class "dgCMatrix"
[1,] 15 . . . . .
[2,] . 1 . . . .
[3,] 10 . 1 . . .
[4,] . . . 1 . .
[5,] . . . . 1 .
[6,] 20 . . . . 1
> m.L <- asLogical(m) ; assertWarning(
+ C[i] <- v, verbose=TRUE) # warning: C is nMatrix, v not T/F
replCmat[x,i,j,..,val] : nargs()=3; missing (i,j) = (0,1)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class ntTMatrix to ngTMatrix
Asserted warning: x[.] <- val: x is "ngTMatrix", val not in {TRUE, FALSE} is coerced.
> assert.EQ.mat(C,m.L); validObject(C); assertWarning(
[1] TRUE
+ N[i] <- v, verbose=TRUE)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class ntTMatrix to ngTMatrix
Asserted warning: x[.] <- val: x is "ngTMatrix", val not in {TRUE, FALSE} is coerced.
> assert.EQ.mat(N,m.L); validObject(N)
[1] TRUE
> stopifnot(identical(D, as(as(s, "triangularMatrix"), "CsparseMatrix")))
> ## logical *vector* indexing
> eval(.iniDiag.example)
> m[L] <- z; m.L <- asLogical(m)
> M[L] <- z; assert.EQ.mat(M,m)
replCmat[x,i,j,..,val] : nargs()=3; missing (i,j) = (0,1)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> D[L] <- z; assert.EQ.mat(D,m)
replCmat[x,i,j,..,val] : nargs()=3; missing (i,j) = (0,1)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> s[L] <- z; assert.EQ.mat(s,m)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class dtTMatrix to dgTMatrix
> S[L] <- z; assert.EQ.mat(S,m) ; S ; assertWarning(
replCmat[x,i,j,..,val] : nargs()=3; missing (i,j) = (0,1)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class dtTMatrix to dgTMatrix
6 x 6 sparse Matrix of class "dgCMatrix"
[1,] 50 . . 50 . .
[2,] . 1 . . . .
[3,] . . 1 . . .
[4,] . 99 . 1 99 .
[5,] . . . . 1 .
[6,] . . . . . 1
+ C[L] <- z, verbose=TRUE); assert.EQ.mat(C,m.L) ; assertWarning(
replCmat[x,i,j,..,val] : nargs()=3; missing (i,j) = (0,1)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class ntTMatrix to ngTMatrix
Asserted warning: x[.] <- val: x is "ngTMatrix", val not in {TRUE, FALSE} is coerced.
+ N[L] <- z, verbose=TRUE); assert.EQ.mat(N,m.L)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class ntTMatrix to ngTMatrix
Asserted warning: x[.] <- val: x is "ngTMatrix", val not in {TRUE, FALSE} is coerced.
>
>
> ## indexing [i] vs [i,] --- now ok
> eval(.iniDiag.example)
> stopifnot(identical5(m[i], M[i], D[i], s[i], S[i]), identical3(as.logical(m[i]), C[i], N[i]),
+ identical5(m[L], M[L], D[L], s[L], S[L]), identical3(as.logical(m[L]), C[L], N[L]))
> ## bordercase ' drop = .' *vector* indexing {failed till 2009-04-..)
> stopifnot(identical5(m[i,drop=FALSE], M[i,drop=FALSE], D[i,drop=FALSE],
+ s[i,drop=FALSE], S[i,drop=FALSE]),
+ identical3(as.logical(m[i,drop=FALSE]),
+ C[i,drop=FALSE], N[i,drop=FALSE]))
> stopifnot(identical5(m[L,drop=FALSE], M[L,drop=FALSE], D[L,drop=FALSE],
+ s[L,drop=FALSE], S[L,drop=FALSE]),
+ identical3(as.logical(m[L,drop=FALSE]),
+ C[L,drop=FALSE], N[L,drop=FALSE]))
> ## using L for row-indexing should give an error
> assertError(m[L,]); assertError(m[L,, drop=FALSE])
> ## these did not signal an error, upto (including) 0.999375-30:
> assertError(s[L,]); assertError(s[L,, drop=FALSE])
> assertError(S[L,]); assertError(S[L,, drop=FALSE])
> assertError(N[L,]); assertError(N[L,, drop=FALSE])
>
> ## row indexing:
> assert.EQ.mat(D[i,], m[i,])
> assert.EQ.mat(M[i,], m[i,])
> assert.EQ.mat(s[i,], m[i,])
> assert.EQ.mat(S[i,], m[i,])
> assert.EQ.mat(C[i,], asLogical(m[i,]))
> assert.EQ.mat(N[i,], asLogical(m[i,]))
> ## column indexing:
> assert.EQ.mat(D[,i], m[,i])
> assert.EQ.mat(M[,i], m[,i])
> assert.EQ.mat(s[,i], m[,i])
> assert.EQ.mat(S[,i], m[,i])
> assert.EQ.mat(C[,i], asLogical(m[,i]))
> assert.EQ.mat(N[,i], asLogical(m[,i]))
>
>
> ### --- negative indices ----------
>
> ## 1) negative *vector* indexing
> eval(.iniDiag.example)
> i <- -(2:30)
> stopifnot(identical5(m[i], M[i], D[i], s[i], S[i]),
+ identical3(as.logical(m[i]), C[i], N[i]))
> ## negative vector subassignment :
> v <- seq_along(m[i])
> m[i] <- v; m.L <- asLogical(m)
> M[i] <- v; assert.EQ.mat(M,m) # dge
replCmat[x,i,j,..,val] : nargs()=3; missing (i,j) = (0,1)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> D[i] <- v; assert.EQ.mat(D,m) # ddi -> dtT -> dgT
replCmat[x,i,j,..,val] : nargs()=3; missing (i,j) = (0,1)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> s[i] <- v; assert.EQ.mat(s,m) # dtT -> dgT
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class dtTMatrix to dgTMatrix
> S[i] <- v; assert.EQ.mat(S,m); S ; assertWarning( # dtC -> dtT -> dgT -> dgC
replCmat[x,i,j,..,val] : nargs()=3; missing (i,j) = (0,1)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class dtTMatrix to dgTMatrix
6 x 6 sparse Matrix of class "dgCMatrix"
[1,] 1 . . . . 2
[2,] . 1 . . . 3
[3,] . . 1 . . 4
[4,] . . . 1 . 5
[5,] . . . . 1 6
[6,] . . . . . 7
+ N[i] <- v, verbose=TRUE)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class ntTMatrix to ngTMatrix
Asserted warning: x[.] <- val: x is "ngTMatrix", val not in {TRUE, FALSE} is coerced.
> assert.EQ.mat(N,m.L); N ; assertWarning(
6 x 6 sparse Matrix of class "ngTMatrix"
[1,] | . . . . |
[2,] . | . . . |
[3,] . . | . . |
[4,] . . . | . |
[5,] . . . . | |
[6,] . . . . . |
+ C[i] <- v, verbose=TRUE)
replCmat[x,i,j,..,val] : nargs()=3; missing (i,j) = (0,1)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class ntTMatrix to ngTMatrix
Asserted warning: x[.] <- val: x is "ngTMatrix", val not in {TRUE, FALSE} is coerced.
> assert.EQ.mat(C,m.L); C #
6 x 6 sparse Matrix of class "ngCMatrix"
[1,] | . . . . |
[2,] . | . . . |
[3,] . . | . . |
[4,] . . . | . |
[5,] . . . . | |
[6,] . . . . . |
>
> options(warn = 2) #----------------------# NO WARNINGS from here -----------------
> ## =====================
>
> ## 2) negative [i,j] indices
> mc <- mC[1:5, 1:7]
> mt <- mT[1:5, 1:7]
> ## sub matrix
> assert.EQ.mat(mC[1:2, 0:3], mm[1:2, 0:3]) # test 0-index
> stopifnot(identical(mc[-(3:5), 0:2], mC[1:2, 0:2]),
+ identical(mt[-(3:5), 0:2], mT[1:2, 0:2]),
+ identical(mC[2:3, 4], mm[2:3, 4]))
> assert.EQ.mat(mC[1:2,], mm[1:2,])
> ## sub vector
> stopifnot(identical4(mc[-(1:4), ], mC[5, 1:7],
+ mt[-(1:4), ], mT[5, 1:7]))
> stopifnot(identical4(mc[-(1:4), -(2:4)], mC[5, c(1,5:7)],
+ mt[-(1:4), -(2:4)], mT[5, c(1,5:7)]))
>
> ## mixing of negative and positive must give error
> assertError(mT[-1:1,])
> showProc.time()
Time (user system elapsed): 0.039 0.001 0.041
>
> ## Sub *Assignment* ---- now works (partially):
> mt0 <- mt
> nt <- as(mt, "nMatrix")
> mt[1, 4] <- -99
.. replTmat(x,i,j,v): nargs()= 4; cl.(x)=dgTMatrix; len.(value)=1;
> mt[2:3, 1:6] <- 0
.. replTmat(x,i,j,v): nargs()= 4; cl.(x)=dgTMatrix; len.(value)=1;
> mt
5 x 7 sparse Matrix of class "dgTMatrix"
c1 c2 c3 c4 c5 c6 c7
r1 . . . -99 . . 241
r2 . . . . . . .
r3 . . . . . . 243
r4 . . . . . . .
r5 . 45 . . . . .
> m2 <- mt+mt
> m2[1,4] <- -200
.. replTmat(x,i,j,v): nargs()= 4; cl.(x)=dgTMatrix; len.(value)=1;
> m2[c(1,3), c(5:6,2)] <- 1:6
.. replTmat(x,i,j,v): nargs()= 4; cl.(x)=dgTMatrix; len.(value)=6;
> stopifnot(m2[1,4] == -200,
+ as.vector(m2[c(1,3), c(5:6,2)]) == 1:6)
> mt[,3] <- 30
.. replTmat(x,i,j,v): nargs()= 4; cl.(x)=dgTMatrix; len.(value)=1; missing (i,j) = (1,0)
> mt[2:3,] <- 250
.. replTmat(x,i,j,v): nargs()= 4; cl.(x)=dgTMatrix; len.(value)=1; missing (i,j) = (0,1)
> mt[1:5 %% 2 == 1, 3] <- 0
.. replTmat(x,i,j,v): nargs()= 4; cl.(x)=dgTMatrix; len.(value)=1;
> mt[3:1, 1:7 > 5] <- 0
.. replTmat(x,i,j,v): nargs()= 4; cl.(x)=dgTMatrix; len.(value)=1;
> mt
5 x 7 sparse Matrix of class "dgTMatrix"
c1 c2 c3 c4 c5 c6 c7
r1 . . . -99 . . .
r2 250 250 250 250 250 . .
r3 250 250 . 250 250 . .
r4 . . 30 . . . .
r5 . 45 . . . . .
>
> tt <- as(mt,"matrix")
> ii <- c(0,2,5)
> jj <- c(2:3,5)
> tt[ii, jj] <- 1:6 # 0 is just "dropped"
> mt[ii, jj] <- 1:6
.. replTmat(x,i,j,v): nargs()= 4; cl.(x)=dgTMatrix; len.(value)=6;
> assert.EQ.mat(mt, tt)
>
> mt[1:5, 2:6]
5 x 5 sparse Matrix of class "dgTMatrix"
c2 c3 c4 c5 c6
r1 . . -99 . .
r2 1 3 250 5 .
r3 250 . 250 250 .
r4 . 30 . . .
r5 2 4 . 6 .
> as((mt0 - mt)[1:5,], "dsparseMatrix")# [1,5] and lines 2:3
5 x 7 sparse Matrix of class "dgCMatrix"
c1 c2 c3 c4 c5 c6 c7
r1 . . . 220 . . 241
r2 -250 41 -3 -250 -5 202 .
r3 -247 -250 . -250 -250 . 243
r4 . . -30 . . . .
r5 . 43 -4 . -6 . .
>
> mt[c(2,4), ] <- 0; stopifnot(as(mt[c(2,4), ],"matrix") == 0)
.. replTmat(x,i,j,v): nargs()= 4; cl.(x)=dgTMatrix; len.(value)=1; missing (i,j) = (0,1)
> mt[2:3, 4:7] <- 33
.. replTmat(x,i,j,v): nargs()= 4; cl.(x)=dgTMatrix; len.(value)=1;
> checkMatrix(mt)
Compare -- "dgCMatrix" != "dgCMatrix" :
norm(m [5 x 7]) : 1 I F M ok
Summary: ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: ok
m >= m for all: ok
m < m for none: Compare -- "dgCMatrix" < "dgCMatrix" :
ok
> mt
5 x 7 sparse Matrix of class "dgTMatrix"
c1 c2 c3 c4 c5 c6 c7
r1 . . . -99 . . .
r2 . . . 33 33 33 33
r3 250 250 . 33 33 33 33
r4 . . . . . . .
r5 . 2 4 . 6 . .
>
> mc[1,4] <- -99 ; stopifnot(mc[1,4] == -99)
replCmat[x,i,j,..,val] : nargs()=4;
> mc[1,4] <- 00 ; stopifnot(mc[1,4] == 00)
replCmat[x,i,j,..,val] : nargs()=4;
> mc[1,4] <- -99 ; stopifnot(mc[1,4] == -99)
replCmat[x,i,j,..,val] : nargs()=4;
> mc[1:2,4:3] <- 4:1; stopifnot(as(mc[1:2,4:3], "matrix") == 4:1)
replCmat[x,i,j,..,val] : nargs()=4;
>
> mc[-1, 3] <- -2:1 # 0 should not be entered; 'value' recycled
replCmat[x,i,j,..,val] : nargs()=4;
> mt[-1, 3] <- -2:1
.. replTmat(x,i,j,v): nargs()= 4; cl.(x)=dgTMatrix; len.(value)=4;
> stopifnot(mc@x != 0, mt@x != 0,
+ mc[-1,3] == -2:1, mt[-1,3] == -2:1) ## failed earlier
>
> mc0 <- mc
> mt0 <- as(mc0, "TsparseMatrix")
> m0 <- as(mc0, "matrix")
> set.seed(1); options(Matrix.verbose = FALSE)
> for(i in 1:(if(doExtras) 50 else 4)) {
+ mc <- mc0; mt <- mt0 ; m <- m0
+ ev <- 1:5 %% 2 == round(runif(1))# 0 or 1
+ j <- sample(ncol(mc), 1 + round(runif(1)))
+ nv <- rpois(sum(ev) * length(j), lambda = 1)
+ mc[ev, j] <- nv
+ m[ev, j] <- nv
+ mt[ev, j] <- nv
+ if(i %% 10 == 1) print(mc[ev,j, drop = FALSE])
+ stopifnot(as.vector(mc[ev, j]) == nv, ## failed earlier...
+ as.vector(mt[ev, j]) == nv)
+ validObject(mc) ; assert.EQ.mat(mc, m)
+ validObject(mt) ; assert.EQ.mat(mt, m)
+ }
2 x 1 sparse Matrix of class "dgCMatrix"
c5
r2 2
r4 .
> showProc.time()
Time (user system elapsed): 0.07 0.003 0.073
> options(Matrix.verbose = TRUE)
>
> mc # no longer has non-structural zeros
5 x 7 sparse Matrix of class "dgCMatrix"
c1 c2 c3 c4 c5 c6 c7
r1 . . 2 4 . . 241
r2 . 42 . 3 . 202 .
r3 3 . -1 . . . 243
r4 . . 1 . . . .
r5 . 45 1 . . . .
> mc[ii, jj] <- 1:6
> mc[c(2,5), c(3,5)] <- 3.2
> checkMatrix(mc)
norm(m [5 x 7]) : 1 I F M ok
Summary: ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: identical
m >= m for all: ok
m < m for none: ok
> m. <- mc
> mc[4,] <- 0
> mc
5 x 7 sparse Matrix of class "dgCMatrix"
c1 c2 c3 c4 c5 c6 c7
r1 . . 2.0 4 . . 241
r2 . 1 3.2 3 3.2 202 .
r3 3 . -1.0 . . . 243
r4 . . . . . . .
r5 . 2 3.2 . 3.2 . .
>
> S <- as(Diagonal(5),"TsparseMatrix")
> H <- Hilbert(9)
> Hc <- as(round(H, 3), "CsparseMatrix")# a sparse matrix with no 0 ...
> (trH <- tril(Hc[1:5, 1:5]))
5 x 5 sparse Matrix of class "dtCMatrix"
[1,] 1.000 . . . .
[2,] 0.500 0.333 . . .
[3,] 0.333 0.250 0.200 . .
[4,] 0.250 0.200 0.167 0.143 .
[5,] 0.200 0.167 0.143 0.125 0.111
> stopifnot(is(trH, "triangularMatrix"), trH@uplo == "L",
+ is(S, "triangularMatrix"))
>
> ## triangular assignment
> ## the slick (but inefficient in case of sparse!) way to assign sub-diagonals:
> ## equivalent to tmp <- `diag<-`(S[,-1], -2:1); S[,-1] <- tmp
> ## which dispatches to (x="TsparseMatrix", i="missing",j="index", value="replValue")
> diag(S[,-1]) <- -2:1 # used to give a wrong warning
M[i,j] <- v : coercing symmetric M[] into non-symmetric
> S <- as(S,"triangularMatrix")
> assert.EQ.mat(S, local({s <- diag(5); diag(s[,-1]) <- -2:1; s}))
>
> trH[c(1:2,4), c(2:3,5)] <- 0 # gave an *error* upto Jan.2008
> trH[ lower.tri(trH) ] <- 0 # ditto, because of callNextMethod()
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class dtTMatrix to dgTMatrix
>
> m <- Matrix(0+1:28, nrow = 4)
> m[-3,c(2,4:5,7)] <- m[ 3, 1:4] <- m[1:3, 6] <- 0
> mT <- as(m, "TsparseMatrix")
> stopifnot(identical(mT[lower.tri(mT)],
+ m [lower.tri(m) ]))
> lM <- upper.tri(mT, diag=TRUE)
> mT[lM] <- 0
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> m[lM] <- 0
> assert.EQ.mat(mT, as(m,"matrix"))
> mT[lM] <- -1:0
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> m[lM] <- -1:0
> assert.EQ.mat(mT, as(m,"matrix"))
> (mT <- drop0(mT))
4 x 7 sparse Matrix of class "dgCMatrix"
[1,] -1 . . -1 -1 -1 -1
[2,] 2 -1 -1 . . . .
[3,] . . . -1 -1 -1 -1
[4,] 4 . 12 . . . .
>
> i <- c(1:2, 4, 6:7); j <- c(2:4,6)
> H[i,j] <- 0
> (H. <- round(as(H, "sparseMatrix"), 3)[ , 2:7])
9 x 6 sparse Matrix of class "dgCMatrix"
[1,] . . . 0.200 . 0.143
[2,] . . . 0.167 . 0.125
[3,] 0.250 0.200 0.167 0.143 0.125 0.111
[4,] . . . 0.125 . 0.100
[5,] 0.167 0.143 0.125 0.111 0.100 0.091
[6,] . . . 0.100 . 0.083
[7,] . . . 0.091 . 0.077
[8,] 0.111 0.100 0.091 0.083 0.077 0.071
[9,] 0.100 0.091 0.083 0.077 0.071 0.067
> Hc. <- Hc
> Hc.[i,j] <- 0 ## now "works", but setting "non-structural" 0s
> stopifnot(as(Hc.[i,j], "matrix") == 0)
> Hc.[, 1:6]
9 x 6 sparse Matrix of class "dgCMatrix"
[1,] 1.000 . . . 0.200 .
[2,] 0.500 . . . 0.167 .
[3,] 0.333 0.250 0.200 0.167 0.143 0.125
[4,] 0.250 . . . 0.125 .
[5,] 0.200 0.167 0.143 0.125 0.111 0.100
[6,] 0.167 . . . 0.100 .
[7,] 0.143 . . . 0.091 .
[8,] 0.125 0.111 0.100 0.091 0.083 0.077
[9,] 0.111 0.100 0.091 0.083 0.077 0.071
>
> ## an example that failed for a long time
> sy3 <- new("dsyMatrix", Dim = as.integer(c(2, 2)), x = c(14, -1, 2, -7))
> checkMatrix(dm <- kronecker(Diagonal(2), sy3))# now sparse with new kronecker
norm(m [4 x 4]) : 1 I F suboptimal 'Arith' implementation of 'dsC* o dsC*'
M ok
Summary: ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: suboptimal 'Arith' implementation of 'dsC* o dsC*'
identical
m >= m for all: ok
m < m for none: ok
symmpart(m) + skewpart(m) == m: suboptimal 'Arith' implementation of 'dsC* o dsC*'
ok; determinant(): ok
> dm <- Matrix(as(dm, "matrix"))# -> "dsyMatrix"
> (s2 <- as(dm, "sparseMatrix"))
4 x 4 sparse Matrix of class "dsCMatrix"
[1,] 14 2 . .
[2,] 2 -7 . .
[3,] . . 14 2
[4,] . . 2 -7
> checkMatrix(st <- as(s2, "TsparseMatrix"))
norm(m [4 x 4]) : 1 I F suboptimal 'Arith' implementation of 'dsC* o dsC*'
M ok
Summary: ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: suboptimal 'Arith' implementation of 'dsC* o dsC*'
identical
m >= m for all: ok
m < m for none: ok
symmpart(m) + skewpart(m) == m: suboptimal 'Arith' implementation of 'dsC* o dsC*'
ok; determinant(): ok
> stopifnot(is(s2, "symmetricMatrix"),
+ is(st, "symmetricMatrix"))
> checkMatrix(s.32 <- st[1:3,1:2]) ## 3 x 2 - and *not* dsTMatrix
norm(m [3 x 2]) : 1 I F M ok
Summary: ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: ok
m >= m for all: ok
m < m for none: ok
> checkMatrix(s2.32 <- s2[1:3,1:2])
norm(m [3 x 2]) : 1 I F M ok
Summary: ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: identical
m >= m for all: ok
m < m for none: ok
> I <- c(1,4:3)
> stopifnot(is(s2.32, "generalMatrix"),
+ is(s.32, "generalMatrix"),
+ identical(as.mat(s.32), as.mat(s2.32)),
+ identical3(dm[1:3,-1], asD(s2[1:3,-1]), asD(st[1:3,-1])),
+ identical4(2, dm[4,3], s2[4,3], st[4,3]),
+ identical3(diag(dm), diag(s2), diag(st)),
+ is((cI <- s2[I,I]), "dsCMatrix"),
+ is((tI <- st[I,I]), "dsTMatrix"),
+ identical4(as.mat(dm)[I,I], as.mat(dm[I,I]), as.mat(tI), as.mat(cI))
+ )
>
> ## now sub-assign and check for consistency
> ## symmetric subassign should keep symmetry
> st[I,I] <- 0; checkMatrix(st); stopifnot(is(st,"symmetricMatrix"))
norm(m [4 x 4]) : 1 I F suboptimal 'Arith' implementation of 'dsC* o dsC*'
M ok
Summary: ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: suboptimal 'Arith' implementation of 'dsC* o dsC*'
identical
m >= m for all: ok
m < m for none: ok
symmpart(m) + skewpart(m) == m: suboptimal 'Arith' implementation of 'dsC* o dsC*'
ok; determinant(): ok
> s2[I,I] <- 0; checkMatrix(s2); stopifnot(is(s2,"symmetricMatrix"))
norm(m [4 x 4]) : 1 I F suboptimal 'Arith' implementation of 'dsC* o dsC*'
M ok
Summary: ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: suboptimal 'Arith' implementation of 'dsC* o dsC*'
identical
m >= m for all: ok
m < m for none: ok
symmpart(m) + skewpart(m) == m: suboptimal 'Arith' implementation of 'dsC* o dsC*'
ok; determinant(): ok
> ##
> m <- as.mat(st)
> m[2:1,2:1] <- 4:1
> st[2:1,2:1] <- 4:1
M[i,j] <- v : coercing symmetric M[] into non-symmetric
> s2[2:1,2:1] <- 4:1
> stopifnot(identical(m, as.mat(st)),
+ 1:4 == as.vector(s2[1:2,1:2]),
+ identical(m, as.mat(s2)))
>
> ## now a slightly different situation for 's2' (had bug)
> s2 <- as(dm, "sparseMatrix")
> s2[I,I] <- 0; diag(s2)[2:3] <- -(1:2)
> stopifnot(is(s2,"symmetricMatrix"), diag(s2) == c(0:-2,0))
> t2 <- as(s2, "TsparseMatrix")
> m <- as.mat(s2)
> s2[2:1,2:1] <- 4:1
> t2[2:1,2:1] <- 4:1
M[i,j] <- v : coercing symmetric M[] into non-symmetric
> m[2:1,2:1] <- 4:1
> assert.EQ.mat(t2, m)
> assert.EQ.mat(s2, m)
> ## and the same (for a different s2 !)
> s2[2:1,2:1] <- 4:1
> t2[2:1,2:1] <- 4:1
> assert.EQ.mat(t2, m)# ok
> assert.EQ.mat(s2, m)# failed in 0.9975-8
> showProc.time()
Time (user system elapsed): 0.161 0.003 0.163
>
> ## sub-assign RsparseMatrix -- Matrix bug [#6709] by David Cortes
> ## https://r-forge.r-project.org/tracker/?func=detail&atid=294&aid=6709&group_id=61
> ## simplified by MM
> X <- new("dgCMatrix", i = c(0L,3L), p = c(0L,2L,2L,2L), x = c(100, -20), Dim = c(12L,3L))
> R <- as(X, "RsparseMatrix")
> T <- as(R, "TsparseMatrix")
> T[, 2] <- 22 # works fine
> R[, 2] <- 22 # failed, as it called replTmat() giving narg() == 3
> ## now R is Tsparse (as documented on ../man/RsparseMatrix-class.Rd),
> identical(R, T) ## but as this may change, rather R & T should have the same *content*
[1] TRUE
> assert.EQ.Mat(R, T)
>
>
> ## m[cbind(i,j)] <- value: (2-column matrix subassignment): -------------------------
> m.[ cbind(3:5, 1:3) ] <- 1:3
> stopifnot(m.[3,1] == 1, m.[4,2] == 2)
> nt. <- nt ; nt[rbind(2:3, 3:4, c(3,3))] <- FALSE
> s. <- m. ; m.[cbind(3,4:6)] <- 0 ## assigning 0 where there *is* 0 ..
> stopifnot(identical(nt.,nt), ## should not have changed
+ identical(s., m.))
> x.x[ cbind(2:6, 2:6)] <- 12:16
> stopifnot(isValid(x.x, "dsCMatrix"),
+ 12:16 == as.mat(x.x)[cbind(2:6, 2:6)])
> (ne1 <- (mc - m.) != 0)
5 x 7 sparse Matrix of class "lgCMatrix"
c1 c2 c3 c4 c5 c6 c7
r1 . . : : . . :
r2 . : : : : : .
r3 | . : . . . :
r4 . | | . . . .
r5 . : | . : . .
> stopifnot(identical(ne1, 0 != abs(mc - m.)))
> (ge <- m. >= mc) # contains "=" -> result is dense
5 x 7 Matrix of class "lgeMatrix"
c1 c2 c3 c4 c5 c6 c7
r1 TRUE TRUE TRUE TRUE TRUE TRUE TRUE
r2 TRUE TRUE TRUE TRUE TRUE TRUE TRUE
r3 FALSE TRUE TRUE TRUE TRUE TRUE TRUE
r4 TRUE TRUE TRUE TRUE TRUE TRUE TRUE
r5 TRUE TRUE FALSE TRUE TRUE TRUE TRUE
> ne. <- mc != m. # was wrong (+ warning)
> stopifnot(identical(!(m. < mc), m. >= mc),
+ identical(m. < mc, as(!ge, "sparseMatrix")),
+ identical(ne., drop0(ne1)))
>
> d6 <- Diagonal(6)
> ii <- c(1:2, 4:5)
> d6[cbind(ii,ii)] <- 7*ii
> stopifnot(is(d6, "ddiMatrix"), identical(d6, Diagonal(x=c(7*1:2,1,7*4:5,1))))
>
> sclass <- function(obj) as.vector(class(obj)) # as.v*(): drop attr(*,"package")
> show2cls <- function(C,D, chr = "")
+ cat(sprintf("%s & %s%s: %s %s\n",
+ deparse(substitute(C)), deparse(substitute(D)), chr,
+ sclass(C), sclass(D)))
> for(j in 2:6) { ## even and odd j used to behave differently
+ cat("j = ", j, ":\n-------\n")
+ M <- Matrix(0, j,j); m <- matrix(0, j,j)
+ T <- as(M, "TsparseMatrix")
+ TG <- as(T, "generalMatrix")
+ G <- as(M, "generalMatrix"); show2cls(TG, G)
+ stopifnot(is(TG, "TsparseMatrix"),
+ is(G, "CsparseMatrix"))
+ id <- cbind(1:j,1:j)
+ i2 <- cbind(1:j,j:1)
+ m[id] <- 1:j
+ M[id] <- 1:j
+ T[id] <- 1:j ; show2cls(M, T,' ("diag")')
+ stopifnot(is(M, "diagonalMatrix"), # since 2019-07 // FIXME (?!) for j=1
+ is(T,"triangularMatrix"), isDiagonal(T)) # was "symmetricMatrix"
+ G[id] <- 1:j
+ TG[id]<- 1:j
+ m[i2] <- 10
+ M[i2] <- 10
+ T[i2] <- 10 ; show2cls(M, T,' ("symm")')
+ G[i2] <- 10
+ TG[i2]<- 10
+ ##
+ assert.EQ.mat(M, m)
+ assert.EQ.mat(T, m)
+ assert.EQ.mat(G, m)
+ assert.EQ.mat(TG,m)
+ }
j = 2 :
-------
TG & G: dgTMatrix dgCMatrix
M & T ("diag"): ddiMatrix dtTMatrix
M[ij] <- v : coercing symmetric M[] into non-symmetric
M[ij] <- v : coercing symmetric M[] into non-symmetric
M & T ("symm"): dgCMatrix dgTMatrix
j = 3 :
-------
TG & G: dgTMatrix dgCMatrix
M & T ("diag"): ddiMatrix dtTMatrix
M[ij] <- v : coercing symmetric M[] into non-symmetric
M[ij] <- v : coercing symmetric M[] into non-symmetric
M & T ("symm"): dgCMatrix dgTMatrix
j = 4 :
-------
TG & G: dgTMatrix dgCMatrix
M & T ("diag"): ddiMatrix dtTMatrix
M[ij] <- v : coercing symmetric M[] into non-symmetric
M[ij] <- v : coercing symmetric M[] into non-symmetric
M & T ("symm"): dgCMatrix dgTMatrix
j = 5 :
-------
TG & G: dgTMatrix dgCMatrix
M & T ("diag"): ddiMatrix dtTMatrix
M[ij] <- v : coercing symmetric M[] into non-symmetric
M[ij] <- v : coercing symmetric M[] into non-symmetric
M & T ("symm"): dgCMatrix dgTMatrix
j = 6 :
-------
TG & G: dgTMatrix dgCMatrix
M & T ("diag"): ddiMatrix dtTMatrix
M[ij] <- v : coercing symmetric M[] into non-symmetric
M[ij] <- v : coercing symmetric M[] into non-symmetric
M & T ("symm"): dgCMatrix dgTMatrix
>
>
> ## drop, triangular, ...
> (M3 <- Matrix(upper.tri(matrix(, 3, 3)))) # ltC; indexing used to fail
3 x 3 sparse Matrix of class "ltCMatrix"
[1,] . | |
[2,] . . |
[3,] . . .
> T3 <- as(M3, "TsparseMatrix")
> stopifnot(identical(drop(M3), M3),
+ identical4(drop(M3[,2, drop = FALSE]), M3[,2, drop = TRUE],
+ drop(T3[,2, drop = FALSE]), T3[,2, drop = TRUE]),
+ is(T3, "triangularMatrix"),
+ !is(T3[,2, drop=FALSE], "triangularMatrix")
+ )
>
> (T6 <- as(as(as(kronecker(Matrix(c(0,0,1,0),2,2), t(T3)),
+ "lMatrix"), "triangularMatrix"), "TsparseMatrix"))
6 x 6 sparse Matrix of class "ltTMatrix"
[1,] . . . . . .
[2,] . . . | . .
[3,] . . . | | .
[4,] . . . . . .
[5,] . . . . . .
[6,] . . . . . .
> T6[1:4, -(1:3)] # failed (trying to coerce back to ltTMatrix)
4 x 3 sparse Matrix of class "lgTMatrix"
[1,] . . .
[2,] | . .
[3,] | | .
[4,] . . .
> stopifnot(identical(T6[1:4, -(1:3)][2:3, -3],
+ spMatrix(2,2, i=c(1,2,2), j=c(1,1,2), x=rep(TRUE,3))))
>
> M <- Diagonal(4); M[1,2] <- 2
> M. <- as(M, "CsparseMatrix")
> (R <- as(M., "RsparseMatrix"))
4 x 4 sparse Matrix of class "dtRMatrix"
[1,] 1 2 . .
[2,] . 1 . .
[3,] . . 1 .
[4,] . . . 1
> (Ms <- symmpart(M.))
4 x 4 sparse Matrix of class "dsCMatrix"
[1,] 1 1 . .
[2,] 1 1 . .
[3,] . . 1 .
[4,] . . . 1
> Rs <- as(Ms, "RsparseMatrix")
> stopifnot(isValid(M, "triangularMatrix"),
+ isValid(M.,"triangularMatrix"),
+ isValid(Ms, "dsCMatrix"),
+ isValid(R, "dtRMatrix"),
+ isValid(Rs, "dsRMatrix") )
> stopifnot(dim(M[2:3, FALSE]) == c(2,0),
+ dim(R[2:3, FALSE]) == c(2,0),
+ identical(M [2:3,TRUE], M [2:3,]),
+ identical(M.[2:3,TRUE], M.[2:3,]),
+ identical(R [2:3,TRUE], R [2:3,]),
+ dim(R[FALSE, FALSE]) == c(0,0))
>
> n <- 50000L
> Lrg <- new("dgTMatrix", Dim = c(n,n))
> diag(Lrg) <- 1:n
> dLrg <- as(Lrg, "diagonalMatrix")
> stopifnot(identical(Diagonal(x = 1:n), dLrg))
> diag(dLrg) <- 1 + diag(dLrg)
> Clrg <- as(Lrg,"CsparseMatrix")
> Ctrg <- as(Clrg, "triangularMatrix")
> diag(Ctrg) <- 1 + diag(Ctrg)
> stopifnot(identical(Diagonal(x = 1+ 1:n), dLrg),
+ identical(Ctrg, as(dLrg,"CsparseMatrix")))
>
> cc <- capture.output(show(dLrg))# show() used to error for large n
> showProc.time()
Time (user system elapsed): 0.125 0.007 0.133
>
> ## FIXME: "dspMatrix" (symmetric *packed*) not going via "matrix"
>
>
> ## Large Matrix indexing / subassignment
> ## ------------------------------------- (from ex. by Imran Rashid)
> n <- 7000000
> m <- 100000
> nnz <- 20000
> op <- options(Matrix.verbose = 2, warn = 1)
>
> set.seed(12)
> f <- sparseMatrix(i = sample(n, size=nnz, replace=TRUE),
+ j = sample(m, size=nnz, replace=TRUE))
> str(f)
Formal class 'ngCMatrix' [package "Matrix"] with 5 slots
..@ i : int [1:20000] 6692226 4657233 4490801 3688935 344371 6380246 2797160 3584813 6553304 2327896 ...
..@ p : int [1:99993] 0 1 1 1 1 1 1 1 1 1 ...
..@ Dim : int [1:2] 6999863 99992
..@ Dimnames:List of 2
.. ..$ : NULL
.. ..$ : NULL
..@ factors : list()
> dim(f) # 6999863 x 99992
[1] 6999863 99992
> prod(dim(f)) # 699930301096 == 699'930'301'096 (~ 700'000 millions)
[1] 699930301096
> str(thisCol <- f[,5000])# logi [~ 7 mio....]
logi [1:6999863] FALSE FALSE FALSE FALSE FALSE FALSE ...
> sv <- as(thisCol, "sparseVector")
> str(sv) ## "empty" !
Formal class 'lsparseVector' [package "Matrix"] with 3 slots
..@ x : logi(0)
..@ length: int 6999863
..@ i : int(0)
> validObject(spCol <- f[,5000, drop=FALSE]) # "empty" [n x 1] ngCmatrix
[1] TRUE
> ##
> ## *not* identical(): as(spCol, "sparseVector")@length is "double"prec:
> stopifnot(all.equal(as(spCol, "sparseVector"),
+ as(sv, "nsparseVector"), tolerance=0))
> if(interactive())
+ selectMethod("[<-", c("ngCMatrix", "missing","numeric", "logical"))
> # -> replCmat() in ../R/Csparse.R
> f[,5762] <- thisCol # now "fine" and fast thanks to replCmat() --> replCmat4()
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
>
> fx <- sparseMatrix(i = sample(n, size=nnz, replace=TRUE),
+ j = sample(m, size=nnz, replace=TRUE),
+ x = round(10*rnorm(nnz)))
> class(fx)## dgCMatrix
[1] "dgCMatrix"
attr(,"package")
[1] "Matrix"
> fx[,6000] <- (tC <- rep(thisCol, length.out=nrow(fx)))# fine
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
> thCol <- fx[,2000]
> fx[,5762] <- thCol# fine
replCmat[x,i,j,..,val] : nargs()=4; missing (i,j) = (1,0)
> stopifnot(is(f, "ngCMatrix"), is(fx, "dgCMatrix"),
+ identical(thisCol, f[,5762]),# perfect
+ identical(as.logical(fx[,6000]), tC),
+ identical(thCol, fx[,5762]))
>
> showProc.time()
Time (user system elapsed): 0.416 0.05 0.465
> options(op)# revert
> ##
> if(doExtras) {#-----------------------------------------------------------------
+ cat("checkMatrix() of all: \n---------\n")
+ Sys.setlocale("LC_COLLATE", "C")# to keep ls() reproducible
+ for(nm in ls()) if(is(.m <- get(nm), "Matrix")) {
+ cat(nm, "\n")
+ checkMatrix(.m, verbose = FALSE
+ , doDet = nm != "As" ## <- "As" almost singular <=> det() "ill posed"
+ )
+ }
+ showProc.time()
+ }#--------------end if(doExtras) -----------------------------------------------
>
> ## Bugs found by Peter Ralph
> n <- 17
> x <- Matrix(0, n,n) # "ddiMatrix" now
> ## x must have at least three nonzero entries
> x[1,1] <- x[2,1:2] <- 1.; class(x) # "dtC"
[1] "dtCMatrix"
attr(,"package")
[1] "Matrix"
> x0 <- x <- as(x,"generalMatrix") # if x is dgCMatrix, no error
> ##
> z <- matrix(x) # <== not the "Matrix way": a (n, 1) matrix
> z[1] <- 0
>
> x[1:n, 1:n] <- as(z, "sparseVector")
> ## gave Error: ... invalid subscript type 'S4'
> x2 <- x
>
> dim(zC <- as(z, "CsparseMatrix"))
[1] 289 1
> x <- x0
> x[] <- zC # did fail, then gave warning.
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> x1 <- x
> ##
> x <- x0
> x[] <- as(zC, "sparseVector") # did fail, too
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> x2 <- x
> stopifnot(identical(x1,x2))
> x <- as(x0, "matrix")
> x[] <- z
> assert.EQ.mat(x1, x)
>
> i <- 4:7
> x1 <- x0; x1[cbind(i, i+10)] <- i^2
> x2 <- x0; x2[cbind(i, i+10)] <- as(i^2, "matrix")
> ## failed: nargs() = 4 ... please report
>
> class(x1) # was "dgT", now "dgC"
[1] "dgCMatrix"
attr(,"package")
[1] "Matrix"
> stopifnot(isValid(x1, class(x1)), identical(x1, x2))
> showProc.time()
Time (user system elapsed): 0.011 0 0.012
>
>
> ## check valid indexing (using *random* indices, often duplicated):
> chk_dsp_ind <- function(sv, n=512, negI = FALSE, verbose=FALSE) {
+ stopifnot(inherits(sv, "dsparseVector"), n >= 1)
+ d <- length(sv)
+ ## lambda=2 ==> aiming for short 'i' {easier to work with}
+ P <- rpois(n, lambda = if(negI) 5 else 2)
+ for(i in seq_len(n)) {
+ I <-
+ if(negI) { # negative indices: 2 are, 4 neither ... always "valid" !!
+ k <- max(4L, d - max(1L, P[i]))
+ if(verbose) cat(sprintf("size=k = %2d: ", k))
+ - sort(sample.int(d, size=k))# replace=FALSE
+ }
+ else
+ sample.int(d, size=1L+P[i], replace=TRUE)
+ ##
+ validObject(ss <- sv[I]) # Error if not true
+ }
+ invisible()
+ }
> s <- as(c(3,5,6), "sparseVector")
> set.seed(11); chk_dsp_ind(s)
> set.seed(3)
> (s2 <- as(rsparsematrix(ncol=1, nrow=37, density=1/4),"sparseVector"))
sparse vector (nnz/length = 9/37) of class "dsparseVector"
[1] . . . -2.200 . . 0.330 . -1.300 .
[11] . 0.950 . 0.140 . . 0.810 . . 0.540
[21] . . . . . . . . . 0.013
[31] . . -0.580 . . . .
> (s3 <- as(rsparsematrix(ncol=1, nrow=64, density=1/4),"sparseVector"))
sparse vector (nnz/length = 16/64) of class "dsparseVector"
[1] . . . . . . . . 1.80 . 2.50 .
[13] . . -0.76 . . . -0.58 . . . -0.80 0.84
[25] . . 1.30 . . . -0.51 . . . . -0.62
[37] . . . 0.71 . . . . . . -1.30 .
[49] -1.60 . . . . 0.10 . . -1.30 . 0.18 .
[61] . . . -1.30
> set.seed(1)
> chk_dsp_ind(s2)
> chk_dsp_ind(s3)
> ##
> set.seed(47)
> ## system.time(e.N2 <- chk_dsp_ind(s2, negI=TRUE, verbose=TRUE))
> chk_dsp_ind(s2, negI=TRUE)
> chk_dsp_ind(s3, negI=TRUE)
>
> iv <- c(rep(0,100), 3, 0,0,7,0,0,0)
> sv0 <- sv <- as(iv, "sparseVector")
> sv.0 <- sv. <- as(as.integer(iv), "sparseVector")
> stopifnot(canCoerce("integer", "sparseVector"))
> sv2 <- as(sv, "isparseVector")
> stopifnot(validObject(sv), validObject(sv2), identical(sv., sv2),
+ sv == sv.)
> n0 <- sv. != 0 # -> is "lsparseV.."
>
> sv [n0] <- sv [n0]
> sv.[n0] <- sv.[n0] # gave error
> stopifnot(identical(sv , sv0),
+ identical(sv., sv.0))
> sv [3:7] <- 0
> sv.[3:7] <- 0L
> stopifnot(identical(sv , sv0), identical(sv., sv.0))
> sv [2:4] <- 2:4
> sv.[2:4] <- 2:4
> stopifnot(which(sv != 0) == (which(sv. != 0) -> in0),
+ in0 == c(2:4, 101L, 104L))
> sv [2:6] <- 0L
> sv.[2:6] <- 0L
> stopifnot(identical(sv , sv0), identical(sv., sv.0))
>
> ## the next six *all* gave an error -- but should be no-op's:
> for(vv in list(sv, sv.0))
+ for(ind in list(0, FALSE, logical(length(vv))))
+ vv[ind] <- NA
> stopifnot(identical(sv , sv0), identical(sv., sv.0))
>
> ## [i] <- val -- failed to resort @i sometimes: (R-forge Matrix bug #6659)
> y1 <- sparseVector(1:3, 13:15, 16)
> y2 <- sparseVector(1:6, c(5, 6, 7, 9, 14, 15), 16)
> i <- 1:16*12 # 12 24 36 ... 192
> x <- sparseVector(numeric(1), 1, length=200)
> x[i] <- y1 ; validObject(x[i]) # TRUE
[1] TRUE
> N <- x[i] + y2 ; validObject( N ) # TRUE
[1] TRUE
> x[i] <- N ## <== bug was here ..
> validObject(x)
[1] TRUE
> ## gave 'Error' invalid .."dsparseVector".. 'i' must be sorted strictly increasingly
> stopifnot(all.equal(x[i] , y1+y2, tolerance=0),
+ x[i] == y1+y2)
> showProc.time()
Time (user system elapsed): 0.24 0.003 0.243
>
> if(!interactive()) warnings()
>
> ## [matrix-Bugs][#6720] Subsetting with empty indices does not drop -- 17 Apr 2021, by David Cortes
> ## https://r-forge.r-project.org/tracker/?func=detail&atid=294&aid=6720&group_id=61
>
> ## extended by MM to all versions of "empty" :
> x <- c(1,8)
> (m1 <- rbind(x))
[,1] [,2]
x 1 8
> m1[] # remains matrix
[,1] [,2]
x 1 8
> m1[,,drop=FALSE] # ditto
[,1] [,2]
x 1 8
> m1[,] # [1] 1 2 -- drops (as default drop=TRUE !)
[1] 1 8
>
> ## Sparse Matrix and actually *any* Matrix-extending class did not work
> (M1 <- as(m1, "denseMatrix")) # "dgeMatrix"
1 x 2 Matrix of class "dgeMatrix"
[,1] [,2]
x 1 8
> S1 <- as(m1, "CsparseMatrix")
> R1 <- as(m1, "RsparseMatrix")
> stopifnot(exprs = {
+ identical(M1[], M1) # remains
+ identical(S1[], S1) # remains
+ identical(R1[], R1) # remains
+ identical(M1[,,drop=FALSE], M1) # ditto
+ identical(S1[,,drop=FALSE], S1) # "
+ identical(R1[,,drop=FALSE], R1) # "
+ ## but drop=TRUE which is the *default* much be obeyed (also for *empty* (i,j):
+ identical(m1[,], x)
+ identical(M1[,], x) # should drop, but did not
+ identical(S1[,], x) # "
+ identical(R1[,], x) # "
+ identical(m1[,,drop=TRUE], x)
+ identical(M1[,,drop=TRUE], x) # should drop, but did not
+ identical(S1[,,drop=TRUE], x) # "
+ identical(R1[,,drop=TRUE], x) # "
+ })
>
>
> ## [matrix-Bugs][#6721] Assignment to 'dgRMatrix' with missing index takes only first element
> ## MM: This has been fixed already!
> X <- rbind(0, 1:3, 0, c(0,1,0))
> Rx <- as(X, "RsparseMatrix")
> Cx <- as(X, "CsparseMatrix")
> X [2,] <- 0
> Cx[2,] <- 0
> Rx[2,] <- 0
> stopifnot(all(Cx == X),
+ all(Rx == X))
>
> ## [matrix-Bugs][#6745] show()
> ## NB: is from a bug in head(*); *only* applies to *empty* sparseV: length(x@i) == 0
> op <- options(max.print=999)
> ( s0 <- sparseVector(i=integer(), length=2^33)) # show -> head() failed in Matrix <= 1.3-*
sparse vector (nnz/length = 0/8589934592) of class "nsparseVector"
[1] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[38] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[75] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[112] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[149] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[186] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[223] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[260] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[297] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[334] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[371] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[408] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[445] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[482] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[519] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[556] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[593] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[630] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[667] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[704] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[741] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[778] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[815] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[852] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[889] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[926] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[963] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
............................
........suppressing 8589933593 entries in show(); maybe adjust options(max.print=)
............................
> (xs0 <- sparseVector(i=integer(), length=2^33, x = numeric()))# ditto
sparse vector (nnz/length = 0/8589934592) of class "dsparseVector"
[1] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[38] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[75] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[112] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[149] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[186] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[223] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[260] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[297] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[334] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[371] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[408] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[445] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[482] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[519] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[556] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[593] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[630] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[667] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[704] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[741] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[778] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[815] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[852] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[889] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[926] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[963] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
............................
........suppressing 8589933593 entries in show(); maybe adjust options(max.print=)
............................
> options(op); tail(s0) ; tail(xs0) # (always worked)
sparse vector (nnz/length = 0/6) of class "nsparseVector"
[1] . . . . . .
sparse vector (nnz/length = 0/6) of class "dsparseVector"
[1] . . . . . .
> ## *related* bug in `[` --> needed to fix intIv() for such large sparseVectors
> stopifnot(exprs = {
+ identical(s0[length(s0) - 3:0], # gave Error in if (any(i < 0L)) { : missing value ....
+ new("nsparseVector", i=integer(), length=4L))
+ identical(xs0[length(s0) - 3:0], # gave Error ..
+ new("dsparseVector", i=integer(), length=4L))
+ })
>
> ## Yielded an invalid object in Matrix <= 1.4-1, instead of throwing error
> llc04 <- new("dgCMatrix", Dim = c(4L, 0L))
> c40 <- new("dgCMatrix", Dim = c(0L, 4L), p = integer(5L))
> assertError(c04[1L, ] <- 1)
> assertError(c40[, 1L] <- 1)
>
> ## Indexing with nMatrix rather than lMatrix
> set.seed(3601)
> gC <- rsparsematrix(6, 6, 0.6)
> gC@x[sample.int(length(gC@x), 6L)] <- NA
> ni <- is.na(gC)
> li <- as(ni, "lMatrix")
> stopifnot(identical(gC[ ni], gC[ li]),
+ identical(gC[!ni], gC[!li]))
>
> ## Dispatch thinko in Matrix <= 1.5-4
> R0 <- R. <-
+ new("dgRMatrix",
+ Dim = c(12L, 12L),
+ p = c(0L, 0L, 4L, 5L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 16L),
+ j = c(0L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 7L, 8L, 4L, 7L, 9L, 9L, 10L, 11L),
+ x = as.double(1:16))
> R.[1:2, ] <- R.[1:2, ] # was an error
> stopifnot(identical(R0, as(R., "RsparseMatrix")))
>
> ## Didn't drop dimensions ...
> stopifnot(identical(t(as(1:6,"CsparseMatrix"))[TRUE, ], as.double(1:6)))
>
> ## Was briefly wrong prior to Matrix 1.6-0
> set.seed(0)
> S <- new("dsyMatrix", Dim = c(4L, 4L), x = rnorm(16L))
> Sii <- S[4:1, 4:1]
> stopifnot(exprs = {
+ is(Sii, "dsyMatrix")
+ Sii@uplo == "L"
+ identical(as(Sii, "matrix"), as(S, "matrix")[4:1, 4:1])
+ })
>
> ## Bug #6839: regression in <.s[CT]Matrix>[] in Matrix 1.6-z
> x <- new("dsCMatrix", Dim = c(4L, 4L),
+ p = cumsum(0:4), i = sequence(1:4) - 1L, x = as.double(1:10))
> i <- c(TRUE, FALSE)
> xi <- as(x, "matrix")[i]
> for(cl in paste0(c("C", "R", "T"), "sparseMatrix"))
+ stopifnot(identical(as(x, cl)[i], xi))
>
> proc.time()
user system elapsed
2.300 0.127 2.425
Matrix/tests/validObj.R 0000644 0001751 0000144 00000016100 14575137654 014572 0 ustar hornik users library(Matrix)
### Do all kinds of object creation and coercion
source(system.file("test-tools.R", package = "Matrix"))
.drop.factors <- function(x, check = FALSE)
`slot<-`(x, "factors", check = check, value = list())
## the empty ones:
checkMatrix(new("dgeMatrix"))
checkMatrix(Matrix(,0,0))
## "dge"
assertError( new("dgeMatrix", Dim = c(2,2), x= 1:4) )# double 'Dim'
assertError( new("dgeMatrix", Dim = as.integer(c(2,2)), x= 1:4) )# int 'x'
assertError( new("dgeMatrix", Dim = 2:2, x=as.double(1:4)) )# length(Dim) !=2
assertError( new("dgeMatrix", Dim = as.integer(c(2,2)), x= as.double(1:5)))
checkMatrix(m1 <- Matrix(1:6, ncol=2))
checkMatrix(m2 <- Matrix(1:7 +0, ncol=3)) # a (desired) warning
c("dgeMatrix", "ddenseMatrix", "generalMatrix", "dMatrix",
"denseMatrix", "Matrix") -> m1.cl
stopifnot(!anyNA(match(m1.cl, is(m1))),
dim(t(m1)) == 2:3, identical(m1, t(t(m1))))
c.nam <- paste("C",1:2, sep='')
dimnames(m1) <- list(NULL, c.nam)
checkMatrix(m1) # failed in 0.999375-10
checkMatrix(tm1 <- t(m1))
stopifnot(colnames(m1) == c.nam,
identical(dimnames(tm1), list(c.nam, NULL)),
identical(m1, t(tm1)))
## an example of *named* dimnames
(t34N <- as(unclass(table(x = gl(3,4), y=gl(4,3))), "unpackedMatrix"))
stopifnot(identical(dimnames(t34N),
dimnames(as(t34N, "matrix"))),
identical(t34N, t(t(t34N))))
## "dpo"
checkMatrix(cm <- crossprod(m1))
checkMatrix(cp <- as(cm, "packedMatrix"))# 'dpp' + factors
checkMatrix(cs <- as(cm, "dsyMatrix"))# 'dsy' + factors
checkMatrix(dcm <- as(cm, "generalMatrix"))#'dge'
checkMatrix(mcm <- as(cm, "dMatrix")) # 'dsy' + factors -- buglet? rather == cm?
checkMatrix(mc. <- as(cm, "Matrix")) # dpo --> dsy -- (as above) FIXME? ??
stopifnot(identical(mc., mcm),
identical(.drop.factors(cm), (2*cm)/2),# remains dpo
identical(cm + cp, cp + cs),# dge
identical(mc., mcm),
all(2*cm == mcm * 2))
checkMatrix(eq <- cm == cs)
stopifnot(all(eq@x),
identical3(pack(eq), cs == cp, cm == cp),
as.logical(!(cs < cp)),
identical4(!(cs < cp), !(cp > cs), cp <= cs, cs >= cp))
## Coercion to 'dpo' should give an error if result would be invalid
M <- Matrix(diag(4) - 1)
assertError(as(M, "dpoMatrix"))
M. <- as(M, "generalMatrix")
M.[1,2] <- 10 # -> not even symmetric anymore
assertError(as(M., "dpoMatrix"))
## Cholesky
checkMatrix(ch <- chol(cm))
checkMatrix(ch2 <- chol(as(cm, "dsyMatrix")))
checkMatrix(ch3 <- chol(as(cm, "generalMatrix")))
stopifnot(is.all.equal3(as(ch, "matrix"), as(ch2, "matrix"), as(ch3, "matrix")))
### Very basic triangular matrix stuff
assertError( new("dtrMatrix", Dim = c(2,2), x= 1:4) )# double 'Dim'
assertError( new("dtrMatrix", Dim = as.integer(c(2,2)), x= 1:4) )# int 'x'
## This caused a segfault (before revision r1172 in ../src/dtrMatrix.c):
assertError( new("dtrMatrix", Dim = 2:2, x=as.double(1:4)) )# length(Dim) !=2
assertError( new("dtrMatrix", Dim = as.integer(c(2,2)), x= as.double(1:5)))
tr22 <- new("dtrMatrix", Dim = as.integer(c(2,2)), x=as.double(1:4))
tt22 <- t(tr22)
(tPt <- tr22 + tt22)
stopifnot(identical(10 * tPt, tPt * 10),
as.vector(t.22 <- (tr22 / .5)* .5) == c(1,0,3,4),
TRUE) ## not yet: class(t.22) == "dtrMatrix")
## non-square triagonal Matrices --- are forbidden ---
assertError(new("dtrMatrix", Dim = 2:3,
x=as.double(1:6), uplo="L", diag="U"))
n <- 3:3
assertError(new("dtCMatrix", Dim = c(n,n), diag = "U"))
validObject(T <- new("dtTMatrix", Dim = c(n,n), diag = "U"))
validObject(M <- new("dtCMatrix", Dim = c(n,n), diag = "U",
p = rep.int(0:0, n+1)))
stopifnot(identical(as.mat(T), diag(n)))
suppressWarnings(RNGversion("3.5.0")); set.seed(3)
(p9 <- p9. <- as(sample(9), "pMatrix"))
(np9 <- np9. <- as(p9, "TsparseMatrix"))
p9.[1,1] <- np9.[1,1] <- TRUE
stopifnot(is.logical(p9[1,]),
is(p9[2,, drop=FALSE], "indMatrix"),
is(p9[9:1,], "indMatrix"),
isTRUE(p9[-c(1:6, 8:9), 1]),
identical(t(p9), solve(p9)),
identical(p9[TRUE, ], p9),
identical(p9[, TRUE], p9),
identical(p9., np9.),
identical(as(diag(9), "pMatrix"), as(1:9, "pMatrix"))
)
assert.EQ.mat(p9[TRUE,], as.matrix(np9))
## validObject --> Cparse_validate(.)
mm <- new("dgCMatrix", Dim = c(3L, 5L),
i = c(2L, 0L, 1L, 2L, 0L, 1L),
x = c( 2, 1, 1, 2, 1, 2),
p = c(0:2, 4L, 4L, 6L))
## Previously unsorted columns were sorted - now are flagged as invalid
m. <- mm
ip <- c(1:2, 4:3, 6:5) # permute the 'i' and 'x' slot just "inside column":
m.@i <- m.i <- mm@i[ip]
m.@x <- m.x <- mm@x[ip]
stopifnot(identical(1L, grep("not increasing within columns",
validObject(m., test = TRUE))))
.validateCsparse(m., TRUE) # don't use this at home, boys!
m. # now is fixed
## Make sure that validObject() objects...
## 1) to wrong 'p'
m. <- mm; m.@p[1] <- 1L
stopifnot(identical(1L, grep("first element of 'p' slot",
validObject(m., test = TRUE))))
m.@p <- mm@p[c(1,3:2,4:6)]
stopifnot(identical(1L, grep("not nondecreasing",
validObject(m., test = TRUE))))
## 2) to non-strictly increasing i's:
m. <- mm ; ix <- c(1:3,3,5:6)
m.@i <- mm@i[ix]
m.@x <- mm@x[ix]
stopifnot(identical(1L, grep("not increasing within columns",
validObject(m., test = TRUE))))
## ix <- c(1:3, 3:6) # now the the (i,x) slots are too large (and decreasing at end)
## m.@i <- mm@i[ix]
## m.@x <- mm@x[ix]
## stopifnot(identical(grep("^slot i is not.* increasing .*sort",
## (msg <- validObject(m., test=TRUE))),# seg.fault in the past
## 1L))
## over-allocation of the i- and x- slot should be allowed:
## (though it does not really help in M[.,.] <- * yet)
m. <- mm
m.@i <- c(mm@i, NA, NA, NA)
m.@x <- c(mm@x, 10:12)
validObject(m.)
m. # show() now works
stopifnot(all(m. == mm), # in spite of
length(m.@i) > length(mm@i),
identical(t(t(m.)), mm),
identical3(m. * m., m. * mm, mm * mm))
m.[1,4] <- 99 ## FIXME: warning and cuts (!) the over-allocated slots
## Low-level construction of invalid object:
## Ensure that it does *NOT* segfault
foo <- new("ngCMatrix",
i = as.integer(c(12204, 16799, 16799, 33517, 1128, 11930, 1128, 11930, 32183)),
p = rep(0:9, c(2,4,1,11,10,0,1,0,9,12)),
Dim = c(36952L, 49L))
validObject(foo)# TRUE
foo@i[5] <- foo@i[5] + 50000L
msg <- validObject(foo, test=TRUE)# is -- correctly -- *not* valid anymore
stopifnot(is.character(msg))
## Error in validObject(foo) :
## invalid class "ngCMatrix" object: all row indices must be between 0 and nrow-1
getLastMsg <- function(tryRes) {
## Extract "final" message from erronous try result
sub("\n$", "", sub("^.*: ", "", as.character(tryRes)))
}
t1 <- try(show(foo)) # error
t2 <- try(head(foo)) # error, but previously a segfault
stopifnot(identical(msg, getLastMsg(t1)),
identical(msg, getLastMsg(t2)))
## test that all prototypes of nonvirtual classes are valid
for (cl in c(names(getClassDef("Matrix")@subclasses),
names(getClassDef("MatrixFactorization")@subclasses)))
if(!isVirtualClass(def <- getClassDef(cl))) validObject(new(def))
cat('Time elapsed: ', proc.time(),'\n') # "stats"
if(!interactive()) warnings()
Matrix/tests/factorizing.R 0000644 0001751 0000144 00000067571 14545303537 015371 0 ustar hornik users #### Matrix Factorizations --- of all kinds
## for R_DEFAULT_PACKAGES=NULL :
library(stats)
library(utils)
library(Matrix)
source(system.file("test-tools.R", package = "Matrix"))# identical3() etc
options(warn = 0)
is64bit <- .Machine$sizeof.pointer == 8
cat("doExtras:", doExtras,"; is64bit:", is64bit, "\n")
### "sparseQR" : Check consistency of methods
## --------
data(KNex, package = "Matrix")
mm <- KNex$mm
y <- KNex$y
stopifnot(is((Y <- Matrix(y)), "dgeMatrix"))
md <- as(mm, "matrix") # dense
(cS <- system.time(Sq <- qr(mm))) # 0.009
(cD <- system.time(Dq <- qr(md))) # 0.499 (lynne, 2014 f); 1.04 lynne 2019 ?????
cD[1] / cS[1] # dense is much ( ~ 100--170 times) slower
## chkQR() in ../inst/test-tools-1.R ;
if(doExtras) { ## ~ 20 sec {"large" example} + 2x qr.R() warnings
cat("chkQR( ) .. takes time .. ")
system.time(chkQR(mm, y=y, a.qr = Sq, verbose=TRUE))
system.time(chkQR(md, y=y, a.qr = Dq, verbose=TRUE))
cat(" done: [Ok]\n")
}
## consistency of results dense and sparse
## chk.qr.D.S() and checkQR.DS.both() >>> ../inst/test-tools-Matrix.R
chk.qr.D.S(Dq, Sq, y, Y)
## Another small example with pivoting (and column name "mess"):
suppressWarnings(RNGversion("3.5.0")); set.seed(1)
X <- rsparsematrix(9,5, 1/4, dimnames=list(paste0("r", 1:9), LETTERS[1:5]))
qX <- qr(X); qd <- qr(as(X, "matrix"))
## are the same (now, *including* names):
assert.EQ(print(qr.coef(qX, 1:9)), qr.coef(qd, 1:9), tol=1e-14)
chk.qr.D.S(d. = qd, s. = qX, y = 1:9)
## rank deficient QR cases: ---------------
## From Simon (15 Jul 2009) + dimnames (11 May 2015)
set.seed(10)
a <- matrix(round(10 * runif(90)), 10,9, dimnames =
list(LETTERS[1:10], paste0("c", 1:9)))
a[a < 7.5] <- 0
(A <- Matrix(a))# first column = all zeros
qD <- chkQR(a, giveRE=TRUE) ## using base qr
qS <- chkQR(A, giveRE=TRUE) ## using Matrix "sparse qr" -- "structurally rank deficient!
validObject(qS)# with the validity now (2012-11-18) -- ok, also for "bad" case
## Here, have illegal access Up[-1] in ../src/cs.c
try( ## After patch (2016-10-04 - *NOT* committed), this fails
## definitely "fails" (with good singularity message) after c3194 (cs.c):
chk.qr.D.S(qD, qS, y = 10 + 1:nrow(A), force=TRUE)# 6 warnings: "structurally rank deficient"
)
try( ## NOTE: *Both* checks currently fail here:
chkQR(A, Qinv.chk=TRUE, QtQ.chk=TRUE)
)
## Larger Scale random testing
oo <- options(Matrix.quiet.qr.R = TRUE, Matrix.verbose = TRUE, nwarnings = 1e4)
set.seed(101)
quiet <- doExtras
for(N in 1:(if(doExtras) 1008 else 24)) {
A <- rsparsematrix(8,5, nnz = rpois(1, lambda=16))
cat(sprintf(if(quiet) "%d " else "%4d -", N)); if(quiet && N %% 50 == 0) cat("\n")
checkQR.DS.both(A, Qinv.chk= NA, QtQ.chk=NA, quiet=quiet,
## --- => FALSE if struct. rank deficient
giveRE = FALSE, tol = 1e-12)
## with doExtras = TRUE, 64bit (F34, R 4.3.0-dev. 2022-05): seen 8.188e-13
}
summary(warnings())
## Look at single "hard" cases: --------------------------------------
## This is *REALLY* nice and small :
A0 <- new("dgCMatrix", Dim = 4:3, i = c(0:3, 3L), p = c(0L, 3:5), x = rep(1,5))
A0
checkQR.DS.both(A0, Qinv.chk = FALSE, QtQ.chk=FALSE)
## ----- *both* still needed :
try( checkQR.DS.both(A0, TRUE, FALSE) )
try( checkQR.DS.both(A0, FALSE, TRUE) )
## and the same when dropping the first row { --> 3 x 3 }:
A1 <- A0[-1 ,]
checkQR.DS.both(A1, Qinv.chk = FALSE, QtQ.chk=FALSE)
## ----- *both* still needed :
try( checkQR.DS.both(A1, TRUE, FALSE) )
try( checkQR.DS.both(A1, FALSE, TRUE) )
qa <- qr(as(A0,"matrix"))
qA <- qr(A0) # -> message: ".. Matrix structurally rank deficient"
drop0(crossprod( Qd <- qr.Q(qa) ), 1e-15) # perfect = diag( 3 )
drop0(crossprod( Qs <- qr.Q(qA) ), 1e-15) # R[3,3] == 0 -- OOPS!
## OTOH, qr.R() is fine, as checked in the checkQR.DS.both(A0, *) above
## zero-row *and* zero-column :
(A2 <- new("dgCMatrix", i = c(0L, 1L, 4L, 7L, 5L, 2L, 4L)
, p = c(0L, 3L, 4L, 4L, 5L, 7L)
, Dim = c(8L, 5L)
, x = c(0.92, 1.06, -1.74, 0.74, 0.19, -0.63, 0.68)))
checkQR.DS.both(A2, Qinv.chk = FALSE, QtQ.chk=FALSE)
## ----- *both* still needed :
try( checkQR.DS.both(A2, TRUE, FALSE) )
try( checkQR.DS.both(A2, FALSE, TRUE) )
## Case of *NO* zero-row or zero-column:
(A3 <- new("dgCMatrix", Dim = 6:5
, i = c(0L, 2L, 4L, 0L, 1L, 5L, 1L, 3L, 0L)
, p = c(0L, 1L, 3L, 6L, 8L, 9L)
, x = c(40, -54, -157, -28, 75, 166, 134, 3, -152)))
checkQR.DS.both(A3, Qinv.chk = FALSE, QtQ.chk=FALSE)
## ----- *both* still needed :
try( checkQR.DS.both(A3, TRUE, FALSE) )
try( checkQR.DS.both(A3, FALSE, TRUE) )
(A4 <- new("dgCMatrix", Dim = c(7L, 5L)
, i = c(1:2, 4L, 6L, 1L, 5L, 0:3, 0L, 2:4)
, p = c(0L, 4L, 6L, 10L, 10L, 14L)
, x = c(9, -8, 1, -9, 1, 10, -1, -2, 6, 14, 10, 2, 12, -9)))
checkQR.DS.both(A4, Qinv.chk = FALSE, QtQ.chk=FALSE)
## ----- *both* still needed :
try( checkQR.DS.both(A4, TRUE, FALSE) )
try( checkQR.DS.both(A4, FALSE, TRUE) )
(A5 <- new("dgCMatrix", Dim = c(4L, 4L)
, i = c(2L, 2L, 0:1, 0L, 2:3), p = c(0:2, 4L, 7L)
, x = c(48, 242, 88, 18, -167, -179, 18)))
checkQR.DS.both(A5, Qinv.chk = FALSE, QtQ.chk=FALSE)
## ----- *both* still needed :
try( checkQR.DS.both(A5, TRUE, FALSE) )
try( checkQR.DS.both(A5, FALSE, TRUE) )
quiet <- doExtras
for(N in 1:(if(doExtras) 2^12 else 128)) {
A <- round(100*rsparsematrix(5,3, nnz = min(15,rpois(1, lambda=10))))
if(any(apply(A, 2, function(x) all(x == 0)))) ## "column of all 0"
next
cat(sprintf(if(quiet) "%d " else "%4d -", N)); if(quiet && N %% 50 == 0) cat("\n")
checkQR.DS.both(A, Qinv.chk=NA, giveRE=FALSE, tol = 1e-12, quiet = quiet)
## --- => FALSE if struct. rank deficient
}
summary(warnings())
options(oo)
### "denseLU"
## Testing expansions of factorizations {was ./expand.R, then in simple.R }
## new: [m x n] where m and n may differ
x. <- c(2^(0:5),9:1,-3:8, round(sqrt(0:16)))
set.seed(1)
for(nnn in 1:100) {
y <- sample(x., replace=TRUE)
m <- sample(2:6, 1)
n <- sample(2:7, 1)
x <- matrix(seq_len(m*n), m,n)
lux <- lu(x)# occasionally a warning about exact singularity
xx <- with(expand(lux), (P %*% L %*% U))
print(dim(xx))
assert.EQ.mat(xx, x, tol = 16*.Machine$double.eps)
}
### "sparseLU"
por1 <- readMM(system.file("external/pores_1.mtx", package = "Matrix"))
lu1 <- lu(por1)
pm <- as(por1, "CsparseMatrix")
(pmLU <- lu(pm)) # -> show()
xp <- expand(pmLU)
## permute rows and columns of original matrix
ppm <- pm[pmLU@p + 1:1, pmLU@q + 1:1]
Ppm <- pmLU@L %*% pmLU@U
## identical only as long as we don't keep the original class info:
stopifnot(identical3(lu1, pmLU, pm@factors$sparseLU),# TODO === por1@factors$LU
identical(ppm, with(xp, P %*% pm %*% t(Q))),
sapply(xp, is, class2="Matrix"))
Ipm <- solve(pm, sparse=FALSE)
Spm <- solve(pm, sparse=TRUE) # is not sparse at all, here
assert.EQ.Mat(Ipm, Spm, giveRE=TRUE, tol = 1e-13)# seen 7.36e-15 only on 32-bit
stopifnot(abs(as.vector(solve(Diagonal(30, x=10) %*% pm) / Ipm) - 1/10) < 1e-7,
abs(as.vector(solve(rep.int(4, 30) * pm) / Ipm) - 1/ 4) < 1e-7)
## these two should be the same, and `are' in some ways:
assert.EQ.mat(ppm, as(Ppm, "matrix"), tol = 1e-14, giveRE=TRUE)
## *however*
length(ppm@x)# 180
length(Ppm@x)# 317 !
table(Ppm@x == 0)# (194, 123) - has 123 "zero" and 14 ``almost zero" entries
##-- determinant() and det() --- working via LU ---
m <- matrix(c(0, NA, 0, NA, NA, 0, 0, 0, 1), 3,3)
m0 <- rbind(0,cbind(0,m))
M <- as(m,"Matrix"); M ## "dsCMatrix" ...
M0 <- rbind(0, cbind(0, M))
dM <- as(M, "denseMatrix")
dM0 <- as(M0,"denseMatrix")
try( lum <- lu(M) )# Err: "near-singular A"
(lum <- lu(M, errSing=FALSE))# NA --- *BUT* it is not stored in @factors
(lum0 <- lu(M0, errSing=FALSE))# NA --- and it is stored in M0@factors[["LU"]]
## "FIXME" - TODO: Consider
replNA <- function(x, value) { x[is.na(x)] <- value ; x }
(EL.1 <- expand(lu.1 <- lu(M.1 <- replNA(M, -10))))
## so it's quite clear how lu() of the *singular* matrix M should work
## but it's not supported by the C code in ../src/cs.c which errors out
stopifnot(all.equal(M.1, with(EL.1, t(P) %*% L %*% U %*% Q)),
is.na(det(M)), is.na(det(dM)),
is.na(det(M0)), is.na(det(dM0)) )
###________ Cholesky() ________
##-------- LDL' ---- small exact examples
set.seed(1)
for(n in c(5:12)) {
cat("\nn = ",n,"\n-------\n")
rr <- mkLDL(n)
## -------- from 'test-tools.R'
stopifnot(all(with(rr, A ==
as(L %*% D %*% t(L), "symmetricMatrix"))),
all(with(rr, A == tcrossprod(L %*% sqrt(D)))))
d <- rr$d.half
A <- rr$A
.A <- as(A, "TsparseMatrix") # 'factors' slot is retained => do chol() _after_ coercion
R <- chol(A)
assert.EQ.Mat(R, chol(.A)) # gave infinite recursion
print(d. <- diag(R))
D. <- Diagonal(x= d.^2)
L. <- t(R) %*% Diagonal(x = 1/d.)
stopifnot(all.equal(as.matrix(D.), as.matrix(rr$ D)),
all.equal(as.matrix(L.), as.matrix(rr$ L)))
##
CAp <- Cholesky(A)# perm=TRUE --> Permutation:
validObject(CAp)
p <- CAp@perm + 1L
P <- as(p, "pMatrix")
## the inverse permutation:
invP <- solve(P)@perm
lDet <- sum(2* log(d))# the "true" value
ldetp <- .diag.dsC(Chx = CAp, res.kind = "sumLog")
ldetp. <- sum(log(.diag.dsC(Chx = CAp, res.kind = "diag") ))
##
CA <- Cholesky(A,perm=FALSE)
validObject(CA)
ldet <- .diag.dsC(Chx = CA, res.kind = "sumLog")
## not printing CAp : ends up non-integer for n >= 11
mCAp <- as(CAp, "CsparseMatrix")
print(mCA <- drop0(as(CA, "CsparseMatrix")))
stopifnot(identical(A[p,p], as(P %*% A %*% t(P),
"symmetricMatrix")),
relErr(d.^2, .diag.dsC(Chx= CA, res.kind="diag")) < 1e-14,
relErr(A[p,p], tcrossprod(mCAp)) < 1e-14)
if(FALSE)
rbind(lDet,ldet, ldetp, ldetp.)
## ==> Empirically, I see lDet = ldet != ldetp == ldetp.
## if(rr$rcond.A < ...) warning("condition number of A ..." ## <- TODO
cat(1,""); assert.EQ.(lDet, ldet, tol = 1e-14)
cat(2,""); assert.EQ.(ldetp, ldetp., tol = 1e-14)
cat(3,""); assert.EQ.(lDet, ldetp, tol = n^2* 1e-7)# extreme: have seen 0.0011045 !!
}## for()
mkCholhash <- function(r.all) {
## r.all %*% (2^(2:0)), but only those that do not have NA / "?" :
stopifnot(is.character(rn <- rownames(r.all)),
is.matrix(r.all), is.logical(r.all))
c.rn <- vapply(rn, function(ch) strsplit(ch, " ")[[1]], character(3))
## Now
h1 <- function(i) {
ok <- rep.int(TRUE, 3L)
if(c.rn[3L, i] == "?")
ok[2:3] <- FALSE # no supernodal LDL' factorization !!
r.all[i, ok] %*% 2^((2:0)[ok])
}
vapply(seq_len(nrow(r.all)), h1, numeric(1))
}
set.seed(17)
(rr <- mkLDL(4))
(CA <- Cholesky(rr$A))
validObject(CA)
stopifnot(all.equal(determinant(rr$A) -> detA,
determinant(as(rr$A, "matrix"))),
is.all.equal3(c(detA$modulus), log(det(rr$D)), sum(log(rr$D@x))))
A12 <- mkLDL(12, 1/10)
(r12 <- allCholesky(A12$A))[-1]
aCh.hash <- mkCholhash(r12$r.all)
if(requireNamespace("sfsmisc"))
split(rownames(r12$r.all), sfsmisc::Duplicated(aCh.hash))
## TODO: find cases for both choices when we leave it to CHOLMOD to choose
for(n in 1:50) { ## used to seg.fault at n = 10 !
mkA <- mkLDL(1+rpois(1, 30), 1/10, rcond = FALSE, condest = FALSE)
cat(sprintf("n = %3d, LDL-dim = %d x %d ", n, nrow(mkA$A), ncol(mkA$A)))
r <- allCholesky(mkA$A, silentTry=TRUE)
## Compare .. apart from the NAs that happen from (perm=FALSE, super=TRUE)
iNA <- apply(is.na(r$r.all), 1, any)
cat(sprintf(" -> %3s NAs\n", if(any(iNA)) format(sum(iNA)) else "no"))
stopifnot(aCh.hash[!iNA] == mkCholhash(r$r.all[!iNA,]))
## cat("--------\n")
}
## This is a relatively small "critical example" :
A. <-
new("dsCMatrix", Dim = c(25L, 25L), uplo = "U"
, i = as.integer(
c(0, 1, 2, 3, 4, 2, 5, 6, 0, 8, 8, 9, 3, 4, 10, 11, 6, 12, 13, 4,
10, 14, 15, 1, 2, 5, 16, 17, 0, 7, 8, 18, 9, 19, 10, 11, 16, 20,
0, 6, 7, 16, 17, 18, 20, 21, 6, 9, 12, 14, 19, 21, 22, 9, 11, 19,
20, 22, 23, 1, 16, 24))
##
, p = c(0:6, 8:10, 12L, 15:16, 18:19, 22:23, 27:28, 32L, 34L, 38L, 46L, 53L, 59L, 62L)
##
, x = c(1, 1, 1, 1, 2, 100, 2, 40, 1, 2, 100, 6700, 100, 100, 13200,
1, 50, 4100, 1, 5, 400, 20, 1, 40, 100, 5600, 9100, 5000, 5,
100, 100, 5900, 100, 6200, 30, 20, 9, 2800, 1, 100, 8, 10, 8000,
100, 600, 23900, 30, 100, 2800, 50, 5000, 3100, 15100, 100, 10,
5600, 800, 4500, 5500, 7, 600, 18200))
validObject(A.)
## A1: the same pattern as A. just simply filled with '1's :
A1 <- A.; A1@x[] <- 1; A1@factors <- list()
A1.8 <- A1; diag(A1.8) <- 8
##
nT. <- as(AT <- as(A., "TsparseMatrix"),"nMatrix")
stopifnot(all(nT.@i <= nT.@j),
identical(qr(A1.8), qr(as(A1.8, "generalMatrix"))))
CA <- Cholesky(A. + Diagonal(x = rowSums(abs(A.)) + 1))
validObject(CA)
stopifnotValid(CAinv <- solve(CA), "dsCMatrix")
MA <- as(CA, "CsparseMatrix") # with a confusing warning -- FIXME!
stopifnotValid(MAinv <- solve(MA), "dtCMatrix")
## comparing MAinv with some solve(CA, system="...") .. *not* trivial? - TODO
##
CAinv2 <- solve(CA, Diagonal(nrow(A.)))
CAinv2 <- as(CAinv2, "symmetricMatrix")
stopifnot(identical(CAinv, CAinv2))
## FINALLY fix "TODO": (not implemented *symbolic* factorization of nMatrix)
try( tc <- Cholesky(nT.) )
for(p in c(FALSE,TRUE))
for(L in c(FALSE,TRUE))
for(s in c(FALSE,TRUE, NA)) {
cat(sprintf("p,L,S = (%2d,%2d,%2d): ", p,L,s))
r <- tryCatch(Cholesky(A., perm=p, LDL=L, super=s),
error = function(e)e)
cat(if(inherits(r, "error")) " *** E ***" else
sprintf("%3d", r@type),"\n", sep="")
}
str(A., max.level=3) ## look at the 'factors'
facs <- A.@factors
names(facs) <- sub("Cholesky$", "", names(facs))
facs <- facs[order(names(facs))]
sapply(facs, class)
str(lapply(facs, slot, "type"))
## super = TRUE currently always entails LDL=FALSE :
## hence isLDL is TRUE for ("D" and not "S"):
sapply(facs, isLDL)
chkCholesky <- function(chmf, A) {
stopifnot(is(chmf, "CHMfactor"),
validObject(chmf),
is(A, "Matrix"), isSymmetric(A))
if(!is(A, "dsCMatrix"))
A <- as(as(as(A, "CsparseMatrix"), "symmetricMatrix", "dMatrix"))
L <- drop0(zapsmall(L. <- as(chmf, "CsparseMatrix")))
cat("no. nonzeros in L {before / after drop0(zapsmall(.))}: ",
c(nnzero(L.), nnzero(L)), "\n") ## 112, 95
ecc <- expand(chmf)
A... <- with(ecc, crossprod(crossprod(L,P)))
stopifnot(all.equal(L., ecc$L, tolerance = 1e-14),
all.equal(A, A..., tolerance = 1e-14))
invisible(ecc)
}
c1.8 <- try(Cholesky(A1.8, super = TRUE))# works "always", interestingly ...
chkCholesky(c1.8, A1.8)
## --- now a "large" (712 x 712) real data example ---------------------------
data(KNex, package = "Matrix")
mtm <- with(KNex, crossprod(mm))
ld.3 <- determinant(Cholesky(mtm, perm = TRUE), sqrt = FALSE)
stopifnot(identical(names(mtm@factors),
"sPDCholesky"))
ld.4 <- determinant(Cholesky(mtm, perm = FALSE), sqrt = FALSE)
stopifnot(identical(names(mtm@factors),
c("sPDCholesky", "spDCholesky")))
c2 <- Cholesky(mtm, super = TRUE)
validObject(c2)
stopifnot(identical(names(mtm@factors),
c("sPDCholesky", "spDCholesky", "SPdCholesky")))
r <- allCholesky(mtm)
r[-1]
## is now taken from cache
c1 <- Cholesky(mtm)
bv <- 1:nrow(mtm) # even integer
b <- matrix(bv)
## solve(c2, b) by default solves Ax = b, where A = c2'c2 !
x <- solve(c2,b)
stopifnot(identical3(drop(x), solve(c2, bv), drop(solve(c2, b, system = "A"))),
all.equal(x, solve(mtm, b)))
for(sys in c("A", "LDLt", "LD", "DLt", "L", "Lt", "D", "P", "Pt")) {
x <- solve(c2, b, system = sys)
cat(sys,":\n"); print(head(x))
stopifnot(dim(x) == c(712, 1),
identical(drop(x), solve(c2, bv, system = sys)))
}
## log(|LL'|) - check if super = TRUE and simplicial give same determinant
(ld.1 <- determinant(mtm))
if(FALSE) {
## MJ: CHMfactor_ldetL2 is unused outside of these tests, so we no longer
## have it in the namespace { old definition is in ../src/CHMfactor.c }
ld1 <- .Call("CHMfactor_ldetL2", c1)
ld2 <- .Call("CHMfactor_ldetL2", c2)
stopifnot(all.equal(ld1, ld2),
all.equal(ld1, as.vector(ld.1$modulus), tolerance = 1e-14),
all.equal(ld1, as.vector(ld.3$modulus), tolerance = 1e-14),
all.equal(ld1, as.vector(ld.4$modulus), tolerance = 1e-14))
} else {
stopifnot(all.equal(as.vector(ld.1$modulus), as.vector(ld.3$modulus),
tolerance = 1e-14),
all.equal(as.vector(ld.1$modulus), as.vector(ld.4$modulus),
tolerance = 1e-14))
}
## MJ: ldet[123].dsC() are unused outside of these tests, so we no longer
## have them in the namespace { old definitions are in ../R/determinant.R }
if(FALSE) {
## Some timing measurements
mtm <- with(KNex, crossprod(mm))
I <- .symDiagonal(n=nrow(mtm))
set.seed(101); r <- runif(100)
system.time(D1 <- sapply(r, function(rho) Matrix:::ldet1.dsC(mtm + (1/rho) * I)))
## 0.842 on fast cmath-5
system.time(D2 <- sapply(r, function(rho) Matrix:::ldet2.dsC(mtm + (1/rho) * I)))
## 0.819
system.time(D3 <- sapply(r, function(rho) Matrix:::ldet3.dsC(mtm + (1/rho) * I)))
## 0.810
stopifnot(is.all.equal3(D1,D2,D3, tol = 1e-13))
}
## Updating LL' should remain LL' and not become LDL' :
cholCheck <- function(Ut, tol = 1e-12, super = FALSE, LDL = !super) {
L <- Cholesky(UtU <- tcrossprod(Ut), super=super, LDL=LDL, Imult = 1)
L1 <- update(L, UtU, mult = 1)
L2 <- update(L, Ut, mult = 1)
stopifnot(is.all.equal3(L, L1, L2, tol = tol),
all.equal(update(L, UtU, mult = pi),
update(L, Ut, mult = pi), tolerance = tol)
)
}
## Inspired by
## data(Dyestuff, package = "lme4")
## Zt <- as(Dyestuff$Batch, "sparseMatrix")
Zt <- new("dgCMatrix", Dim = c(6L, 30L), x = 2*1:30,
i = rep(0:5, each=5),
p = 0:30, Dimnames = list(LETTERS[1:6], NULL))
cholCheck(0.78 * Zt, tol=1e-14)
oo <- options(Matrix.quiet.qr.R = TRUE, warn = 2)# no warnings allowed
qrZ <- qr(t(Zt))
Rz <- qr.R(qrZ)
stopifnot(exprs = {
inherits(qrZ, "sparseQR")
inherits(Rz, "sparseMatrix")
isTriangular(Rz)
isDiagonal(Rz) # even though formally a "dtCMatrix"
qr2rankMatrix(qrZ, do.warn=FALSE) == 6
})
options(oo)
## problematic rank deficient rankMatrix() case -- only seen in large cases ??
## MJ: NA in diag(@R) not seen with Apple Clang 14.0.3
Z. <- readRDS(system.file("external", "Z_NA_rnk.rds", package="Matrix"))
(rnkZ. <- rankMatrix(Z., method = "qr")) # gave errors; now warns typically, but not on aarm64 (M1)
qrZ. <- qr(Z.)
options(warn=1)
rnk2 <- qr2rankMatrix(qrZ.) # warning ".. only 684 out of 822 finite diag(R) entries"
oo <- options(warn=2)# no warnings allowed from here
di.NA <- anyNA(diag(qrZ.@R))
stopifnot(is(qrZ, "sparseQR"),
identical(is.na(rnkZ.), di.NA),
identical(is.na(rnk2), di.NA))
## The above bug fix was partly wrongly extended to dense matrices for "qr.R":
x <- cbind(1, rep(0:9, 18))
qr.R(qr(x)) # one negative diagonal
qr.R(qr(x, LAPACK=TRUE)) # two negative diagonals
chkRnk <- function(x, rnk) {
stopifnot(exprs = {
rankMatrix(x) == rnk
rankMatrix(x, method="maybeGrad") == rnk ## but "useGrad" is not !
rankMatrix(x, method="qrLINPACK") == rnk
rankMatrix(x, method="qr.R" ) == rnk
})# the last gave '0' and a warning in Matrix 1.3-0
}
chkRnk( x, 2)
chkRnk(diag(1), 1) # had "empty stopifnot" (-> Error in MM's experimental setup) + warning 'min()'
(m3 <- cbind(2, rbind(diag(pi, 2), 8)))
chkRnk(m3, 3)
chkRnk(matrix(0, 4,3), 0)
chkRnk(matrix(1, 5,5), 1) # had failed for "maybeGrad"
chkRnk(matrix(1, 5,2), 1)
showSys.time(
for(i in 1:120) {
set.seed(i)
M <- rspMat(n=rpois(1,50), m=rpois(1,20), density = 1/(4*rpois(1, 4)))
cat(sprintf("%3d: dim(M) = %2dx%2d, rank=%2d, k=%9.4g; ",
i, nrow(M), ncol(M), rankMatrix(M), kappa(M)))
for(super in c(FALSE,TRUE)) {
cat("super=",super,"M: ")
## 2018-01-04, Avi Adler: needed 1.2e-12 in Windows 64 (for i=55, l.1):
cholCheck( M , tol=2e-12, super=super); cat(" M': ")
cholCheck(t(M), tol=2e-12, super=super)
}
cat(" [Ok]\n")
})
.updateCHMfactor
## TODO: (--> ../TODO "Cholesky"):
## ----
## allow Cholesky(A,..) when A is not symmetric *AND*
## we really want to factorize AA' ( + beta * I)
## Schur() ----------------------
checkSchur <- function(A, SchurA = Schur(A), tol = 1e-14) {
stopifnot(is(SchurA, "Schur"),
isOrthogonal(Q <- SchurA@Q),
all.equal(as.mat(A),
as.mat(Q %*% SchurA@T %*% t(Q)), tolerance = tol))
}
SH <- Schur(H5 <- Hilbert(5))
checkSchur(H5, SH)
checkSchur(Diagonal(x = 9:3))
p <- 4L
uTp <- new("dtpMatrix", x=c(2, 3, -1, 4:6, -2:1), Dim = c(p,p))
(uT <- as(uTp, "unpackedMatrix"))
## Schur ( ) <--> Schur( )
Su <- Schur(uT) ; checkSchur(uT, Su)
gT <- as(uT,"generalMatrix")
Sg <- Schur(gT) ; checkSchur(gT, Sg)
Stg <- Schur(t(gT));checkSchur(t(gT), Stg)
Stu <- Schur(t(uT));checkSchur(t(uT), Stu)
stopifnot(exprs = {
identical3(Sg@T, uT, Su@T)
identical(Sg@Q, as(diag(p), "generalMatrix"))
## LaPck 3.12.0: these must be more careful (Q is *different* permutation):
is.integer(print(ip <- invPerm(pp <- as(Stg@Q, "pMatrix")@perm)))
identical(Stg@T, as(t(gT[,ip])[,ip], "triangularMatrix"))
identical(Stg@Q, as( diag(p)[,ip], "generalMatrix"))
## Stu still has p:1 permutation, but should not rely on it
is.integer(print(i2 <- invPerm(as(Stu@Q, "pMatrix")@perm)))
identical(Stu@T, as(t(uT[,i2])[,i2], "triangularMatrix"))
identical(Stu@Q, as( diag(p)[,i2], "pMatrix")) # Schur() ==> 'Q' is pMatrix
})
## the pedigreemm example where solve(.) failed:
p <- new("dtCMatrix", i = c(2L, 3L, 2L, 5L, 4L, 4:5), p = c(0L, 2L, 4:7, 7L),
Dim = c(6L, 6L), Dimnames = list(as.character(1:6), NULL),
x = rep.int(-0.5, 7), uplo = "L", diag = "U")
Sp <- Schur(p)
Sp. <- Schur(as(p,"generalMatrix"))
Sp.p <- Schur(crossprod(p))
## the last two failed
ip <- solve(p)
assert.EQ.mat(solve(ip), as(p,"matrix"))
## chol2inv() for a traditional matrix
assert.EQ.mat( crossprod(chol2inv(chol(Diagonal(x = 5:1)))),
C <- crossprod(chol2inv(chol( diag(x = 5:1)))))
stopifnot(all.equal(C, diag((5:1)^-2)))
## failed in some versions because of a "wrong" implicit generic
U <- cbind(1:0, 2*(1:2))
(sU <- as(U, "CsparseMatrix"))
validObject(sS <- crossprod(sU))
C. <- chol(sS)
stopifnot(all.equal(C., sU, tolerance=1e-15))
## chol()
tC7 <- .trDiagonal(7, 7:1)
stopifnotValid(tC7, "dtCMatrix")
ch7 <- chol(tC7) ## this (and the next 2) failed: 'no slot .. "factors" ..."dtCMatrix"'
chT7 <- chol(tT7 <- as(tC7, "TsparseMatrix"))
chR7 <- chol(tR7 <- as(tC7, "RsparseMatrix"))
stopifnot(expr = {
isDiagonal(ch7)
identical(chT7, ch7) # "ddiMatrix" all of them
identical(chR7, ch7) # "ddiMatrix" all of them
all.equal(sqrt(7:1), diag(ch7 ))
})
## From [Bug 14834] New: chol2inv *** caught segfault ***
n <- 1e6 # was 595362
A <- chol( D <- Diagonal(n) )
stopifnot(identical(A,D)) # A remains (unit)diagonal
is(tA <- as(A,"triangularMatrix"))# currently a dtTMatrix
stopifnotValid(tA, "dsparseMatrix")
CA <- as(tA, "CsparseMatrix")
selectMethod(solve, c("dtCMatrix","missing"))
##--> .Call(dtCMatrix_sparse_solve, a, .trDiagonal(n)) in ../src/dtCMatrix.c
sA <- solve(CA)## -- R_CheckStack() segfault in Matrix <= 1.0-4
nca <- diagU2N(CA)
stopifnot(identical(sA, nca))
## same check with non-unit-diagonal D :
A <- chol(D <- Diagonal(n, x = 0.5))
ia <- chol2inv(A)
stopifnot(is(ia, "diagonalMatrix"),
all.equal(ia@x, rep(2,n), tolerance = 1e-15))
##------- Factor caches must be cleaned - even after scalar-Ops such as "2 *"
set.seed(7)
d <- 5
S <- 10*Diagonal(d) + rsparsematrix(d,d, 1/4)
class(M <- as(S, "denseMatrix")) # dgeMatrix
m <- as.matrix(M)
(dS <- determinant(S))
stopifnot(exprs = {
all.equal(determinant(m), dS, tolerance=1e-15)
all.equal(dS, determinant(M), tolerance=1e-15)
## These had failed, as the "LU" factor cache was kept unchanged in 2*M :
all.equal(determinant(2*S), determinant(2*M) -> d2M)
all.equal(determinant(S^2), determinant(M^2) -> dM2)
all.equal(determinant(m^2), dM2)
all.equal(d*log(2), c(d2M$modulus - dS$modulus))
})
## misc. bugs found in Matrix 1.4-1
L. <- new("dtCMatrix", Dim = c(1L, 1L), uplo = "L",
p = c(0L, 1L), i = 0L, x = 1)
S. <- forceSymmetric(L.)
lu(S.)
stopifnot(validObject(lu(L.)), # was invalid
identical(names(S.@factors), "sparseLU")) # was "lu"
## chol() should give matrix with 'Dimnames',
## even if 'Dimnames' are not cached
D. <- as(diag(3), "CsparseMatrix")
D.@Dimnames <- dn <- list(zzz = letters[1:3], ZZZ = LETTERS[1:3])
cd1 <- chol(D.) # "fresh"
stopifnot(identical(cd1@Dimnames, rep(dn[2L], 2L)))
cd2 <- chol(D.) # from cache
stopifnot(identical(cd1, cd2))
## lu(), lu(<0-by-n>), BunchKaufman(<0-by-0>), chol(<0-by-0>)
stopifnot(identical(lu(new("dgeMatrix", Dim = c(2L, 0L))),
new("denseLU", Dim = c(2L, 0L))),
identical(lu(new("dgeMatrix", Dim = c(0L, 2L))),
new("denseLU", Dim = c(0L, 2L))),
identical(BunchKaufman(new("dsyMatrix", uplo = "U")),
new("BunchKaufman", uplo = "U")),
identical(BunchKaufman(new("dspMatrix", uplo = "L")),
new("pBunchKaufman", uplo = "L")),
identical(Cholesky(new("dpoMatrix", uplo = "U")),
new("Cholesky", uplo = "U")),
identical(Cholesky(new("dppMatrix", uplo = "L")),
new("pCholesky", uplo = "L")))
## determinant() going via Bunch-Kaufman
set.seed(15742)
n <- 10L
syU <- syL <- new("dsyMatrix", Dim = c(n, n), x = rnorm(n * n))
spU <- spL <- new("dspMatrix", Dim = c(n, n), x = rnorm((n * (n + 1L)) %/% 2L))
syL@uplo <- spL@uplo <- "L"
for(m in list(syU, syL, spU, spL))
for(givelog in c(FALSE, TRUE))
stopifnot(all.equal(determinant( m, givelog),
determinant(as(m, "matrix"), givelog)))
## was an error at least in Matrix 1.5-4 ...
BunchKaufman(as.matrix(1))
## 'expand2': product of listed factors should reproduce factorized matrix
## FIXME: many of our %*% methods still mangle dimnames or names(dimnames) ...
## hence for now we coerce the factors to matrix before multiplying
chkMF <- function(X, Y, FUN, ...) {
## t(x)@factors may preserve factorizations with x@uplo
X@factors <- list()
mf <- FUN(X, ...)
e2.mf <- expand2(mf)
e1.mf <- sapply(names(e2.mf), expand1, x = mf, simplify = FALSE)
m.e2.mf <- lapply(e2.mf, as, "matrix")
m.e1.mf <- lapply(e1.mf, as, "matrix")
identical(m.e1.mf, lapply(m.e2.mf, unname)) &&
isTRUE(all.equal(Reduce(`%*%`, m.e2.mf), Y))
}
set.seed(24831)
n <- 16L
mS <- tcrossprod(matrix(rnorm(n * n), n, n,
dimnames = list(A = paste0("s", seq_len(n)), NULL)))
sS <- as(pS <- as(S <- as(mS, "dpoMatrix"), "packedMatrix"), "CsparseMatrix")
stopifnot(exprs = {
chkMF( S , mS, Schur)
chkMF( pS , mS, Schur)
chkMF( S , mS, lu)
chkMF( pS , mS, lu)
chkMF( sS , mS, lu)
chkMF( sS , mS, qr)
chkMF( S , mS, BunchKaufman)
chkMF( pS , mS, BunchKaufman)
chkMF(t( S), mS, BunchKaufman)
chkMF(t(pS), mS, BunchKaufman)
chkMF( S , mS, Cholesky)
chkMF( pS , mS, Cholesky)
chkMF(t( S), mS, Cholesky)
chkMF(t(pS), mS, Cholesky)
chkMF( sS , mS, Cholesky, super = FALSE, LDL = TRUE)
chkMF( sS , mS, Cholesky, super = FALSE, LDL = FALSE)
chkMF( sS , mS, Cholesky, super = TRUE, LDL = FALSE)
})
cat('Time elapsed: ', proc.time(),'\n') # for ``statistical reasons''
Matrix/tests/abIndex-tsts.R 0000644 0001751 0000144 00000010633 14444520706 015377 0 ustar hornik users #### Testing consistency of "abIndex" == "abstract-indexing vectors" class :
## for R_DEFAULT_PACKAGES=NULL :
library(stats)
library(utils)
library(Matrix)
source(system.file("test-tools.R", package = "Matrix"))# identical3() etc
validObject(ab <- new("abIndex"))
str(ab)
set.seed(1)
ex. <- list(2:1000, 0:10, sample(100), c(-3:40, 20:70),
c(1:100,77L, 50:40, 10L), c(17L, 3L*(12:3)))
## we know which kinds will come out: "compressed" for all but random:
rD <- "rleDiff"; kinds <- c(rD,rD,"int32", rD, rD, rD)
isCmpr <- kinds == rD
ab. <- lapply(ex., as, Class = "abIndex")
nu. <- lapply(ab., as, Class = "numeric")
in. <- lapply(ab., as, Class = "integer")
rles <- lapply(ab.[isCmpr], function(u) u@rleD@rle)
r.x <- lapply(ex.[isCmpr], function(.) rle(diff(.)))
stopifnot(sapply(ab., validObject),
identical(ex., nu.),
identical(ex., in.),
## Check that the relevant cases really *are* "compressed":
sapply(ab., slot, "kind") == kinds,
## Using rle(diff(.)) is equivalent to using our C code:
identical(rles, r.x),
## Checking Group Methods - "Summary" :
sapply(ab., range) == sapply(ex., range),
sapply(ab., any) == sapply(ex., any),
TRUE)
## testing c() method, i.e. currently c.abIndex():
tst.c.abI <- function(lii) {
stopifnot(is.list(lii),
all(unlist(lapply(lii, mode)) == "numeric"))
aii <- lapply(lii, as, "abIndex")
v.i <- do.call(c, lii)
a.i <- do.call(c, aii)
avi <- as(v.i, "abIndex")
## identical() is too hard, as values & lengths can be double/integer
stopifnot(all.equal(a.i, avi, tolerance = 0))
}
tst.c.abI(list(2:6, 70:50, 5:-2))
## now an example where *all* are uncompressed:
tst.c.abI(list(c(5, 3, 2, 4, 7, 1, 6), 3:4, 1:-1))
## and one with parts that are already non-trivial:
exc <- ex.[isCmpr]
tst.c.abI(exc)
set.seed(101)
N <- length(exc) # 5
for(i in 1:10) {
tst.c.abI(exc[sample(N, replace=TRUE)])
tst.c.abI(exc[sample(N, N-1)])
tst.c.abI(exc[sample(N, N-2)])
}
for(n in 1:120) {
cat(".")
k <- 1 + 4*rpois(1, 5) # >= 1
## "random" rle -- NB: consecutive values *must* differ (for uniqueness)
v <- as.integer(1+ 10*rnorm(k))
while(any(dv <- duplicated(v)))
v[dv] <- v[dv] + 1L
rl <- structure(list(lengths = as.integer(1 + rpois(k, 10)), values = v),
class = "rle")
ai <- new("abIndex", kind = "rleDiff",
rleD = new("rleDiff", first = rpois(1, 20), rle = rl))
validObject(ai)
ii <- as(ai, "numeric")
iN <- ii; iN[180] <- NA; aiN <- as(iN,"abIndex")
iN <- as(aiN, "numeric") ## NA from 180 on
stopifnot(is.numeric(ii), ii == round(ii),
identical(ai, as(ii, "abIndex")),
identical(is.na(ai), is.na(ii)),
identical(is.na(aiN), is.na(iN)),
identical(is.finite (aiN), is.finite(iN)),
identical(is.infinite(aiN), is.infinite(iN))
)
if(n %% 40 == 0) cat(n,"\n")
}
## we have : identical(lapply(ex., as, "abIndex"), ab.)
mkStr <- function(ch, n) paste(rep.int(ch, n), collapse="")
##O for(grMeth in getGroupMembers("Ops")) {
##O cat(sprintf("\n%s :\n%s\n", grMeth, mkStr("=", nchar(grMeth))))
grMeth <- "Arith"
for(ng in getGroupMembers(grMeth)) {
cat(ng, ": ")
G <- get(ng)
t.tol <- if(ng == "/") 1e-12 else 0
## "/" with no long double (e.g. on Sparc Solaris): 1.125e-14
AEq <- function(a,b, ...) assert.EQ(a, b, tol=t.tol, giveRE=TRUE)
for(v in ex.) {
va <- as(v, "abIndex")
for(s in list(-1, 17L, TRUE, FALSE)) # numeric *and* logical
if(!((identical(s, FALSE) && ng == "/"))) { ## division by 0 may "fail"
AEq(as(G(v, s), "abIndex"), G(va, s))
AEq(as(G(s, v), "abIndex"), G(s, va))
}
cat(".")
}
cat(" [Ok]\n")
}
##O }
## check the abIndex versions of indDiag() and indTri() :
for(n in 1:7) {
stopifnotValid(ii <- Matrix:::abIindDiag(n), "abIndex")
stopifnot(ii@kind == "rleDiff",
Matrix:::indDiag(n) == as(ii, "numeric"))
}
for(n in 0:7)
for(diag in c(TRUE,FALSE))
for(upper in c(TRUE,FALSE)) {
stopifnotValid(ii <- Matrix:::abIindTri(n, diag=diag,upper=upper), "abIndex")
if(n)
stopifnot(Matrix:::indTri(n, diag=diag,upper=upper) == as(ii, "numeric"),
allow.logical0=TRUE) # works also in R versions w/o it as formal argument
}
cat('Time elapsed: ', (.pt <- proc.time()),'\n') # "stats"
Matrix/tests/matprod.R 0000644 0001751 0000144 00000115623 14500446564 014507 0 ustar hornik users ## for R_DEFAULT_PACKAGES=NULL :
library(stats)
library(utils)
library(Matrix)
### Matrix Products including cross products
source(system.file("test-tools.R", package = "Matrix")) # is.EQ.mat(), dnIdentical() ..etc
doExtras
options(warn=1, # show as they happen
Matrix.verbose = doExtras)
##' Check matrix multiplications with (unit) Diagonal matrices
chkDiagProd <- function(M) {
if(is.matrix(M)) {
noRN <- function(x) {
if(!is.null(dn <- dimnames(x)))
dimnames(x) <- c(list(NULL), dn[2L])
x
}
noCN <- function(x) {
if(!is.null(dn <- dimnames(x)))
dimnames(x) <- c(dn[1L], list(NULL))
x
}
} else if(is(M, "Matrix")) {
noRN <- function(x) {
x@Dimnames <- c(list(NULL), x@Dimnames[2L])
x
}
noCN <- function(x) {
x@Dimnames <- c(x@Dimnames[1L], list(NULL))
x
}
} else stop("'M' must be a [mM]atrix")
I.l <- Diagonal(nrow(M)) # I_n -- "unit" Diagonal
I.r <- Diagonal(ncol(M)) # I_d
D2.l <- Diagonal(nrow(M), x = 2) # D_n
D2.r <- Diagonal(ncol(M), x = 2) # I_d
stopifnot(is.EQ.mat(noCN(M), M %*% I.r),
is.EQ.mat(noRN(M), I.l %*% M),
is.EQ.mat(noCN(2*M), M %*% D2.r),
is.EQ.mat(noRN(M*2), D2.l %*% M),
## crossprod
is.EQ.mat(noCN(t(M)), crossprod(M, I.l)),
is.EQ.mat(noRN(M), crossprod(I.l, M)),
is.EQ.mat(noCN(t(2*M)), crossprod(M, D2.l)),
is.EQ.mat(noRN(M*2) , crossprod(D2.l, M)),
## tcrossprod
is.EQ.mat(noCN(M), tcrossprod(M, I.r)),
is.EQ.mat(noRN(t(M)), tcrossprod(I.r, M)),
is.EQ.mat(noCN(2*M), tcrossprod(M, D2.r)),
is.EQ.mat(noRN(t(M*2)), tcrossprod(D2.r, M)))
}
### dimnames -- notably for matrix products ----------------
#
##' Checks that matrix products are the same, including dimnames
##'
##' @param m matrix = traditional-R-matrix version of M
##' @param M optional Matrix = "Matrix class version of m"
##' @param browse
chkDnProd <- function(m = as(M, "matrix"), M = Matrix(m), browse=FALSE, warn.ok=FALSE) {
## TODO:
## if(browse) stopifnot <- f.unction(...) such that it enters browser() when it is not fulfilled
if(!warn.ok) { # NO warnings allowd
op <- options(warn = 2)
on.exit(options(op))
}
stopifnot(is.matrix(m), is(M, "Matrix"), identical(dim(m), dim(M)), dnIdentical(m,M))
## m is n x d (say)
is.square <- nrow(m) == ncol(m)
p1 <- (tm <- t(m)) %*% m ## d x d
p1. <- crossprod(m)
stopifnot(is.EQ.mat3(p1, p1., crossprod(m,m)))
t1 <- m %*% tm ## n x n
t1. <- tcrossprod(m)
stopifnot(is.EQ.mat3(t1, t1., tcrossprod(m,m)))
if(is.square) {
mm <- m %*% m
stopifnot(is.EQ.mat3(mm, crossprod(tm,m), tcrossprod(m,tm)))
}
chkDiagProd(m)## was not ok in Matrix 1.2.0
## Now the "Matrix" ones -- should match the "matrix" above
M0 <- M
cat("sparse: ")
for(sparse in c(TRUE, FALSE)) {
cat(sparse, "; ")
M <- as(M0, if(sparse) "sparseMatrix" else "denseMatrix")
P1 <- (tM <- t(M)) %*% M
P1. <- crossprod(M)
stopifnot(is.EQ.mat3(P1, P1., p1),
is.EQ.mat3(P1., crossprod(M,M), crossprod(M,m)),
is.EQ.mat (P1., crossprod(m,M)))
## P1. is "symmetricMatrix" -- semantically "must have" symm.dimnames
PP1 <- P1. %*% P1. ## still d x d
R <- triu(PP1); r <- as(R, "matrix") # upper - triangular
L <- tril(PP1); l <- as(L, "matrix") # lower - triangular
stopifnot(isSymmetric(P1.), isSymmetric(PP1),
isDiagonal(L) || is(L,"triangularMatrix"),
isDiagonal(R) || is(R,"triangularMatrix"),
isTriangular(L, upper=FALSE), isTriangular(R, upper=TRUE),
is.EQ.mat(PP1, (pp1 <- p1 %*% p1)),
dnIdentical(PP1, R),
dnIdentical(L, R))
T1 <- M %*% tM
T1. <- tcrossprod(M)
stopifnot(is.EQ.mat3(T1, T1., t1),
is.EQ.mat3(T1., tcrossprod(M,M), tcrossprod(M,m)),
is.EQ.mat (T1., tcrossprod(m,M)),
is.EQ.mat(tcrossprod(T1., tM),
tcrossprod(t1., tm)),
is.EQ.mat(crossprod(T1., M),
crossprod(t1., m)))
## Now, *mixing* Matrix x matrix:
stopifnot(is.EQ.mat3(tM %*% m, tm %*% M, tm %*% m))
if(is.square)
stopifnot(is.EQ.mat (mm, M %*% M),
is.EQ.mat3(mm, crossprod(tM,M), tcrossprod(M,tM)),
## "mixing":
is.EQ.mat3(mm, crossprod(tm,M), tcrossprod(m,tM)),
is.EQ.mat3(mm, crossprod(tM,m), tcrossprod(M,tm)))
## Symmetric and Triangular
stopifnot(is.EQ.mat(PP1 %*% tM, pp1 %*% tm),
is.EQ.mat(R %*% tM, r %*% tm),
is.EQ.mat(L %*% tM, L %*% tm))
## Diagonal :
chkDiagProd(M)
}
cat("\n")
invisible(TRUE)
} # chkDnProd()
## All these are ok {now, (2012-06-11) also for dense
(m <- matrix(c(0, 0, 2:0), 3, 5))
m00 <- m # *no* dimnames
dimnames(m) <- list(LETTERS[1:3], letters[1:5])
(m.. <- m) # has *both* dimnames
m0. <- m.0 <- m..
dimnames(m0.)[1] <- list(NULL); m0.
dimnames(m.0)[2] <- list(NULL); m.0
d <- diag(3); dimnames(d) <- list(c("u","v","w"), c("X","Y","Z")); d
dU <- diagN2U(Matrix(d, doDiag = FALSE)) # unitriangular sparse
tU <- dU; tU[1,2:3] <- 3:4; tU[2,3] <- 7; tU # ditto "unitri" sparse
(T <- new("dtrMatrix", diag = "U", x= c(0,0,5,0), Dim= c(2L,2L),
Dimnames= list(paste0("r",1:2),paste0("C",1:2)))) # unitriangular dense
pT <- pack(T)# ^^^^^^^^^^^^
mt <- m[,2:3] %*% pT # deprecation warning in pre-1.5-4
stopifnot(is(pT, "dtpMatrix"), validObject(pT),
validObject(mt), is(mt, "dgeMatrix"),
identical(as.matrix(mt),
array(c(1,0,0, 5,2,1), dim = 3:2, dimnames = list(c("A","B","C"), c("C1","C2"))))
)
A <- matrix(c(0.4, 0.1, 0, 0), 2)
B <- matrix(c(1.1, 0, 0, 0), 2); ABt <- tcrossprod(A, B)
## Matrix version # both Matrix version:
class(AM <- as(A, "triangularMatrix")) # dtr
class(BM <- as(B, "Matrix")) # ddi
class(Bs <- as(as(B, "CsparseMatrix"), "symmetricMatrix")) # "dsC"
(ABst <- tcrossprod(A, Bs)) # was wrong since at least Matrix 1.3-3 (R-4.0.5)
assert.EQ.mat(ABst, ABt)
assert.EQ.mat(tcrossprod(AM, BM), ABt)
assert.EQ.mat(tcrossprod(AM, Bs), ABt)
assert.EQ.mat(tcrossprod(A , Bs), ABt)
## currently many warnings about sub-optimal matrix products :
chkDnProd(m..)
chkDnProd(m0.)
chkDnProd(m.0)
chkDnProd(m00)
chkDnProd(M = T)
chkDnProd(M = t(T))
if(FALSE) {
## FIXME:
## Matrix() bug fix has revealed that diagonalMatrix product methods are not
## handling (have never handled?) 'Dimnames' correctly, causing these to fail
chkDnProd(M = dU)
chkDnProd(M = t(dU))
}
## all the above failed in 1.2-0 and 1.1-5, 1.1-4 some even earlier
chkDnProd(M = tU)
chkDnProd(M = t(tU))
## the two above failed in Matrix <= 1.4-1
chkDnProd(M = Diagonal(4))
chkDnProd(diag(x=3:1))
if(FALSE) {
## FIXME: as for dU, t(dU) above
chkDnProd(d)
chkDnProd(M = as(d, "denseMatrix"))# M: dtrMatrix (diag = "N")
}
m5 <- 1 + as(diag(-1:4)[-5,], "generalMatrix")
## named dimnames:
dimnames(m5) <- list(Rows= LETTERS[1:5], paste("C", 1:6, sep=""))
tr5 <- tril(m5[,-6])
m. <- as(m5, "matrix")
m5.2 <- local({t5 <- as.matrix(tr5); t5 %*% t5})
stopifnotValid(tr5, "dtrMatrix")
stopifnot(dim(m5) == 5:6,
class(cm5 <- crossprod(m5)) == "dpoMatrix")
assert.EQ.mat(t(m5) %*% m5, as(cm5, "matrix"))
assert.EQ.mat(tr5.2 <- tr5 %*% tr5, m5.2)
stopifnotValid(tr5.2, "dtrMatrix")
stopifnot(as.vector(rep(1,6) %*% cm5) == colSums(cm5),
as.vector(cm5 %*% rep(1,6)) == rowSums(cm5))
## uni-diagonal dtrMatrix with "wrong" entries in diagonal
## {the diagonal can be anything: because of diag = "U" it should never be used}:
tru <- Diagonal(3, x=3); tru[i.lt <- lower.tri(tru, diag=FALSE)] <- c(2,-3,4)
tru@diag <- "U" ; stopifnot(diag(trm <- as.matrix(tru)) == 1)
## TODO: Also add *upper-triangular* *packed* case !!
stopifnot((tru %*% tru)[i.lt] ==
(trm %*% trm)[i.lt])
## crossprod() with numeric vector RHS and LHS
i5 <- rep.int(1, 5)
isValid(S5 <- tcrossprod(tr5), "dpoMatrix")# and inherits from "dsy"
G5 <- as(S5, "generalMatrix")# "dge"
assert.EQ.mat( crossprod(i5, m5), rbind( colSums(m5)))
assert.EQ.mat( crossprod(i5, m.), rbind( colSums(m5)))
assert.EQ.mat( crossprod(m5, i5), cbind( colSums(m5)))
assert.EQ.mat( crossprod(m., i5), cbind( colSums(m5)))
assert.EQ.mat( crossprod(i5, S5), rbind( colSums(S5))) # failed in Matrix 1.1.4
## tcrossprod() with numeric vector RHS and LHS :
stopifnot(identical(tcrossprod(i5, S5), # <- lost dimnames
tcrossprod(i5, G5) -> m51),
identical(dimnames(m51), list(NULL, Rows = LETTERS[1:5]))
)
m51 <- m5[, 1, drop=FALSE] # [6 x 1]
m.1 <- m.[, 1, drop=FALSE] ; assert.EQ.mat(m51, m.1)
## The only (M . v) case
assert.EQ.mat(tcrossprod(m51, 5:1), tcrossprod(m.1, 5:1))
## The two (v . M) cases:
assert.EQ.mat(tcrossprod(rep(1,6), m.), rbind( rowSums(m5)))# |v| = ncol(m)
assert.EQ.mat(tcrossprod(rep(1,3), m51),
tcrossprod(rep(1,3), m.1))# ncol(m) = 1
## classes differ
tc.m5 <- m5 %*% t(m5) # "dge*", no dimnames (FIXME)
(tcm5 <- tcrossprod(m5)) # "dpo*" w/ dimnames
assert.EQ.mat(tc.m5, mm5 <- as(tcm5, "matrix"))
## tcrossprod(x,y) :
assert.EQ.mat(tcrossprod(m5, m5), mm5)
assert.EQ.mat(tcrossprod(m5, m.), mm5)
assert.EQ.mat(tcrossprod(m., m5), mm5)
M50 <- m5[,FALSE, drop=FALSE]
M05 <- t(M50)
s05 <- as(M05, "sparseMatrix")
s50 <- t(s05)
assert.EQ.mat(M05, matrix(1, 0,5))
assert.EQ.mat(M50, matrix(1, 5,0))
assert.EQ.mat(tcrossprod(M50), tcrossprod(as(M50, "matrix")))
assert.EQ.mat(tcrossprod(s50), tcrossprod(as(s50, "matrix")))
assert.EQ.mat( crossprod(s50), crossprod(as(s50, "matrix")))
stopifnot(identical( crossprod(s50), tcrossprod(s05)),
identical( crossprod(s05), tcrossprod(s50)))
(M00 <- crossprod(M50))## used to fail -> .Call(dgeMatrix_crossprod, x, FALSE)
stopifnot(identical(M00, tcrossprod(M05)),
all(M00 == t(M50) %*% M50), dim(M00) == 0)
## simple cases with 'scalars' treated as 1x1 matrices:
d <- Matrix(1:5)
d %*% 2
10 %*% t(d)
assertError(3 %*% d) # must give an error , similar to
assertError(5 %*% as.matrix(d)) # -> error
## right and left "numeric" and "matrix" multiplication:
(p1 <- m5 %*% c(10, 2:6))
(p2 <- c(10, 2:5) %*% m5)
(pd1 <- m5 %*% diag(1:6))
(pd. <- m5 %*% Diagonal(x = 1:6))
(pd2 <- diag (10:6) %*% m5)
(pd..<- Diagonal(x = 10:6) %*% m5)
stopifnot(exprs = {
dim(crossprod(t(m5))) == c(5,5)
c(class(p1),class(p2),class(pd1),class(pd2), class(pd.),class(pd..)) == "dgeMatrix"
identical(dimnames(pd.), c(dimnames(m5)[1L], list(NULL)))
identical(dimnames(pd..), c(list(NULL), dimnames(m5)[2L]))
})
assert.EQ.mat(p1, cbind(c(20,30,33,38,54)))
assert.EQ.mat(pd1, m. %*% diag(1:6))
assert.EQ.mat(pd2, diag(10:6) %*% m.)
assert.EQ.mat(pd., as(pd1,"matrix"))
assert.EQ.mat(pd..,as(pd2,"matrix"))
## check that 'solve' and '%*%' are inverses
suppressWarnings(RNGversion("3.5.0")); set.seed(1)
A <- Matrix(rnorm(25), ncol = 5)
y <- rnorm(5)
all.equal((A %*% solve(A, y))@x, y)
Atr <- new("dtrMatrix", Dim = A@Dim, x = A@x, uplo = "U")
all.equal((Atr %*% solve(Atr, y))@x, y)
## R-forge bug 5933 by Sebastian Herbert,
## https://r-forge.r-project.org/tracker/index.php?func=detail&aid=5933&group_id=61&atid=294
mLeft <- matrix(data = double(0), nrow = 3, ncol = 0)
mRight <- matrix(data = double(0), nrow = 0, ncol = 4)
MLeft <- Matrix(data = double(0), nrow = 3, ncol = 0)
MRight <- Matrix(data = double(0), nrow = 0, ncol = 4)
stopifnot(exprs = {
class(mLeft) == class(mRight)
class(MLeft) == class(MRight)
class(MLeft) == "dgeMatrix"
})
Qidentical3 <- function(a,b,c) Q.eq(a,b) && Q.eq(b,c)
Qidentical4 <- function(a,b,c,d) Q.eq(a,b) && Q.eq(b,c) && Q.eq(c,d)
chkP <- function(mLeft, mRight, MLeft, MRight, cl = class(MLeft)) {
ident4 <-
if(extends(cl, "generalMatrix")) {
function(a,b,c,d) {
r <- eval(Matrix:::.as.via.virtual(
class(a)[1L], cl[1], quote(a)))
identical4(r,b,c,d)
}
} else {
function(a,b,c,d) {
assert.EQ.mat(M=b, m=a, tol=0)
Qidentical3(b,c,d)
}
}
mm <- mLeft %*% mRight # ok
m.m <- crossprod(mRight)
mm. <- tcrossprod(mLeft, mLeft)
stopifnot(mm == 0,
ident4(mm,
mLeft %*% MRight,
MLeft %*% mRight,
MLeft %*% MRight),# now ok
m.m == 0, identical(m.m, crossprod(mRight, mRight)),
mm. == 0, identical(mm., tcrossprod(mLeft, mLeft)), allow.logical0 = TRUE)
stopifnot(ident4(m.m,
crossprod(MRight, MRight),
crossprod(MRight, mRight),
crossprod(mRight, MRight)))
stopifnot(ident4(mm.,
tcrossprod(mLeft, MLeft),
tcrossprod(MLeft, MLeft),
tcrossprod(MLeft, mLeft)))
}
chkP(mLeft, mRight, MLeft, MRight, "dgeMatrix")
m0 <- mLeft[FALSE,] # 0 x 0
for(cls in c("triangularMatrix", "symmetricMatrix")) {
cat(cls,": "); stopifnotValid(ML0 <- as(MLeft[FALSE,], cls), cls)
chkP(m0, mRight, ML0, MRight, class(ML0))
chkP(mLeft, m0 , MLeft, ML0 , class(ML0))
chkP(m0, m0 , ML0, ML0 , class(ML0)); cat("\n")
}
## New in R 3.2.0 -- for traditional matrix m and vector v
for(spV in c(FALSE,TRUE)) {
cat("sparseV:", spV, "\n")
v <- if(spV) as(1:3, "sparseVector") else 1:3
stopifnot(identical(class(v2 <- v[1:2]), class(v)))
assertError(crossprod(v, v2)) ; assertError(v %*% v2)
assertError(crossprod(v, 1:2)); assertError(v %*% 1:2)
assertError(crossprod(v, 2)) ; assertError(v %*% 2)
assertError(crossprod(1:2, v)); assertError(1:2 %*% v)
cat("doing vec x vec ..\n")
stopifnot(identical(crossprod(2, v), t(2) %*% v),
identical(5 %*% v, 5 %*% t(v)))
for(sp in c(FALSE, TRUE)) {
m <- Matrix(1:2, 1,2, sparse=sp)
cat(sprintf("class(m): '%s'\n", class(m)))
stopifnot(identical( crossprod(m, v), t(m) %*% v), # m'v gave *outer* prod wrongly!
identical(tcrossprod(m, v2), m %*% v2))
assert.EQ.Mat(m %*% v2, m %*% 1:2, tol=0)
}
## gave error "non-conformable arguments"
}
## crossprod(m, v) t(1 x 2) * 3 ==> (2 x 1) * (1 x 3) ==> 2 x 3
## tcrossprod(m,v2) 1 x 2 * 2 ==> (1 x 2) * t(1 x 2) ==> 1 x 1
### ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### Sparse Matrix products
### ------
## solve() for dtC*
mc <- round(chol(crossprod(A)), 2)
B <- A[1:3,] # non-square on purpose
stopifnot(all.equal(sum(rowSums(B %*% mc)), 5.82424475145))
assert.EQ.mat(tcrossprod(B, mc), as.matrix(t(tcrossprod(mc, B))))
m <- kronecker(Diagonal(2), mc)
stopifnot(is(mc, "dtrMatrix"),
is(m, "sparseMatrix"))
im <- solve(m)
round(im, 3)
itm <- solve(t(m))
iim <- solve(im) # should be ~= 'm' of course
iitm <- solve(itm)
I <- Diagonal(nrow(m))
(del <- c(mean(abs(as.numeric(im %*% m - I))),
mean(abs(as.numeric(m %*% im - I))),
mean(abs(as.numeric(im - t(itm)))),
mean(abs(as.numeric( m - iim))),
mean(abs(as.numeric(t(m)- iitm)))))
stopifnot(is(m, "triangularMatrix"), is(m, "sparseMatrix"),
is(im, "dtCMatrix"), is(itm, "dtCMatrix"), is(iitm, "dtCMatrix"),
del < 1e-15)
## crossprod(.,.) & tcrossprod(), mixing dense & sparse
v <- c(0,0,2:0)
mv <- as.matrix(v) ## == cbind(v)
(V <- Matrix(v, 5,1, sparse=TRUE))
sv <- as(v, "sparseVector")
a <- as.matrix(A)
cav <- crossprod(a,v)
tva <- tcrossprod(v,a)
assert.EQ.mat(crossprod(A, V), cav) # gave infinite recursion
assert.EQ.mat(crossprod(A,sv), cav)
assert.EQ.mat(tcrossprod( sv, A), tva)
assert.EQ.mat(tcrossprod(t(V),A), tva)
## [t]crossprod() for . incl. one arg.:
stopifnotValid(s.s <- crossprod(sv,sv), "Matrix")
stopifnotValid(ss. <- tcrossprod(sv,sv), "sparseMatrix")
stopifnot(identical(as(s.s, "symmetricMatrix"), crossprod(sv)),
identical(as(ss., "symmetricMatrix"), tcrossprod(sv)))
assert.EQ.mat(s.s, crossprod(v,v))
assert.EQ.mat(ss., tcrossprod(v,v))
dm <- Matrix(v, sparse=FALSE)
sm <- Matrix(v, sparse=TRUE)
vvt <- tcrossprod(v, v)
validObject(d.vvt <- as(as(vvt, "unpackedMatrix"), "generalMatrix"))
validObject(s.vvt <- as(as(vvt, "CsparseMatrix"), "generalMatrix"))
stopifnot(
identical4(tcrossprod(v, v), tcrossprod(mv, v),
tcrossprod(v,mv), tcrossprod(mv,mv))## (base R)
,
identical4(d.vvt, tcrossprod(dm, v),
tcrossprod(v,dm), tcrossprod(dm,dm)) ## (v, dm) failed
,
identical(s.vvt, tcrossprod(sm,sm))
,
identical3(d.vvt, tcrossprod(sm, v),
tcrossprod(v,sm)) ## both (sm,v) and (v,sm) failed
)
assert.EQ.mat(d.vvt, vvt)
assert.EQ.mat(s.vvt, vvt)
M <- Matrix(0:5, 2,3) ; sM <- as(M, "sparseMatrix"); m <- as(M, "matrix")
v <- 1:3; v2 <- 2:1
sv <- as( v, "sparseVector")
sv2 <- as(v2, "sparseVector")
tvm <- tcrossprod(v, m)
assert.EQ.mat(tcrossprod( v, M), tvm)
assert.EQ.mat(tcrossprod( v,sM), tvm)
assert.EQ.mat(tcrossprod(sv,sM), tvm)
assert.EQ.mat(tcrossprod(sv, M), tvm)
assert.EQ.mat(crossprod(M, sv2), crossprod(m, v2))
stopifnot(identical(tcrossprod(v, M), v %*% t(M)),
identical(tcrossprod(v,sM), v %*% t(sM)),
identical(tcrossprod(v, M), crossprod(v, t(M))),
identical(tcrossprod(sv,sM), sv %*% t(sM)),
identical(crossprod(sM, sv2), t(sM) %*% sv2),
identical(crossprod(M, v2), t(M) %*% v2))
## *unit* triangular :
t1 <- new("dtTMatrix", x= c(3,7), i= 0:1, j=3:2, Dim= as.integer(c(4,4)))
## from 0-diagonal to unit-diagonal {low-level step}:
tu <- t1 ; tu@diag <- "U"
cu <- as(tu, "CsparseMatrix")
cl <- t(cu) # unit lower-triangular
cl10 <- cl %*% Diagonal(4, x=10)
assert.EQ.mat(cl10, as(cl, "matrix") %*% diag(4, x=10))
stopifnot(is(cl,"dtCMatrix"), cl@diag == "U")
(cu2 <- cu %*% cu)
cl2 <- cl %*% cl
validObject(cl2)
cu3 <- tu[-1,-1]
assert.EQ.mat(crossprod(tru, cu3),## <- "FIXME" should return triangular ...
crossprod(trm, as.matrix(cu3)))
cl2
mcu <- as.matrix(cu)
cu2. <- Diagonal(4) + Matrix(c(rep(0,9),14,0,0,6,0,0,0), 4,4)
D4 <- Diagonal(4, x=10:7); d4 <- as(D4, "matrix")
D.D4 <- crossprod(D4); assert.EQ.mat(D.D4, crossprod(d4))
stopifnotValid(D.D4, "ddiMatrix")
stopifnotValid(su <- crossprod(cu), "dsCMatrix")
asGe <- function(x) as(as(x, "unpackedMatrix"), "generalMatrix")
stopifnot(exprs = {
all(cu2 == cu2.)
## was wrong for ver. <= 0.999375-4
identical(D.D4, tcrossprod(D4))
identical4(crossprod(d4, D4), crossprod(D4, d4), tcrossprod(d4, D4), asGe(D.D4))
is(cu2, "dtCMatrix") # triangularity preserved
is(cl2, "dtCMatrix")
cu2@diag == "U" # unit triangularity preserved
cl2@diag == "U"
all.equal(D4 %*% mcu, asGe(D4 %*% cu))
all.equal(mcu %*% D4, asGe(cu %*% D4))
all(D4 %*% su == D4 %*% as.mat(su))
all(su %*% D4 == as.mat(su) %*% D4)
identical(t(cl2), cu2)
## !!
identical(crossprod(mcu, D4), asGe(crossprod(cu, D4)))
identical4(asGe(tcrossprod(cu, D4)), tcrossprod(mcu, D4),
asGe(cu %*% D4), mcu %*% D4)
identical4(asGe(tcrossprod(D4, cu)), tcrossprod(D4,mcu),
asGe(D4 %*% t(cu)), D4 %*% t(mcu))
identical( crossprod(cu), Matrix( crossprod(mcu),sparse=TRUE))
identical(tcrossprod(cu), Matrix(tcrossprod(mcu),sparse=TRUE))
})
assert.EQ.mat( crossprod(cu, D4), crossprod(mcu, d4))
assert.EQ.mat(tcrossprod(cu, D4), tcrossprod(mcu, d4))
tr8 <- kronecker(Matrix(rbind(c(2,0),c(1,4))), cl2)
T8 <- tr8 %*% (tr8/2) # triangularity preserved?
T8.2 <- (T8 %*% T8) / 4
stopifnot(is(T8, "triangularMatrix"), T8@uplo == "L", is(T8.2, "dtCMatrix"))
mr8 <- as(tr8,"matrix")
m8. <- (mr8 %*% mr8 %*% mr8 %*% mr8)/16
assert.EQ.mat(T8.2, m8.)
data(KNex, package = "Matrix")
mm <- KNex$mm
M <- mm[1:500, 1:200]
MT <- as(M, "TsparseMatrix")
cpr <- t(mm) %*% mm
cpr. <- crossprod(mm)
cpr.. <- crossprod(mm, mm)
stopifnot(is(cpr., "symmetricMatrix"),
identical3(cpr, as(cpr., "generalMatrix"), cpr..))
## with dimnames:
m <- Matrix(c(0, 0, 2:0), 3, 5)
dimnames(m) <- list(LETTERS[1:3], letters[1:5])
m
p1 <- t(m) %*% m
(p1. <- crossprod(m))
t1 <- m %*% t(m)
(t1. <- tcrossprod(m))
stopifnot(isSymmetric(p1.),
isSymmetric(t1.),
identical(p1, as(p1., "generalMatrix")),
identical(t1, as(t1., "generalMatrix")),
identical(dimnames(p1), dimnames(p1.)),
identical(dimnames(p1), list(colnames(m), colnames(m))),
identical(dimnames(t1), dimnames(t1.))
)
showMethods("%*%", classes=class(M))
v1 <- rep(1, ncol(M))
str(r <- M %*% Matrix(v1))
str(rT <- MT %*% Matrix(v1))
stopifnot(identical(r, rT))
str(r. <- M %*% as.matrix(v1))
stopifnot(identical4(r, r., rT, M %*% as(v1, "matrix")))
v2 <- rep(1,nrow(M))
r2 <- t(Matrix(v2)) %*% M
r2T <- v2 %*% MT
str(r2. <- v2 %*% M)
stopifnot(identical3(r2, r2., t(as(v2, "matrix")) %*% M))
###------------------------------------------------------------------
### Close to singular matrix W
### (from micEconAids/tests/aids.R ... priceIndex = "S" )
(load(system.file("external", "symW.rda", package="Matrix"))) # "symW"
stopifnot(is(symW, "symmetricMatrix"))
n <- nrow(symW)
I <- .sparseDiagonal(n, shape="g")
S <- as(symW, "matrix")
sis <- solve(S, S)
## solve(, ) when Cholmod fails was buggy for *long*:
o. <- options(Matrix.verbose = 2) # <-- showing Cholmod error & warning now
SIS <- solve(symW, symW)
iw <- solve(symW) ## << TODO: LU *not* saved in @factors
iss <- iw %*% symW
## nb-mm3 openBLAS (Avi A.)
assert.EQ.(I, drop0(sis), tol = 1e-8)# 2.6e-10; 7.96e-9
assert.EQ.(I, SIS, tol = 1e-7)# 8.2e-9
assert.EQ.(I, iss, tol = 4e-4)# 3.3e-5
## solve(, ) :
I <- diag(nrow=n)
SIS <- solve(symW, as(symW,"denseMatrix"))
iw <- solve(symW, I)
iss <- iw %*% symW
assert.EQ.mat(SIS, I, tol = 1e-7, giveRE=TRUE)
assert.EQ.mat(iss, I, tol = 4e-4, giveRE=TRUE)
rm(SIS,iss)
WW <- as(symW, "generalMatrix") # the one that gave problems
IW <- solve(WW)
class(I1 <- IW %*% WW)# "dge" or "dgC" (!)
class(I2 <- WW %*% IW)
## these two were wrong for for M.._1.0-13:
assert.EQ.(as(I1,"matrix"), I, tol = 1e-4)
assert.EQ.(as(I2,"matrix"), I, tol = 7e-7)
## now slightly perturb WW (and hence break exact symmetry
set.seed(131); ii <- sample(length(WW), size= 100)
WW[ii] <- WW[ii] * (1 + 1e-7*runif(100))
SW. <- symmpart(WW)
SW2 <- forceSymmetric(WW)
stopifnot(all.equal(as(SW.,"matrix"),
as(SW2,"matrix"), tolerance = 1e-7))
(ch <- all.equal(WW, as(SW., "generalMatrix"), tolerance = 0))
stopifnot(is.character(ch), length(ch) == 1)## had length(.) 2 previously
IW <- solve(WW) # ( => stores in WW@factors !)
class(I1 <- IW %*% WW)# "dge" or "dgC" (!)
class(I2 <- WW %*% IW)
I <- diag(nrow=nrow(WW))
stopifnot(all.equal(as(I1,"matrix"), I, check.attributes=FALSE, tolerance = 1e-4),
## "Mean relative difference: 3.296549e-05" (or "1.999949" for Matrix_1.0-13 !!!)
all.equal(as(I2,"matrix"), I, check.attributes=FALSE)) #default tol gives "1" for M.._1.0-13
options(o.) # revert to less Matrix.verbose
if(doExtras) {
print(kappa(WW)) ## [1] 5.129463e+12
print(rcond(WW)) ## [1] 6.216103e-14
## Warning message: rcond(.) via sparse -> dense coercion
}
class(Iw. <- solve(SW.))# FIXME? should be "symmetric" but is not
class(Iw2 <- solve(SW2))# FIXME? should be "symmetric" but is not
class(IW. <- as(Iw., "denseMatrix"))
class(IW2 <- as(Iw2, "denseMatrix"))
### The next two were wrong for very long, too
assert.EQ.(I, as.matrix(IW. %*% SW.), tol= 4e-4)
assert.EQ.(I, as.matrix(IW2 %*% SW2), tol= 4e-4)
dIW <- as(IW, "denseMatrix")
assert.EQ.(dIW, IW., tol= 4e-4)
assert.EQ.(dIW, IW2, tol= 8e-4)
##------------------------------------------------------------------
## Sparse Cov.matrices from Harri Kiiveri @ CSIRO
a <- matrix(0,5,5)
a[1,2] <- a[2,3] <- a[3,4] <- a[4,5] <- 1
a <- a + t(a) + 2*diag(5)
b <- as(a, "CsparseMatrix") ## ok, but we recommend to use Matrix() ``almost always'' :
(b. <- Matrix(a, sparse = TRUE))
stopifnot(identical(b, b.))
## calculate conditional variance matrix ( vars 3 4 5 given 1 2 )
(B2 <- b[1:2, 1:2])
bb <- b[1:2, 3:5]
stopifnot(is(B2, "dsCMatrix"), # symmetric indexing keeps symmetry
identical(as.mat(bb), rbind(0, c(1,0,0))),
## TODO: use fully-sparse cholmod_spsolve() based solution :
is(z.s <- solve(B2, bb), "sparseMatrix"))
assert.EQ.mat(B2 %*% z.s, as(bb, "matrix"))
## -> dense RHS and dense result
z. <- solve(as(B2, "generalMatrix"), bb)# now *sparse*
z <- solve( B2, as(bb, "denseMatrix"))
stopifnot(is(z., "sparseMatrix"),
all.equal(z, as(z.,"denseMatrix")))
## finish calculating conditional variance matrix
v <- b[3:5,3:5] - crossprod(bb,z)
stopifnot(all.equal(as.mat(v),
matrix(c(4/3, 1:0, 1,2,1, 0:2), 3), tolerance = 1e-14))
###--- "logical" Matrices : ---------------------
##__ FIXME __ now works for lsparse* and nsparse* but not yet for lge* and nge* !
## Robert's Example, a bit more readable
fromTo <- rbind(c(2,10),
c(3, 9))
N <- 10
nrFT <- nrow(fromTo)
rowi <- rep.int(1:nrFT, fromTo[,2]-fromTo[,1] + 1) - 1:1
coli <- unlist(lapply(1:nrFT, function(x) fromTo[x,1]:fromTo[x,2])) - 1:1
# ## "n" --- nonzero pattern Matrices
chk.ngMatrix <- function(M, verbose = TRUE) {
if(!(is(M, "nsparseMatrix") && length(d <- dim(M)) == 2 && d[1] == d[2]))
stop("'M' must be a square sparse [patter]n Matrix")
if(verbose)
show(M)
m <- as(M, "matrix")
## Part I : matrix products of pattern Matrices
## ------ For now [by default]: *pattern* <==> boolean arithmetic
## ==> FIXME ??: warning that this will change?
MM <- M %*% M # numeric (dgC)
if(verbose) { cat("M %*% M:\n"); show(MM) }
assert.EQ.mat(MM, m %*% m)
assert.EQ.mat(t(M) %&% M,
(t(m) %*% m) > 0, tol=0)
cM <- crossprod(M) # pattern {FIXME ?? warning ...}
tM <- tcrossprod(M) # pattern {FIXME ?? warning ...}
if(verbose) {cat( "crossprod(M):\n"); show(cM) }
if(verbose) {cat("tcrossprod(M):\n"); show(tM) }
stopifnot(is(cM,"symmetricMatrix"), is(tM,"symmetricMatrix"),
identical(as(as(cM, "CsparseMatrix"), "generalMatrix"),
t(M) %&% M),
identical(as(as(tM, "CsparseMatrix"), "generalMatrix"),
M %&% t(M)))
assert.EQ.mat(cM, crossprod(m) > 0)
assert.EQ.mat(tM, as(tcrossprod(m), "matrix") > 0)
## Part II : matrix products pattern Matrices with numeric:
##
## "n" x "d" (and "d" x "n") --> "d", i.e. numeric in any case
dM <- as(M, "dMatrix")
stopifnot(exprs = {
## dense ones:
identical(M %*% m, m %*% M -> Mm)
## sparse ones :
identical3(M %*% dM, dM %*% M -> sMM,
eval(Matrix:::.as.via.virtual(
"matrix", class(sMM), quote(m %*% m))))
})
if(verbose) {cat( "M %*% m:\n"); show(Mm) }
stopifnotValid(Mm, "dMatrix") # not "n.."
stopifnotValid(sMM, "dMatrix") # not "n.."
stopifnotValid(cdM <- crossprod(dM, M), "CsparseMatrix")
stopifnotValid(tdM <- tcrossprod(dM, M), "CsparseMatrix")
assert.EQ.mat (cdM, crossprod(m))
assert.EQ.mat (tdM, tcrossprod(m))
stopifnot(identical( crossprod(dM), as(cdM, "symmetricMatrix")))
stopifnot(identical(tcrossprod(dM), as(tdM, "symmetricMatrix")))
invisible(TRUE)
}
sM <- new("ngTMatrix", i = rowi, j=coli, Dim=as.integer(c(N,N)))
chk.ngMatrix(sM) # "ngTMatrix"
chk.ngMatrix(tsM <- as(sM, "triangularMatrix")) # ntT
chk.ngMatrix(as( sM, "CsparseMatrix")) # ngC
chk.ngMatrix(as(tsM, "CsparseMatrix")) # ntC
## "l" --- logical Matrices -- use usual 0/1 arithmetic
nsM <- sM
sM <- as(sM, "lMatrix")
sm <- as(sM, "matrix")
stopifnot(identical(sm, as.matrix(nsM)))
stopifnotValid(sMM <- sM %*% sM, "dsparseMatrix")
assert.EQ.mat (sMM, sm %*% sm)
assert.EQ.mat(t(sM) %*% sM,
t(sm) %*% sm, tol=0)
stopifnotValid(cM <- crossprod(sM), "dsCMatrix")
stopifnotValid(tM <- tcrossprod(sM), "dsCMatrix")
stopifnot(identical(cM, as(t(sM) %*% sM, "symmetricMatrix")),
identical(tM, forceSymmetric(sM %*% t(sM))))
assert.EQ.mat( cM, crossprod(sm))
assert.EQ.mat( tM, as(tcrossprod(sm),"matrix"))
dm <- as(sM, "denseMatrix")
## the following 6 products (dm o sM) all failed up to 2013-09-03
stopifnotValid(dm %*% sM, "denseMatrix")## failed {missing coercion}
stopifnotValid(crossprod (dm , sM),"denseMatrix")
stopifnotValid(tcrossprod(dm , sM),"denseMatrix")
dm[2,1] <- TRUE # no longer triangular
stopifnotValid( dm %*% sM, "denseMatrix")
stopifnotValid(crossprod (dm , sM),"denseMatrix")
stopifnotValid(tcrossprod(dm , sM),"denseMatrix")
## A sparse example - with *integer* matrix:
M <- Matrix(cbind(c(1,0,-2,0,0,0,0,0,2.2,0),
c(2,0,0,1,0), 0, 0, c(0,0,8,0,0),0))
t(M)
(-4:5) %*% M
stopifnot(as.vector(print(t(M %*% 1:6))) ==
c(as(M,"matrix") %*% 1:6))
(M.M <- crossprod(M))
MM. <- tcrossprod(M)
stopifnot(class(MM.) == "dsCMatrix",
class(M.M) == "dsCMatrix")
M3 <- Matrix(c(rep(c(2,0),4),3), 3,3, sparse=TRUE)
I3 <- as(Diagonal(3), "CsparseMatrix")
m3 <- as.matrix(M3)
iM3 <- solve(m3)
stopifnot(all.equal(unname(iM3), matrix(c(3/2,0,-1,0,1/2,0,-1,0,1), 3)))
assert.EQ.mat(solve(as(M3, "sparseMatrix")), iM3)
assert.EQ.mat(solve(I3,I3), diag(3))
assert.EQ.mat(solve(M3, I3), iM3)# was wrong because I3 is unit-diagonal
assert.EQ.mat(solve(m3, I3), iM3)# gave infinite recursion in (<=) 0.999375-10
stopifnot(identical(ttI3 <- crossprod(tru, I3), t(tru) %*% I3),
identical(tI3t <- crossprod(I3, tru), t(I3) %*% tru),
identical(I3tt <- tcrossprod(I3, tru), I3 %*% t(tru)))
I3@uplo # U pper triangular
tru@uplo# L ower triangular
## "FIXME": These are all FALSE now; the first one *is* ok (L o U); the others *not*
isValid(tru %*% I3, "triangularMatrix")
isValid(ttI3, "triangularMatrix")
isValid(tI3t, "triangularMatrix")
isValid(I3tt, "triangularMatrix")
## even simpler
m <- matrix(0, 4,7); m[c(1, 3, 6, 9, 11, 22, 27)] <- 1
(mm <- Matrix(m))
(cm <- Matrix(crossprod(m)))
stopifnot(identical(crossprod(mm), cm))
(tm1 <- Matrix(tcrossprod(m))) #-> had bug in 'Matrix()' !
(tm2 <- tcrossprod(mm))
Im2 <- solve(tm2[-4,-4])
P <- as(as.integer(c(4,1,3,2)),"pMatrix")
p <- as(P, "matrix")
P %*% mm
assertError(mm %*% P) # dimension mismatch
assertError(m %*% P) # ditto
assertError(crossprod(t(mm), P)) # ditto
stopifnotValid(tm1, "dsCMatrix")
stopifnot(exprs = {
all.equal(tm1, tm2, tolerance = 1e-15)
all.equal(Im2 %*% tm2[1:3,], Matrix(cbind(diag(3), 0)))
identical(p, as.matrix(P))
all(P %*% m == as.matrix(P) %*% m)
all(P %*% mm == P %*% m)
all(P %*% mm - P %*% m == 0)
all(t(mm) %*% P == t(m) %*% P)
all(crossprod(m, P) == crossprod(mm, P))
})
d <- function(m) as(m,"dsparseMatrix")
IM1 <- as(c(3,1,2), "indMatrix")
IM2 <- as(c(1,2,1), "indMatrix")
assert.EQ.Mat(crossprod( IM1, IM2),
crossprod(d(IM1),d(IM2)), tol=0)# failed at first
iM <- as(cbind2(IM2, 0), "indMatrix")
assert.EQ.Mat(crossprod(iM), Diagonal(x = 2:0))
assert.EQ.Mat(crossprod(iM, iM), Diagonal(x = 2:0))
N3 <- Diagonal(x=1:3)
U3 <- Diagonal(3) # unit diagonal (@diag = "U")
C3 <- as(N3, "CsparseMatrix")
lM <- as(IM2, "lMatrix")
nM <- as(IM2, "nMatrix")
nCM <- as(nM, "CsparseMatrix")
NM <- N3 %*% IM2
NM. <- C3 %*% IM2
stopifnot(Q.C.identical(NM, ## <- failed
d(N3) %*% d(IM2), checkClass=FALSE),
identical(NM, N3 %*% lM),
identical(NM, N3 %*% nM)
, ## all these "work" (but partly wrongly gave non-numeric Matrix:
Q.C.identical(NM, NM., checkClass=FALSE)
,
mQidentical(as.matrix(NM.), array(c(1, 0, 3, 0, 2, 0), dim=3:2))
,
identical(NM., C3 %*% lM)
,
identical(NM., C3 %*% nM) # wrongly gave n*Matrix
,
isValid(U3 %*% IM2, "dsparseMatrix")# was l*
,
isValid(U3 %*% lM, "dsparseMatrix")# was l*
,
isValid(U3 %*% nM, "dsparseMatrix")# was n*
,
identical(C3 %*% nM -> C3n, # wrongly gave ngCMatrix
C3 %*% nCM)
,
isValid(C3n, "dgCMatrix")
,
identical3(U3 %*% IM2, # wrongly gave lgTMatrix
U3 %*% lM -> U3l, # ditto
U3 %*% nM) # wrongly gave ngTMatrix
,
isValid(U3l, "dgRMatrix")
)
selectMethod("%*%", c("dtCMatrix", "ngTMatrix")) # x %*% .T.2.C(y) -->
selectMethod("%*%", c("dtCMatrix", "ngCMatrix")) # .Call(Csparse_Csparse_prod, x, y)
selectMethod("%*%", c("ddiMatrix", "indMatrix")) # x %*% as(y, "lMatrix") ->
selectMethod("%*%", c("ddiMatrix", "lgTMatrix")) # diagCspprod(as(x, "Csp.."), y)
selectMethod("%*%", c("ddiMatrix", "ngTMatrix")) # (ditto)
stopifnot(
isValid(show(crossprod(C3, nM)), "dgCMatrix"), # wrongly gave ngCMatrix
identical3(## the next 4 should give the same (since C3 and U3 are symmetric):
show(crossprod(U3, IM2)),# wrongly gave ngCMatrix
crossprod(U3, nM), # ditto
crossprod(U3, lM))) # wrongly gave lgCMatrix
set.seed(123)
for(n in 1:250) {
n1 <- 2 + rpois(1, 10)
n2 <- 2 + rpois(1, 10)
N <- rpois(1, 25)
ii <- seq_len(N + min(n1,n2))
IM1 <- as(c(sample(n1), sample(n1, N, replace=TRUE))[ii], "indMatrix")
IM2 <- as(c(sample(n2), sample(n2, N, replace=TRUE))[ii], "indMatrix")
## stopifnot(identical(crossprod( IM1, IM2),
## crossprod(d(IM1), d(IM2))))
if(!identical(C1 <- crossprod( IM1, IM2 ),
CC <- crossprod(d(IM1), d(IM2))) &&
!all(C1 == CC)) {
cat("The two crossprod()s differ: C1 - CC =\n")
print(C1 - CC)
stop("The two crossprod()s differ!")
} else if(n %% 25 == 0) cat(n, " ")
}; cat("\n")
## two with an empty column --- these failed till 2014-06-14
X <- as(c(1,3,4,5,3), "indMatrix")
Y <- as(c(2,3,4,2,2), "indMatrix")
## kronecker:
stopifnot(identical(X %x% Y,
as(as.matrix(X) %x% as.matrix(Y), "indMatrix")))
## crossprod:
(XtY <- crossprod(X, Y))# gave warning in Matrix 1.1-3
XtY_ok <- as(crossprod(as.matrix(X), as.matrix(Y)), "TsparseMatrix")
assert.EQ.Mat(XtY, XtY_ok) # not true, previously
###------- %&% -------- Boolean Arithmetic Matrix products
x5 <- c(2,0,0,1,4)
D5 <- Diagonal(x=x5)
N5 <- as(D5 != 0, "nMatrix") ## an "ndiMatrix"
D. <- Diagonal(x=c(TRUE,FALSE,TRUE,TRUE,TRUE))
stopifnot(identical(D5 %&% D., N5))
stopifnot(identical(D5 %&% as(D.,"CsparseMatrix"),
as(N5,"CsparseMatrix")))
set.seed(7)
L <- Matrix(rnorm(20) > 1, 4,5)
(N <- as(L, "nMatrix"))
D <- Matrix(round(rnorm(30)), 5,6) # "dge", values in -1:1 (for this seed)
L %&% D
stopifnot(identical(L %&% D, N %&% D),
all(L %&% D == as((L %*% abs(D)) > 0, "sparseMatrix")))
stopifnotValid(show(crossprod(N )) , "nsCMatrix") # (TRUE/FALSE : boolean arithmetic)
stopifnotValid(show(crossprod(N +0)) -> cN0, "dsCMatrix") # -> numeric Matrix (with same "pattern")
stopifnot(all(crossprod(N) == t(N) %&% N),
identical(crossprod(N, boolArith=TRUE) -> cN.,
as(cN0 != 0, "nMatrix")),
identical (cN., crossprod(L, boolArith=TRUE)),
identical3(cN0, crossprod(L), crossprod(L, boolArith=FALSE))
)
stopifnotValid(cD <- crossprod(D, boolArith = TRUE), "nsCMatrix") # sparse: "for now"
## another slightly differing test "series"
L.L <- crossprod(L)
(NN <- as(L.L > 0,"nMatrix"))
nsy <- as(NN,"denseMatrix")
stopifnot(identical(NN, crossprod(NN)))# here
stopifnotValid(csy <- crossprod(nsy), "nsCMatrix")
stopifnotValid(csy. <- crossprod(nsy, boolArith=TRUE),"nsCMatrix")
stopifnot(all((csy > 0) == csy.),
all(csy. == (nsy %&% nsy)))
## for "many" more seeds:
set.seed(7); for(nn in 1:256) {
L <- Matrix(rnorm(20) > 1, 4,5)
D <- Matrix(round(rnorm(30)), 5,6)
stopifnot(all(L %&% D == as((L %*% abs(D)) > 0, "sparseMatrix")))
}
## [Diagonal] o [0-rows/colums] :
m20 <- matrix(nrow = 2, ncol = 0); m02 <- t(m20)
M20 <- Matrix(nrow = 2, ncol = 0); M02 <- t(M20)
stopifnot(identical(dim(Diagonal(x=c(1,2)) %*% m20), c(2L, 0L)),
identical(dim(Diagonal(2) %*% M20), c(2L, 0L)),
identical(dim(Diagonal(x=2:1) %*% M20), c(2L, 0L)))
stopifnot(identical(dim(m02 %*% Diagonal(x=c(1,2))), c(0L, 2L)),
identical(dim(M02 %*% Diagonal(2) ), c(0L, 2L)),
identical(dim(M02 %*% Diagonal(x=2:1) ), c(0L, 2L)))
## RsparseMatrix --- Arko Bose (Jan.2022): "Method for %*% "
(m <- Matrix(c(0,0,2:0), 3,5))
stopifnotValid(R <- as(m, "RsparseMatrix"), "RsparseMatrix")
stopifnotValid(T <- as(m, "TsparseMatrix"), "TsparseMatrix")
stopifnot(exprs = {
all.equal(as(t(R) %*% R, "symmetricMatrix"), crossprod(R) -> cR)
all.equal(as(R %*% t(R), "symmetricMatrix"), tcrossprod(R) -> tR)
all.equal(as(R %*% t(m), "symmetricMatrix"), as(tcrossprod(m), "RsparseMatrix"))
all.equal(as(m %*% t(R), "symmetricMatrix"), as(tcrossprod(m), "CsparseMatrix"))
## failed in Matrix <= 1.4.1 (since 1.2.0, when 'boolArith' was introduced):
all.equal(as(cR, "RsparseMatrix"), as( crossprod(R, T), "symmetricMatrix"))
all.equal(as(cR, "CsparseMatrix"), as( crossprod(T, R), "symmetricMatrix"))
all.equal(as(tR, "RsparseMatrix"), as(tcrossprod(R, T), "symmetricMatrix"))
all.equal(as(tR, "CsparseMatrix"), as(tcrossprod(T, R), "symmetricMatrix"))
})
## More for kronecker() ------------------------------------------------
checkKronecker <- function(X, Y, ...) {
k1 <- as(k0 <- kronecker(X, Y, ...), "matrix")
k2 <- kronecker(as(X, "matrix"), as(Y, "matrix"), ...)
cldX <- getClassDef(class(X))
cldY <- getClassDef(class(Y))
if(extends(cldX, "indMatrix") &&
extends(cldY, "indMatrix")) {
stopifnot(is(k0, "indMatrix"))
storage.mode(k2) <- "logical"
}
if(extends(cldX, "triangularMatrix") &&
extends(cldY, "triangularMatrix") && X@uplo == Y@uplo)
stopifnot(is(k0, "triangularMatrix"),
k0@uplo == X@uplo,
k0@diag == (if(X@diag == "N" || Y@diag == "N") "N" else "U"))
else if(extends(cldX, "symmetricMatrix") &&
extends(cldY, "symmetricMatrix"))
stopifnot(is(k0, "symmetricMatrix"), k0@uplo == X@uplo)
## could test for more special cases
if(!isTRUE(ae <- all.equal(k1, k2)))
stop(sprintf("checkKronecker(<%s>, <%s>):\n %s",
class(X), class(Y), paste0(ae, collapse = "\n ")))
}
set.seed(145133)
lXY <- lapply(rpois(2L, 10),
function(n) {
x <- rsparsematrix(n, n, 0.6)
dn <- replicate(2L, if(sample(c(FALSE, TRUE), 1L))
sample(letters, n, TRUE),
simplify = FALSE)
x@Dimnames <- dn
x4 <- list(as(as(x, "dMatrix"), "denseMatrix"),
as(as(x, "dMatrix"), "CsparseMatrix"),
as(as(x, "lMatrix"), "RsparseMatrix"),
as(as(x, "nMatrix"), "TsparseMatrix"))
mkList <- function(y)
list(x,
triu(x),
tril(x),
{ z <- triu(x, 1L); z@diag <- "U"; z },
{ z <- tril(x, -1L); z@diag <- "U"; z },
forceSymmetric(x, "U"),
forceSymmetric(x, "L"),
{ z <- Diagonal(x = diag(x)); z@Dimnames <- dn; z },
as(sample.int(n, replace = TRUE), "indMatrix"),
as(x, "matrix"))
unlist(lapply(x4, mkList), FALSE, FALSE)
})
lX <- lXY[[1L]]
lY <- lXY[[2L]]
for(i in seq_along(lX))
for(j in seq_along(lY))
checkKronecker(lX[[i]], lY[[j]], make.dimnames = TRUE)
cat('Time elapsed: ', proc.time(),'\n') # for ``statistical reasons''
Matrix/tests/bind.R 0000644 0001751 0000144 00000020076 14470702707 013752 0 ustar hornik users #### Testing cbind() & rbind() -- based on cbind2() & rbind2()
## (where using 'cBind()' and 'rBind()' in Matrix)
## for R_DEFAULT_PACKAGES=NULL :
library(utils)
library(Matrix)
source(system.file("test-tools.R", package = "Matrix"))# identical3() etc
### --- Dense Matrices ---
m1 <- m2 <- m <- matrix(1:12, 3,4)
dimnames(m2) <- list(LETTERS[1:3],
letters[1:4])
dimnames(m1) <- list(NULL,letters[1:4])
M <- Matrix(m)
M1 <- Matrix(m1)
M2 <- Matrix(m2)
stopifnot(
identical3(cbind ( M, 10*M),
show(cbind2( M, 10*M)),
Matrix(cbind ( m, 10*m)))
,
identical3(cbind (M1, 100+M1),
show(cbind2(M1, 100+M1)),
Matrix(cbind (m1, 100+m1)))
,
identical3(cbind (M1, 10*M2),
show(cbind2(M1, 10*M2)),
Matrix(cbind (m1, 10*m2)))
,
identical3(cbind (M2, M1+M2),
show(cbind2(M2, M1+M2)),
Matrix(cbind (m2, m1+m2)))
,
identical(colnames(show(cbind(M1, MM = -1))),
c(colnames(M1), "MM"))
,
identical3(rbind ( M, 10*M),
show(rbind2( M, 10*M)),
Matrix(rbind ( m, 10*m)))
,
identical3(rbind (M2, M1+M2),
show(rbind2(M2, M1+M2)),
Matrix(rbind (m2, m1+m2)))
,
Qidentical(show (rbind(R1 = 10:11, M1)),
Matrix(rbind(R1 = 10:11, m1)), strictClass=FALSE)
, TRUE)
identical.or.eq <- function(x,y, tol=0, ...) {
if(identical(x,y, ...))
TRUE
else if(isTRUE(aeq <- all.equal(x,y, tolerance = tol)))
structure(TRUE, comment = "not identical")
else aeq
}
identicalShow <- function(x,y, ...)
if(!isTRUE(id <- identical.or.eq(x, y, ...))) cat(id,"\n")
## Checking deparse.level { <==> example at end of ?cbind }:
checkRN <- function(dd, B = rbind) {
FN <- function(deparse.level)
rownames(B(1:4, c=2,"a+"=10, dd, deparse.level=deparse.level))
rn <- c("1:4", "c", "a+", "dd", "")
isMatr <- (length(dim(dd)) == 2)
id <- if(isMatr) 5 else 4
identicalShow(rn[c(5,2:3, 5)], FN(deparse.level= 0)) # middle two names
identicalShow(rn[c(5,2:3,id)], FN(deparse.level= 1)) # last shown if vector
identicalShow(rn[c(1,2:3,id)], FN(deparse.level= 2)) # first shown; (last if vec.)
}
checkRN(10) # <==> ?cbind's ex
checkRN(1:4)
checkRN( rbind(c(0:1,0,0)))
checkRN(Matrix(rbind(c(0:1,0,0)))) ## in R <= 3.4.1, from methods:::rbind bug :
## Modes: character, NULL Lengths: 4, 0 target is character, current is NULL
checkRN(10 , rbind)
checkRN(1:4, rbind)
checkRN( rbind(c(0:1,0,0)), rbind)
checkRN(Matrix(rbind(c(0:1,0,0))), rbind)
cbind(0, Matrix(0+0:1, 1,2), 3:2)# FIXME? should warn - as with matrix()
as(rbind(0, Matrix(0+0:1, 1,2), 3:2),
"sparseMatrix")
cbind(M2, 10*M2[nrow(M2):1 ,])# keeps the rownames from the first
(im <- cbind(I = 100, M))
str(im)
(mi <- cbind(M2, I = 1000))
str(mi)
(m1m <- cbind(M,I=100,M2))
showProc.time()
## lgeMatrix -- rbind2() had bug (in C code):
is.lge <- function(M) isValid(M, "lgeMatrix")
stopifnot(exprs = {
is.lge(rbind(M2 > 0, M2 < 0)) # had Error in rbind2():
## REAL() can only be applied to a 'numeric', not a 'logical'
is.lge(rbind(M2 < 0, M2 > 0)) # ditto
is.lge(rbind(Matrix(1:6 %% 3 != 0, 2,3), FALSE))
is.lge(L <- rbind(Matrix(TRUE, 2,3), TRUE))
all(L)
is.lge(rbind(Matrix(TRUE, 2,3), FALSE))
})
### --- Diagonal / Sparse - had bugs
D4 <- Diagonal(4)
(D4T <- as(D4, "TsparseMatrix"))
D4C <- as(D4T, "CsparseMatrix")
c1 <- Matrix(0+0:3, 4, sparse=TRUE) ; r1 <- t(c1); r1
d4 <- rbind(Diagonal(4), 0:3)
m4 <- cbind(Diagonal(x=-1:2), 0:3)
c4. <- cbind(Diagonal(4), c1)
c.4 <- cbind(c1, Diagonal(4))
r4. <- rbind(Diagonal(4), r1)
r.4 <- rbind(r1, Diagonal(4))
assert.EQ.mat(d4, rbind(diag(4), 0:3))
assert.EQ.mat(m4, cbind(diag(-1:2), 0:3))
stopifnot(identical(Matrix(cbind(diag(3),0)), cbind2(Diagonal(3),0)),
is(d4, "sparseMatrix"), is(m4, "sparseMatrix"),
identical(.tCRT(d4), cbind(Diagonal(4), 0:3)),
identical(.tCRT(m4), rbind(Diagonal(x=-1:2), 0:3)))
showProc.time()
### --- Sparse Matrices ---
identical4(cbind(diag(4), diag(4)),
cbind(D4C, D4C),
cbind(D4T, D4C),
cbind(D4C, D4T))
nr <- 4
nc <- 6
m. <- matrix(rep_len(c(0, 2:-1), nr * nc), nr, nc)
M <- Matrix(m.)
(mC <- as(M, "CsparseMatrix"))
(mT <- as(M, "TsparseMatrix"))
stopifnot(identical(mT, as(mC, "TsparseMatrix")),
identical(mC, as(mT, "CsparseMatrix")))
for(v in list(0, 2, 1:0))
for(fnam in c("cbind", "rbind")) {
cat(fnam,"(m, v=", deparse(v),"), class(m) :")
FUN <- get(fnam)
for(m in list(M, mC, mT)) {
cat("", class(m),"")
assert.EQ.mat(FUN(v, m), FUN(v, m.)) ; cat(",")
assert.EQ.mat(FUN(m, v), FUN(m., v)) ; cat(".")
}
cat("\n")
}
showProc.time()
cbind(0, mC); cbind(mC, 0)
cbind(0, mT); cbind(mT, 2)
cbind(diag(nr), mT)
stopifnot(identical(t(cbind(diag(nr), mT)),
rbind(diag(nr), t(mT))))
(cc <- cbind(mC, 0,7,0, diag(nr), 0))
stopifnot(identical3(cc,
as(cbind(mT, 0, 7, 0, diag(nr), 0), "CsparseMatrix"),
as(cbind( M, 0, 7, 0, diag(nr), 0), "CsparseMatrix")))
cbind(mC, 1, 100*mC, 0, 0:2)
cbind(mT, 1, 0, mT+10*mT, 0, 0:2)
one <- 1
zero <- 0
dimnames(mC) <- dimnames(mT) <- list(LETTERS[1:4], letters[1:6])
op <- options(sparse.colnames = TRUE)# show colnames in print :
cbind(mC, one, 100*mC, zero, 0:2)
cbind(mC, one, 100*mC, zero, 0:2, deparse.level=0)# no "zero", "one"
cbind(mC, one, 100*mC, zero, 0:2, deparse.level=2)# even "0:2"
cbind(mT, one, zero, mT+10*mT, zero, 0:2)
## logical (sparse) - should remain logical :
L5 <- Diagonal(n = 5, x = TRUE)
v5 <- rep(x = c(FALSE,TRUE), length.out = ncol(L5))
stopifnot(is(show(rbind(L5,v5)), "lsparseMatrix"),
is(show(cbind(v5,L5)), "lsparseMatrix"),
is(rbind(L5, 2* v5), "dsparseMatrix"),
is(cbind(2* v5, L5), "dsparseMatrix"))
## print() / show() of non-structural zeros:
(m <- Matrix(c(0, 0, 2:0), 3, 5))
(m2 <- cbind(m,m))
(m4 <- rbind(m2,m2))
diag(m4)
for(i in 1:6) {
m4[i, i ] <- i
m4[i,i+1] <- 0
}
m4 ## now show some non-structural zeros:
## Mixture of dense and sparse/diagonal -- used to fail, even in 1.0-0
D5 <- Diagonal(x = 10*(1:5))
(D5.1 <- cbind2(D5, 1))
## "FIXME" in newer versions of R, do not need Matrix() here:
s42 <- Matrix(z42 <- cbind2(rep(0:1,4), rep(1:0,4)),
sparse=TRUE)
(C86 <- rbind(1, 0, D5.1, 0))
stopifnotValid(D5.1, "dgCMatrix")
stopifnotValid(print(rbind2(Matrix(1:10, 2,5), D5)), "dgRMatrix")
stopifnotValid(print(cbind2(Matrix(10:1, 5,2), D5.1)), "dgCMatrix")
stopifnotValid(zz <- cbind2(z42, C86), "dgCMatrix")
stopifnot(identical(zz, cbind2(s42, C86)))
## Using "nMatrix"
(m1 <- sparseMatrix(1:3, 1:3)) # ngCMatrix
m2 <- sparseMatrix(1:3, 1:3, x = 1:3)
stopifnotValid(c12 <- cbind(m1,m2), "dgCMatrix") # was "ngC.." because of cholmod_horzcat !
stopifnotValid(c21 <- cbind(m2,m1), "dgCMatrix") # ditto
stopifnotValid(r12 <- rbind(m1,m2), "dgCMatrix") # was "ngC.." because of cholmod_vertcat !
stopifnotValid(r21 <- rbind(m2,m1), "dgCMatrix") # ditto
d1 <- as(m1, "denseMatrix")
d2 <- as(m2, "denseMatrix")
stopifnotValid(cbind2(d2,d1), "dgeMatrix")
stopifnotValid(cbind2(d1,d2), "dgeMatrix")## gave an error in Matrix 1.1-5
stopifnotValid(rbind2(d2,d1), "dgeMatrix")
stopifnotValid(rbind2(d1,d2), "dgeMatrix")## gave an error in Matrix 1.1-5
## rbind2() / cbind2() mixing sparse/dense: used to "fail",
## ------------------- then (in 'devel', ~ 2015-03): completely wrong
S <- .sparseDiagonal(2)
s <- diag(2)
S9 <- rbind(S,0,0,S,0,NaN,0,0,0,2)## r/cbind2() failed to determine 'sparse' in Matrix <= 1.2-2
s9 <- rbind(s,0,0,s,0,NaN,0,0,0,2)
assert.EQ.mat(S9, s9)
D <- Matrix(1:6, 3,2); d <- as(D, "matrix")
T9 <- t(S9); t9 <- t(s9); T <- t(D); t <- t(d)
stopifnot(identical(rbind (s9,d), rbind2(s9,d)),
identical(rbind2(D,S9), t(cbind2(T,T9))),
identical(rbind2(S9,D), t(cbind2(T9,T))))
assert.EQ.mat(rbind2(S9,D), rbind2(s9,d))
assert.EQ.mat(rbind2(D,S9), rbind2(d,s9))
## now with cbind2() -- no problem!
stopifnot(identical(cbind (t9,t), cbind2(t9,t)))
assert.EQ.mat(cbind2(T9,T), cbind2(t9,t))
assert.EQ.mat(cbind2(T,T9), cbind2(t,t9))
options(op)
showProc.time()
Matrix/tests/packed-unpacked.R 0000644 0001751 0000144 00000031373 14565737512 016066 0 ustar hornik users ## These are tests related to the replacement of many methods for the
## proper subclasses of 'denseMatrix' with methods for the (new, more
## general) virtual subclasses '(un)?packedMatrix'.
## for R_DEFAULT_PACKAGES=NULL :
library(stats)
library(Matrix)
set.seed(145206)
if (interactive()) {
options(Matrix.verbose = TRUE, warn = 1, error = recover)
} else {
options(Matrix.verbose = TRUE, warn = 1)
}
U <- function(x, diag = FALSE) x[upper.tri(x, diag)]
L <- function(x, diag = FALSE) x[lower.tri(x, diag)]
`U<-` <- function(x, diag = FALSE, value) { x[upper.tri(x, diag)] <- value; x }
`L<-` <- function(x, diag = FALSE, value) { x[lower.tri(x, diag)] <- value; x }
mkDN <- function(Dim) list(A = paste0("a", seq_len(Dim[1L])),
B = paste0("b", seq_len(Dim[2L])))
denseMatrix <- getClassDef("denseMatrix")
packedMatrix <- getClassDef("packedMatrix")
unpackedMatrix <- getClassDef("unpackedMatrix")
generalMatrix <- getClassDef("generalMatrix")
symmetricMatrix <- getClassDef("symmetricMatrix")
triangularMatrix <- getClassDef("triangularMatrix")
dMatrix <- getClassDef("dMatrix")
lMatrix <- getClassDef("lMatrix")
nMatrix <- getClassDef("nMatrix")
## FIXME: Implement in C??
unpackedClass <- function(packedClass) {
getClassDef(c(dspMatrix = "dsyMatrix",
lspMatrix = "lsyMatrix",
nspMatrix = "nsyMatrix",
dtpMatrix = "dtrMatrix",
ltpMatrix = "ltrMatrix",
ntpMatrix = "ntrMatrix",
dppMatrix = "dpoMatrix",
copMatrix = "corMatrix")[[packedClass@className]])
}
packedClass <- function(unpackedClass) {
getClassDef(c(dgeMatrix = NA,
lgeMatrix = NA,
ngeMatrix = NA,
dsyMatrix = "dspMatrix",
lsyMatrix = "lspMatrix",
nsyMatrix = "nspMatrix",
dtrMatrix = "dtpMatrix",
ltrMatrix = "ltpMatrix",
ntrMatrix = "ntpMatrix",
dpoMatrix = "dppMatrix",
corMatrix = "copMatrix")[[unpackedClass@className]])
}
...Class <- function(denseClass) {
cl <- "...Matrix"
substr(cl, 1L, 1L) <-
if (d <- extends(denseClass, dMatrix))
"d"
else if (extends(denseClass, lMatrix))
"l"
else
"n"
substr(cl, 2L, 3L) <-
if (g <- extends(denseClass, generalMatrix))
"ge"
else if (extends(denseClass, symmetricMatrix))
"sy"
else
"tr"
if (!g && extends(denseClass, packedMatrix)) {
substr(cl, 3L, 3L) <- "p"
}
getClassDef(cl)
}
## Tests methods for packed (unpacked) class 'Class'
## using randomly generated matrices of size 'n'
testDenseClass <- function(Class, n) {
if (!is(Class, "classRepresentation")) {
Class <- getClassDef(Class)
}
stopifnot(extends(Class, denseMatrix), !isVirtualClass(Class))
is.p <- extends(Class, packedMatrix)
is.ge <- extends(Class, generalMatrix)
is.sy <- !is.ge && extends(Class, symmetricMatrix)
is.tr <- !is.ge && !is.sy
is.d <- extends(Class, dMatrix)
is.l <- !is.d && extends(Class, lMatrix)
is.n <- !is.d && !is.l
## For randomly generating matrix data
.mkX <- if (is.d)
function(n) rlnorm(n) # not rnorm(n), for validObject()
else
function(n) sample(c(NA, FALSE, TRUE), n, TRUE)
mkX <- if (is.p)
function(Dim) .mkX((Dim[1L] * (Dim[1L] + 1L)) %/% 2L)
else
function(Dim) .mkX(prod(Dim))
## "Full factorial" design with varying 'Dim', 'uplo', 'diag' slots
.Dim <- c(list(c(n, n)), if (is.ge) list(c(n+1L, n), c(n, n+1L)))
.a <- c(list(Dim = seq_along(.Dim)),
if (!is.ge) list(uplo = c("U", "L")),
if ( is.tr) list(diag = c("N", "U")),
list(stringsAsFactors = FALSE))
newargs <- do.call(expand.grid, .a)
newargs[["Dim"]] <- .Dim[.i <- newargs[["Dim"]]]
newargs[["Dimnames"]] <- lapply(.Dim, mkDN)[.i]
newargs[["x"]] <- lapply(.Dim, mkX)[.i]
if (is.sy) {
iD <- Matrix:::indDiag
if (extends(Class, "corMatrix"))
newargs[["x"]] <-
lapply(newargs[["x"]], replace, iD(n), 1)
else if (extends(Class, "copMatrix"))
newargs[["x"]] <-
Map(function(x, upper) replace(x, iD(n, upper, TRUE), 1),
newargs[["x"]], newargs[["uplo"]] == "U")
}
## Test the matrices generated by each set of arguments to 'new'
all(unlist(.mapply(testDenseMatrix, newargs, list(Class = Class))))
}
testDenseMatrix <- function(Class, ...) {
is.p <- extends(Class, packedMatrix)
is.ge <- extends(Class, generalMatrix)
is.sy <- !is.ge && extends(Class, symmetricMatrix)
is.tr <- !is.ge && !is.sy
is.d <- extends(Class, dMatrix)
is.l <- !is.d && extends(Class, lMatrix)
is.n <- !is.d && !is.l
## This class needs special care because it has an additional 'sd' slot
is.cr <- is.sy &&
(extends(Class, "corMatrix") || extends(Class, "copMatrix"))
newargs <- list(Class = Class, ...)
if (is.cr)
newargs[["sd"]] <- rep.int(1, newargs[["Dim"]][2L])
.M <- M <- do.call(new, newargs)
m <- M@Dim[1L]
n <- M@Dim[2L]
r <- min(m, n)
p0 <- (n * (n - 1L)) %/% 2L
p1 <- (n * (n + 1L)) %/% 2L
.ZERO <- as.vector(0, typeof(M@x))
.ONE <- as.vector(1, typeof(M@x))
.NA <- as.vector(NA, typeof(M@x))
loup <- if (is.ge) NA_character_ else if (M@uplo == "U") "L" else "U"
## For conveniently getting and setting (non)trivial triangles
## of _traditional_ symmetric or triangular matrices
if (!is.ge) {
if (M@uplo == "U") {
tri1 <- U; `tri1<-` <- `U<-`
tri0 <- L; `tri0<-` <- `L<-`
} else {
tri1 <- L; `tri1<-` <- `L<-`
tri0 <- U; `tri0<-` <- `U<-`
}
}
.m <- m1 <- m2 <-
if (is.p)
`tri1<-`(array(.ZERO, dim = M@Dim, dimnames = M@Dimnames),
diag = TRUE, M@x)
else
array(M@x, dim = M@Dim, dimnames = M@Dimnames)
diag(.M) <- diag(.m) <-
if (is.d)
rlnorm(r)
else
sample(c(.NA, .ZERO, .ONE), r, TRUE)
if (is.sy) {
tri0(m2, diag = TRUE) <- tri0(t(m2), diag = TRUE)
dimnames(m2) <- Matrix:::symDN(M@Dimnames)
}
if (is.tr && M@diag == "U") {
diag(m2) <- .ONE
}
pM <-
if (is.p)
M
else if (!is.ge)
do.call(new, replace(newargs, c("Class", "x"),
list(packedClass(Class),
tri1(m1, diag = TRUE))))
upM <-
if (!is.p)
M
else
do.call(new, replace(newargs, c("Class", "x"),
list(unpackedClass(Class), as.vector(m1))))
tM <- do.call(new, replace(newargs,
c("Dim", "Dimnames", "x",
if (!is.ge) "uplo"),
c(list(M@Dim[2:1],
M@Dimnames[if (is.sy) 1:2 else 2:1],
if (is.p)
tri0(t(m1), diag = TRUE)
else
as.vector(t(m1))),
if (!is.ge) list(loup))))
dM <- do.call(new, replace(newargs[names(newargs) != "sd"],
c("Class", "x", if (is.tr) "diag"),
c(list(...Class(Class),
if (is.p)
tri1(.m, diag = TRUE)
else
as.vector(.m)),
if (is.tr) list("N"))))
stopifnot(is.ge || identical(pack(M), pM),
identical(unpack(M), upM),
identical(t(M), tM),
identical(diag(M, names = FALSE), diag(m2, names = FALSE)),
identical(diag(M, names = TRUE), diag(m2, names = TRUE)),
identical(.M, dM))
if (is.ge) {
if (m == n) {
## Not symmetric and not triangular
U(m2) <- if (is.d) rlnorm(p0) else rep_len(c(.NA, .ZERO, .ONE), p0)
L(m2) <- if (is.d) -rlnorm(p0) else rep_len(c(.ZERO, .ONE, .NA), p0)
M@x <- as.vector(m2)
stopifnot(isSymmetric(M, tol = 0, checkDN = FALSE) == (n <= 1L),
isTriangular(M, upper = NA) == (n <= 1L),
isDiagonal(M) == (n <= 1L))
## Symmetric but not triangular
L(m2) <- L(t(m2))
M@x <- as.vector(m2)
stopifnot(isSymmetric(M, tol = 0, checkDN = FALSE),
isTriangular(M, upper = NA) == (n <= 1L),
isDiagonal(M) == (n <= 1L))
## Not symmetric but triangular
L(m2) <- .ZERO
M@x <- as.vector(m2)
stopifnot(isSymmetric(M, tol = 0, checkDN = FALSE) == (n <= 1L),
identical(isTriangular(M, upper = TRUE), TRUE),
identical(isTriangular(M, upper = FALSE), FALSE),
identical(isTriangular(M, upper = NA),
`attr<-`(TRUE, "kind", "U")),
isDiagonal(M) == (n <= 1L))
## Symmetric and triangular
U(m2) <- .ZERO
M@x <- as.vector(m2)
stopifnot(isSymmetric(M, tol = 0, checkDN = FALSE),
identical(isTriangular(M, upper = TRUE), TRUE),
identical(isTriangular(M, upper = FALSE), TRUE),
identical(isTriangular(M, upper = NA),
`attr<-`(TRUE, "kind", "U")),
isDiagonal(M))
} else {
## Non-square ... _never_ symmetric, triangular, or diagonal
stopifnot(!isSymmetric(M, tol = 0, checkDN = FALSE),
!isTriangular(M, upper = NA),
!isDiagonal(M))
}
} else if (is.sy) {
## Not triangular
tri1(m2) <- if (is.d) rlnorm(p0) else rep_len(c(.NA, .ZERO, .ONE), p0)
M@x <- if (is.p) tri1(m2, diag = TRUE) else as.vector(m2)
stopifnot(isSymmetric(M, tol = 0, checkDN = FALSE),
isTriangular(M, upper = NA) == (n <= 1L),
isDiagonal(M) == (n <= 1L))
## Triangular
tri1(m2) <- .ZERO
M@x <- if (is.p) tri1(m2, diag = TRUE) else as.vector(m2)
stopifnot(isSymmetric(M, tol = 0, checkDN = FALSE),
identical(isTriangular(M, upper = TRUE), TRUE),
identical(isTriangular(M, upper = FALSE), TRUE),
identical(isTriangular(M, upper = NA),
`attr<-`(TRUE, "kind", M@uplo)),
isDiagonal(M))
} else {
## Not symmetric
tri1(m2) <- if (is.d) rlnorm(p0) else rep_len(c(.NA, .ZERO, .ONE), p0)
M@x <- if (is.p) tri1(m2, diag = TRUE) else as.vector(m2)
stopifnot(isSymmetric(M, tol = 0, checkDN = FALSE) == (n <= 1L),
identical(isTriangular(M, upper = M@uplo == "U"), TRUE),
identical(isTriangular(M, upper = M@uplo != "U"), n <= 1L),
identical(isTriangular(M, upper = NA),
`attr<-`(TRUE, "kind", M@uplo)),
isDiagonal(M) == (n <= 1L))
## Symmetric
tri1(m2) <- .ZERO
M@x <- if (is.p) tri1(m2, diag = TRUE) else as.vector(m2)
stopifnot(isSymmetric(M, tol = 0, checkDN = FALSE),
identical(isTriangular(M, upper = M@uplo == "U"), TRUE),
identical(isTriangular(M, upper = M@uplo != "U"), TRUE),
identical(isTriangular(M, upper = NA),
`attr<-`(TRUE, "kind", M@uplo)),
isDiagonal(M))
}
TRUE
}
.dense.subclasses <- c(names(getClassDef("packedMatrix")@subclasses),
names(getClassDef("unpackedMatrix")@subclasses))
stopifnot(all(vapply(.dense.subclasses, testDenseClass, NA, n = 4L)))
## diag(, names = TRUE) preserves names
## if head of longer character vector matches shorter character vector
n <- 4L
m <- array(rnorm(n * (n + 1L)), dim = c(n, n + 1L))
M <- new("dgeMatrix", x = as.vector(m), Dim = dim(m))
rn <- letters[seq_len(n)]
cn <- letters[seq_len(n + 1L)]
ldn <- list(list(rn, cn), list(rn, replace(cn, 1L, "")))
for (dn in ldn) {
stopifnot(identical(diag(`slot<-`(M, "Dimnames", TRUE, dn), names = TRUE),
diag(`dimnames<-`(m, dn), names = TRUE)))
}
cat("Time elapsed:", proc.time(), "\n") # "stats"
Matrix/tests/spModel.matrix.R 0000644 0001751 0000144 00000022411 14467060443 015737 0 ustar hornik users ## for R_DEFAULT_PACKAGES=NULL :
library(stats)
library(utils)
library(Matrix)
## This is example(sp....) -- much extended
mEQ <- function(x, y, check.attributes = NA, ...) {
## first drop columns from y which are all 0 :
if(any(i0 <- colSums(abs(x)) == 0)) {
message(gettextf("x had %d zero-columns", sum(i0)))
x <- x[, !i0, drop = FALSE]
}
if(any(i0 <- colSums(abs(y)) == 0)) {
message(gettextf("y had %d zero-columns", sum(i0)))
y <- y[, !i0, drop = FALSE]
}
isTRUE(all.equal(x, y, tolerance = 0, check.attributes = check.attributes, ...))
}
##' Is sparse.model.matrix() giving the "same" as dense model.matrix() ?
##'
##' @return logical
##' @param frml formula
##' @param dat data frame
##' @param showFactors
##' @param ... further arguments passed to {sparse.}model.matrix()
isEQsparseDense <- function(frml, dat,
showFactors = isTRUE(getOption("verboseSparse")), ...)
{
## Author: Martin Maechler, Date: 21 Jul 2009
stopifnot(inherits(frml, "formula"), is.data.frame(dat))
if(showFactors)
print(attr(terms(frml, data=dat), "factors"))
smm <- sparse.model.matrix(frml, dat, ...)
mm <- model.matrix(frml, dat, ...)
sc <- smm@contrasts
mEQ(as(smm, "generalMatrix"), Matrix(mm, sparse=TRUE)) &
identical(smm@assign, attr(mm, "assign")) &
(if(is.null(mc <- attr(mm, "contrasts"))) length(sc) == 0 else identical(sc, mc))
}
### ------------ all the "datasets" we construct for use -------------
dd <- data.frame(a = gl(3,4), b = gl(4,1,12))# balanced 2-way
(dd3 <- cbind(dd, c = gl(2,6), d = gl(3,8)))
dd. <- dd3[- c(1, 13:15, 17), ]
set.seed(17)
dd4 <- cbind(dd, c = gl(2,6), d = gl(8,3))
dd4 <- cbind(dd4, x = round(rnorm(nrow(dd4)), 1))
dd4 <- dd4[- c(1, 13:15, 17), ]
##-> 'd' has unused levels
dM <- dd4
dM$X <- outer(10*rpois(nrow(dM), 2), 1:3)
dM$Y <- cbind(pmax(0, dM$x - .3), floor(4*rnorm(nrow(dM))))
str(dM)# contains *matrices*
options("contrasts") # the default: "contr.treatment"
op <- options(sparse.colnames = TRUE) # for convenience
stopifnot(identical(## non-sensical, but "should work" (with a warning each):
sparse.model.matrix(a~ 1, dd),
sparse.model.matrix( ~ 1, dd)))
sparse.model.matrix(~ a + b, dd, contrasts.arg = list(a="contr.sum"))
sparse.model.matrix(~ a + b, dd, contrasts.arg = list(b="contr.SAS"))
xm <- sparse.model.matrix(~ x, dM) # {no warning anymore ...}
dxm <- Matrix(model.matrix(~ x, dM), sparse=TRUE)
stopifnot(is(xm, "sparseMatrix"), mEQ(as(xm,"generalMatrix"), dxm))
## Sparse method is equivalent to the traditional one :
stopifnot(isEQsparseDense(~ a + b, dd),
suppressWarnings(isEQsparseDense(~ x, dM)),
isEQsparseDense(~ 0 + a + b, dd),
identical(sparse.model.matrix(~ 0 + a + b, dd),
sparse.model.matrix(~ -1 + a + b, dd)),
isEQsparseDense(~ a + b, dd, contrasts.arg = list(a="contr.sum")),
isEQsparseDense(~ a + b, dd, contrasts.arg = list(a="contr.SAS")),
## contrasts as *functions* or contrast *matrices* :
isEQsparseDense(~ a + b, dd,
contrasts.arg = list(
a=contr.sum,
b=contr.treatment(4))),
isEQsparseDense(~ a + b, dd,
contrasts.arg = list(
a=contr.SAS(3),
b = function(n, contr=TRUE, sparse=FALSE)
contr.sum(n=n, contrasts=contr, sparse=sparse))))
sm <- sparse.model.matrix(~a * b, dd,
contrasts.arg = list(a=contr.SAS(3, sparse=TRUE)))
sm
## FIXME: Move part of this to ../../MatrixModels/tests/
##stopifnot(all(sm == model.Matrix( ~a * b, dd, contrasts= list(a= contr.SAS(3)))))
##
stopifnot(isEQsparseDense(~ a + b + c + d, dd.))
stopifnot(isEQsparseDense(~ a + b:c + c + d, dd.))
## no intercept -- works too
stopifnot(isEQsparseDense(~ -1+ a + b + c + d, dd.))
stopifnot(isEQsparseDense(~ 0 + a + b:c + c + d, dd.))
Sparse.model.matrix <- function(...) {
s <- sparse.model.matrix(...)
as(s, "generalMatrix")# dropping 'assign',.. slots
}
##
dim(mm <- Matrix(model.matrix(~ a + b + c + d, dd4), sparse=TRUE))
dim(sm <- Sparse.model.matrix(~ a + b + c + d, dd4))
## was (19 13), when 'drop.unused.levels' was implicitly TRUE
dim(sm. <- Sparse.model.matrix(~ a + b + c + d, dd4, drop.unused.levels=TRUE))
stopifnot(mEQ(sm , mm), ## (both have a zero column)
mEQ(sm., mm)) ## << that's ok, since mm has all-0 column !
## look at this :
all(mm[,"d5"] == 0) ## !!!! --- correct: a column of all 0 <--> dropped level!
stopifnot(all.equal(sm., mm[, - which("d5" == colnames(mm))], ## indeed !
check.attributes = NA))
## i.e., sm has just dropped an all zero column --- which it should!
stopifnot(isEQsparseDense(~ 1 + sin(x) + b*c + a:x, dd4, showFactors=TRUE))
stopifnot(isEQsparseDense(~ I(a) + b*c + a:x, dd4, showFactors=TRUE))
## no intercept -- works too
stopifnot(isEQsparseDense(~ 0+ I(a) + b*c + a:x, dd4, showFactors=TRUE))
f <- ~ 1 + a + b*c + a*x
attr(terms(f, data=dd4), "factors")
dim(mm <- Matrix(model.matrix(f, data=dd4), sparse=TRUE))
dim(sm <- Sparse.model.matrix(f, data=dd4)) # ==
stopifnot(mEQ(sm, mm))
f <- ~ a*X + X*Y + a*c
attr(terms(f, data=dM), "factors")
dim(mm <- Matrix(model.matrix(f, data=dM), sparse=TRUE))
dim(sm <- Sparse.model.matrix(f, data=dM, verbose=TRUE))
stopifnot(mEQ(sm, mm))
## high order
f <- ~ a:b:X:c:Y
mm <- Matrix(model.matrix(f, data=dM), sparse=TRUE)
sm <- Sparse.model.matrix(f, data=dM, verbose=2)
stopifnot(mEQ(sm, mm))
f <- ~ 1 + a + b*c + a*x + b*d*x + b:c:d
attr(terms(f, data=dd4), "factors")
dim(mm <- Matrix(model.matrix(f, data=dd4), sparse=TRUE)) ## 19 100
dim(sm <- Sparse.model.matrix(f, data=dd4)) ## (ditto)
dim(sm. <- Sparse.model.matrix(f, data=dd4, drop.unused.levels=TRUE)) # 19 88
stopifnot(mEQ(sm, mm), mEQ(sm., mm))# {32, 32; 20 and 32 zero-columns ..}
## now get a bit courageous:
##
## stopifnot(isEQsparseDense(~ 1 + c + a:b:d, dat=dd4))
dim(mm <- Matrix(model.matrix(~ 1 + a + b*c + a:b:c:d, data=dd4),
sparse=TRUE)) ## 19 202
dim(sm <- Sparse.model.matrix(~ 1 + a + b*c + a:b:c:d, data=dd4))
dim(sm. <- Sparse.model.matrix(~ 1 + a + b*c + a:b:c:d, data=dd4,
drop.unused.levels=TRUE))
stopifnot(mEQ(sm, mm), mEQ(sm., mm))# {173, 173, 149 and 173 zero-columns !}
## stopifnot(isEQsparseDense(~ 1 + a + b*c + a:b:c:d, dat=dd4))
dim(mm <- Matrix(model.matrix(~ 1 + a + b:c + a:b:d, data=dd4),
sparse=TRUE)) ## 19 107
dim(sm <- Sparse.model.matrix(~ 1 + a + b:c + a:b:d, data=dd4))
dim(sm. <- Sparse.model.matrix(~ 1 + a + b:c + a:b:d, data=dd4,
drop.unused.levels=TRUE))
stopifnot(mEQ(sm, mm), mEQ(sm., mm))
dim(mm <- Matrix(model.matrix(~ a*b*c +c*d, dd4), sparse=TRUE)) ## 19 38
dim(sm <- Sparse.model.matrix(~ a*b*c +c*d, dd4))# (ditto)
dim(sm. <- Sparse.model.matrix(~ a*b*c +c*d, dd4, drop.unused.levels=TRUE))
stopifnot(mEQ(sm, mm), mEQ(sm., mm))
f1 <- ~ (a+b+c+d)^2 + (a+b):c:d + a:b:c:d
f2 <- ~ (a+b+c+d)^4 - a:b:c - a:b:d
mm1 <- Matrix(model.matrix(f1, dd4), sparse=TRUE)
dim(mm2 <- Matrix(model.matrix(f2, dd4), sparse=TRUE))
sm1 <- sparse.model.matrix(f1, dd4)
dim(sm2 <- sparse.model.matrix(f2, dd4))
s.1 <- sparse.model.matrix(f1, dd4, drop.unused.levels=TRUE)
dim(s.2 <- sparse.model.matrix(f2, dd4, drop.unused.levels=TRUE))
stopifnot(identical(mm1,mm2),
identical(sm1,sm2), identical(s.1,s.2),
mEQ(sm1,mm1), mEQ(s.1,mm1))
str(dd <- data.frame(d = gl(10,6), a = ordered(gl(3,20))))
X. <- sparse.model.matrix(~ a + d, data = dd)
## failed because of contr.poly default in Matrix 0.999375-33
stopifnot(dim(X.) == c(60, 12), nnzero(X.) == 234,
isEQsparseDense(~ 0 + d + I(as.numeric(d)^2), dd))
## I(.) failed (upto 2010-05-07)
## When the *contrasts* are sparse :
spC <- as(contrasts(dd$d), "sparseMatrix")
ddS <- dd
contrasts(ddS$d) <- spC
Xs <- sparse.model.matrix(~ a + d, data=ddS)
stopifnot(exprs = {
inherits(spC, "sparseMatrix")
identical(spC, contrasts(ddS[,"d"]))
mEQ(X., Xs)
})
## Fixing matrix-Bugs [#6673] by Davor Josipovic
df <- data.frame('a' = factor(1:3), 'b' = factor(4:6))
Cid <- lapply(df, contrasts, contrasts=FALSE)
CidS <- lapply(df, contrasts, contrasts=FALSE, sparse=TRUE)
X2 <- sparse.model.matrix(~ . -1, data = df, contrasts.arg = Cid)
X2S <- sparse.model.matrix(~ . -1, data = df, contrasts.arg = CidS)
X2
stopifnot(all.equal(X2, X2S, tolerance = 0, check.attributes = NA))
## X2S was missing the last column ('b6') in Matrix <= 1.x-y
## Fixing (my repr.ex.) of Matrix bug [#6657] by Nick Hanewinckel
mkD <- function(n, p2 = 2^ceiling(log2(n)), sd = 10, rf = 4) {
stopifnot(p2 >= n, n >= 0, p2 %% 2 == 0)
G <- gl(2, p2/2, labels=c("M","F"))[sample.int(p2, n)]
data.frame(sex = G,
age = round(rf*rnorm(n, mean=32 + 2*as.numeric(G), sd=sd)) / rf)
}
set.seed(101)
D1 <- mkD(47)
Xs <- sparse.model.matrix(~ sex* poly(age, 2), data = D1)
## Error in model.spmatrix(..): no slot of name "i" for .. class "dgeMatrix"
validObject(Xs)
stopifnot(exprs = {
identical(c(47L, 6L), dim(Xs))
identical(colnames(Xs)[3:6],
c(1:2, outer("sexF", 1:2, paste, sep=":")))
all(Xs == model.matrix(~ sex* poly(age, 2), data = D1))
})
cat('Time elapsed: ', proc.time(),'\n') # for ``statistical reasons''
if(!interactive()) warnings()
Matrix/tests/write-read.R 0000644 0001751 0000144 00000003471 14444662477 015113 0 ustar hornik users ## for R_DEFAULT_PACKAGES=NULL :
library(utils)
library(Matrix)
#### Read / Write (sparse) Matrix objects ----------------------
### Rebuild the 'mm' example matrix, now in KNex data
### This is no longer really important, as we now use
### ../data/KNex.R which creates the S4 object *every time*
data(KNex, package = "Matrix")
## recreate 'mm' from list :
sNms <- c("Dim", "i","p","x")
L <- lapply(sNms, function(SN) slot(KNex$mm, SN)); names(L) <- sNms
mm2 <- new(class(KNex$mm))
for (n in sNms) slot(mm2, n) <- L[[n]]
stopifnot(validObject(mm2),
identical(mm2, KNex$mm))
L$y <- KNex$y
## save(L, file = "/u/maechler/R/Pkgs/Matrix/inst/external/KNex_slots.rda")
## recreate 'mm' from ASCI file :
mmT <- as(KNex$mm, "TsparseMatrix")
str(mmT)
mm3 <- cbind(i = mmT@i, j = mmT@j, x = mmT@x)
write.table(mm3, file = "mm-Matrix.tab", row.names=FALSE)# -> ASCII version
str(mmr <- read.table("mm-Matrix.tab", header = TRUE))
mmr$i <- as.integer(mmr$i)
mmr$j <- as.integer(mmr$j)
mmN <- with(mmr, new("dgTMatrix", Dim = c(max(i)+1:1,max(j)+1:1),
i = i, j = j, x = x))
stopifnot(identical(mmT, mmN)) # !!
## weaker (and hence TRUE too):
stopifnot(all.equal(as(mmN, "matrix"),
as(mmT, "matrix"), tolerance=0))
mm <- as(mmN, "CsparseMatrix")
stopifnot(all.equal(mm, KNex$mm))
## save(mm, file = "....../Matrix/data/mm.rda", compress = TRUE)
A <- Matrix(c(1,0,3,0,0,5), 10, 10, sparse = TRUE) # warning about [6] vs [10]
(fname <- file.path(tempdir(), "kk.mm"))
writeMM(A, fname)
(B <- readMM(fname))
validObject(B)
Bc <- as(B, "CsparseMatrix")
stopifnot(identical(A, Bc))
fname <- system.file("external", "wrong.mtx", package = "Matrix")
r <- try(readMM(fname))
stopifnot(inherits(r, "try-error"), length(grep("readMM.*row.*1:nr", r)) == 1)
## gave a much less intelligible error message
Matrix/tests/group-methods.R 0000644 0001751 0000144 00000053617 14523122502 015626 0 ustar hornik users ### Testing the group methods --- some also happens in ./Class+Meth.R
## for R_DEFAULT_PACKAGES=NULL :
library(stats)
library(utils)
library(Matrix)
source(system.file("test-tools.R", package = "Matrix"))# identical3() etc
assertErrV <- function(e) tools::assertError(e, verbose=TRUE)
cat("doExtras:",doExtras,"\n")
options(nwarnings = 1e4)
set.seed(2001)
mm <- Matrix(rnorm(50 * 7), ncol = 7)
xpx <- crossprod(mm)# -> "factors" in mm !
round(xpx, 3) # works via "Math2"
y <- rnorm(nrow(mm))
xpy <- crossprod(mm, y)
res <- solve(xpx, xpy)
signif(res, 4) # 7 x 1 Matrix
stopifnot(all(signif(res) == signif(res, 6)),
all(round (xpx) == round (xpx, 0)))
## exp(): component wise
signif(dd <- (expm(xpx) - exp(xpx)) / 1e34, 3)# 7 x 7
validObject(xpx)
validObject(xpy)
validObject(dd)
## "Math" also, for log() and [l]gamma() which need special treatment
stopifnot(exprs = {
identical(exp(res)@x, exp(res@x))
identical(log(abs(res))@x, log(abs((res@x))))
identical(lgamma(res)@x, lgamma(res@x))
})
## "Arith" / "Ops"
M <- Matrix(1:12, 4,3)
m <- cbind(4:1)
stopifnot(exprs = {
identical(M*m, M*c(m)) # M*m failed in Matrix_1.3-3 pre-release:
identical(m*M, c(m)*M)
## M*m: Error in eval(....) : object 'x1' not found
isValid(M1 <- M[, 1, drop=FALSE], "dgeMatrix")
identical(M*M1, M*M1[,1]) # M*M1 failed ..
identical(M-M1, M-M1[,1])
identical(M/M1, M/M1[,1])
identical(M1*M, M1[,1]*M)
identical(M1-M, M1[,1]-M)
identical(M1/M, M1[,1]/M)
})
###--- sparse matrices ---------
mC <- Matrix(c(0, 0, 2:0), 3, 5)
sm <- sin(mC)
stopifnot(class(sm) == class(mC), class(mC) == class(mC^2),
dim(sm) == dim(mC),
class(0 + 100*mC) == class(mC),
all.equal(0.1 * ((0 + 100*mC)/10), mC),
all.equal(sqrt(mC ^ 2), mC),
identical(mC^2, mC * mC),
identical(mC*2, mC + mC)
)
x <- Matrix(rbind(0,cbind(0, 0:3,0,0,-1:2,0),0))
x # sparse
(x2 <- x + 10*t(x))
stopifnot(is(x2, "sparseMatrix"),
identical(x2, t(x*10 + t(x))),
identical(x, as((x + 10) - 10, "CsparseMatrix")))
(px <- Matrix(x^x - 1))#-> sparse again
stopifnot(px@i == c(3,4,1,4),
px@x == c(3,26,-2,3))
## From: "Florent D." .. Thu, 23 Feb 2012 -- bug report
##---> MM: Make a regression test:
tst <- function(n, i = 1) {
stopifnot(i >= 1, n >= i)
D <- .sparseDiagonal(n)
ee <- numeric(n) ; ee[i] <- 1
stopifnot(all(D - ee == diag(n) - ee),
all(D * ee == diag(n) * ee),
all(ee - D == ee - diag(n)),
{C <- (ee / D == ee / diag(n)); all(is.na(C) | C)},
TRUE)
}
nn <- if(doExtras) 27 else 7
tmp <- sapply(1:nn, tst) # failed in Matrix 1.0-4
i <- sapply(1:nn, function(i) sample(i,1))
tmp <- mapply(tst, n= 1:nn, i= i)# failed too
(lsy <- new("lsyMatrix", Dim = c(2L,2L), x=c(TRUE,FALSE,TRUE,TRUE)))
nsy <- as(lsy, "nMatrix")
(t1 <- new("ltrMatrix", Dim = c(1L,1L), x = TRUE))
(t2 <- new("ltrMatrix", Dim = c(2L,2L), x = rep(TRUE,4)))
stopifnot(all(lsy), # failed in Matrix 1.0-4
all(nsy), # dito
all(t1), # "
## ok previously (all following):
!all(t2),
all(sqrt(lsy) == 1))
dsy <- lsy+1
D3 <- Diagonal(x=4:2); L7 <- Diagonal(7) > 0
validObject(xpp <- pack(round(xpx,2)))
lsp <- xpp > 0
(dsyU <- .diag2dense(D3, ".", "s"))
lsyU <- .diag2dense(Diagonal(5) > 0, ".", "s")
str(lsyU)
stopifnot({
isValid(dsyU, "dsyMatrix") && dsyU@uplo == "U"
isValid(dsyL <- t(dsyU), "dsyMatrix") && dsyL@uplo == "L"
isValid(dspU <- pack(dsyU), "dspMatrix") && dspU@uplo == "U"
isValid(dspL <- pack(dsyL), "dspMatrix") && dspL@uplo == "L"
identical(dspU, t(dspL))
isValid(lsyU, "lsyMatrix") && lsyU@uplo == "U"
isValid(lsyL <- t(lsyU), "lsyMatrix") && lsyL@uplo == "L"
isValid(lspU <- pack(lsyU), "lspMatrix") && lspU@uplo == "U"
isValid(lspL <- pack(lsyL), "lspMatrix") && lspL@uplo == "L"
identical(lspL, t(lspU))
##
## log(x, ) -- was mostly *wrong* upto 2019-10 [Matrix <= 1.2-17]
all.equal(log(abs(dsy), 2), log2(abs(dsy)))
all.equal(log(abs(dsyL),2), log2(abs(dsyL)))
all.equal(log(abs(dspU),2), log2(abs(dspU)))
all.equal(log(abs(dspL),2), log2(abs(dspL)))
## These always worked, as {0,1} -> {-Inf,0} independent of 'base':
all.equal(log(abs(lsy), 2), log2(abs(lsy)))
all.equal(log(abs(lsyL),2), log2(abs(lsyL)))
all.equal(log(abs(lspU),2), log2(abs(lspU)))
all.equal(log(abs(lspL),2), log2(abs(lspL)))
##
all.equal(log(abs(res), 2), log2(abs(res)))
all.equal(log(abs(xpy), 2), log2(abs(xpy)))
all.equal(log(abs(xpp), 2), log2(abs(xpp)))
all.equal(log(abs( D3), 2), log2(abs( D3)))
all.equal(log(abs( L7), 2), log2(abs( L7)))
})
showProc.time()
## is.finite() -- notably for symmetric packed / uplo="L" with NA :
spU <- new("dspMatrix", Dim = c(3L, 3L), x = c(0, NA, 0, NA, NA, 0), uplo = "U")
sU <- new("dsyMatrix", Dim = c(3L, 3L), x = c(1, NA, NA, NA, 1, NA, 8, 2, 1), uplo = "U")
sL <- t(sU)
spL <- t(spU)
trU <- triu(spU)
trL <- tril(spL)
stopifnot(exprs = {
spL@uplo == "L"
trU@uplo == "U"
trL@uplo == "L"
identical(trU, triu(spL))
identical(trL, tril(spU))
})
isU <- is.finite(sU)
isL <- is.finite(sL)
stopifnot(exprs = {
identical(isU, t(isL))
all(isU == isL)
which(!isU, arr.ind = TRUE) == c(2:1, 1:2)
})
isFu <- is.finite(spU)
isFl <- is.finite(spL)
isFtu <- is.finite(trU)
isFtl <- is.finite(trL)
stopifnot(exprs = {
all(isFu == diag(TRUE, 3))
all(isFu == isFl) # has failed till 2022-06-11
isTriangular(isFtu)
isTriangular(isFtl)
identical(rep(TRUE, 6), pack(tril(isFtu))@x)
identical(rep(TRUE, 6), pack(triu(isFtl))@x)
})
showProc.time()
set.seed(111)
local({
for(i in 1:(if(doExtras) 20 else 5)) {
M <- rspMat(n=1000, 200, density = 1/20)
v <- rnorm(ncol(M))
m <- as(M,"matrix")
stopifnot(all(t(M)/v == t(m)/v))
cat(".")
}});cat("\n")
## Now just once, with a large such matrix:
local({
n <- 100000; m <- 30000
AA <- rspMat(n, m, density = 1/20000)
v <- rnorm(m)
st <- system.time({
BB <- t(AA)/v # should happen *fast*
stopifnot(dim(BB) == c(m,n), is(BB, "sparseMatrix"))
})
str(BB)
print(st)
if(Sys.info()[["sysname"]] == "Linux") {
mips <- try(as.numeric(sub(".*: *", '',
grep("bogomips", readLines("/proc/cpuinfo"),
ignore.case=TRUE, # e.g. ARM : "BogoMIPS"
value=TRUE)[[1]])))
print(mips)
if(is.numeric(mips) && all(mips) > 0 && doExtras)
# doExtras: valgrind (2023-07-26) gave large 'st[1]'
stopifnot(st[1] < 1000/mips)# ensure there was no gross inefficiency
}
})
###----- Compare methods ---> logical Matrices ------------
l3 <- upper.tri(matrix(, 3, 3))
(ll3 <- Matrix(l3))
dt3 <- (99* Diagonal(3) + (10 * ll3 + Diagonal(3)))/10
(dsc <- crossprod(ll3))
stopifnot(identical(ll3, t(t(ll3))),
identical(dsc, t(t(dsc))))
stopifnotValid(ll3, "ltCMatrix")
stopifnotValid(dsc, "dsCMatrix")
stopifnotValid(dsc + 3 * Diagonal(nrow(dsc)), "dsCMatrix")
stopifnotValid(dt3, "triangularMatrix") # remained triangular
stopifnotValid(dt3 > 0, "triangularMatrix")# ditto
(lm1 <- dsc >= 1) # now ok
(lm2 <- dsc == 1) # now ok
nm1 <- as(lm1, "nMatrix")
(nm2 <- as(lm2, "nMatrix"))
stopifnot(validObject(lm1), validObject(lm2),
validObject(nm1), validObject(nm2),
identical(dsc, dsc * as(lm1, "dMatrix")))
crossprod(lm1) # lm1: "lsC*"
cnm1 <- crossprod(nm1, boolArith = FALSE)
stopifnot(is(cnm1, "symmetricMatrix"), ## whereas the %*% is not:
Q.eq(cnm1, nm1 %*% nm1))
dn1 <- as(nm1, "denseMatrix")
stopifnot(all(dn1 == nm1))
dsc[2,3] <- NA ## now has an NA (and no longer is symmetric)
## ----- and "everything" is different
## also add "non-structural 0":
dsc@x[1] <- 0
dsc
dsc/ 5
dsc + dsc
dsc - dsc
dsc + 1 # -> no longer sparse
Tsc <- as(dsc, "TsparseMatrix")
dsc. <- drop0(dsc)
stopifnot(Q.eq(dsc., Matrix((dsc + 1) - 1)),
identical(as(-Tsc,"CsparseMatrix"), (-1) * Tsc),
identical(-dsc., (-1) * dsc.),
identical3(-Diagonal(3), Diagonal(3, -1), (-1) * Diagonal(3)),
Q.eq(dsc., Matrix((Tsc + 1) -1)), # ok (exact arithmetic)
Q.eq(0 != dsc, dsc != Matrix(0, 3, 3)),
Q.eq(0 != dsc, dsc != c(0,0)) # with a warning ("not multiple ..")
)
str(lm1 <- dsc >= 1) # now ok (NA in proper place, however:
lm1 ## NA used to print as ' ' , now 'N'
(lm2 <- dsc == 1)# ditto
stopifnot(identical(crossprod(lm1),# "lgC": here works!
crossprod(as(lm1, "dMatrix"))),
identical(lm2, lm1 & lm2),
identical(lm1, lm1 | lm2))
ddsc <- kronecker(Diagonal(7), dsc)
isValid(ddv <- rowSums(ddsc, sparseResult=TRUE), "sparseVector")
sv <- colSums(kC <- kronecker(mC,kronecker(mC,mC)), sparseResult=TRUE)
EQ <- ddv == rowSums(ddsc)
na.ddv <- is.na(ddv)
sM <- Matrix(pmax(0, round(rnorm(50*15, -1.5), 2)), 50,15)
stopifnot(sv == colSums(kC), is.na(as.vector(ddv)) == na.ddv,
isValid(sM/(-7:7), "CsparseMatrix"),
all(EQ | na.ddv))
## Subclasses (!)
setClass("m.spV", contains = "dsparseVector")
(m.ddv <- as(ddv, "m.spV"))
stopifnot(all.equal(m.ddv, ddv, check.class = FALSE))# failed
setClass("m.dgC", contains = "dgCMatrix")
(m.mC <- as(mC, "m.dgC"))
stopifnot(all(m.mC == mC))
## 2-level inheritance (R-forge Matrix bug #6185)
## https://r-forge.r-project.org/tracker/index.php?func=detail&aid=6185&group_id=61&atid=294
setClass("Z", representation(zz = "list"))
setClass("C", contains = c("Z", "dgCMatrix"))
setClass("C2", contains = "C")
setClass("C3", contains = "C2")
(cc <- as(mC, "C"))
c2 <- as(mC, "C2")
c3 <- as(mC, "C3")
# as(*, "matrix") of these __fail__ in R < 3.5.0
# before R_check_class_and_super() became better :
print(c2)
print(c3)
## ==> Error in asMethod(object) : invalid class of object to as_cholmod_sparse
stopifnot(identical(cc > 0, mC > 0 -> m.gt.0), ## cc > 0 - gave error in Matrix <= 1.2-11
identical(c2 > 0, m.gt.0),
identical(c3 > 0, m.gt.0))
## Just for print "show":
z <- round(rnorm(77), 2)
z[sample(77,10)] <- NA
(D <- Matrix(z, 7)) # dense
z[sample(77,15)] <- 0
(D <- Matrix(z, 7)) # sparse
abs(D) >= 0.5 # logical sparse
## For the checks below, remove some and add a few more objects:
rm(list= ls(pattern="^.[mMC]?$"))
T3 <- Diagonal(3) > 0; stopifnot(T3@diag == "U") # "uni-diagonal"
validObject(dtp <- pack(as(dt3, "denseMatrix")))
stopifnot(exprs = {
isValid(lsC <- as(lsp, "CsparseMatrix"), "lsCMatrix")
## 0-extent matrices {fixes in Feb.2019}:
isValid(L00 <- L7[FALSE,FALSE], "ldiMatrix")
isValid(x60 <- x2[,FALSE], "dgCMatrix")
identical(t(x60), x06 <- x2[FALSE,])
isValid(x00 <- x06[,FALSE], "dgCMatrix")
isValid(sv0 <- as(x06, "sparseVector"), "dsparseVector")
})
showProc.time()
### Consider "all" Matrix classes
cl <- sapply(ls(), function(.) class(get(.)))
Mcl <- cl[vapply(cl, extends, "Matrix", FUN.VALUE=NA) |
vapply(cl, extends, "sparseVector", FUN.VALUE=NA)]
table(Mcl)
## choose *one* of each class:
## M.objs <- names(Mcl[!duplicated(Mcl)])
## choose all
M.objs <- names(Mcl) # == the ls() from above
Mat.objs <- M.objs[vapply(M.objs, function(nm) is(get(nm), "Matrix"), NA)]
MatDims <- t(vapply(Mat.objs, function(nm) dim(get(nm)), 0:1))
## Nice summary info :
noquote(cbind(Mcl[Mat.objs], format(MatDims)))
## dtCMatrix, uplo="L" :
(CtL <- t(as(Diagonal(x=4:2), "CsparseMatrix")))
m2 <- cbind(c(0, NA, NA),
c(0, 0, NA), 0)
op <- options(Matrix.verbose = 2)
r <- CtL > m2 # failed in Matrix <= 1.4-1, with
## Compare -- "dtCMatrix" > "dtCMatrix" :
stopifnot(identical(is.na(m2), unname(as.matrix(is.na(r)))), diag(r), isDiagonal(triu(r)))
M <- new("dtCMatrix", i = c(0L, 0:1, 0:2), p = c(0:1, 3L, 6L),
x = c(10,1, 10,1, 1,10), Dim = c(3L, 3L), uplo = "U")
m2 <- matrix(c(0, NA, NA, 0, 0, NA, 0, 0, 0), 3)
r <- M & m2 # failed in Matrix <= 1.4-1
assert.EQ.mat(M | m2 -> ro,
as.mat(M)| m2, tol=0)
D4 <- Diagonal(x=0+ 4:2)
rd <- D4 | m2 # gave invalid class "ltTMatrix" object: uplo='U' must not have sparse entries below the diagonal
M2 <- Matrix(m2); T2 <- Matrix:::.diag2T.smart(D4, M2, kind="l")
stopifnot(exprs = {
all(!r)
## fix in .do.Logic.lsparse() {needed uplo="L"}
identical(rd, T2 | M2)
identical(rd, as(T2, "CsparseMatrix") | as(M2, "lMatrix"))
})
options(op)
if(doExtras || interactive()) { # save testing time
### Systematically look at all "Ops" group generics for "all" Matrix classes
### -------------- Main issue: Detect infinite recursion problems
mDims <- MatDims %*% (d.sig <- c(1, 1000)) # "dim-signature" to match against
m2num <- function(m) { if(is.integer(m)) storage.mode(m) <- "double" ; m }
M.knd <- Matrix:::.M.kind
cat("Checking all Ops group generics for a set of arguments:\n",
"-------------------------------------------------------\n", sep='')
op <- options(warn = 2)#, error=recover)
for(gr in getGroupMembers("Ops")) {
cat(gr,"\n",paste(rep.int("=",nchar(gr)),collapse=""),"\n", sep='')
v0 <- if(gr == "Arith") numeric() else logical()
for(f in getGroupMembers(gr)) {
line <- strrep("-", nchar(f) + 2)
cat(sprintf("%s\n%s :\n%s\n", line, dQuote(f), line))
for(nm in M.objs) {
if(doExtras) cat(" '",nm,"' ", sep="")
M <- get(nm, inherits=FALSE)
n.m <- NROW(M)
cat("o")
for(x in list(TRUE, -3.2, 0L, seq_len(n.m))) {
cat(".")
validObject(r1 <- do.call(f, list(M,x)))
validObject(r2 <- do.call(f, list(x,M)))
stopifnot(dim(r1) == dim(M), dim(r2) == dim(M),
allow.logical0 = TRUE)
}
## M o 0-length === M :
validObject(M0. <- do.call(f, list(M, numeric())))
validObject(.M0 <- do.call(f, list(numeric(), M)))
if(length(M)) # o <0-length v> == 0-length v
stopifnot(identical(M0., v0), identical(.M0, v0))
else if(is(M, "Matrix"))
stopifnot(identical(M0., as(M, if(gr == "Arith") "dMatrix" else "lMatrix")),
identical(M0., .M0))
else # if(is(M, "sparseVector")) of length 0
stopifnot(identical(M0., v0), identical(.M0, v0))
## M o
x <- numeric(n.m)
if(length(x)) x[c(1,length(x))] <- 1:2
sv <- as(x, "sparseVector")
cat("s.")
validObject(r3 <- do.call(f, list(M, sv)))
stopifnot(identical(dim(r3), dim(M)))
if(doExtras && is(M, "Matrix")) { ## M o
d <- dim(M)
ds <- sum(d * d.sig) # signature .. match with all other sigs
match. <- ds == mDims # (matches at least itself)
cat("\nM o M:")
for(oM in Mat.objs[match.]) {
M2 <- get(oM)
## R4 := M f M2
validObject(R4 <- do.call(f, list(M, M2)))
cat(".")
for(M. in list(as.mat(M), M)) { ## two cases ..
r4 <- m2num(as.mat(do.call(f, list(M., as.mat(M2)))))
cat(",")
if(!identical(r4, as.mat(R4))) {
cat(sprintf("\n %s %s %s gave not identical r4 & R4:\n",
nm, f, oM)); print(r4); print(R4)
C1 <- (eq <- R4 == r4) | (N4 <- as.logical((nr4 <- is.na(eq)) & !is.finite(R4)))
if(isTRUE(all(C1)) || isTRUE(all.equal(as.mat(R4), r4,
tolerance = 1e-14)))
cat(sprintf(
" --> %s %s %s (ok): only difference is %s (matrix) and %s (Matrix)\n",
M.knd(M), f, M.knd(M2)
, paste(vapply(unique(r4[N4]), format, ""), collapse="/")
, paste(vapply(unique(R4[N4]), format, ""), collapse="/")
))
else if(isTRUE(all(eq | (nr4 & Matrix:::is0(R4)))))
cat(" --> 'ok': only difference is 'NA' (matrix) and 0 (Matrix)\n")
else stop("R4 & r4 differ \"too much\"")
}
}
cat("i")
}
}
}
cat("\n")
}
}
if(length(warnings())) print(summary(warnings()))
showProc.time()
options(op) # reset 'warn'
} # doExtras
###---- Now checking 0-length / 0-dim cases <==> to R >= 3.4.0 !
## arithmetic, logic, and comparison (relop) for 0-extent arrays
(m <- Matrix(cbind(a=1[0], b=2[0])))
Lm <- as(m, "lMatrix")
## Im <- as(m, "iMatrix")
stopifnot(
identical(m, m + 1), identical(m, m + 1[0]),
identical(m, m + NULL),## now (2016-09-27) ok
identical(m, Lm+ 1L) ,
identical(m, m+2:3), ## gave error "length does not match dimension"
identical(Lm, m & 1),
identical(Lm, m | 2:3),## had Warning "In .... : data length exceeds size of matrix"
identical(Lm, m & TRUE[0]),
identical(Lm, m | FALSE[0]),
identical(Lm, m > NULL),
identical(Lm, m > 1),
identical(Lm, m > .1[0]),## was losing dimnames
identical(Lm, m > NULL), ## was not-yet-implemented
identical(Lm, m <= 2:3) ## had "wrong" warning
)
mm <- m[,c(1:2,2:1,2)]
assertErrV(m + mm) # ... non-conformable arrays
assertErrV(m | mm) # ... non-conformable arrays
## Matrix: ok ; R : ok, in R >= 3.4.0
assertErrV(m == mm)
## in R <= 3.3.x, relop returned logical(0) and m + 2:3 returned numeric(0)
##
## arithmetic, logic, and comparison (relop) -- inconsistency for 1x1 array o = 2>:
## FIXME: desired errors are _not_ thrown for ddiMatrix (when doDiag=TRUE)
(m1 <- Matrix(1, 1L, 1L, dimnames = list("Ro", "col"), doDiag = FALSE))
## col
## Ro 1
## Before Sep.2016, here, Matrix was the *CONTRARY* to R:
assertErrV(m1 + 1:2)## M.: "correct" ERROR // R 3.4.0: "deprecated" warning (--> will be error)
assertErrV(m1 & 1:2)## gave 1 x 1 [TRUE] -- now Error, as R
assertErrV(m1 <= 1:2)## gave 1 x 1 [TRUE] -- now Error, as R
assertErrV(m1 & 1:2)## gave 1 x 1 [TRUE] -- now Error, as R
assertErrV(m1 <= 1:2)## gave 1 x 1 [TRUE] -- now Error, as R
##
## arrays combined with NULL works now
stopifnot(identical(Matrix(3,1,1) + NULL, 3[0]))
stopifnot(identical(Matrix(3,1,1) > NULL, T[0]))
stopifnot(identical(Matrix(3,1,1) & NULL, T[0]))
## in R >= 3.4.0: logical(0) # with *no* warning and that's correct!
if(doExtras || interactive()) { # save testing time
mStop <- function(...) stop(..., call. = FALSE)
##
cat("Checking the Math (+ Math2) group generics for a set of arguments:\n",
"------------ ==== ------------------------------------------------\n", sep='')
doStop <- function() mStop("**Math: ", f,"(<",class(M),">) of 'wrong' class ", dQuote(class(R)))
mM <- getGroupMembers("Math")
mM2 <- getGroupMembers("Math2")
(mVec <- grep("^cum", mM, value=TRUE)) ## <<- are special: return *vector* for matrix input
for(f in c(mM, mM2)) {
cat(sprintf("%-9s :\n %-7s\n", paste0('"',f,'"'), paste(rep("-", nchar(f)), collapse="")))
givesVec <- f %in% mVec
fn <- get(f)
if(f %in% mM2) { fn0 <- fn ; fn <- function(x) fn0(x, digits=3) }
for(nm in M.objs) {
M <- get(nm, inherits=FALSE)
is.m <- length(dim(M)) == 2
cat(" '",nm,"':", if(is.m) "m" else "v", sep="")
R <- fn(M)
r <- fn(m <- if(is.m) as.mat(M) else as.vector(M))
stopifnot(identical(dim(R), dim(r)))
if(givesVec || !is.m) {
assert.EQ(R, r, check.class = FALSE)
} else { ## (almost always:) matrix result
assert.EQ.mat(R, r, check.class = FALSE)
## check preservation of properties, notably super class
if(prod(dim(M)) > 1 && is(M, "diagonalMatrix" ) && isDiagonal(R) && !is(R, "diagonalMatrix" )) doStop()
if(prod(dim(M)) > 1 && is(M, "triangularMatrix") && (iT <- isTriangular(R)) && attr(iT, "kind") == M@uplo &&
!is(R, "triangularMatrix")) doStop()
}
}
cat("\n")
}
showProc.time()
##
cat("Checking the Summary group generics for a set of arguments:\n",
"------------ ======= ------------------------------------------------\n", sep='')
for(f in getGroupMembers("Summary")) {
cat(sprintf("%-9s :\n %-7s\n", paste0('"',f,'"'), paste(rep("-", nchar(f)), collapse="")))
givesVec <- f %in% mVec
fn <- get(f)
if(f %in% mM2) { fn0 <- fn ; fn <- function(x) fn0(x, digits=3) }
for(nm in M.objs) {
M <- get(nm, inherits=FALSE)
is.m <- length(dim(M)) == 2
cat(" '",nm,"':", if(is.m) "m" else "v", sep="")
R <- fn(M)
r <- fn(m <- if(is.m) as.mat(M) else as.vector(M))
stopifnot(identical(dim(R), dim(r)))
assert.EQ(R, r)
}
cat("\n")
if(length(warnings())) print(summary(warnings()))
}
} # doExtras
##