Matrix/0000755000176200001440000000000014550025127011517 5ustar liggesusersMatrix/NAMESPACE0000644000176200001440000002513214514041632012740 0ustar liggesusersuseDynLib(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, setReplaceMethod, signature, 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 ............................. compMatrix, generalMatrix, triangularMatrix, symmetricMatrix, diagonalMatrix, denseMatrix, unpackedMatrix, packedMatrix, sparseMatrix, CsparseMatrix, RsparseMatrix, TsparseMatrix, nMatrix, ndenseMatrix, ngeMatrix, ntrMatrix, ntpMatrix, nsyMatrix, nspMatrix, nsparseMatrix, ngCMatrix, ngRMatrix, ngTMatrix, ntCMatrix, ntRMatrix, ntTMatrix, nsCMatrix, nsRMatrix, nsTMatrix, ndiMatrix, lMatrix, ldenseMatrix, lgeMatrix, ltrMatrix, ltpMatrix, lsyMatrix, lspMatrix, lsparseMatrix, lgCMatrix, lgRMatrix, lgTMatrix, ltCMatrix, ltRMatrix, ltTMatrix, lsCMatrix, lsRMatrix, lsTMatrix, ldiMatrix, iMatrix, ## idenseMatrix, ## igeMatrix, ## itrMatrix, ## itpMatrix, ## isyMatrix, ## ispMatrix, ## isparseMatrix, ## igCMatrix, ## igRMatrix, ## igTMatrix, ## itCMatrix, ## itRMatrix, ## itTMatrix, ## isCMatrix, ## isRMatrix, ## isTMatrix, ## idiMatrix, dMatrix, ddenseMatrix, dgeMatrix, dtrMatrix, dtpMatrix, dsyMatrix, dspMatrix, dpoMatrix, dppMatrix, corMatrix, pcorMatrix, dsparseMatrix, dgCMatrix, dgRMatrix, dgTMatrix, dtCMatrix, dtRMatrix, dtTMatrix, dsCMatrix, dsRMatrix, dsTMatrix, ddiMatrix, zMatrix, ## zdenseMatrix, ## zgeMatrix, ## ztrMatrix, ## ztpMatrix, ## zsyMatrix, ## zspMatrix, ## zsparseMatrix, ## zgCMatrix, ## zgRMatrix, ## zgTMatrix, ## ztCMatrix, ## ztRMatrix, ## ztTMatrix, ## zsCMatrix, ## zsRMatrix, ## zsTMatrix, ## 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, ## "Other" virtual {for now just unions}: atomicVector, index, number, replValue, # dispatch fails when not exported ## "Other" non-virtual {for now just experimental index classes}: abIndex, rleDiff) Matrix/.Rinstignore0000644000176200001440000000002414444344620014023 0ustar liggesusers## currently unused Matrix/LICENCE0000644000176200001440000010735314516257267012533 0ustar liggesusersR 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] (excluding cs.[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-2023 Douglas Bates, Martin Maechler, Mikael Jagan 2. Matrix contains patched versions of external libraries CSparse, AMD, COLAMD, and CHOLMOD, all from the SuiteSparse collection of Timothy A. Davis. AMD and COLAMD use the BSD 3-clause licence. CSparse and modules Check, Cholesky, and Core of CHOLMOD use the GNU LGPL licence, version 2.1 or greater. Modules MatrixOps, Modify, and Supernodal of CHOLMOD use the GNU GPL licence, version 2 or greater. 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/0000755000176200001440000000000014547723665012452 5ustar liggesusersMatrix/data/USCounties.R0000644000176200001440000000073513612521507014622 0ustar liggesusersstopifnot(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/datalist0000644000176200001440000000003713517134750014165 0ustar liggesusersCAex KNex USCounties wrld_1deg Matrix/data/KNex.R0000644000176200001440000000057513612521507013430 0ustar liggesusersstopifnot(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.R0000644000176200001440000000102013612521507013365 0ustar liggesusersstopifnot(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.R0000644000176200001440000000067313612521507014432 0ustar liggesusersstopifnot(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/0000755000176200001440000000000014547724215012304 5ustar liggesusersMatrix/man/printSpMatrix.Rd0000644000176200001440000001525314461332432015414 0ustar liggesusers\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")) 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")) 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) } \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.} } \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.Rd0000644000176200001440000000737614446607050015761 0ustar liggesusers\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/compMatrix-class.Rd0000644000176200001440000000314014422605232016004 0ustar liggesusers\name{compMatrix-class} \title{Class "compMatrix" of Composite (Factorizable) Matrices} % \docType{class} \keyword{algebra} \keyword{array} \keyword{classes} % \alias{compMatrix-class} % \alias{dimnames<-,compMatrix,NULL-method} \alias{dimnames<-,compMatrix,list-method} % \description{ Virtual class of \emph{composite} matrices; i.e., matrices that can be \emph{factorized}, typically as a product of simpler matrices. } \section{Objects from the Class}{A virtual Class: No objects may be created from it.} \section{Slots}{ \describe{ \item{\code{factors}:}{Object of class \code{"list"} - a list of factorizations of the matrix. Note that this is typically empty, i.e., \code{list()}, initially and is \emph{updated \bold{automagically}} whenever a matrix factorization is computed.} \item{\code{Dim}, \code{Dimnames}:}{inherited from the \code{\linkS4class{Matrix}} class, see there.} } } \section{Extends}{ Class \code{"Matrix"}, directly. } \section{Methods}{ \describe{ \item{dimnames<-}{\code{signature(x = "compMatrix", value = "list")}: set the \code{dimnames} to a \code{\link{list}} of length 2, see \code{\link{dimnames<-}}. The \code{factors} slot is currently reset to empty, as the factorization \code{dimnames} would have to be adapted, too.} } } \seealso{ The matrix factorization classes \code{"\linkS4class{MatrixFactorization}"} and their generators, \code{\link{lu}()}, \code{\link{qr}()}, \code{\link{chol}()} and \code{\link{Cholesky}()}, \code{\link{BunchKaufman}()}, \code{\link{Schur}()}. } %% FIXME: add: % \examples{ % % } Matrix/man/band.Rd0000644000176200001440000001006414545063005013467 0ustar liggesusers\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/expand.Rd0000644000176200001440000002377314446607050014061 0ustar liggesusers\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{compMatrix}} of \emph{factorizable} matrices. 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/all.equal-methods.Rd0000644000176200001440000000332714467060443016114 0ustar liggesusers\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/nnzero.Rd0000644000176200001440000000652014467575574014126 0ustar liggesusers\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/Matrix-class.Rd0000644000176200001440000001766614514041632015147 0ustar liggesusers\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,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,pcorMatrix-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{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.Rd0000644000176200001440000000400114467516513015666 0ustar liggesusers\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.Rd0000644000176200001440000000110014422605232014141 0ustar liggesusers\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.Rd0000644000176200001440000000346314500644730016333 0ustar liggesusers\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.Rd0000644000176200001440000000664314446607050014063 0ustar liggesusers\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.Rd0000644000176200001440000002720414467575574015406 0ustar liggesusers\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 CSparse 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.Rd0000644000176200001440000000346214500644730016322 0ustar liggesusers\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.Rd0000644000176200001440000000522114462010167013605 0ustar liggesusers\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/chol2inv-methods.Rd0000644000176200001440000000570614516234475015770 0ustar liggesusers\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.Rd0000644000176200001440000000450014467101201015546 0ustar liggesusers\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/SparseM-conv.Rd0000644000176200001440000000501414422605232015075 0ustar liggesusers\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/Subassign-methods.Rd0000644000176200001440000001327214446607050016172 0ustar liggesusers\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,replValueSp-method} \alias{[<-,sparseVector,sparseVector,missing,replValueSp-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/Cholesky.Rd0000644000176200001440000003665514520542570014364 0ustar liggesusers\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 \Sdeqn{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) \Sdeqn{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 \Sdeqn{\\\\\\\\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/rep2abI.Rd0000644000176200001440000000130414422605232014042 0ustar liggesusers\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/dMatrix-class.Rd0000644000176200001440000001152614500445405015301 0ustar liggesusers\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}}.} \item{zapsmall}{\code{signature(x = "dMatrix")}: ... } } 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.Rd0000644000176200001440000001735414446607050015464 0ustar liggesusers\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.Rd0000644000176200001440000001147714446607050014044 0ustar liggesusers\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/bandSparse.Rd0000644000176200001440000000714414446607050014656 0ustar liggesusers\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.Rd0000644000176200001440000000634214446607050015652 0ustar liggesusers\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/facmul.Rd0000644000176200001440000000373514446607050014045 0ustar liggesusers\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/sparseMatrix.Rd0000644000176200001440000002404214446607050015252 0ustar liggesusers\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/condest.Rd0000644000176200001440000001042714521202214014214 0ustar liggesusers\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.Rd0000644000176200001440000000316014467516513015635 0ustar liggesusers\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/fastMisc.Rd0000644000176200001440000002624514503343553014347 0ustar liggesusers\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/dtRMatrix-class-def.Rd0000644000176200001440000000536114461513642016350 0ustar liggesusers\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/colSums.Rd0000644000176200001440000001043014454070607014212 0ustar liggesusers\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/BunchKaufman-methods.Rd0000644000176200001440000000735714446607050016605 0ustar liggesusers\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.Rd0000644000176200001440000000673414422605232017076 0ustar liggesusers\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} % \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{uplo}:}{Object of class \code{"character"}. Must be either "U", for upper triangular, and "L", for lower triangular.} %% below {Dim, Dimnames} work around Slot parsing buglet (< 2.2.0) %% \item{\code{Dim},\code{Dimnames}:}{The dimension (a length-2 \item{\code{Dim, Dimnames}:}{The dimension (a length-2 \code{"integer"}) and corresponding names (or \code{NULL}), inherited from the \code{\linkS4class{Matrix}}, see there. See below, about storing only one of the two \code{Dimnames} components.} \item{\code{factors}:}{a list of matrix factorizations, also from the \code{Matrix} class.} } } \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.Rd0000644000176200001440000000754414500644730015635 0ustar liggesusers\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/sparseVector.Rd0000644000176200001440000000312514446607050015247 0ustar liggesusers\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.Rd0000644000176200001440000005265714514041632016141 0ustar liggesusers\name{Matrix-deprecated} \title{Deprecated Functions in Package \pkg{Matrix}} % \keyword{internal} \keyword{misc} % \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{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}} } Matrix/man/kronecker-methods.Rd0000644000176200001440000000562514422605232016214 0ustar liggesusers\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/Xtrct-methods.Rd0000644000176200001440000000473514533727074015352 0ustar liggesusers\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/bdiag.Rd0000644000176200001440000000767614446607050013654 0ustar liggesusers\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.Rd0000644000176200001440000000226514446607050013440 0ustar liggesusers\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.Rd0000644000176200001440000000433114467516513015670 0ustar liggesusers\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.Rd0000644000176200001440000001014414507041765015660 0ustar liggesusers\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,dppMatrix-method} \alias{coerce,dspMatrix,pcorMatrix-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/boolean-matprod.Rd0000644000176200001440000001575114477531636015674 0ustar liggesusers\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/dimScale.Rd0000644000176200001440000000365114422605232014306 0ustar liggesusers\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.Rd0000644000176200001440000001553714520542570014662 0ustar liggesusers\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 CSparse 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 CSparse 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: \Sdeqn{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/atomicVector-class.Rd0000644000176200001440000000254014422605232016323 0ustar liggesusers\name{atomicVector-class} \title{Virtual Class "atomicVector" of Atomic Vectors} % \docType{class} \keyword{classes} % \alias{atomicVector-class} % \alias{Ops,atomicVector,sparseVector-method} \alias{coerce,atomicVector,dsparseVector-method} \alias{coerce,atomicVector,sparseVector-method} % \description{ The \code{\link{class}} \code{"atomicVector"} is a \emph{virtual} class containing all atomic vector classes of base \R, as also implicitly defined via \code{\link{is.atomic}}. } \section{Objects from the Class}{A virtual Class: No objects may be created from it.} \section{Methods}{ In the \pkg{Matrix} package, the "atomicVector" is used in signatures where typically \dQuote{old-style} "matrix" objects can be used and can be substituted by simple vectors. } \section{Extends}{%% FIXME: promptClass() should show the direct subclasses ! The atomic classes \code{"logical"}, \code{"integer"}, \code{"double"}, \code{"numeric"}, \code{"complex"}, \code{"raw"} and \code{"character"} are extended directly. Note that \code{"numeric"} already contains \code{"integer"} and \code{"double"}, but we want all of them to be direct subclasses of \code{"atomicVector"}. } \author{Martin Maechler} \seealso{ \code{\link{is.atomic}}, \code{\link{integer}}, \code{\link{numeric}}, \code{\link{complex}}, etc. } \examples{ showClass("atomicVector") } Matrix/man/dsRMatrix-class.Rd0000644000176200001440000000552214461513642015612 0ustar liggesusers\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{RsparseMatrix}}, \code{\linkS4class{dsparseMatrix}} and \code{\linkS4class{symmetricMatrix}}, directly. Class \code{"dMatrix"}, by class \code{"dsparseMatrix"}, class \code{"sparseMatrix"}, by class \code{"dsparseMatrix"} or \code{"RsparseMatrix"}; class \code{"compMatrix"} by class \code{"symmetricMatrix"} and of course, class \code{"Matrix"}. } \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.Rd0000644000176200001440000000531214447626522014445 0ustar liggesusers\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.Rd0000644000176200001440000001076614446607050015441 0ustar liggesusers\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.Rd0000644000176200001440000000673114422605232015352 0ustar liggesusers\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/number-class.Rd0000644000176200001440000000112314422605232015150 0ustar liggesusers\name{number-class} \title{Class "number" of Possibly Complex Numbers} % \docType{class} \keyword{classes} % \alias{number-class} % \description{The class \code{"number"} is a virtual class, currently used for vectors of eigen values which can be \code{"numeric"} or \code{"complex"}. It is a simple class union (\code{\link{setClassUnion}}) of \code{"numeric"} and \code{"complex"}. } \section{Objects from the Class}{Since it is a virtual Class, no objects may be created from it.} \examples{ showClass("number") stopifnot( is(1i, "number"), is(pi, "number"), is(1:3, "number") ) } Matrix/man/diagU2N.Rd0000644000176200001440000000546714446607050014033 0ustar liggesusers\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/unused-classes.Rd0000644000176200001440000000104714422605232015520 0ustar liggesusers\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/macros/0000755000176200001440000000000014547723665013600 5ustar liggesusersMatrix/man/macros/local.Rd0000644000176200001440000000126714520515200015136 0ustar liggesusers%% 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/CsparseMatrix-class.Rd0000644000176200001440000001150614500445405016454 0ustar liggesusers\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.Rd0000644000176200001440000001151314461513642015570 0ustar liggesusers\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.Rd0000644000176200001440000001056114435451016014452 0ustar liggesusers\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/expm.Rd0000644000176200001440000000506514455203155013543 0ustar liggesusers\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/man/LU-class.Rd0000644000176200001440000001155114520753540014213 0ustar liggesusers\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/rsparsematrix.Rd0000644000176200001440000000623114446607050015474 0ustar liggesusers\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.Rd0000644000176200001440000000173214422605232015455 0ustar liggesusers\name{Matrix-defunct} \title{Defunct Functions in Package \pkg{Matrix}} % \keyword{internal} \keyword{misc} % \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}} } Matrix/man/spMatrix.Rd0000644000176200001440000000572714467047212014411 0ustar liggesusers\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/isTriangular.Rd0000644000176200001440000000601414467101201015221 0ustar liggesusers\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/is.na-methods.Rd0000644000176200001440000000553314473267633015256 0ustar liggesusers\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/updown.Rd0000644000176200001440000000523714467575574014133 0ustar liggesusers\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/matrix-products.Rd0000644000176200001440000003666614477531636015766 0ustar liggesusers\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/generalMatrix-class.Rd0000644000176200001440000000231714461513642016476 0ustar liggesusers\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} % \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{factors}}{,} \item{\code{Dim}}{,} \item{\code{Dimnames}:}{all slots inherited from \code{\linkS4class{compMatrix}}; see its description.} } } \section{Extends}{ Class \code{"compMatrix"}, directly. Class \code{"Matrix"}, by class \code{"compMatrix"}. } % \section{Methods}{ % No methods defined with class "generalMatrix" in the signature. % } \seealso{ Classes \code{\linkS4class{compMatrix}}, and the non-general virtual classes: \code{\linkS4class{symmetricMatrix}}, \code{\linkS4class{triangularMatrix}}, \code{\linkS4class{diagonalMatrix}}. } % \examples{ % ##---- Should be DIRECTLY executable !! ---- % } Matrix/man/packedMatrix-class.Rd0000644000176200001440000000431414476733334016317 0ustar liggesusers\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}"}, \code{"\linkS4class{pCholesky}"}, and \code{"\linkS4class{pBunchKaufman}"}. } \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. Class \code{"replValueSp"}, by class \code{"Matrix"}, distance 3. } \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.Rd0000644000176200001440000000407314446607050014456 0ustar liggesusers\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.Rd0000644000176200001440000000416514467224234016505 0ustar liggesusers\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/lu.Rd0000644000176200001440000001426614520753540013216 0ustar liggesusers\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 CSparse 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 CSparse 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{compMatrix}} 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/rankMatrix.Rd0000644000176200001440000002103614516234475014715 0ustar liggesusers\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.Rd0000644000176200001440000001102114444013764017666 0ustar liggesusers\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{ The virtual class \code{\linkS4class{compMatrix}} of \emph{factorizable} matrices. 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.Rd0000644000176200001440000000760114446607050014761 0ustar liggesusers\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/replValue-class.Rd0000644000176200001440000000132014422605232015616 0ustar liggesusers\name{replValue-class} \title{Virtual Class "replValue" - Simple Class for Subassignment Values} % \docType{class} \keyword{classes} % \alias{replValue-class} % \description{The class \code{"replValue"} is a virtual class used for values in signatures for sub-assignment of \pkg{Matrix} matrices. In fact, it is a simple class union (\code{\link{setClassUnion}}) of \code{"numeric"} and \code{"logical"} (and maybe \code{"complex"} in the future). } \section{Objects from the Class}{Since it is a virtual Class, no objects may be created from it.} \seealso{ %% FIXME: bug in Rdconv needs '[Matrix]' below: \code{\link[Matrix]{Subassign-methods}}, also for examples. } \examples{ showClass("replValue") } Matrix/man/rleDiff-class.Rd0000644000176200001440000000263714422605232015246 0ustar liggesusers\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.Rd0000644000176200001440000000513014422605232017217 0ustar liggesusers\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/BunchKaufman-class.Rd0000644000176200001440000001535614446607050016245 0ustar liggesusers\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.Rd0000644000176200001440000003170014520542570015430 0ustar liggesusers\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 \Sdeqn{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) \Sdeqn{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.Rd0000644000176200001440000000250314446607050013406 0ustar liggesusers\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.Rd0000644000176200001440000000136014422605232014772 0ustar liggesusers\name{index-class} \title{Virtual Class "index" - Simple Class for Matrix Indices} % \docType{class} \keyword{classes} % \alias{index-class} % \description{The class \code{"index"} is a virtual class used for indices (in signatures) for matrix indexing and sub-assignment of \pkg{Matrix} matrices. In fact, it is currently implemented as a simple class union (\code{\link{setClassUnion}}) of \code{"numeric"}, \code{"logical"} and \code{"character"}. } \section{Objects from the Class}{Since it is a virtual Class, no objects may be created from it.} \seealso{ \code{\link{[-methods}}, and %% FIXME: bug in Rdconv needs '[Matrix]' below: \code{\link[Matrix]{Subassign-methods}}, also for examples. } \examples{ showClass("index") } Matrix/man/norm.Rd0000644000176200001440000000620414520545102013533 0ustar liggesusers\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/Schur.Rd0000644000176200001440000000673414446607050013664 0ustar liggesusers\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/denseMatrix-class.Rd0000644000176200001440000000343014500445405016147 0ustar liggesusers\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.Rd0000644000176200001440000000422114467516513015664 0ustar liggesusers\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.Rd0000644000176200001440000000421214447626522014634 0ustar liggesusers\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.Rd0000644000176200001440000000361714467516513015642 0ustar liggesusers\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.Rd0000644000176200001440000000555014500445405015313 0ustar liggesusers\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.Rd0000644000176200001440000000432214467516513015676 0ustar liggesusers\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/dtrMatrix-class.Rd0000644000176200001440000000561314507041765015657 0ustar liggesusers\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/ddiMatrix-class.Rd0000644000176200001440000000624114500644730015616 0ustar liggesusers\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/cBind.Rd0000644000176200001440000000615614470702707013617 0ustar liggesusers\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/nsparseMatrix-classes.Rd0000644000176200001440000001332414461513642017064 0ustar liggesusers\name{nsparseMatrix-classes} \title{Sparse "pattern" Matrices} % \docType{class} \keyword{array} \keyword{classes} % \alias{nsparseMatrix-class} \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/TsparseMatrix-class.Rd0000644000176200001440000000554214467224234016507 0ustar liggesusers\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/isSymmetric-methods.Rd0000644000176200001440000000761114467101201016532 0ustar liggesusers\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.Rd0000644000176200001440000001220614545303537015321 0ustar liggesusers\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/uniqTsparse.Rd0000644000176200001440000000625414473671326015122 0ustar liggesusers\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/mat2triplet.Rd0000644000176200001440000000455614473555676015067 0ustar liggesusers\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.Rd0000644000176200001440000001350414500445405016351 0ustar liggesusers\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.Rd0000644000176200001440000000435314500644730016334 0ustar liggesusers\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.Rd0000644000176200001440000000421714476733334016664 0ustar liggesusers\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}"}, \code{"\linkS4class{Cholesky}"}, and \code{"\linkS4class{BunchKaufman}"}. } \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. Class \code{"replValueSp"}, by class \code{"Matrix"}, distance 3. } \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.Rd0000644000176200001440000001735314545303537015644 0ustar liggesusers\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.Rd0000644000176200001440000000354714422605232015575 0ustar liggesusers\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.Rd0000644000176200001440000003341314520542570015501 0ustar liggesusers\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 \Sdeqn{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) \Sdeqn{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/graph2T.Rd0000644000176200001440000000704014473555676014116 0ustar liggesusers\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/sparse.model.matrix.Rd0000644000176200001440000001453314446607050016473 0ustar liggesusers\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.Rd0000644000176200001440000000651014473555676015616 0ustar liggesusers\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.Rd0000644000176200001440000001104014500445405016623 0ustar liggesusers\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.Rd0000644000176200001440000000666014500445405015620 0ustar liggesusers\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/dpoMatrix-class.Rd0000644000176200001440000001426614507041765015654 0ustar liggesusers\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{pcorMatrix-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,dpoMatrix-method} \alias{coerce,dppMatrix,pcorMatrix-method} \alias{coerce,matrix,dppMatrix-method} \alias{determinant,dppMatrix,logical-method} % \alias{coerce,corMatrix,pcorMatrix-method} \alias{coerce,matrix,corMatrix-method} % \alias{coerce,pcorMatrix,corMatrix-method} \alias{coerce,matrix,pcorMatrix-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{"pcorMatrix"} 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{"pcorMatrix"}) 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.Rd0000644000176200001440000001027214461513642015245 0ustar liggesusers\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/lsparseMatrix-classes.Rd0000644000176200001440000001504614473555676017105 0ustar liggesusers\name{lsparseMatrix-classes} \title{Sparse logical matrices} % \docType{class} \keyword{array} \keyword{classes} % \alias{lsparseMatrix-class} \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/nearPD.Rd0000644000176200001440000002064714446607050013750 0ustar liggesusers\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/unpack.Rd0000644000176200001440000000760214446607050014054 0ustar liggesusers\name{pack} \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/symmpart.Rd0000644000176200001440000000505614473510330014442 0ustar liggesusers\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/invPerm.Rd0000644000176200001440000000720114443717760014215 0ustar liggesusers\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/dtCMatrix-class.Rd0000644000176200001440000001061114446607050015567 0ustar liggesusers\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/abIseq.Rd0000644000176200001440000000356714422605232013777 0ustar liggesusers\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.Rd0000644000176200001440000001603614446607050015317 0ustar liggesusers\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.Rd0000644000176200001440000002475314500445405016357 0ustar liggesusers\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,atomicVector-method} \alias{Ops,sparseVector,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{[}{\code{signature(x = "atomicVector", i = ...)}: not only can you subset (aka \emph{\dQuote{index into}}) sparseVectors \code{x[i]} using sparseVectors \code{i}, but we also support efficient subsetting of traditional vectors \code{x} by logical sparse vectors (i.e., \code{i} of class \code{"nsparseVector"} or \code{"lsparseVector"}).} \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.} } \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.Rd0000644000176200001440000000510514446607050015554 0ustar liggesusers\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.Rd0000644000176200001440000000252514500445405016516 0ustar liggesusers\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/chol.Rd0000644000176200001440000001766714446607050013534 0ustar liggesusers\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/MatrixClass.Rd0000644000176200001440000000221414422605232015011 0ustar liggesusers\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/rcond.Rd0000644000176200001440000001222314502643141013665 0ustar liggesusers\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/Diagonal.Rd0000644000176200001440000001122314446607050014303 0ustar liggesusers\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/DESCRIPTION0000644000176200001440000000563514550025127013236 0ustar liggesusersPackage: Matrix Version: 1.6-5 VersionNote: do also bump src/version.h, inst/include/Matrix/version.h Date: 2024-01-06 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, notably CHOLMOD and AMD", "collaborators listed in dir(pattern=\"^[A-Z]+[.]txt$\", full.names=TRUE, system.file(\"doc\", \"SuiteSparse\", package=\"Matrix\"))")), person("Jens", "Oehlschlägel", role = "ctb", comment = "initial nearPD()"), 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("R Core Team", role = "ctb", comment = "base R's matrix implementation")) Depends: R (>= 3.5.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-01-11 08:36:29 UTC; maechler Author: Douglas Bates [aut] (), Martin Maechler [aut, cre] (), Mikael Jagan [aut] (), Timothy A. Davis [ctb] (, SuiteSparse libraries, notably CHOLMOD and AMD, collaborators listed in dir(pattern="^[A-Z]+[.]txt$", full.names=TRUE, system.file("doc", "SuiteSparse", package="Matrix"))), Jens Oehlschlägel [ctb] (initial nearPD()), Jason Riedy [ctb] (, GNU Octave's condest() and onenormest(), Copyright: Regents of the University of California), R Core Team [ctb] (base R's matrix implementation) Maintainer: Martin Maechler Repository: CRAN Date/Publication: 2024-01-11 17:50:15 UTC Matrix/build/0000755000176200001440000000000014547724214012627 5ustar liggesusersMatrix/build/Matrix.pdf0000644000176200001440000334160214547724123014576 0ustar liggesusers%PDF-1.5 % 2 0 obj << /Type /ObjStm /N 100 /First 822 /Length 1261 /Filter /FlateDecode >> stream xڽX]o0}ϯ6664ikmں^($_2~UhI `s8LZ3X| `B1p0IcygR0%BJeR3-&}{Әo4ÑQ>m!ї80S?| .Sz=;[U.؛m\.[/78˷G7_8_.4cwn(|S)$)QHuz3݀ds׃nȒf[u.,)mEPR(\}n\rhvZ|W=MI G9sZ~TQw^5ϛ0_6azhΔs]U ͵P`=]-ڦ(,l} p!u\t ?h-faR?}rsmoa;zeO#&iwK6>wG7> stream xXMo8WH}E/  Ac/8eʕ"ɯyJACdK=Er޼"<%<<_hK 􅒞&U 5EFPp F_%# C?4QO|| D`OHi\x E R=QTY$t$eO$ N}  >C0S>Ðp(¨%#0H90,B "$ʣBHb, G)`*8 ]99 W`Q$ȃ y$H @p 4&M7MAPs:u#:; /8\ 1 Ao`E<jqfujF" AȃQpPHO,ԁa@fj5!8h<)11  C6 I AC)L7`G`tLϹA`4 MHeM &(~pX8{铸4}ެzXTSQ|<LxbŚ]ZsEłcO:-m:]rssqN6?CKօ>=ǸgYY9{e_H̒K\&s.^\v{)Lr M\Vl=on6ƮKx̺c.Sq>!o<:Z:4۞7ksiI\睫=|򇴬|u CPݍez|"dmuwimfQ}3'ʏ ц9e̻Kпlx i{=zU6MVVX^xך^@|Z|u-y{{!"K*{1,KmkKuxSp"?e^[.W]`xa/y`li~io:8*=POj/a>/vw ґ)r9ъi۳ASvo!"9-/c3(׸ {7g> 5^Y9#;hѦqyw"m>i9&.پeq|!xmo0{3bCoa!{!=}=ݮa0g17qꊲi/ī?!wOb3҅#˦v7vosNelWLʤ-a% endstream endobj 528 0 obj << /Length 1324 /Filter /FlateDecode >> stream xYKs6WJwf֯d$tZ)A`w$@ZmJVHG޽<o=wD1<7#JCDQGƗ,%|bQ`L8}4x#BP躴`{NX ޳b&@(Nq&DGZE<"”h]"!/A3("lP|Ȟ kB2iFժ3YF/hi0IsieU̧Nذ0:'& 2e v[c%jéRښeSmͧ]l0}I "۠mseTBYA(tmiԣeKV$n ,~lY#;oCd7V/-f2"3!˓*c%"gٚ oAS_ReB̫Н$:ˢς)\OxjD˅zz334JዱlLn@BT]hU}~ˍf]ɊTKglGyrRȭM|ŸzżJ䭧Є!`9RScx+.[o\SaB+ 鶊[P?Цf=G%LpVkr6CۥR|=5ͬuNR#]s(jP9/Dv]nϩ*r 4~CC燤UL> stream xMsH[|:Y9L@lDF'E XV=NwOuinzQJGZRlq(I17zlBFy>גDȈe&SA\S&5"3.>2nTnMo=_ <_pލQSo͏qC:Y;\?A(IemZ?}iˤTp],n:B%t\"ߑ*#\^(E-\ANn'e "S} 'mY{ώ8CAvܗٓ@} :lӴ8qK!pG0Wp{> E(y%@0 @&{ o븺+XM׍ZtAY$ *.P]ތ>݉@ȫ븭+OBC cKVb錝SX }$yaAb-HH'N34Y% x꿿pq:pʑiay^MF>+Q|pA`n]—98ri-8Ci% 3p}%%~AG $,v .V(7w!!R&l{ 1T_\ drRYeE> stream xڽZnH}W"yH/շw533 EmmdI{ncѲM$0烇?lEG!U yl|>~EcU3d͸y9U>̼l u;Ɵ\_^Tnnˆ+)qyC­ehOvg+]3;ӯzt{{Y n͠ΫqYIbx- OfqUA/q(1+`'뽽x=ZM8>b^sN6} O`X',3"Hy}{FUsaōכgfQS?]\An }4FQckq7HIu+!F7t22s5-!*Uج@K2 |f~ (hcy5YC؁˫+7YC܁ceZ5UԠU ,(,An?H CZgdX=0kkv0=*]=w՚\=Ľ.|,{UQVG%,(݊tCMM5jrM5R\c)X5ru:2x.㹌2x>3x>3x>ㅌ2^x!ㅌ2^x!ㅌ2^x1Ō3^x1Ō3^x1㥌2^xke!wm#tŜ$f FEoT/$ @9[ {_Ĥ%l5ؿm d._ &UbV6v&Q왳6 ~@cFKX/lr%퍣 .h@ҡ~K'J7 &moUl5X+CWӤӆ9[ HYt_&@"ň LW&tWޅOj- 9͜mUWv(9[ mUWv(il5Xlb/lcVr*ݮE8NtWvM~?p6 endstream endobj 705 0 obj << /Length 1018 /Filter /FlateDecode >> stream xrH~ ?Y&OdJJ6,j۔ѴTɒ_ <ݍ@R}}tӍHpϳW&1`vPB.T*H΂<^FgHΉ&QZoㄦ^2$Wu/Sj2n҄zs!N9#\,.O*mkٲ0bIȩ1a!iI߽^d?Śk$)K {("_| b,ls[;S_er V3WUz_[ PO@".C_dfUf>b$q!S ۮnHZ$F[m r7lW|bp|`Ý"Jںrt~(m]έ[Is1d,M˛SfqaQ\d~Kl]`[]RX0)j !Qa]Q}F")*pJ@諬am0ҝXljU6y@u@oj9<`,6Sh=`O2>@{K9EfyS[{0 nYYeX=-Tfag3k:/\l FIp%HK 0@:zۗΏ€׾ qsXQ_ZƓ塁p-C*L֏kZly$q`Y7lkLǑ wYdZ1rXc@=]4Nx[ڇ lpb7kl5-u,3w|w ?i,v/gTB1YVa!}iϋay40r-V>֓m*(V\G19C9O*]Ge = XV叭xPlYhi,ǡd'U=eS@`){|B},pEC$]㨳on$CP̏; endstream endobj 779 0 obj << /Length 1897 /Filter /FlateDecode >> stream xZMs6WpU{Ty`|:fS{S)!~Xҿn!G< xu2wibRFW7$TJ#4wY_~ /1Y,%_%1.C<)DG5_DBИ꠳¯% 5? XlK3Ow=NH迌τ؜ٟr^ֶ 8*~&\(=M^we#ϒ2噹q Eaק/`ҳD9 L6@fd3a{W;+._3.?-le(?*[U .A4;/+߿-,V,=oP)f;[kL3_ r ߥrtb:ZPxCzr aRٝQ2=.qus_SRF ۋh~ѽ빍ƈJ7_N 2JRxhC("'jt81VNڝ(M4/1|bDO^=W$xo}B簕 gϜQu^7mqó72I8U/ƟˉuF|gc0BQykkC9tN #DgJԽ^qs[0pΑsY`q\$aĢoƮl)ʵ/[߂˂xmmF|ZM 1mU[l`iRl7Tb9q{8;YO#|?$زںOyB$D|̛r,_7>8QRoMo?~.rraVRm!8!IZ&f >h.&TQWXrK0GyWRSl6v ?le۬45m>k+6*-8P7Xu[U6 Qi{1`rNLŘag\UC^jw=&V1l2jOqHĮ `s["Ǻ/(٦+q:?)yLV`͐W97t"Ua&"GBhe(i44y]$g9]m:YJ;ƙf"`Pdr+S/ńɨ`}e%q/(Bqt{8`p(GY<ɡXvartv|.^*h):I48hbw endstream endobj 627 0 obj << /Type /ObjStm /N 100 /First 916 /Length 2211 /Filter /FlateDecode >> stream xڽZMoϯ1dU0] `>$1tj'GH2y5Ct\@{UYyS4RX9d)*Xq͆4Tv9  @dv(]D *sqbH @Jj.,\Xsva ԅkFJH pD͵PKŅq RVBAJ ?99 KB.!kv ηj(1O nV\z*wą7uq3 Α-vxHd.pW֠Ip *p`&@'p x7&K%X.,$S V P8T_pC#&W5p ղ KU]Xq(Buq7% T,vPx|kp0 {M8[+WF~RlQgfQ YqJ.3S9yxOb߈¿b(E S" N(<իÿ~>77?>?n~:}W8~wr!a,ppD81ǸD6}^ :O;-~怿0-|ĐL

P+w?2?,Etaգۛ7>ty f7]cLx h7CzopO7Ԋ?yJOyaL:TOwP4z?o=|濬Vmj>_֦O>i铦O>i铦O>mӦO>mӦO>m鳦Ϛ>k鳦Ϛ>k鳦6}M_m6}HYv4|~}W&Z0f=渤Q %3vs![(U;$K]/W8͕/"Rh̫+~t8ŘF?M#—jgK)#_eotҍvYc4QPdqEA:BPV;4[(RD&z$O@[(3鯌TuE^(PXqO(:zD&8_#),#6`YIt YV; d8*DʅQrA IpvEJ*:фUjGAd[(rzdBf3ک$1.CLԬXWC`Faa %ՎBee {谰3M@곾7g[dXyBȬnHhl ՎY, ;ψTLiU3 ;(6Sf2xBLR YJ"u3%KiBeLAE雀b+1KiBLR6'T, s3AKyƹJRPG6sPp\*=imXjD*$jLT- 5u3YKeBMLR/6T&T͔- ud3iK2#FҶ$3N'[[z y+sY_ U[)l̬6fV3jcf1ژYm̬6fV3jcf1ژYm̬6fV3^{H̺$ yXGN[a@2CHgpFNOL#g ]oM=i >@ >fI+>m9tQ;f0m)f0ĨA+5 :)#M3QiT Z`I+ʼ =2-MV#sԓ< g5F?[$ɿnL zF(E_o/C oY/oYRr] s0ntzGs߾^{ yajv ~Gb endstream endobj 839 0 obj << /Length 1816 /Filter /FlateDecode >> stream xYmo6_!tf1KR[趶Xl  m?(2mEW&$ 0DIysw ^~9=| CYL|Q 1Bςw|8yf8FILa-=/RSF.sS7yJ|K9k׀(N8 6+^d2VD'o~st\cXe 1zӬw. [;ֳu_77-/lZ"z_\BXo1)E%sr4~8F!%;*ϗ)ɀKd.RNh4NE\VJg-hQ5%dQdk^筐UcCͭFe:dk^iCiP+C_% 1M ;rR -6t j |ƴK+o!ez1վv'!hzO*@Jg*bbK,R8,]]}ڬ]#hk\bxk= lq5ԹBW}hg~ endstream endobj 862 0 obj << /Length 1697 /Filter /FlateDecode >> stream xڵX[F~@Cm)HZ%Ql"UI0bw}\eWV̙o <콙z;ҋP$n<1b\zH0./39vM; H2b̒8ː3u v!o64ГVħ*^޶cϫNC'!RW,]Ylx>s4,&h"!좋SoZпfoZFpe*_kTlQ,B `;ݡ?}Y.+Z hPDg>$1%ꚇp$)%= r{*-~ϗqD()A>qJVL^Btx] IFf+h ÏCt.\^+N/ΗvoMIռ1 u2; nD"'a`qϾC,Tb3d':?RUi@[,NKK\z\ήl^~DVstjmsg`|lN}吶4dGACi/4(Ba S?Ci^dbKd S[pEG}|weiiig|`N$:/{jƄG_VΩCbpUkMh're\>iG! @[*#bJ%HtVq@MX_1eUY'mAoϘ:U Rk?zf:p;Yl],Ƶ+uhJgCF'Eĵl#nλ1'%8}壱D yDm<AqswEUkt 8 1)oc:ɽO D"8!׳Vʣ\oJY:6n7>r"Dعл,Xԗ* 0P 'Nr-jSR=/ @b,StAok#fܚE\#9DAdtKH^?ƛLU !H%Q$.CzZwI`41 m FHo 4/^ia|b[*{xiu{#B$ 'M %^(ĖzrT+DR-Hݑנxa#|C(v4. /L|^ĢۙCp}u`.!a I=m\u<7JcMtJwN-Y榞r.z-I8DK#?e K*)P:~ͻg0@D/ 9 n|1aYE"8]Vi'w }+D/VM%㈲T˛Re|A9TbD ݤAUQI!~~77Aҍmǭ\>%ɶ4%^H0SO~r{1)A\ѭ? 㙊W+I4WqzP\dWl+Ql}8M*`l R4*;wUr_ؾZ+d%!C#{1GsccA}w۷AjYRzh/+6tE虵|> stream xX[o6~E$lIKf$;ȺDv?H9(-=6<PPͮ<1b3qT\mf?^ њc` z;0NS*urrݬUtfnz<dwoJom{U^g Jn(9DVfzd1:b>*^wCvh[W9#oL;"䈶:&G\!<ި+~ m8P+۬eҬ#5 )2 ۯWgz^PgF#ˮ/;;O/ʹb3..p>lFH@!w^8cx׫G^et2ݎ :y@QoFboVwgx>!H |qcrlm D@  VKљir,s^BVD"[Mq`Ndk8لq딶fqDl8CA(Ev?oT1w8KYǹzjnYn ?xҫ_rsY=kf. ߮\EjupQxvSQhi ڔ.;H1@rc_&S"ې5 u"&CrcVQȍ/F`Y˗ϙ~QDK{".!}xe]BCP8w[=!:eI]ȊY/.sfhr% eok4:6԰nTZnOdj-yvp/g1 ]~,wAqHҠYCV%Afb$6 =`CuP\ d` :Vy\;<ٝ lo) ِCXٳ>@>l8dCQN!֧42B Acg*!λ)} Ape+[R(a"=M<0u=5IϻAf|Z%XiZEE ~dZٗ UIinmǥeRkyKY18C2H*{fF}(̒9 cwbdKp-B~DT:p`.j̳ ;N,vϳIB. /]4w8*E?8/zyOn0wOq$>MB 7Jm `T۠,U(We3ڜ/p> stream xYMo7W^3F$ j8FA7QWr$M}߬֩TYW$5>#r\LX]qRLhp\%'RJNT\q%AV͛N1(;_\e뫫Ő1P]Fb#CEkFCl l#lD63fhʜ*X XB6p3c6 V`#XYF悑 P`Ӕ80BRƞSrK(vB#F̊ S #4u>SɄHrf%(x!BU' )ea4&A$'CQJw;fm``YŚuǜ$La +OP..o˕/C83 L_5hVh;bMxPN6\ 3fSAT_d1`ȅm c{Xe5$WAJ0FHdd^aK)M:(XP4BK!.u &AY|9V(˫+r1]j5SA.Cwf܉k~WN,Q7WWdc0a;pE6do N *1H|"壕u:6ӎ!l:͡s+̬`xhQ \s|xڝX_)^+0-VEV]uz^\N,޺peOx!W%^\+HAs#w>R~#'07h/+ypX.x=b6Bd F PX^5"W\ ;BkSԄ{T] 7٘( 7(GEӗ!k%D;$& CMv7i|Dd8} {Ja¹2T8"j&+ 6HH8VG{V3a[ 5 }%|] .s}p_/ .Sg8bD>hOH sk` .ʞ0YmRD*𹜑>9)_Ud Ӳ&`Ȱ jq $GAn@F7H> b.gg tu77ӫd>"$<)75XE v tnƧ@njk,(&!v@+'/ƼR3Vnm.>ÏWCfV$'"wewT9u0GP<FX!=LCTAF߃0〛AASaUDcP\/fd4ZCVZcfO5filililililil-cV`t,#[F#Ou{8${-J˜ .8Wo_g&>{LF]$zP R2mnyH;YnQ7VÛt^ɰqF+<]Q}IMh"Jʈ8i- 7*W^18&2]H}7 bqsm2kTh䝬s4c5h+v +A$ endstream endobj 922 0 obj << /Length 1324 /Filter /FlateDecode >> stream xڝW[s6~W0u$6g$gC4<(`mr]7ÃJ;55•A0FcQ#\?~tAr|"vǘ2e)W`e9SØITZa V-C~2p (-y *ϼlFA2[7  Uٷ]zU:/ɑp4 r K!cECV/Btg؄ Fb|}.m*rapU Pt6^w!>W֏g<:xa_h.ծ5! "R*Cxo؁w %a|LCyQ %9.c=Y'#F ^%.3jM:q0r97-,"R`O+ ?ѳ2z3}/@nLkĎ)>*> stream xXKs6Wp|fLx$fC$fN$>@"Hb)R&eL/" -vQ ^OX _E2$Bb6PVF  b1h28UA}dt/ N2~ivFz[Ń#N;4!ED8 kṶX=+d( 'wyQyǂbCq:VyJ߃ղ- 5Ɖ O1rUuMDNgUƽ߃U-@ -l0G${ֲyH SA6ZLQg8f|g5-gVViCĈqAAt*w!7ЛF7 ͧ{hZ9ypD俞sxA!<"> AHMaef凱Ҧ)8jO&L wg_ϰ5z<$ȶgn` ~ Qwt0/?&E0$q80"Fb2H/L>6.[1|!HvMބ΀ nhJcj:yUA>* k:I*@(^V!Y-L5 lFiZ9T]U*msh6~JG*eM@2 ރX * @ZTƇ읞Ow<$D:,5"QDq8Y 9t/h8TjYνMc;jѕ<]Ct̘.F6=" /=lvz߻y& Ͼ7WV;,4eQOxR ',A'^C,xOcXn.r lL խ/(~Qf6vf_N̂ @)4`irzBC{ˆc@SS6 >p}[+N۵* B#/8w ^rc9`'|@uM>֨!wh4 FO`jC)ɥsj܀ف0 ,vGh"o7#&%`ZجݿNW76=Z0ڎg2h  RH;аKf0Y߰xѳ]]}Gvz3WHcQ ?y%Ж&qZ*h u=L RW嗹Q_wޗ6*>n]Wc/FQگs/ڀe#'r3!U Yiy_']ù-Ѓ4v7ODX:G}9Z endstream endobj 982 0 obj << /Length 1192 /Filter /FlateDecode >> stream xڽWKo8W."D=ݠ]t\Zc/v+S^Rn^e BJghl~c:$tk#AD!Oe|cct$}J=PeR[V=TZ=DsyZYO2"B{p8Ueky>҇mZYWE* p<#y?/v⣷wh)Tkst=}j> 4Dy 7S (aKq@.\B+#~h9]*$;<$ #e)yw𩮡 ZyAԄ4+PpzcU\PXKߏp=gV/nfSH7qdz*;dٕ~bn)r+ftB](m`܍\:i?Q?'d'hj V5z ueu*YnJ{M`^f ;4fKW,0Z{>rN lO/_H37^NowEM ۓݘ$^V~U0CV0,sz|чl3Q`9}ds0vJ.+_4̎ɢHEA'xKNz K`zȌ?>

> stream xڽYYs~ׯ@i_@́aǩzTXܼ~!pв=3`@JJUst}x[xuqq)4H#yG xyqDX{_eVoYٷןh#$48N-\s ]liʼ7=)Mt 9 _q( "IXL=GV *>ٜ %>ƿ™r:z W"a?1a3F*APb)ISK&NAǢ{{<Q3kTVf h*[ C":b*K=G\!)`"j`j_3X6qز^!賌%G("{_LQrޡxN,׌M#0+x"qGpOq=S\u@qhR ]e;ZN(d*k$rcaɄ-=06ǰF{SveE; =2O.?DZh*Ve8r" ucBoө'EoT䃉T9t9}ܣ.d\<^6PIbUXlRT[ʖ(߀VizwgsAC|r9^hD"۫14k=Az&ppe'&Z4ۢ >h:$ 4wHM'`EUI@ r4 x< vU&+SE .!̄Yp j̈́9س) rq!zJ٧wIڕ1N%Hzcg|άR@ 3*I[z͛RoT a.C^ʱE{;魄|G}peDVBλZuS j#fW [9T@!g;>qb!fiIpt(*bTgǺW'lѷ)%I1 yvrjѭNc)7wա0*z"$# B"<>SN,/U!ҟF]iAg-7 f[,TB 2OyV~WC[t8ʱ 8 W6Z4ŐӦE|hG}|i1F"mUsF*56 1X`$荜ץub?H&^b,hqWu.PZ"541+uo,t3k0&D V3 ^vdTd>T3 ߱O D}9A]S*EE ˌXSeE@U A ;[Ӿ&\Y6|8fD%֨Ziݏ 2&d9:G^ =wx-}v(%۞'q!Ĉ͏l/ds-P( -x 'pa! "oZ4l-'s%o #hO;mS[w Sl{Aۙ%k[f~+ )m 3O95^H> stream xYKo#7 W^d"%EC`^Mߏq^dzqX͡>I$EJ1; Պ]LV\,mvDmq!KAFց-Pձr+w&C$#F#fc`h

<qoyD2ðZ nveb~Xʼ08@q;lN܇?oڔvI\=Ԩ$^n>'W*u endstream endobj 3618 0 obj << /Length 1657 /Filter /FlateDecode >> stream xڥXKs6Wp 5c"xٴ'q:4Oi4IL)R%w)RlŹ ,vv!6y3zNB|0JC' ) w h<:}2EEpu~eE4jÄs.擿' a#8'~9f+u0с$vҍ3F"_p' `%>`IθFldH^V3FU~'d[ NB; GGGAL`;dum7r2}1i"hIv-`Z\a|wa@`\⒲*m!8״ỦiEI7r<^[0cY,0Om}cVi9R9U&3O0~(SwYWݪ,cpnPi*Ϙ02G3wIoh610 S%(q~Mfٷg,vosk%nԬiAvЭ* a=LDRI:Ȉ3M f F9a,$Xa Gc쮋g0FFq:  &ϞR4 GN4kem,&أWƜ OjOo&gSG=b5 ˃ u0c@hyOND8‡b1c}_RmnA!3׹\ Jfc2(5dUٴyk%lU } Mzg۔&V7$!h#dsQIدχD нp;)k\΋:r8EXkAL<. +\Bۋt-7Q#W^@-'G?\̧s3x~y}1NLa^GP/O5T'mE&C=[`īۻeVm4fv/SMnڠdclN1PCqzq50.K endstream endobj 3641 0 obj << /Length 1768 /Filter /FlateDecode >> stream xڵXIs6W0ʅJ- LCdtȧ4$p>,\ r2@oag`٫w"qʝ!#N1buVk糛凸.eUzc^QET 8fy} Cz"g`g ;) uΜO?:~ӧ'C;FG4dGXZR;g)k(\r-JY,[HpDҊy&CVX0 @R < ۝'Z֐ҳ >2~\[jz~5B CNˍq6g/'gZ{# B'^?:#8ElPjt`XdAzl2To }na\%QEqf^`HRiBٺZ?ޯsSR0NuZ;q[) Q9|ć {[Mp Lr9k]]{r"tlʰȷnIq᠃-kuUIQ::ͷ6VR{In:2P+Gwq@n2WEE^Z%(PGQ?QBCrq֞V l ÆRPDODƢ7r`R6rw a K3B[R0 EWA:A^E$Oeook_N^dFF`<.'Tއ\m贮ea.ђbɢzD0BPJ b,v7MzDcay;j*"q[£t~ ige]b}hin}'0^L[W*y7\uAŃ "#h;-2NW ֢Ӭf$ e)AԻA)iH:qThË}9;6s'aLT'1M-$F&V:tD?£>؞k;I#w*>Yƒ 5 0P=+1Iˬ*~KyQ@&Qq7ɓPH諧x@a(6^8'hz #4 ~{u\ץܙs080 _TJZ_ZItE.j+)C^1%$/'K\?:c#[ ZpkDZ=n@u/2$5q:bGϭ6wj U endstream endobj 3555 0 obj << /Type /ObjStm /N 100 /First 979 /Length 1874 /Filter /FlateDecode >> stream xZ]o[7 }">( (f6`4} [`ݿߡ&M]ߴK^%Rr$삓Ou:#&c1UbURnBqtA786Q&|7W\aT`9CjP&+$FG1 ʆf(8P!fBHRȐj(9,*.f")Kl \ L,0Z 6b6 ,08EhUl-"-!_Ŷmˀ0;N9QOs"YMCR[E5 Y18$q0&EH4"9B,Eb MvRlE59&L'r-~$2aÑI[*5)9ĿlJPvP7 )_$FŦȶ8R.Kdˢ "/fQ\.Yδo7XYNa|]IlDL%Wgl-]{)N =DkZ05MƄ@m +sI )Fo)ֹ"_C/Ȫ}n^=ۡ[;Hf^jom^~>ϖ3aqke5OXCA.ݩ͑L.fɛh|ar3h|<]oϦUw/痓4R[H^k71ǕlkZ] u- i_l?\_̯ϧ Yx=nڃM a@>ZVz9%=oOk3{r,/Ÿ]M-HX 6>}iP [,FQU5-I[IVd#cb8G%s8u13ov:bEOb'Sߜ KZo{vRW;+9E[aM?.e BC zTP~|~C+9+ZpVp'3aAۼ''''/]ȃSŞ` 6\;\.KCG`5hPP?2ە=ʼY5 wwO^-q_AW]S_%m?<#KF˱$vi& jHD vM$r;^| j}NX;(eTw7 o_mo*W;[ NES+bQ'{%nk>$V+v]]^ izΊӁ}mGJsx{=hUQ\}&ct >vLW lEJ Dnv![_S:΂Zpwwa"ڂ`+rsMਸ਼@o!;*Z͠ E!Bb k>;L*Ĵw(Sy|[ysс]SD;+8k_M69{<;}ᎾHG_/tER'tH:ϲq< *R) djr=hxl?0wK>Z]v|#iC!]`}TVkؖq}uD .#:bеtOkPSC j@*( Hd_ v6Tp!`aCw` Z2 i\/y4.h: 杰$k֘}.rAÇY}[w5 endstream endobj 3660 0 obj << /Length 2407 /Filter /FlateDecode >> stream xZ[sܶ~ׯLj$AṲv&';v\R%ރ /Ԫv.8|΁qp?Ny%eTR]Dcĸb`4FVӟU'C(%AEޫ6z vS:xB#2JqFɻqG)M{3tqBP߃ӨTHՁJ4!Jo/TMU4lVukUi$'{5")JKV5:g$Zur6S*VRZվ9%WtW76ThM .I=9x1 -֏qy%Ze]>kS@(I!~f[ۼ۩R3kXSέ@YJ C$ueZ+*j][gw*'YdnCP,}q ym6*( )%fK&EZ? G_H(3t&E}RҁlU٨78ĵDHZى5BG +5)Sſ췺ڼt= laowoƣ td/02*vY4PwSݾlΜU0OwVmem(%`QM+m>SłBXj`4!!6҈KQ nE ROTVM{of6]\dj3Qk;UK 4(ֺπPImTidI%ˬ6Nljz?+:@p"zDz+;ۧMmd2k,c Xm:@Xi f~y8xq(Б#g笯}Vyo/꧷/ָr!k^2FUoU}C^jۦ 7$`uw}ؾlSCMa⏊!;(lB%0Qux^ٮYiqF HjsL!u"Ald<1&HNO֑k訶pi_4]mҒ54[qi%}u8aa5e1|cr /gѬ r 7| ss[uJ3> zmt;8ԩ`AޮBk%P;I xpx1ͳVMR`Q 9?委L/}f1a.m\F^pAqgwv.ҋ\Y:NqQ'%#@DnrJjT<&Do, .kuH:9_e!)1_$~1Qִu}=.9ՅtjCE}#O[lY"}9%|OW銩\Ǭ:}B5z:Zvʗt;]"EcB,DN3k9pbf79u3YANWW(M..UA]٘:KwٺOuv6_f3GR& Fx?6D_ҟS$NSdpyޣyIJmP>﻽}Re $5ǥ/lۼrhڼȺTmhG D)}d,g/twڍ3ie Ҁ˫]A endstream endobj 3706 0 obj << /Length 2313 /Filter /FlateDecode >> stream xڽY[s۸~ϯxg[j' 7vguŻ!$dH-/݇R(۩3\|;y⇛痡7QL",&uI̗brN;y;[fYACJyf-p-=֮ #m&BI,`0`*x:w>KY Ɋ{N6JmP^mRNCF.ܐ@vL`^ޞF]cx͜)/1U:K#R3bA-)0pW1[Inh}p=pM t{jnݾK(ApX 4'$qm٭tvL*~"d1,= 拞tO_X,(6J")Z^" d񶦏j4׼ؕϔi}"Yҡ=͚.4' \WYt|GkǕ{z\"nA`p# U%eTqnԄB+,3'N78.%Mkho|踐#/`m^6^;q4D8̽">n0X{ Bb`HDZ͍Vi#D' P@d+ڊmoيGPPAC C21Toxl-2:Ҷ&@[5s"qH`Y+tgp*-CIBa ҇M$s'up5Y H4?6 OYմ+N.¹/noPN]W$یnvJ~!]`78*ާEzրU*< zTzW=_Z/4'>,di1ɉ栈62鋡4)΂; i+H2szj t>˶Jwpe0\)99)>}sRlR /K~r-f]{~^&XYݟ:N>e ι vnT 8l&5+Bfz"g(Cw*\7@_i*ثбa.x%70t)]SؓN*Z$Xئ3_LaO1ϕCȖzNjv@ē3 WH[BU s8$HE!h )a\ B+Gf' 6͆U FSulE\ɺu+$~#Lf;uʈ6s4#|\h"d^:i#  !p*5A`._.CSBFkrPsD SyÄtV?"2N|TJ%o2qjǮu@bSHz:2JAARANrݠ&M_zn%{iСlC7,PjY[t/%$/'/qX)]'˶:DFr7I#8[`U<8Z:׏1>狣? !eU^wgpu_cq=5 K]{jd)n/<iW_I3+  HE`>t_,1*ǎB^U]-==o=p_U4 5s޲3WaH2$1IdNͿyk@6ys_\nV^_JQFQK[eV4!_5%@ oSﯾ%UrIW{Er-> stream xڵYkoF_A(J-ɼIb۸".ve4ŖFT߾w|Mΐs9awaWWRz1%j %FQo~ ˟W|}P&#I̠}RӺLvkċ`zV6jSvW_-{wHJov(A1,idn.UֽXjizU'CQ뇋Wv!YJ:0<\d2Np F'&`n%k?\voqgNǭ;bt~xkMwE*ZfERr浍L$82U](4pH gOP~Uat6dR$w&oԦY؍FtQ ve&z l/#oV G:K"/~{bXyfㄠ3g޻ſ;O[#/@^ ވ8Bg#I(H ׅmӺR6/nԡ\WkY? p9}I(EB"N%WꖟFn $B;*=~[x(@J8ݸC{1IqQkko]rf>B8[C"E^yݛj(qs'K!]nӶ1bm@w{v( GESx(& XK ('Ǭ_PP].ݺȲs~mo|}wn:_lm{Iy&CRTw'_5'I5sJ&r1PZCUM 0^"tΜccLnh,<8kj$Wo߽iU9.%]NzyڻQY1`,&?PcPt`̄-J"ChgVA9 ԃ@+q֩νrQ~ Kr<8x`G ЩSGEv9gp8cTRX>Abj=x0vvke"K3֎JC?+tOE(ꫲ ̰nmk+I cلwծh*o7fL`RhBH8rr25G=ߛWSj^La,zkG|#Y2~5 {aRG, ݞ C"}ZZu] W'K/21"|]U"( bI(-4:+P؀EO.˴l14K h+(Qa["՟% 1{rKD4cUy-Aabk.ex]gNFZNMpN"2vP_ВՃt(8c:rT>OH>9Wwi DJ6ִtQns$!6`疂bG8ј?5#PZdO6vQ)4Vvmڍ{jcGNkbV@lϻA2+$X6] 'x'U=ץJ*g;}gγV%C/ k_Mysijhv'p" epߗ'U[2N. `|;a|B5tꑝ4u(N*C_Ã2L٥ҽP[L?`L)7qPAVq@[۪Nvt:ˁI:cV~o3uٷC V^}nL`K|eܗE~He6x^f5Womm?&]o[&v 5Ѯ?s ~6OM^g *KۘB$u4)\+8S7irWIIQI2&̪cv1aw߫zWl>%QwsaQ_P>6^ W .#l4itwJ_$Ph`IA HqَNX&8h2_*5w}`Mv\X%Qp NQMXXS~Л >Էƨ艊ddrtf?Oo endstream endobj 3756 0 obj << /Length 2239 /Filter /FlateDecode >> stream xYs_q̈pŲ38ƖpA@K{{tьp8Ƚǽ/~xh/bQ f Ιҁg|%i.oR.盿xe* "`j肻}Q/Z48IǛmփ/jᅰ8Vx,ЪX6U|= 2]eEde;ׅ,NCFDY3\\! ği.d?}iCpF m\/1gN~I 02bl~MMS7TWCz&ML–IVEiI_9ijg҉~z8Jit շ@Y.8ǵKy@n=]!tVrOt^!K6>so ߀7SQYʍ`PϽpI.t0>=3`dQ(Z''LڟuMr4\fj.Y\۲NP1b?A7V@1SbuZ'`60LA# 8|E8,AZ :q}H+؎&i6iѤKfUV%s)w;Ы^;|184S0w @3MKN8KzA?ҤxLʰPJ{"}Zq]%l= cpr]v)&B0a"R-co@:ag1o:Վ5*2@z¾_f6@E)ĮH YI>gm(xDͣ%a'a\.cr5YwpxFLkĊlƄ pZ6@ qzf҇e4P:eUw $fkbSafW,6lǍHc H*A拀KڞȓU RkɌ褮.U<T 'ڹ3HOow_҂F)D֯i. )[37̊@I&Cs{Oґ1]tz襅Đzh>J5tf Yź 82[i$jPO0hʥM.!P;N 2~('2'/uBxJGL#<2to/έb |;|s+F\7i 4 & X.rb44fكnh:nH%C2)mbj<ѡ2+ܱ9OԏW{2(#d2Ob*+,QR3pfp-]P> \DUj3oWD½ro 4t_BlXж]x>>Y~z~W-;^1 WAIŢ>)[r:_zӈ= cαɮu}'BY)VH_?{>'r QhdF6t ґ^6X<- ڕtc\ YC1;{#(dz.rD򈠯?i2h7R(yؚ Œf3牒CzL]FwLw݃cFx -?ݰ!dg -yp!JBI *)g G^ݧy,eS@ t5ƯWS:; 9QA hOT)!SW>LyȳgSR7%d4u~H7IVm$,+ن!f8.ԲOj<ԀRU(Į^)T@0. bI#dMD,uݝ"=k;=]Fjvۊ0oQiTE}3mh\78FsKJ%?N`׸ ̓]U+VJg^&0UBXã}iMF{Yq kw-w|ub2 b3<ڽcd T:/K).eqI.Уl!Q4q]wy]KUUn5MIon. WU endstream endobj 3650 0 obj << /Type /ObjStm /N 100 /First 985 /Length 2522 /Filter /FlateDecode >> stream xZ[o[~x8V\n\q*ұ-D>+ɩ_oC;N,KYK>$9Ґ83 (+T$DR:aY9 xB !J@^Fy"낊`2$&XA {,, @N ѕX!2$[F(H"e+#"AFDR֐)KF0 0ˈ2"JeDdEFIF?Ɉ58 FD "(&"n $M2e0"2SerBeŦh"ac /j9e8B1Xteتw\<2_R>QFcϔ!l&Br*DݐPTAcd>Cbm>Va 5RAbP"HQEv23D,B`1ZI,7ZR15\vk-TJ^,'BI@*WP81O&sDwm«F,AEeS0"2&#{ye& a8W$X ca<Ã'|P?/TMiX.g?x?7[ְ-1v&-9jc?CrwKux#(ʰ &&G8L ly<`y?~.ӑj^WKuԫ-~3,v˅xy.]zy;W001[7cqyzLf^Vq* jyynYv| ks Bc=Dj;jҿTËNOn>-+b2ZlX<X Zu6``Z lq1∶6puZ\ͤqX".ɴ.B %spU<)iuXgqj&v( (QkB'M7]UF-@jy/jRIJe4{r|;$u4 *-Ĕ6">ۧ@k Z[8 1QE7}LҪd9}yu*(6ŰRq7nlKyOэi3N:b#' 2^5O ͓rwblNf67ݬm–}wc }ԁJq*Ko *~XJҬmh2NiJO.6>I9EJ)xUi/! %#$ΗcNHhgΆ=GFƈ(5&(K~P_u`z $<%4tOd)) FGk1)Y\_B/nXŨnp$rdrg쬟w(uk$S.o6 yzٍ6<9u ar2q0 h^.;(s(M0~˺}?m.PFtB-7|W"k]0%tK3Ї]8E|:h$3: <HmXTZZZZ[W D֙m֙meb^qrً͢v/?TFVȰv}CONH y1 2˒zV^K@jzwiIrgY?KR79K2Ol:BlY{yKU.hvپڡL,Ig?+e2],wZܶ3SI_/n+M+W>q8"ziwx)K:]M0= _7pp\;L.fXH?%-%XɈ}75ÿ$ylջ\Vy/wձas|N=޷nEs|6 yo=чy?iOO V՞٨u!˳~C)]wXL-w !z{O|qY5/@r#/sG_|2AnU%7K3l{nn;n2iKnk(̶ku}7~ +*sf\~Y?׬k=k=Q`;*lIr%򢩷pBx(VH OS}e-0 ^t2Q%Ab\y: k?j, endstream endobj 3984 0 obj << /Type /ObjStm /N 100 /First 989 /Length 873 /Filter /FlateDecode >> stream xAo7<.93$ M&@zQrHjjkTI 7%A!0٧}YkRf5dcЂ<&>[%rZF !l \%#*=hMM GJx:Y{ETmjFESD9 sxTUl[5xx9;s$ s<`.2D#"Gȁ%%*J FQ(X*9X+ipx4rtx4rCNNNmJE&rta&GǎerOC [-(ΜUeN5, s%3RGM ץC9x7zeK:j*uD,EZ&Ԅ!L!9`dF+xr(< 9P&) F[#ɡ993Pur(:9/$rdr "i(B3DูYL6azϋݧ?ϼ~w1?o  M7̋ŴܬVG.h8sרU{nn.L*<[q:_ ]wA\-˵\tGD~+{p9ֿ9.Wz:Wfu4ijbƂQ֏bqqyXovg|߮WWcE` dA\ka^ 905b}SnZ=*]KAax;EaDF|U8bňV]:6߯?2L>`% /ݧ8Um*?FGËIbųxY> stream x퓻ql1 CG"9q ϸ* 8Z+,#^NEklbIĕ*!rTnӓJ.*-G'G9*iTLPq)E2^T4+Tf΋J/FQUNi<& v0|h}"#X?A P8$(d"2 $RCFQ(d49 M`_hSrc"G%r8/j9:Ŝ]-1j12ԐqמSӇr&Lm_GϢk8Zӡ6gk8Z}NaA`*j)Dm <MC&SC 80d$9 ICFyhrF}%p%q)/LprNP G #x~@;.Ͽ~=XO G^ endstream endobj 3999 0 obj << /Length 2258 /Filter /FlateDecode >> stream xYYo~x 6P;Q/{8dk DzSg<}M]W_Uׄ*\^~ǫd1Ww+x!8[ݕǻ~T.("̤&;WۮTD/W,v?JW3)S8_QWiGE+%Z{[iut` *rWپ0~./o%,DȂ$]GMf)a_܌[]c'nJۭ+mI DZ:'}k9>;PO ؚ,}W ܏Aw}tj)w[V,th^ݸ%1 Yy[;nu$ A$+;{{7 H) 1E܃a~d]k7>:4HͫhB9E޶K,*4,Oipk}8JA:ǂd"zyTSUJk"K!]ܾիS Mn'\SîhsFRK!,HM8ZwC 6X{_0vHtl#( CR u-fV'E$S@Ĺ;Ԯ:AA_ p?we& o%D)h}5ۖQAˈ$uq[HCH2h!56mD`g_T6yJpƟYbѯh E3%v仼BdV+_FYlUͮx>5#V/ek̶\i,ش>k媱+Qi"Tq 6`aA;6dOYMT[2aB&UwZSXjm>}noH9pv,+LAbK1PNYcLNto5Q[YP7D4Z;A/BIIӆ 4J=].@$So[sVܜ2N LZ > stream xYK۸ϯPy/$]ìɦ;>y}HY>ڱ})R,ry ~}5gǛ"5KX={\L*=4g fٗ?Ӷξ~}Z̖fQZv!Nn0[+bREQoZS6+낞˺jm]p??M $LNl{M~m<%"v6[U{x{z=ۢWnr;6ՋkmӺ1{FYe,/Em*HZo3Z+W>[ ,d^b`gi ~Pp0 =:P˱?J_,wUٴn.Jy4fE/kN )$H_#F!QH{gem۬*" b19ќ4]CKs>gSg_UA:4E wz2q17P@jG44 tc&Up*a6ܸ{_U޽ﰮyl fC- []aJ09WjQFlx-iNo%Ζb?oE87˶GIĎ!@bBhˏl gF8ѝ/{Ǟ0%Dqc8M]@3Oc]9+$S:)|@ Ů(_9l^d4pzBJ3ŻtacpJ1 U7ffV]cԏݨKJZtWB5_h<(Q7v-UpxGXܓAE<8hZHjO>/+$ .b~:aģΙ>~G~ލLPb.o^J0Ds`,:A3;ZٚegߕqLmR?w6; d?i@iw!YK#YC>8W]8!:!o}{Nh;H3ٹ jAr/-i񘱺+A,B&FwWO18!:βpڴ4i=k,\jr!ؚ䲇gw1Η_QԿ)` '/ Wi,o~LYJMII,P{:+cɰ$5FS c[)WAcX]i*a س)nұh)^MEirSn3Z nG+w_AŢP }r0%Rp`Y]m'(>T3,D+.EQ# RrX!,^Maf|'#8*22Fn>s|樰nż8L H8"6dr\BmFwn}2"!GQ\x%GvCCD4[>S+m 6;rhf+?8t2thlSպT]eW5(Mg1f:8bpTYi̪R ï%$A%ܰ sM{ ˮ0;,NFn==BD@P1lHbQ2)vK#,|%l#+,w7(1sYJ htU8Q Qx]Os9TUy׹NwM$*`N1rg*̝wNP}JWd=$=4`1;4YU-(â儤Qt`_6Pp1чAtCtoݳgS۶j)woZZBZf?K`uhA5ث_ Bk!pp9t.CY`*bZ<#a9Yb}#]{2JXWaۘOY{%1$:Z$6? endstream endobj 4040 0 obj << /Length 1825 /Filter /FlateDecode >> stream xڥrF=_!Cmj/ڋVm !t@;%a-ɎYr%$fo|Lv%mq?^ݜ=ù,캈2E%M|c'_o|g=P1 B 轨~e$k6kfė/5IH"$3ԛ2&3cXU%kԛVe&eZWiQ+-smGZݑHGCxYdƈ7;4taN'&aF0jc:CSJi!;a %em!2"5ǸHzB>8ı'{ADRmծ7Gh]\ oEhوrrJxȧS! [M-d yTdv?3ֶ#G70yVDfM }F SHy'% %.6}cU/Fm6=&oKqA|G!j%.I2u҇:NH;Lf\Oz?dR{,*k:a\a=sJ%[Ű'6ui!A'kdC}  yhqV")ЏeRm@8Ld*\~zr"f(qZׅb{2e_W y,zg#Q\]ȼ: `#Ö$*mI nO,X4%Ny/; 6B&414jȓj;(+3*KcK{eQiri}Eޝ؏aØj :!mpSEE C.pR1[1GSi ?0C!]ci3Vf"wS 7uR"ZZKNTc60:7d*i6Ր'&uV̘kU%*- eM([^YMAªɡQ tUs8Ҫd"o$F`vL.v~|.GPR]O'fLBpLQvuSW B`^ԶspǷ- ZVJQUCӭ9պ~r\-M>AѪm n0V/i\E^ : ț~c}ߛM{='ޝk۪rTg픹KwSϒWm՚bEQFuѳbg!)#mX F'Mڻ(<$m ڋNژmbBx`SϮn=ڈہ7s'Z}:1|p;rm}uΜީp2:px\~p^hg&>e-_6lۡ}3x\wr3(:2]i2  4pw˻]38'(iF`"2ffIz%*^1ZD2xlSQ/:`2D䀢?W" &WNW endstream endobj 3986 0 obj << /Type /ObjStm /N 100 /First 968 /Length 1827 /Filter /FlateDecode >> stream xZMo7 W >@ ۀv(&^,;.͗+=(!iQ\pbt1wr͞#1EqTMSi㢚RM"'4bHLq$iK4e1Muª`%&dv5Y45 f30:\ /ɐz z]"$t }̑ P0G`rʶ9b2樢Ne' gKkEN[cVx?ܟmX4@*cu#$ J0G'lZtCT )J4cԙ5J֬nf!a'GH(a D@c(.tٻb#cʒu^$6ȥPL.1K9(lrlY@ ,Rqa FAw"pv(ͥdqHI/c}A,tuY 4-4:uQZ!Pn@2LB.*q%fE1DW͋t "ap+WPaG$#F{gFÊ68XH p+I)zwrsqfɣ8fOHYx%YsLN'no Sk%H@R_< 1'd`[5,/ռ0L×ɫ;v×nz݂xj?ƃ>'s%Uf0<ϧ7|ALb|z>z6}aa"k{F3 c^a+(k43X!yoTKw+Ql GWO[7RD*`YĵSWI )Csu//@uKl A>q"e%6Mn.F]C-VTBE|Dd7 2uӣ)(V"pM $j\l>ia#8gs GJY'|~5n n aZ(@ڹY"AMƵPz_M!mMFMXfRpx>w;G(88mhqhgC*6*F̚կ%iCB_Hb`X3GR ˺RK- ].p ey[2HOV!(?痓xW+[@zVoz_V_~}| p4#J8A =.{1:NF;M&kf$Ť NOګEfn&%D["ņ9n3=^EnA5#I Pa; $cƷ2# dtͪ =7NUNe5iH/)Qyo(XbRN8esiEW,bڏ.1M(>{icr` Ŵ԰벩q yC?Vt|~|1]S" uBptE:]NWtE:]-9m&*k5[?OJsU_*/ e949nbZZ>C_ }Lq 2u9åi&Z a3}UGSje!|ձ%TmCy: 25 M)l|+o+OKM u-c[oQeAn- 6qv49}e^&AϰM2?!.>x]忭ickJ@_jQvr endstream endobj 4154 0 obj << /Length 3097 /Filter /FlateDecode >> stream xZMWlVYc$vRJr`ъhXɱ+|{⛇/xG-nR*n74 FHn67>gm_in}׷SEtlJ5NzE`^uWLCעjkۏ MnV4!*q9OHa#OaVޮl-у݃G3] S>;7f2=僻ow 6ޔM^&;ӻaMM!HB qyH8RI3rⱌ>d띛e ;hcqKA)ѭ>(c0w,sәzٺ5Hph#YmF T h\QJR)ݒ몮MsM/K'xtd{ * O#a{2,+T7 ^=EMPf6eڙ7^ǫ~DxU2ܟUB < x5"`$ME Z"8,e R1?HE^K$ƣ (SrBsxŁRgX!^e;LHg9DBG]L8@A|<},^-Jw$\xc *\ 58慔)~ZbDkcVx/8Z X8 Q̭4z4}@[H̖݁ЄO( g.HEQao+ \rf㜨>328|,xS)8gPq7(*#ȬDHA @q9 W1-kpj\weBlz5r X+OI"& Z cԲ]-,' >#rR1>mOi?ó)Cfl$t)5ɀmmVI1INg]c1 鲜Dcv yꒌℍu j54/{M!7cV͚9 ,I)*䙱EG8Du_mtT'zS z.84'DFc*O(EeU₈T ]2]AX/ Ş,!E,X k-Wz ;*!2x(fC$=;lL&E壍=x(IJ :WJ.l(PB-en3c|\Φ;x܅cS%E1מ E+!GS"{%DٸⰭ+_TD:-:+nRA3;m}`%~ި | ]vC`*/wҼ @$Zy`XYTu[9TEw;[-c] @Dnl+p|Ƿ.FHiN ` tx>M7|5X}2 А=X^Y@"ESizϝP?ѥX;{#-7g~l75gb]/νcm.Zs]NHn`8dG!Ydysx uU|=eb6~sMJ?udU9=IrU,vf{y{rS3 ,ngc kA] ֍1:rtp| T =?br&VEFe]|o0?upG #YWP|6. \0L2 >q|0KHǍHEp-[܍&< pS9 4>`[f/LA.6#c%SXH4Jj3lVCfvFţN?:ڙ}ӧ*sxLTˁ9<P9m{ l%dg!˾b=^\='$R^{ɇKǞ[J ;CT' T;9@|E_˩kɉa@KO}0!d>bJˆ G7%q§2]|tyʭ؇L]Q}N@\JKTD^[=AxVf0旇xp#}iFikܷI"yf4ƃz2,=m:oTL endstream endobj 4127 0 obj << /Type /ObjStm /N 100 /First 974 /Length 1212 /Filter /FlateDecode >> stream xYMoG W^f3|F|m9*Kd7# v.{a/^f%P$$Ůzk%͂FĂN)T#jXe(k&aY!8XI :v7*bSf \dU\ԋ qdGCE-y5"ƨL5!jƨ V-J,! b5*j6h\ 5j4UPv@֜=;5zuFhh-A"ZQ1̧"zf!d`3CEp { OR3rDַq>%bGvU>JLH!i%pz\vsq4)gGt%V6$ ~gf}f& fʱ;nȠ)9~qL4;0DԎf77 oЗmjgָ&X(Iiw[$?l72zcžМۦqRƨTwBB` $iO–q)cG*v/KSMzT~{p{s^2=Ke^ݬOV<s7)O-8nO endstream endobj 4179 0 obj << /Length 1085 /Filter /FlateDecode >> stream xڽWmo6_!$`o2KREW4Mb\`7`Ah[^\jy-:QBEѳk߷"ܷ QJ׷q)Ei:<-+EH> zrNpu[Ga%=eCPÈ;M.L9{KѠ. Alw:_+W%yȚ}R;FQ')Zŵʎ*BC. yS}Ore$v,Ъ $+M\p1KM#l2n?žM)E[&2=yΰXw8qMUmPF-'\7~ Ɵb ]D8P:P$K>1 $TN+puU䃨OU' Vd2qo`}T-tCjJ =luw@H3'dQ:~1RKUd%gWIWM{o.ֺQT@J)ⓐ}N5a/Qj底H?dr AR&rE24"fux̦6U^af}{<ʐ;nݲ}/џ߀s=ll8jܤ,TfM2$珆<] lbﰑ:[T:T2K0ܙ}b¸6H0u`*-NeMEVƥfVY]D^-JTTi=+6$ᾅ) 6BIRGփf-,1cσF0CN/r_Oef= qVK󥹡]%g0/$ ҿY@)tgAxSm۳qV̊$ֽuY8̢mg we~nsHV KneKQo' 6 6 L앢L{O尔߻ JZ${pX9an`| B%)T'`<ѹjkQK`d_w M?k endstream endobj 4195 0 obj << /Length 1122 /Filter /FlateDecode >> stream xڕWn8+l b( .2iZ@ݤYh$G~\$:k Ry0A;DЧşŻb &f(!3K]yG!&Wx,p ?LiZ~gAaK3}rLP>#GGD>89 kw.t%X0Lpօ:/ l^c1; a/5#+~zdS; 0kN\AiU^WףN$iLE1Oȁj#g@e;?p1BO( 8/_o<֌";K;@AM}vw[AEv7n[(^ʺ iПf,pMW`f}WVXqx endstream endobj 4219 0 obj << /Length 2106 /Filter /FlateDecode >> stream xZKFϯ |b؋MɁ8#䄤<~TsZǏEaf8W߾23H*뛌` FMnA(^~ӷ/?e A4lw%|yz} S_\_qE`32Hl]^g>ٽ-3NRzuo*' S8D _P!M/_+*[>qQ1.R~HkM*y j"sx~,uGxlE DׇPmF"Y_t/> —u4Y<ݝEձ -J/6HA7ib 2I!l8Ţ.FL =ãzGX#<ẑEt1Du MPSJ MiFS'6)L0vuضbL-%toz뺱TW!F#~ jSv0C dLG&U}e]泲rS>`1[ ʻCSˆp]|]a׷y-xQ{6PD00с~bcT(&{Z3ま.N1ׯ߾HEAZGI5Px; wg pkynθ:$.Bk\e0! ?-kX=i3k!nRe-@dEg,?I&my'| ۇ|(biK' 4Y<;80?&6}9vNqw_s@vbN@P9-~]C:y TI5ԣ##"NP"a(|w #5K0nӧP u PY2o*ۃ1;\۶W)e!+}GA5Y|1i06$mל`wq0$5gsH ^Mۄ( 嘅ΊUhM+f&/#0e *K7sb vO!V{r/zFU`iS 8ĥ΂!l&T}~'zt endstream endobj 4255 0 obj << /Length 1740 /Filter /FlateDecode >> stream xY[sF~ׯx&3rHsk?$v#d"p%v}XJLV˞;Gx~=׳痳>'_cĸ;#r5HVa~E ۧl<σs;iKQ[4v/%uԢy" OT/q^oJHM(+v~l>T7Sr:<~Pgr8Sfq iCP0kuU x펵i_a.F#vV /A*I͞31 m&(6Ƿ:aBg4^;Q\`$vk?Y õ$r1-+H-`Qyn!8G.~:\&%pJGgo΍Z998`[o^CSώa^cʐQX(ߚz9r~QMfݧwCRƗ;L.zJb./ыG{ZĎ VW)#k08û?W[]v},zh5KӶVG$f.0U0@; O.! St~"W>VLW?"qQumfDqDtٮ[U>%pFdA\cxsP`^:Q.\+zj^54Ე5.+[z*Bn{92!ս%PgQEvDYoҫ 0v6Sn@o˰B]8 jm!h!JbOzƚ//ggDT a(2v˷`;_NGb~=k +KDFvA5h_4% <4O>1k/7]: e2#10iU:K }AXG~Gr*HܑR#n:n:AAGX:~-ǯfi@tU/*^ps2.-~-rM.ʫ]fBbu(k(,hn+_f筢 2 )5eN;\i1OIl h=KFt}Q6 uSiiRQӶ\H,q[}k;ܡhI*Tmn9bym<q"#cQ49EWQ .RT -jWAm,P>:lm>^e@nG’cgPC**AOfTM{4i -l ΡR0o,G%[dB> jq4ݦRaIW㩯O~x2HG׉_P[g8LY*rmX7b:ğAISpC; xؚւ)qiߘRbk[хk>~(B̝(L>q*lFy$d!%HJwBȿ IЊ` \@5| L:P1,϶𠮗&yaVuLXeXj׫1fIҹSkJC';Xu10 &<=1enPXw)&M@zY5啟JG1rQM 1ѾJ;[(Y '\b@ XaBU.uڙa-XEXɊ6Mt(c1>p%th݇AwW)"yy9 endstream endobj 4162 0 obj << /Type /ObjStm /N 100 /First 984 /Length 2183 /Filter /FlateDecode >> stream xZ]o}cBcn )6ȃ*obÊJE{2q+׫<HՐ<;3]3䉌dEXT(&eU JP %HeLJEzث z/Wgs: ;9J9@Qgd2}0 ? -^PX(*L )+`yPRe}IJY[t<FPFp}RL]Kֱ'_M5?C+LQA :RPK.EAM=ys*aBЍ,\gQIJplS jEl:fJ@GgQW 1OX!;`{N0 $ȱދJGKjms{X_R&U;a!q]C Uљ> C*^0)z/B !UKaCUKEAR5#T;f?bz$19FJMN dG8l$$60Oj  P.56_ST\}"<蒐H U|ѫWGVX,Gl[p}q䯓^MN|-ÁD6Fgx l^233Lޘ?~Zj5gOG7mD5;]~Y>`5`l~;yK[q= fM,"&(b2ݮ/RlB\,܋$$K9ft(1E[rl/@2]cJp6jvb l i(bDa@,>7V'fۈ2lʌcwnMdLvʈ> }\lde5 ;Ay] 3hjwxi._/0z9;``3yLw_={7M[l7ZT5zmvK;^~5u7Yfւ,Sn$pp_bkjkoBhBl1?RZbŠXǐz=s{z>\|ٌ[Ax PP7 :>$js [}wۑFZpC̖%ܟE77m/cG^`ԛ4z10Ё\HRҠ籢Eߋiw#9[ h[~Ʃ5gd1:@{j{< cyJ28ogDj%Q{7!^r_rq4+4ޓ0&iQWɢ#՚Ns4y֕؟DY  v/%1Y pdz>d|9#ЮAm8"$bkڎ\]IH]ts?^ucunDw0JHd"EBM +&ݸ8a[0ň@1i ,%VE^ÀҷJp&VPzBSp"> stream xڥYݓ۶BqF0Aufݦthb?~ fFgg95׳QJ3)QnW_n#R1iQe ]xтEb ^?ֶS72X6-bjOm*Z٪?]S>7 6 `IvU#[(J_~cn_oW 636(TB5_lA"lɑf1bvI%8FVch){683[ZmWt:-onϔ³WgN-\rj*L^.rߕu_`O!wa*s\?^35$y5~eQboHq]Yp'{ڗb} ~n-ܡYRe?PES.5J7~M#>p8De@,(C[lj>v9 6x"?{7Wk7y' ֒^4!IfzbUs[nl-CuUڝGn~m8ŬOc};%CcA횧heޗKEę4rCzfvAcU 2rbZJ{Uu#6"z@*\c N(HCR^BnO<#H*zmfĄK$OFFM@)ng7D+7ֱy`b9uPcWpNGՌ О6э=AzUIGx*UbL>?H$&ZAhƒ[;qв":@90h\<=(PQarV-A3dP:ϼL߅ D3Bm[s@zt%|P#/'NnpMAW#_̚CBy19f-?=S`!W{`B+b #&qc/Puf5éVr I凤>sr$"h[7:<4?=I J=jMݔ& @ķ, 9s*e3Šy8`sx/y fFB 01;ۤ bu˦n[(ZW(ͻo\\ ;&8?RꇻnZP٥mjE64s);żļ 0ܿrU/ҳQL0JDy/Aq!+9P&!UbHwUR˪7x̨*H4t Ȋh "%|wh#W&NI&6zLG}Hl'=' l]eGTr[Hpg IlRMZ~^FB}bt@H 0=:W+чRRͧ J "Y1Xt~* <]Bd #5QQ%9jP|V_vڜm>W66SΜ -Gז]"PZU}q9 A(\z3Uv׆C s[p,7?:RJT@c|U"*1en4$(z,晄c#$t D@TQi1"S JEgWN_npS2FXW'lդc~,7c~N>[a0Ϳ >e8 |z[v:;`~}η0W2gu꿞 endstream endobj 4306 0 obj << /Length 2624 /Filter /FlateDecode >> stream xڝYK6W|Yi˂I|9LfLR[EAcTcn4ı%A<ny̛O^b&x4{|cfq0ೇ?Ro}x6XJXˌyyvy|y+e'fڒI^*F+GL&mUZ,y"盪檄f[ꇅ&_pysE2oTKaiA68(؏HݨSʠq̖dҴuUus5߭5%Ѝx䝘\XL_$,H4"&Bo^]m WTM^Ӣ6}Hv˪3+zϚA].%["^.xEMb.?j܅dEyYp(݆og #xiZN|KNmUnKΞc j01$7 .-pxDҁ)}z} xn)FJ5^ P ψM\!-*>Q+*/?!Pz NodG5ďǚ-ZU,Kzyi{AԢ"SPϡivjgj'k[g \9U`I$bMc%C1ᤠAH|%^& Dc 'x=noaw< Wec%zY#3bdZTf)iAfQ{$oVYL˔rтdGNC_X 0ͬZ+jmj#RLçH>^c*ZdhPɁ^|Hҙ)60@7j*)?ߩȾyg>Ua?lviCz,HfJEO#ېjoGK^gUKKL7h{'GM:bCliԠ-lCDJ7Fp6K Ke&Nҁ{_5WP0xm=ڏx qunQs? a 8:%³+1cnFʡ _?!hQ-*C>̓6Āܛ7VGFv_ծٮUu5'#7igh ߷~7NOEM9.8Ca'tU(_+ EC" 4 -K.pVeqіQAߤ>D {WoG&9C## >qv8.L &4 R9N/ئ <%Rqd! Q>XHN8/hf2 x3/01twhn3g %y\tp@ A>6e$~c P$rt`0b۱ν>o'He]WDĄL[T듴Ŭ6E#}ӫT#%-Q  }U&<5 Y8$w9K2 OǾ@iGCeb$6ZR3ɒ8bk5뭷9Xhp>:0.ࠎ|L*ya4'\CٛB'A)GLxZ(_ rG[%ѥXTMjPƮY(+Z_U#}L[(WDuYT啀E uWrmUVX뜶b%EhەVht]ZnIP04$O4n0gӤ)ڐUySPx~vkj-6ٰ3Tam-w@ =UkìjWA w~|mN~2Iث 5wiܻŭR >  #IݼoЏ+>C|79w/'VpB|O9`}ϥaC]- jPoX27nqR;G5KW0y@X- [g>LxBRUW㬄Of P*:NkWD;W*6q}aȂSo*O#PaZ|sMr?Hg!B88̃X_g% dͦ\}Nu8xI S)ٽ,S{}z樶t'.ʱunv T = ݟ߀KT~ ir`8W ]Or]iu }[QgrYƥ@kE?XV?>sWBMW` E adqOFҚqP@SK%̅I1֔gYէI0iơ!3RWK$F5pVNL2a?Gs™waAo>@h:7pϟ endstream endobj 4316 0 obj << /Length 1351 /Filter /FlateDecode >> stream xڭXQs6~ϯ97dj+ rCnsv:mòCK{%$!Ɇ$5/yjw%p'oN.Q4K@hv!A@YAxvݞ!Ln>\c,m~^ʝ@ /CGai48J1-낵z&hFrD$"ƀP"(Ux³}Z C!bE C lR-m.]PL#&$LNki҂4N]ݢEp\ tlqp`MWZֲiV7q7f߯# ZuΫ\ϥ݄(1mPeɷ}jUuU'ǺiJ-ϗ(cYExHҮ#|}@}DS;78z ֤IRl.\%rѓ PiL{69NCd UTHpdM Ϫ]HO1qǯa;3@|DK%,;1L-> stream xX[o6~K{ 蒴v[]vrjMOJ{@sΕtXg.f8 XZqV8wH劽Mm$|\Y8@aSI/6-3[0XE!!VR>|t>ȍ#ZX(Dϭ7?Ƴ uC+`zY #lo$<OZ~>hlKV(^_UWǕ䔨\ +$Gf/vBe%I*pt ADD(Й4*hk1JcI;`J (T-9cZ?CU,"Eyr՞mHB}lڹx:#@Q3$I1ݥuH7~% 5溁b \4;F&@%06Cp;Sr4v{BD܋ ?67TT%of01[bQ)v(MQTժ. bKRSH,WXz:̊g>A&ϸ k{b SDz@jYjnl2Xu!ōXbNTIL^\u7e|(@"]zňt K?U|EK"VN|u; ҟ 7l3Ifݡ{P֪ 8 錎h7c&QKgOTICKW*Wu =!h~L\3VoIU7S!fz.4/_MwkUkq2Yb]JT]bSMy)[i6QF]р%53).ajIp3!nϚxPU'϶CHޫ¤*v9ޤI.̽N4WYb8T\68PqD=?ۀBe0]dM@*u)hÛI!aڠnZsW&l\vRŪɅ`T}0Jid1Є~huL H~[MewZ-\p6 P2 6= B\hjә>kSXtFQ1ĬADٹ.F׊,Wx4cJoJw'eLB..mH:Nkyn/-ͽewYҲUj1 endstream endobj 4352 0 obj << /Length 1586 /Filter /FlateDecode >> stream xXYs6~ׯ8/RBp5Ng2nSBd<.(I_x2bŷ `/gR1%C@0F  F:x3'T.ޭ?}("EF=i~Ihv\fg8 ". -fo` );#Zr< N(Fބ(<t. (-7/>euKrRVT0&ynƉIDD3,g=Pu;#,W]d6<%U=a4e(dfyfؚ؍QfK&8bLGt $lPz9C9q㑤hlз [0‘7y6_}UQTՔ{cHD֙'!L{=Rikc/Wx`))8@gt.+&BϼO}px>/Yca{H.tڨl'IS :J [ GܙeRf" 2O/g?Ia c 8沃b)$uӪV*Ҵ*$+rc_vJk;& CQPon9X%Mjpc xO^<@He{h~|ҪU angLeC蜌q;IRDB?cY*tj=SݸPi"\Aqq*yb3j8vLsn) j=zji(} yuk[Znt'!d&Pj;0N"g2oP~ EǾom!smjRGJmOψ(F8Dibo8B͡y,xoHl}↾1f^י;J* 8m=!wL&j;^nSd`Y7ggrF(m8d<ti/GiBt %Ac 9$sQ `>&K`o#>]Q$ h$x6{ bcQ|/۽9}P\_ h0w3"p ¹/[}ie 893aM9@>):ݖz) l,%htmTk~9|K/A.b)0Kwۭ> stream xZ]o[}cB~n 4EmFɐl{囵בuc>,`sל3TT'5G4Y6W}]ݥՒK)ѥ蛃!&ZbF+*,E^`^"b/Q`[C/AD+mhc6LY lȕF;UF3 ïƊ6k6,1,*X$UEg:ek06"R>'IMc4(l)z`eղK{0К0 (~WoBዐ#`!Џhn- WBoQK^.M18 IhEX#~ D4gR ,^:S৘eэ^9+N[ðm8%*I.^ ̚93˭_i2P] auuZ@ %X-,"W8e^ J/ݡ^`Q0,-pD) 6PLjGZ3> ւW1rg$GOM|=b9˦?l|6`ׇwO1y6ɫlb \G%7&#ܞ'O䵛mf&_^_u2]zWOG;;"wj>4Vvb:9~8 5 q+VB<@ZNNCzBf^=*`טvx3# gc^]mȕI=s,!!C ܼABtB8$f%(ð3ɕgA8ȣ(;d i)e`NΗ +H>$HR"ػNXR#+s}ky]W{͔6o@3lP昬5aN97ƱH WF5vqJlclr,LIM+0)ҭIXFǡBܖSؑ' wfzs훱m?0``b#UAETTetĴΐO% "@Aր l *g~P -L]nn>tGJ4i5OT|T QvEZ-*eS7~5؛]j\ɻ0x!c˖agx0C"# 8oh8ϣq<6*ɋb9@^hx=E#dwݻ %D-@2Т (i0t0l0!3A*1rPxq!NYGGe5(ǡ0Y%nCf1~ `Ad cMSð>]b9]45#e^FnȬfu6Xw ^T{w[L}9b7<w p[(zo(%V=4;)e-X-̌1(}.Kkb7NL:{ޚ F=$+$ԘL$ F9d^wg4j:W'q3h*ZDnC^&~z6`@)ۋa}>]J£3l mu_JhFxhs`.<5(_,ǹ`) <"#GJ[d^d#(PeoI~s%?N endstream endobj 4398 0 obj << /Length 2182 /Filter /FlateDecode >> stream xڽYmo6_!;;h-P4zm?6cjK>In6;|2]6Lgy6ѷ7zQRIe2R#h~⓮A7rS/~{RbD*MaM;Pe&`7O7!0wqp/4^C A3Ǜ Ix0G ˊnpMQ֜^,ҕYY,K!$']f]TG12W8:@@HNʏM^#{/JhI#ݜlbč'Sk}>1vXPѺ|vq_@Wz_ktpʤCov3yHg1|}gؙr $CK$HI #(̋E*ngu AF)v Fh$i#!>QNζ:ϱ2+.~("CT4z>$<`V :gxhSˊ!I*氘" 3 {z~>AAT7 #to X#,% LA>=r.Ek_nMfIt!diJv/o/%b=mmFmX\+ywR iW݄3]Xu۴SP͈jr2+ywq&fp`'M H`?,fJ"uޛvH@dQՂ:J@wHV|ﲾ OX{U+̔S"b 6L ,R YYIhp$8E$7nv7fSWWGf/~tlbH)3gmVkeLA݃)k]{kD4pƟTs0 EDK_?OMn4dVFOeOZWڌn b & Agw.ZN,'ouu22pfs_6z72@AGq:_զ]Y)ɉ:&z , zӑڒd$|Vѵ3X$'F*[A2nyR2Oy=^=ELXH3IUERv+umv_|$01N=ʥX+m5JFqHn~מM= C,itqܕs2a+f\a>!D,Y燣m~Vg ҳ1[ b Iiq(\)RФw@2:Sfٍ>bm1BE3a6$W ޞZJS0fw!EBRR]csw p8 "u$mH[fZmrs#5]7E=g.IJf'8./cmuΪf/,R uϔiWQlb<,Ll Xg/5wA>>w^l.$]ѻ1pmu v,ݸ| Y [L&!VGFJ!ΉУ1-s&Ppo#.*A D.KeNI|(CȨKĝ_Y}]&OGș0)CBd\\|iO2uXP0cKηr<䗠H.:@*$3YV[Kɐp:c8vUb O>woJHis e\}]f;{{7 qϚmC[-huf[u6oꦪoOE$Ixޱ ސgtz~€OǼ# ê/CC);,Saa3 endstream endobj 4416 0 obj << /Length 1746 /Filter /FlateDecode >> stream xڭXIs6WJBtq2mԓLB2'\__)&%ACx|ރ\g_׳D 7t] NCde%f ['fZJK7EY)V:&  rG!s[f,kFyJ-HcGB+8ݛhnv^,s ;"ۏy>fxQŔk4?xb[t$om3/i9s('2vKj Z1^.o h&JMEz /nv})s nuy(9]C;B,יq$5,R_Gq7"\[.Kb&964%ƧyҲasR@J7V滺MchA#o k Fw?1%IPK dQjSUZئzB21`¾X0[hlVksT4ev##r4%a2)K<K1K ^Z|r]TՃzF ]Ƿ=5+ZA]MϿUjNӼε̼LL+L) G+s4y)Qa.'q3gꬪe 4ONNOm\+N3fҵGVVL3Qu*P W_? 4]"Oby:+ǽ,atKԡ0y fvuC_S'TO:gʥʙ4K@x:).:&omCH)uH859Y1mĥ[ XHdx !v̞[#rW(IJw?V;a",9ktC(@4%=/G.GG\"@u$'[SL aO,>>N"ƃ6|}֭S CB/s65PQ֝g32 endstream endobj 4436 0 obj << /Length 2080 /Filter /FlateDecode >> stream xڭX[۶~_z0^@:MQ;M;vX 2H+]h/N$`0o3 Ͼ=˷,(Oi:;(K1J":;_>um'-o¢]'ŧ|Q"Z-#4D'Ɉ:!erR/"btb!f!ɀI/!MpPv- rf^~*-1 9u]i,di+DݗVf[edz̋iÊ'UZbbo#!M,2S' e8(K5JlD Y Bvעژ 2+#8$cx#0&ejE^Y܉EN{(bO=9k#ֺK'wwfeY%Hi%{&Ux͇lW=\IԨM-$DOxiEiAIXt 4)ʳR]Iܔ;P;l^7w, ^oĂ? H(5ן V/}1Š ؏ӢHT" (@c+ntYjM>56<=ll/Q1͡.piYPvÔ!;X:fs|E.y+ /I)&swH渟IpLczf& eeskZE WHIBJ??Χd>`6f_nFu+2}ST~?|7 D:B`}ŀ`w{Z $13I=A,Anw;!Ʉb dzrbJ*MhL^Z·rmz=n_Np1nTܭWWp 8R C?AENWf[IR?@;zFHjsaI3y3 Q3}ZW>јh f559^erz =OW5-ӏ}9];.rU"01EU )Ykכ~fݟn~~ܡflxY=&oy=:r`~mbglwORMX4m̈kim&i nj*wUfy򎙧ǎW9EYr\2 K4҄}4~ݡs,:Ӗ_D:o'DU{4MQ Y; $3.]+,fg':ZzZ>>)8WχQt?PRl/+_>SE[;S>rP稬TTf(B芶ܫ23:JSk!.XSզRW( H44_ʶxsE 4 EQ6?R0C>ʶ'IYP"Z4 x{TZhBl(%f{MencI)qb˴}KXJ.8&^P]lԅݔN}Ns{ CqиєW`INVuFQ2F*u.xfBR}K0!WHQ%ϐӞћB"+ƱKc6-oSZx{x VegAa|308BĖG ^? RL?h.L cʤ )z2?|8A~e -d)q!7B#Fp%-Z`h!Ν֫1 ՟)&zP@#@D(gŞ dYÄ$噼cHP豄|;3ُpRENX^4 E֧ٸhy3?;#g!ێʔiȆdsD*NT endstream endobj 4381 0 obj << /Type /ObjStm /N 100 /First 968 /Length 1597 /Filter /FlateDecode >> stream xYn[7+l7g0phkdʷQY2$H=3MԊo  oWpT\p);]ŪBuT qThb3 bVp.QAl`q frҙss)W R\UVp$4 24H18XSK$:H͔IG4USY\& XQ RrDŽ e5V W@*\b ث  Yl,-7\|M`OhT"`Eª=l6X ֳ9<#$l`uH=d@ށ6{pw`tbSmO` kHf 5 ud> D-(%7NB,d*Uٜ7*: .M,(QoH<gJ%|Il\.5Qv!U׈U줪$84e2f( 4K.}9u65`\L xN.v.W(Wib8%V Sq&2-R-F o8 Gc~3=y~D?BJ"h |*U qz/Qv:D1?YB|aDGm|Rߌ$a\}ItQdVk‚*mb7w¶Uzhr^/ p |jQhS pu=` ѻ .Dl^ rq;a@6|ӽ4\&[I*V>T~?=+DrGop_&$LAk-`w6wE{SB Tq#ZA&un64D?ޏ}e?(:Z0+LZ6V!N_}rp~Oe Zz{t*CJ/GgнD)hԡ_04 W!^RUV^^kRGrKD@egY̻byխw#FD4C> stream xڵYmsܶ_q?$AtMtdcɟ̄ _,X)ꢸd@`}v+㫿߾zs%*e v |Hb3fp#g*9e=fMg]S<2k[W c$1M]{m (|"bMZ KC1^Uؐޝ2:#}̳4 -9& ]i<F }O9 5c! 3/J*sC;_G"׍m~UՕ(l,ABڪ镾?6j򢮨5u"~4cuh65z+f+]]†ot6Y"_x}FR9MԅM"|^]~. &W-C GMgZU%<1E}`F*C/Ԃ{(aXEjuwWujjF} 7 u(*' #`A {`.C6䱗]4Hԡݹ/`K!7rk'9UH[ s]#(kAk2$#ORO#5Ï4XU&2SH5`Mv2͌!3 ߙW_ f?;&3&p2ܔu̷#Npƻ6 -roeĄibgOI99avY؅g>kz9[`]8vf{߷f'&Dj} ɜ~g@ )]X)= :BSrۢKgsPa6irXoDVswؗ6T,j6E <⃧GlX C*G4j*$2}U&.>VhƺҾcJXo\j8b^:6Lc-ra >/P<3JһEppF]pxnL35(3[!>zxk;6M5d9WHM%Lש^/ I@&1O,Zz_Dž%8װ n9r8 ɍ _"K )gX#y q)!]Ⲏ`H|bc s0(JQmVtb؅Qt/~0#d$F$SpVyXj`HM_ YTPx)@M;5ơ!k~_HBvݞ*S8;ᛝ\F3P*` {6[,Ŭ{"ZE0tO3$ a,L r>Th#6)OquG޻KFFX ]. 6:.t?>Cg}:K< G/3d @Eaч.?Gg!Wr',dDE>;h2;Ta>ۛ × >5sC<~[ݐ+_}}?Zu3m@(Y);;g!Joޫn_oN _ru<`h]u}0b}~65g-eT\_1F!^y4Bj ko$^x,оÁR8|{|^rCm_$|>U&K(%h3Wh=gBWyQ:)QǼ (Q8d%\?o9EG (k:p(|/XOF nɝ~Cڮs]VH`|"n<>~xpHu8Bs'*/"Br]B:ЕJ͈mMOkSN''I#{V@%8~AE o!RE!XN}9,SʗHgF 3LHfOVl!ҖwEdip̓l!kױgSj|;&.+v /!KթJu$%{:MX%eh웢4c+K*6G]%ޓLC dH(pI s~^h%]1A] |~T! "|w/iAeTe~Wm/oo/?\|t}b_g, 8P>BґsH?O 8j)3 4̷j͛8uƂft5mCI2վ>kugx\0]~ غ3gV Z_K[\@/K&| f"&tmI){, пe]bmSH-#Qȡ4*4{cBnI.4> stream xڭXKs6WpTʘ6ݙ6qX990$,1C%w Eʠl=hv9E ՕC0F8#3 QyǸ{ &E$'Ӹɿ^c6NB0~zU!GQro Il*U* I/] ͱjj]U+(N4+)16nZ>֕.U *j׌!=zR!𜤘}6AMEsOLܹC cQ`l+,|Ã=EQH]t)ËWl^T%@gmBK%9`q26`Ƨ˷G,xwV+*sĘKy̕KgsJ ǁ-ޖ^[Gͮr+\ApylqX@XFH}#HC{HZCwU/ 07;$NbSt פq&oSynӇj\UuaKzP'})ylgtfI*0 U#3i:gwy ,kMr^Gu1`ʘT% 10UXCNIbB:QxW JGGaY VZ8I&6$UٴYk>v eA4| e+J?W& q: !}Z~gŃ&e\ɋP㫪wqpڥeb|QۍKm[Yي+$&U]f[$j*ѡ9TR(>.޿~mA :l(Dmͽ4]FSnn=/y&=LiD>z"Gx*:A!S I>YCSᑊ(<Ϛm CTdqEȨZ$˽݆20aKbk;aC<9,WUg7(ө؅xO {QH$:L2$}kGD:9Y чF.`5\u"IsIH> stream xڵX[o6~<`%)m@&Z*3:Y$yIwx,ɴ/_&oWל{19# ziF:յ{GQ$(҇M*{^犾}Տߙ!/WYa)Z7U_NQ➦#9ߛ1liSMbWZblV-JQHeWģ~l$pJ9 ?jWk>s塂N~۩!0NW_Vct3{K`PGރ>BBG#E8K/VX"&9+9PG ŜY%j'ܧ VӛrN:ZlRNPho2sd2pD0uZe&+ ggCH+0WkiОEvL 1O:جt{{{+xvzID޴v6 C( jn*YI4!$$cۓ҈UhTIlL =rأ"Ȇ'tac:B ,uq"B4ۓ}*S裑%dH UIйe0DQIXXh,5c͒|](+NZu5FM{_ң2ik Hw$_dۘ#ÔRV*]f %(1XIQ4]'U6r:}Dz0nweEQf`̧w^8ݗz)eA̫IwoFw@}BC@ q}̒``Pze`1i с,A a{FEHZ0,_!YʌeVtZ1BY} Ա@6\sMRZE^.33"G"{TN9 R>w|# _"A)QnU.. ech:yXfS'jXteE#Wnzӊ*&-Ǵ*Yob+gS%qCr;*YGo/p$?-Gn1} aUQVN'oHe-98Ս m EҐTtE( Y߫I6l).i|0{iB/`^XM8"gZgg1̮Y,#ɞNFҰ(%<J`1/29gCD߮~o8΅C>n@DgM٬ <="4PQ8Ƈo{%v{3q(M7?N j[w;9vmA|ɪ\/++}Ys~AffyS.|6sF_\LjEcghԤ倲IvfQzͺ<^NA-z&:+`l+ :L¡ċoXedYPO~PMY?O6CH<#[Eצؙ`'٢`M.ܬH:%#"GѸ8˕+ >H}2KJMW*t]!d3> stream xWK6 W(Ct%EJ2kҙmdȒGv__ e:N@@#^ƣ޳S)ġz(%\ ) -Vޛit:Ogo?\= ÞC" ƹfP{p=cRГdU=mz*p(ݑ7g@]~mhn.`˴~1AJs {}!FI(d$ڦJqM̝~**fgtiy[z(Vv~x>I9:B {?"(Z+hkCfXǶ;Xel diPwFAQ6F$ʤشyb1w}e8 dqd}AIMr{Wfd1y?az˩ s᥻ɛ[p9q]֝'#Rps[$.$@/qNXd?qI}GeIt@+׸<`SRG>yT%^``tZߎHA ~"A18tᱪ*ۛ+'G˔B+Wp jMP:-rǨcPMpUMc>^%xU |mV3ʊX0UiSVV~l d0iʲ\otkJ $jĻy!<qTUz Aw^:!>e5ͨ2A"h= Ⱦ-њRg& b-LѤN]#Wm:`ZkbfY7@4\9`Kכ46EA KF||~FC{Ռ˩ڑ㤟%n_trsߏRu &":놀sM2{_RUKʺdqS"nCKg Pma,MfUVlڭa Ŗed溹29&pk8ߥ]ܥp@bf4Gkok܏L}_㹴H@搑9丛.3o3~YX$|aQR#[6NJ<!XNCԵ bf%a* %6MI|ZٙmYi NS?N=!hcl#fȣnN6蓅vBȠq_WTͶfBDmi+;`hݻ"\" _WuHpS^ i> stream xYMo7W^( !#@mhkڪmĐYF7VTN5ycuŘ'/ˎ(hoıG*ѱ6ltQNr7E` 6ov)4ťh339gvZ 60BP|!eG\IȰ1*xNA1ͯQ׈iP̢<>P@j b:TY AmDuKp0+,$NB,) $D@O2IcWؕ $;%[!7V̒k*08H%raS5 Ɣf) 0$|ȶ)@`ԤHcm[ib&.EɌiMS6 \D&$8 $h @Р̅B]͒\b8?UUfESL 8+r&qbqYfc̫p!l*f+dLȶ m(]5D[WHT`{F\lߓG& $\6lFdfhHБ χnǟYxc"eruqq3v }0ޞZrKCr 2"A.aȃ,O4 Φswo_׹[x1>Nǃ>'K+Jxlۻ7ѫWwdTJ^"R?BhI'^_N&SLzFۥMç  ]=oϿO> i Q{0X" h%ztE`5M2}?uذ/gg?‚v5Nkråxdݵ4.ތdty/F#EI|QklЇM7]Ot۴z6WQ$GMp!1~٣^]f;M^](d'OS+{Ʊѓ;bփ2?IBr KQ_;%U m;V-)+]u-=a hr"o@QujS^ `ҽ[[K™{{q4æǞh 4Lncw}>飊؝oXTmJY e-h}UdwUd{ack!k#E첬DZϣO㓝7Zp/FکnQQ2q5í:G䡛y!tJvN8\hhn{?|pyݺPݠ~F?ap+| endstream endobj 4550 0 obj << /Length 2062 /Filter /FlateDecode >> stream xYێ6}̾4o`A< g$FӂՒ==_ŋ.T{zX, %*֩:UqW?]pNUbA~"#*kͧ_܅|6Ō =NjAr0ohͪ ~/ˮu/q274ZmHBB3Y<^vMת9/i:a  id@I֎tLvEQ4Lܮ#DxVC׉a†Hg$/XvJ /yrFN[n,h‰ZP5YƬYRiX̦]5& t4w[Td˗i>^15cdz#0_&˷3!1mwC![Z&b ~E ;KMǼm=짭')D8?,6a,zOCF|".dr XEYioyP+'#3߽}+(DL$z9=[) E.m?um xST~󦑀7IZ![]BN`A|=F^5!ߴVf,mz"vkfl`fSp?O$YnYx~Uv +rs%-->xqZb4Rw~S9[ | UHn nݺQ.]WZg`M;;|g@UkMxlRƼ Xa%s:we DH6> stream xX[6~`E m&Ӵin^4!=q!Ie[l$ z[Ko4Dd_/3Ρ*-@HPdӻni1 (k!Nݱ>өc#(EZZbٌbY~Ր̤aa|@ وcpp .B+TYo*{vP܃^@İǏAG:FOAŸݞYb7+93N@ ogC4 w2!k`W Piy-~_ eV~vetEx`1+<}Tu^ŸؕŽ}k5Ĉ$dUUJ.'^ug-'tBpKQr-F9i,Fn=jFyTȖARxQOohYGopsA4" l%&ON[eMeW7_jp1+6j. >U.5>LvUmol0vaKKTE6ibD̡]|4j$.`GD[nYJ[n$4bX&8zm<9fEEAmN6T6[v0"O;E$slA4t+ tv%/v{;6`p~([o ,/6N^Jޝ( UJ$m?޼\UTf:-j# b[fr"@| aPBҾﺈjh_߈@"XSgpv,çr8%{I 3Ag(!\Nc~T6svz:_8n͊#DеF]8U]hg0ĔѴ]Zl(xyzyL=&]S~\!vh{3/,?:eؔ 9⭀*-f[.*tàn$DK$GhTF]snˇD侭#乺ng3EA'Ms_#u(fC%z*)M1$MBʇ\mU)"StN!z{@sv H dV} Fr<~|S(zjc*=0k"ҵty#՟a Y7*Ɋ#5fxW 0n̟iV7h:6J󟳦7LI-yGn tJP٩%H _`?}_4킚=KOb9Z7e>~^x2Eq͠>ާ0l~:j>p endstream endobj 4587 0 obj << /Length 2333 /Filter /FlateDecode >> stream xڵY_6O!(*,I"KlkmdɑlwDIKiŢ(r84  ]|w/q(bwD"n|Y/>/-dLT@H/:d]S|Yˬmqt`H,iI^c$ O-`c)%1$T4J1M0`.Re]QW%4#unx &/ШCz: uS43c18S)"nmN!K MLf݄Z.3P.yL>;o51$%)u~zd_cyvuoI=-WYOU/ yc&mgx4Jm=KP d( S/棆yY?] zez\^x0b.ggdeixh; 53}Ό,FX 1t v_e6L0~y1fck&ut2 L{-p&zQj/wrA17sT]^}K"ԥ87*#) 9P[4cS4U8h3CrƦRĘJ}RjJ9ENDI7vb5 vXDqI.2 @Kqj,"FvH|HYۓň  mɻ(]D|N"#4qCD&f Y?/kLFLhˆ/SˆQ*) #[R&8;9EAw&k l<|(Pu)ZpNh|3bJAjuu_7{+{ DljV` v-˜ gZdh%@Sի*se5$qH>c2Ҫf|g^8͇G%Z)87 U^#"MD&"Y 0$] [<hT+ITIFn5/emU?Jrkź9d_o.U588"\="b7`ygC`"(j"Bݮ޴ߛחuZ/Zi|dhӚ[ͫSË A A7膂%a{B.}1)_!BBًA"+3X2NiPtQ/jJ\DS?3JԤ] ־<@xɽa?%x?kF:R;k@y{GhrB>Mw6*#Uxz|C&~.!.6/KYrT4枓W|}H'b /& endstream endobj 4605 0 obj << /Length 1804 /Filter /FlateDecode >> stream xڥXmo8_V1k+ݝӝT[u69`쿿 ,&6ѩj 3ό{{~}r~D^8{`h{Iwn-m񴺽2'h$MA^Nh`{ f<5i6}\wx~D؊xݻ ~Wl߶fi pjm:=3;Ȃ$(fl:׫ؗh;\]/qlHdt:B){  euBfb)BP *sQU@ +Z-izy+j1k`-#뇉aS+ޘو6 Ywh AS0EK⧡oeƯV-\G4F1SOM#R5E ! G'A u9oy`"MiV~з6Sf"ek} ]af!u6XkD^|8D6!նfIhLF2r'Bi4ڌQJGb>O3Cn@(Aq[14rY%4r)\)pM fu*x̧3chO"xcאbA !(ݭBo{#[6qbAt@CnKP S9BY9oڤrA {k\;!(]`>LYgqh18]hu/A,dIhsVE'D  0"2Ԅ)p~EHΌK gp2u}cUe1#s2UEc qedW`lјNl1Us-Hb f˹ J,H9-7 bނtZbpc^WC4:=:6ՇSiiH*R˪VvfU"~ zvϤ/@.e{ ~|zH=ߛ*ȡnMiY-}-b@IOOO[:,AX HH2l5TT>0c2ꧡVo3A?3GX{{195WK4O- R7h#ȿ*dLP0㺤g/⾖dza]d5ҽ>L]~\3}|XC!&V97AFѣNA{ޮzc ~[zv&˹zX֓%PvZ ?Z_*6x|> stream xY[۸~ϯ0$1 l.Ȟ`}mV#K.{ %>Y,&HL2|s5_|7zx{˴ԋBpTFs(x- 7M<٪4Bnӹ)_)po+ɹpp- Nw6Ź+jvxBdgX8W"w*ʫ$Es9oZK-mseS)W:jgipÉh))Jp-Ĵog`|9F,]4.~b*[2A{zٕPKqoJs~|閵2NeIBPw'4gy])5n?X@i2Q(8'O sd25|[ y6l(}eެDMQi/=eSrx⑊el`OC:1l9݅w01#K0+Q^cS)y?گX@%7^5yQf7V ['*(Gߥ 4Ǜ2~T]8ݟ%}%A"غ㵉M4֗_/8"DY܀4pa#[m0w>'1q+lēH~+4esl/Yu@d i[TG%6}'90sRJ%`KFB-9*M6[[I6\G㮦Ϟ;=d [B-4cꂡډ b[J6:4NLTDTak+ D1<>}Ab 6=Vc m̧ 35%b_)VO_-K!OV)Cm1Mirɵ'؈K9։pST_#-b FU7>]q^Z^D OލE;t7YUL0Kf< ħR#w_L`mAw?$_0d! 2.8\"+bd$sxZ;ESjnbSh8[ϯW$[cΡXl8T4*FcId3)3^5C^ w \ Kf1 ֩lƀGm@RY- (v(hCGWÏ8:O㮾*moAҖMMW]z#*IpkW[2] 8کגvo Lţ20C8(SJ (CX/Z"7AJL_z˶MHLSǝvӘ8UD1+8-Bͦ?TA^:hK쭏{{r8sw%Px1?Qi˨oU/~vN@8*չ0B.ǘ N(yc^F}_P_Z2C0dx"*<Ƈ SDVN0:3Pk~z46?˯Ec(cP_k!A*BO1wo8H%|f?@rAebTP`}PaIf1IzB)eQ.$pq}%TH⋻Re`7+b endstream endobj 4643 0 obj << /Length 2441 /Filter /FlateDecode >> stream xڥYo6߿"HN.Dػfvaht;Y2$ rlC|f//m,YXn.8f"Ub%7E?)-RDX@mODĞK|!M&_]LϮy*/ L\[Y+S.SZä+{z4X"ȶ{ kiW T 5ihW݌;Qh:IX.%72\E;RPq,;Kk-]Դřm_x0IY2l)ӄc> 'r |䯱(~knk:kr+Dї\Q򗅔QK_9mVݡ1%R`;wDͪ.Yט} LEA 5~o5Wt(xێПpɚՖV@î+NrhiGO.3kOځdE'J8K .0ӎߡBs$YO@p%+V4j}cۖT e&y¤D 8(}ګ}}ܹLfZ#8)˳??1!h&HfZ[gxQϨXs&AvoWHzVnl@xZى|0s8u'2pf0$d5dk+-1]"L8]K ܫ6"xi/Se.X4N4g!}WUa.u~3|.*%xhʳvEGwu$tԌH :ML3GO )~5Ϳ/HǺĄbm8o:!X4 m)%{c NDMM (JrAz?tk4vf͚nj@hdc9X+*!iٵ)])ʴS15W֓j 2BT3xUz:=)gڲP9"G@Edy/b͓ B\ф:S:ݡ](lࡣ4f=.) -M c|`vw\O˕Y,jmފz@xUW$pBs$B1 ćbՓ~WcDPX|!; wM(L"pG␯)G͡>xE x j}gfO _2v7"m }w._ʍihâTEҴ뵭%Ep*Z ^"/9Xuc/:3ǻ3|#`O+U+BQ)˼@BZ ZSrW]׍! Q>dLedmp|"{S$S+B0=ޯj/&qU_ӷfG{so_L 6 ;2oy_f?Ksgf|KW35Ԏ?iDxxӨ޽n`? jsk.理ǥSH8sRT+KCp$߄s|?ő{ endstream endobj 4542 0 obj << /Type /ObjStm /N 100 /First 984 /Length 2360 /Filter /FlateDecode >> stream xZn}W}rHn-m<:bK$&3זW `yvw<gΐbpƙ}2A? l *D# &La7%xOC4&bg!%g|O}FPРJ-e >+jR"z(DWxHY2hV( ZW)7Dj &_}dw~8 | J NRݡG0]}#ɾNL:4d) &_FHR[)&Go xΆ7p”q8PIL/⃙p +^ޚ8N>2x7 Y]۫ORgӥyʌ:Cvipu YVO|vv-͉}x{hFKso7?w7M ]FGbv;?Q'׳Dખ?,jss4~t:C'jT[ ҄T!oOd`z6?4/7'^(3 :k%]{5?~F?6?> &GSv}-瓳c~Gť=/TY ³z`u-FP6xOtjXm-ív,pq9;pm7FHb} [}p`hꇣ!FdAsM ߌdr6ƌP3J!#%!.dh 3ʆނ}9-np1D.A-X <^ 3 q>߃S]pwDl:ob>w˿,'e EgO+2.zaVq &9} YaMmu׷ŀP">6V3R5G,P!Uوc|z:~ݐ[QGAۢoDqsx=] L??M􌽼ʻyS~%R+H\q\D7pp#7pp#&%%aED!ЖaSbi 亙*m9V …S0zB,YCe ̃tRw hR,2ۆdkrz\rުjP1]yI5~ʉu2Oo "VOA- )`jQݩy&oX5 YYȆ= YDm=<_ endstream endobj 4660 0 obj << /Length 2361 /Filter /FlateDecode >> stream xڭY[o6~܇7T.M"M\,=VwFK:C{/҈z|Eшs9߹ N N~8ыB$UB0FD RF"O>[GG( C7 ųZwuњGسyD+JC}+=>wϼ x2z6Kj=6yisݛ7?]~>=^zsv%1n͒9(K3'qɛVϻbۣY׼7xuūʅR_n;/kݶJ4eE~^+Tk*|7VDm[\BwY=ɪ]]/%(#*T\]z[v׃u ĵ)K뺧Jl0#|z}{9 HOMy6o|A_uS#>=e-NXef5j-8mo*:;zs~tsD-Nީ (M3N x!֞\'$U!O !#줜#,A(S9M3-~oOd:]ݔ_󮬫2z2L!B{.r3pZg .?C1zvk]kؔ'4at}uBpݮ3TS%y`9X7iY  *eɴxSW#w{].:n+gL d!LU~Yx"2+C<>ƴ@\dЫ-* ֛ S&b ə,MEdCkͶ3]S~B"%AvD^E n佝$ LJ%)̡8t12p;l0\Eh&FMc8H$"}^FG%h0 P^ѫDbט|tdzt= ݞF]"~%8@0rPf޳΢B`Ĥ/~W*ih?:TΊQlܘ>}tf $ÉԼ+1k6`鷻h 웚2j]SE7$}RG<ÁkUQZqBZe[k@C}B! J8a\e{ 1%G޺]o׺,„|I!4ˤ_~aZ3W[3 UߋM@4Cұ .(+mBԬլ\oVz Oe+~"Elg˼ձS٨X6*[;fVҡy[ץ&eoWB+( OpQH^ TYSoz"RiE:!񛠰T߽r8AJ͡A45=Oիw_|~#m4rϙP00*A'=ٓN\Vy-* Ҡ[-r|r 9b;z2.+#liV+#Iv85˱ 93%Čya JmIaV$6XG\{k h_t vm~4doX/LW-<,Kt:0SِC bF 0?dNl; 2FkW4P*Tr$4JWMkPzs~} endstream endobj 4684 0 obj << /Length 2234 /Filter /FlateDecode >> stream xڵYo8޿2P|b9 >v`ޗ(du%G&7|Hlىsw)`1!'7QH4\]Oƈp"CSp[N)f+]/E5rwa[TRN jѣ3*͠[FqU=H4)_L`>D#BKi j::.+m,&2β7R7Z$yҌ`m}Of֊CeOB"(Ga֝o^/u> eL>me ΥzsR0rFR"t<>cGNP$3zI Kjǘ(qQԮHII6L9p0)Tw\ŵ :E>X겨^v$KתqݶcW(L]{k 1)T98@*j瑙7GԛJ5zJ.2BWIλy1%"n~3&k4yBREV*W^f2ŽIl /:AA4IVG N R>ہҟpdKRţA2d EvlbD6%.QH 0!fwK]1 [~V T,pBE}8(MKm*lլY !dõ}e‚L݅X>sDZ\a fciugyA) jJ1U4F?9!C.Iڥ^<c3GN܈ 9v.X) ʺ1i/Hj.Iiv͏Fa!"::dю(ݎId QѰSLH N4(10=HZ'-LfILۭB8&ow"+<'E&{#WNLgb#w#UK0D3W_@BAt|Nejk!#MjPeF#Md;y g;9VG} 8L@~]䍯m=dp5~Sqh&($l=S K{ MTQ V0۹֫ bzqʂ3z(6d\8ު04M*䔊1o'f (אp"I(^+gFBDx/fnQ5#iBurPĹ'9rC|ى}v2ڋ6i+܊պ-4, zVrHbWnb-uSښ&DC ݋S TO8%K~]j_eU0:?2-A)1;wl9/|{S"N_I9\9x[7d}9$H[vG+AB=1:lVJ:`D४:XA( s,+rv"#S)ȏ`]6r%fn>SM+pa+.6t{c2@_ŵ? 9ߪ?Pݹl;,q^߮?&2pN+~ @WX؏pT2n+zp+}7g9  Ӿ׶7 W+a*>HHQh&=_P~{xz[{\y]& r*, yPjJԬy$e p`(|WlOոh:]\,.\2myſyc3Sywm{16RĿw#hM 2O֯]?ieJ a9khIX;Sj8ut|&p?{d ӈĺP|g>˱ed~ 6mGofGDӽgG:y# 9zHأ8nϞ'I3&Ő,x\c`]8Tks3nehCu8FՐ]VE3 hCZ׸n Etߘq>yU6PDm}ZվEwi5[FqRK@rs/:rO3쳹pmVz endstream endobj 4693 0 obj << /Length 1192 /Filter /FlateDecode >> stream xڭXas6_&\ǖ@{ vHgNi&#lvB.JHȆk miWxN>NN.GA~g2s|sa;pv p&s{Qm,Avm[K/h'r7 °۽e YNS2Kh:eEy9< u!Cɧk3CMBs‘W,F]Kh WnN.ʊf]8ol?Do,[t,I$fYh;ֿ c ϶z+M›M|F\ZZ1c<Ǒ5.y,N0nڲŌ nʉ3i򏼺w I3>/<#!I.oIW"RrVyP\5vǖ!`0xP)Lm t939.TN-/'&zOH EU=Qa5 vt\J[pMMh$sя\_țl(E?oה `+#Gen!h4zUWB Bѫ X'("pPC8yq|FG|^ӄ1C,%cWAqQњn_Ϙ3gf r64^bͽkޢW𻌟'_K^b#ˠZ$|ˇ90yhQ⍏vD'V^"{TkRn`Ca&X0AkO{ 66L7ʰX TVV͒aӼ"@ sNJ|dzNC;,YHSs}9ۖۦ K!4mrş, 웕c,6V?Nx59 endstream endobj 4700 0 obj << /Length 2227 /Filter /FlateDecode >> stream xڝYs6g!N7u8s=7Ӹ73)IVoz-庵'k,[ƶVm}[L\gm0kXwӊț*}}Y;'Ay$7.B]I=wPd7}l/ً;yY 'o2Q{^#挒&i͗YZp./IV.pXh4+ZO="2~{7eƛ,Z.M"/2OVڥ' )<]jͼFCTu* x)bEwjyh8S&6uLib{"Wl6H9J]VU"*C PZb^5ia1EsAwE,!EgSM<ˈx(!YL)$X&hA#< ){W<zpc?.[>|%Fq46$_qSf*FPxa3638cYE27w̜ nq[xrg0+3Y?p9C2|ݶWI[ oqpu[-s|Zp[1SYEiMP[ЛDru# Ii*VHi=oR >`Λ!*uTR0N;F14E:M<ELg{J.s\efR/PY@)xb5{|1eסz#~Ѓ\8-ٌnOa̩cJ~`P6JI9N0 *=N&RހǴY˞|Kĸ ^Gnځ!g2X,"a)徽c#wWN 6I_K 9Z_Zj&֝"!?x 9ܰ8UR bS&UuYJMy RcGAfL y]/m:ט .m]ЗujZ)R% MM]yb\,F8sIdi҈ KCgkU.NTrnhkŘk|9seF}N)#I I U+iz$˸}ll'1p]-֡tPN' H2:?\lY̩C RɈ4bR˲.?8nl>$V Xvx=r(W!Tai\_^_!Œǚv" Y{'WǗy !2`"!4yX1 EPg(6FGm`kH"~}6B"eF4T"C.3} {8X@'dG-쮦ut?"2Ć .R(AW!;ïX6A4*QA 3,'N%(0~l{ endstream endobj 4722 0 obj << /Length 3525 /Filter /FlateDecode >> stream xڝZKs6Wh}<0@DXn*+ 9}"phQ"rp0x;A[HLn:$GYK`\N2l⸧8ꙟ-1g rgiږ- tK 4nˁ4!H5pG9{+0yT4KXIz[Dn OȲf9`e"f25xB + .b.Ct$|LayX~LAj=,D`Z+> }a-8k6ؖ`6_(!QOu6|90;pZvDi:!NPBO]⒴e/$`6t97j)0.+U#a>/p!8-rYcqa >#OMC0:ywmIH=JҼorK!a +{=`Q\HxP!#$;AlSsfH3Sx*ښƮGQAWIp(&L0m]p{almљ,}{Aw`*},~Z.nj2QUn+Ah]1ontjZDmm*֧+4fmH b5@J}#D8WYC#104vqzuA4XtcƅxZzUhXWm/M'=L&I(_C "i-W{_Yƴm?NJq5 }UJs%Oᗃ%DT;*ms5W1zlV47V%~'&{*A= UMXxt*5)-},!z- `CVr]\rAҥXT/jOɣ9.S!@%]v&/X+|7˚ȵXy8xf&~Tp6 9 VDO@mÇ)lU۬]Y,Jn4Ef^᧽,^<AZP6Lĭ&y.[[ llA?"ߏwE gn5D@?+,OzuK@6ŻǙ9n؝XY=/5 ǗZ0 և֡Q,Ϭ'![pGێȃ{Z$ 4u<&#z0xA,ǘgJ,l5g{sa?cR桉d/t G}ǫ*tc:qK7(? 4ȭ߹n Z寬 )}=Z7"'\?tVGxk:wq)`s6>֝rE7 -Top!)>? q\r#&Yі ˲wb 6dV_wHpPJE'g%'e1}ޘj=@s$GHRnZL%f/p ͫ e endstream endobj 4732 0 obj << /Length 1590 /Filter /FlateDecode >> stream xڽXmw4_2`mUI~(mBḺSq෣7;c2Dsuգpr='G_/{$" eυdM^3%ۓWnc O"BGPNCڬM쉇jʼn72g@45M#b8+\یpRP-㜩Ij2=}H4UƣB-N0&I$VOr\_ӢLU㜈=o!tL%ɀƬZGHBOX\b>@\u YսZ+6|T+Fc6J _a+-YSZ @ew ]%Vxd t 7Juܱ"9H,oݰg>-+0b91\MlV+&e;B61YQ%y 1ND+l`urW,`A)d V+90NsEjrѬjUCR18R=Y0ުմI3J(<x֎&V3g6DYZs{5v0f/#`>54tF9Z)thQy:%HU&Xӌ_m9DbC^g+;#(\\s:5;CTb!Npv&〔w w8|v{g0JxV- |SŚeS3䴣 3ˍr-y(42*Wǝuj9!4K)^k}AOqFמ+|<^XxOo ?$,aj5!S®+>*rU֦(>ԩeY&اSS;h։ ߃$ΌX˔׎/?]p}ܠSѻ>Po$ۖJ &޷"sGmQ(/zVQlj:4TCd yz7oL۾7wf^ - )ͲOz#%zJkL*߆ mC"YTXEdHx &k&Mq6p e.Ui;ظn_LQb/aO+RhdZ&U$02Jü:ZR>lV֘P#M֦5C=jGo}\%EO~ `⋃Vֵ%M )##Fl5J>)>*9l6o:O]jkI7( ],vטmAtYBUt:1j|<>GSoAR_:J Yپ3`N)L~aRx#dz ~> stream xY[oF~҇k2w]m MumhH|_̅HcY / s7tr3g?\~$#zr0JzhJ)zϯ%r4U(F$AfR|Stgԭd~%n.0?ٟl(hj;]S>mAWwvD{\ 3J2YamWoUUwSE|]?7מ߭vբ+ 3MʒPlLjG bZŽ؋[Ǭe/}IB8S?d /Ae"t`n&1H?z_#h8eg&A0N xv%͹ .EmfRME~J\H ltHtkI梨]4dp ,#Tɣ7FAz7a_Yp#}k"[l$u))Ƈ{([;jWSӢu>?wZ?p?~rV?N^-.4~ )xdb'žӌ z8Av.$ QES_aVx7QB.]zWuqCBq@7gy nc6$2^)N8m޴mfվ`fϹW)صŇͻ~{h}1[E3cMQuQ=*{xR\ܫWnciI3\F1탱w|vnTVKUSo?45ciYXp"XmKKmBL zt Q4)ڔՍasEu#25Nv3 h^[lPhW 8ewk0&Q7ݫ_^ERUIPg6wjS ;kgAF]ikz[F~]A1YvTJO!{,bر4OE󑤻  L8$XF< (?S0ؖ*$! ʆ' HOHy([Kq4312PJ>T#"MdF|jj&Ҭ?"4k|p.)3}a@2 fNN[v-8qT$9YU=%n\,UTWE rCܰUp"V'ǒLU)fΛ9pRSm/HQQ(j3HEn@Utοz,CW$񶮢坙bGvYBev @vXfѼ+e4CIAPpuPz-Ô$aa$V)Mt%PӐ t*5aiڵ NsHbla sh7$<>`squ?E:jw"axX4C4O0}LL{7|ӷ(@9핃1 \s{DX2]c`w؄&\;u3mt '6R CE|)J ]ͫe,D@'G{vM9}ob{,E?M1j9idžeaN,>/qO֝a)a:2ΰ?%!CqKiD`r!kp6ޘ]Dd6Dcg 4Wb), ɥMytg ]wHxP}>Y*qU%0&Ii~|3#&L}zm*fi (-'#1K,Æ I cLn激?x:'R-QzDPPw)@!aP28F5ԀcbZΜ vO[lUT[ϊ}u*GڐK{oI%TBD/NW$Y޳g ů/jŕ&1"{U;v1(oE+5 endstream endobj 4652 0 obj << /Type /ObjStm /N 100 /First 985 /Length 2452 /Filter /FlateDecode >> stream xZ[o~s0imm<HYIf}Ci+5H3C#y.!G&UG&DG%jBqф$ C&K%@PW؛jnBrDbcAF{R@0H9(P ECAHH@$@b(b-"x䠆:a\^qjNqlSlS##`dس:ZD'q.9Ij挕)3K F֋@t B&k[C RqWzO4U{l3/|=sֆ TbH1tbkO-`D ez })`V[dc5A\60B68F-lɥ 7Τ\L*vz.5ؙLV>hz 4 öH0YBl4,pnV1圳rV>!67ri9V+9!Wb2|^k*Qj,0ۖ$HW,(O儵lajLcj.Q$v&!z`s@#*v =g*D8AOS=櫃?/ݳtxku~ꞿpMOV-xR-#p Ru̿/>NVǟ&gh^0`Gy|i^aˋw;)=`=L[BV1LSfpô$~9"DTךLp?a_p%N._z1?9b\K׽~^ֶzaz=ǰji ȶ|9\L޽O?f%F(bz@',`ZR/&|J=PЂVOb8yNg0jqNgb\^p <}z`# \^BxKڐ K3_IJ\;#FAVȺ ŤAi'>;_MGEBZ܉iA!{D}AYh3M;M2Tx!V@ފW9i -?'p8CjK'(Ol9!u?MTOFȡ4444ss{.}ϛ)(E_bQK)jS3qb"S k\)+]p~]Ą<dR@oBϵy[W,z"c7s;X6'O0gDD|w56a{z:ϺG?VO?u:L%s\R RÑx+@ 3XXT#SH!W'1 +VQ{hEA$懃b!b^vө' Fm:#U+-x/bHT(7@,sMz?Mf4"S8`c@u6 ?‚$Nqew~6.}5~ARw"yv9;9l4ԣhO.o]x7oh~{=I͊q!M N-uh8P[ԁʂP\rŠޢ̷qm=Io)sQXݿ@ٿLsP}Mc2vc Ҋ bIC鿨Og#h >ɋ0LkyAFm|Q5jmRCcΒ+Hמ`c:bov J/l i R/=S31[Hݕ` Sl%3-P tu6?TDq+KhIcGCJ1zr b5&#og?v*]C"Rq.ņew >@D$W0b(~ו`;.ܪd`#2r䪨Qxe S2w'o bI2IQ jѮbPq؍2| R;RO;je~<"|2̛Cl.7R{LJp[Ȁ{LPu`V|U%BM!n~vS˔k h 5Gj'vW>LY-pѾ`!\4e3s(ƣ yN _b35 DFmԸ-VuJclU3IJaoWeo|CCC6ҌUHDPEʈڢاkS_]C(ʾB`vB.Th]RB BeSEE;v5 &r3mԳlHC'|$CTb endstream endobj 4766 0 obj << /Length 2088 /Filter /FlateDecode >> stream xڕXY6~P9\" :Uc;IE/IDAK%9ק ^5j>xwȟ%, e8Yrxrv}u,A7r]0\EI, #$z+3׋bC/N]K5YYв8Vϝf. vZ >W TIV|\Y8g4?򹛋f_RUЛ++]^[eV. 6(JUgtGS]UeUqV^]wY<+c胥ˣev*{]eRoPdT?tqO$|M۠P9m!f|_ !bo<'1?jAJ0|t!^Qͽiv~'=&# /sK(@l)!_ĝ$oqO<.eiהw'w#V&!y.pW@pzOEqWH~L#qlJWN+UilbO-oRz5:媂d}?A~  uɩ>< k6 >!X:brsnZv=ktuh2AA֝J423qpԕyfs7HٓC9 VnyFLj6Img)]#afep}+b"w%]tj5Vr2SyQ u!q++,s6m ?g%M?FEYF} K5tG5о:O$ۛ<9UW[=a/(cnT'J0]ZSbiJP@r &$e=|X4Jʱn,qdSZ X. Iuuе%3]uڌ]HVǩFE]xE#tkGpJsHh-qUyjh0]ᵏ`9p쳨ӎcBJm+Gs LJ6F3 >8mK,NY)0?OۄqP/j$h\gj{ލ+.D\%9Ij/\$kr'8ua+ڎ6nlIw]yڂ5rF1G6\vUS/~χI ?ƶ__+ToL.,[/5Oe endstream endobj 4782 0 obj << /Length 1339 /Filter /FlateDecode >> stream xڵW[sF~ׯ`f/,6iwS[V )ʴzsηm|ry͹W}DwBgt\̢!"}q1v^'R*o]^3D Ι(%Z#iy3wW,<7 fŶH9d%IUf/fJQTȊ_~Vg']ޤ)^Low )l /QJWuVٶPQL-'G-Mn~Q4? p "'L>^#>q(dֹs? s"0X%fѰ;8MBABdiRAxH&7DZA08fE5XݗfN:NxrD&߃|>  Nw^"wTD1„S p jx羆ٺPݣ;Z)Ua\g> stream xڭXs6~_/x&$!t4tzsm^bH@p7~ЏoWνCg?-fnC$\:(%N() |,Vgl=灻<ŇwR6$av 1.QsznCԛ{Uo5/ЋJOIWZ7kqb֮s"v uV0`9K`1ȝ':xFI=9NOPvsGþM}aEBk 2'@35`3?tJ4g*aOc`B#XaADgZNlde1 #91sTv*$Eԭfƍs3M.IIUV빼=>`8zҍ&YmOˢFX ϳB%ĵ$LXRMxxQ`1ٱo pTt=NKc3 nz0nhC[ E74IL 3t ` lT><=tJuC +-2Sn$' *IopԺB)%Qy:&,ԴRIӱ[5 >~BkBtB0oR!n@r de y,$\W*4-SU$7']_Ě0=总l^΍'2=t+`Uu3q7 X\:.ۥ2EY)=A s^?j1Ro 'J`>p$ I%/3ׯFF@{dDB}Lb~D~B~:miS0gϋWYl$sDP00rL(c{J7HfcT- )BDQ\ͦ4`D",9'A6 ll> stream xڥYK6ϯQJY^$![]ʤj!.O7>ɣḾ _`?EABG.`!@EYqB,"!SYT7n1mQwǻ1ҀpFD$'dYz $cDI"paH!T FI3 "A'Iz~Kˬ:7<ŚUøW(a)MBMP*b{tSWLQ]`A)TRi bR8ʲ㚭U<\A)luz`(*NƝRue3|N&OKkYQ%7("]%adEZ>"gk{_~q£ỽSOc'.pJVn(oPz IE3Dh,/ۼ_v5l- $}{Zs%Q =H1?'ޤ{usw_wG_lACZ&tUn 3]6yP~{0ev;8o7f])Jޡy95evܷ&w]ň4iveɺ𫓃OƄw6pzѠѾ;B4W qΒNpk"@ѻgesR!@<85ط;Swagf^Qica[]IH/F`ȍ,oP0ШW+2؝ rq<c+ <?xD!'BͶ@0W _uTWn,gۗXadmJ Ѝ-z2WIosLH&ZCyG3MOˮ=لxP"ιakݘ0ኯC7:Ծ\ܶH&M`/WV38i2)}Zt`ɔ 6mwAM8bBehx ƈJlD\n FzK71B2Jb.dw:3hƅк$ںEZv-lâ,OnhF-ǍT\ bB(͚J>yUczX~hgFUsF˫ Jߣ'$M=19,!]S,$F8(V—?טF.BS.H"UrS,X=cix*>c&ȅeŎ+EXZys ° Pؕr>\~Xޘ Ԝ ˳f>U rkq;#z_y{8W$4:b~\hL`(=U a|'bhX2o;N‘:]0l7w' "j4b?s)P3TP`LJ6пѢ6{AمTNy@[{+^ S*RS`<奪PDR㌨%,a` ڶ01RE@ BM]{=H(n)y-3ڗ/n|SYg^QR8$7&P/h=LJW |;7J=H. `pmWP~BVCV#SnG;fKvJ-3O$DeNh)Ibk !hQMr|>Ҳf=YXax_HDTy5-gpb*;'<&]Ea,gN:}GS/ۋG2rxeϳ`;nxA('_\ºՃTyv]W ))ܶ=J~Hz ]d\0"tR_?lNq;X.kز&9mzUJz{pm}>r endstream endobj 4845 0 obj << /Length 1967 /Filter /FlateDecode >> stream xXIs6WpCL AistS[=9Pl1I">,dȲgzEǷ~oppٛYpSۀ`$ #`>X(YGmѶ?yOcs`l>"hv<>]n+ɗ7q "9bS+jX&o."q.]f_˭buD0[F-#/4}Av.1VvkZ}(*䃣5}!IzLhܽEFr_( E}$c"Jo# d4ݿjJWn"q2n{3}Jk(nң3 XFx[g˝DKo- J#6gM+0y3_O(L^Ўbv5#@ҷ%F(< Vg%B1σ!hXoo'}QR8I 9#OQ xN: ]2p mn_4v_gCusVMPX) Yv^S1'Mv,3}Q+sM Sspb#Sl> 3dby_VyfBk)վڇ\5jf_;FDFTOX ܄" CTI8o!Wžʭ] c{,rUŃ,ו Xmu _\bLi:%Q`roKch2 5hOO6(9l}{<юʡ2^8^\p48OH KÝ>'ඬצ"*l44|)JhޑBN:2 ̓؊ PN-1 ؖ.mlʱ%2]L Xmn,wI6WQ&:iD5̸0fi < PџHqN3^֋z!e!MlIʺT.*AA{=ZLK]kqAZ68A);J+'5R<1#a`|q$.*z8 FRu։~'d_-3݈1ytǕ+f >"(魩4'P ȴ^+Ql<=?MK\kOA8i.%da pF 6pӂ&vrv= ry'MQM ,"ǠߊGqʩÃkƴǻ5 lNRBu@)>/)4ԘY%0>iG( '&aqA{ROֺ47ޝ1!ΝzW͘){@ fCY|( rPM0evƼY7tpʃaHUpΞ?Ra Ԣo ј+d8Zi>q(uG%SŗvWh~ϠKGa^0\c>Hȡ~?ke#l_;X1>/PUBu,~];^H&NJt@a=g(pivyg ȴΞ/BJ$L) 6/E&^d mĽ>Dˇ1 BO+Mgyh@)uj? *~U3%|9H&@?ظl֫_&] endstream endobj 4758 0 obj << /Type /ObjStm /N 100 /First 971 /Length 2162 /Filter /FlateDecode >> stream xZ]o[}cBqCr &H@X$YV6:+)mg(QĒ}\9@_$-E'E\e%GQ`G*FDX8.7ȍ9sqBrq9'KOi,3 SPospFEL[l\%j| *5(|,M(iRq`T1e[ >dg59NՖpdTq9b""ai =DvlMFP(X5ş(TTi# 6)I+(SE*ۀJ.)]4` %m6W*,Z0-.o0US.A %(r ƪKs dj(.%!$@ѥ}SPƏK VŠ5h9F^BhFPP.SjsѴhr2*9Ӷ8WX%($fCh|]1v7Q9>ήHPARl0`̏ 0A +*2gQLUDnbnɌRac ,XI+l~L] ȶaYO<9O՞8d)o&٫ڝϞ٧-W3|:;<gxv2y9[->.fMho~_LX|r/(`Bj =dղΖNp'6ar2y=v2a<-fɏ MT<>1M6@3M}6ez`zn?!c"Wo.MZ%2qoA%z$e`v(=!%܅bl=T)g˅!\Aglő#0# :יw#N)Lu z }>nHu(=8)ߌE:yJ<%vB::;Q:c)8WJRVLjHj6_#z'-Pv I2}#y>]gjD_͌ XT2P^g_fVoQ0goE(MCzxVcX'uwjV$ht`60C-coBEd n~jH~_,7MÃu]AkHCe(P޺$("Kh:IC#'w$ b:t7ҍ,og_{Q{r=מkO'-AGhOJ@P# 4\:ƬBgٸTgA`ލX j;PP,/GlXO ("®D=b5b}k,0d칝?8؁h>, 1P'>ǷV!xD˄h$80r~v59F}*2ЅoZ 56/a3t~cHApXyւ /z>c6@\DC S<wGþc܈gaŎFP(Hr34U2d[I&paơ5O 7k֯yZfSPv3NQ;!Hȝ(cVAb jvxFć|u5]f?Mˋ#TvKxcwnHV r4x+ђ]Y˷@a8;Q2"~w ?ˋcN<.>_4_Yl?"&ڞtB'Ly){6JViK>\>.g6Zf7pq&t"5G֋+F1o&=)r(V)slQKioWιqn0k>ұJv(@Q*r3w\(-ޣμ+-0mo@@ġ]z/w@(JcGu?tcMXN4[%1kFG(8Q7wvK,0ؐ+T)a+[îtfnrQ8O& endstream endobj 4873 0 obj << /Length 2151 /Filter /FlateDecode >> stream xYMo6W{=ݢbw ۊ֖8C%ˊmE)>3CGG?}꽔FZR-"1b\FH0-7ѯ3"O_y0I00i;sg>*""r||A}4=[U I}_q療?d)ƚTIY?'u; Mq [?7-+̑ @O~|#FiCQ띇uz= xYrr(V[)9迁.bx|G,fqBq?L=Dܸv}pF ='8Z<x#'H+Eǜy,fɺ.쯤Ί"e+y]\"3g۴Z٣YBǛ xGp6!n&|<jWqhHRp0D!0 c:2m &H!,dl:]  IbȜ1I±K~>ev6ӲY"0BDLy 2,D6#>, #t̔5\#B<^lb'Y|vC1@uݳ(]-rҩ.X;Dc+bc/FOM/,>C3z7-)={c ,xݢ %[CM1b0P  ?r1]g/.@/|Pj|]c]dTts:u֜C)t_gTmdOA Nlظ.COƮȜUǠTqqTdt˖I$PЌ25F15qb,4Z^a0:xjE޲~\TD SAšy\/$訛o ukkzU}j!rT|ճ#8CfT gֻ7ח6֛wQ%eyNu8A8_5LFT(.+'.K H /jGi^ugQX,HC#& ^ֹ0 6?3:%/tt]3 ;NRŸ +Mբ醞ka)ԗ$n]ڄ iqn:)!\NY-44v°X3A\i;7FYܫ5[A.yoQ)L΍&o \EjmJb@dbx֭$_{ЫsM%wS$e8\bh=[{hRTcz zi+7D`]I<FS<}7>"!pӡJp&g+#Ǻ[h˜w(J팀AZ]T0? V9*7$i+J"%—kc͗NCC6Oc(ž&` t@$]MړYeD8jZS q$:6ݍ_$xVW6U=دHLZ*Z29y1O\Ÿ ^qq09\_M0|ppS*Dz.e2"ᰦC*5 cC<-23 endstream endobj 4890 0 obj << /Length 1794 /Filter /FlateDecode >> stream xڭX[o6~ϯRt&+!k]5=t ˴U\]twxM)HS~Bbg`E; |Nbxԙ/tV7rYO>_.:EYyt5'X)Ģ:x5!ˋ׽+)Q+ L)7Fݧ?lT~nZ.27+Ҽ]fZ}YiE4YY|kukΕ0(!S,zVK$b4lV&ֳ<%ٲl9 δ;5% PgkkgvQ )ZjmJۅP8 cܗH/|#/Be;q"t1SL< Rpz AuT٭:];8lIDUr1SsMh^OHΚF1&~SFG뼟z,B"ĔXt(q|(>i(FE {<z:E3%I|pG c Rͪ-Ry(`~He#r& sA%Œ Ȏ^}V$藂7d=cDD4(z~lw yP $80 }Xo*i"Ȥ1,L \[BD Q~Frpߨ)>TEYmDzBp<3k$Mf"2ɖtSQwIn?YR鏻%KbdՍKci9/ZN̐b((L;*:ݠ/$ =P7-m[kO@/F5\aS%YHY0^-gA6^2G,2]nv\"Bre·e1]ʜJף,Y=8y>?tBd#j@C|8,#GubEywru6G!Ѐǖ*nP(}yO]*:Coȿ(p{<#f_԰W 1 }vWvZQ Qr5bYGI#l&A"jZ4v:#d7ȏ*.+djڬP^QdFM7R&d4P#laHq3&=F3uɘe1 -XW(sB"/VIY}D"w}!I@ 2MM}f+>n.^ /0H XVU2cq(g9/\1HȷjqR L?ic;>!nXyR8ލy(C!2H8Z< M}2K @/" ÈC8d s? aeZOg.3+AG(R!97z- Ն<1n-|DScM>eGm@Z?V7Ĩ`(>)@WC)ؖK#22}er;h >up#`tȉ)"{w_z5t!^,o~y惵l}ݷ >$_Ojw1t:. endstream endobj 4921 0 obj << /Length 1915 /Filter /FlateDecode >> stream xڵX[o6~ϯ0u nM6K;`DZe%q6`}ɒ8NH|B9ę=N` H0/&q8wdL>Z_Ny1 0Aw.ı5V")#ǜv&TNjh{nzu8qh@;|r|gxjc]Ef!ocmd_Q)R#bZkW^]q;ħ ȼ ?N C/Ύ&m;'!yZ3k:*TQU[=Emz1%ȥ-7*O4Z,$tI'O@P`89 Ɵ&!2L(CS#B{wiIZthؚ'V>"ں:$aQ s8Q^Mo5̔kMxR5JJEgTPlbS >17 itQCm H8E]"%l#EMmTFh+pT4*vCÔ+1Lp0<4=׷ =.%K9hy%4V*b+^'ii? 7d'e"Gk0̤Ҽ\kDD(v*&]D[$0ÈO(OFB1.գDbGY~luɐZhbıh>=>7 QnAܒQC$fii޿amSH0' Ox{F*x/|UYyose*4od9z^RE DL%A`Y W2O0V*>IZHY HUUm'YΫ,DXβhşg/3>3yKDӃUsx&R8֙z9J1O":N:eƲ"veep9@_2{^PqY)'Q ߘd։Iob#" ҫt E(RGHIs9턤a?w>\w7G?><`F/LC@}W+,FɎ_FȳdH3+ON-'ф?<ퟨM2ӯq>je/SM;'qb"4|~@+ endstream endobj 4938 0 obj << /Length 1463 /Filter /FlateDecode >> stream xXo6~_!f5ߔ m[24;lHH-ԖSInw$%Ee%ڥ݋Iw`|H B2_cĸ H0|\nV'Dt&-'?=93E(v pғ#N%7SCP0ʨp x T`<|S0O6cی:)t\f7F]-VmVD{RDOUf)(Ó:9K[aV+jS١fqB Sʨ{df?kՇƫU;[> `WEAn=Q8^=^="_fxt8}[ֿ% ,H֣w8Ha( : "8Xg֕o6;A@$|% Jz)BDI=cJgk_MB`0P<~O/̏Rt,N[Qd؈]n 6Ol"f5n?" ۖUϒVS~ˤȮ;s+K$2: "K F*䭠XMWH(KL1W>gsr7J-h>\&m% t!h* Dho=)vV"{D(Z'JwD*ш|M|Ya?{j@dE矏._W?/WTxr $N.) p*,uaçjUwE{NzU5)3ـۏL2+lf ϰ|yﰺ=io@"82!o1yV/1;&ڇk ,`"Nv P,` qZ*r[1KWOї?,xMYz@DL1LDᱭHי톫`>TnW#(1^fuAn YB/cSt5{ŧxma3>>A.JMҵUqFuS(t])uoa endstream endobj 4857 0 obj << /Type /ObjStm /N 100 /First 977 /Length 2151 /Filter /FlateDecode >> stream xZ]o[7}c˙(p[(,EVb!E_g(QȺYKC|'>o178CU C٫EUNHTe/Ɠ}C&UeϦgC.J{bhȆbBH*yÎ06梣d*eá`1DŽkw :lB'%UB0c*.eB4BsH(*e̘JRN3&*-2Cy$-RTV˱~Ucsq*!)"SVkNE*UE&8 '@$]UMīːb}uf9H:XqwXb@hD-M(&ZCUDL\lbs@*& 1șC t~hDנj/ڦ`RR5Wѕ,`v&S<8 T%i ֩ Eɫ1mWHaSnŢR1.{GHd0SS3B U CTE0#2Ӗ ԧzqIUGYQ9Gy˯7gE&rz=>?v$Oi8o?mb#+9Mt'IZ4apՃ׈[w~6kSy|6<-͹~tFf3߯F0x7:^h\h.cuz>-V9it1}0/B VSR5щf>*+We-]rlQz?rEuԝ]Yh^'^w?t?v/ϩ>-"` < Q-TEʂg~jfߜ`4X`qibLi/ѐOV];=$,.l>,9ۂXREڊjd0\?lz qA4_4(B'@ #yK(\L'<ƆwqJVy [Tv sΆ󯰌/|Re]CZe)  0 J}܈SFSOϨy#ye8{[`m ];hV " ʭF ZCm]{\$FG;PPia(&txﶯb6h;;T4w :Vnd0yo=ׁ3ӎHQ&)XjOmH#~~Bd[?m۾]Sɨyrw' t (O>yP/Sjܾ4JύFs9C?0&X@x:Ԅ=?>#tχZl?o.˫ߺn:ZNol d!-k7T"&" 烒qҾԋ-l:8d"ˑ^&(D=tXz9(z DxGtQ 4C/_{1+ŧ!XvX=nY7F59{jErOmF' rxyI 'AH(X cD#X @M&HԆ6mAȲ![j|D[OaQVsA VoY *H6@fPn[78t+'>Azѐ2R +e뼼MF"H)$%r ɋ뷿 khV0LYfmiHn )_ޔQ޹)v, j;)*=K8bOma= =ܩBfC,Ht i4^F3VlgˌDA A{L>༬[r5j2" ;u 1'd]Pz\Qdf IV$x>6CXbK endstream endobj 5040 0 obj << /Length 3850 /Filter /FlateDecode >> stream xڭZ6b/+1#^f7th]ٖBmɕS1h1GwMx'/<{E7 K"ܭox28 nuCu47j0TjbÁT_g\|5rU'OB7Ss)%21$RѧKhgMgs%x@3/0x꾇?fn*$CG P! caVu=:8گ"Ҧ2辿b ZXt||kɜ]*6y~ȋ{x{%2n~ݿ u|6: ?ߢ*?aWj,ќFe0+&9,њal2QTobEupƚm^di?McQIsN=3v φ&Ni,m͞HXF$uDYqlzϧ3c|0wjjؙa3i,5ķNy(u rxJOZ>u t)uXitD|wv?%p( Ԣ,Epq?؎UW naȪJ$${>bgq3$NpyɪSrw=LDEqi] XR )I00VU/۴:u~_[GJEJE*[\[(l^Վze=u:.kYv= DA;୐ ŒPW32lya&\ hm4n> V72i3S!gN^#Ph+`qئ(fA'Cɖ۴Lxo? L;T}Ԫ1jqaU_ C DQd1./PWvo݃UaPCNR'$Lgn!Om"FϾ.IAXϛWYEQ)o60OCζE°W),7Y&;TyK@h; t2[tQ6>vjPc;ѿϊHԳ_Ԍ9/YB:띑S 7Z~yF:]a|Ț?A:0/Nr=Dx"<]W^ ..qn·JJQ@8(@&`O}n&xi~Cöv)}pk`x>vU H,cGON"T `5/xx$r0m1^N %#K\Xh2."=P8p`2cpv.LfffmiRk 0&EƉ8n0Xao[Fu OrG%v^*B\37c Z@Ƭ!J;n'zAQOLD hOo^~n*f<2g7u$\ȦKG A=XS&O IBPWүMHm5M3L iGB}!'!oC'q9꫷R-k)NɿN1Q{5ir^;Pb_*xAn{@E[m>]1'a2'!=\"d'imDEn`e@QA rVtQ?`aV6|k0f@:Y|S俧k4o?>bqQ'O M]ZPڔJ'v v+' &0{ჲǿ:yVWG[VH'*K kEj0 m{uB5H@}CtS ̭ꈿYdyf`jMt[͂_9=Cc%ąXJ'hUyc ~Ȗ׉BqI8}݂.'.x5PyXZ 0/18Aۜ-:ۄ4H3 ;4-kn3UIoiШ [+ c,6Y+Xx_*KWBHGkX71 7m@_, ؤ cL4 I b608Đ5 Ո'*'Dg?2,:"a&9UOX.$;l$~\p;Rzc.ԇdэo*vFv\7!u09Ч"]w E / tmUݗ Kgmi @s^>WK|CA pęa=OF'93(Z?B8Po# lJb4["fb5:Az tSv|D_?gU/^}KE (YwKZ1vc9At-dq1>Ts/?'l\I YIÒpajvϞh m&=J"dǕu'{T}TcwE5xNfbضZ_- ,@6=N [~-Qj\sk$*{w]-*λy,L$qNLȄphdbHy`bՇ6̄g 7redWؑGYCF u~bB@ޟ'}=a ѓWn߾{=*9@t?=DrөDX RИc'wpq|j%8j;;Ƈ.K;B8fk)K$Xh5'd3IfKvUb G'-T;޷po6FR QTUrݶ\dʽzyjwxAmLOn0*pPiOdd&c`'@B'wÞUI r`$`V"`[Y8b^j'l)Qkq7+K";Uh7Q'a8]hMud ;R h3Wr583YXKcFvQ#0[~N/"GКNp5=@϶rהNJZ G{Wy[M@ƶ,.A$XB +&!ps.X.\8e 0Vڝ砡DU/AWh$0 Cuj,i7`.%fR˶.!ma|w,H8-fW]Va\! TxP}aY#B}vbG'JwvޛI_xކ%>k5u̕K,=kyD.ƷE"vpFțBgi 2:j#c/F8%zHhth4+`9;e|#c#u8-|HP ?ga>IXrjk!?"X̾HagZO3/!c endstream endobj 5026 0 obj << /Type /ObjStm /N 100 /First 974 /Length 1189 /Filter /FlateDecode >> stream xY]OcG }ϯc2wlϧVѭت-! %${nV}/'=ܹ'HDw.]Q[2C;I5lb̤#N3 wΉrtp\(wW*&sܩAP(4pIԋ3qdG#9sŜaucH,a5cTԍQqg@#Ug@#3iThv4J6phШnM-@n5g@3aNaU( %Vg @҄1:H4'M= DH wh$/1"kܡ1@ :RhAEg@eg@ug@z 4,pX41:NBAX4X͌ VqF&Ь+;h( h@s2@#7c`ZZ4Ddkg@z66_+>X3%J%Ⱥ`jj5/ʝ%PVjX3-=MM܂ GJU8l8sWtBO??*˻ٛ7zBO ='zBO ='Bv \B \Zh8xƃ~@a`x\mO{9Aq:uz8o霆4_Fa8ݸy4l87bߴm;/Vtns8~N(5Looo ,,03qgΐ;#팝C-;cz0[]/ Vqa}`)X y)JjJ5žlEhoNaiތ?jN.f|kylGyLk =v}}J1aaYJ0SR ;BdLr3j`+_z -!'Z/Vi(XN%+-=1$,RR(1=LG_)7 vx!G[j gz͢ 6^nDlu.Vtd毷5Hm5?WN^k)J.?a^0=XjSK!hɍJng!K9!%Nvj@TN"eOu9:8zF6 5T{_<<zSQEwVu'xwJ[vGBpb) endstream endobj 5056 0 obj << /Length 1820 /Filter /FlateDecode >> stream xYmo6_`g6CJ^eEEl#щYr(ia}G%v݆ %{+ [v^} Qٞu:q=0my1Qp4c)+EqpqZSC~j%-(p9դqSm%M rF`dc-Z }'S`j9#Tb-崤5 `Eo(3-ӡ;5}x1p/F-/Fx١B;vl ! d&c2 ˓ xjIL&2Q2Q2I^_O^o=0`QXLlhv(I%Ƿk ԅoE rw*wyE'XE|eTt`=X j] +ϯņ|w+ ĀV۔Tb@/ KDiU2W~:e+.)ըw;OJT{&>p{Z XcC*Q2?A]3LkjwbV24l3p_]R,#̆&{RdW M%KYqmݱ{Kg]P ^ 4Z}wq~|BzE|Vjt\>mSѝ]|e$򢘉\gҞi^JବD::wC )ϮkۙZۆek}3pUj;X؏@wHj{v'SvΣڐ֙-С}Z;Le'uEVtnt*L7lmIR1{Gډ6nFUtLuBu~)S&0/}2JU(~;lISOBڹ9xT("0O-k#un1B5V!zaH}1^lD]-0fIuA:2с98:"$ԎӂNj\-H DF||tP=_Ǝ[,dJ4Ev huWx%G>zAiS\X.#O)KiD S鵸B2-Mh)ϛΨ}7չv6͊)x.WźPё1 T ހmmm}5> stream xZYo~_!%0!`Lu$<}ɖĄ"&e}aJ~P]w}Ut->eC-RF4Zl0""]lP$_7$1_jj%94!Tnػ"1ؽv4Is_eؕM=<8dDmX Nn`Ck̰QJY!rWÈ4WkV5сFN} s*;~ D`DáJwD7a6$큓C| F$RDHR!2rG&ڲUҌνrƘEmS+ȷ$!RF i!$Hkf/g ci:F$б;9H$z"OuӢ2SZ byʪJjeV]iea^.N:WlLUY1Ne@T,WX➐>נ cm,!Hľ2.< w}k~6V8Hoow d8Gϥjꃬed6ی\MݩZ~^[%ϭ=6>5+P͑j4 ʪۨǪy!58[yxwgy zL} 2SDbr73s\+ܵww-p|wbX62G5s齿я6R+g:$E~0+ZVe]R 8RÞZ>+za{1 6&IhNTᔅhl͜YWeIWY`H~) tP-4Tuf }ScIOݚ5'~HdFC,p9MpK:]/s/)g?d$H0/eI O7Ƿ D>KXm@$NyZ,H?m Y݀䕡mTgLr~ `(:!EkhPޢp.ƶL nKjJM=X ZtY-^'˗(8 ~JLRoOe=Uv:: RB'񱬏';oĘz`g<ar\~x[MzYdHdbmv[kxMu:['ı\0 5%9 rguN|yגUiuΈ6{g3f.RRtLҖmP\)7S0ƾ\<9ѫ̗@}H]EW-x:.Q1/4${QUKS'Hc|c~2ܪt-JqT鴗.RNFW)VT[n233C6Arƒx*gqrS;f< w̙ I_|Tӊ:yYU B$E ]c}LSyX$>cMQo#"Ie֩iB9UE *ٝT-?!rf-p}]1X{UE*ˏ"ix$r`~mЬe7K%eS";~~y_xB*XEk&ZfeXb[h@QF]Od 6܄!oⶦ)ZcIfHLU~!cQyuu;\ Wfpj:e, ,v8gNbiyl;La+dS, Kl+4 ϵtwu#8r\Xȅ- 3U%##@bQ>C`Ф ŵ06}#F>m)A )]g7=iӎD{c~Fme4th3:Ż" $줟mQ?o{gw(Mv5ݺ8_ S7TAFc 6"A~o!`t ZpTm {hϸy?jA?%fkc֟욃|/ b&-¹ԤwW!kT0S,BY#qhN~'ea)uAR?Z=mpH ׻ mhCq,G.4~;ՍB幈9é!& ߟާXiCm9ټD| `%\6J~=wabڳ#ns!p+Hէ钄q]7wb$yB:`&i၉Q[w+$vugӞF)_ D#~ID 77]LdL$Ck_ endstream endobj 5102 0 obj << /Length 2042 /Filter /FlateDecode >> stream xڽX[6~ϯ0܇ʨ"R@M(b]M ,Ǣ<ʢWg==XQ4sw^7/^"EiLM # c1 FdOn~|6G[Y#pDT/zmHF6'fۆr=i7b۪m r"(Mh'Tb+Ն$_(U5L$hgDQIwJ~gF wʭRVΎۇ<#/( ##&[U4N@}N~-c]_)e[UhZ[葻$|!QdOn4Hϙ ̢^b41J茢흴s.vEߴ Nt !6=ҤͱlV#;jJ;|1X6&_m~q[܊hӐM$+Ji ʣ)JP̒)f %:܊ڡu~2$N2(D[+Sf6@܃u cj"#!w'Hy'-eOszȾ4OWF}oEQnj)h9b4BxU; s'E `Ӻ5)]{X[8 *fֱmVʛ_2#.Fs &ʹ.qC燡* ^?inͼ3W2wl"舣0e[5h ;PkPќ)UӀ(hY*ߕHUwc2pW)EkʃZu׀uQEp+&l=&źdl\::tA{ މlr{W:g  %Aq;½d} G$͢klyI}tgaZGgFtq{5:g6ikrH {\bDJp-|.g\Z?fC/Uޚjȉ.c{si &6q|tMVX 3Њ,>Eg>#¦6)C>N8;n;TpKNBm2ƈh="Nb m=)Hνr:t_)&&B!CX)oPGŤET?O'>r<0L ;yeRϱsᚬ ՋWn(EN,˟njL? 1>`Ǯ`[H:5]7Zd׮i៵?@\{^: Թ$"@1)mcp/v{xy'gYE͋ endstream endobj 5125 0 obj << /Length 2178 /Filter /FlateDecode >> stream xYIs8W|*&I]ݕ$)-Q2)R!ĞyXH2$KN]>0~>k)f2R#ht3>M7V|DFIB!jYnY?NkN6J7ƌQ3JsNc]a;ьiL0JEDwXTu7-LDYY&3\-af #|O;#lAzhuMnů,]]MVrK{83gwunջo2Ee1Mv2o>Zo,{cȹfὅm)km ~Z쇨EAk[1G)B +yIii벰jIWл&9H~7=:{V$ּ~\ >w; v8R4r}`d;>i^`4oEc#xu!fi.9@;_BeI(|]t|XBk?=A59J"NՑ͓8bfG P#&̜Ʈ?o1B@t(W֯__^# k(p;̜64"9Á@\8R}SxoLZWޜgsqn]ME,]^=O֛*-ǹC9u 8gߦRWA&9Q ꨜNw/ HP'Po4xT*׿Tz[Wd?Ma>qMr`$l q(XeeE0w1 o:;s Bh;~7TdTfdUALI{\ڜǾ%벢g>.M>4mO#Jʍwt.;=1n}RusIǍ;åwBp[OIjEW'$]M,39os*6&K$:z=09!7ؔe\Ƥo7CTshlf!#a h_];1h4(WHa]<=Gl"ty"#wC~sU3^\q7``ɑ\xD/F AD"Mۺ?Gv8y|K$Q F}{s] endstream endobj 5144 0 obj << /Length 1461 /Filter /FlateDecode >> stream xڵW[o6~ϯ\t7!uW&] Ao^P0 խ&>T$dDynwΑqk`臫31Bzg\ 1=\2bca%jͧ˔uC~rRxDaKZlŪ1 L/Yz%QQqL q"b܈ |A?ߔynn6nhEj+? !~ UB!uA8X,]bpQ<Л+as% .J~T"@#qW1ߞ(qdi+ P;E XΪdɗ- o#7tts((ҢpPz佄<9e<P{}WAW[]9voiV{v y<@B_z]|a'Hw0PՌŲ_u,Bn O*mWb3IaUNGeG^t2x^eO°]׏zt(w fOlA*Vq4c)Y3ufMb JUQ[I'_J z1ǃ;Iђrǔ}4 '}C&qntA ؒn %aS Uipy{;8dEHLP߄mި'B14M쑁nuжwAOcd]t8v_%Ox\!v#۞5H:\iL͕EkECOX"`*\"(U^ ~JP>(0-Vm٥,KyPUBZbVs/{z]2\OUږs1'<fnnuII~hI~Ǫo]*YHݓ<>Q}  !l gah=-DPuxn>z(L D7&߼E4x9: ήŹ`עϺ?2`k'f?5bJ0MUy,ʷ v^cִ_St|f3Vr;7C~o}K: V2 endstream endobj 5163 0 obj << /Length 2835 /Filter /FlateDecode >> stream xZKs6Wh}j-/drz=SIͦj=d4t$R!)? $Z={LM/5 O>kqc&14j"8gJIh8 ,Sa>T1 e ܢjOR>~ٟg|":RHI9O0hn&Zj[z_w- a(5!YXmn˙z6~:3ڗE^."U9P" \c[9~FĚ8~=P^UZf[j:k*F4@ϿTpɧ _g0ͧpXїzg-:oilUa!+\>X4)o'Me( L#tT ǨL.Bb lv8?],n2J1*`1鼀/ O4(z}c[TBE$_Ra&ѤvOf%5sg,P, s t6L) iz-WhIj*mZl6vIgq8.3XTPq!KT^{.VRAMho1+}^|#{7%D1Dܰ! :n[sf{QMa5wej'P#I.xp_jvqGltMLEƛ\Zes8aDgkwԮ6V.>r`p`_zi0 YbL"wA,GQܩ(ۉ9 `xerBuCoDˣ݈")> LLFc|zF+D{^T)盬@ {D"arok3 Ѵf Q(-V"_BOu!@ S+g*ڭMjq kde9^)>>rp970= Y ##bޣ(_!(IiGVL!rRwiˊ Ʊ6 sV6OG 9CO-K;2||VFG}0!]tmULTh(36;\|x94i"GL/=lX`ڳIƶ 7:t@hp!E<^=9RjSzrf^|"Q?sKfMPr =no#H.h42 Io1rp |ÎB柰0lז EQ -qӫ$QpOjсt_#$ u?/P}*FѠ]|x5hzPU5፷,:kׯB>K5Hlxfൃl; 㲟.>ht _P5D g0eE+L֕/N&E>1F2)zUc)޶a L"i޽c=cuol+*.cن0g(.9[RMO[FnLȾuR,. ޓ  wV_A^O(b3%,n{6p⾅hz]' 6!#Ect]7Cdo 5!u]\.T-aj'oyp z3)n/*({<|ڣlUG%! xNb-4_F_g飌 endstream endobj 5045 0 obj << /Type /ObjStm /N 100 /First 1000 /Length 2710 /Filter /FlateDecode >> stream xZ]s[}ׯcP\,vQ3c+6Ӹ?0mI:N}T"e^yǹ 6HgƻO\SdPL栍)@\7AbCIcp^Lt<2*CƏ1JL*kJ^;dZ`{VQ@h| :mLgWƗ e.9뼉 sTm$oXJ NJ%PM#Q@_=ޥwH@: ^PW rݗ:V! >+xNŢ+ UGVbXE" h=tD!VI a% *EHXWH JDGjbALDd<6@S 1K%dUdI}Vg#sxgrL΂):+طXuMt]GS)\>⩾:x12-a ڃM,N I ޔ{R*a;DlSko,<4!-v96dD r] .hR5eAa)B$C ^VF ԩ&KH޼*03bDgYdu&o>Nt0w;cC_"V0y``i+؞(fWyc?5Y|?ޏOsuulx5pԽ.Ƴ ѽНou}P,ǎ[x0{^2}=5XoMbvttή;Z\M'b4ףj}ij;i-x%R>e˿n}Mð7} `^_D=6.^}GR*rBÒ:^a>x@ enq6f+Q=R;|ʻR{J9wP%YBݮulMӚ@Ÿ{^ĮqnȻ/x}/^e҄Є cbaj0XZ,LmFNmFNix^"*q5msfqz1fڼar$g2bd^ K>!1`g26Ff~qzY]e@`8#+XM8nq7Egf8j_πtcDˇ9T[|'D\,Қ H>Vd`p)"QY/G3l|ES5MPn`KC5EDNJêt;ZfJJxӚ L`~lԌBXWw1z@uHJZ-|"ժa=:ٿMKW{D%]{ػBȓ*:$;33nNY-^M O1 wnm6n 3a/0Z]s޲uPb=Hq'JJ?Z:ܕ2K㔥q8ei4NY,8eH)X=&BNUL=|1piZoex;%Abw ֙{CDV|8mvvWˡ%do&~=/ ))T~%mEl^w=ߛ;k}$b.n,FqR5[tϏ smv~пo.]wrO70w7p`Ww\7<$w%ʥ@MM&HBbRrȾi*Kd=qFpXDA#}/va d} U=&^R_ 6(5%,ֻ|G@XǦjp*4o#. F XWӗR#[ɞ% LdA7;6a8@ xCȻSKk8߶umq Qm[3)/[lۚ|H6l>;yHnLn}cFeQYnT;lݜfk!D+%8 yzy1%,T> stream xڭZK۸W({$#jM%9ؓTT1=%)ۓ_n4@iAl`]?\(b/<X(E, ._kͺ~?ǣoBD)hf8I{ U法H>al$f*nYa,^{N74x:;ht{,;.Z껯}VFDˬ,r0V3ET'x|Q ءKiٳÛ|zp0TuJݶD>R㡪q9dBF^n7Tt\ &E Ł˶Y۱ (p"@eq EEZMs{iAgΩsP"9YhZbIgJƊ$rs ;!^0 lfřTV2@,F~F&/)Xq g0Y2僶=1C!a2!r>b鞃쏭{k{}Ѷ;.@KA&PP@x<`/6jߩL1Q}xg|'Xsܞ1AM`RoEUnBS:[؎Xr~)2zTMo&V!ahvčX76GGD#r(6;]v#D4emWm3d9fG8R, bJg,qBZ{_X?4V{;Dd>g"[iq) _.]y!U|ޔGԭ`TjC |jM3D-iHḡoh ahvԥۨ%8'pKgGX@e6XR:Aڣ!XuC3> joMI犂I6QKnSǽ+ݚcq=دhJ^cUZO1*~NF Fhʺ؇]x_rF{V‡YW"֩5"Œ)7Hi02==(MDžj YA3FF鄍m+lw $e?8MVQ2ƹu ʓDo2k|baɐ^˲" 7D/匏lG|dae- `G]m bYYdk8(Y \eh޺0 gSZpѸW C!\Nz4^FE)/34IϹ(L*Lh1q0[|ߎ !\?U9(EB,Vw֣258ʋ!9eG/ %eI-F؟mq8UW,b>nyL %Ӛs<J=5tNcxNwGaX^9._*+H,1'rN{BW"B6`R (vBNGKuT2YqH5TN0.AB O,i,FKX0kŇ$vhARZ%u#Uà)*;GY@Q2D_RI2R_MC܋!ICJW/R!VzG}RmJCn^_s\Ǎ&֔rX_:ҋd0d0Wʩ( y@ݟ G;}uܱ}҆8@4ƱjL3\?:X41M?.» A_PBC ecDžor˱m\/ɀVS3 t+y0rʆ䵯.b*mMIsF ؆Z8ڞgaij~+@ĽňR sl 鳵wc*iÓaGF%n2Me`K"bnU^|yO04UeݵsJS?qɮ\ vj\yM^;̨gg˴ߎwǿ?YV`νrꊹ˝Pq#-G=/rZϬDA:$iA+P]тoB=չZ*R1g 쏮,FkMavӹS-֥&{7Xګq[1tܲSD!H]sb7(g =Pqt saؘ5p%z8΋l{.@!-l}EL9AuYoVȧ1yݎT awkSzjOMd9`gɼp鿺DK90zZ\Wqɢ?f ݟF> stream xڭXnF}WCID*r"}I'(^K%{6\Jpo3gf=ѯWnpQ腣f:=,t` nf~KtD̋"!DwwTW !h-7/ SmwGs8skn;ӹI8הpK\=S1q; ")NOyMtǵݸ?ʗ[gEVNK젋F^xMfK}}RXKnfe~w=]G^;{lUGa֐ʹN߅R}Q  RԸ*P"Qʇ,oHex@ҳϵ#w~?[zs̖$?V'`kܞˤQPg3.wdBmRȲ6 38F=J'u[,S7`$HV!چY)O`&g'H)U%7*Oj;9GNjARfz/dNHSe69`v&,M8h٤t2U_,BS_X vXr#+NH--\bSϳ}7;g5܁b6d%j*èn $ϰ5!FC;0! Eͷ!;99FuciWjdo*$}X-}1h C["@Sme F3>2:£܇~3դT,715s%,\Q7`kr CT* W AP엀@sb[l'8#sm.ѽkyYڐ뽙uǷy Jv6ldf.TMTyGnXZ Br_jꄭ(abhp<bľ5ފ\SJ ]?Dj^}xSh^S*xT9RJ' -O=#="jꙴj8ѐƈl~al0Sf][i|˷As43Z1-ͥ&΍'ؽYn J.no=ȂtprLf"8?oN ;*3MP(Ԟ}0x4;htSܴ) 0jaqŸ 4XQt>nE|hL/DWcwNkʃv%tsώA{z͟Ł2ηZ_w$X endstream endobj 5214 0 obj << /Length 1800 /Filter /FlateDecode >> stream xڭXo6= ĬHzkѮk ˆ5Ya- Fmuz8(RʲkPww=dY;ُg/ԉP߹^9uG}']<\/OS*MV׎E#hڂ-dC>Eu8{w} mGJz}:Kx 8]5s(O=muwUV!⇧^|KAQ6,Ӥvam-Faz3!]$JW!GϵBƝfnnOwBǼؤ9k92Wˆ?!COQ2W`C zHr}R~Mc:0Bc 4XsJ!JB\;Á툋pD/:fF4ʲ>Cݾ(F1Q!FLbǾ-Yq%Bgp)M<_MpwD٪&s(/{䠄MW3F:jCcAHw'@-}B+"ԤOtQɼ~-!Ec#%KOV.vJoBGg1יcc?30Շr 8tBc^r'Gcܑ6v$ ;iysIbPΨڕ]!YPt ꠾.bΫ5`3 Z$khwe)!xi ?Su(EDƷ(зZh p89](KcI> stream xYY8~ϯh`Idl,v1C "MJtx$9ݽ~X%e(աjw\n_.2"^ `28`W /]J =UuU} ECVg攕HpҞu,KJySxL&^]$Yb1aFw)J=SEidES @hދ0dYp;,'.cNJQn r>.c }`l{ .øҽ;܄!SgAKR[-\@`_nN*"OcɈڝS@! xBYԒ5C(&UWu">yylj~y,A6O* e?{:#9XArYr='NLݫ0@!>Rtfsf攵LLFkJR}Fi11RȎ|8@g:~RËR3gx6"/9 8! oA xJaY!7@> yՇ7<ڨ8"0&~XVmS~o7~>JxPЗ7@4 (j&iۈbR  &y & {Gj/ P֪#p#qqDP8gx`m+'8qbinD0HV@2ɀl{srl ]1(rw m} ,XYuqNtȧ1419 '\D/0ch+XW̰B[d1n%a~(s24McN/?x;U+?d]KƝN5uۢ:VIY)dl1WQHה;Xjjm0{Q̙ RK5Xec`g19H3Զh -UG@Jgھ#,ӕKp0[}NuD:|U؍Sq&JO<m$tkl-[Ԛ6-}L}˿AA䡛 IG!/iIEl#~"¿Tb[>tꮝ+1zM  zĩ5肕OwsI[#+sk@׮9u`?(5?H&0,{Kh$`PA6W^zߥXdAc1}Al7k yKNI2I1$ X%)5Ȇ 6llYc=7E/0qgEio+j<1s>ergq#'sс7# 6G`z+|> stream xZQo7~cB3! +A7Q[ $I} ZJ^~g!7E.Spلȉ x]Zq96ɕ~RCH&eVb:T]\(^@z@j=JPw=FH5C*QH&1ZI:RN c*U p&ǡ_1aı&%)_q]v\T1F.NwIl`jJ4+{%m;Yk)HIDOIW=bTGpf=r!7 Fݴ&cRS *П@"f&H씃 ĩ"jWuN ,mƩNĄk *b"bBBnj M.a%"Hzc#P;2v6FD*HU=> ŋ@ zF$@2DߒW) 0]L/Wb<(";4W,eCۻFoLNHy#xs 漅ƒv=F G.RHps$uAZ-4N[~ =wA歖 )nn 6FZ&A5'P !: Ƨ٪YTשZ7A86`B%n,fS0AW@*HĦh=b~yaS7y}^7r;<nZlce\<욓!FyhJ_*t%7?]b V#nc/P/p/H/^^Ƚkνk.k.k.koƊ*.{Y INEu#8PKut8r>Ϧ7#6plB੖y*P9kV[J#cԁDž2LEı|"=nfޜIQ1z >xLл(ڣ$ @ŵx+- ~Ad$TqYӜavNv|Gs+SWۂ*z-,u# Hx!W"r/4(@<-H}(𥸅Rd/hIvA"ƘLgW͡<0WQP^'%s#M^ BY7Ȯ ׎"nš." ϫQO*c(>kUwG7 XIvʎ_#"mC`+pJ6f85d|n3aTB@aSTi;NuO-SVs#f Yg_VflEZw\puEA(3?cV.F^^HǬ-A4TcAhDړпՁrvz,:a (•h8,??yej Q ?bNiGw2鈩sGVa|,`ӸP?g6{ﭿC>vdT$fH_1Mgrsa_lJOJ'ғRI^J0 S0t7S9{qzV'DF"HAFKj-ݘ3u %̆A=NmrH+q|@>`#K䕓޾ʒ 11=z՝)zBv\ch;$֬0yՈ(@PjA|هb1. NgQe ԄN 6@Wݪ[^Ϧ\}P\GA+i(|a~-c)@8qܲ [>T+ORlrJ>K X=> stream xZ{8q>d!Nm>bsFc뻻+ \$YRDM曫~F fMLD n*Q2! P8bnKj:#Ë4dz_^k9MMY忥M^ q&8yN,%#^מoz^[\$K4 CJ#vZ@/b\Nx5r鯞 >iU^392'1MExl㯟rߜfDu5ۮdz&ӔȤsd8"$,B)"0"WGC&pP)NW:`WRu 9`zTYv*)l5V , C+7nVYU@=,je`5R~ D l\D0F " &}E91ʌ9L60p7gu 3CeOږy)xmD<ФUEAW`Yb΂$.C3Ӧ3UF&PwQf$ı =$֥*,6l̈́^$FaY/6ӺaaEF0㽱Ԏ#e "CSzh8b8SyϜE:&0V;El ^ȳSU=TN3IC'W$ %\b[ݼʕ*F }rRm,V.Mv6!@ &Aȱ:M:~cMevhjXUن(1V)g}TvT6m NЂA4{Z9N8Wí~?ap/;tp<Ձс< x-9vZԕ:bF䰵A,9V΃:~U큽'XÝ|nھfΚ,;7z]p%w?S )MVL+ȕ-\r@Wx{q2+3k`C/2jذ Lդ}w^ְ֙xnI~kMY7~}@P+| *w=S8Ok?1G\+官= @>S0Xs=K JS~Q0t ~mD8PTf'_ct gBm:QSRؙ/д/uRWb8"B"Vœ<^oz>>k?̕*TGJ@0V}bp CP9ˢ}_!>mʾ5rHq,N$؈w|Xyn:FO30fr}*uHc>xd-SD>ELɰw\úߘf q[j^W(5:a+l$oPR,^6!H, 81\DsS[A4<oIxvӲ*=R!3v#|.tZ|C AI OӐ'jORD\MTbqJMg:( gϢ4:[6~( -dCsF~"mÞ6zo'=踍2zԉ# `֋NgYlX9oFO][~ ̸ R92˔2Nc;핢F,fťx *k=댸q4LPP.V1:P'BṣJ(ՀV4;pPvH=:Sa=@1Gr+M.r?2O>hq~,4,)BRc<4ӽf3i*]mO<@& >>2fhh$ %r$sױ8j]v(?S(ObFg_+F[-@u E)0@?}x0> stream x[[۶~ɓ ̸8L&WKG"ew{p!@P͉v|Q1E<( +@] AJ+K`Fӕy[tF{fm¶(kNls%CBd*/#Ɔ^zL5|-V3CK7-[ R`D;KظfwMЉcJ 'CvZoV}-6 C6ۤH45'(|dWzțKgNV7{Z2i۾$z?nWEa.ozIĬl< -hY>Y엺X҆HgzlQ-܏f}4uͦi$DLzi )r`[c@! ¼Ns c02/&okeB WŒ7_|K;u'缫UR P~\5gn(Le"BHSl@Սȇ>hh+E^ȘD.u`zMu V Y6uJ- $8_9MHv,30*4!+})o+/hYb.]Y $PuhM2)9!|,bӚqR(Eo޽_Pmn6 o\xvSLPXydWgA4#gB3nG΃ ဧ{Yg܁ GSfC锘i99فp`.AWI,-6ġuٛ~+2Ga|bI ,P aMFtk ։7%K ༴Ca >6!xN%E8 &c|"p3,Ǿ gcuh|0ظӊ.{3p-@SbYUZfLd.!o9_ LmķGP)4RN$ܫN56+܊\AZe[Y?$xyuH1Y!ƒjUf|S$3]ho֍ ~m ҈zB~\&;6ű8:qNx0˱N 9,7z=GS`e߹lm%b-I͌:=OED( FSZm7k$p%C"o6O&֙{ikOA8b}{ᾬS.RPƾS@8+/^kSjnKxtzqmB=zg Cx2 "4>;H 2CrsחTxDEѽdc_|\ע\T5Ds񬫖uo[}ȄCwc, Pr Y&b+C6}6Grg;N;T@^)[͇dAӏs(ٚb%FXd>qs6IaNH#q0 '90ܭsNXÁ sNEODB?H?}}T3A |,O`8Q%lџVCu,OȑT+s"D$N?2-#8@V DX3@1,MD [3pEGceHeD+V3b8`iJC!Oz _^5[ne*cPQa!`_ɸT}&^>/zg\ogֱJA]t+>O@6\!蔺 v?T l'ÐETʱKpԆm%+on< xn4a>' |x܃x@Yr8\I8'A;9hFh SдB8pC\}DuB0dUʔ/_'844Q2o#>]z~wT@rBFP.I+s\=%q40!|@ßɂͽUp:p%CoTzR]w?K$@1N;PdWIؓ0VS`ؠaNd@X|_|>u;JDIQ&.Fg'䲛fXcd-yn)@^+h?dRF~"'n9Y~R 50q;sQSSjE"' endstream endobj 5346 0 obj << /Length 2000 /Filter /FlateDecode >> stream xX{oF?Bpт*4|p-l(R&)n>H4H58>8;3;f'_EbB0FN.UPyWoBtNH E؋iSN:fL*{lFtJT*Mz&WJo^]9?x}FpN5Mg!AAJ^Mg,AlG^%CjRBT F#w"\!͑t$ vkԷ}m ̨( vFt=~OQE8b ZUL2kԞ~)@dʱī= bOfa#!ozJ q<ÍQYdzpDΈY;ä;ʱ;.6(Bę{c ^#bq ( @P}|0"H)C*Pj=P"2T(ڃ)0ia s S0eӿ>Kȑ$1 BA^v^P A.@ zw4RUi8XgK]I #ʞ"BC!r|g Łl%RܧT$˩Se` L1l^7BI{_rʤ$ǥepޥly{?@4I@'L$J)-l}m.pژ:7o`*x?%nuVĹNWmNܽaϽ|GrE>fwx(l9u'uca[qkc9|xSES[V+&!'B cq>_8WM+c#MzCƂc 8Cn׋utyXs󢻫& 7- -:([r$lQSﴁ:hah gBo =0"vMl2\?Q{Pn)o@)K `  r-"wmt`TW-Y7t5}&|+ 7: $ù)Y%'1*."pd[4Ayh@H惸`c| @*V6K0X&,(U "aK#^hr (dn,Kܘ-+x=v5`,G Žo"_NEB/v$Zuݓf,"B a|H"E:2\_.ȱ$2 ?Pu>mLs ܔ~s/W3=PmⳭLa齚.˦ <4U-WDpZyS6ya|6+q>UT\TdXtr?b'y}gj*`3Ke/uׅM6n㺙G7KqU&6iGc7V} *> G)^6Z;ӹd?L$>ԑa1a7,ZkZ6]Bb4==i+gL޺?݉]/{-TOׂ`//~WV1tl1͌'_8:7EYי/tE mw^{6ZCq@ʊ}S6}U:JNG;|H䊜}|Lp$;g[TmljlnGd˟?y| \PtpүcO?5/Xe+/9v7\Ֆ endstream endobj 5364 0 obj << /Length 1201 /Filter /FlateDecode >> stream xڵX[F~WXDQ=,%Ui{NDBHU%_$޽m >7E׶yֺ{mAMlmѰ#ô# l;xwfA*C⎤RsYBw1J#&LZ: =Xr[}C3p>Wa1ȱ/,4'9x.ݾW}UE៺=%[!`>fRonʼOm "<Kɭ1R,taTj8\xTFzaO/y#7­E^BZ|@IMbKk"M[0V*SŜ\(fhT1jgY:HLSZw^rUjxDX,z4 e>HvoTMگ^PWϠ0(yx5KĽc<;9e˶YK<O;ʡyGG.b?@Wόp׷ V#ɷ0a#WsH0 ZdIB Er9?<5,C9D*BV)j'x2Pr*I>Η4uKLAdǢN1eQ `jtMN.zm\) f72ކ(b:*H 2o_L"]~ytee7GQo4kNK])"v TXP0"R|)p.VBBq,S9~jXJC`7L>uG}Pt}]yP%pbAzc>%kq=/(MwU;Q׹asT|ng9[|kk g=K@31FS}]k_T H<Ka"o7DuC&-J.Vtx$O^ޒ(ɆuMmMD Cj? !GͿܶ endstream endobj 5263 0 obj << /Type /ObjStm /N 100 /First 987 /Length 2250 /Filter /FlateDecode >> stream xZnI}Wqyw14knV0_'; Ӹ 쨌 .r$G"&L&PMPDJ6¦+@p(dMQSWGihCآT GFr6 98*MВBfGZ`$uBkbkKjkˎa$ءڪck+RBFlHjmX16؈`#IZlbmFn㨰Q8*l6 F65; mIj$]N٭RQRC9Lb,0^f"ԩ&E?7ӤxaiMCaMNlSHx6@M?eӆ Kژ!8$qmNR%%LRw`XA Av926FHV\M[ur5!ktP06;^ͮ+R )Dِ7hd,5,f ˦p-˨ U )|UY p.nL{H>> Kv̈:]S 7(dC4t3G# XFt#=#9")7^gjvÚtpi6 5c݀JF$ij90s_Y{ZRWl);4)& -Z@8Bdp?B 6*XCb( d@1Um s / FS;*LFVl2{ Z]X] v.[1|)/jPE x.6"&#'T7%: wG#Bwv1ټ1@]AZw,n5<<#5ƌr>DN (~DQ-S*u"cP6k;D Dd19#6jz=v2X7HMHٔ@%z#$?L{bPPt ~bK3Ƈ)cEj xU JPFjGE!ch`W!:wNɮѵko/s~VT%yk endstream endobj 5375 0 obj << /Length 1204 /Filter /FlateDecode >> stream xڝWMo8W9ɀŒHJEΥ݃*Ӷdr/?eQVN %A2i\B'4`` ~b!B^tM;g/6,ˤY1@{\M#cjVtJ[zm ogN^E\D?bd)vP շrӨaZ,%.1?])vS)mYlMȅ]Rʘw[)9sYU/,mywhk#r#ˎuU}$:ȶ8F,!/ zAȝw $9E~1t:=>e~ȈJGYߩ= 11Molb#l? h© =ۄF8_jz;ރl ĸ "|]^V=y,0P;I%%b a^j6=:?t."dD~42-D3{oVB ~L]pC@z4X/B|m2{/zHy0ʝ [= ɟ?Me8~&8t[C>mWZis^l+^vVJ4k, [ |z}5|( U% D(zepw0(MzZ'SuYuf?CЕkބԆ, OguJJ2Π:p e> stream xڵZn8}W4Hsċ(*Y`o`'ƾ$yմ[;jGoIQ8H(XuT*ZW?,*%dru{QDDF$lu]}Xӄ|ǟ1ʹ"\֔ģ_o*H†o$_xmXY]u(?%+4uNϳ.|>U[lM6x.-$GYŎb 8#B\㸜BSȬqD7wY0iQmr@ƙjE7m D׷Ώ 1TugN/,MߖVD'jlAʼ߶P(Co猢EoHW|-8JMc+")yQ$i`X xh@%(PBPG7'D0| ouY?yVx /F1yy uzJKˏ+f㜧qFu,8-~l %&8#ǚc9s@՞b !WM l)̲ )0 3k4:e' ,+l%JLl[m*˹%@SٝF^[G0#lC]Ĕ1 H}>pBI$f rL> M l1^k4szvE=a`i`7# ߋra1_zS5!~}c{!x"@)9b/dnYp7(sC2fG6HwԤfv1.g > 3ySPP`potE`jL|? A#Ϻz=l  +Ħ9K+mq@aYk>zx2#i˙ZH9S9Pq_ 2^tI,ܟ9N;;):j)g4?3gIzOw^yA4?uIռZr' PX;?iHhC8oP  d69y"9p63ؗ *ޒӲʥj/!PPA?[-Kp|i$2Pn8%ݾ&{$t+") Cֲ^IjkƯz;h}[G>Nw2Z-|o%P!u5Ed֓PݰgN_<E \Q*!<]V 3_FXljtb'ض-R >$9dܕFAv# ؤvعn-q1ހ>)vt<ptwHw_(X):k,߽!ϞclXB*@nϔS(ue[W9wrkP*BLJR1 aҡL6=}:m- jS{Vo CT\+jFjF 3[ [X/]c` endstream endobj 5365 0 obj << /Type /ObjStm /N 100 /First 983 /Length 1334 /Filter /FlateDecode >> stream xWKo#EW.=]]VI( َz*{.8+53uUWn!5IZb9Bv9W!P]9 'GcɎb-*G)RQ&a]!A"Gԛʐ"jtT"*<+ՠ&RqX3*cdۂCKl=l:\䀍UFUHHLQlRU u1X(JkP AbD"U% B !2fhUV  "g"V16(Ĥ8B\d I $P UH45M4B͓^[O\p:8p3q3],֐ƍT}EVnX>v:_?`a/]{%zt 43hAx-f/6zv9nLw@=iWsb<٬ vF.sy"*9j $RMǎnarhr֛dͳgk;K>~J*77'\sOF+m4&% 2'N:7;vO/w Y٣YH_ "͔Jb8/7zۛ埏t1?V~Ҍs6# {^{k{_ endstream endobj 5478 0 obj << /Length 1917 /Filter /FlateDecode >> stream xڽXnF}W PH %[/JZ"^;{!ER+:Ca\s93sf(<엫p8n3##3b0:[!)+גi]K^%U|MD8DL8S^T;1c9ǡ~s!Jy1݌gf(MY'0HtϕRSNة+#3HԨ]KY;LWjKW6R0QvӲ-K-4Q-akSMr+O!o,)SsoMbvLL 2#f@o\+]Ty KyK~! 9A ڔ0uaKhz8k7 4D3WÆYiKt':z7+Pgs86 G 1DpjXS-) Yq9N/1&m/y暪xWlen0DJ+%zA@?'>6 LDz%Kq,ZlfŲh<2H:-XzevҢ}7e@>2`}/Rպ@ڞ!xd5|[VCWƗl-%J9ʑXT45p9L]аO_꺗:&@4C)I8%$D(,i3@z\ >cr%8m̍KSAnfdYb:@ ̡ *=tZ(F¼VL}ݵ"L3k$ psۧfy=8ip/S6=f||^g344jk/sYnG.n3%Ofrf3,UcCk@DCJ婁/dU{ys#WF0yNaxࢅ($"Bg8}U|6|M endstream endobj 5486 0 obj << /Length 1425 /Filter /FlateDecode >> stream xڵn6_`6K`mMKXdʕd'YMe)I; yѹlm,l=;}+Bo"#slkZs/G  zkT-aٹKX|/<+7BanQo;GXys&OrA߭oTĂKVȋ§O+5J#$;-]MIVNv%`;ر8KpIN- Hj]~FxRI\FfsuQUe(7Z2#.^(9ə 'vtD049R^9#ohI%Dc*odIY'1r ϜWyQTUZ!Q;-.B endstream endobj 5499 0 obj << /Length 2050 /Filter /FlateDecode >> stream xڵY[۸~ϯpw IQ4EY/uwQԣTDRR2 G+.!t)-jx}Nlb\xHŶǚQ1jgE.X8?sOYq1.2tjܗ{\uiNEEFJ Y9V,"L82d `n0a4AfS%iqgmRgeQe46+ƈ C+Ci$A C-Aan|9Z}QSu# q_Uye8>:Ditot"F&5=3xL,j0պЬU="-[ӌW\Ŧ[JEmչ@2Ҷ|g Xxή@F?pֆͯv ~sGY}ƅx)@\zȡ)~pݥ{sI֍6Uv7zq?FݸqDgNr_sn m [XOnhFWO$iF"8~,9IE<,)g6OG1Ws"puS k }Q$b)m,_Bj?|6WK Vto(ror%K^"zx ?\ŗj^)8xG+v-ͻ υ`gsEwnJp՜N~22ZcZw"vY; ϟtuT{ui3},[>t|5 z Z0=ё-ٚK 2 q7N~U'5Pǧp/p@"lyuK)EjFa f/w$%A1{$0br=+l[_axn8B8g`غosX2KDС ΀a.bgtteץ'PsTO|sYk't3Ws)~E0rڦY^76ֻ]Tuf62jkX#>[+|y<~ǹoA9N!qv<5v2?Ƹv|:+>T;L3}x'nP=~W A?&pHu/Ѻ\KUy-)e@yAV+OZ5܃.ǧE9ʚ}K>S١c1߆d^QF܁7VZzb| endstream endobj 5517 0 obj << /Length 1920 /Filter /FlateDecode >> stream xڵYYs8~ׯ`y""'%Ugj60-!2gERR~)ҐlaW ht}&я_O}(CYLkD0FQc$rJxvsw~@GTp`dyj^^7z}$Jam9#% s;ݧU/X` ~/Ova9(2W'&ד&hqD:Er>;IJ47eĵ|]M9   T o =ρ lD(RV̩ӯpa6(}lk;֍lXߜIPD{ HDb *nA6+Uڢ0p ]6C(Na,[ )L^Ɗ>U:T*`w/Ռ%:A.%(T!2[ 5#GЮdyYi)i'ݝ♆ &sz"xU & cCb18Pʊjd+]12o^1Jqvrlh}DǤ_$:W'Om:xPM(S$iX=41pM u#6C%Tգ ǀб֓מy yd#c:)tZN]3xݹ% ߕ?t\o&{_|d F OW{m~n+i{ }cQ6(La@պsXݹjJ:?ԡdoĩ%Qʷlt| k|y=nDځ~^)fThbf?cm5A׀ @'IzN,' endstream endobj 5472 0 obj << /Type /ObjStm /N 100 /First 979 /Length 1662 /Filter /FlateDecode >> stream xYMo7W^( uZ)(9(u$C=JDqU):E _#9fHǐq&&$S=-(d㵩sӭF=or6ѧxJ'5E9`VSUFD|ФJo3<f,R$o$F*F)w%*j8 /p-^(d AWwsr\8Mb|m1-uYQM5IFCEMXz͜wtbaFDF&8Q .B5J`~aeH|i[iV)Ƅ^恓ϙ^HRc -C ͢@͢ -T H @)QThpGf1чGr>Rlȁsʕ>VipB"G>jndvS.5brjl $$6dv2 HC~@*"YS|p 6|$nJLZ` sFdoF ܩT+Yɓv"D16MtiIlF.Qx]boW<!zW H2Bx4fšLnɟW|O:.6`x4Y̮bEݫƜ:-)jtAOM~jRZ 6`x|vٞ1>&ý~?aT1i) D-:xϾXMzO`s9}j|v}r2/r%{ X3ҹmT!ނ7>mT- ڢxP͡ns9;.{eiK-Oړ|r0~zA_/BjlG1l1{[@#28FP%&ocIjcBF@F4l1k/L 6+.)'hߌr"W)nϕU-7lxgǗŢY z`ɠeBh}+`w7ͲuYFVl?m j44ql͟Ż__]'H'tq[kWw M;4 9!;jI\-<.v"<|Hh]-`y A* lo&=(Abܗ|;0>>֗k/{'H>G" iBEe(>e Ck0^lg/'1 45c" E+%/c",NH~OA=ѭXuvm{s5%u6x~.JSТ4^qP:a]x|'h'>+Wl/x n˾l}(Qm %Oi۳m]>d^ Q#e.A'=R$D:Fway(8˲ w/;SsOxٻQ*];qhF %ӝYG姵ػ6n(PE_hQf endstream endobj 5592 0 obj << /Length 1150 /Filter /FlateDecode >> stream xWKsFWPރ{@{p*V$%HbW(v}zeﮓ\Di~coaZq/D[n<1b\zJb$u*?.Njk);Y( C[_!J v_ [r3>UFOT^:Ӭy^ '"Z}<8Cƅ[Upgyej-Iҽ&:i ѰMUԊJU$(*3hrUֱqp,duA:ba׬ A3ևg=NH"OGO'0I( HF @D!Vg^=TŌi< $;e`0x)܂x~@P@I1fB2-Nƒ.DP2=1%NҞA\\q$ G! a1Hm /yYy6xy+h)jP+)`lF! Tk3!Q%1}˝.\D UtM{w d4)K@9x4t 9^=P!d-o}]/7&;iO$&b5(xm P']|iB8Q/˱][^_0aC{1\ |]żܗh6}+^CcPWo'FB!FMYzWykdѰzF6TgkHWfIؕGB#dz]M Ơ6S0XLt9(" FOGtે(=u-I3p:sz4SsP,,/RCx=΄|nwn7d=*?$$olNtE#݂tv218.෽ed d[66 wT\@qj5Hkz_Z!_\N]6EY8AVw,n(̓UWOT\T>㖿 '<' :Sw49P/CҤ.wð]X 597tK9LS؝~x endstream endobj 5631 0 obj << /Length 2063 /Filter /FlateDecode >> stream xڵXmB/5CR$EmvsI%iv@i[=[r$>3$jy X`9H33367~$q0JI$T+Jdăusb񻯾`j>d'χi<{Ol5.~W70i8%,VAvwJtdE>xohl D2%&DVwXy՜b% Xn~ڝ2'\hقC`4?3XknJ'DI%vsޖ3V"!B+צΪe1Jo1btD/ܡ: ?v6:̼๵F /XfshR '޺iA;%*n=1>[04O /lqKNʢI"*XF6DDJ78;ôX;a_n,A$\61ڇ)?ݐ-AQа6~`2{ Ax7;T?=Q@~:ĪCA WGBa(j(_v?|O%ZEBTd^2٥fmQ(9PJQT"C=9E)ϑXLꘂ`j"iQ]eSF[upD/gvN@ۄBxґ](*"v+o]ZL5R8}Bͩ[ TN}{I)+ħ} HiV ׾([p8xy :c_`(N5.0D~@^FBlL7{Slݒ(fD9+/w@% L},u^l;kw;]|HBwnXzf`s1x@<ף$ D6hş\49_r*HAA-+8}2 %<5uݔ3)(s+V O>aPG&p"#x#{fl( l.949jt_~@"4W(Ngq9 J#1ź#"*}h_."@E`u^ԔO[<UxSKi?GzKp"ηEڜ*c)MLp|arq oQyZ u\O$c=Æ!%Ɓig OsM$}ͣRW0DDjL`WE=qv*Oc}Ƭܟi XvQH\yB4{!T}iwt>G\4' jwtKhq֖Sy0A,b9P*J:"uW33anmٲ"D2 ,enV3.~uX[]氾Ec1 ۟¯n7~b3=8$cilyr&Zu4ړ " mB@y/l$^5wLZ9hDO|ݜKēzvtcBe~;As?R7$(glsjd=e߻R> Е9,4{Jy"Cv, U|+v5"k,~PT㏅"AnrݔZԻ/Vf7F7nLS#[vzX/Ai&)/'x_ˀ*[/wb/\WF v_Jv&7PLXxjT[J rF/j|a8X&T_.TkɣQ*cT/a/H|!Z "RKX1\ϟ?9ݭy-w9SH"lx +3c}}UJong4F2ϱ.u^KMGZζo0"މ~ endstream endobj 5651 0 obj << /Length 1753 /Filter /FlateDecode >> stream xXmo6_!_fDl-^[K8Zeɕ&#)%r 0H;=ɾ|OōG}g͡dT;ySOk706^C?~2$.vַv 2]YɓNP8>ՃܞT]?4K! ,}g4u_ߛDM{ϋ0gN*X{[Yz=yYZ(ǷoLյ*Kz*P kMqU}u[U&Q:s 4c$ˬ"oG6SQ]Zil;Wj]jو'^]Z}V'$ |sTZlsۜ}4/vW4-޽]/Q>.>ת~ڨWqOlv_̍@V]?u SmSFpƖiT0h.z x0@zmr|P{rH%D-7+[KJXzwzgϽԩYس`{+OIL;+FbIhɔS Y3Oix|grО2|%~qU.Ӯ*',IgZN|V IBm8|D}POCI|sYl0ij:5+`>-0㠑~o!¾iFpD Q5{KD{- ^Tמ&!js^xuc~yAtKJeȁmGtn̬n|-Sk团Fl2կ{ǖ{q AG@F2n/jt@h%cN jׂGpP8k5x!qQ;ysf̞Ĕ~\)ir)Ъbאk~x$wazFVDHAKڊHs [^^wdBdz~뎑#wkn ytcts~&vIV[L3?hg_ӘRؔޕLI0̩vNդvx6Bjp0luRB[_Ʒ5By|z IB4% Gօ")d}uaɔҩ&#LoDlM;jZZLE&B]T`ġm?X!'o@ u= >ikX01% endstream endobj 5587 0 obj << /Type /ObjStm /N 100 /First 968 /Length 1537 /Filter /FlateDecode >> stream xYMo7W^~F|m hkZ#T IF77[+V)=T#8bL삋1dWuI1#9*jFv, Z熭N98Itѝ .N.=٥eir1p gm.>A糕;:rݱ 'hkvlYo,!޾AAZߠ$ ҧV]I6{Wu^zޓx}/AƳ4 :CEs!-/-.o{zOmhjڹ35ՎMS$xkPopoHohoH{Rqvբ(X]lU}rZLo|:\PqlgdeӬ&~Xmn4\ΆZ|-PcN\Woh!>~D1EA;F%=@޾]uUI">$ț#wFA U3ט72j:\seĸ>nk"hhM?N>n}L4C%ǽS 4ܨJ[ԓnE^ۡY*D¾c¿.o~~y}U}U}U}U}U}U}UyL$k@nGBPs:VlR/QɠBM9H DdMHfu#/w%!2-`d&e/{^v=>~#s1 &*H`2=*Ix_j*V&{jH>K/_[m3i@9 t+H3e+CF endstream endobj 5688 0 obj << /Length 1895 /Filter /FlateDecode >> stream xڽXo6_!d1)QaǀKW BeʕwQiREx;*^mx2Id KGÐDq$$-;GBD:R.Cת'O-ko4/zMI"ղ%VE_Dd[OlIRs?T=#5@0A#2a`7!}pLP (4$t 7'0')Gd HR܂?Ke A!c% Bڝeyd1_rt=*#1*t0"sMyZ9RhԿ2zy': ԤΆu17dcҌd(By1JGIϝ0#Fyo+jjm1 z#\8t $!YB!wpGtYC<0XnJ' wƹq{&_%"\8q/ub`eW+mj!Tl f(ɖn+^\R,(_{*&Ҡwl7AEйGxqr5q``E6WGU0jv sKf#{^7e$$fqvYEUP>l($)aY!QQU|7꓈9.o򢓍+zǶC$e[]1Wue@Aqhh}y dܿVKc#,L%ed@G0 `~axY,Yu,nV`1PNO^1UvpʬU&5rX+Sړ1g(zt-HLXyS_*2[8Ô #Ia$+ 8Ul^NKK+)}1N*L^g ʍᆥS2G^u^qFx2K&ό*sL3GHIT&ZPf˻ݭ$-]$~%ն&*tDWUfk2x5E a:̀2&djc@̢ ~a`h, Tl o˽ f1~W:ؐnlJQFRx8~c)~\Ac  'Ѹuf4bҊp,jxZma j;|ɘ J4VKqH!Wbhmzp$910fΠ"Hwϳ3x2'-6e#]&.n`_rk䏺 ?׹&ŬŬZ 揳ܔݭ\xڍ4(L=ѧ1]j2NM\b[xfFTCu4e;6/V(&8!L}_A8i8q y{4)’H+@|zC˦u"wFkMflU~y#1(Be'Kbk˭ʻc#3&_$ endstream endobj 5716 0 obj << /Length 2234 /Filter /FlateDecode >> stream xڵYYo~hxZ\:g3@ٙŮ;nkÑq~}X=@!"uW4_W|o~Vۇ ZgnumMַW?/[OQ4;҈i !t];G:tڗ!Vvs|?Z\7$ Zt۶Z(| Ŋ\<4DzO^{EUFAa>^]/?KϨPwKJSh{* s2ɱ!2l;;l6 aJvKÐ|)T dÁ;`#ɰ J^^.ZÁPn2f_Y$Yxck-(L$#W")ͪyG1+"ד? &)`N =>X@6|?~ͪrtuGmȯzyl?bH6C{GM:!3-qW:i>QwrRE^Ҿ4u :\H/..{z*_h9Z6^߿[40iKWUXxn&qcrIr'܈ ߨ;s̯ I^}^J`cE 1\gG4Y=*Gru{I3eͯg"bLΖ;a-di2fX̮SAg>Cx;yVEMv^[@'8BhL-Z3q} ĠYw9MG"ctNXAɱX];_JSq`6$OcI'mdl0fFWҼY%?+%_zEV~$n, iX0p(GBkhCsk{YOJm*{IL@* t:wk(I(9)t1?_EnrruIr |U9.kD kI9@kJ*eޝ FfPBE,j 3h>/1p‰.,X]`΋=8\^COqf8Drd{ 4'&%m2iQ;9uSհϬt &0'~x2xUL3;Ž[w\fMam#àʼnЍ7ct$bQ1`a("S"5E i'H :If2u,jzMj{Gp.,@ttz6l'Z*2A!J _K|8;,¼Mwݎ>4?.};<2$27|[@-,J)v{ ̛6 ,R6J4K]XT!.HEG0ܑ:@a 28d^X7>ʡ0+&#x _G ngLzh\6gY'Jfrwb@>e,cq.wq{?~2 endstream endobj 5745 0 obj << /Length 1845 /Filter /FlateDecode >> stream xX[4~_08e#Cg^` >66.#Kc2`GfϾvuK!fiAlu=q(3)b)ֳ7Vdv×/%;J EJ0To:$qd֯n6֝%y-cI[^.0r:"_8í<3yj.Khgbmf-v?{S&UVa=7)Ϟ|7#ٓAHI}YG1$᭴2_fݙ}fsy+$U|eIit 8ERc9NjwMZYE1!:#;GZ25~1G Rr>#`1; eq̓ ^ڼE!eqbQ e67[[P@`(^@VY/@q]7 AH6ؗ^gqXoVkgH\w^0Y!N(3l;(Nf6b1v4P*  ]>sy<pw1!O?],y}??{x -_CŪmvO͆f"c|OceύMlz?Ч\G8ұv]Ob(mfM^a!eRhZ"(6S-Կo3ǹύŤraRG*,߄F"+'*v;F(Ҳݓ|Am6A:@0k b iD!cwP廻8W @ҹ@ǤGuʭ4sZ%Maa,s$"‰U$j8gX- aVı^jOGKl *YU@>ܝ JvaV!Lj-i;솃<ۍ(ov~@@HC(8\M]`tm8 iyKЇ/) iWqM|F0Z /# Iͱz_dˣTg\FMƇIlKv>:?ջ;7x€u#G?vX 踹Tnǔ\!ܽ2о?{Kwz:-cjh]`[F3iKz|T[?(˦>ϒM')# j |o:Wi > stream xڵXIs6Wp|&!N&;v{Hr)b-*Iq} @ vۋH[{w~t5zs&TxW1.<)0 gc`V|Z^}xs&D$SIn}DLoa vA=R/Cq5p(CzD:ĺI$B"2T.8 >wЏV(̜LSsh2/s'_ E^OZNKm$SmaSy'p{r|BQ5]#gU /߲Z6I$_"]VG>c aҐ:: E ^U}ݒS($'Wia,7<.˴t0dq! ѐ'B1HyU21ߚ>Rӫџ#RGڜJBBd1{SLSPo]x!9w9uub<.`%CMALRHE7^q-t/'@rc&YKfl,!%U^d|YSC</@sIZ&E_!׬+m (}`|Y ػwD@[:7;ȃE|jԦwB8î+AI#NMI5 {7Zt>AObapFz++lˋ7۠5 Yqk}9t\7g5\Yi5\yY|}_sI&=rA(Av],qxxw>LF Cr@aXiR'Z}1_ɐ4weX%Vw"wtIeVmAx5O˴,==זj[d aN1EdZ;'.slt)J5ah ` ;A@wbջ`|?DaA.ژzAP?m'Է _}/Z/V,onWw8 qRЯ!O =R2 0[ICLG}^#KK)-$`+|z5 endstream endobj 5674 0 obj << /Type /ObjStm /N 100 /First 970 /Length 2010 /Filter /FlateDecode >> stream xZAocW\(rf!EE X؃*+kc!7hzՋ۠aߐ83ȧsp쨖*3v ∛jrل옚:M8rb8SVSR2eO5eeFr5NZKq^Hɤ T h.ֆB6H.V *Q`3 %bM8" EE1AX)`06}v$ HVѝR*Lr끹rh=0pNf`=&Rѷ6Gag38fcD4YA6hX40xC;Ccp`bKfkBbQkpI:0>II3 & )Yt% IzBfHh=URRxz[f(QNHr,C-Ɣ&W$m łkH99d²"aF YTA+P[ K4Q%Y,JQ0f@k5c*L^[xҦ@  Hs-WWfJ])AѫWGy67t1X豏ѷ_X[}4LK1P3J0md3i>_>Y.nݫWnrbu;ͻ}A~lvbƛZNM~MoTgnx1}7?cvmIXɛzyכ4~_\M_/?V$+L)D_[7]a,lΦbĠ fZ څ{JfU?=jhzv_'=تf oyGh)M<[:Oo~^淫7f@&0) dE';,VEJ>(T(f @Py{Td'b=a |o.K?Uj6q q Q1b1QR@8 tvy:eU[(>l%ٗ`jDer<9>Z[Ve/h?W 'c6X79LTshGצ1L`63wG1+hOH('DP/–n+H_.hJtc`llu5]02nENh$Gfݳ%ic(1V/v՘yU=*l8ldًxTT}=h*FJE(=c R#_ϐwgb%d'. ?&[8<*y*AގrN4jdDPĪqb(/ RSCeFu'^F;fH` j y`?a%P1;2y 2S߾gu`Hy/yUm o7oôAg@xdm G.~w =ǡPhME# ETa&'>a|J|% -%+-q.t̡ ]t̝$s'ɬd0NP,(=Pe`c ܞӍ6JN/ xסI嫴Aqt9i%(E3v)ɠ8;Jsiqll2L ps+H;69?f9nAHelt/|Ha1Joӻ?Lczh` mv}K%OA|i?Ȗi_ٷTu/U (7sm6Ձ)ү@[)WhEhvP ԦZ@qG,Qo%KO:NRxSAS'qr'4gf(ˊSt_,Q{s}@Q?NAq8,8-P 31S$|@B)"XynNlSќ3 ?s!5 endstream endobj 5795 0 obj << /Length 1859 /Filter /FlateDecode >> stream xڥX[s6~Ԃq#Hz6^I'S[~J3Y%n)R!u_^%ʵq988zkzO<9{Hq-=F)Ry[O3凳w,J?@-,JkOhs z>]dmJ ,6;Hv'v-Ɇs"}u/&}ևg$]7W?)Fz˗j[]m9_bU|=}ѬY\iҌyRE#\ԻU\駸 ð]߰Ie/o|!0ZBp9\26H5kι?g:Ф. pp!L ^CY l-XH({끾B*Sؽ6>>و}Od@){.|uL@P'0ڐ>-54*oV)&C?Xӊs9*hv[iTjh#;WNe!%*Sɨt[pGʞjtJb:c*/SIY+:n'lަlL~tZQ??D*v=D72n;jy9b]jF^=z+ ރ[$@ gG=q(MjE<8g/ ر{lom#7FL^]2\!?$ [m2 $`tm)n!\Ҋ'mP :j ؉I5Ts6ki~q+\ m:+tl\w:HjfzXmUXbWk=Qd5Z??,Jb5QS(JPk4|'p9ǏNmnCDt@J$HCBch7a]tt:0[S]~NxZb \6$|!6؋eˋ.~rͤ q]C-ku9g,ѯQsJjɚ'Rė4j|J,C-cKާU [NiHԦvgg&H ѫAMeξ;sLO@n{V]ęCXJ,ߦƸ2fc`"7:k值Ԧlg`L&mEd`g6R(u܉~*H^O\}q7;*by 8 $0H`(k޻8 |$p.g=^$:p=YH}C;;qP.5z hm~m aa*P_\F8v* k#CڵJOrO".Ly J;n/0`j=,qU_PC1fqIQTAuum) .jwAԅzdXgPJ;/\jSgUסHfDCYwNq?X"dGR2q'qٍIngd>"^ٹcoiKG˱{G%=[ T$J-֘@k B)ɛ3P@tw ֪+4ؔxZkFy[¡-Q"5kXfWJyh4[-V:3a3,<2#z`aںqjhXg؁}sm}7'}4HҸO#)! I9:׽Ȩ)-< 'WJV.hpy0xȀ/t endstream endobj 5818 0 obj << /Length 1980 /Filter /FlateDecode >> stream xڽX[۶~ׯ$} &ntwuIt%OKBk 2_߃ )RnX8wyvuļ%! A( ( /]Sp.o_^hMB% 4qEv|4{O_HEoP 5Yy}yͰ␙C G(mk+m!ԋHN؏Ӷ)XopXcPmee:Ծ^|bEujunc)"%D']4L,g-08,PQ`/x9|h{wfj1Q(KoŚbj!Q-#0XNJ\NVĸ/Wp8/2!Z^% ]/nƕ(KgH81X*kl>8J.6B 0]$] mrd_gǜe,b2p.KewK ng~֮6"-tdr3,Ai!!mpǏFt*ܝ4"mWYd զunE{'[V!&ZJ{n^i}d u^B tBZ) @Ɗ41q3I$1 <49X1fC(­~V3Q%,kv^߽9w:pՕK 'y|@PLk݁ұ=Γn-Ϣ8@͒D ֲ(}_z/QZ!ф6ޝhD@n{EJwdlNBf,`sЕC¤G\X ѨwdxLTj%=|9VSx`4LȈ{iV6ֺIBpeȊb!i'E)P(9yE(֎FQ[<mIC 4Hb lu@ر@ZH@ŮF(.Nft6jg d|Ag0c:Ir ^y2K^r)f4QFbh2Tf37OP1|(:lLS.;! !)o!5ud"VOd/z5X| ;hl_5 endstream endobj 5827 0 obj << /Length 853 /Filter /FlateDecode >> stream xڽU]o6}=kĐUltI p<@7DB%%./%V}Ϲ{I`<˂΂:@8ɂ< qw!"yY0-Ulpc'g)\4#C_5SDB֕L<#$qtŐ`" 5)DE$)…TuKU;2t5n5E;; ;;- *E 2t9i{9t)Pm;L% vǡ#@FZ{i9RΤe*FnpzDb 0x0VIaowJP9ߏ'flkRa~KauzZ^]]-g'_.ޱ#yk=HPK폯mEK!|Gᰂ9#^**Xˮ/8][}g9mFs)+x&hFS^ŰݏnVv4 PM/Gܩx!O{ot;[S[,uʲlT\:ǮŃ L=nfm=V?POQk9]|CFU*hwςRGwC?hnߡ94=Z&_iUw endstream endobj 5906 0 obj << /Length 1310 /Filter /FlateDecode >> stream xZr6+؝3xX6mi:tt16%%vM tF/=+*{}s~p|Y)E#3(>Rݫ>y|'߽~/M~wTfy<>q Z "(mqVb  V<D"{nkIԬjߞ=>a6%c`c9WDFwQC Į Pq(O:4D!,1w 뻨HHdK0(  y`p#@" }\}d,ndaГ 12R1P͖u wİus&{L`^a{Tm^TV, }sd"6 $zk8}u-ϕ)zkjJC{&86ų_ax_TW5N fu*Q$!%좑c^i.(\KoBa'[3|{fwruYq'C|0+mo7 '^i礵g/e~'Fň^gsȢ;ڶ8z푎}kᢋ8[  $=6˛bydPZˡ.NA}H\Z~;*}[*m` ˳,! Rcw M֔[c6G{k{ݍR2- 1s/ :Ip* &vA릮uXH? ޾[beA@!/L*}@BWޅ!\)x<$?ȉ2 a  C 2cE;mGU7嘪w#zB406Acmk@꺍0?u yB;wl-zBP[=!y`ěE]|‚` 6#mh?&?OCQܗ )Q,ncu_"%>hgd G/#ӏΞ, ݮdRpgR8Mam~)gJ"?'%tMOQ|]5wC߮a{م-{E65[p^uP _:Z{ޓ;$vxN-@oE^8dmmÎaOSN1 i&%:{"OS:8Я#sK ҽ],36(1t~/@ endstream endobj 5783 0 obj << /Type /ObjStm /N 100 /First 995 /Length 2516 /Filter /FlateDecode >> stream xZo~_C  m?.qIr}4rre%^)P fwgoH暳 .\\Bu$Uq%JzQ N(2T4c\+Fe0N]F$ReHu\TJJRo\ +%bMMІ!믁F^# ;JU(xZH$ '5 Rcc~9^cnq nEzR|$jNO ` j,e$Hp$([cCǰue9F7cZWͧnxz}=[ /kկryha.^p684h8k SҐ>a2jٷ\<{5s3/r\M?¿P1dO/&˷j\ Ų|1[.Ř!;Pi>bsL^#rq_WrUO>[XU]~>]VBՂ=*gg"Rx$o݆C4k <#E >:~Zqoaxz]/߽]?on Dʩ<̽N9C)}¤vNevJ>#] =l?\#!zm!27K7+ە<¾͘WO<]z6yT 9.@YD0n.3e xhv+BoF VsbvrϞʝ}^LL@^2?l / 9d#Чq;VXwod+d 1mL&8g $ ރWAI/!YJ;t96JԱ b2&oDRZ54KtP>"KqȾhFP}sD{iy~ʁ3er>?@g;?-gG(u0sƸfd-MA::ДALdu9ZL<rbT/gF ̔' G7Ň߶s/$G9x"7}IR/)ZEa3FIAđY XB6R"~۞92tAx_$i_KT&zO+]Tv)oݓ@a :*Q>H@:+4F& !@& iL)AWkV7\]_j}<&9$5} Ө|5]-< %Ra2u32$o lMDӆ[3Qcy|O">%pj {d̘e#co$pL0keaL3 -`HWcj$ +rܛ}|/OU;e!|6u2gbxsOmD=O JJ[;,9`.xBF bBjY-Pn0?@KvDn.O@ژh|-/g1Ɣ٘2S {88gl<Of9dYNf9dYNf9lYf9lYf9lY.fVVVbY.fjYfjYfjY,fY̲e[[[[[[[[fYnffYnfy3Bh¨[oBuo ܾ=@1Q 21t҈YߍA Z  \} Vu!:z 3~d=\@P>ft 2 usH ;b(Pqv4>$:nA$LC( $v܄Eٗ;"%-,twvtH5!ݚʏCȷ2* 07NuE0N_0;ټnsb~ڠ=;ZycQf!P+46žfPpWbcz+ pNI=c;&Ozzc=UgvtǨIS@^o_~b Q=Zv~l(Π;\vL磦ms8GHJ4#*K]&.Yyٜ5݅ endstream endobj 6012 0 obj << /Length 1466 /Filter /FlateDecode >> stream x[]o6}ϯc ̊!zmҴ]bsa@Fm!I׏rdJ7Cbѹ_T୼{{zqvq͘[,=>,CE}9GBk5{_%"yC_zۯk?#Ʀ ěacoҵ(*63YJ=PLB?u_xveFV > icu9S^P(((Q(=pJ2XD!{z<;[|(HB+^gi ; "e\xA0B?3ar{a1䥪ű+`qfbB&B 4OD|@@US? Ϩ[{KN~RV22B1{%h1wGC}{q<Д1 8 k ʃVJrլdOD>'RUw"@ͿpH|q\ 0ˢ}nPTilDWv{pVJj\AӫwwivƅR8\כ,,5;0%0 p0J^m2Y٠@Q4}ёa,b"@ ;e#<@O"I#C! $Q%lC1٤ X}gOշ&ơa#ĹE;ƹ2옍%]\s`BQ`w!X{%x .&Gdֽ·A`,D郢eU]6i0CJlO/4 #pCJV^9Q1w2 d0afj]U-"Gԧk3yHx mKC=Gb>bPk%|J.N]+JKwTnQܪڤ͏ 8 #CMv~a<9%Mu\l"(2 AsK%u܂ц!hxX}GpY>rp8$'*,?[$].{?dc`/&n6ӕv:hl<cso` n<\Ky(#`q6= ) ,N7z0LfN<Ϡ@l [ppiD}iH^ҽUijShײq.h6\H5ȔU cvO"w,1J}pHʦw@[,^ot 7\j.}\J+ q.E{wG`m%,+.O)w$q A/ekd[.lUp!2ݾ*v&“2\_- 'ݾ_{/2K~_ʃ endstream endobj 5908 0 obj << /Type /ObjStm /N 100 /First 1017 /Length 2796 /Filter /FlateDecode >> stream xڽ[A бhD"%p[ć(Gpf}zfh#)kTRMꃖX4}`UAO샑lZ`O!wU@_Pi"Z"QO4:Jb%|ĉwaNd6 OpJßzm*j.}T}Ω≱FPp.ImKW뚤bI(|>Xy$4|Js<ްVQ\\![7_4DI0yſ(0⤍] 1V5i!"̕H#4SR'ÈRg#N] F5`A`Wyt#Kk <(TrB!Aqc`J4-9 a  WҀr g*.5>SO]n,lFuu&\l"0p\HڜCFFu՘jC׉ X VcgX]bZVG;AGp!S8l$݋w7>}xx|;O_yǏ?|[@χKO-s703yߦ/ttxg?oÿ_I&N8F`s,m!o\ԡK{,!B(bbSV[5;Qu!Zi !33gMQ$}Ś;yH!zB_(VRbًPAV\<@ Ȥ̊3m\A!?kt}c"{`9PJE?Q5P}]c(z :F3u3>{*1g`k[ IUEj@NޅnWV+1'8Ѝp̊%DtG v,}ŗ|AR.vL,fZP/r;n)!kSTc g5 Aڋ_E%@Ȁ ר|R_XcCרVnv>0C m~Z^Pwv(nqܟ~I?f cՇyGlO]HP&a:kuVظAp» 6yqZYZ^A~Ea<4,7oV~!ݍ/!%v-w`L]! *[g 9^An9dXU7 W:;g3 D6xo2YYîVY ʪ6ev#$vr[d_ Ζ^ ct۟72DfZuү=OBH]Aۻ#˥OTw]-1tKxc`=]|yM /8zrO犣S15UmU (˪zk+S~_ eCJf+qP)fRƶn]W?j-+܋P]^țŨz~OΨЍzɰA#ͷKz7贳lJd "ݨ)(FV#^.u^8auk ^$C~xfK mm/|4|YfYEgo<_)i endstream endobj 6111 0 obj << /Length 1456 /Filter /FlateDecode >> stream xZn6}W1HB>6iiQp%zW))Fʔ&.ÐGgng xoN^NNϒi.=> c/?b[ego߿zV񝇙DkcC'Ao,$w^$y¼M(oi!z-I'7>EݏoN ĉ3 'Qxpz Kd IPac `_408CŰQZYLw'Goo\g~.Bހ @QdJj~C ;0zGHrd6PiQ "OJS{>?8Lsxv z":fA$$!1 lnU3"36ɿ&/Z ,xS(2_Ch=&4&&Q/d1Qh!n b!c \*^ =aY4?a{TbTU|E"OkPKD&BfUcD t@hFGƯ^{#(Г5'ksL> D> Vn[ |GM8޴4xq'daoq@ꁊ JgCs{$S1HLcZdV0MsE3&Og:N[Y8G-gFR:n #ݺ77x, h%gN꼚IrV#694ɡ77 tb:̔U0FRbwDUQ wKW,WGَP2/muzؐyU7]bWykٟEu[I|> G&$DR N7G&=k$a'Nz$/Zn6.c;ް=n36&.ƂcFb, 7P-& 0lʤfj PBe%8`#M-vWC I.?n[2Kچ M*#<> stream xڽ[ˎ\WplجY$ -( EA EF }N-/ 6 MtzSGTR&u%nKZH ^JC 5IE ) šȥkȮD|%s)(&.a+a m3|f= o$u{IxIL].IU؞5)]mI,̤w{z}v$j5JҾ}AIff(.5>,>]|+nӁ&cc\_%5p$#$U Ò͍7,YJOFQH ; H ;RZݚz5nxdwu<ꩻa!4KBQӨX$D&n{&P%|aEEa *Wͤ@ݿ(Ԃگ@q9.Dĕ›H+-X*wB"J;b5XM8@TE(Sw\ku\j\j҄hw\j놋#"V| qu*y b5A=kVE~3>x???}z|.<}P\x״x|Szu($Kɮ1u("ٳt>])]}kAU3 k6}׆L ^(8-ۂjf-<δ #rgknH(`^}58Δh+MU1<ZgѲ^'} Sx?J%y6Zah:sH]B90)>2f!awЩCdg̍w%gZ3%ߣd[i )l16l1Ѣ̐-|GjHrgUwG?2ɦ+g=d^-C t[9V|(~:+ 2F?k\hjh:sG_Q"σ*~sm7[:m,y/XhӞee~=A1YZnC/fni0pЬ|Cc^C?AV[fLm}}Jhm]?R ׂ)Eu~qZt/U>Tg)ZK`S8$&WEaq>kl{x?-QP,'Ci}↑>c'\=0,'&#/în>sbBk 6KEfްC.b1`qַLf@V OEJM(>MޣϾu> 纄ݯ{>_&\_os!Rן:boyH3^wo/KHB+qĽ͂zuH_u+ߥ_40kKf17O?m/>^89/z{QToZMIG|tyEzSzk뼄oOTu#||ݣÏoy%mv(]~}c>[| }7jPvcoCs B$ !9999%%%%%%%%%%5555555555k @\r 5k @nr -[ @nr={ @r#G @<yȷE"(ABj- f-oRߟ ]y+)9Gn'()JV+kt*Ӯ!kr¤q$Dq_:vhkoG8#$n#bwq[+nLqcv1{&]CfWٍ+Jni'pv[3_hq얱<7m r<2sf -cf: 96bD:/bĮؽf|BfwCff.ܢ]y3JF{:vWi~qw1+gE-|`]y2JsZ%]y2Ug=k{6NR`^zry߻zLכB_<b3NqQ}lf4"JX6p89+/U1;턆*Zq_znw/釬 t-CӍw_ՉwQ7}+1ƺmg޹:;[Q/zzqH/y{{g䊓G+[E9W^sj#oi$vL:J;qL:SP9S endstream endobj 6187 0 obj << /Length 1281 /Filter /FlateDecode >> stream x[o6+nû5M t{P,&юdݿmQdFqLC:<;W tt>N~N.8wsg 8`g:ΐ|qRC1m}fjWVֻ.6,BR笲åtFI^-QU2c8_Y3 VY]˯)(kl~b:C桺.C[f\ƊLYt*N`*USj6m[^5nrOgyi,Iuiz\y[ݔ?]?"sgI7))H(QZ^M82akmZ9A*ݮjwA:Pwjfq $ȺT`@S` gz'*w9,-o`Qwiq5{Ѵ)(I{AVmȰ6!(`ބM n#[0[D,*U]ch#Hw,hy{0W 9ܤnghy@TqAҴH[q57A0yM͂$a?t=LQ(~W0[,8(Swnmd'g9X:g<#Ӡ/L>ʬ7NX63=b{!Sqs 6u7@Tb2h.B@0VY0pAA;iO{픕@ԄB 4JQ=0 樅E2رcd,Kfc> 9qM!UwnE 9ʤ-Z-ћ"G,;,{hԿE`0d4j~b22g"G&Iס0I^"Hi"G.\^#' =h*'oI229`"G&d2vB~y,,䨢t]z"JǸ*L'');ɧ cc F` 2IuJ@?@_i}i*mZ_!|Aմ; \(0 Q endstream endobj 6113 0 obj << /Type /ObjStm /N 100 /First 1018 /Length 2695 /Filter /FlateDecode >> stream xڽ[˪\߯a2[U?PH@$8%]#}:խ TA>WGZjČ6.FG8UIV.4ѹ4xǓVDF{Rץ$1)7j%I?6I2FpIEEzzImpICG֒\CGxZzI&uIfJ{' X< +'ـ4hjă*Z^Fy|(!xHA`>,.(0҈d2(+4>ޅ  a =H!$4";c7-PI xi鍻A8~1|8 9^ [DТO/)=~o~_|/uw(o/_ߧǯ~OY1}m LyP˳TtPu蹂A;DDHy4sU:ВM=d?NE76/wxZr8#Mښ`3n#+RӞQ`CAv K̆$r_Do"|z8o2B/7ZCF_%RՎ[YNo8Z5#;Ʀ⧒KBO\siԋO6ؽlX p o-D4(DteA@)AA;ePQ,a_AYQ,T|j {S!ȳ+_":^'0*gb7kj v[zO?/|~@}S_Gw"8K~w󄳤W_L>>_bߧa/Ͽ.Nt0.n# ̼_} 193:E6}.ye.d.t.l.&Nd:u"Dl&Md6m"Dl'Od>}"D'O1c"D9&rL1DN:DN:DM6DnM6DnM6DO~B~ .= XCǥ?ʑ3?_O#gD0>q8'~5FNr8&~V@13wiϑ<'~#yNtU|@"ٶ"Uގ9_į36JcZ('~4~k0Dl΁_ALn?>DP $Լ N94|/:g,丯2]+9sow'sgONZ9V%~GiQ+ώӾqGu1 94Pf>|a# 1qDB?kNNg,4=B֋mpXVwfvֻNHVͱdDUAʈ"o[rۻY#bGNE|NGsύ$\I 8 y?4 +iT8]o9;egѩgEh#('?#('j OCF.4ȫ 3Ɍsv;& ;DHy7B见c$AKS&"q^BZa}r4#G,TWaWwVn\sh˶O9r,Ů+0JU7gЌ9;]H#";*8Ϋ/{#;T`Vꖵ]3m uyko JavEQT7WFZ>6H:xa9і-xQjn '2jQV2ߩȫ|D+(ʱ"8R doP5+A{SqLJg\.*E endstream endobj 6271 0 obj << /Length 1342 /Filter /FlateDecode >> stream x\[oF~Wq+dǖՒBV>xC ŀcf;8kFgs3O_F: (3ztP#yûn㧿G|> stream x[M[ݿ_e83! n {u_ =%{9 =0M賓I DIAAAARp 5(x % uB^瓭$ E&IikTyRHZ ZKumdF^È e^L %՞tO悫-L{MaQRCRmJ.CSA.R6jr9^|\pdwRO>[wN>x/H3J Y}އ[sTF u/B`TJj:fYԎo.ZԠmNHu&zd:ROdk-CK8.Fj݈Okr Հ254\-ՑFk 7'G :Tz& *LAR_sQԦrURNk*VH"FihR;q+Fb4+yck7hXy/Fäzhx;hhpuD zO0<2sc"`2q!1yp4~Oo߽{xwx_?wxU{(>+_?ܿ^_>Wc;!Fw!!^%S{&uoSgrzD< 03jDA^ѹQ->*m"qK1f#N&,sz,թYdg*],Nj!w$EUM"4#hF]zf >P,~aʺY9H?rRWX< gtD\sYPYw8!`$_jaڨS: Ģ(u7Y.:u7 d^<'|BnI1Qf,󬍹0(JWX#`YTE!Y~*Pgk*PusT8Q0uJ5nHq2N3cz2YQS, jt?*(-{_=8A[ v|Yʨ-|q_W2xtxY:czL= q6N޿o1ǟ|ksTZ ;7ߡL 0lœY.pٗKhKK8lY.PK%%%,dYȲe!B, Y,dYȲu!Bօ Y.d]Ⱥu!Bl -d[ȶm!Bl .亐B .亐B .亐}!B /d_Ⱦ}!B 9r,Xȱc!m f~@Jv <| iر`XrcJ7Ͱbmd!K*Z>7tk9XvkYܰ#A$PKp؉quC2]m>ٓ61EJ!HFuvK0ED0H],Mԑa>H^ ҡDG `/el&APB3)M$:*֒-|EkH+S#uv3a>L oGY'bȄ` =unrnۅ]R*De%$: 5;`#4&DҞ>ˁ|K۫v K-YUJL8'CPsWn"ՙEgLqW*4iD#]`"*pJfY-0ε  KLcs6n&ٸ+9 endstream endobj 6329 0 obj << /Length 712 /Filter /FlateDecode >> stream x]o0+|Ilzcզl4aRi?@ fK2 EQBdN|`Z"'o8#Jf6G0 4;J؍%X8^i 㛡MfX8 nfp̨[ϳh1pcȫ46UQD )mTQ1/l;L!gTVF$M(ȈZ2l觑DyK#JQAGîCP{368N<phnL`ޔUju}8߬2cVw2#֪0#(@=NELEP)jz&i)kLr_bp䩻-\ӣQHyBJ4O $i-PuxF/ }?G1@C,";F7S*( hGS TsEQۇPA$UݎxgjQ)A-m.\.7D5$6"Lw,h~vEw.]bf3L8-Ro&;/#@T9ª?.8 ᤧ#\%uwm[M1&dyAXAsL6nY} >RN {8o (U+hIA;'~2ʐ@ "'(C05Q,Wi+g×A endstream endobj 6386 0 obj << /Length 704 /Filter /FlateDecode >> stream x]o0MGbn6iQ"C"0/$Ӥ* G‡s'1AcDM]л.RX &PQB0w`3ϯ/s%T*U :zZpO`areyW2KИS |d8q#b<*pUVcjM s*VF$)"ψ2yv&xOaOQTpFtj R> stream x[Mo]Wpl8`Hb-FE[ 2T@bwC?F*$≅*i#NB:zhMژ]`d%ti5ϡOB5t3e DH;=5.3]̡%p|M<N'ao=/) ina`ax60EA`b6LlRDlRDlGl2l a,(801[6n5  Bٰo V0VN* G/̦q,\[DΛ]oT]ՋW::nsuӏן1=zW?ޅwVz((|4:Jk_ŸGdQ[LZ'!Y4VƢXLcf!#rsm,QbBHKϫY;Y @#jV#3Ƣ9xޡspdCazïno&:6^$  ?~|s px{]x yu3]}f?~?}0=U9y&3<_Vٟ1<?sq..cfNL.媫3'{~.[!lƊɺՙXv!.,ؐYYW`Sf}1r).3'e޷|4?|d/lPqߊa"Zꪥj6Pu=T]5C͑͑͑͑͑͑͑͑͑#G.\8rqő#G\:ruՑ#WGv^#7Gn9INjˏϡ"6^.X.\#ŪBխ /Rx\-g gW,(䳊b>aU,'ۄvV412rU*⊕ yVxPU;GE"J;-<%J}]] q.>"喝 ^<@_~0Xܧ0? ՘^1Y\ף6%Ps$,\evObSO,W^IX,UIev;y{ endstream endobj 6445 0 obj << /Length 587 /Filter /FlateDecode >> stream x]o0{~o"u86.V^T$Jش?qeS:EhSr}#K~~P2 z~hOHF#}f5%w̿g/otΥ;4T4mmZhH6s\{b' #=s3]_Tf;{9sE]|H.Ud͟m DDCūXFJM&\m`2|n7uCzPُ+=1hY'CŢGWYi `ҙ k" $?  1  6k6&^aoR8PCLQׅC_ ʕ&WPU>^evo_nW336}2(;l6YPpfA!ۘl4k& _ sEH424]&Kv+Hw#=RdU2XT t*ٱ+J<8 rԒtY2X ܳ*@PUb endstream endobj 6501 0 obj << /Length 601 /Filter /FlateDecode >> stream x]o0{~o2u86&\6iP+D l)bDڒ*%c8Oy9 #w uhM  Hpƨ'sIwo? OJu{~T[=,,Xt.xg.w\M凨\/idERpVI-ҙR|fK{g q4* ξ>Tuew"׎+g]N]6O*{sҺLx2Hw@zG> stream xOo7:n/zE% (6H@v7!ME]8}8P\kd y jV$&nݍ676 JܠD?`q".zBA\̵Lbxfy$Kbm(osb6\Kbc!vGM|((ቼ uC!xh$L6:1,tg=I#g# RJIһJZ;PI[5)$24jՒ6<,vM'nAtq&/Gض>p4S'p;ڠ_ƍtk$v. : m&% nzlz7=5'%>R]r\4!o5 mx_mk7:hNZ< GwؿϺ]7IECjkx0є5nHIԶl@ AKa(`>_arV™Eƞ7'&dX{WQѡg+4rgm@!1!1ٳ~N\]]^^}vW8}{}͛ɡ=p7}8t6A.-l::$+&={N[,>k!tdBD߆bGZ/.vLêw RžVڑ螺b&;Zj .Nj&&VYwX=͝u5EAҏ(j.NsUlW3 !R=+MHr<Cc@D9 > stream x[o0w~_Zu?V>Dh큕C%K"MPU(!9?}|Ao]^K4֒I@r$X !ZVVB6zs"u}7r5TeuW"HnpR =$ȓ_q$gtk%9E\Z5ꍯ6v=/{]nn,t0A.( KrKV*FC GaS=\=QFX ?4 nS}cdFdyB&Jn$J{.=[ (;T *0ٶ(]cOoa'`= G``hf Hn"TK'Hn.";cRxica(oe d/3ܡ.! $fHn sW((~7sr-5wq`4X)9Db&F O)`a'e_f(|f.]\dĒK-$P+67Ɖ)Q̈oI* endstream endobj 6634 0 obj << /Length 1098 /Filter /FlateDecode >> stream xo6WE7،آMa P"2?:K$|Ef|QxkrT$HnO~DD@+,.0 ;s8=d`ڽ{2+϶<E9({(qGhx(%?}vi GI+8nJpGyPfpEX,cqVkFq!LBupK갘(%ǒ>LӌۗS&ZZpew)=Zh@2K= }u|ؠ\^1%-WxNnB`wkݡdnW TTti5&Z'o[FM EB_dcvB؎uU5G04)0%)ax,='y>`^.sEh%!NYJgǥQUO[Rյq7i P 4'(MJuU (li]lvyo7SrXPW3t"1zy~E_Ԟ,@DuQ2k&ٷp4Ɉ#dnZ0a?;<˶?=i]EisܑiMSaHZueuGY x\R"趛St47qkhS>`&¢i1X8SL_fz4샽|Xu׽B#GD6 Вʞ6З+5K#瞃ÑmĈ" W*L-DEu @m`T\ ??# endstream endobj 6503 0 obj << /Type /ObjStm /N 100 /First 1017 /Length 2038 /Filter /FlateDecode >> stream xOE)Ȍ B,"-}`|0Bfx,ٞh;%4e^*UѦ=MGZ=ĪzIJRAMݺ-Y˻$*wMDD)@)yd\cD]dP28XM?L $3({d{bc hSY|gf}Lk%c_ 9!Hsa^ WF{1h67-sԄh5cQ2ЀOu- & >!rD>!0~2Cb9>] eu5Y@` .fPξ OCԑ^ֆt1l2^btòo&D)*wvq.fh t1X^ OB`k DabƢvB`>] Viyɰr+7_b|ׄ7_bkB7_mW*ś. 1{/ozW=SM94OChv۷/N`OOoxktɓwޞޝ*ۿ}{7_7&Aۀ1o}o;ڲw{ h=y(F5k(P\Cr 5k(PnBr -[(Pn,,,,,,g7Ho,,L=0!Vf"2 40!„XY{faB,Lsfa2,CdbifaB왅 20!„XY{faB,Ddbefa2왅ɰ20!„XY{faB,Dd&„8gaifa2왅 20!„XY=0!Vf&ĞYĕ g&µ{-^˺ײ{-^˺ײ{-^˺߲.F.^ÿ`6ġZ=Pj)|,'H?Ef0b jWQh?/pD|| AVT[ !#j!`){Z0+ Z3~ZxC [qY-.?'?4PO~Pie=__).犤FRjQԨZjCu^PzF=G=r={(PC#G(P> stream x]o0+Ƶme׵U&u` K(AIS>Ch\D=>@mAvњ\0qfGC0`Pk\{8C|qcBS݄\zmtwǺ&/n*Xw0WՎVɉdtL)BS )J@Gf:57 K2"eE7Ȭ-fmΓ0zۉ0qZ E` t-,ZE< ,s+MHp̓R24&Fco,L3Q!rFX4]Qٌb΅ Ick&b+u;<{cjx4I; iWWŨ%_)m8 P !QȀj;;Z4xsx˅;GJ{l %((TC9W/5H  FE|rwIdC%I J, J3頓GQ9ysZAqOLsDɤ簣@"i; 'aD sH6DD)@;:$aՇWrpѮ#ޔyp7T"%Tm3Қ0^Ő xsd[dN45h'kNnTpSFR2qb'ꝏd|9d᥀lm "x-+xÔε;U幅* Ju J^^QVqA]1V:)fꔸF+J^ay%~WPύ G U!_p9Wwm]"ʢrKމ݉ {C7 w&Ԇ_MMnDD&㨫d> stream xڽ[M1pX_d H"/#Ʈ!g#_z}! h9xUTk%TQ"pb I @p Z1DDµDCK6ftMcJD|&&)%XǨ'6)S6vAvIRƳ]А- ɽ&zK0$}=W$=VCk8)[$&5Yjj㉖S'+6sP)#J1dN$abZr,wA1 @E u</SspB/!ǻVƻE%(#Åqs喚xSHRR`1^rn;'O "ھWD>6 w|& "Dۻ?+M]^I$ EM@U^tu.گ 3y/{UF 8\A=\+M^ V@/a;.^ ZCmy;SHW@x}/{#&AP[z;oX:rWѡUGՉe!~PU`QlܨB%-3ǹ8r"~Q6Z׻wqHVU(P}u(/ A6'ax71xUD@ ~Pl endstream endobj 6792 0 obj << /Length 1327 /Filter /FlateDecode >> stream xI6)tLih"uI[uʲ+ۃۇE2P8C<ǷIq3ww: (3AB#8`g2s>oɏq~0QcHZצOƁc2g`bSӀ 7νM7z<-(L@:Qq3 aO1`|`9n0^x/˙odH[@@1fA@ښk - c=})&1-l1lGis^)0Vn*OV)"?C߭7iUIQqd*ϊLvI6˅?=a^5FFb.燮Oۍ[qKw+Voz*< On83鏘_X%m`̶g=\ŀ"nocCiߦu̺^ZGo]0v$j]Ti RMR~ᇳЀ:4ڹ@b 7>{&Tx/)ɝM^fkRsg[ l_Dlt2cCq VM 4" +4斓{w8e{blJ*[T5_vU endstream endobj 6695 0 obj << /Type /ObjStm /N 100 /First 1019 /Length 2582 /Filter /FlateDecode >> stream xڽ[ˎWplؼ/>mAI,-Z( 0bp>V+ UϢ ͞:ĵ惚L=M|S zIT*;trUpnjn%՞gGb0%Vw#b$0IG-I5c$cORk>(8H5Q4#KږgknG-y[Ɉ}#haD>Q2WU9H^1i\ݲ\62^aa_ Zs؛嚚*4*V-ֿلR'dN]4}TKbmRS˳-14h*49kICJiDVNc`SIcj:Ta)P8Т".C5C~NQ6\)Tr @g "N |AdDU]pxG<|b3ٸO5&STR`RX *f0b6vqf*f2-M|D r:&{ݧOw7_4ܝ~xw?ӏh~;t)ֳ냉e L-E:I?=}L}}c;ہ(S+C)W&acw;8hY Ur`r,h k6 I(Kuy8|bD "aӼe{9x1l"x!(, 2,v],2 j%L5uК+ҵ5WգY0B9+gxޡt?lXD}U֒W͋qgi\Pן?tzU:)yɻӏ3/>Ͽo?<̕Sv.Ou 3uӚeybc,@b122222222222222222222r 5k @\r -[ @nr[f jnCKX`v,U ?cxU bj 5C=(h㝀`QeQ,w$?N I;(, o,*QYyeAaP[WDWOV{(޻ Nrcph1`,(V!dJe+3ڳ^I̴c ᝖)HxEAeJHEjqLEr@)R@9A}zXZ -u+7ZKH"1lϪ:bwZclHBb؞eJy:{;Rovp! ;-VVRBZ-o9{^ `a,̭0YT@!52-Y=7S{Ґuw53jFbShI gh+ + y}6t Aϐ`QڅE&>Eߑqf>K{zoa`.H#]+BWp5JBhO+QsX&2{E/&bVB- a d~|5қ='!dvf/t6fAd?:2rIfgvksy56to,(޶Y𾍖vH}rڌqWzrTgHgY:E `r,`(l" fz,~JX#7b)hn<D,[Ko૽_濕,{wrJ{y v)T> stream x\Ks6WH0x7n&>xN;i$ۜZ*ʙ8I ֲ89D!wX]{ɻ9B&W}D(#Mf7?=\нG`J z|ŏ>v'O){~{a bkӛ_ExBBQ"_A[o?/) 0O3t0X a0@Ȏ>~ر5}>n1utHl-#m"g t3_8ojH⛹x1徼 >\xPTTT׋CQ*xnAt\to-nI$H@ ASPcvpJ3b)ORu_VE.]ˁALҬ(ݶj޸ dsTF! _@c̽KNUCdvQDV(I$AdfaY1}z= ,twY{#*ds_H^^q}nH*T/zwTw+(0X;N x8nUa+GEPY`=8GgR C"/WgP:3pݐVB$Hą>z{gPaU8DR8n 'OFIMx.~d壇HٜB+~0$7hٖ ;#P-bd|4ANJt68jr#sܽz?9 endstream endobj 6795 0 obj << /Type /ObjStm /N 100 /First 1023 /Length 2621 /Filter /FlateDecode >> stream xڽ[K\2٨t^z${xx0dɿwTun9[P_CխwnmMSI5K$⃚V $%jh2>%jZOgh ƨz%fk3N,uIl쒺B9J[H>jIޓy$)w$Z d ̳xά@[&^?#I'^$9Oyt&;Z֓d}, 9 Q25'H5ri(dFwQ :Qҝ&«: y1”AlE<|yOmΫ _,v] ,\ VG2c8 և(C<̹!wDž @:tQ/"_+Ѩǎ/C}i,6By΅4S'!{iҸ5 iRxAK< OcDo&f"S7$SadŋvN?<<~;/_yO?zW"ӟO9懻OwZ8/SJ#pbŋtzNz|N/~LU`JB@m͞ ͮPlwX$^wp`S:g:dS|cLJ/6^A zvG|3ן?tzU:KzN?B×̿맏grR6,3sX>= 38S.q@b1r#挘3be5g (bPcbc5k @\r 5k @nr -ÚzXSkaM=5ÚzXSkaM=Ƀe#G @6{`abl S*Ym;>^Z8\A}!!y Hpoq]ǁK`rB,`#!Y$2Aސg$dy7Iz&^Xˍ-$Q{n^v՞bP)JFI#K`~da"M+ dsWI@,t@ L` ,Vj'{=gqE,gOIld5{بfcREy`(l &`s^R\&m$T+R-WTvce<oz"6aqAS0*J0Fr+#"ap0DRpMa| c,=QlCF|0ͰX;{kȄjm`dAdԬ x(%P2㖋^ZSx*+?M{E@1{c%1uڡ1_@ xʡB6,FkB+l QMyKY0j PHqR դFbPDRЎ&1Kcu8*46 _q0 8D#T>6rGo{~nxȐ6<wjz%ѐg8k7O7KONo:*r ?PCnKy^R;6ߔcKsb,~}f،[v&`t#Ἆ'xk#q)n#Kw *1R76 ^LHeY ڟdP̱7Gj\3+jHjtKtTÆrmk[]}7žj6r8/{/s'n8ߣ<dSʠy)sz6( eW,ݎKY5[YNJj#a+A1Qn$* V'JnY6$'H0Y$Zzb^Eh}c{#qnl8\r$ڣf#@˕ wkoT@5K=Mecl=o?'\A\I |"h˻$a:*qr6_ ĚC9ZWu98 y'C d.A OWG9g#(s#R] L`WkuA$*H {.KP=ܧw I|ïF AvgbdR#P#N`U9SDOks>cI(RLd#QaN& Hm]g!T+3&z e7p< 1)Jǒ~/HLx^.HTr_ܨW QP)ʁQw%޺2o{9:W!1sV?m+{e2셄%''jQ[ endstream endobj 6979 0 obj << /Length 1247 /Filter /FlateDecode >> stream x[s6)xLgV7tyMP 6Pp:~ sQ~w,~|sNc"R0Di{W]ﶞI1> stream xAo0;)qmc?뺶ڴEӤn,"= Y@!-(<̧3ws;z?]8I~9c2p`]Bb`[FKh}ǻW& #[OaBoAeA4~? ɾ&OCn.=BW"gBA~`S WtK d:X˥&`HQ1I~RP!xs<'[v~89P#B Vȅ|eg&\"!xL3 *AP0Qթ#V13FqƘ0 :_2)D?DƓm f0. br2#L"J+m[Y"J+Rn8%IKsui>$s#(;fmQtxIe*jL+WlIRT>΍ux}%g~-M;TZ~dP$Qܸ7Xev\Pad> stream xڽ[ۊ$}G:㖙@6ذH {Y+''gUuTd\3sFC ZGTL(\o--+T[V j و'Ns!?_ǵ0[ VXQz1(l` b}^5|3P xpA-#l|04Ƙ${^:QF47`40Bh10k̬͂zhc4a/ m$&# 븐0]pIX_ȞLGuIЎ$:/5sT|^'M'&cq]ꎊƋۀBt]" CGdG/0|ڞaG@[$UYR D(*r{)DOA*e\0v4JT!5Dt(H~Q3dgBs=G7O•,֐U7َR/IzŞjudUoPL$ CbC1yaP3j ) FS&@1a n2惑KܢX9T^`.$& ŌIh[ J¢ڢI_IC3\_7_ӷ[wYP=wۼûe^ODeh=_4H4hӫs꫗׏xw/1c~ys7?~ïej`!W/#($"J;CsHphs& a%j~0 h@BG+:U 4A>ua|bEnubֆ,b <4ȃO#T> stream x]o0@+x$][uiR4DZB$&tkU)ʹ{pI0:>#`9 cgP v.??GD0aH`CcY}(ʒ"JE,f22Dˬ/MWyO3FJ8!ЭI __VheCp_#2,jͰn}Nqb\1Gc-D@T1 l ̧B(fQ6u\*o*@ < *@zA޻7E Pm| jU5c˓@}"[ars'2Aq@d; ƣ h<J0MbClަ/W#5g8~˶Ɠ+ 2PK5׋a6DԐ?'Xu h5?{,KHP=I"IVx@ֶ,6l ;T&QakVx:t wq r&f 66,"ڒ٢t;KcSҧz|ϖPnV-@qa:Ni&E8)̬@zVa,9iwsU 7 @lg,; endstream endobj 7037 0 obj << /Type /ObjStm /N 100 /First 1017 /Length 2119 /Filter /FlateDecode >> stream xZM7ϯq)R 133x d>VA=^QǗk )(Pf38p)f{7ClV =-P*bVDݔ\.eH9PKVlzfuL75JE+Fa :w Y2=, 9%djȆ V r3 cJ% b`q^$/uT3 +*A:ڂu^0'23sP톅sК;kъaa jp"f!8P:%la,˨-- ,[l-+\ VMٔE A2Hg$dBQϘC8CboKECKԖZ_G[贾4!=bWTC_Q}"F LM(T8` osU= Д!%Kj F@auXmނ(7%R f>٨6 2g}&Ll*fLy ?,fcb6d m,KٸW hf -l[6b56n=9w?-7o{|Pқ}MˏwkfT#V[EٳpzN=z/.k{JQengQȘOB4 RKՊD(ǚ˧QLH( |P(H)IVbE&S =>(鑗c E*|Pdmv '.aۢKiUm\ Q}5p&ZHLI{3 G; 5uB(tBbJXqZy(i%$E "Bg %Ş.mCuZ޶$E˷GGXvn5W6h$\<X^9B|9siqP47_E9>Rdqr(wfhPc.Vܸn+7 G\? "j4޷R8Ö j&  Qp4N"%f>aor.5|wEM*w:/v20;eH dTӰĈy@8 sCvl$jl0銃~ KeB,6bDΊUy+bLWdrbcb;bcb;;ĖN<)DؤZܘU9ӄPL#1db3J31L'T gb{(FLlJv*cLx9Tc1bS6s1 c.uB,6.bŎ r&cAQ#2v$9P8P ،j\̫ŐQP-7;+& 6Ngc!R+yӱ2V8c1cyxM-C8_?\T)q+ooۇ- Sɗn8ѮQ\^<>{ym8)8 /-fzo-><[ֿ_~GXB8p~&#'%1E݌ 7anFq={VYݳgu={V\sq=\sq=\sq=W\su=W\su=Wss=7ss=7Vomtһ9-I ׳[1h2i ڜQM8wrˋ& }]uue"oA^{޻ma^ Ĩ0&:Qa {Ĩ0bcbW{7.:Qa {Ĩ0kb_bz7.:Q{a zP¥^1z'`pw0l.LJpAZ S@ F[ozHf`u^1`S@ 눂 O˼Je^G1d` KOxWyAʘ]:C8Ļ+ߠ%m1K&hVUx^<,`ݻz1t}wK!:V6Xaȼx:jP=peQ )(oew WvPٝbWv7+ endstream endobj 7158 0 obj << /Length 1061 /Filter /FlateDecode >> stream xMo8:vmbmXֺFe9b_t$OK3CɯNO#-<Q&<)0x`7w4 #ɵ1On<4?&-nNn.fv:p+HqfHs s4X| ̗izNJ8t=(q!11Ut#yNjʕI8X#toM"i 0y} h6ap2e"?OڢϏ}6,>5;B餀x휣&@@4-:XmF@4c G"6 _ATY=_PYVeOOAX7eôO1T倕B<_UfshsBZG&pncteWǞ]XWvB;@V1c;`VClKD0k>(Y/b> stream xo0+Iۏiև M=DuhPB3P46aʹ}-|..% 4҂`3e"#NI0>]K!S-ژzF0 KG_n_zWa _u2{>GqnʼS8#99yf4-+\fE(X܏5?H&Ap;""HDA5]>D$⬑lQ }d/pݞ)dL7\dRn{Ma%+qK51c{I 1d-*G6@5jfq%*{BEym]Dm^8J0Yk@&5=Kpof'5l;f^ai+6m0҉ISy$|hLZa #X$Le .>R-* JOHԝFh3i ?RT RS⨔=C]UPI'=SQpN~GA9U+4ϙj?/.g.0iо]&Es4R0_E.c.& 0HKLU18̤uyevzw!h Ҷ]devS/@^M gT[՛.%Iu|?_BU&]D' )+W65\u-iq:> stream xڽ[]}_QKMݏU`[( $ l=$zP%]#9zndP= :[n9JD}Q򅥺|Ԓ- c1$ 1_4:VHFMԛ# K\JUKL;j$ւ稔Ձ l"+MRZ$|jIdnK˧=-#ID%IoΙ)$IRI9Ds&QKIN*+.?eNUwYRҰkm"sMi[ir枌'gɖ}+l9+dC`źn>ۏr)~l4T7B/PN᱒a$졚 GњzGQK̙jK M@49^ oTWrZAޱG4ݾ|ji gr1[':4ݹ%XO1ƒ8bV1 Ə K[S' c\۹4Dž`Sdvc^º-0vGMJ":߰,oãuc7YbN3!%_=0gN}:}tw㿞?wtuAj(oN>k?ܝ~^InH\kH`6={N?ӟ_=_> B(WB9G(-3geA-7;Lp ɪhgOXpYfA]YNJX^YpɵWx^4:- *RsV?|7LJ"o0/rAg):T~tzE:)@^{t3mw<~~oiU53Jy&o$YF^Q:`'-;MՎc"(%歹܆-ǒNA@XY$I p 9eJ{Kv̈́̓D ?+(:ɐ|6RiG"Q $*:;/rmcM>[[*mfO;~$ Y: -;@ԕvl-hn+H(~]IH=X~a(u{T N#tE'3\jtphj LFWQ8q: ) rQ=4{)`{уOۅk.M%Za܂]ۜ1JH )(/"$C4U6Lr<38v e֤-<_*.c5~>A3|ZD[eYx|j܂!EwPglc9lՌ[P@PUO>4΍1ϚąZV ?2VYKUYGWϔ,i\g^d_+k%. B`sPPPPX((, -[ @nr -{ @r={ ȇF @<yr((A E"CġPq(8A E"CġPq(8A E"CġPq(8A E"CġPq(8A|VVfo fv}u&seޅ,P !@ҷJ/$}a=*A{ffs&=p'\ksCD]iܐcA>rA!"tI7"Yhґw#X:C*iڡ Pq 5[>VcaOJb.h'څ xÞE9˽vEDᕄw8]5꘻h%shn eb>( :R rziACj_m=i9+M0yd";6z:\((>=gdͭYXڗ(=k%xU 6"R"[ntb!U "-Dc%Y:t] a!qe|L'"g""T[zˌ[J endstream endobj 7350 0 obj << /Length 1264 /Filter /FlateDecode >> stream x\KoFWҚ=6i-I JA%Kr)J37O>L'{ )7G`o>>n%G)}>}9B/]4 ӧhOpu|-/ӊ$ocYOn5D@^Rx98*8YP$f> 3!>|0>0Rl0,4 _W0Ld4{Y>hc@jpEPa6\aW"W4}W#Bj;h|h^v`32 QX>0h*a~j{/^w*P+=SMH*c!9XmX ~ :bj>Nw3 +[PQ|6,G`h04@Cv3`RlKJb۠ 2cPDR%ILs nVBJ2@i J{D= UC}p5e\+D[UdΘc(_tNCF|EZ lgԽ6P3 'NƟONg[ {2!oLKAb%u:W:g[`Uy^>"UkW d&qymuzQQtEYRU.-)NapMC)er$a s1$,cA*Њ;E\(}r˹BHw~SdF uo$Ƶt}@*7k=V_<0~li:\̕Aqj|j^өHҗ}N~[y@Yv5A&^w"o2ǂϪSCf> stream x[] }_QKRI0 k0?8KX,1l}[ݽ|'ЩXjJR+5 )Tj%gjELhЃP ?MȡjJoARj 8Rf !ئfH6Tv j9VngwCPg/SW2ԍ,3~P"i2l2l"RGt-r$ \QQl,X7E &gQ8:[b,,nQeq%dK}΂8rv6Jعxcmdy lnIxic1XObnicv6SO}r}XL>m,}Xݧb>m,vw6SO,v6Ki0XOݧ}XL>3K80,ݧ}&`f8`ݧ}&`fi XOLz>gu3}gfv3Z SOL}:Lk80t >0t 280;Pj( b(@A8i6}(eၕe=D;T>PaFQT{>)0`q3O|1s YY%$"m})3C0i#T\z+DDGVb Pq%,FفxmϕPrOh r ,. O$QCnIle'!HMg.ޫrnqwT{a'a/ʙj#q9tA gFrwKK'!f~x=c(b!_ۉ t4J"':2 pd M}9x9$ʙʴL&3_2`$5OI"w'/ W endstream endobj 7484 0 obj << /Length 1532 /Filter /FlateDecode >> stream xKo6:@p&f7X $cԱ ~ҶXAk!B?3Bq@g³k-Kb*p(}盏~kVmjzG y|?wt?ZOY4[_܏foxrMO~gX #!+n?GSV9`whW Nv#Bު݈\+v >?LsQN"#\*/z9Kbvd cd#CULFnb5(dτd£a52h/vbqvD}*1@Vh٠ZOPMa\t.9r|4?O%d Gqj4ַҘ Pu$gBYd'5dBjqtB7*e]hj9/@:P͗~pFFXFY-NR X+tpp۞a!~.-C3}1=HV=x@Ff+S.*ۙv&%ҁ83.D@˅tKlяk IXeP/t OwXuv!~dv`y6)c=d,t3 ~#dQO@&{δ t>79aUx{ bd@5p9>7}_[pTmZc@9V}s{ҟ.ƺ092=D7a `|UĢͭ=/~։*oC0xV;%C"-ww t%_Vŝpm.ba [[h<F@T} 6S8~IH{w&맡yQϷڶPk޷ WTUz;PULjxD&%yBߘb97Gtܰ<pU#AKI-J=O/oMԆ%kkZ_~ݝ[1\%yS6OU¯QѪv,{h G[ GVG!gUÿg}S }R5s%JG A^ijѺ"D@)銃adv^HOsxSy$[&e?< ^{TfI=@:)nߢ`?d~ Sqm endstream endobj 7352 0 obj << /Type /ObjStm /N 100 /First 1022 /Length 2666 /Filter /FlateDecode >> stream xڽ[M7ϯqsQ], f}TnUO$z+Rz,0z \$43r(.Zky\\Jf@Vr#PsJaQ,J6+ꀂ%u UgVw.u|Kx, @V9q! Yo5d]-!r+ cP wG=1)wCalcpRGm\A:ShR 4ZR V*jT`o3֢{s2;4Vi/K V Uڳ厅J {ipqa`d ^|ą6e!op* 1/RC2ˡKo l\\.T1۔lxQ 7J2n@I3qOm,3`(J4c* Q^.hl@ Q5/`4JqT1pjZh8[h a4^ܭa[hyq8L,ªXhYFˋ5y!ITXjr~No><>ׇޝ|]BHO;;N?|rLr8~d8V;.xNo鯏oesIw7E ĕ;m 8`T&3UMQY4<=c(^tz`؟??}o?LiW$u3@Be1ٟ0xh7(VCP7͍%An\8rqő#WG\:ruՑ#WG9rs͑#7Gn9rwݑ#wG;rwկnd7 uQhn8292929292929292929292;2;2;2;2;2;2;2;2;2;rvّ#gGΎ9;rvVHn8:::Ǡx Ǡx Ǡx Ǡx Ǡx Ǡx Ǡx Ǡx Ǡx Ǡx Ǡx Ǡx Ǡx Ǡ1~n*5㻽i0QHXO2WhR5ILYn#\7d z $ hdt&umމD*k:q8ةTOV<%w;_ 2"6I1KIdw\\a59@ WM+84>+K{_ | m Vx5E-r3Nuv&^ܨհT'7yoĂ%;ވh)k5^֦gk,;խaLh m|DzGkþs5hom3]3)F_<$&X@[W^TAuM%]EMؠҊ!H>MX}Kme~^bZۭ:$}4D~dP0ٝBEF+G$xbFLh'aqa8L-<"9 ZZ H!!/~'cSgr rf|ճ_;$fJPb| si!;#LBpGe֙IlэCLqWj+f90 QrvR#3\~ ,uHNl endstream endobj 7654 0 obj << /Length 1664 /Filter /FlateDecode >> stream x\[o6~ϯc Ԭ麥Àn4 dhGW#(Y$8F\y}p\H#-F`(qJUFK{*$f˛6lsDn3}jz}=X-*3poWnT#! yߘт,(f'ժbqtY҇ d5͞_/ߞDW I#"@n~D$lUH4cmDeSd,NP@HzryxLsLIhP.}&[W"v^.+NWn)LyK{JH<@3>ƤPE/-y8F}S~ZĐx0`Ga▶GK}RX=|OC2DY3Z6"w{!%wYh]ɩ$Dy2 <4BLDX>|8’)m3wm=f"B@jȪ6;0Sd30"a_K0$yxʛzEf8 k͆WRi77s7Gs._,fk|EI_h0ڝ &XVOHFE(]M9 Ґ6*ZZw'.YtˣtoC\a5^_JDKۮ̲̎e M$B\d_ &-P}dY܎?Q4A۶59\amDsDքX\@ͯD<#?@,-S5;#F"9u4Gt%{;XU)].F+Z,w s.OZ0 }eOZǫ*|rz6^ly/@=s,qrfq?ˡryXv4f]G0|}=XqytРjH?ߌNi endstream endobj 7486 0 obj << /Type /ObjStm /N 100 /First 1014 /Length 2611 /Filter /FlateDecode >> stream xڽ[Mdݿ_eQT% ?$H2±31$>Էnӷ3V{t$)JMFI%5H d4/ԤB^dG^hix'*6kD4S1kx7kD(I氵Df=Mxuֳij^K6NX *`;%n]B/ K5 yo*i%xԒiOҤxi$&h »\9UYR.Tg=Mg1TiOZOGR6Ф ; iU9Nu8S 6v秚tZ2:?mXғԢ4){?j6*%kQ*'*TC>mT'~~ xPЙ6Pc>UJSYE%u )usz^K}Diӑu++0:rB1]Lhm`jGwnzctMJz9Y%K+nӳB6+4XpS`T`Dͩ41l5 h֨\,Z=f"`$;{'0x0{wWzaw558^z:}_w^><_?O/^{_N_fɽOF͵d*1yyz*M?|N_?3FϞ 3D_H$72Hݰ9HYǁddvK% dCjh,d-|E,tdbh ,lX y2Y? E[h { ,(XAfk˧IԅApZV[X׍{.<Ѕ$z$ȂDll$8$i"i0C+=< QkaLR-SeuZo0K$Z\L.ZFu!h+-b0,BLbӃ`6&oa9mrpU/1  Y YY Jo2Gc˴baȍֻua]Eue,ؐiuk`iZ6)2až&HԂcka=Áa`_}e:Ӂg0C$&!$8Ҩ"c#O!;ghw3w33(rE}\#W* w&IkC$.QM@Xh P? kql"Hlq! qN0?9$1VNai#Q S`Zv_HqLb"XNP^`B Eh}x =X짢v(#bVl-ulQb}»h(mVWw$!jSA"bC*C̝MorC- 86Rק'vVMXG#Xo ˅DA;A16=r]jAQB<1*4BGAAиJÄ_ 1i'a3s$V2>pG$[󘃮w~>JY]K tYIl)c}}*HW$ $tq΢OV&'IzG.j Z*hcF]0&c_hH翇j%ran&`jYl,Id =YC؄:|WV7ܒm~޴ߤiDow&V;[*=i$ݰ64]FDcfM¦_5!1EQgR;3c2&>:fިہa9/„pÏ!lQfZz]kk3 endstream endobj 7656 0 obj << /Type /ObjStm /N 100 /First 1014 /Length 2120 /Filter /FlateDecode >> stream xڽM%9ϧR79/9ITpnp1j#"tø?+wST*y?t!M 6UJ-E [(9@د(+Ɣ\w\Jě<@įJUpUwZ`6RNgaA ] \w?Kxg& B}f*AD_ ۂd)HaZDq,A8 9] ϖf^_n ?N HMXC2ƤyWCCrȅ}.j[u]҂qY4(` e/,*JuR`|SS0Dȥne`!_ZFF+> U"Pe>_R6\+_ vriqNP` L`D`$RX|MQI#AԊ*ߘ+'1KX߱b5n",[;M\3.k$%ǧO˗|<_???$D|x~ ?abDrM%*F}>} _ |~6 h Z'z1wRLGWjj`hC@N]6]VS!Q9GɽhG W;#fCs'DfyB/d`澍;KLFo^OEa@ *_͹ғ oށ*]$U0Pr* ۛcՀj qGCK;b1bՊX58}A$;!˳KQcͰdQZ}wV@h7Do6`| @-fꇉ<^c"LWl9pK`8 5n28VYCڟH ޮE EYJ5!䵆kB XAܑđ 9O^(BA{\@ԝ%TT]z\IPݙri{R&{mPC9&"7NEfyR6Ƕ"O`bf%N$i&Q.!ha8 l m@ ک oKŦmKQg =r_XPď1A իJ{ & AEͭ`PRj^3P$ ,agꟀͧFA*EOmMuXi=Ab!i?ȠjQBPah@R>]'sL).f2yjBj q?Vw %yc?(`K;:f rzFDzRx՛ jgsWNJv%P&Q (1 FXA8 6(1 FXAœQb@< aɌaDmĈbD5+ը%?\)$Dp> PjbB8ĀXAY endstream endobj 7757 0 obj << /Length 1569 /Filter /FlateDecode >> stream x\Ko6WlDZMڴh=b eCR/ID4c! gf8 Gpqzqy#H1MFB@( #x4|O}sŁPJzy C{f/o(==?>bK $)ǙdQ[ x[Gߣ@IJ%vH%%0uApou 3 :)vl5z ),b52 jyS:>"cHi߂l"{Cg 2 8OylDD"Sϋl>,F(Ɍa텙& ,3!!!o`]5+(![?:G(ʬXnV~ ?oۧw$vQq?[>$N;[[,t +EgY ٻHswCԨ*A|qL`mXZLf]@*Ð8cm c@QϺL;@ jH,DS]JՒVXPeC MC (0f$Dr}Ȇ{ћꝈ#'̓Ar Hfu7/0ڷNLM_JO^gw2y%$~h\}yC~m58lfintL*Sy.,xx&f/gLMn`+)f)|BL8̏s4/D:ӋizR:?W_.TSQ{Jh)% @S^}O]L^d:> 3T= |ڤƨs_338 q%öpj]A")):Y͍vXLA"U1BlK  }H-jIi4c!&EUiaNQ0UK"ڱjUi=ܚ=AR= ֲ,it*u8-]tP"% 8_qz*9OgJo @P *Z40 @ K~H i:0(FUTs^Ru2eu>];r];"_Klrȸj7&\&}bSH8=wl F[m(ꉵe9fQG>rv*x6P4<FAX'ȫ"XДQpS6UAx][)ޓT; ?Kدc$nmV*rJ h! /|[^=rL.+iGY@|Oi0Iܫ8^m+nfc2Zz`$}FѠc. ߐ7eOb|Df_ IX.q#ya]'ȋ?r )o'mA|nB;Zڌ[ZNfQw_ endstream endobj 7657 0 obj << /Type /ObjStm /N 100 /First 1021 /Length 2624 /Filter /FlateDecode >> stream xڽ[M1pXU, l J$`DAcXwj9xzl;~|]orLL$AMܚ4>hI}`5AO+9D( ?xm䣚HZs%c뉉FbVÈJbGXY1ت$> 9++O$ԝY!G棑D͟ȟ`J+c f|KmM疪j{jO#1TPR5 _✱ ZHM&Ԋ˜g S״O@M| mМR7:H TxAy LJC߆+ss JZƔ2D-b6)qq0j$_ _༠DD&s.Vn01/#s!uʜ`t:V^dj<&`5)Oݭ8>f,@1n}}撄S-o^9/=οnN?xA?r?nN?~~L*Y |D.й#^ic޷իtzNN~lon3 #whAvW Q0U RiOJBe 1@kvIHy8l ] g%a+%!FB!ARojYudP˥8{rq!a#{itz m5I (Hu!2#>h?uLZ1!DJĿJqXȡ["ػ 1 _:Vd]|RGղK ;̞ڳq ¸tU slU͝[ W򀡊A)NȽ MdI0gdI )Hx)"⤰=vnx^Qn\r*P8t(J]}^ ls8saCw)ʠ$26 Jb 8ō B aec@-qHJʽ@̠**'F־2C^IuQJV/-Oˁ\5E W2:+Y F8~,`q, x`!`]mnV(}cq.bdA0&٭TGIڱ rvfs :)T6JgnFl}`9`xV:8flK{EmKF HEdOȳ:X%ԋHQx!o_H \Uw`?ECBAg~Mzx>XS3yJg*ǘqi~w~!GoiۇnA>޾~No}L_o=V{gTkv~Oǟ>}wkҡm<@OaiA-1p $5A @@@֘1ŜsZbX-Vor={ @r#G @<yg4+%Ġ@cb`11d d d d d d d d d d ddddddddddd d d d d d d d & k& k& k& k& k& k& k2 #Œ~WB V c:'C P)<*F.0 {$Vv[~$H8]+[K4z~KL|_z%PLoj^3regnʅD_x=JvWo+K}aD}+KW"zz?giGȻ;fbeX#, 3 &kK,Vh~ (X|Qx۵X/_F js]y8&Fz9@p!^}QaɄ ejK_7'Wm]⚀^RI"6T;ۍsM k ]_ h>8E[߹=^@Uw/PąE(> [V1*+}xMLr;a\PY@-k_hv+JzYx+m@eW5N2O-}#A2 >=C7^ѥ$yGWci߫>O{Hl}+y_E2'xXynEM endstream endobj 7845 0 obj << /Length 1340 /Filter /FlateDecode >> stream xZMo8WMw QAW-/l5h/eɮob,Fiqfy;c:Q8A rGpt|zۗW7J )mhFnjꆢ'&XL>{_o?j=Y,Q r&b,RlX;d 8'OYdc?:9yv|`BW2Rdb]Qh1ӱ57zlN[N:  acDMFTя"J8;L1%/aW (7s9u)Nu>%r,%l-^J!:ƚ|PJ0ǿS^$pewX #$-wŒW 8άup1(ͧh|P%@/vO.aY@ vXR{&2u`*S*GE?B5 fjt8[[T&N(T E̟5:rZB[C bPD LQe^zB .sF2ކ"NDc E_ղ:YVx!xm%9.J-ڷ۴vF_nW*0ƛǦ_&_!kcQJY*O:_/Vd?E>b%| 6·룚뺧N:IL;ratYa2"rfM8)sdJVGQ*32`VZl#H <+U}L:1ink )dع=o^GnU*JP/l캰 !Bl RՉ[Wg9T4=ʫq6Yc2y`?Xt>.z`+oSwuŽ* ȎjC\QuIyRA"^%燘5pYfгv]h] `=? `Yer1}= BA`C D\#jr:șwwj8o(Z&K% Xj/!,RoWOħ\#2j).!jD؃%iM2QЛ2}GT).`; BY.}RbQr/dwe7HRxE\<\+I*@f+P'FZḴ]Nׁο-u~vY58cْsvoΌxff(m8\^+PO&pP/Suo: endstream endobj 7759 0 obj << /Type /ObjStm /N 100 /First 1019 /Length 2579 /Filter /FlateDecode >> stream xڽ[K1pX/>mAI$:"0b p}LOρj{>~,ֳYTR&AK\= a0 JIo+|!ITj&Bw wU}٘DMF^9*`Dd$e4a2g #`MpI"(LI|= _#MM0 bޭI]ܒܓHjXV9 7mW g X9d}b.cGLmd}|a/:$R4*瘝*ǻQj}nMug-A.kOW sKUΉ[wqpqA~E>9גVJ*C #z[hm`s *EPBHq0TuZhtTFs}%<XM$ma6ς0Q P}X$8> nmP!똍UAmZJl։!f5(8)uQxٟFw|Nnu4tݳgw7>{xx|;Ӽ/;|o CywҼ;=.qV5Y g.={ᯏoyos-=PKMl ITɝBYI.$zAb\6I,$1$yޏEdX [VV(/Bڨ2YT#_T2Z2rlHuU+^pB(cJҀ fFT3\$Q\s{%gQC Eɤy+YJ#A1UnrR SM4\ ȳa:=+%ʌ"B%20O}Hv(,;C5P2FZRp\헊 zYN$b3༥Y-Ez2;C>ʊxuuJ\ /?>~x}txsSzGɻ7;x+_??)*6_,w%8DG$')OvN88qP 8q@nr -[ @nr={ @#G @<y䓖rŀc 1X j Z z YYYYYYYYYYYY2#=T\:y{<[j;y=x8x=(~~lNfflm1KT} )UDU$J:Ք7", +WJA A Dm~̼n$$*H7I-/jj=[GnoXf7Jv,nrP?oR8g~ȷ^xOk~5{1m;  P_rx CÛ; BQ5?cBE-qWzOeb& ފ0^^+vo[ʞj=_+je@OҸA;R1uy79> stream x[o0)w"TBybCݧ ƒ.28 A #s]ēL4«$ fwapfz *Q- dbΏ3{dv ZɸPdx, GvXIY|)}04'Q Vtپ0B\OAY{W[[%÷H@1,'3&U#TVLTJਬRɶ*yQ1Ps"WrMTbG@}V&CGeJnTmdpJlPuzD/UH @yyZ` Y=vI\Td )=zpΚ&^G3SJ#55L e >cÂxkuh$3zq 2uiɬ~*0jY`r(K'I]5.KДƶ‚uB60BuS-=aHnũ9NބwwauKs34 {-lnm[A\}(L߁5XĶ^.^7o[\`D@&1jy3J I;$ N3j浊'IGGW!]EJUwVFN>6:}WCڠ >eqzEzDɨ\TN+ZyH{[Tѳ^:j> :5 endstream endobj 7847 0 obj << /Type /ObjStm /N 100 /First 1018 /Length 2504 /Filter /FlateDecode >> stream xڽ[M1pXb  H!"/#Ʈ!g-_f!sfM[*{1ڒRRŏPjĀ*Ǡ&$(HF\5 *(Qoq"G51q,Jۘ^c) [ doN1@-3R%5S%Ԙ˒j1jeЄb 6BCxU)>fx11E\bIcFIL=$>kUSֱF@: O@z"c>ԂM2ǒZ)PZ$#D*LČq; x;:Ư-`IXp5H.i= =Kws,$睁  :Uݛ J<aJr@Q0%*,cj!.[N?xJoI<yFRƛ’~$Qw9!jx]A 9- űh 4jeFV0G&[6 gjUVp0؛A,([CpFذ'eHH("Z0M%Qzev]l=siCEn%jӈIDoT!~t^` ?u[ad/m !^Ș*; &)A`JZkYHDKUɜJ9Bs90"=tu>5}^Kkw YUPzϼz?]-*)) *DD}53ES"6^0|U3#^v , ?; 3Y]}w;tb512h)#m}gP]pGۦp{^@ ؕ?[KEDgh1 b#$*¥NB$[I\mߑxZGV3!M/_~y7~4@_!R!>zeb/∧e8{O/_ӛߞһ58ޝJOTxO?~KCRM?~ xC؟8b Z2ˠ99:2mtl&r:u"D։Y'Nd:u"Dl&Md6m"D'r}"'r}"'r>}"D'Od>/Jh^99hss`s`"DL&2Md4i"D'2Od|F~wP's7ah#"_JkO~\3FGJLwxd43Kvff+Ӂ$$"@i׺d|~@"Ӌvf4(D~M3Shh2Lqh-W2^$ h〔8^pu /$ TʁY5L_Y0y^BYE @xvN׈'},z9|V|6r(9RЂVaHͦlܖ H XLaI.s@ew6L %M/TB"XF760}1am''vs@`dZLCj($ y#.&B\w /z{4& bDkAM4BD!qkPnr#GE|d\vD)$qhz%J-ΪL *7q7H5!tđՏ"3!dU e JPh\;,= D 1c7zMкc3 OnG(DG5dP02.Zō&tkAB4#Iu$8DE@2ƞo`YIɕMYxJO Ňttߏ+UeYws[u<,S\!G *5qBUgI0PkdEMi$. n`_LHC;u܈lCtkGTxY4 {pB%ڙǁiMםD>Nnx endstream endobj 8024 0 obj << /Length 1385 /Filter /FlateDecode >> stream x[M6q\yL E4Hzp֪cD R-t⍐5>78X8x}N@#-f1LR`) f5o7wRzs?aW8~sǠ0~zxaJdk78|n&ۯ6c۬?MOED_L<5s槈:xOV EoKØI~`>> O ׀i+H@Pيtb5_yQiCg6Z]} wȝ6oE[ГG$fEZH{P!4%9ONXYsEL"&11okN#!ؠc{,yj8ƐʼoT8aݍKq~jv"O5s: ?*l`ƎI$7|/5,hҡ\1& Դ, -{h_ R!-]r [{ Ʀl"lhO#F]K߻yRV}yR7IB@9*RgJ~M~,F,-p :PY֛0!uF td/ѷ0wDӜQe-XuBszhes ш/ K"K'_nftTIB"Ԑߢˢ_r = *x^(6ܐw7 _r퟽.aoDk<9Ga @بBz Dȓ&10TbsXC"Ȁkc]1c*tC9}e<~_/W/T@",`HиP9%d.Xjb&ṋ E(Y 2$ "\YzDɧy^](abAXB8C#KY=|hZrxͼI8kzzյ^.&;Iowr!}*w9qH U9#y-af9&0%Œ\ƨ:0IeiL85.;G;nZm;jeX}g0-= ]8Ry?yjM vyڍID OW k6aKk!]&5[G!>2`3$|j2/+F=;C ʥkW. endstream endobj 7931 0 obj << /Type /ObjStm /N 100 /First 1019 /Length 2448 /Filter /FlateDecode >> stream xڽ[M1pXEV%@tH"ȋkp}^8 Z4X,rj=P{JrVƣdyTj~hhYQ%j8Z ^ad`āj64ʁZ58*FAKSn\Z5pI0uO9n)c=S8Fr.ƅ{ȥh! Z~J EJR(m%eO iAbB")s Mcҗ9+7w(TxPAm2  1C` e+xMƻT6 >vc*-4b/4r7@51Ci 6`- cAw Zw{F+[?(7y@j)ڬYdNf^:(?,f+L4frBuhRMb3<Fbr 4QhTyѨ`t>&!h/@d#zALCĺth\qCti(Әfi4b\L齛I3_]oX^xo˛2><\~xw !ˏh|xKxWnjJըB%f5l:6R>x.oOoeoKc@j̘F{dDId /H Ji" HߨCA14D`c7bB:XnZpv̂DxDX䤖8q,ņ%Y,X,JXmȜ͂4 ͍W$<汑H?[!E[iWH]lR"H~6 N]!%Sl NJl,RE6\sLdEF9`eWH5,tcOWH17 !gsVcgXڮ")vP; ,l|"I6f#uNwSjw-=[!$0Ƽ+ay6 cֵB+``atB^w#SV7f({@}Jzj mi|o>\^|.o@^G峕HOw|ǟaJ:7lObHZibFemdool}}m #G.\8rqőőőőőőőőőőőՑՑՑՑՑՑՑՑՑՑ#WG\:ruՑ#WGn9rs͑#7Gn;rwݑ#wG;!6 zzyÑɑɑɑɑɑɑɑɑɑɑyA~?'^12) +u*g̅jVThD5nq{#kUCyR$C԰ss!IҼ`D΁$9(@)|/hcZa Ь`A_M1u$X$1~NK0m9do{1;~r@3㯤MSoiJ e\#BEt=eEqsl$k12n ";))SXC"s>$2pLbE0ٙn`'ZlZv$ I3=Ku7LV\o!11aRC2[b+*q߂e}L!QT+xI5+NgjtUE;us q[:fQENv3VBRYC?odQӸw V.R-Zp̵Df6!Zo,* ,P^Xy12; JJ+`Ҹ5q5rCQ|Rve!#$}1 endstream endobj 8213 0 obj << /Length 1797 /Filter /FlateDecode >> stream x\Ko7W6uECKuȒ!%wWw^!3͓ ~DG.~_\*>2H?#0.GJR"w?{Dcz >կo9d:~~jqu?\nfkI{0K{*Oh+b/ti# wfXWr:~mWv˃ѣNO.F_PwTV@n<\x,[!xJ_@6fev&Km4 4 apN)fJ 04xqY~Vs9OWI3jR^)P@ 5FJHBmٔE-M81OO9_+ IÓ`I OBH,\6w hݕ1؏9$)Neݟ c D8xUSZ C8|[lnĹ +6 @aGrU=b_d,'Z! ԰2,;ozKyΤ!颒NQ}WCgYVVVtTObQcJ {ݒ1Btej"(§0>cO%=:~<4IHC{hz !aI&Y74ػNLDV#;)W9ǞAܴDivP~dG~\^TYء/vK*#C |ggs1;εnh"z#aMɮk$cȉ`-_FЅ],Ch9ll-Y`AphBuaVߚI]Y71₣"@1~=Eu pI9@/=x]8~ExڕV8=t>ս+ތ2q^p`TSmGEx 7E;j;ͬB߰b»2sFpYx3M ^CDw@S"XcfxE{p4B%WD.N͍bBD09i:Tw΄3T? ⍙;a2ŚK8+A  dedTN哀kA•:9 y(k5!>aRd[JP.a-3@Ũ0B\mNn[/z:,aJ;{5?2QaAG wu*1Al{$}QNUlMaE?׊6w{21|c/!H W-L6ݳxՒ![4ʊF'uc1 endstream endobj 8026 0 obj << /Type /ObjStm /N 100 /First 1026 /Length 2726 /Filter /FlateDecode >> stream xڽ[M1pXU%@tH" ˋkVݯg}z4z*SҐBOɂz#%بިhF toІxc IARޒ 2-uHP? 9H|ռՂj*˳#V) ]jъ>Tj@]Y9O=#nl)1"_&(:5 Śˡ䖰J5lI[mǪ_@k*)TWgYaF眲RA9'r.6IO4'`ykyV?QRhu^-ZWbGP/p7*/gJsYy`̫Ɓb'g ް&3rQ5j Mkb/iW#4\Fdp.HIݼ+Qq/ g ĪiMpޤNm79:zSYn@o zӼ 7-:zS7ћvs:7@:bi"Ir66ЛPׄC\l$x%OK¶hC=<]O\}իvN?ޜ}q~/w9}Ç(>r2ܜ~>;KnbrIǥf]x*ޅӟ߇>6MۏZ4x,<6ib!16z,t1)T5r)/dF?vG$!QXXk1#~GգYicQ-܎b)SK *`6]`lr,R"laUcAr]"}Lj%$]9"1m+t62h}"MbAk 5"ϸ/AKS3hx1Z5>H`H~w pzcG{ɛn/_>ο˧R}Dтر?Bi:pmt6X[jlFeFd#r&r&r&r&r&r&r&r&r&r&r!r!r!r!r!r!r!r!r!r!r%r%r%r%r%r%r%r%r%r%r#r#r#r#r#r#r#r#r#r#r'r'r'r'r'r'r'r'r'r' Y aC062FcAd!Y,D" Bd!YLY fJd%jPAjPAjPAjPAjPAjPAjPAjPAjPAjPAjPAjPAjPAjPAjPAjPAjPAjPATjPATjPATjPW ~gWא>  ՃhrH+z#EZVH A5T.n0=(Ӝ,s(.&{ 8K`eYNo,rv4w@@#-"#9E A irk2c /z+V'5%X%w$Q<(3 rBm:t: ۑDq=ZIds} _b6I(j[WI=#nZUȏwd1EI[;h[4_g{W @9fA"zr귧B̢3X8"^W :B]Yx3ĞBwU*X$==9TL\Թ΢ٞJ'h%9\ec:zWDWLl]Zm}OKwK;YE9hz8d_'u#l Yf*6Pkb)Qg8Jugɘl *&DQ!w\:Q'#5"dcm,j%&5\Yl[Õ~xoyf i~샖T.0r%0`О款B%.YBkGت[PHv/` d۾Z_t]N^/M^.9/01Lxuz3 {U"q9v?/&sÿ]:w=ڏn$PU"F7S9|hOEs8^/0$ݷZ=sX)Ȳ2FU{4ua9Ў)gԔ˼ge_r*_'H+WIFb]м&T_X YuAӵjOҝr\;kXI˙ OkHbju[W3WFJb]|]Lf7'#E?W|bXN1v?X7 DQ,Cf"!PE{񥂣Y)7WS"#8JhH/'ΕZN~h~@lQ#Ͽ'N|q%lQ9FlQ<Iԏn,zrh#=%Q9+ LU,:I-;9=tÝS|_ tfQл$RG[&2~k?0kg,>?O!_ endstream endobj 8215 0 obj << /Type /ObjStm /N 100 /First 1014 /Length 1953 /Filter /FlateDecode >> stream xڽK7+L6J% I $;E&mȿ)]I7f! [è[_=]b`\A\$Bv)+PX+ OdjULOJWbd%uQ)[XZRt)e{KJ.Qz\66wVOl߀)V:d(8bzI1>J4h@XЬc>8}/!LXb{:lqpj8:qr$ T bىhN4/ zIUkM֍(EYk\&,CCemrm])4@H4ޟN9E8UZ99SerZ tV~k]%㥉=WI^KܢaMZE|~ -xiZІ2>!Ԓg( #_} t^O߹7#`/xŸ 5& ޔ,|@_I !LTu#Iԇ+B!ʞA BRB\|FQu+1-c\bMu#W&3{ι7di~Bd##HENâPSO3Ը!#DX+F.23 tKH8(%|vV6P>@p`^jG> }3>kyX C f[NOP. 6Ebr4t2`\ !JμsJy0(0  cs7:aԠ  egV''S>ap\[!vv$΃ݒh]&1F}od*#ӻN1 ѫ3"qlBf,cĜO/ , YW$ʎ0r@3 \2p0rp(;B|3t\"%W z% $ iIbs~L)E%'D5Do䚡Ѝr Q~))'D5lнrP~w\3~ --İ5D=`p,s7ԋg{o>BotTkr:Ž[LSs".=aUDĚs0T K9,^EU_jtJtP )v)5E= A1THJŐ":]CBUsj&_˕]P< A18p1(Pr@buMuP .)`.%Xs%*|@"bHdMHSL,)MI1$C"K ]"kr`,c,[R)a-Z T@Dj1s 2Pسz\Bl l;bx Ut)5ֽB|@$;#A0 ~]1zF_]y%CyFZ֭/-.RĜY[Xv'1Z9Š>F)bIN1XS9Š:]Rl=GRTiČKX1OD@n"" ,B݌3&8:b5K,L;-_ގhwc {iQT^x+r<"Ǔ^-M~(d&B?[!lGbX"ˎ>0Ɓ؊hj:կ`@; 1rs50|f QfZ(@ endstream endobj 8357 0 obj << /Length 1709 /Filter /FlateDecode >> stream x\[o6~ϯc Ǯmm6ް VSHΚ׏i[%Fib!F!~)8Og?N..9)8ɧGCMf0?3RܣDB ҄6zcgP(xn_[D[E6(PHtM}zQ'= [#8JgqoU:/l?Q@2df۷ n-DArT&ʲڒ~؆J0ZSM c48( Gz% pN"[8A*#i(@ a zR=JM RX ͓aPag9o4Z%l1 bBs6tcWxٌ5TMocv8ݮtd_/[_KPs~ĵ6Ehyp6\u`m|E@lH ;q[;==|d_pNN%^.+4e(rDÛI3'E'EEYDWz{x i?ۛTEUA^'4O3Z#w<$`ni~)SmHȘ"C|:XKU|ʏ8&C!XQUdFȄ }¬9W򜶬RKr\3 8-0:#."4@@PukGIT``ͭ[za$ MH?N pρ} O8]O#*+7bEA{p.R[U6!UuJk\WUH6I|31Z8Z]TNw2 0|HI1Its2Of', - .!B!1"plab6$TgsZU^-M2Z.K.Sg8觿U!4 $mܝ0!=5U@c@oe4!!*6YcwLJ 5|1ϲyrHAKme}g\`{>:A9*äޞ`1"<[P#6iDaJpWI_EfQC:# y48u߼]ڋOPw_I MՂ,D `5T;w[=KɄp~bھv(ߚpd;g]>ᾠgH/`L`0/DRS]& gr'2 fÀ@fcLf |}m.Zz|8u e;HǟyZnZw}nr;U}i:7_M˺ endstream endobj 8216 0 obj << /Type /ObjStm /N 100 /First 1021 /Length 2693 /Filter /FlateDecode >> stream xڽ[K$_eQK% LH`p2±/518>QꅺaԷT>T$ԩh,ްDֽђꍞ#|Tq>O,uVKCD4Z-0z"5hhuv DT褉e oYb1%n6}h4|4.I:2yHI0'QuΘXw1Mu$C} nIK(mIt'5ͧBI:+}{*T%CZ2>st{:3sg]Ԥܰ0` m5x=ޜ_Hgrs>5LP#P cXK|ASGs0@I3Qmt4\&i)A1Jkh֡S@&^sxpErg47zXZy7]LlVuV>Mc4*00D.VhѰLl`4Hə .Ыc4Ҝ&XYP!,41[q8q:`4)n߂{ ի9>}_qt8N>B\YȮФ COӫWU:t"oҟ'<_YȮ7Ѕ,2ʢ zD\7=״CVֱ`B}Y Qh( EXݒ¯br*F;$w"E"@N_pM[, w5|j[8rz?qz廯A>|:~cz{yɧǟ=6ߧ/{oxo?{5MI쎴K}@oFr5ѣ1 >TAhH44@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@nr -[ @nr={ @r#G @<ygCܨѠhp4$ FFF 5q 5k @6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a|wkKHu`K Yjvgb<_y@x_-KLAVR|Q3yLb8,g/.,g{Ѿ-LDg4~Pe#ccai #^ӐC:ZGQ,,P6|+R{rӲ'.(smG)l!f&FIhE>2:"9S]V90li)4$1K3HaԲr!tb#$7pA32s-3KȁVrPέ]|9Y"P2ivHv҈{f8cWE# [Xo T=[X!@"paTw\5vA&;9#v0#*KE>#KByb9ԎI,U 5FJT";;@ͧ/$!h!Q ᡳ`p?(}e}/<%_YTʾށ+EuP&y4 z0]I2G@!:r܈/r2Y*#+Qės7LH_ z׭| endstream endobj 8414 0 obj << /Length 886 /Filter /FlateDecode >> stream x[o0+xܤ1?nZ[u:iʦMX`!QJs !JE8|lN 55G泥+HdhL@)19R"LfL]݇oM?^\!% ،58TɾY7>6cMz~Lҍ:ҝ0B}_?QL&1!ig)XJEsT64_GIzD +[`b@q]]%Lwb}2ЧX lZl'L7Ka(iC(hTj*eђ]@Hb7B0S %g-<{lVz}f}G2O1%A4b嚘H@,q˅?>f6鮞]Lږd+_с`fؗT׵ ȑ`9gN08_A p29$ oEbQ~6XHw b4g O_HWX^P*h\:ir$gNֺ##%F81vWs&4=.e\ur#jChvP09BO:zL*'E۴*Rz̼< d?mǜ]-D4E_D)K.0)1bI^`/hWKdPH8̭9$.z+kh^;UE ^R+#HU!( ;՞zfAc_A2%@r/y] Z_u+Ff^',uPZ:h+pu8Q[AU(>!C_41`Ebۊ{,-{dySh[9X/ێ5 endstream endobj 8359 0 obj << /Type /ObjStm /N 100 /First 1017 /Length 2370 /Filter /FlateDecode >> stream xڽAo<6>r8F$-`>5|pH,˕r| 3sJҐB+\64r 9HޠPo%7gVrZՐ)&w0Κe!$hQ YCnY@(/W9s T 'A ZO@-' ~Vr@~P(Pxʡ媄˳5>8-W[X`cp[9 \kV }06` ĭp -V1'Z~s˒(9`.= ܊PrJVpK%UZЇpn99}AF$UѨTǾ֠\U,>feч$y>\Oi> }û> ёQw9bT[0I;ԂcR0r0CfNFHiWjpք&5UU&0mG18lz}$,z ">g[Rǃ[@oHGgpd4 y8fxxQ[n@od+zGeo@dիv.?\}/w|Ç>^rx1|^(*sL;%bU ?߿O}mĀ}(Tcl 1y(f ؇;xBDFY<4qF0EƂEPԙ~Ѣ"ISҼ6P${ǂ cૃD'Q KEODWĘ!_O?D9V8NQK.٢a喖A3:s(ZH +@wU2gu,i 2VG hQ^v`OCN"O \k8ŨI2?wp]tR]|zb;/waJ a(ТB~|57ŘQq4z{oʺ1_>|o>NG63( j%-k7oF 22u4t4haYeuXaYeuXaY6,a mXnr۰܆6,aنemXaنemXaن1GFF 6r^,V o HPªS|0Txtex0^ @$Q e 50+@ /:*uo+]c:Hҟd{3ǂR2ҫU/XPNzMQhdCE5Q|]wkuMMy)O( ۹b]PG Z!a=hINf:RX>"ɋs!C4 |.'b6Zbe= zUjkR|'z'iDD&J(~Sb!gY B7;僠 P$!'q/MLeX#4vx/A{1vd Do7-ד! hCakm HzP|+G~qfX9ilqC TQk'Cv !6CvU CvUmG:(4U((Du(V6(T\eOzUa#&6aaÑê6# v!áʰ`jXM-)*6# Vp> stream x[o6_pXvM,6{l%1Ȏ ѱ2%J6%q vFɛgRGG<>gV%2B)CNbg*ϟ/b浟q6MeSg$ؼJ'QH2 f/6D@TOx,.✔ea󐁔`\ 9o?}>,zZ0Ulf0TM(ߐD G|V (iOP1T`āh0 ˕v44VspX#{Q$M]98&%_1'! 𞙨vH4(Qh, W~0vAHT 'gN%kvS 3<.TaA8;$qhx)H #P3!NFByǛfhv`==v:V˜\?d TAu+Ϝ^tƢ3%<@l6їx5M &} jEOWe NFtA Tj6ϖ6b(\u*EJB&5{C"=:bGTeq9WQrZi[?"E]ڙZ5VamRO0.(Zē(V!-BX0S@Xi`K"O(DEJ>hh&_]B! d;U8WF, j;;b%ΙE?YD<ϊ:ʟh" &PWplc9R>9I,v.Em!<; | o!l-%=U Mkn Zc'GeLIY,X$KR&%"P/D 1yp AN<)b5II&;hoMY(3G<|CggI* ߧdYCҒ%|akC6}@Uy4'[tn owEf68 _!7H{!7ٙJw^PĂ?\bPeC\6oB'A]]m QFۼehxKOP̎Wo]H'}zng}ۼv W 鼱b olen9hWu8r_x<(1z< vhsZsW{ [te^C{A^ywqJ> endstream endobj 8416 0 obj << /Type /ObjStm /N 100 /First 1025 /Length 2590 /Filter /FlateDecode >> stream xڽ[M$ϯȣ}ȈX 6,=^^ FẌY_dWTKU58@SU/^eNjRC M(b\ r`Д[T/qS TyjlCNI1)d~+rg!Y`'` F%.8b8=0K-g*nլ$Yc Bbָ'j^RŬqRUIA1lt1~kS]c@L s:?f3nFn_}i}GΎYYYYYYYYYYYYYYYYYYYY8rqő#G.\8rqՑ#WG\:ruՑ#7Gn9rs͑#7G;rwݑ#wGȹˀ|}>Jɑɑɑɑɑ=cP=cP=cP=cP=cP=cP=cP=cгYLÜq*OZ塚[;ӼFˤsTk-*j6X$cFrr9x7M,T#Q,, xAe@D&[~Q^bF6YYQJfQ)vdTgVBjD?ra-RX /D92jmy„D-}> ԓ7V#vhUbza7u& Z( Jp-.)8cȌ2o$o@"Q4lb KrqB4 =m+߀r$do.i/ڂ7X h l+ Qv0µ,rO2W|aQJ֏f-bVP:,R-Bx+Y܄AJX\8t0: 5߀D߰&YDkgufbw3k& ث[8s,2O$aLBca" nY6B`A *\ r̅I3+XLu h<z}4Ոtp.$H@ T$S ?7[uIӂE{BA-Fb%]U犕Ē+vI\,Jp9#PPUsW4&QZ/1h9ҩM)r9A62=HBqt @Z)./`۾P[9Yyyv,&RTGbjd@RVGv Y5ӖҙMXɐ6ޙK/rLu-X.h 'Kbg.ᱲXcTDʙ)ejmK)i:g \V:\]e>^]Q9~-5VKк]#>]7 X5+"jn^DRDw9t_EW(vI X> j!z7Ic4NmO0bӵ̌u<7:,xҵdX7+ =m.}fa[pS({7xW3BbnF7}| =|$!kPd endstream endobj 8617 0 obj << /Length 1133 /Filter /FlateDecode >> stream xYo8+6#-&@ oEwTKqH%hR꠮H*ȃ|AZlltu͙%¶(Jg}zWwH R#GFv"ah˟IyvR$lM0Fqb!ڎHa|冡F0Hqu&EsVY?N_O0T3!z 2&6L2mp~NScD} I̮ajKպ_vӊ!:~*]o%Fz0\R( Wb*BGߚ@Gh |eM/7`HH23{fA:o4);y]4:ELn)޳qhHHJ##pD%o#6SV,U "VTs{g!zd7ar13qw[]2y2*= /'y$95AD`V ޼,;zm.>jAUkw-e yoZ4~Hgw^ZxePtk'HϻРaE?Rq!s) N @2 }/$gp( hѽŗ\tј`:AUg#nX}tW@i8AX^V+Yw7YF J+V)_%?_FYŲ endstream endobj 8541 0 obj << /Type /ObjStm /N 100 /First 1018 /Length 2483 /Filter /FlateDecode >> stream xڽ[M1pXUd  H!"/# ׇ졗t?.'7TRoĉDBBIChɸFƒГDv^(K6P&"D]-$M\ʸ;zb'! 7QxV r‰{! \#w$\r-I; RjJ4U@uXJXjcj=֨Zj|oOPM[K*=4 ɱ--$5)%u;Xc䁧5phbUj[ajǎ-esB<,,y9 "հ.^ױn9:'+%y{MKbxC(GFՇu:jp⊵NtJ輗 DTVC'D&DFFZFk=A11N b5wX|VcN b5v &|V 9jRaCύŋӛzN~};}Oo Cyw//-\&Q;` i#"k66\mz"~L?=yH}n7wbQ ((~ O*ȡAp{5!%;"TlF NE #)4$7 E&!@j¥7"$qIt5R$5 MfpbMT 6AX m,fĻ'#Y; Vqhv?EUda 2YIhG)E:ϱ3)\I38d8SQfdEOY,3]U ,X(!T!d4&׌NCPqEiKTAh!(%.3 ;-b1"{BE{dU:̂bkfTj0\HbeEz-\Akcq ZO` AkA6#Dǖ #t٢₝'Η-:g {2C}/ů>~6ǁøE?*|uÇ>^|No^!A=Vsns~v~KCUhP3G*x@z?_?#5N<.LNMaئЧ)&rm"&rm"Y'Nd:u"D։Y'Md6m"Dl&Md}"'r}"'r}"'Od>}"Db"x 2:6MOa"DL 2 wPqGl IB]PE΢ bR_BY(rW7ZĂBhdZʠ(#?ųAN-𢌵G|Ӓ~4R Ujqd@fV{)rZeR$ f}MZF#nBGƍfiRt|`Q1kBߘ5_8!BMq~S+(inF b۬ 4\nZbw*MkS6jtc&H&JmwDF v!͎&dc\Dv;"$bO"˓(0j-mTQTK9s#.0ujG#U}Dl'y]V;jT1A0YPGXF"p;*xY:Qی ez 0_u7T jHj«ӊ%"HUv9/XbevLlҋRX!ղC[|9u{OY5q9WtyrܯqmhC6Uܖ&0ky蛏@FrMz>r(4fz D41$J5đB^sC9\7(ڎ(zkC%&բ9H(^.$:fBN!s@ܯXɢG$/{[cFt@Rdn*oGdϘ$3,&geߎ\E4#BWR=ᦨS0*g|ƫBk#q)nh07I?7I9o8e9#E8̊#[^S35gt)<>P*tlG1Z ף@%b= TyY#f&A$XP, 1K6W+Xq[m A?Xv_F5C 6FZ+r11䱑@YY$bx;ZZ_T}QnˬGr[Lx?悭U ,dY"~"3Vx#M#_s<Nzi\^,92N*B1aPElSKs Qݪݨ؍~Bjۯon!X79l&?>4 endstream endobj 8733 0 obj << /Length 1572 /Filter /FlateDecode >> stream x\[o6~ϯc،x'_6CewAG-w4bّd,Ri!1ύG{?]\1I b΃0ag>yA_.8=8JC}3?~qE` c?^oL{L[ voR=<=3" B (OAh`1!>!F"6i#83) )VzXGHFbGLr#(Ac%5@PadN\3PnckP P~!Yh9j7#4J6uCx~nWrt(8hp096%ٰia36)mbs!_e({y0_(_=htz6-WoW]>2ș!2J!%hÍuPq-ka i4afOw .ֳWӤ]ޯaq`)cN«*B l q(<\I~)Y_lMjNi|/R<= |U@;g4/{::'|3vjWwmIJU{느LzS\VdzO:0W|p'un@ OS RMw]y6ؓG0>'߮M>)+V1zhql8yH/^loziu(7\oĥrpXާ~Tưqv#eKkL餖 gCu) ЯMIrp=)*E\o'4GID. endstream endobj 8620 0 obj << /Type /ObjStm /N 100 /First 1025 /Length 2658 /Filter /FlateDecode >> stream xڽ[]\}_яKOWWUW7m$DA`bvTa^X{Oq*7X|ln\S5O_uR"꫚IzU\7jE*Y,U&UOUeՑp(Lvq'0̯cNL|%8l k(D&HL41TQm訷it44:s@ V _} i@Z$!ėwXB1 NOyG(Ѽ 4ARBbwd,! }< Q.݋w7>~xx|;|_O_z?x[$?r-7w?jVI%3pa%N/^72w$髯,^5 ߥO=3Ό~D}eIx+2 N ?<Wק$BGψO7*E(~ L폐?ӚXlh,Z,,=@@@@@@@@@@@@@@@@@@@@@@@@@@@@@nr -[ @nr={ @r#G @<yȧ XXp,$ EE S S S S G4y;-rĠE ZĠE ZĠE ZĠE )R+i\i$-9s|a'6r@{-9KdQ #K޴"𞧁|$!{%>@ JjTvAdHTߐд䁤8F_fc% hxњ Ve˂D$tg _o$`&I ghLv6"6&1}Գ5ЋQw2PA+c'rGMڲU;/e'k 7fRT)3xQ!pʸ` +8 (g}]Bg/QQ*LB%w4/#$MqNڂZcos~NBx;;`D:gs0.L8{ _ iVbbduj1}cMɢٸ_j蒋8 UZW},HTtUma_Nbq1o$0y!1ntz_2D>D/ $=M 0 RL:_` O-7Y[X"2U9RʼnE% ?C&>pK)+s7Xl,XAYA viDW1t$>tx?U" rڮo SqlTNF}vF┳`Y6ak$dS+vp ҫ Q Z6ѳ_F^'r,&$rKX"<NQh+Y(rL+X*jgݍ^˥Y!USws Yl,N ,WY6]1|Fu8zi_;1"N,~dw9^嚕OueTdSko{B|0MΆm7X\'gҽuAκz d% b֓'A)dǤK9pY&+> w*"ͷ2ơH]Tf C ˜@^UrEAXl jj|};((,,0w4Oܓ1N5|>\ `Q7H31rpĂ #l@O~3<ُMXJABơ"@6 YTh3 z+ò")hGœgKϭ?mQ )7~-[lXD΂LwU|*^"2og]g`!;g$,( K[Ta+ۉg%GEs( S:6jFbm&EA!sKc҈/\ 풍/x0t~UZriT]o}sW3¥ =7 c7\zTĹ8F}q`s.v;I҅?8sQ!= {v]o1rʝ ib#qکJL6⻛MPYU4Y0Xo]gRVK?'r.xLln!QͭG/RL61\'9nVR endstream endobj 8800 0 obj << /Length 837 /Filter /FlateDecode >> stream xIO@sR2x endstream endobj 8930 0 obj << /Length 1298 /Filter /FlateDecode >> stream xZn8}W1 mh-}ڮ#Ԗ ҖJ.Dq,!BBqϜ܁sG1w_! ;CvS_^ J$)=~_o6%Ə/1z- wݬ]&Xm0 '1$C!Y1eT!nr]S[P& ?6Fq[U=UI$WϻIaEdWg.J)&|&cJ^b2w!"x"+> stream xڽZъ}cW**0 k0?8!,Yf{ ϩt_3!3::]RTuSN6H0,IaxINj%naH,a䵇>R,7z@:2"Rw_#R}v`[zDfQ#R}g:egp) Jd=sFN?ֶY}ek,[۾2}7}ۡ_j6> 8}vje2 Ddƪ}2 lDG*D4zrhc.3Gd9IZuyNWRhvziq Tc>z |'rɞj,Tg$֖ 7=UE)yrҎI;*擓vbEFH|}8Dau[ =iGurҎ*Ꞵ urҎ"ɕ'J|349iGQ򞴣y'3ߓv`&'ؓ?9iG&}OQNQ]˨T''(z"z:9iGUeOQ}YݐX|*f.Bghэݸ4B|1* ht(qubD.D.D.D.D.D.D.D" Bd!Y,D" > stream xڽ͊%Z]şBf`lm3coW2Ȕ85ꩤָ$%- p$X4ԥFjJMnVS(Q-%N"QDF+{,1I@ukKZiM6F+Z{=(')SIB=l&%6&WO J-I6'S+I()ou $[&Imk4iݟZҝjҾdŶZ21V$&{YBS@g,EIv18hQSeY W#1}DUj/Q9yѰ撜|{OԒ&7?m1ذ=yZnl,$[݆VPZnxn< 6Zm-j0uvN)ƠKm/&wk *D9º U}T*<vJwty-(…=Pc8pbX#[50#rޅ5#kAv(Fc@,ضָ/q_5) &ӧǏsz|ooo=~~PϏD?o~Ƿe{p+ FJ"xSzC/?s&ߦ{B }PԚ)O \\o X--ob5SLJXjc$KV!*(jLjY" bA%[(TZFFVaɹev/C+VhF(=j1V7C;t7+~If笡%TfmDP'%wT0gW9!?&UWe~P r(칼 *p)JKM12kk$dGl|B- cQ H-v k╴p(3c%PW򥀪9 2FdQeS0?PDXbpP bO.ªB [ !c |HtB slD`xP }PJ Dhwcaa^m3P *tײp,'E!cxZ^R+W))hq$8RH¯ґ@*5? B\@!xH`zb~aead)]k.n) U:䥿sˆ4*Yj 3 ni%Ap˥Q;)߈d}+оb3eD2:0ZAk1F֘1 `Zb`| 0.teR1<Ⱥ2<@f3]e|GBѕrzmǡ ] J/"u1 09 J-Eb9tSS{TDxm| TN!NzR 95zjPbNQ/-NQؑ:Etx3SxN!?:< 9x3\8:ڹ8kIgXSzȠ8ǜ/Xb9E` @2(+d ^sY,ל kؓwY W,A1.XOcN)lP:G4m=חjN˟b8 bp'SKT֠9 ȠYdJRYdP<{0w8]Xcz*>P- ~GԲ:Bp0)nsYzzB%:+6ByI #O!dƣ&"oz Ȯ0Y s/7]EN1 l!S؀| &2 endstream endobj 9030 0 obj << /Length 1246 /Filter /FlateDecode >> stream xZo6~_q횡ևLV{l/5ن?:lѥH& wGwQz:4RHq̣#cyջ맿߮o8 &#8 c K7j)"(RV'Xd?owJD}'q5)=0¥5,2TD09O"S$I0Zb+`(AH1BQ|*|0 4uMH/"L֫>&&XB~aa H,`{@Y 9nBCʝ±5MM&p!=YImyKHxWHJB"L72oR* N鏯(&iL!!NNL;d폔ek̐{ָ@{TVU0^ @֛rSA.U!I:f)D03d#P* @ <=|&]`I{D1 5J(9G S8"NLY)M(N&9,v3ߒ45kƈPhт;l~%&&{1=}&,vPQ]In}3RIҥB0iq{!pdc8`q=>wHFHVlkv^Kl.-29[nE|-W}ځ*!@&p2CVUd<M[U7P@@NI{}@ > "a_b #0[뷻^ NƷv׮Sg孟ujr{`)vrPam$+8:\?ak;: Ǔ=+[IDx=[/٢*Mr0"‡OspleQ,Ww#6ln_|lŞd^M-ǃH{茤>#if$< ȌtsFԁ1v 7Wow endstream endobj 8933 0 obj << /Type /ObjStm /N 100 /First 1020 /Length 2581 /Filter /FlateDecode >> stream xڽ[W\8dXEۂ H:8tPE`5}^qzuρӀaը_W^T빇Zra3r ifPDfPK5H7Η$qZ 9gzȔʚ>TLjJ*bnOѰz.,PRg9Bw(rZBnx̡$,kD e<\!5R0F#Z\9psAYU RkrjUq]RZ +1%l Е| wS7 )<&}Ec  @ά4M*ܮD c(-%(7Rp֠**AbT7R T=?.Ư hYWqj|& G4kZ^])eߣb- hx',|9Y7(LM;\Nm_G&s\Ox z0s-C- `bg;0 6%ʸ!c1`b4̀2F#CdF ^Ѩf LV\VjHV5\L\z/N}8}twzOy?~҇_O;>w7{m0E9|Pn9E8 <{ O}}?ᄏXm`t($[$(V TKp`AiP@Xd Uc>NJPVHQRJrXmM›pBBDy믿~_=>< W(eb< xE^X N??~z{pzwSGɻӏ r[1/{;w?<j0d[ ^ d"?b|YꆸɍQpdvdvdvdvdvՑ#WG\:ruՑőőőőőőőőőőՑՑՑՑՑՑՑՑՑՑ#7Gn9rs͑#7G;rwݑ#wGL!:#An7؍ꆸn479;rvّ#gGΎ9;rvdrdrdrdrdrdrd:#Ӡ0YKָ@Az@rBiu򀌉A (vy+PH5A S@-d |9ַYLT_TjĈ#݉@ mTY TSD!c XjԢ խ$0[H6(/#>gK+e&' aB`ԁ*P@;E4SC XJxe)"fъg*eJ:3M,&P5a.hQPT7OV+%c6:PASr/xbDF>&+X,A |lސ7b"^ 7'A(sͬ H4ОA3 )(r!h3yC 5%15kU/qIRq)Is-E[Gn 1Y Z3ѐ1,azW}I[]}fQg!w[oK"4!WvYr\,ش5$f&LS-PYN #Qpj=heq NԏlKpJzR ΢8CrQПQ ytKu%s"Ƃ X9X3W*5}_X`5f'kBb昭aRP!4M1ZjʚbCv9mRrҦs0y&, +V٦e;b`a],PS%ףI(,'W_f!Ɔ‚l)ªW:G' hBieumHeK(u(YdGW)юKt6%ق%*la 8lAvC< endstream endobj 9087 0 obj << /Length 542 /Filter /FlateDecode >> stream xMo0;N m7R{д,E*!Z42 _yd10%\y?RR)D E3FPH1*AҜܟ!MoN/hČF27;uh>z ! /Ïod:x4G2k/7c7}_QH#~JF bvc}Ƚ/$;<4A}.8L.:Pmiu"V6k~0 %rH4:c:E-xw<*\*x׍qYjPO! qPOҚ$®ȴ1O-8A2w ;mpX:,eҤjwP B}}ݍB}$@g v;ngwY}DzzoW endstream endobj 9206 0 obj << /Length 1679 /Filter /FlateDecode >> stream x\r6}W1/kLWhL'B"E$A4GZ,vgwAޝ0>y{.@1B@(#x0>Ïg|?(RZ6Iע="E` )z($ov5KFar3. hȤCLUbqzydq|Py>G#!(&Sd1_.s8I.X,7dS0̀( dׂ8},/5a/ ND3pg!3U\,"2fQx6Ч4W ̿*E):j }2 pN](pm%PQ_f"udB+KX_CxQCI^Xb;rN#ic#_咳d፠N ġ#dއ|67Sz -#D ي,|;7{f"uWUz+ܾ>E^ l7LbY` (M( q\5hh0ce@ O'YA0G$a! Ga ukܹ (h(:MjPi4Bu80h[7;}g0nraLO7 }yc yC2$t )GȐ*`HekgHGbH=jÐ^h<2 Ȑg "RF4H&7}Q&f q ;!lQC*j}A[0UXN[48OO#}np-zَ`VՈa$⸍f4㪝Q@/5DCGOOlw .y(5]7L`qzvM;v+UlO(425'%kx*V5!RK\ctFKiJQPכ<52_G`6^ͧ>cxGxl$Gx,ُ26EU[&/5t(4i@VH;O{5k*۟Y4?$1)|܂V.u,(6YGNZ13>\ Md}ҹyob$~P 9 $~PR:YX<' endstream endobj 9032 0 obj << /Type /ObjStm /N 100 /First 1024 /Length 2475 /Filter /FlateDecode >> stream x[]}_EWUJ5N ?8!,YfT>3,̌C[ԝ}tZ*URIs\(AQCIↅ+,lozhw =m7>_ V b[ ,P-hT5tJ Ż(hЖխ[lpRCxBVknPzu{2Bk 'ǫ@TC7gPs(2ƨ%bJJsjX'-APSr RSshl\h2ܑ*N)\~~)))#"t568#"qݷٳpzN}}N~y눧}+;17F˲EKi.1jbELEj1 'K2 v;EHlln>[^ӆHNO|#8e_]}8|"^_)?!/A=FSY?~9m?װMUs*E/}H&|61:mCݍB0NcFI4 r!r!r!r!r!r!r%r%r%r%r%r%r%r%r%r%وlD6"Fd#و܈܈܈܈܈܈܈܈܈܈܉܉܉o,+!vi"* *MHd!QS.faH! ,Łmy,a s(9 Y"5I$j/ѻ@9 gmYo,P,rΊRYWgN*Ynmdκ)~^2'f{|ɜ^YWGdNdMw,=YdΒ;jDZT$PnG/dQŝu5 \2gκ^.3'ug]zr mݝu5 \2G5rɜ;b~Ԡ9κQ.ӏଫYV.ଫYY7Rx-ڶl۲bi[Flbm[6Ymd-,lXږMlXږ2XۖM{[6Y,m&-,eޖMK2`[FK۲Ibo&mdeҶl۲bi[Fl&mdqnHbm[6Imd-,lXږMqo&mdeSp\ږM{[6Yl*ޖMK۲ ewum]۲ m] x][vO/h6ۗ*D{r*7 % 0Q;uNqPc5ArArPT/}NcvCh(LШ4FiY,D" Bd!Y,DV"+Jd%YL]JLLLdB5^ x/TjPB5^ x/TjPB5^ x/TjPB5^ x/TjPB5^ x/TjPB5^ x/TjPB5^:_҉܉܉܉Ơ01(Aa cPƠ01AcܽJjˋ9V W۶٢gCQYA‰jAFYӺ Z ՂbCP*Eί34YDB)]!a߹MՇt @n# ρ Qj.X' LG}D>4JQAbk$# Qˑ~ ePQ:GII]Hh ~Y$Pp6Ih )"HPډ^v%]{qF:%J(w2~,T*PO;)Џϔ䐑j{zId?I"$>82Ket`z :90Ѓ5"FVsh?yE>2Q5zg.}tg~5´yƩ?TCkŮ>q)n8;2J$BjF!hI" R<Tz_Qe1C ee*nk(J7R}y!yΩXע`Cr~~t<|r?SrӢJ JFwJhUll/KD\"5)O: endstream endobj 9225 0 obj << /Length 516 /Filter /FlateDecode >> stream xVMk@W1k{MC%jl wIA2[Ivt(! af{ovƔ<Jn(Δ"bD? R \(1qy}δhrCAK뀞>}x}{ h> lćÏ_b5Oq'ߒEMRv*e:nH$!"X)KT2GSB_q{x}bҧ; ϯ7 Y&Jl]$/d?&ϡR6yDnԶDW zHEmt6q3B l ڤ'EޏߜA;rg)U~EDQA.GO~.+g #;+CWu̞aE#$gF?,\g&aCpm3|^\./jq--h}o5ICd@)sBvk*g@p@<}3(!JJtvWN RV衚 ]MO/' endstream endobj 9209 0 obj << /Type /ObjStm /N 100 /First 1014 /Length 2426 /Filter /FlateDecode >> stream xڽ[M1p`` ;I{PE 5V+~  gIW,eҐBTBf*2P?9X}!'5Iȹ+ԗdUYZb5dZ ?')V}OɁ(o&&Hs@Z2oʂWHg)0Xg`3qUȂ2en }!$)]%}DAZ[8hR7YscQ4(SQJrKAm} *ˡ,BWc1 bSo2 uV-,_k } K[)}+3r@)*,c*jJȪP||k[VxG!i/*أξUm4Le.VK 4Rfa-2%oWȇOۊO˰Ԓ/ex>| I2ӟ7@}1l 9BrL0xpJJ3DAZ8o&[Ra5b=j (f 0 5իWW6:Ow:}wuBdH7O9}Ϸ560Yj4wy) "s߆W]8p>^?_9|0ĘGpfxc0Ŋ`9GJ5S1 ~($Ϙl bxl" 7"s"G'VP>1!!D"TԔ)C0Ӳa dž=@P ?a)zPy~ A^,z,pT&{%8PP"`h(Q,)VCP> (#ThcŊBᦨeQ,D']/ᩈKh x@qgԁ(*PMfEP;7Z/MT#=i Ե.*QlZEP# ,?ZL(!dObBtk*Q7-3OdW"@eD٪?hb%G2~U@+9B% -=1TYE=LG꧟5㓃)BER6e1 epX;#,z 6 O0jdG@U-Gh]ُ҂!rգ@XVA2p݋gt97마rA6"eBA$Sd`= f~p삘mDmS@>ʢV 4o\@Iޯ(ARV]@iSu^M%#k޵]!ۦ3}TjXZh;>y2A= HB@3*0Ri >Jsc#lS"AƓEs,UD1z0 `{`w4xYuS R8vAK:8 [Q(̆ LPd pɎBq.~:bIdEPV_B I27Mt BCVN5f14yc |Lafxȁ/3!< Ԓ<d"Qw삘IFݱfy$8g^(qH^m$JM% *if\`k.~g23k wJYjRr+XmJ düt ?* J䃭b?k_:\7J~p<H ݗ_{쫾1/2ߞe>׳_K%No?pzM81|-yu;=~/o?/.z˧2 _ϕ~x"~.wivwKσ<432:e l 4VeIIK=XQQE׃rf =fw-̽ܓ`h7S^z0XŋGMH:(r4oAJ: "![ Ht%'?RP}Ş{DJ>@HbCS%%19ٸ:8_*aHH,Pi5GV}KVE#>(nvo@n 5IELەx}Y {6daϖE1$+<4OWf\k}zva, endstream endobj 9227 0 obj << /Type /ObjStm /N 100 /First 925 /Length 471 /Filter /FlateDecode >> stream xͱ! / e`οܟpakDF@{-[=[mɺڭzyͺ^!<AQjH GYYȽ5-c"Uw͋ܲ~,ѭ~aoue,¸!@v'jĵ!m3]Ȧހz$98WvUq.? -x!G~v|r8R9;gz9"gr5ynX^s&[d5sb3"vC-.Smo8ᜫ \m/{5d;C^I{o׽ '/㽫/ C"1,1Q}cCoCPx1{è5za83gOK%{w1 Wy"MnˇGW>Ԡ>/P?ҋ>7C,?X endstream endobj 9251 0 obj << /Length1 3128 /Length2 22958 /Length3 0 /Length 24511 /Filter /FlateDecode >> stream xڜT\%4H @p-5;w(pw'{pנ]yQCNB/dbkqgf`H8ڂ =,蕁f C\ Հ6<8 QC'3 g`f0spXh067*v@r[;w 3s'ߏ*cj!=ؚlhgXma@ejdch d hfmhb023Q@`gu0deW**k=:;0M&ka qmL)Y)/_r2@ht`4q0LL*s'';F_vMlN٘Z[m&N# /W`_X `.&6 4h)[YX g3qXthhoRL lLm!ol\<տOWN~wM?ѿO1?󯳿h_c˄A67t"vyv'`w5T<υ:/#?UJ Q hhdl059 hhE ^ v:S50::}1/b`&6fv;xY '7  lsvWq~BF߈(qE#n߈ (1%~#o `ҿo"F`.߈ E7sQ\#0E7sF`.o7sv#Ven:`˙Y8}d2-gc%v:X8Zn/'N}#F` #Cc+Gb:F@1-^[ 2)ۂ[wbl$ֿ J bb |I1 x! x=@ \!^.ulgX s_5?U6v@?42? <;V@p~'. [9d7b]~Uj%fplÊcp ;C?o? } U,l \X;1%zd,e$vGio59vF's.`ο_ß7&RQ>y t?cgphM-4FX5 ls尹$tYmXO8eWi#^{QYky<:s(”^Dx{0BŌ)0nTH/QЍ("1dҮnUcti^ifض 82i ͔9^P~+"*g@ԏ@:n=QR|WqO A{ѱwɿ+iZr6̖C%sLS_"1‹kyJ%I9-ȇ>CfdL icQI81 o+tk w PlҞu=Ma'MHK%`i4 {iT+W>;hT3ճs8Bb2!eUgUphsoGSScp)8|¯6`8t"#r0r;H0!Ǧ Y)'8)4|6GǽMը-0V).,$~f̃,KU!axK1- H^|a^o,m0)lyohBNqY?= 5#!>.l "RU:9lАA&RY ªRw]`し^OLsXb-:i)--pBTw}Z ߁IA8b{!^dqTv_Sy O#*6GAF &\n9|+Tp0Z]bðTdSg6-@{~MnH·WēۧGZa`~AbeƊp) UxDj Dy"gz]MTm8kW W疯q" gyPsn{*$!+xVѥ|Bg߰Ҵ6YI}a}za>@f ?hɥ,+!-w^fwиO{$hQZ˷ *ʘ׈3aUmxbadZBjLw*T{B5Hc6h~(-mbzG}  JoKjz 4t ɴqv o/R//y~r%3tFֽ9:P k[h0O0S%$R6?qM,7) Y(z\5#}͂v#!JgJC|87\Iߺ؋[p:w I-#m=)Az“Pnoc@ f|gЗu.tϕwv?:Z^.$12*q9)dMއ!90dA Uk n7Pj7$3dR Jig1(Z$!g^pu nwӐռ{]3݇vl1r={nۛfw4J}@c-؝Zw3A._aN{GP&d9lNnx K}<5md̉jGoD_LǑ+`N|1R89_ {ͺQ{kzAQjbq·i ?, *`^9FW#E=X]by%s9PT2)򢴄Id6q K|{궀ѓSg1@HyRPRס&DբxnvM|Ce`?Ψ7պ*˅AU5m.#ݖQBF: %ҕ@X*VI?jIf!" InMղXg6*9 >U>d[dd ܔӑ榭NY= dk֧/'|*31 #G-;ɡ6YPpq n|~fS*kսrі5U[<IiS0/$ƀ;=Ԥ\Ntύd^ HpZ83l$w=9pCuH"IB2/Ӡep}*i<9}Fxn;5s Ñւb^wfD$ Twc?9^YСwKC?֏ W x |`Y ʼ/+#sH7"dnByRT+ %8>ѼO'R"ov<-7Ke +O95juҊ#>yd^/}ٷz2Y̤叙EQ-nhn֣ h1ڛqW/4C3j]kuaoUBiU OhaIIxWj)f~Vt]gk)Hh+!rREfhY[ƬA B {yIzlG=h,-KQ2L;u[AhPt 'qm~sw_9'R%~7Oh U1Bʾp#!l z';6d,/ ןCX2 UyY! 7-sOy"X+Wߺ'fvs٭'k&ϲ;5Q@3#cfNFY%z .wO+@a#X[szF86AseaBy;ȖYE=%⨾t'K;1O281dP&FKTd9<^>QRMD-aW:(MXz8$ȧ;H]uJ@>* k&=[bVE5˨U.+K2ס;o*b+ 'Q{{NS)BqΚrjfA\9fb2FeIb];8TV6)ͦ!/oJ͗r[ٜ.Xx1~[ i%%`Gu؇S pcAYC׵dZ[[MHWB?DE|̴jCшLҚC5dHfn\ ?J~⏵x 윁 զ9復# "F=-蔋s'Ru:?5OD}R2Uo?: .&&'i%+|}!hHnL!ȨEثj;ZL )伐3U?Gw&UU'/%h/$lS} ajEeX?$=Ubƾn&e_P!&9P}rr &wO6!̈B]ut^0'FliXQJڱL=BiCM nWWl 8f') ],f"77ߖ ҭò1%tOAna0ΡKdUE RܐiF*]k:>3BA#Hy;V$1[ ВXh+K^H8$v-L=?6G>|}z^Ic | EE?N˞\6-\5c̩˼m=KS@/oOx>s Zx>CvTUI߶4ʾSq .jإYyv 1OޏfhtNi8!4crM0-Ϻqkw&ySƓo1Qj^uT/"axvxmqCc/ vߎ3HX3vd5~{(` {oK8pUT:XxAL9J1wH2T"}n KŗiifȔl:PK3׃$?A ]8%Hm}˻kF zY#f탓ipxhN.kv/sm4u#`,U"?^DйIPtoc6+:39{wATgξl Gna0AM}+Zr1K^ygcu~q3&1x_7hߛɥcV SO?OqWwK_t#w DU$H+9'1x"A@GzjkaHvn6P Eq*cr>fNӜnla4Ƅ_aF'ouR vx!LBr[Q?|z-hʋ:c4bo\,W!y ^V<ܽi @p$Fw+/ܯ"u?X%[z AdX7Eϫp 5{+Ch۹bLVNÒjV8L}ɹjcIYfY4Vގ:u|A{m-MpKzH#j!gȍV-bQbpuze=z)-MgG#.zne3wǜ~z҈'LWPswו0(f\Hp.wܷm=(w!g_ce~Lp@(s6/qV9,ϙSp2OF9>$CЮ& kS4/6|AqHF-a2% <֨w9 bRXyEzqSMlkB]7G򐐪P6%rxĴ<}mejZDE.$. ]+VZo7$]{C[P>'B)5OwHp <J1jK{!"r|z#w|}E\)`к<ƘIr CސDu&Z(۠ [Q ^k8Oe^ڗxTz*J]x94fWJZ *[x ~2ڡIALkiYZu GkJ!@bL5c_y,r즽i&(d0"a&6^<.u,Nxu:X*`j)e^yrIRFF`ݣ<F}WRyOMsv)Yq _,L uPt<}1l-X(S<ZL墜0LB#WU}6VƎ0$;ŷ%TXzVvЧU>_Kk ';a~C31wwm݈`17Y?>l"g$Ju1R1_1(Fm3v"w`-X֠ bLOAM8Tݸ1ۥ.1/]c1ͪKQ#b``$l SJoUh dr- #_v+暗f3aK|t3>8w}_yfE#y +ƶsHWJui`F_%~ =W955oFf:'%ePf /WKZ:9'ҖNPK !T)Ia(3>/vsxٺ,yix>}n„*L?e X5dnaF~ǣ@oR? T Yy?S0IfMZ*9Rq?e`k$vfD-~w8e1Nu23KVi1ΟQw?~0G jD79sW> Q:/O<$%iccQĶGT܁xo%qJ˝\0G.j<"ҭFծUȭTOuSAIzNJ[X{!@<  ca. /a䂞Lb g ."%TA7ԬU #85۸)ԗ(vJ6 X CC*_r{cL^i_d}e8وa`Lܪ,I!5ҿ$ԑBz'ӆ|!j..ۭ*ꑧ5tp2av3LoӎGSWX^ö=s%w2`*eMjg)XAxKW% eu8L F1kگq;VU_1˧U >&.8ݍ΋F>ۤѫ#zCJ A ,ԗE) fr-f𕯧Pe etږ'C~Gٱ0)Fn`=յ 3 N |=áF'O(; CF4XՀ)C 5+@alշd=mr erඍ^tPY~K*Ѡ8c[hx|O-T3gSYDcuY܀D}7S7 _t$t+IoG-$I{.'(AmXK&ƒX}'u{ϬdvؔDQ0;Tc;?Kg57~QjO9&sMc4}G؅ e MQn)IL,ʜF8u uBr PR%Vfp {s0"#,P7>03=^x"ە:)Gw!tW8NJOi,,j.۽ w՚ '$Ϋ)IsK!]`֟^MոM~jް!<(2'Tau ^^7yE7T!a2ѐR 6Ӓj4Iֺk {i@E)\S^b>lYuǜu^ڱ~}6ey[#W%a軼w`3{"dٶsdM)v5 Y7ACE0>& *q ,h;N~ vI܁ M+9Z#"Da5*'WleCޟ8A0tq0 MyOә*uoG3'Bq(,Y>NI+bgL:qY!ԑڣQZ'/0$Ѽo8_e;ly۷w:⛩xp]-.Bw{@'m 'YU jV4aeHM2 #|vE(7 EG$ ˌƑ吅G7eDR"}`MOhX "%7ˊꨧ *'v}EYN61O7Ɔpr+:R~"8qADVsʇ9cgozRϩrc1DSMr?QЌi ^}'Wfy.TZIg(4} (U7nL6JR O?%,7Bxm`=(eփ>ˇ_c$׆TmW:㠹~U]ogũ8 ~Kp7_|+unanJ2CM7eϊhc6͠թ|)I?~rCDHTO>8iS. gnVT%@a׏ <,ؽe?ܴvcAHCďY[CٱecB1&.)rxK Et,`]hZa{T'DԄgW'-w43*ià~ ؠxUA S.x4x4U݌+\0ۑ;fB~g$dQ.|0,t\nJ@e2;^σ^k`P#1L.ݞ0\!P!׼- =d:fI!d[[3K̓o9ƕbLf3I9rn[Kbz)՟3xc+Vek]ZMVc4sZcRa PU6r rrѥ AGBO.OA{l;K0:QZ❒WzӎXe9ihC6v$>Pi9];^!Lt$\Q[l#lI9_c|J = .00I>l`h8jJ&{l m%1SOb7e#UptsY*"/Y;giI LqٸHeoR_}坩`yq a4u]#a}\ A8m}EHή7rfx _ƞAYJ6- Fa=Hr ˧u9|LۿE_6P Omt `j]U:*GZ](Ȅrm4JV i1V[_%w\ӇБ= *Lzgric-; 1Uf&6ٿ[En.f\[u]\U;muqɎV X\e6ΥcbS\R̴93j_RVBϕYu\.!&X561/@)-v<|]-i1Pӄ%&G)cW5r HG âb. zVcA=ʕO~ QwAD|\FvɠvlxCbg8&IS1@YVũs'~f/߃{p , @~|!ɻ+$?"7xɽQ<#Qȟ%0t:],up@B~"Qewޮ\!$lB=#%=zLōn-s3~0^LjJvb@Ij:, <)MplyNm'TúzoB4:neޢ{)w.ĔL>_4\t[z_7|*7t)]n穲?LG=W⋲K^@2\|Ci1%wyA‹(#OUpӾ=\ tpQ)aisKohB8#mÈm)< Wᳯjڜvs./} a7 q0v˗/$Pv9etv:62+XJYy,hLYhIW?d 5lS. IZ޲!waobbrlHK 4m+N@/\\t$ЄaxUsj[*T!3 (j=4묣fv4FaH| :I][A%(P|3i]uu6k6٘҇O'2b5 p6Gr@/ Pg kl=eZ_`4}3VV mC*G| '\oVZۮگԆ.KgCƢ #:$E~%۵@5jeR4wӹVJ?[/֧T|>QKk.ĮVb/fVt72Jn7О:vceU1'iSM ꢐ7ѷ~AZ8.54͉hT#)r~ǩfNQH9Cg[z g)Di{ȾjҰxΥ4nx)_ym+@*,*m/xҷ,0>u+e_}ٝ "O) n-dem6ǧ Ҫe\CVߠǘDtX^o\:j w n^'cȆJvҡ= nP8N*VL8~]kB}AE[3ѩ"ߙQ56ׂ3k]4-0u&kM/빜Xl,6Fͪ*G'?QKB3"eY2wiQ%vߔ֧ wۡnBV0B7a= c5Rbo~%-dÁ \V:bbH=ذ"_QmUgj$\(aٟuZqMy^\N澗q@m,kOGMODU&~YESG' tL49n1@ d9D  lW&\bP]V4ϰ' _EJ:һpH2@~P$bSP7bbTpR 4J!S(lhKyg):bЕ\ؒ!/p)Cv3YRsysׅx΄۵~K!GO)57>8~+6 8paO[Hae`>w͘-QFb(9CyMZv-$R\FGw[k2iG6߸r+L;ҠD.R{M"nv[k'Ȩ8g6Ssث T lpuXpCXD"H=UMla.IJ<+@w7~lnv 1qIs+rEu'ZlgG8^!-tz2?Qb;&μ7-Cf8wwEeN_jۢ P̀ <ٝPIR> sK T}!է(E5BMySp;zshRdtD=}Bheүéi`EC6],3.) }.vR.sfBNAnxiG qȀ_"bp4غ|#5zn { MKʜ [,q~qp _7uϜ=q9CcQA=0(ξș! y]1R)Jz7t/QR?nhԺ2'&q[Df*I[4֚IJ^sO"7y+<{|&  ybȜ䵧Ռds>O)6v~a&4.6+}z_6? iU.ajBN=oWGͽǺWzZ> e;l<'O7`GLUR0MĮ3;Z&y«'U@$bBW\㒉vl"8Avq͜:-;ķW>VvP O K >G(\^?BqH_ F2Ja@0vY>l; g T:ܚ|[ 芚C!a3&.Qj3 tY߾}lx5-ck-Aw\!U08IV[8pa]&+\=Mπۊ,ne%ʵy\Y 0*2A_O\.wܼhRbT_W¶H)Z_D^O*t|i-RY{:"i&&knlwO*$ ~& 6Q L(#?Ȑأ<^ǝ -qf 6˖i #瘭/9)փq nn@Xڑ0 4ox#,ܐOz_ oކS9BP422K`㗅/a!嫨~PfÚ;I1V0(uIL*rцLtfcGoQ d@%tҀU!pr<*%Q0sh3SxCx ZTۑ`LְyH²!jz4eZ*zNh7z)}^X-e Tnh 8~o˽^olSa+M+⛸se &>E=$cx&]+1'bE.bU_?ZaPH" ٠Gފ0E|?`|>ߓ~4_(i5ןf>- r 0w}(ir4qxkIO$Kd^-f㑳 b.fWJ]팍ڬmvP$$}}bx-Uo.Oq.E^[W:.xXZUd ز[ͽX xd[P+"*nc䙅 ;2bM!uÆx37??o7LSvLRg΀ǝO{#E2wHR:yaB ^= k~xtA? g qpE,˪1׾T&̧m-Plǟr8YK?6VPG`\Y3Q>w"|)L#Ĉmx p>kZ9đnAH̲lԚbv +j=,];ği'>Lƃ晞X5kQ2B@ߣTq+Z#hG+K@B/%/)N*άĵ5HjTV=*J+1a8sdeHkx64h ; i!U3Ur,hF{ 1dCa͆D'|>~DF+Nk>{LI=-dXn*4v~_87W)QsX_ g I}.a!^-!GµBR5EOMIfAӼ무I~ svQkT`lP;8͎t"sBXpc*(?770^F -D }4S4Ъ^{Y@D7/Ax ox%zv[FT?4嘏:&ϱUbqiH,i>1f0V,tRK@XkmcY~]laƢ'RzDl-ֵ7x}@SeZQC{Ds8kuFVM OSn`W'K FY 9l=<(ʤ%oP%0".doB5).-,* jNtZYP;<`56&g}O"[C`'{@ dY Z9|edG$ݝK%!=Ns9ٱ U "Xt k/4RITtQ)+=9h B?5{,;D+9P?|VdX<TQɳTFIΙ$7 dQ,+nFR#1_ZaR Z~gnn G;';9ȺL +"G%͔©?zZhHάN ҟ7V-.F:d2`~K0ʭҠ T\zn)$rལkyrg44!z9OlDDy t*pWRT4Z6؋7Gsm䷜q`m8 'X#?\sj'J$Kǧ}FTaɼs0pzDON2鋓o]4z1Gz2&芥 *gg^4 Jcνn 'W͆{h9)CUFCh0RؓT$sB>d5Hyھ5J=Q7)'_4ڪ*5+6?ygc}~M|,܌u=<;!VY!YҜGgq¾Y#NDja_j!Dm!W/K3bՍeԾ7]hpKeohEƉQÈt A43 F@ǭMD.WMW`;j(gqFq M`=Xm^t4n|%PIؘvڷ 2(ryN;iZ"pQpHBuaG<U۾z3{u7|LR?xM *_gX̤v›Qp2-LUk\@խނ`K+&o/ t+Nr&!_K ˡ'KB`dMil-|f d}*ef.xG6٭Ϋs ^D4d#oO>r"FO 0ܛLR>"Gu=ݝs_}777wKBbώ}n3~$yQf9+ l5y{WTYF#q-LZ9jjN-Gk2+)W2_~od `qMߊ-MuΧWky[|3B=f50 )IF,CWve:W Nq"!a0~?QwTzvLhCiVp _@E< +֜FT⮍b 0Ty؄ wN!b4/+4VgUHqџLuqkuVa@O?)"IPV![ꅶqqm\9x]D}l>rw=>ԳKVe QJFpkOr8Ph( ',ˣڗy*C2DwSaZBxKX#<+T$S<}o%KH?pzu&0XK]҈ 1_5E10W;ă1Z蓲W_ t6Q'@E'yY;ڽ@=q#)CeAC ^G1E0PBBMzS} Qh> B:ţG'Y 0W>pNͮ@IQ!;VXԓ ĈYo UPv8@v};X Xs'.~=BQxDx/P:L/=:F suF0Epɟ 3o_^F?Bؑ *Ae'yc'h*Lq "a/NN-f]K'{wk0Dgd-䈟OXټ&5MGjO׾5F 9ѹR@W5=@EVI u$bBNADPY"P|K< Ә\(,fȮ3K*PV}B<2;[4[ݒe2PIϭМ!z$=NvO<9?e" <؅Cӽ̖\`2B|6fQWҼYE&Uc> stream xڍtTZ6 -(1H)030 9t" %HtJ+R?ƽ}k֚gهI׀GnQÐ<@^~ )//@jEBCP8L?ycS!oZp+(HE% j< pw? ys_`P\\;@ A0q rP_!إHw >>^'/( "ObY2@S/+ 0; }@ C`7.^0{ps;@]&k&p4@P/g ws0GQE" O"~A]Av7_*zM#HO^O~i2^!= ~E@7}3\;,˝+ܘ9Ba~qQ; 4rnʀB 7?(O7DxAQ D`$ q}? ࿑?a~LLMːO p_G@# . DE I?ap|oWDgC8 .-7_d3H?pF^ț5Ђ,쿩&߻z7ݬ8 c8޾dhOݓ2E-{ \:̨f(2b>@3hjB.WEwa3,j^ڹV + dCW_b0Das(bt }_SYqBtweF{\J&݋ cvWzu|%YYdrI9d!A?ElMST93l3/cWTmu44".w](7TJى14=&pwekݯT>aKR&:!f8}r{'`_Sh#{Z1o륞O&:a=>daԭykWdCc3.bJfqcg;A 䉹3ХB<͡u!ߥl&.돴3:ːXLS|Uw/=4/_`&)%p;k-Ŀi<9_04WoR ̩RwR)I`KrMmiWq#p7oj ėC?Z{(!UfqN8ض։=7'ۯ͢Wn)>w[ vZž"0MPwX BQYu`z'Q<ReuvZ-o -Zm^"H'*̎_ z 1V/oy  #t( L#I[5_C7@di7D&O~'/{ͣ8e;0}lҷ"n _eV2K;ݺ*g<ۼ~h¥&f2fuw .mP- ֡H4ClNmTAsmvq \bi+2QOxCe KXFnJ)JV8DKm }Z i"a`jY5*BCmPw&܊NEe`^0KTL-f:fݲ MxFBxVy3me/g[)Me=x4TI5Kh;ݒ6\UAJm@EjQE̬YVK\OG#[c[%ni䆱!q|6\%jG+ޔϹ10]Ii$Y]6Yy0ㇽeKD6*8=kcU"y䚌vUz繊Ѝ p8W/ 4z}KP6u$ۓXŖS_/+ j )yBOL;Q1 1QHݜ4*M}.j#`" +Ef,RNˌ~0 Vl[Osa$H 7NY"!gԳ߅P@~f@iEHDGUT/Nesʕ>?>S.rY,㞣wMs6<O7/hj e(KI>PBp 32L,cxW cvX5 _O?;B B}e2G;'"z/ewUX)@58YIJQ6Rt+{wAOz~fY6#]MCMi/%Cγ_˪%j~Z]tӣ> i{Z$mfb#%@ǐBcDZJHX¡jT9&Q;xՌX%M x JѝwfǗwbQ&h@z|SbÙ~mo ZaޚX/iS,VBi6g=&&/ALO ^k)?.I'4v=vt̳4"5:mڱrqj=$@nEfu.jC1AErYbm?S7NL4,J! b+X_O{ahv߾Y9( 0\˝"t&"%mbws+7my >`W;;Sb=TQOULLy"\ d7)}Rrꈾh%gn . b݂`DB/-)ѩPI{$5^巌A?I?uIO3RWڤlr&y-~Q*^0[+/x\{՟T,&6n|Vj<3߶lPb(v BGݢUAeoMS1 {ȓ= a"~ee@:xJ.*Q}Hil`TrfY~r F6ʨ0֭t[~%>nYMl3s45WZW;v3AU ջBU<bǔvr}1}2 w="|sm):jh!R UZQw"uV [{#j7ekok0Uֽҕ^*[ň|lp<|QUߖ0QpG]h)kmOl[2tvi9`AtؤALqGh4xws1uƜw;60*ԏ»zA3Wr8)Q=WL® 7jNO!a-}3. ?XiCMFRr!S hbQrRu+kL'ywrtnkO )>xt~]CQ8Ti%~'!j'81ZijFx/{A(ؚxDLMUE|k5'}Lv@]J!~J}rraݯ6ёC/*xb룤S3ؤ?) (%=!n'7pI_MmNjLcxhKzO K]0oŽ@eU!eNiL?"fX : - Of=n c礧YHcog~x6&fQ=!PXp;)nn|S|MJEZ] ES! tK$<4T9d.uU$MyXF_LT,*/O)־b碬"Z%pEAh)8lE.jڋ(߿nvb?aCR1(Pur=Vy[$~u;t[JNhƓw.>o֝}UxPNvŀoVW0n #:)dN $*3و]c0`R/131Fqd+-KvfZrMQ=0r^~4Ѣi(y)sDž%ܣ1[ t }vvrtBF)I`blLB}QWOl&xSfl1J4.DcAV=^}:«k[c?8&pſ616}kw}:K6GTa9dbGT%0U9NV"hO/sY`2 "Q)_ޠOJ $6)$SX$O^Nm_'cveDXwPex/ &˞#4vU̷"74C':נƀ.8ix]}s D3_ɶi]ItE62^衱f{b;5m,ks_MVR~&`K1 ÑQ+o3K O]opۢ["yVKZfoꏞjּH URQ#5{΃鹏;V$nx'*L:Hָ:;iFNIy%.b>_߇,z2xV* >r>N,t>ES:YK-]\D}f}3\|T\5~ڹSqeCQn~8ųS¯ï`d3@zaLy6\{'o4w{vºY>ܼY-YpJ#U$a ]JxQ(鬦 ?1ں79"TgER椉6<dž Z J1P {"NJv{S$i YC:+s :3\eeJaB,NAgB86ҕzo\|:;X&,Vy؆X;.G uvC k )09Rc}!P&4ůqЏQDWf^9Nz`X??2dmh4#pFkY\/-Bׅܩ:>S gf9 S*T g5Ig*zKUtѲr;v԰3l:k~rO aǂ!GOe_q9+RlL9Rcl]ʓnSZV)͜$bBE Z$՛TaLt淦x9Q.v:[ŪU 7 q\D$9mw@xakȈ aȿ5.nJ\jTH?I~d?N򞾬C,NJ| VW}hS1fy'rg]{h:$R D.w5nv0b5Z LP> stream xڍt[ ;ilhl;6wjl[jƶؼ9E1{7ZsgDQ^䳝- *''`bbe`bb''WYGOndag QG ]&+̬ffN&& yb@ c@ \?*#j377'aG #-@27yhY9dqbs4Z&N&.&ƀJmL]<9@_ *v W ]`madbnlklxP(؛KY_ tom# ۿFFv6@[w [3 @, Dv{- |V+w}NF '' jd6ؘ؂O}}Vv!S [cӿ0vgTpp6λ`gdb8L܌ no"_=ex[{:]L Ggo./33-@C3 [?&wp03;G̨()-F("bgeг3ظGhv~d~Sc`kz7 0s9EF? `C\F' QQC>K\LJ=z޳VCi!n=kwM_~|ߋ6=Rx?*yZ߷=ӵhchGvc^|iF {6=7?Q{ybs;w:C`?=?=W?ݹFΎM> =&&n&FsvFmc|Pg),c~)8̌%ϋ}̟-;E{=?Ouq # ,ҽ]$+I3(65`yvasmY8%({c,S}C4p&qݜA=]?t? *XÀzK R߸;=C;N ԁ g,ͮӒ7b7˙Zmk-+J; ;3ˀ^_:̣ }]Όt(,k581RqU~Q@zۿOOslWWQ&BUu4^I ?G |[wbʡӏ4K;i"@oa@< =2N.M@9he{(p6{!SLS a}B:Zsxh^ggJ߭74,m?`~2YYd.P^w: r2GI=6ɠR L67[<&j]#7!CMަ Ŷʎ<+2{Nca}i>f ;3Lv" ~X3{{ha]@ci^5gaT5mz>(ݤ .倐ww`NhoI3/a݅7@]<莍ΗTb߶ЂJޅ)0ŘTn}iw29@8z8Xѹҵ1rXkRCAт_YhbBpZ糪$ FϑGOdjc"ZLv%mVC|ZoFRTra c?2`=# -/V*s}nI/0W<|V:pvoB"lR`[=aw G)Lөz5Xk$(c1GHӥH\kܚߖVT z;gzttCL+1%eCo eAS_Ž<-[44Czʛ0MZ8}j%$5@Q{Ã_B`&u"bp\WM*jMod8?0FY1URT *yh]_R.3H +S[`7ps!su*)XGClh_Un6hYy_Ҟ@m-ؒ~Ux 2jR㇞stIu[̏>R:(AhX9uwk۲A9gj1'p]6BS4XO11 fKIsݑ(Ւ{8@Ih"RX]TƩi@qKu(L+՚Duٗ)vw /sFLa:"RꜴO۞NmG,W{[5D9u[} -zAjauE-GEl`!X< oKa^8Xv 1$uvՌ 8 P͈PW~vA7Y_)፾/Eʰوn{,bTI_Gmsj2-V'K#zۢ`!uJ!8A>(hOڍvB9ژ"+)Cg i̭SIgM1;s09}񇏻NJkb^/:<}GjkmH*ܼ~j!XZ3(ܛnB#S6Ӂꊲ9<C\~Xπ4%I+_oM؄+*Q/?]o݋ sʁ%~73N%#86v]۫Z9#UfR,Ѯb$=e_k/(֢d͢@l& ]@%2;^$)zs6@/ h0FLΗ[q4lTb}-?kW6Avӫ=XRO&^Y2z{;h]y"ݚ͊E4Ǐp`GvRh >r#jf 8.{!'}{77`Xc4S˪Ϙ+mHtd]ܼ != WQ qA|J/B$)vB@d=e Gg%Mo0$nP]j'NՏv7bŠØ IyPQ=X3 ǺBl*BI&Ku3Uw 6 rcN_ c"_z0 ?v(ĉ'[FJ|1p $*HAFv9ƊQV?ss}% EZtc%2"L8cĉCoW2Vк}L6mq0֐/81~qsp2.},#0I!9ZXr<Ӊ/=dF*~$eqY-L[KBA$I>;bpӟx}s/߮ DbW=`x }LLUagޫRN o)?yPDn`.qi~p<;ܐ|=Ag(1xeO+Xbi,rW/s@m*O@7+ꮷ>`s*ŰP(xys5+'X>luxxí[\08P/Nr*w:*n'ף~d8#f5e _$ a;4gr=&l<]ڿʃhG/ҌPRkF xAV3kGlōPKRqW}VȦ viZCNd?&,IBBo sSf}J,~t Ku,[gY7q}Qj 0qI,X"`s˼#:C67}Q͈jLUǘ/IT,z&2 Lu'SIwQ)ȘѾ(ˬ ?১S^;꒱G2ٳvoi~wj(FW췋wB$x@/*6UU͊ cq \l&j=9\QW T΅h/:5%n_0XzMje>78I%O-bGًLCF >X҅Mg<XC2y޲'}z.͠a\2:vW  ?X'fJ8Nj)ʳ6^ PK$=ڴ}'%@v- M0&(G7tWRpz}kPbb; G*ف{XWO_8bAHc\VDy|ෳqBix!%}}=P9U)k¬nv~ m6DB{1? ךx=\Vm" dC&kCƧ:&vQ?'j [" Q_hwGqru6Q "ՠZs9`C,EwŠZb t]%,vh|3%yRI}@N ҙCB{B2BCw%1F&nhGh8$ q]T?-[Ͳ'k:=&I~ 0ҰupW$tC࿦p |j>0JQ[.aQqEkz 9\{ThAvSQ-G|vAEl\8c4ܰjheKᓠ;FDVfo7B},*du*$Zx#^0LavHHdzx, Ũ*g9oḨN.⏍ĵMO?s, wi@tFSLL?Ϊ9񩷸}dJ%!pL_һ\a0TR^gU7i@ql3 S*QD&iX|kS U /Sl ndnqnh5psqH`2Ց]{iX Bk^B&Եu>ϩB:9~0tt)Oז 6++h5 IGzb=UǢ4<,ZU\ޙQ6$|Zr ΁7C_^:td*gMCi#h;I!yz*BG!P󶃳/)v/Jws_\&+) 6R=ܱų$~Ŕ[ %e"K\ F#.ӥup[WfͱeudݛEz(qC9I47b?6H5q=IvD/Lh{S72ñX^ܻ܃PpHi(D, ,.24Hj (HcN2tƢFufPFCN4bwNOV)Qw<!%WQJ\Ȥ?aԳI]\eڏd.vIbKf밯G9@e/xjj|/s1ZҏOa $OaU5FG䑄!&I~n:) |\2WՃ +9d[áa)90a/l}[Q@H9| T+z׮h.?bEuJ(S:^(z|4 iDu`.7}Oy ߛǤp)]?s9 *rMr,؁"kOD>PǤ`daoqX :YmrHzaLWH0g5/ 5KK0lBC 0{nɟԭѷpӈ<+_*:am ]s<"&) 2VTkI[åܢ!9)Wr9!h{ Fx/ )-9mC8][2Y0^EιpVs,h>dVAYoTfS+ߔn5u(ïdT-FՃ *X5WLl8=4kgz6?] u^W$g%"n,a&Ne74_ah cR[JU]%Yl85Do}{fNf0[ӀE-Ga099D[Tؾbi9 x.x~CpkdJxk1Nv 7eZ@z7I jyۨ9%82|CS{p Kuݼ-wCMY *‘(;Ͽ|Lu2FV(h'\MPb+\3Ŧ9Z˝)ӕPP=0B9},ѰܒNӒla~K9QVt 0w5> & B؆7,U%m[/#3|h?~̘vLglIiΉb.Pa;I%=*ȗQ0 C2 BX\70_wl ?.z43bȳ$fRhj'GPeS,DžfƗXQ6TUqϋQ!y,6qFe%di $.-Dt4/"AR,K MvW΁nW5Qy[5JxB\n*۳L;&Ww)MB"#G5*4z=rpFd/<.93M  FMZQAGChiCBiOl~(ۛݺFu66d,L.rKxZhO 0S u _M`댧Gi :׺3yM\ qx ? T~B8PϐBTC9GZO3M-4Iw"^ ^JEtE.>\ſ,4ijw,JmDbC*cG&~w3y"e++~?:Qc)b4FW*g ,>Q_a{*uu^6)5@ :+':Cz+;bȘAcvkAr}o*o}r!0N[SWh1\ÉgI,9gf.oW<רvM;Oy %iU,cׅ3a,a`qݽ,$kp$[Y$B2ʆK9?]Is{וx&7MXa9s1C=PSw1,T4[W|+^~bQ& Õ\iV^VN(择h9˸8f(xml*ԗ8V]b8] FMA"rTYH}3:W0,g-jK̢ex,/^؂/^Ryvý=^XS=~dK6F-xu/]2&g_۲BQ籃'L$F90nc"w$CL<Z_7xMP9'tȞpCp_ 51g:Fc͎lҏB _Z /(-b+]BU[(thm B\cAF,sz {}öǗ6C\u!Ox,%t|_Z`th2*sa, R7{qx>XCrD=[Zߒ1sY2cƍEQ=ȌTWu>kzWD2Ƽl5׌kbb ]vY㐩V%T=}' PO}u쩊1N#S'q{1qrZf c[~g#WCzk[X=Z-\lC}+&&헻9&;*>Dn)`!ByҶseCP@)p$91C\Ѯ#+/ws&`$ s*m<ƨK?zqc(7{(gw7J0+$VH iץHk"gTkJKb2RwMtqxi7]L`\JnFK6 W}e/FJ%acj^ޯR*cEA NO)-ܟ$FW˲\%,Iw} /H( lޜt?Ng|fp\fiM_}$Nq0X|lt5-C=+"µOx*0GH [҄B^ܗf5 Ϸ'N,瞸g@,8IO na<(xع͞>:tJQ_&mjZr)kgΡ;nxr󬟐-/;nC;$=ɾT+daӾ(HS^thGזRB=NWDTsLtI_q8 GXc;?X|zu+Z"'<:7Q@ cY!;+Ͻ?y2=E wweՀf8V?}^xػ_$d[y0HcClJV~vJ_AK)W|^10,^XٞtҾ``>n}-r߲]{J[ ͅwlGEV_'(Y!Z;J,V'6i iuVtڪ[Rd8X,{QI_8,n<[ T1Qk cþ K%~XċA\1 8nyHʐL7&'%=7Exw!MAzI~KmynQ: bId./CЦXpTA;GҬ h>]{gS,퇊Jto_M>W㔰,V,|ŁztOY^fSCq $ bw:}JSbPE0 Ss "(#Q P% LiGlTIqqxa ՂetW3*eZ tH') `T4՘|$s׸WGvv2Y.;V-d/3fMET̞M bvĴ=J~-^ᰭ!U~gقZ,·*=,ͺ$of,=ɬ9:o{ l{-5'c=Xy&S"=/4?gPvީNcplw}PJM@o=n yJtl斳f9eA(*n+),;lMEÈl}0A'`&CLa]Z,\LmoWHuTxZQaԨws M\(Ӳi'z8= ^~.+̦ VVNJ녥Uu>Bḫ^@''2W$qOAtJAiLh:Z!DdhPJoCȍ@,d7ZܣN{ROgY@IvON) hW[3TաFwAu4~@[W4ܭu1mFoDB/b]Ba1M~{Ώ52%Ȱq*z~# A$զb;S 2M?Zg(GD/uvӶ/n+uA2L/bU< LbމdzjvyeNFѷB>Y}J󕣹ф-Fw 񦩭ߋ`XxstjUw(_P}A|(ȋ|gB2rjHlGf#+{-AN' 1T, dT$zۖSbjcd /g7%muKW0/v}4ܑK춿2+2*Iװ9mNFJ}I~.A %Px=a;yqkxFIH&ՠo֓\^\|tSjۏ·nK p GCyjDVD 4T'% <3>[5-2 4[11a'( 0 & &G )qoq T]la09j/l$=n:?[_R/E6' b`9p?i/.olPykgʤ=T0n#y-`@we6~uV4FD ]{q4dx.w7!E!1lYR SLqy{b^7 b uWOI'LDVNIRąI}˷jvuc1OS3 :A^_MeY)-- q:Bl]?4Bؤ80*蟴`1뙠pU]1>mmH%[TZ$(,ZN~nc"(hhwi‚(݂V@'D7xJ5>< }x^YP`55#n4)#+/1tZа灷Oz#- CQ/}-l\.TlL܂?PcS~R \Q^So0$}Gg 7Qa;`Hx]-v <ˁq4p45wR9QCϒDL޸T-6Uts#C̜ƩefH:zFxhY椧BFꓛq͋5IƃE |'U* /vvZǜUD3yCd7!Shk4v>b&i@~Ąt؅~N_Dɝ+JcLJX$q%GVѦ T1RےIMYDη!孎mqU>W>Y%D}X3j%ϼP5茸)u?@vA@hFtpC[l+QڰS&^-8Lmy eu ,iV ІJzz$Ê'o&Kx| a~ &:BLP겪Lқ@gAL 06צ=h[ -!Wi=^jk# }MS:֏OY/ ^EҦcӚoĖzOϟl]Eٛ/z.-=OvFٰD "6<'`)ύy-2Dbȉ΍T&ZjxGy]{WGVhۼ;h]{ED)A?RF#1 b4޽B{~6|Y*QW**Yoh- / *-ŅSC,Hw{} ~-!)RSQW+RJ>Q0#ISr6DTPe~R %Wп>ӗտ˒c3j]7o(gq:ƴNrjff +W̾؊m̆{>Gw:S*ʟÛ"v̥kp_`O"}mTIڔ8cV5ד|w^_tU62˃=?OJME69P7|cG8UC=E캖ᑱ~DOj=jMRjS"y#4svUU5"CG{>ۅm8q p"JI+Ys HȲZ^m6bYfO`FKKycto_եZSaxXp3;z @T ohtn=qD9D/˳tjEHhR |.!Vpt> stream xڍvT.RJI ]Cww0C tHJ7H4ҍC]5k~V&}C^;8 !x% ( ANnV;_%7)(pD%$@ (/ M tpĝU upD#Ö !!; qڂ`:0B!vD \$@|p7YNxqyB肜!&#`9B /r8Am!0wT@0@`7|';T Ԁsu ܡNFUu*0;%3p'՟2 bv?} {P!<\aPW_E W֑Wy#/7j? 5$jA,}|$;\hR{l=FuS@']EW~j|xUSg)~tS$hyi %n]h1 YIk:fRKU4>~*֦0[}hf]uNYJ}ɬ%zAUI;OI\3xA8LENYd>:s]?=]%4d㷓]+&.W ԝx{Ej^'%U}O-{  b1] Km`<3!l:.|x6wV>}r dab'*44!XOy,7TYtk8vxdo{-\Ěӑ̚.#ݝ8p`ɋn n}bWWc.RJzo^55 S_p WDFB F;Gm)а< LKHl~IayGd:K>n&"OèrFGoLj~O>}^2sbATA毦ՅW9i&)+pW*55BakN2T;9sj_>a f`lU3I u.,'f߯5;%]%R??.M:3&;K"ILEe߉fd6aB[L o>u C]qU$+NT(@+ւ#e6.C܏%ZUaS_z[|HUm0##6%#RMjnUy-^Т}Lɡbxk)LN02SvSVƴӕ"/١\$}l6Ι%Tv#KCcز!h&דodAy67SC(i_εlRD0b7,vJ}I(Qi`ʕO3ݡb)5~ DYLvS4F(+8lS%MJbVI剛*4D>rc@*$}e,fR;3{hm3 LS_=K3xY\D;mfU2:)>n y-팝'XѰ(u%k:LS|6I+rlAl+*_=՛1fOkd Yg ]xtI|%H8L汜a5Clz_/Xpz\6}{s|a&ԿڟgGNAk܈H/wZ GER lOUBQE"3 ;q[kMTٝ!==xƈ|ZxWC|H_Zx2PuGN([Uߊu0c?2=9d˼L!Y1(;(!eɨ:z$(>? wæل9W!6aޭ*:u߯/hv3udd)t'՝&!؍uatp7 5,|F=q hGкŴE>A;. `2BH5qTw]o$;mWj.; Z؟;C_x(_ 1:O]~K'K"q6^ZOSԍy$͒+5WK٤ Մ*"JJbsƛ; R)ea4IhM5tLuͼwm?HmOu3)[_ךjvWd Ի@8b?q[VT_I[GV0lTB)ձ|ŵؑsk6ls Gb|7هZbL6#PQ7'Ϣțk,ڜ \?YqFkD/_n̐KOߏ Pp7%  {J$ZL0 !u4scz拏8hc!ۼS-H}݊ѬBK[XS]Ova-c h:c%=Ǘ'%0T]>O=3aK3EoOHM|L磶I7!Nox MuQ\#sȧצ'(Hng9ex-'T|5wͫu&L\1fțqh4sY\yan|,3Av:WӖ#vD$Ñ hђwC' XIZ:2SI/z\^`ڳjxOkڟJw"KAˋM4vNdƦ ~f􈽀k S1۪zH2`U<d*_87d[fNd&>T8k.MTzEmD GrnbPog'cw >DS)z^8Ăb\c&⠖k졂 d&J>*i$a5%z_W0qjc=1rs<+tc.e{Hf.tC!YSbɼWpEeu9q{/ K; dѴWڸjn Rm>!͟N+~aX65uF7)}*&=f-:<!Z1GM{{" }S=ClXevDtPcɶ- >8ḣ_3)2ʋtkBDfCغsا>ׄziZZY%<@Dl7yJ>ܻ{GZ!|tC50Cigԅ+ >lΜ5(G56 Q5x];..r<.ZJ=u %iWf# 92Us[\׳bkhm氋YDoxؘn!Rct6̶5 |S&\hy *Gۜ]CIB4V慸o~hCmR(BSO }MO c7]V E'}K;`2RdLF&Σѡ}, R~,+8=ɦ%DI0#I9%$p0R=GX{kZ1>~x`tVcYBRk Hqٮz8E 3ƔBVU}&: <=gym?)ؓO}a>r.{W^no;l=..&$)/؇x'c N%kk~RcyWDD4T]P!7? e8<~X.j #  64nӹp]`y=H` qOAw}!7N BlK˧=<)&gf0R~VE@pB}UTLpxԀbSHGr-DZ;;q1|c*:U(`&/xi#;K8_C:1t}2oM7;T=݌'mdfJy///(,,˂${ ٖU4rbs`FT<@>nZ;Mx'YIa|AxiE>s*=Rc[gQ`;ɹ} a"q4c\mEOz<[ "2·0*i7#O.ܔSo?텖P7oOxEɄj=hS޳=oLaJ%bLmKP^0©ZM$$O!`ħ42wCX _Eqn(oG֧G=0wp"^ C{S BCpR4V%",MEʒ*Rt&V]j8 t0qDmQf},2s*~_,3ed쾨AZZyWzS\vʗM. ޽QY`ĸ'V(Ǫt02? Q*/Fê{3<<,rS' 꼔N 8aՑe/xea%3af6EƠ3Lo[h1:-T&0c /Ä,$* :jL5u6'ݽ E0LO qO^Q+^~fY1 us%$yNi՚J]>!ƴ3M$9L2wv?=H+m*h( tdx-5kfh4HǏC3}#%n i|pqQc7*ks $ DK ?/E||LO(m{Z%BntzQly. Yj&_#yC.oFEBSs7#Wx2Ԣ;|Z9P kco,2 4E*F樬s bkٯ(=x%O;-0ظdk~(s~?82mtecUT|vgyÛ.2a, endstream endobj 9259 0 obj << /Length1 1545 /Length2 8598 /Length3 0 /Length 9625 /Filter /FlateDecode >> stream xڍT[6LJ 0tJt7 0t ҨtJLJzsZ߷fgu׾72!HJr@VF B %FP;mye b2_d/|o_u9?77]\@FK6F5mUB [|), y~8e>fq]N9aO7k\.?]Bƻ_Σ7Ae' )R Յ$`lگLAUӻLU$)&UU.Cȭvi6Rbܰ!4Y#4_ rs嫵/}DRN~['A 1!BQ6J/9hN_ў/JW߇ڎv1/OPGān86uT[}EiE[t৷ygm@J˾R4;[kfH n,Q$e #[cD_)5HK{MV%k= y [|.5 cʑ]lzͭHbyj[pa㇆TZ.OЧ7e8c &5+K"A5M!]Eyܵ߮&(zt#P&C_o}RF)KX>U>nȓS̾C{[4~ /ѭICo'4]R')z[&bܠ@MgHK6\͈ /tXjfpE%Jo㲒MnoF9H/ʙ圵Qr#n:ksWqP^)"4`SE҉.؁&4dot.ILnkDֶL~ߋp_Fˠ%as"k Úd.ܤtL`45^CUrfQO>+b%r&uxY0t8\a)Yw`*៬kʆ`pr6`>Zp&<82rYO\4̶W(1JUV:&s?y5Rg9';G,ƅfAm*,vl]qf?YwAxukI )x0?|70΄bFs %R'2E0 $g ԮKf} m+|*\4IЕYݗE^F@EV[j7oRbu&d,ob(F0b,:̷..Had|yewN'jU$Ba ;joeh ahG$%C \-k҂ a%%iJx-u|8j"gZNx!2:DyNwK? cۋ6V{lz{t~ثgmV\ڱ€ "7Re} ?VG [?V|4*jaG{\tˈS7'tasPMp(0!VP\w#e?i)Dž7oGㆿKrHA AFxg$oĖ@jPj&4WMbҋެͩO Iy_#n3|SZCk&qfCbQÜ(5y_d˒0Jȩ,N$~ʥ1Y68zPnס\s|1=wR(%E@5󠚁Qz]ToOd)No~W魁h"-Q<⳥OphuxdN3>>;r7-MfoRR8=op(4s~,﻾<QÄ83)e>\̽ ?F bę-Q,oy6M@& A?襖HF W?a?El4;Ң跓Xd{98>]{3UCboZU0Ǘ3k*WA?F_;+Lɼ07RN1&+9$>퍅<=wwzx,աl+s(kI8JYAS{Qoyczӎ/h_ҮE efԨ4 cYK)-IEbT9K 2>hR3C@bIÌm{@0/ce#0u,Pe3yd`Y^v8wQkoE@ڼf 2 N?j*8aV'&NuG\-%xORۙ{?RZq4k?+GkNH޾O@I _G&$}@'BQc`5(( :K;Q3d6zlh0-Mӛ[!f=$E bwR'*'yS -0g7rCb "M`f##VJJHfb(٣c~Zrr$}XcFaN? .ԎkMi9hkiu?0n(KC[1&5礚EuP6Vo*"G܀`*2zu˯}Y(wjlM7k1M< F7䉠&.w9E[+ACǯa\-;EԒ"'z3w@M6T%e):q[J7i#PHm>b2U"9=lJ,X:h-U+WjagbXSd7/Ml*7Iʭ c YL}P5:9NH`@^?S3B| fNpa,(ke*pGԴ2p̪])(uŻ3ߊ?%DŽ,Qҟ| nC+8FJyrȔ9=SJU-t^})+9PـֶKoȻ FCsDsw|1/ \|e_WOW@HTHdžx;;24{,JpA2L>~E+z3a>xpYfTwC ԯzMA[]`|DvfTɺ Үf endstream endobj 9261 0 obj << /Length1 1790 /Length2 11937 /Length3 0 /Length 13089 /Filter /FlateDecode >> stream xڍP ݃`H' ,Cp#sW^Q^vջ ZJ mVIkGK#!Vpppqpp aZ=+,/ X@^y`='/E c@WZiG'/5> VNAA~?$. + 0@btxheav!^Aqbg`ppestcdx v-+h aPh:v ׿pmG  ؃`n`k 59@[QEVnl ?rtp{=.,-]_[[-,_ VnX6w{V. '++z˲`kiG G}2 {5`G߆ lmGnN`PQo+f x988@gʎ:^N?89:l^lP|\-܁ߎP89 +h e 0x'㏟~lkhk0}RRV+/~o e" WXj1//R?M 97{?  { u./UҪAn׫x]I*Zk Vv/\-?hu޿>|ݜM) rcŸx..^(C~x>h Sv6#=? [eq-],_B?8_ b`c?0+h@g/89^vпט2g|M_c^=47-VdOu݁}Wzv _rA[/+OH.GVn.5CWy=V(3V¡ヌVIxnNn0̻c ~a^u2Љ!p%@s1)A,Nk|en WdM2)Ķ^{?h04rqo==kzJg4+QK'X?~4*ͱ̜&B!1zbN]]OdzPcF;]cn{L˵Ȑ gxGj7I`֧`wHE:K+.Wz%H+U><ƹJOҋP]̅J,RHf#ra.tAp0n`wP<0zt;0_$#Nj$kg(N _ i*bYp"o&|&uO̹a(=Lz̛{ٯTmm {$%Ogi>yF8CNlLJzMRӵr|6/ u޹>Eي(`wwylzͱyѬ#uAR!aֻ݂߾I9ݝ{DJ |M+0U=U^2fc ْHGʝҡ!S_G~cуTQ`^GyO$wdN*PUC V[( ϴۋf zgR$:kP]#C4>E<ݍaޏqti mWt=$kHӧzpRԈoF%+*o^f[Δip5J$웨q4ͪx>#ߗ OMp7(MP%LWq.(jiؗm#YbG#AmLӿt-C*TM<&Y?]ZiJ R EÏWB75~0=0Mp^2!7kA%ǛqI[)23:n_/IQ⋔"ҼpRp72`wZTWWU.>@d.~tj6 oBSCsBVj]/GC4<( VR}|ڋ|ߊx$иiGǝ(F)ꤦw*c۹ҝjGp*am%y H61Sg@mIp@~P"RPJk+ 9"F2}x:Ǥ^r }Y#kQ;pd Hyx6Ѳ;Fi(_{->5;b)Ut{7ci*I\nm7GX@i.ߋ&}a@&^J>+a=*}[,O(O0Ԣhv_;㳩HUqvS;tK4O;,Yŗ3ݛ v$&\ueڷjrI2jKoJ[ɴjGen{ CBJ њs!`4?|PuTE5ÝL^}&kET} ]mzcJ$yÞ %wFXENa:;&clP\2}7N% ܜTߎc,ܒv"%$hD YSliF&n x-\![HlKJt+; KqK]}cYlGsf{bL 7ª7YUț^oL}p*cT,Å}K5wrZF"'1q*ԿXZ͐vfIPɭ+X>ĵ}g\(Lٸ[:4=d΂GjMpYhj(s:; AǗc=2D| -um/A5˵[kL+ph^ )mn<4*MoQN~負'Xp:y՗@!`aJFSbM3ťc9P]%oJ0 wpDIdܫf5r@N9%٧]S5YyH~6NZ2L%V̡KAcU3Яz f BeTZW6rH4GubІkڼ͗vbFnlQp&Z5ўԢEgN[Tv J>*C족4:52eS+}#s<E|=>8'*KM۹< )4./Ǯ_t^ WaREKn]NXJy͠"QJKSDX!osQ,l]5RiXǍ+GTD~4bOؽgNg*vm]ʻb0"+K} fj6-EtJb<%" -YXLj^Y2ER;%nC\b0q쪅Qdͭ'OBX6>c<,\*nK Tߌn9FSxnKĸ.\am.K<4Y0 bF# =ABZ4&|o"*AuDQ{:ULɴ,x֘ed }U-[>^|s$]~Z|ߊy >i`4 E;iy3907$,CRP'zDR U,oojh&+~o's򪱣beS>`w}Ee\#XOMpowu쟄L\ mBIV"!?(<ڄ /ӯX_EbIsnA{i΄dn牂 1oNimv< .r6*7$Յ/ gu4HM-v'5^e~h'`/c܊EBRJO~?{w.) CQNA+"MlOf)ZV6?J+j#p/&04UJ X],x%cpHMJ $xWQn3P3BdEbm{.%lu-TVz\`-LTI-VueߔN7okPVKyo?p2I7K{.,%)Z6&|SG F|=[WjtdDB3XH/m'ě*MD|4Tq&PNfQV&U2**|QV<z|v lnќƝ¼^>)`r1jRs'1A2Dtb5h@=yfq=Zy7?+.f/ʧe{C ]r6H66HH`B?N>}^?EYPY4{sB`޶)!/68Q33!|- !ߣnSDF2xVعu:~r8cG&su-iQv F;`-eyødQ?dKhI{PP9([G-ͦ@Bz:g4s_H"CK;,^Rv:?_;v8ou\_[ FOvdp<AJ•R,E֦.08)G22hAhAN :W%{7X3 }_pf7,2-ָ#pDĪ2Nן{l.0-4O=^9Z*>kj)oIswMbKJWG*OE-#cjSEp{-73^2)VHM=O3sV:~H=G);dͿHU~i*. a<]޹n>T|{oW1waQV?o.*&Em~J$]wdtJh߶#hFYJR٢sMczB%gxG<M] +^s){csm5̲;C2P '-=kWuNBjKloڑҴorS[L"i~^~]T'D ?a(I8 {өX2bXTTv}-qw0ߋfX }&w'ug awG8Dv 2N"O-b'Yu&wmXF;9crX,jt(j5s1vq#9TD"evk3A<6?dbjt`MY~O,jxcЗ7uޝSק-(sg߼1rfB`uFӿԝSD5H Y{3{.dRß3C:]=p۔˰X-d ~-ȸ`8ōsZ~G]r /ѹ D<2<UXv7,/[eV7@(ЦtڡS$fT[(nƨƺa.Q)xp0as7]r9 }hXɽE6 tZݎBp V״kGjKRڼ!5ПJRutg,oZ !,2|g|@(eċfFҥ@ %YXZQĜ=2xs)*Ci$HhvY@{K#zBT>{鞠flbXknLA`SjܬIZԇ,(3.Z۰v7| vi_ ԣ)G [vw6LWv%."XFG'ͩdiš%1 d%Vҍ0Mf|}HV}NWN[/d}Y85Qf|,Ƹ*Eb+*׀dkQ&6i`.PN8$,;"YI a3X)Yl'{OOROy53ND@vʥaLtC,#","]ޱfW䩥h6:"E,ecw `NƖn3:< ;!_~?/H1I9#HfGpePXSB8OU7TOMW=Qcd bqdE%6["ZW`Ykcc֔ĢH.]V_cw6j͍[ 7"@8PL%LL ~RVQi|A1웬]+i1_]R/ q١NDݶbW霯F#+X+>S_W'yNA`4Qh,񑲹\eO; } z><(5m˘$/s1G}oNe_e$c, oCy]@DO|"ƀzwr~7Aj?YHk?XZ݅Cb^f5ъBśN:źO&YAAS?ߧ Q0eIrq!)@0}XxVCk#JUrGH߰J]o'8VUvl2#)44knJ=I q4]1!kZ{tzXW(>g.X7M枵X GarHxc.K9B.yA˄kzv砗Q5Gd6×OMEwWM_vVrVWɇ{yqrB>A Ҏx#Xmi΀j&6U&DiE&('$`3{:[=-gBZoE g`k>1#Ls=8JH9OjH~s%jNDMW=-La fټ$$[wO_z~sOkmPB:A,E4eZ9&cFu"kB{1BPtBLE^߈#BjeꃰPwRn)i2B4'~5dD4jދC@I]a \+7-w(`^, O3U׼R rN{ՖDEɫ;CX(CtCvll0D\bʦC2'vHs`n NFPr~Ca܆ʿXx qZ$q7Cc{}< _ě_;&ThR"fP(>:Ե ߸uGj. O3@H@pZ{%]Jk7]q}UQFé\I[%#/Ql|L|ZaX8?mi6AOY4#-KP@,Ohc ~\~-؆c1C~Rf@\փ!K-0M0i(dhZ֫q4DE5#(z &DDÕK\5e^ȋ,2Tpgj~m`ŧm=4$L_th.uagP]c۹7d>D=tO6ow(-ޠm1xEٟNaFDVlpϵ>1U#8wcoAep/|(5>vѯ;>7^38OQ$(a1S(5#ԻUU=&jDÖXC|VF" %*#1Kt0ʁfa|5^q S*wTv)fh *9qct2( ~/Vؠ ồjqDK~8xA2gr^R6:J=3tqrVȧjVГfGY+d̉XF-&`2IȖ< [>+K\TRc4=csANָWzOYD10V yPz \#V{>R@QHa*zy]&\Yh)+󓴕 uR^~'tڑ2#P DŽO=r %9o½*x˾U2Ŷ6Aɨ!ߠ3 mM^ߒJ}j^5u][0K~˓^7tuL|x XϘ4fYUcUgE5Z[޽ޯ;/uakL{]jCgߑ#4;i;kɆ%ᐕY%z ~W$!Zz(R~ bl}Hx?Hr1lozE%t睱Sg#+ ڣİQoNp, _.@ԧz<8K3 Gh]~(q2e죝vg.{v\]\ۚJB'lBߔND /rjbP\V> Mt"v^g=ueRO#I8|"Icr$P˝ۀU4?n^`qd-V9nɛ ?7NzBhͩeG$H}w=$X7>Ō[ &d%LBq%?K职vr&Yhʒ`fJp(є^h 7|> 4g| yI1%Xכ_{w~$yfdTk_:RŇ!Y 1'{ 2)!'ѓ9Lԑ8RlC$N*iTdLNV:܄g.j~i=1/kJҬc솹 Ys_YFuݗd$.5EqH::Z3d/Np>gNQ"HyT;L?°\~Wdm]1=^ϯqgc;#YgSl4ht˧Y0NA:r»^#5ûSp%З FbcQDݩ"?TU׹B1#47,NŨʩ3kxX=Jul$?=ѐ(uĚH綤 }?5cP>)n2[Zz0. WѪسUۀD+:]ˎuqͶ>88bj)!?˦.yϟs7 /_R^/+6G7VwV)Ov|Ⰹ1$`(VG5RqjVik+y .d$Y@9L:>JScr1~VKr\RK2G(f)!` ^ R=IJS4ا) d g.ۗ5 Gq-KzsuV͹PY|ۀYɮA}sTR/];nvyO nmV;.,޿Egs@X%Xk;?#Φoa86>d%z}[z>R:Gcu U|~Q HMi CwTŸ<Ѽ4A) ԙf?PD53 }RKi-q0OۂpJ=/'㴶O #b;}<߾iقaMH~ {_h7Z&=eqƣF"MasǕzD֡-'CY0x`MnsmHt4NrUX|(S)a#&/lFOx ھ$?8RTpL<Z{gb] endstream endobj 9263 0 obj << /Length1 1408 /Length2 6330 /Length3 0 /Length 7292 /Filter /FlateDecode >> stream xڍvTZ-RB/JHQz{B$B TAAH"]:H"ET~Z9{̙]34QrB;(D, T3`uA|p7_ 1U(oF}܁q DJ"- `1@U/ ' F>gş%&H v*y1Hԃb]aPw c ) B=Egya4{1p'rPD|@SA1p pG(o h =&а[]_{T'2(7ʷb& 4P& *%~ZV?P:mԿ!jH2j< :O4YiL_}7|C]Tq5+Qm/Ԇy G~U]3+Ft(J?ě+u|6M ;8NoƋξ0neef :S^Of+.)J`2D.};xRڪ>Ftts᲻垄kg잻۸ R-gϥU<$sUN]̃i_.i.}k *.#*uj7!]'`.5dI[6@'TA+)IXۮ:Xxw6.A|Z(ͥdo&!uU{Ч?{aI(q$\ Dn)[/ktSQ($W܅~~bnNN<g}_ڱ y}\aD< !x[0=Ԑ|{dB'-ug|CkFuZlk.>ALk]ai$IC=ڗT>NSYM>Y #ǷfA&>,Z.%K3je󱝭LޘY1}z!PrWokᱡO}к uצ۱Lym)НKr.J$-< h ߆9F0k&wR{n8wr 5A 7T:~ت4`iNV-7N(VJ$gW3ockf}CWg-D ezvb`fZS]}ХF ug ԙ(,=$R7TVU˾eYDMsҞqyiҖ ';rG$Q3NvL>'{;ژO2YLUxZjKi{_NV%SL毶 =5!OPv<-jL=9!s[KRDU䈅Aq'rjgӮctB5(6OʛHbR[7J )?U{ogNv>yQ!NrNǝk0Qj7i4hrW>wv6+G6Q0IsHaH?*vY0Tq}2AX8|NNۡqF!$WJsqןi$'Saib;=2kE}Ӝ-i.r:{۬x2.4>z1j?X(uRuS9|$K:F&H*iܯ9SGfL96# H],â V$q y[)x6lU@OXt?2YT ?&<'L⪨I~LDY/7T7ӝ&~%av/,ŇNEkDtc=5ʟDJ{%^Խ_jnvI(|^@(2*r 7>D27E'=%XW 2zǴD-36j,U:y[حYry1'>Uak[)2єm]h>{񈮓5IesP{honjȽ+C5vGԙ;5_%S$Vh|yQ9[W.KGr{A t.Zq7(y/7+NzFRJ=݁ʡ 6*ėmgjNn˓x_['[kܘږ[67w$}BWr iV֧ ݈N`IU* me{Uw2hX/xz<s749I|lfcn,Zmz93^Po1]4h ѳ׮vox"_DK3Ԛ]mO6Ț1{/~EYEkaCo+\^LLﱷ\ZnX4}%F͑ kZQ@#8nD&Q>ϕFzcMy9p2qwn9~կQ>nD\3Y<%-'`20F{Sʷʜ7t !hӵkQcI}/?ȈFu@H]I Ru~8 1(iծtSbYH^\⦹~uiSwĞ,5ʦg`ok|RkN̝ЦejEz]k{_h%0 . Σ f# ypZd[ezyj T,%1ZϡNkc XXׂVq;?JRy!R+R6k'ތ~^h0t{J5CTRPz8S.OPmN45'%Z3 Xa(>yx XZyr0#خdO \n\J,]Q7oB(/t %;ӗG[SZQ,zф3??Py:N\ ᢏń!׵wT|Ty*̓IA}ڧ,1g Zخ"ǺA'゙uX H=*\\ɭKKI;Em(VYp\}=y0jP-#t]H}(Χ4_,/S&؍hNǍ2&>dU?`3RbnsjL}q!$U˨!Tہ|/3,Y7DS}cFKVL^ w^}nZxfcgs_wrL9 ؍ GkLu^2ÜHZR䢿$''c tV+װKT #49^3k HU qŒ C8vEHp,voS1W\K:ITf)oQܭp\&s ؏)bڷ9Pߢ*G{Nzˌ^&.HoVQҐRV_1^/$:/JRjԦYضmzfH۩^֐\ d挗 CK`3ES_M-8EN$W)yӛ}k>f0,clOYқ]\8eR6:Ɔ~ہy.4B(YBhv' CpX}/T:*c{j648ʒ/ +En@2<^AgtmXjn2ynuIZm׃ePSQKlBq.̀%ַ#^+_0?.@ '%Xm-5K$*f4~[Ḷd;BCa(P1.q{28Hٵp*-=K=و+y楾ΒGOtÌ&s]\].ՑWc 헩 d%Rmf/'X7uxqgCJEJV >dEīa@ud6Do<_$A /30t#$G gb "Rf=΄_iD4֩r*i] =3R>:`/ַĢڵIϠ3AɌibH.RLR,;1("Jar%`aDNhqP̥b#LLKhoJ5J's^N^C\ cCH<2Tm/5cܵkFs&=Vp;J=>B*B["U|\#(dHc_[`++KZTK#NKCʣٶģm-H+|C0e{~"Ypppg.~XZd4HHęt12.\8Pϯ$ 6+6+FWt9TTzU-.>Ybp/S`;nOH9~ѐZ&zOm ;L'Uy><{R)zY%kȊ_vb|^S OvWܚ-6yqxҮPW])26X^Wla ݙ+K/`#lD;'@S!lg2N'th8<؛MD O :ݶ/'Y9 ,ezCxqHaK58kFYvҾd/y nwQӔ$m+\SvW ͳT y)s2 YĎt}-ܟD\ w)Ѕux(F@ $tƒXC}_R'WRyڽ2-Joi>)">5n, #hl1޴|CջQ퇨G`QAϷ/c "keHӇ/s<LhgT jDOV9xr:"KVC][4w<rzQnԝ.Ǝsr;C{lCfggL~)~n&V. bϨ2ڭKr>VO#KMiv:;uzAD6.]ަai$iXVX!bU-L\&TAׇ?J!KgMͿ' z6K5,8C.>*N¾x@ Ԣi/H#.-u1>=n?2Iw endstream endobj 9265 0 obj << /Length1 1620 /Length2 7489 /Length3 0 /Length 8566 /Filter /FlateDecode >> stream xڍxT>]Rf  ]4HH R! Wy߳s2*8@0(WO@ cd!("`e5#!pVSACC G0e{$JQhzAA1)Aq)_0@h  vvAr%%y~Ap0 бGQ ! !ge9y>` A_%tAG 0v#>p@@2:Tt6@CY O_@ :@OUC)C0=bR=@U`@8C!jfE"~ 9\7( utU PS9QI11QA `- j yPeN A@½@A)@P" g0(58`) @'kaP?G̯kjg a^!I@PPP .. }{y #]TJOp ҅ pCt+Q ML&?3R@~9P`ߟ(z!Q[CU@R =j(F `_> t5& ae% _2ԒPE"jW 9Z6!Q1=nG5$ Dm#7|Pe@p ~ VHou}@ , (*N·w=jWl@(mY6nڔcͽ,@:1_7˙H4ucޢwO8aYdG)$vXifW[/Bl=JI2 ]{O,XVVw^&O4-s?}z?8%|RW+VENCT0:DCƦ(zTLSŶi'sx=eHثYW)fLA}ۍ2gLm>SN&w寮=@fʥ"ךur&$M`wI?`N2&)2&3BŷT&%&w;X-6L&E&C"D1~i6c~!<®G.veHdp^նTrI-ycB߶Κ bAbӻmw>L3ɞaXMj9R՜$ڦi2r^;|PBZd#fIg2. |zNdai27DMaBP>4f "U%˓8j}?^`J\O쭟ޖ'rN+NJiT YEhʱкP띚 zF  Ż]/v3]Fz\֤҃ilF[*`m2 C _Kkƃ!DJրҒ^N3pn{:{ A@`/֕QeZz4Ŀ~s7C[䴙tN!/yH2;&׿}3T-`ftJbUᾘB)֬I70-.O) S SzeF>D UuY1W}oȥ4<6Tʘ/7Pv!!)'tKRиԷlY%/ux.thD_)@k=6EmGqˢ֟ -ڬzE{9Qiw.'j>Y Ndidv1)ӑ;kؓ[M&YDɿM9Έ5lpjFqF4U Ob%ďP#|#9N@ dz99k#A?z BNJ~kuC/_[$꡴4_еbDdngM!2r0]vfEa#M'U?~]df)ԏj|U$:v-FcT+O3'L߄6Vʁލ?ݒ.uu3Mk2uJY64Lrr4Ӗ.ݾiߏ|ܖ2]:Ȓh<)֚h༿v}O#}dS8Y ;8d8aѹ$/R},13ZRSߙi"9 m5Ѓ%k`'IZ>Ο<mȉfbj>>{{{uND#fc.Kn}i|?vã| a!gyKί_; jUUƹ~ *ƣ SW_e}g_af1}OU ^a@s>i^Ї+?PQUU~978yA6$UKo.kKv#W6>T6TWinvh|ΉET:-Ps^%fvG ; 3d}9Kc+Ě{G';6kc)ç[zR,DC|]4bi$nS?4j*P6>{WT/Pg+!1hc3C!Lk(һ0o3GMYIvU޵g" W0]hiC6f=N5aukǻ Sek;݊ gY%Uۨ]eX`ڒ _:Ow7\xu0I{Pwvw;H\>aNmFA R<ƣUlYb=֍w沚Er !2P"Oj Y ']޻ _.>BNc{}Z/_v%S9> PI.{@CBiB?wcqsc٫::%mW2˔?9)<˃bP,KN,j9%)zi]X73 d=rZlg pBO-T{ϿsQ]{COfN*i8 FƝZk2V׊/pڱ.Tґ1u0 !V|[ϜgOTV,zZ `y%CA9l._nQ^Ij-\II;sK'H~mNIlwpN:A BU2Z`$q~dUyso˘KVY?#鎎NASC7[sʦ.Z#DW@ mR 7Ӛ"'YL.۵Ƣ:,@rUx`G:\Fig7\7w9,4x!v/JPn}QSj|lBA0i]}('|b2jLuSZ9\ɬV eVUޡAh"5y}Ǻ-Xö1!JxTSN[3BDP*׫X qHpCtܜOa^OIwOWwςu*tNKHSy3&GfcIcG(2ǖ'jH2y<7x*3iws:U'.ZuPzlCԉSA؛/J3Nѭ.  /OcG"I0νEO'_{q24Hh9r|Mq\fx;* _G-IЯp_\%Өϕ''!Ƚ`Qbӵj5=Wq &ܗ~[iƅJWjp5~RQx8*7% vjqt7W8\e+Яycf"Shc܉'ZvQOdt>w!XC>O#Hri8!5J;Z'# U1b\>>߸:0n:hgrT~Z,q)[u$lY";X[hi D̼U_v|%%׋LO12 )[| u3VR\щ1b^ꐾ*I٫9% mbX4Z0I$y#$x^cDI{Sh;_I )KiiX`DXd0*Yd'%bp( ǬeB뚰Rwr4HzgKؑ9(yHgv1u1WJZ z4o8}JMsFz-w ~a!QZ󞪽,MHcӸeLj' yy~3,X %,GC};Hdl?3 )[~_n[MVKO]zyOAv-_(ױkkc = v@J&% }mf^ xZ7C԰cޙDZǵu{A\%$_>[oJenM<|/pF6o8it񥟕>spryPA (UQ脝[-WguFdZ\o4吵Ǭ|ZVEq[WT*< S)2j9'o&p )Zw1soӘI ڞ]Ll9uWY]|'Oߕnq/.(tXcE5.?_j4.gר4ӎAx&*w2a_* \YƠz[c-g#~P}]Jk8nLq\=25S\T }@bЍz#$,spUJJAGz/Eĥ99t,Uw]4 ib6`x%]ɉL۸$#j8]!YOy.ߤ⿥gplxą V$ĝkc+] CCퟐ7` of58TѸ?F[PI)BJ |y:c}nvnrÏiSc(BxgMb%ǩflвhwtk8YUJZ-uh.b>J OzHv׮m{w.\|Vy0JO~:9B\h.L͗8X&%U .er}2Uy{_"^R4 t d㞎qr8*LXx7VH1eTwU(5=`ݺ>٦dYƶm9h@gt Mq+ĤiyncuKXԖ):0=jٵsA#d;\|Ÿڗ"B[-8kv@#yd942y=t p !J:UtnvWZߵƈ7ƒAZ~gBBܸ9+vqgcIr^A:^;@G1;G5ۏ"d# sHQduQR#A > B}+?L.+}T5:s~ [! xf:N1IG/W-Tz^CGh1 5f7qD*q߯` _#7rʮxg߆M}\+_{s}Z!;.ûXV&AwNϖe2qM{^:YҘВ[eQJ LnǺ,쯀ͫ$bWַ.nH6xj_$ك yt@VV)`5Ƞg) wU|`jM;6'I%ۮbղiDyâi{N!J5]I(^n Y7T9o^n AO W^0 %w:gYHiI&#wÌq>QW^'w]AZgYm$V镀M궯 'ȳ֏^Ze#v<{V&OD]"jG{wjF\_޴ V'5cZ6Zg#}!_/;?<- Df( 1DXrמ܈"%GV1`sJ_5viF>0Y?6L^Xit8aܳetI̻|{C:gM/ojHd3.T*药_˸V}:QHԵH⳵_d`9/G4v+igv0,-7 mOP7*jX NRx^v}ZE(/# %,'3 X:0>te|u37ؒq#38w"D6^ `"*j0$TD\XOI A۳Y(PuwN[ CIA֭k#?{{wO֪Rvi,5aN endstream endobj 9267 0 obj << /Length1 1434 /Length2 6408 /Length3 0 /Length 7395 /Filter /FlateDecode >> stream xڍTTT]K@cP@BCDa!f`)i.~w{Y뜳7y6@y =#1 > &0"]`sGB(4F4p$J$rD % `7@C]8NH- Ϳ~\nHBBp# 0v! 0()lQ('I ݝ@pP] j v錟o s!Q`$`( "z-'(f_``{6kΏ@V.t< s[~W(j9\]`ZJ"J\~էCB!{=ka [Yj sv*傆l(8 z@l{:AA`tN'5 /yݠ \@+DgGP?k#a4@_ϿBDoY6FcUx/ PĬG_-AO7wx<"pf;h2.Ϋyi>*^raML>{kBL4*/(hi)y 1~NaUO&߿Svyk7ߓ2ci/4ۥs9'H=5X.gְhPx~[381a vۃ)Bظ"XğBaɉ^T5Ȕp7t@Aj;XȏW񪛮__, Mm}gKH?,X$}񮖤|BvxJ[>ߑ X{A>3[Q/ha 3>`A(&k -vs |( |\2k"5LփGk߁uN\\Ew@ d<85 }nM 09eyO pb#M?$#Ⱦ,\K1}/#.jH瓾0ASqO!$ jTrc?~|xEpL'16HMI.Z|*V/1_zVFtV>KORxON:~gyJ3to=k sto?W7C*F&#rx>0q!ILQ))`HGzkUd%-Nծ\ %y/S.%AnDםH?.i>CnJKsUCm$2E{G 4WHkD>(!>qr҉_5,) :Q "C@YJH_obW$31 x< b~.21}h~Qw?&.Z`Y=IC Q{R,;mjMdz4lBC{˃.T W;}Rf2o6Ѩ0:G=UJhX>#36>=J)_efOtݍd`|lmo3>FӵWjϞCQǕƿ'G[qv6'ݍ C26x3mN9w~&!ק] bmz#pUý=Uf͑nHO`{]22(mc,6@%G̔hL#fN :ad~~COHߊ1,7b42SÀNnVs} !=ϻˆK#Wv{e'!"nosaOࡂҢGqJ3V[UJlÏ}}_G:+dL.,?]b]z4=%|ϭM{]@~jU s!׀}KVݳ`Ʀhb0qZx~ra5szoSJ]B>ejV^x ,ɍ(= -s4h(w ő~#|-M X4\fRH]ễ5NP$1(KFhms/w}JhxUO L%Jp,f,{F_Gv],xbn,X q߹I9\>˟ #vٔCؚR>nbHCnTgKW D (u(rg(ѐg]C53>ǯ SAq[oۜ?3}t6I!Vl`u2`㐯xLQ}L,(\Ι[.b0bu d+bP_.s֐kḼBz8i='BӋ0G}r%ʎ}ҽYfSٝ{w.soPyz$igBׇ>復s%ML[f=th wDy)3[YyZ'~ǹIZp=_+7J֝Nt\{Z4{Y6 MO| g"b9gSBUiqL1$F٨,[ jFp/xE<9񫣗qTDA^E]$UЈX? 䄊627į)~y!MT=DL [=-C{ͬ.s#(3[Lp9hDBaR|#jMޕpѽ1"dp hnwh`ۀoe[4:NOSxx.N$Fv)LlT)21@lUuBvu&qYN"I|EVXZ͓l;VZ ԳG*<z}vjŃcT8~'En~# oYjqCGܤ2fP&fW{T$=Jj}Fc%ᥡYHeSFHK5I.G?v<]!)|%Lo9cХ:uŹN%;*A]]E-p{^-CūE7'Zʂ42Kp$pGpN/#k_L~Lĕ'[5Kޱ5N_0BJ'7EAk^07|˜X`-);lSivotH8xb[dh`ȠQRfN͜g}zRyْ ɝa6/=!2|4Ҍ/U{)6teyղ6??mt1&baӟҬ*ĄҮ4 M?YּfN Gϴ 2}(Cܰ.|A7PB4qe #.jaMz5{zkָ'Sdmğ˥YMCyGNpF3}N$XvI@2~Tx 6#\ A\YhQҊٯ=̎wèP<&oaq#:!4LYPi\;W.p~Ybz"ʰh+\z xEv\2MZGWS 70#*в{$]`@KE2% hJAz򢘕[jΡީO?:1 IϊާBw6xiwb4FO gd[ʳr4J趔tXE'7E֓y݇{OY) ^&ՇaW7\l2Jg p4 榅 F#3^e ؙ6I%Ȏ2H{D~!xj# iWᶑj^>!졢M)aŽg+}>m.>)hh }c[k6L5"uLp%]n:dF})zؚW )5a[C:=S\K޳D XϜo1NI;*V4EJ/p1 *V#y7_/?'Yfv(0҃ _  /b1|*:o<6Af:xo8ܡ:}2XCF(nt4Kt2&13Rbx`M۵XsJ{Qqe*RV'2y~| "wS۝oґ_|W{gc诋 vjo:B#>9Tv5g`PS]K a)t<"h>n/=:7@@r!ȍOw<ۭ[6CR1^b BFl]+yLj%Ups m5`lƳ/H:d-N){ͳ߬0]3)H7띍bqm_oGPǢ|XTp/ECxF2)Gd %+TXJ}Pi;S(*neice**IęWlpM5C5L48y)0MH;|O@`D:,0r W~_ғ-:6kz/A6iGcED ~8 Lpd搇r_iM\ h1:P}<]_2L\@!/wz7өlOi">QrX"M(c\N?p H-j-G5>N6z%l2;/sl%y~{KdFIbxчܧ4Ks&G\+/N8*+<ў=Xv!9~ܤ]၃!`[ϓlKjWM$(8^&M/={]&[>*l__ endstream endobj 9269 0 obj << /Length1 725 /Length2 14862 /Length3 0 /Length 15411 /Filter /FlateDecode >> stream xmspe-mc6;ضmtl[ӱm[;~{[ﭯ?SO1֪z(H$A.j@Ff^333 B hbe7v4fUOwttP;а56rhڻYZ܄ݜ]\9 \,s+[ @LQI[FA @-Nƶ%W[+S) ;lLAfVo 7?̝j" j 1&511 'q3?@SMGp,'`fe0ZXś Srif@]mmj1{;W@ {w'"-5-?2.!>%'ﴒ_,U.NV]fI_-[%*j ``qq}\SW'' ߤ3 ¯.ٛXUITBL-|[EmifxpH4h"s-sBjD<!_.!|U.xi03Uq\[ R`=u,@b1*BJXISg|"jPg,C LwWw) - +u .tf9kFڊ]KZsL8^iqw}Hϐ J9%)w4Z^2UnJ;C"P5"ҦާRtqM+;tVb,ke^)lFI Z,!&rgGa|n$뷦_7O\4x{ػDi_(,beQ Kc iUa7׻y3mI0k (_9 3Uh@S;Ců⓻O0d6*D|ĐȰA.Y2Y 'sK>Nnt$ [_fhIsze69`&wzt|7 bӼ"ƕȮE媙f iӯ?= ∜`nCh1y>w,v%nVɺI/g>ą ;4--C1ޡebDuyUWLO4QʩJеjt_d/LH 3ڥ$!NLrhB67g׏ ֿZj^f25B0F~߶5 ه$?x{4LeG0G^vPهH=X{j2ޙW֭ :d9Wh% v)qm w:?;7ҼK &WNras;y DFbqyɐv&?EVpK@z43ǧګHcb_%76~ohͥzz'=6>%X8 duN,&S*F`+~ ?$m89弸'g{Y0-B(N$!ʰuu+q[C=Я ta/)S^r=0[#*ge`&,}4m<÷c,e.Э% q>Gj ΁tj:Z M8mQUKn@F^;L)'$s[l_wEA6DF!X*m~J5&gn悩SMhXa<^<è@b_!vO+ZKCGz9=b3R4S:ޮ@ 0DÂyCkuzbn) T9v|" Dqѕzy@GrD<1uJ$V`y^({?nΓ²]P8:`Ț3>* :+sg t-FOw+{?5kKCI3.w#D`I raN ɗ>В) 8\{e}rϤo +$C\Ål q4&5Brc['zɞJHx]ZlU#V9=!&.RJTфioSg5{v3Ls<8/+>uFyɾ3KL_煷 ܗ$\P4=^%d86B#\ztt g\Qqi!+y[᪮W"I4MNy9 "߲"g 8p[\e}b ڠL6HV R_lo$vbhh[Wy˜w^]&C<\}ER'Vv8U75E(`V,Q_bk0Ƚ*ٌĄWջYF.q4y& -qc`k=~Xi!VC }xMwWf|,^LV9@#JR1}2$w:~MQrOyn ZF#ydo`j6n>jMEL.%riaȸNZu 5{2d)f}#s$T`s"{.}b1Ϗ,c,:!DYqד~D;Ni.o1 XXi$R h[J-amٚs!KЇ'\ЪwcRf̘Iwz:L˒N&ѠAQxIζJޔ¬tL^A\/7%t8}FJp9FMh, 5gn7ЁSBdc;lrzNj:hƈ7CEwhgfzAB_ c.smo@S֊hڮ؀60ϳ{:;ӌ'XKt^˅.`chtڋ^#1ZNQ`|! ϐd5N5;S]Y[De\I 7 ҜۤAE&FqQV+֋jWަZvzoX\1/a\:6CKNu'ycܑ9͈r<*qܦr)L#B"!JZCʼns2ŁFE)MkR[FITߑo&)8o#TDEpl?E, VbW^\mYg$&+c) ?ذF!7^aUSzrUfKJLMf$FiZqQoxkiUV+L\ER]J҇%"aW_|}i7Lb8{Kd8):|#X'wwVCKW.R*n E'E \| ɀ  |2R0ΒyZ72=1L¼z\u` `Yk{{TdBߪTՏZ>$6c?gεřSWN+{0A6±2yax)Q,=A>d  Io%5Ħϵe[vx]Sc}tEL9Ca['t3)!n.h@v%^|uqiC/t!Q`/i\_Àp1uI~H؃ ;9{Ѥ8s*M}}r{vêel?g&_>h܃[$\~QPzl8-a6R^aqmM!woo>8uu܎E tBkƴk\,YlP&POx<.#O+;LԆ)Zx1lqxTǿ\V,OXQLA/ӚIp%S[WM7+YcC/(AB.%)2׬,'G7`i \(>h+Ry5cʌu=mfYnʡe cLG{˟(375 HITʡEL:lf,,+A{*a &e(6OuWjӌf0gA;]KشAC)v ^Wt\Wq[c^Lf~[d펶7#Bpd&&͔6V-7HG#K8aPNleoH_1G5,BG?5-Z-78 .C>V-;^nZj? cGjp&(49'^7\mS37Մ4votB5W.@ qunL4kVG PH' kPwiWRcX7@ӎM˧"WUA,<:/p]"k|ѵnB0&R}H7#ja|BTmPs?sY(S@8]!53W]V[(j,?C);OGWMgz0QF ABuʘ)ל'Tޱ=y{JpʖK5D&Y^IkLg2O$q59F8FJ 9+=OCWm2pveǐ{6r~JSi|؈MNJfs7 6T.z= cͭ (l\L(gr ϒr;]?a7dfFOj:ש} dwP;uBJ9z8OQ{jCNL#nV\,y I'O6SKT}gUUfv޾*#JRfA7` 2U i;낒jAG*Ϥ:U(b)|ݫ88ʰ5u^{vx_IC4Se,.A2̃Hšt Vy)9k= G"K/μb>*E u9kO#41`9X*Jw?/g?$sR X뒉_aH|* -T ~u{0F܊% "FW |cY/U_6Q1P٦eʃw[*M"<ßR@F6DF1/k0IJ"󫈏 Fg7,NTl. 1vǰ[xp16<="&p7z. qҹ aҀ>#@[ I ̒W9M?He;¬wyC= %Shm#?"ײ{Q[5EiUپoUwǬ%O\Q*-l% i> ˸@ ׏0#F|{Vy1S3LO *QкjLVU)g5ZcaQ9EjL])q ;an4`{dWؾPRKHXe*wmћF% n%ӫ'W1a20V]6F6SWr;=5RcjWtY5\P5Q\r:˹)mۯOj IHYR4]2:3a]hƶfc\lչ!K:N5v'1PnWσ4Us>ffv`c<Ǯ?3H>N2p1Eܵd}!Ln$2^`Tdh=BWss-04KELbn~ӽI^ r@*dO~,拵w 5cAi?Ⱥș{^:Hkw+`L8kS?Ea?1mcʸ-T0v(Ov2P/<1ֲrV'$T %EF4g(sS@A^<|b0(7@ĿKB+k(|a8}}N7Q 3b˝O%뾵-1YA“=@mUAŕB9Z#VM;%]`ҘJQk[ZpYBW=dEF.y-)lۭio#-3am2jzX@1 Qjj.oaԃtJjfI^-U+%9@I=PՄ\tIt3C ;vbXQ&9p}_qe]{rY|A Cx)B '9,+L qA\}Z^^f~ra8ͱ{i3\2ET@ bA{=MOUSC+-zXd ŅR_3t p_[HǎPxaRkmQoj*EB?MB<#"+;BÿIIK_jWL󩈥[B"|>Lw#ʹ߆N?xwv6 {83{&n)+MJCswr(!sG>X?+%j}cw ь:. 81M,K}YMf_9%Ԏ44Ad{s;nvXd+!<,h[솰~ WwڬdԶĞ_|֢ {_T-qSeX""jJ6OJD;Bx  s:`+<-L'[#K`S#cќBAGT"S+wǦT 5ɝT3yʕBy]*RA;ɌM׌@ѹ cЖD(Oq۰fj2@#~^HAn0 9ӫq9si=[Op&ʁ~J 9,fO+y ۖrkI?G`X5B \[UOBhhZy3)weK"`."6[a=`H8'1 m<߼έUIJheowZ}=.})z{ ZB*ĎJ:ȵYߖn)NTq;\W -Xwd1]S$9%܏jLֺ$qrj-M;*k*ȹH9]w YoG *߉ީ Ln;kP@7@lCg E,@]&#Y}.DuS?𖌦OisXSQ]rE?Þ.ȸrH?ww2QŊTaďP}DfE`qJK:c.̐Zs@T}Uë9o~\m|g g=H%0$rTIj꤈/3=gϊn_xO.ỽjL4mFyAGB7uIѩj ҿ=9`;6c\L5{u_SwSL=U|xnPTzy ASxJ-1;3ddikއ@Vi/ot[\Wg lUŦ}kRj!V}s%x@GC!=l4Ԭq@54(H%wrLwf0*>\0Ca$+= $zY=ˤ8[O0`{ ӵ;NI^x9E\N/gjN!EL(*6Z*z /L7%Up3^Q+cdaVL);gpy3)r %1ܣtb`:j:kuuVbGbAur,az+v>Oo5gæeP.&ڪ1Ze.-' 7 gBZ-v׮Q~xoݲ-TQ(V]XYUo-Ya6N_GD5nl.n>L:P^ڝ_ݷ @\2MK.>$#.dz}Nyиa)Q9m’8S[8;TL_戮'+_J2,ƌEC;ӷbmuɑ6G{l+"DR4.~LT:({uxNНdYKKᾒ"L`F?Vӿ?n!Z V\H5Ȋ츬 ԫfF'oǦ\tX7 )ZU[#7`*B3["zu#]?{Gѩ̆NP7h_z1a-œU{q~l+I.Ҵ4cgq W`THo̢2Q4'nc't9m1o kϻϤVVWmR3j&5fۯbcw;T鳜\чT{+ڎ)U5ܻ~:#f&6qdjr-[FԑFn37u1ܒ#pANoF{Iz-{L0;Y7YK7J|A\+Bo,wKa IҮsdu0YT K#zh3@U' 5F 40rM16?Xz@ zNH9\ėG=2"dPv p{iîT4U{L"*g&׵6{Qj#aDʋ 5hDrIǃn_s7ތ:4" [:+9נbwn4r{ݖ_>S/I nbĪSpa:[(Op\k5UB"oAԔv#}ˠu>~Ƃ8aYbzl9u[ef@3C(uߺ(匿βx[⯋:>hڻ)ֱl3[n H+i)_jeU6a.K( ]rTfXLg"&tK_pU~>u'p\h:.m&%ۼG fuv@PLeۮ'~БLj,s€Ip8A=;8\g<rJ++]kG>sk/B[dl,s'J!o֗{',EPuٙ!᪦i?ڴ^0xL2eiOwPG?[ҬD@= S@mR0sGE\bgV#kv1s!8Z?E!n;IBŷ/[>m+BtIm =5㘸r8ͱ'> stream xmR}TLyQ{?lhjԘhj0[s3stT,-EZۗ|4VێJ"16% mB[vo=g}=>qb %Djʢ39`bd2ζrt㰔@0OJ !Vpc2YVq$JAyJ)bJL|u-.M+a D"JCa (K@)9B0A$p !4! RX$_[,|((lXNhFh Gt+ @28 A!zD Ґ@p$*R h|L0(>GHd*U!%dR Eb$AMZx#!DnIO_0Tq"<@*A Q9!hXI~Jqh* h( āp&}Do$|b-Z%1W_+8CCqA&}Br&zKmU. o_3 e (].'ڡfǁEaʪ% vGm:oy׽sg=;4愷M+m˥=h6skɵmy/e>Z|HPlQ="&c]Y25;*Qf~`WYSeܡX^C79;R(&nHSfC+#wJ荷$qGۓMbZDyYVI~Wp.G}*<Ŷs =MSfYK3OCV>v\8wy䙣F({ :ߑli(.^׺7g!*is[gR mMYRz)Gؙ캙wߣ(#+ѵfIWDvuOЃcsNyE3^eo[_S|EQ3NN {k.pX^YOMg^?#=>(7u7EaS{CP>77౲WR'_vIͧIjkr(xIR5vk&)hٶ1bWw6y*dS۔uu߭)2R]IɈo.?ħz]PƆH kWVCweB`ʎi.0 v )ŻV)Uܸ=j6|CΏ endstream endobj 9273 0 obj << /Length1 1144 /Length2 1528 /Length3 0 /Length 2250 /Filter /FlateDecode >> stream xuSyQa"AXHx\dDg"B+1+|&WY#]AĆ#t rt&TA>Z4s:¢gBvP#X4L,SB ]3i̜!>@͝[q?,fδ6Ptw'alPXp+c62@gH4Lx`Ѹp;џb B;E`B !@5|SGa5 V ku^(o>H0fn_T06x)"o1WB;Blľ  îWALd3Ep?5wO-47˝dq\xӽsiiWsYw! 10uL 2)5,fμ87 `px.1"`P @7C0sN0aB0 Q̯4xf.=eςAp+P/AIg'ϐc0nYXm,Zn+t^fD6r)m`9o9L{c" j湥i0=gCT~Ф5EkcϝWFWO;T&#񺓛Qz|%1͏(u#%[҅S.x^Ѡ[ꨂJvU}E*&6޼d(۴dzt̬]ӣ뫻5S^ّX}Dkm60dx0t~zli^Kɚv󶞆{k'֩#%ILf=?x$6wjVurhu(237k<]iu4Mтָ'" ^&?S^PZo#fn=q-ޞ'IS 6Ɖg'v5+:+E-%F#/7삯O$1w_H\W8PAݓҨ@BT9>2hZJ?U7[qf*L&\꺪#oXl-Aih\Fѹw)}ʭDءx5{b 2+: M%w:~uxe[ؤ=j*/ާ z:V]q[e"Y)sa@&YDtd[~Lwp[:eMY1uX|ƹڪ~9qluL,a$+o[{$mr>[4|x~p7>Qi\XZT< 0\8e@<2}llDUޭ\Q=D-)p#1ve9k|U\3)J)}AؾގWuЉ<گ4kli3[}!FW7=81&A[%E R9etI犓%?Hd)g֍{}:drވ>~s@ҞhReQ? {#nq69WxKKԇn7r겜p=*VmI.xu$ #c|?M>ՙe:Y`{Yt2C eͺiۍ{6i8U捞5 K֭^]%+ ڍ#VE\~E"Pk~%lLs+ęyoj UVHF`iͶ8QO 6kKZ$M sSC] ąhv~B1Ja:`:>LcKRa-4&w([nR(UK}5*a㧬'R4>o R:`4V̷(2語rnxjo \s͓T҅ اPPhy`#qRãvEjA fR[SiNuC%eNy՝թsG9޷h{cdE>!Gm,)hi|-M7Q21dՈDZêhEm 쩒\h endstream endobj 9275 0 obj << /Length1 1626 /Length2 16696 /Length3 0 /Length 17547 /Filter /FlateDecode >> stream xڬSf&mgVڶm_ڶm[UJ۶J۶q_wus'ޘXQN noBDM$oiklo+o%K'0$+g!'qXۉ4D"ff"&...r"{O'Ks "J5e *cBd?5=-(llv.C_;D."3KddCjlciB$kisP;@dbogjOic 99;L,(o!'G%{3!d"Y?5F+loc:)-3K #=㿅SEK "3#\dciZJD:U Kk` `gR/ 2bJ24/CſC(E #,lAMIDH@Lu3rq [7#ӿ#?cbdgw_uV?y`lobR?<):PڠZ+ھ?#b&qs@pGO'/)U/M RsEm0mvFI%e'gR_hdO~&H@(g'O?Fznpiy0RψS\< L8\WEMڳ̪6h4wjmRՃbmJD\kN$Zzc\ǎ`f9jY*k[)#{Q#O~x&y1gFNø.VnG!֊5yn c;bM-Z5-@|ILӌ1-~")禫=Y\[F˕ڽ~(NuZ:@tB7{@4P $pe٣i{:Emeit p ~׭OCv<`*jrDŕHtbѕy\OԍIwZWjg  դ\ i%y.@)u⽢%1<9=c&}:-So{%3쒜^wKL'r8ZS28[](89N;RȒ'M's^/pg f  LjiyR! xEobPgjm"0 ({esGQBAja-mMͿ&l:F167tA0v` #_P+p1Eye{ 0D c^l:1 Ⱦo╮ nB.i)8 ⅺ6R);:g? AW{@vI[11ִ*dhoY<]V?l)hubdbr<.\U i :?{U_D|r$1o:l~zae tgT%1ܻb$k!nІY2Î<2ȱ0d/MwAC6ꚠkpAJyMDi6RWwi|ث(up,Fxpz[NKȇh嵔6Yh= )1>*=.E GS;,/(j 7th!bڸz` NWÏjAP7ݸն7=zĉE_Kһ:{ h<_@-GBҀe d ޘ q+ߧRIi\ͱjyTP^k׽Ȁñ߹ێ7D<"K.68&cOz=%]X ,+JiK9teθ @*nYR6c2a8Xp$q3O.U%-? H?tNd~HE9SȻx}2D! o10_]jv9Iu3`|(xFjm ִRW?ޯ pRó]؄=Q@*3mڸ4]Qɟ8Vk~Ns@);Ir">b'\ޡbwP{BmzYyG*37tQ5rㄽ_Y'BY1µ. 8ϕm% UC=5V oP=U1#PKDtZ@a#()\prPVvE IkI\4rH`d׀?EQXzDo?{Q[]tHԿGǿ|)FL9r,w~  H(x4ׇS쒫,ZIcw]< #D 0 3NF裁REf _ԃ*lr[ ө B jlfLң$҈mDegmtWhLE=aYPt@:#69A}lC^ ZKBgׂc4P '|ycS/Y(ܼ͌Z$pTE.P\s  |(q]O-LTG>tUy/V $sKã]0s9:6T|Dמ1mlKTķRAn`-z^6!%ʠ!{cź3ZʜIpvښJD(ۖA;ʦN:z)^ _!=X F t$lm[ZTK˳q˱nQ-Dk_^37SrBJ^^cz^੮ 4{9g`ۑX3g[fK2c3^7zE[a,DGT8 eʊi- Rv' 5Ixu?azz9AEEM,; {c+e7L=`~>f٫ &9xǪf9GH  a(Sqjc2~<3Ssƙܜf_SĠMj7PK1 @b n.8 WlÅk{#7]FLwY=zy/ v@eV5a_~A@"tHR c]s,PO>nIN }ܤ;k;",+`O5P+{z w]#{{sK^ϣs4& |}~)-'ټ_%lgT;K)SvN ĶOVT*j{3c5SO ܱQgGUtBP5vMй'ABX_/5Ƣ"ͥ`fe3N\:RbGZC9RUdM{:*m]#n=.#IB7>( LqiD_l@jr9c' "x C$6 ,DO˖H{4^cld"O&[MUVne1l+5 5dɴ\{ r _A?.1p><.=la4 :+L r*e}c(1~x%uM55 WV2"|ӫ< ^CPF8^6D%! 7ZPXgvST%Zce\j,+g!h憌>f0Sa2NliG~y )Jhraღ KPIT F4JO͉.hc KNbYg34DԤV3ŠMF|O&Ue-{Ug=2^#O'dqZ] dAALmM=l!Y 8OO> vX^`#Hb٬S7C?Q뼞 b9`BQ9G~INC.^>e;=١Dk/bwh@UVaU՛]%qGO+j3}Ե8Jq@-t_o6mws))S _V V{'[<7nMUg(4몷{L |٬27m#km*h%ĈOTkv,q|aIu j18ZZg}O~Bc:ܷV)ѧOyhBpփdr|'ZpSI0m_vΘRi"@`猎8r踪GOrSi%)*KZ 1A?ߙ6T@MC+(p: Fm6>li R@T;<ʩX,L%w9&9ϭ`f|x)WuČ&G}Ͷ>a^a{ ϊ4FXc! #:=,ķybip\ r*h(Ef:^븺[a6Υn=jKm5rɓā-@S@:rn|:JT79 !eB&=ATaѵןp@{蓨4lݱ^5[Q(gLC_;ß)*oXz0Fz*0(z(N<+EwIH&JpnhKu| Mk3CCMV[++R x(yV%oK~vDɸ\Qf\2ʬFxDժ\h]saHTbKJUJj}gPL;kZSC>|Gᦀ 6sOEqtq,gtHEPw + h3K1[C|`|YB:p-xzWYS }Cp!lмc+|uf EN ;MVc~ݭ-Ɉ,tB0Dk4'iO[OGg87s)c CȪ܂KAFl)nja`KlPMUu Qx; ѓykM,Ѓ $ICWzaX.@Uv7Lۢ\XAp 9R-Ey*'@[ R [P&]Z׫|s6a 6d$ns4{ןi"wQ'Q 6t\L'mCgɓ=Yd%T[jN)"vr57 ;YJ|SK)y2dg<+^S*::W6ܯ`Ȁ&S, nU{Xr5}lA`7١L!6HVҍ ! z`?Q]P`}19R)vN-~3b(AmH(WAMi *x) ]inB ^X~UB/C; ,5xTBa)$ȉ/ru_KU=Zӝ%zNXme1x  y-aڮ:tt$bzbI) Fbw*rt4:Qs@z!D$ zUqQQOz֛U-ƞP;VO5mfmcR $ǥX¾賙np}?sYBK( #=/H3bi +>5>q<컇Th W!vvm.=|6S2)d5E#_ΞFզ; #+1mV[^:.pv%Ń+ualw=M,T΁e}1xb<~qS2s{ WҍD.K]N,4X"{հh"MH/ԫRZL^]};bSN~2}/+r]2rdjOk*j?m\57W# lv[bir+ْTgH߁ ADtH-LT,psc[(#gkbƚogm%N ew_O%Un׿SAֶi7nEws@1i*r4` dѾ[ /yS' ̪?/yR9Sm5m~ i]bQ.XcG}9@F7`*-W"&aTdNd^23وkN\!L X~47Kӳ: P`߲lQExHeď7`U7a;^ZDT뺈ax/DԇtOǗw Cy_:it"%wv ʄ xg++ھAn4THLe ANa\ʪCZy*H KTeaJel}2ht0Ԋq=s{ ,cO;4↘>07KP%{rW }r$ĻɴaiOu1r|T* (qnoNSt>>zuV|sSX@'#q#=7HdT .8*2؟x]&E]9Cgz35T-4MQpWQ!w.B8qY1E8&ׂ m*)1vo"Kh88Ҫֶƥ_uXqm!',~ X0/ Iz5T,VD5S/T?yu (u7~ 2 {/@~Z#0Z~d݀:!ݡƾoj$nF93̮kVoSI0=Bp4'ILyw/=_KrimpߧPG*C4O ˼ʞlpGy[eQG޸$MTxTs!rh31oX)̴>`5O][+)P~ڐAI&򴁞pix?F`[v$d9Ys8k<)YAcޒH GխRsr1T[dk* CsCfE8c1Q<: il$%Gk*/ASJ*;)ٞ}lh'|7(:*+ٸ}7bXh*|]*7;E'y5wr4*ȭQ5 AN+rڍ((Z3`!ثrܧxLR?4sHLW hJR<4Mk2¼W48b f8@EsI*m*`>}Dx2aaXf<#npZ;+I$!}Šo>^8PJ%|X 68ɴ8.>XE6X۬@ۍm0 -vr !8:X+=m3mّ-Jư= ͒K)J]!%7ҬAiՊbcp!wXgKf89#OJ GYʕ/1i'7`/sAm7(LYo.4n"yE: ##H4f+*V͎ᜡIå/NdmR3l ? wЙt@= t/&xS6W EjY啬2fRsbrVoTv2/:hY S[A\>u\xM8#20}ʁpK<gLnoK%C2{g $M n]9FC-YjGP00p7qq'RMI-WzvmS9gN*N?( -5c߀Ee%Ү2"(1 z!Dxr i_m@Bd Z@3<υ%Am:Pn[Ʃt.wK0SX1FH%1^Pgȏ TO`[3i<=3m.+/IT9ϑ iNrIJMS"ft7?5+7x`OO­l;FAFIjT~PV[gb~Nmyƥ UOMgqr]ϋ(B +Te3,?y{6(å$+ŏhfz?عScSc.s+ן !wJQOt@؉ҷdV-" 2 Ǵ&΀|գL8WoJ"њJ ,cZ7m@ʁ>+-1[ôelg2jɌے/e(aΙMx)(o1 ~S B;iA4ĭAG@l/̑ /,h2GvF|xX+%oe͠ ҃`ifmwɛ|,.)=Y{ePo`yIA'/Oφ-GQCA>tIoϟ[WW8~ !:# ZiIZ+)$A "y XMH>o:kִ[-Ņm({ d#~tqSynƱ̺YJ23{Pm" $7wFdqO \1h']"O8mO?R C;(C> '50gwH, }]u+T &28ʲUAOb4hs;)<>#gV?GwIMh-P1w}WՉXp[5_YcҞr2-5XyZA0&#oPR?j_ ׮xLvV^ant_m96պ=f=a >RYvRٶELN4anӣ8.2Nٛq-8NG_h^&7| tEzenK!S`A̽ڟLbh Y&g, *':ȗuQ2?Ŭ4QcJIS 0%"v) g=us056 |qgiՒg~"TiaKƻh `~:wA#W-?IK>Ϻ1^ }3h x5Z%vi,aSlHsKUT]3ǂzy2j ;lZ 1 ӂ!1 ?cŖyH57{k[P^"Zb22v.5&' }\0 9uW/V,OTku!w]fX& ]ASɊ}ms@b?TTC=iTEWe])&)?""co!v\!pl+tη+4􎔗XT9Nɿ/Ye/ ]v#?is||7 1Nb<1Zn$h|bUt|[!TyR'$ϰ!AW0uM艑t~3΁khb)Y$@(+9Dn*gzm]Tޏzcz ([ ܽ Uks}e# ov3n%FiK BW'h+3yvi4˵ F[0ЩEiZH\7ꠋ˶vx-S{YꦟҊ_LpcP&h$em#z\a̶^.jps'*AR`VgF RG x}iߋgs:lv[k'зkش׶#X!xW/fKRMlRI-t 8 (4b~F!I@1rl?Idz0i^p A]QwyebNAZ +aPK|K˅Gw\v,bf*S}:sKp8h(oY Q*KoOH"GUa~98Zv g:\y_c VUb,k* w5FxɳZ`a?S ;iJz˰r-7LGUibwqBU}QŰ l(#բ1>XHRDh.x'"^~ 3S-V[IKc> stream xڭveXm6-ݝ4H# --2 0 0 "%! ҍtwK( ﳏ3}ssu^Ƭ (Ü|-.I & C!$&Ʀ "0gE " 0@H (!!P\v77ߖ.k!H73q $8P #cLKeP8C\M[;BA (\ 357>$S70' W'uغ;@Pg;wH OApW !t`n7+ (*U' 0'r ID@De npG27 S x[+憤ArpןhEAmp9Adn[3.yyl ey@\\BÜ` . L ? D;qy?Nk @qw7P t:zw6U<O/ζHuxE2Cݔn :B!H-2H@[ 3 5S>SfqANB LF0ao^!d)B >x>kPO '(9`#:Soo"@6@=Nzۛ4dD.7/iQGV4a:S1H&H0U W)mx?nRB~t+6G"[VgX!"y+8p5 aBABܷo)}xԜL#=t)e@jy}8?qh6q'wa=k'ಸ]VC&{L :9TZcÅsYV {g->iyU Km|(nPwg,DɀҨ;b X[KaAyfgev5UͿ/bMFpM| e3*7r.T)r&C( 6}piwZܤ[yƇ4J/ضRy(x?66z-<$}nG=%xOG_d_Q:^5UQ0Άo8ҙ~SBmVURYPsK7q5)_Ⱥj8}ˋ;KkL˨ZX5"(-T&bfGx_SzoQG=GϽ" -a>*|jE\pL#pm\g @.|=|Enˇү/րcoBBtQa!ʝbޞJ)8cq޹({VTFB0P:gX'+d9gfRʳg`yWA$:^XTΓ>5N!G쏫Ӭך}cAT62Řm/ٗG쀚'+.+G?*EĹS<r&(LH8ڬ*\M2}Pj25ȿ:NQ: cM-|#V6w8@a&~¯;rE!,ߛXҧ}ӵY# ~w-_^RulPcX,3`{7a?jRe !/b׶#eY4VfW&P<߻|`ı)猄oE' |ah0VS;Q>]y1-6l,N-e8|\}̷oZNb|9KƕNVuk|Q ?n(uv6U\q~>>Akf_1ΐ#F .Aҟr\Bo̬H *yMX2gV0=-Ll$@uML7s*"4iߍ 'k j:_YQzOGcNr7u޽ dfVGT܉6[/=dhp]^dheY6a/$Nf:Q$;7kt:9κ {IygTv^Gq1 xJO^~,4^6P$~i=L j8Q*Y{$7E h_{(\CK 6끗(m`L9MV^j>W}#"V7J̓UZwb/0'GߟVY IhT -ۈGG1\8U[܄= g CBd q<>̼ȣ@/z:6bDɟq$+Km8Tekkӄ~sBDHY}&,姌i29hFAa1܄W ݇y;{ЇbU.(Rt6_1%$. `.:0Pf["reۗ({u)Ʃ^{A8[s3*o445Sٚ|/Et,*%{-x72`@W+#_M*K=9N'b7lN=ta=~l&0M[7U#:qPĒ&.Q%_ F<&iV#<ϖg^Phv{m(S8fWf-oAI/) $xTcw/r$+is0" hs=<$ aד2IBSH~dsƥ{k6'RCyQ؎ص{9#.BxwT-@O5KRǍD;FRSⰅ2qB| }<=\0CEgEE[Fx:M'M7']%Dm 꼄;rޟ&ۢn*b<2"<*gk1,B2nn]= BVYZ?Ve]29K$ ɶ<9SfʄٲCX9S}DEI@J2W.§tʯ|-Yʝdno9[˩`[2 q;eȿYY\b 0ү(NܘZ}۪c sE਋s8dYns[{L{ۅd"MV6볫PϤ0^j,>%H"#gnziU97eo) v|ib"Z&_& %{, â:%"hE\ B:E>;tկѣ^674v.O Xt'Ya|B]$qām_  |qB32ۑÉ!GREAf,-hb&BtZGXrd%KIvJ?tV!6GnPӄ ա tL aV&3hI=G|&ߩea<\$_@ܬf6Co5<ʜdxРtym)hS+!lUsj_;AFk@Jgyw#.qLhmjp~,ǥ9~ܢrVbCe ߫3}-!2~iR@V_>` f_@%/qgo8V6fCݭl2oG؏{>|SجcOo|;|fZm=h{tݺhɞ3ݕ@X)!2*m`u-.=ݳ49gv =<4?6CN Vyx+OKLma&J|ثї"ƱdJMRrj_1/T37dPX16+Uf/b?6>>X ]Q睅i`w)i\dS/UE^);Yѡxb*#]pXҡ/UUCsd"F /h0!15EÈt)W2 _q_LkG=\؃/ "cLi]LhxNG;TAv{&=nb9XVDw1(ΤBK0sk)K ͱeh8ilS>U*w*2_ -1C(E5ymiW5 o؃&mǁisuGhH|*6Z!ٌVe%/ëlio$,7^ u6Ic?9CYO(|-Wgxn$Inx/W/}!u8_BW]w;.`(_ջfTH:+֋% S}>Aj]8{A^_C9?(+-?)^c/Q+@OКg<}F `[Uf"ןa=MUpnXuc%]K^Av⺝NU -/\)14+r(7}SGjbW[u4`߲bLԹunͪl ^'*a6[R^79|lmIʿe.j/|!'Ɍ`q+uU6zߓnȸ@q6C>t,e婝/KijI^YTT;5c17p8pb1f7Qw%u!7tw$PF8+bn}c\UGY%^!Vv4+י|bEwI Is9͇,ϦV;WI[t?JTէiZzcS"yQfzۤ[J:%S\#8ڃ;[J 2geWᅩf=,.#/e׺YcO~T*jjtͼOY˨zW?NfcGs>[g98w<7iTΦIh wOhz"}ݐ{]a`M2#0(GCvyp*~> stream xڬctem&Tlb۶m';]+ضmNŶ/|Ϗ=ƺ'kMFB'd4m -l6@.Y:e3ᗜ L`d5tpjLEƄ̄L\\\0d"@;w 3s'BJ5e *cBh/OG 3[B5`:M-" ZRj[511@Eh t hkbOi_XBvc/71-‘N@B [ckgKttr4vs"(*< h&~Y)_//#XFB G;kC_`vJ?3%t:X`ITohgg/o࿬gNkSz&毘N_,la)[S !&vs8A W&@[kwB) <+$!}$7PB oW}6_Cd m ,?chcar2j5Z8[L- M z/ JH_tVoVE׿gUנ,*~ Wn9<#, t#cb$cdzbf߄ ,ufdW'#fk 4gtT mM Q;;8|U5fehdT58.m0خN5?ׯU*~}}OzÚ+pMBՓAA_zy9/\Q}{\IY ʏ%wm z;R=Ju)yE@5D.Mf 4!O QO:&J5WEg-TsfBF12!"S5Rg)Vi\)$lꔂi!q&ꌜHJZ|S58db~#ۂQmN?:A*TSj2N,E12 jYPF>|Q.aKި.,\.݁\*sK,aSO)Evuԥљ"?'s갷^pʽnPKX?Z>ۇ5IaިjV'Hw 7U89+}'?cE@-'y>- a.zEzހXRM;KǴ)'\,hyWmb+/Xbzv]9.KBlvV:nǏ $PL]T)X|#aJ|dpPT i,7Ut1 @L#GƋB„LsW@6C? حQ->WEDNIV<_㩂"D (sGI$[~!^.YtՖu;R&f͌ǒL)s{'G̖tD^/X6Xy_ f$k9D{^JaOw.'=F)m؄t]wznrS7pCZ&dܿp;C]-ڿ3F䇡na='f%H[B!M9b}ju5$Uto DYB;OzK̋iZ(n# :wo`#,hq#XhجR|V 9hvkLaư DѲ%F:sptP5uOˍXdO vZRy`2ōҤnV~z q"~G}#9TLA[tzHR54 MN1YJpF:Q0batD) Slnd4x'ZrRX$I z-4'r!3{{KeP~ y<ܴQzAtH/ďBlȸAfqnO;=]huÚ-ڸӉ.^O\z^i#zVmoG0?Z!ًPh+< 0(Ȉ cشTh38[emd  ۅ }ԿҺcWibEЏ!˘TsG/NF}+Z=R=!t w-Wc t(ߢM;F̡Rвu3 epf"1mF 07=Å?&s2UAdxv(|!.2f)׸Oz;xrI5Y \5c+t|# 'dчHEKφxڬ.~V4CJfNB6CD'`k(0rUw1)H}O wGO`m ~SJM2C F](y[ GSA8j脢DrzcݷU\N3#[T~t{3-b8 GS!BEJ8;M"P )^&U3]sHY~_%46bVo,_‰N-R9[`+3Ln̖u ݑq=طdl0Bo'i/0wH3SY QUoII2Gԥ*X)c?Lٓ\ 뾁1P(EC X<OFm |DxwlȮ2I|9KáyF_ELyd$/Rj!ߤAc UکiyÊܔ+hʮ 9YݎQs'&p֜=i峿{%Y_8y9\GYTiH5\wI9 K- J- 3I_vw"wc 25f܂~uAnѓX"NˉlC2͚ra\qs߹SحmHOڲoEN:mmGpNJJFںbN;DJ,֎G/Jݙ`S؃cu$GW.NĞZf) rŮƹ`Ut}Wn_8l1^8MrUg6}I9ς.Uzad o=g4^T숇M d3 |'2i>_ #0}&?Faux}75;l|'lۗΈLd8%`axh:M/oRP02.RzЀ?@Wޔ@:v(NM dž;?<\' 31_ZI 3YlM륎ʨSx$Il E 0k#5{ꦢk&طș(㮐>o0o_v4Y1t*3_p| /w?%H/3+ rj~ؔ(e=Ȟt'n i[8DYY,n8nQ/εa =R>[E[+fSI"֟pSkfAz8)ϒ\ 3 a,Bsђ5\;x@]57`GOn˘!#j(0A;0_E!]L IVΙ/Al=M7pN 2zCVB j|lnSV)V7CS'!d~^Σ %"aDTOɾQ)(B>Im,g|CHH?DPh8F`oΖPk+aQYo퐃gwWA7TvNk8ig7 4wUP:f;gS #V'R/Ёb phg_DԨpju_R%3cZ%w.dE=ְ,zz\7H:놆-R)iy .\Ꝩ/\n5g.,/^'3\GX)$=$+зe[;_$޻ II ߝr %ܻXn@ uIui<>Sr׭ tHOmKuU2 MXFjzfS(ܳ*L43c?{fJKI)BrZ" g3m@aƣשm/u5|`9 ~Y,T >hB)`0,fA^ T+t?9ŜM0yM:By2΄_tGfpYMΰvjĪXBm.T Y+#ޮ0j\C^+`>mC' *UI+q&AX^62؃L}_4˘=a5+ ަʆ˧c5;CxRMP<[4<%#o7S}fCrCT[Jާ_U Vc[9;ϱRN`Q(ؿ29AQ/ 5uԤx E1U!NV߭r_KA56’K|EUtM,}ndpWS;r ۆ׌:8 x[Hd"C_is maRwѵ 'mW\tt`oUYS 9%;9׾Il}U:xƧuP{ INFDޙoyAiɖ Kpld%6?<@]HuE$EblT.i/<}]eGv`~FU e]=$SOsw˘ CdHѕpLݘ4QU+Ѹxw3d 8!q;y#KѠ rU7k~pBH!xZ^@2\[u5}1~8Yh<>d;X)Fm4Zd#:IϳBn,[/^C+XD&w`Drk`7arFqd>Z!`:M>v$٬%nMLlq*΂K<3+ ҇&>v':u;n&G`hM R;OMN^ ~:׃t< &ip?Njg*^b'ŊɃ\O{HS7`C* ss0CSL}0wFnDۛVgG.U JOZo8qNK4EտtgLj6U4P7<&yj#^Dot~gxQ0M?;"fil~'bۢ)u PğF/Je .EP NHg/** ۘ0e虮+LÉ}4G(%J%`#"N&5TGZT7/3(,`2ZvqLu*]I@w>䬮źLRG.̯ [x jjs |q"Fc1mm4Ogɧ g{ֹ2pAp]Ae8WbCnUG@BG"rp$~a|D ( PdxIf/C6`$Ԯ:$YOIMJ^u) _W i{S.vh"&m^]`P҅04BG5IjL??a2%E-T.'$lZ!hgLTW֭)"tD_kX;w|/"a0̶|Y" \ЅڣN糋"Z0++"z:Fy8P J ²k3FYGxq-w zG>Lۑ~nv3-Qfņ@h֜f:Et`RL:7[1+'xgJ9G$Y8Gu=}#(`z/!Ӟ%#:ػN_[ n#_.X:{D+&SndVcV߷IDvup{EUb š+{2>l_kהݸ|0^i8|NZ=f^6!Fq9` Z.Bwn^ IE %?sq$ž{To0t{w)n^`Kۭ~pכnj^ʬuVEm>0ZՕy{ĵ݁>aVYvxw | }I_{zѓ r潇%@M+3#%mͦ}үTwtG|&jV(Ua 9e|ϥ5BfL Cij_&gb2pal̫d sYۓl#]u\W?P闫ZJ?ÈMU /\wE][ʰEY˶0MQs>}?q&gsk2GiE z}.p4 iT ʊo Ba 7sd4 V\4Nד%܏)sIz\:[,3'1UQ#ucLmG:xv+^-S/|n}3 ps 2` { viIBEgqc'-oQA}̞3kq/y.TNg0[_mꔯ-[UI0{+l#r^5f<٪(,7)x!^ZcЄER0>x A@T]p|Vp˶:RP{FP WU$@.cQ20xZXKDiUkvXzG7U~A^1Nl \l*mژ{HpS}Şu1̦uǒ{ _G4 xf2q3҈ `hI! =pB !!\@#li4]2[EUBq%,B 9+-ܛmQ?A!ܩ3FSKgkUH(fXj *5K 9٥!M=VxfB-ZȮxSAbŭ;gkFt́// 70YԹDF |=DUC5lUkn= slR*"+f] 8i թKԅzr`߭:2-! ZO=dT6kkövJxNֱ,Y|hN4~}"0Gt2s_9W}N%{o%c++SmTĢ,CJr^i/B ii ݼpإB[ٸ ǚxJWG ^pKB: bմ˲Gox8 d5e&T 'ȩc=?.CPdF*>_p~RAz!ҩ0^d YW?cHߌٿmkD{{H4 Lf=~s4?-`_}P"?}#nN:tcg֎ a!:˶ }jVt-۝Y 񫊳?#"͆Z淚P &X#8.+Jlklt[DYձe~ŕƷK_$EdӶYmVVg*PX-K4w5p⫵U"@_~Gܞ.j^*2Gu}HV4(1XWfR Tي+;|lW^m9E6{I8Rgn;ڼkE;HZSTSph ʬBy e`jdAxe`>U:xhUԣ V)-u'=Qr"ˆӟ_7W`#L68"8k!A, ]R8$T7X h6`]9?[umhi4eMGB}rth 9*zˎF EyOpWߜ}dcB8D=$vlj%JM{urM\%]1"s)u~U/u|ߛ8noQM臢Ѷp1AyBhQO[tkٱwdy}KQUN'.я%18+M?PO]hHHrjk/]dGp̶kT!5crR}BUk>oWXwJ4Y$e{) 3jf*Ba@~nJ'Dnҹ r9ώPAH!"6&ihsbMGwHc`[ꮐc,W4>Kx^pTJoGQ'vXQ ?bSTj7=]lJaϛ]dT~ 0TDpۙ=OcW3@~2KE)JY0]2ʑt cć(LtG=lק([< |mq>6m^OP{7jd#ҟ4DԠe!^ns6DSk]XjS*[ޒyN;pOۭB]p̸TDd cB_y\;Yџk!~xH.{0;lɈ4@Vg,5$ 4Ǡ̠枫=IɑlX gp!> N\zuަAllT?iv@DF=9Yv.7yN}!SWRH3=)65̗("CHI sͳ~S q)4Ob(ĴXl#]>Iҵ-tê_AԴV\3gog\,ՓIvpQh1}hDΜ ξHt:9VA^h64Ae %<*78HϩsN=@>8VO@S5XbWT XYv,`b * ޔzx1}SbEY]>5njTh-ED7Kh|S͜grPd(F\{ W3DqD46S[ihjfbF'9TOQԸu4f "H*(Qi Ι*[@˪; 2h]_#E!Z>~~{!tɬ+٨K_dy^c->]viÔ9<Hv9d=3z+r8ਰfB4B.P߁H*DyE""yW:JuL1"E]$TbBTC.Ҍ3xgw@3&p; b48) />'hu妗^tj7Һ'WO|3\iHb%*qD@]G\~ߓ@i|{Q0,\$ !_rŘZkHU,*P6q7b#eeh`eYS &acw|b LäuB/qia>vш*Y.rgn-}WQY[>$,% $fZD4N̨1\gv6w;j8q֐E Apx\$o݂z7Σa]Zu`5F2,rZƢ.ນs-Qtt.!JQea@p˘=ωە̲4X+pAE`d@Jjg=(5op=ȼ)X?¹^,ʷOL{i ttRco6>Nba{Iq:QB͆ZMn xx%-xr? aW QJ+xʷ.CB\>>F@rR!xH7SY mP`^ҍ?_AQ%3saC#pjnh3ץ4McKøWw@eЖ6FvQ!r6FϹ;[5:}L&ÿ&AaEoTsa X+xFK/u?¦>>eMRJmCsA ҏX &v樛\Kò*qdxVL<:]B,]wk?.&NjRt)2bDӰG^`Uu)c<*rYMe58[~7?u?U ZslNδc'Fp`ݐHu*yeڬצ'rLDBʈnvg1FA{K?:e<ާ\1~h:\quli+g;[3$ /IP>|8N1HؚCH(?tJ謨R2~ sF"ժ1jyIiG+D,)^=FTbuRp-* leYȘ]7HQJT Ü!EÀaBG@Hys֥#dx 'M^op'5yYlWy1$ھDuk0AfT{l~::,D c`IOc?|ǒխ4?:"}2l ּE{bsuo͢^<7V K;Ge$n7i/Fcͻaf1agD 5KN[P>"c&h:ʵu1).?3K=pxҦ[j ,^SKux[@A[˄?7:}$(;+ys$M>Q;B_ܖm0&8eCcRuM/ oisĴr+k$+ ' ,`O ,\6>O;cE%Cq6@dec]h\f.R3^9Ζ93Y (gg\\0|g샜uRhW0JT,Wndn+SƱ>+ eC/e\R ਛ46?0 _%W4H7=R+ EQSy.яSGkY'aa^zbAޚPv_ i0gDEQPoHP!Gums(0 9cai}\D]v ~=.Jfd$uny\^`U[CZN4oJ3;enD`KG4+VXSf{eݱT&i¥ZziKoM덀ڍ;Nb߶hiY"Y+KF<rɢ5/飔XK@832Wz^"Cr$Vtrw";4>6~$m`'0+qa4olv:o苹41O>f!X7A4][WOIz|fJ Z tQI$H[w_aڋa7׼v j2ӟ\AHA^X^ cKRP1=RAVwbtb7LzZ#~kv"F Ζ*geVnʽǯS4 g* i1LĐr:OEV+ a;Ŧ 6wj%כ++1²"a"+_"/ (<:F}O=Gf`eT k8;6KaySܽeֆԞ$FCM[?2 ?peJ|)R@Yl% xlה2 +9/ v  `G#ݯU2!9^4^/ITK=EZAYcp=eD`u^݉ϯ?w7K=EM[? `]'>*9$q$הD\7J>TnB}Wʎ(fxtbb~cn);t;IX0%;[l'Ӗ= ~pgU{4h8 o%mk#sQC'mi9e7yѫ"ü#fEt!^1ƫ^mɅ8YNxOpoJ8s&9bLg.YSmOqFa%2a$;OclV6R*6Ayj@ #J27*P]6$c,+,\##k7 =MX$:T;iM`5z#=$DQ̜W!oܚP?y&.3~$"ژ60:_WES'$ [K崴z H 5£gbOHyɮ|#u +)B 1n2BZ3σIbnx)~^DDɀfrO 4>P,%@^t XgKKjXIQ#L 2?p$[&bc\GZ"m=&wCĈY₌{+ddjX#doR1IWʇS 7̤b-'lj_>n%iMn ٔV뫺y(.A&rInMtgk,~L|iṧC,ȡ*7;Y@"cfYC4%!k'~3R(uե`M/[}M*tsW31s|H>iӗh[*DAtؐ p$o%IzVG2hTZj)02D^a-׆&jj t" P/I|hƓZwIaڲ7E bC ~ -vYUt`=@=<^?7n:d-T i.h _<8W uv $yK^oU47&g|FR7w;2-:`nءmPk̠+ksT\R"}t %?b st]5eb)VR`zad^vsU KM'&wSLA2RC3dbPV6c65ЄJsujShྜྷ[J=~d씅V}; #&wKusJ#1R$UH",O&]3'p-[/k8VyE/^.LilnvQ;A>Cg35tiC\(l5'폽A(*y=i^wZ=t6lJٰv1R1z KCh*Yƍjߗ^m("OꕃJHu*3TX/|ɒ #33.aqҺho#y2hF;ev΋qhxl2n8 L0V˘"L'vv e&Ag5/.HN$Dq;+44I):1Q8MAֺ#z45sMmU=Q61xr9AXR'l,OƏ#eRr(Cj>\'j  'c~Cu`KNt׼^rEN@be~{,xLeu) srAYv zه{a논3tz]4`JR0Ύq^xkjb5 x)N0((K*:لAdO]TǵTrLVQGC-ݝUwt9$%1yL U74ڔ{-'q7{|s>P>j 0 S902nM@$ WxM5pV0g5$Au~6p͈\ ta9„,@6'ŠHiZ ӹù@J3Y+k*xױ@ZR!z֪;=kq,|i؃;cTޅ8[&XW`>: /|y3aon2 uz[zSFu[f刼NR\y㺩z+?ۺ;t?ԠHӑpg%/E^1MioȻ w?5J>YIVbM#lg/\"9&C#+ڤl/yաؓHz!6$&ZX#[lS[K+J'8}Ѡ 8߳='Ai-R7|0,/Pv*q}vV)3 G薬A>WvIbcqjd{  N&"-!:eOjY)O 5do6qf5/F|7쵲6l$lǨ3kD*ĉ*M(`9PBV<8GXܓ#O*{BYYm-7.:2M b7?"@4`0gɪ'*?߶#J#҈ADXh*]6\Ԝ )9Uso[mc7)|qYF"Jr xHpEVZ*)NB޿cJ%#hWKU StN;i1PE\l7%8tg!/>$߭ˆDLk ֍Ť3Yۈ>rW/x{BA?UNF o ^JTkI1kbK?W}rI{zgQKshM\HPrW{An2NN,]b; 8J\k 6d+asMϭ9n)_C{U֑&8Z{?<8?'|}Ӵe1y";PiڄrIđn{(;5DzZL_#dB^߿-ra5=z:='(t :*%|%[v\icg"qȔN%? LZ G{Y4Vx Ԑr3Ld)>>$%Y9Cz`$KQi؄#=[Q#;2~b~L%`@GGYA8hz/l%= \)Lxw5g\Aէ L( .mg %X?dlc tc潖Vj4q+z.h-QW0ujA!ɋ+[˫>"o?gH|m=q;NUUlEv3!2P7>UNl8>-b-'l9kO"%{<kYZ1*P)oсR7bi었^/N$l^hMbv-(GgbrfG-ULe'}{Φ,U#3*U6 endstream endobj 9281 0 obj << /Length1 1644 /Length2 13545 /Length3 0 /Length 14404 /Filter /FlateDecode >> stream xڭctf&vRm'm;6*IŶm;wq?Z5q{Ȉm b6NtL9skCgG%[k9[.:%3KGF&4p21prԁGsw075sP*S|y:ȿ^\Vv@/kGe d[ rJq9U8``Pp627ȘmT[տ#[cJstF_n@7#?*Z`0u0qꁓ-&JK`h`n "< hؚ|Y9Sҿt_0_Z'sGX@W/0;hncV@G//u m/heB+ ?"icb `b\j?3C;h g@2 B -le%g`51%c`3?16r?yWku?I:|E:.zVNF+݀ NFfKjc t2~N"*(W ZZ4S6=&v(|S5?BBnO:&vN3'mJ',k`fgddO~Q#[IkC_t,Yf9b hv3ە4UvmsU7Nrq_8{ߗ>ƴJ^{Pnq0 Gy^lAh3+*AL8\=R>!b4|-8=#O8~| ٳG KctJp`X٬^>f)킅StQ`0V24>Q))ݺEɳez>TˌesETBT5J xc 5FN4EMH):\~2Q>HZh6'oBN*Ծ3A^sphC׈;!gQ/Je1?p71',*gW StָJ_JlX7~玒!MmLe @ן:m.ށqoԔ)勑aM:{G7hlՎ<ٮlJ`M!<\b%"EX" ~c0e:րiEbk?EZ.ʼMC %V$'ۃrqXͩ \xr9Scאf>gVhh9lTM 2ס[ -MrA&Sq(C#EU%nLR1+Q_$%RfbRV稆ht"h@A(T"F`15V U3Ε[hx%O[,jgfɺ%~fcAwXh3ߓ'jW:"3D&X@0f,g9Dk^0\zw'=f9M1麆&ܲզdo;KtącwJƷ02pl /b{NzjLͷqbmr2xjlIJLo[*fU&vwWTxݎ,Lk2`#8ˑ,ӵl4lV >+):v;̘KAG 5OQf2Ğ~.<^\S=z]̌ DcNF&D-m! PjyBp|l -T+{{[5}=RV'1!ʢ.q!?[A*?b_C 9Ij$*t0mȋ_`4yeXuc|1t籊t> Ļj3\ C9ăhsZl,a_8vq_ci?kڔdls>@k G+LWqu'jCnVɗ%ӌFf{ jV){쮖m0 +E1DtR}sF^{cc_(Ҙ!H}eV69@ gx+ VYY=N-a}- <0)MwW|WL%!}:֖ x;1',B 䉱;9As6Qh,\QaiTD<רe(?ЛOf~M2)`R3C)I6>\q bɦljB;enw5][_>=V#i/~5cxn%#Y5;yT_U0G s-Fc ҋ]]_avuD?zI "1&+H%;~ۭhZHFbn_tN+vDQ̃z|df'Oc՘oۘJ$j3n]dGv!=_ȩ-rlEehֲ̲pBGd>FyG)IO8Hr:a-uQ1b6EuJJ7my L%#Qag@kùR=7!X8ʭ9A(ۛoDp}S'H l#ixªfzzB޻j%tA>1ϤH'\[;C44. JbAGgXXqҲqu Ƶ-tE n{Ob5hm˴<(ӎz -_qM@$|^G7q5؍hNho7P $|0N3ji^icF (K6]cB24ac:/ VE?:~)]$_ٶeЅp jU>hOP^FdRXg&ZkQש%l,X^SQ/r~ELnuRϦ+Rk}Xwb<&W[iB T޲y}qm2\IV}( `N_&]ҿi1zn(|1@ ld=:c˳ά=r9c]:qF IzmHNɅOIUe#-s\$3:쾟(&"ޏnL~{NU+AC)njd|lbOB/kf ܸVC$K-**ͬyAH.hm%!>'>e?F"kVT;Xr$u𬮊"IpOj/u t7Px Ns)R”m1"ȸ]*ʅQ|!6Sӹ~6[aM57az@4ޓc@nwZ܏ơPB?vSɉZvZV`ICynf#93Jx`0IKbɬ F֕qFwڝ>6m JUc&iXιG%!H(6yEզ'%F`Цd-Һ=l~B埭I[u;ea9*ٲ%hzHB$SQ 6^ K$!aV*|RS|>~EͰ!$<㩡5WBuWq-Dz1ܓX<<aMPj] &&bьlB%xjmv݁s1}K[ 85} *) vBN\\?lbjel*q_pГg 2VN9la<{PƎ0rI>b>ZHbLDEI"kVeD5D=iӊ~"l4+`&/ }ƚ]([(A9@?GEL'Mz7c:;~9WTrҋnuttԬxQA͹ڡ_v\y(6FKi +/s6E%o/#կMmN0|sԲ 3`pt'w61{]Zɦ[4ϻ7u@`=)fvc627LDrkg-Gi;t@+@hh$h$Ph oSm—&_PFόO}&镾ѾEPQ޽o:R>n~O}򊄍xs aSw8CE9эTb YşƏb10GSN?Rl9W$űN'ng_%U{2XxwsAlLgkQLP*D+r\ЂM[oHgI$|?oT+fFpϏd)y߮<0$uNn;a(+jpNm#]Y1:~q5&+jj$ښj8?^ƩTk1r7-tVNzF4~=* xFۼjQ/\Z~ SGaN߈͊{*c5;#X>*NŇ"a#q&L/K``u-gS'GjrztB?ON+3;hO>p:I ȅDWbPkFg,gk?Xs>W&}v2o.omoEdoBBhіM k( 0zH|c7=;v 7ﯝxd i'V CH_ ў~M zy嫈xugc+B~+}9_B%/v#gad@ mq }*V40LyVR$w că}bi*2ݬTğwfpBGB}ˊ2|joUUNǜf`-\ ,RC7r8iwz݋0̭Ǖy\AC#hV5`<^C̾B(UP٣d۾繛#:?cL;@-4؞`E 0(bZ~lP/yRS)-6{DH.a燍pƕDX%Y7`*2R墫w=?fx$e_,9 s@h'[ :E0va/:I/?y& TS1W>3V[2!q{oJلtC(j-h P|t*~lt LJ!79Dy3:ER؅¢R'=^lfâ*>d"Max%6b͚a'>Ms QlV"Ξ";|4'$}|_ە1 rgw 튭t˫vISx4O];bdl>,͚>hXRZR`Y5jF}*(Eu>2s}h9,$¯LVw KqL|s_feucPwά|O,CJ CôvSz1lƵHF&S2>`Hm ֹr"aeԵN4j900Xv3@N۷~{)JȑluU">5mo\nӢvx~|ğ3?@ S"JCYOG0reLr&C Ѳ.womTcaa0MŵFSeӂf!~`$ s݄:4,cFv}1mc%' YTVٕ$qv!`GG,k=1I؄tR>Ȕ]\0y6E@LeJY恾tQ.(4.gf/Sz/gp9/6=F<R f@Z& 35,^+Esu ӈ-BsC\E8tJn͹23hoI*Z35}[2J.sE>̈7$UGkFr:|>#s&=$FE*>w,15^#AΰoE (rCl/ DΊLZ*; nu*NC?mD (3"`gtJ@ux4 pT1۬pJζ67X?YI;h׃dA4u(*6̞Т*ׅ{N'noPƘ|h8^~knO[>vy x@HdD^Z|pK2F)봞YW u;w^yDH l{=-} o0aɥ释"~Gzʇv/y_)-c#V U,{#-w_K,"%R j2j])vö_mrK! 盃?a1 i,ܭdhS&NljMmPnٱ,Ҁx QQqI{&Ȕ9}rhsZ)(H.rw(z?srH?ĕ_2v/.u,lhkfh3y& \6 6bx=fu!߳D+(|pQքM$+ ǒEˌ bP\bW"sւLCѭf? =v/5Oe"G )2vϤ>n^橫߶Yĉ܀[)tdR[Mq5оqs!!Цt3;G 6)F8s)1sw$2F0."D &T>=^pbij>:}tюWiN1Kk{9}gcphMyWYHwjkY} F퉥*jb =bX]j\%8[%JЛ>H (['ᴅ+YZ66+ I,-y#`3zLjq SM-]Np1#Bd`{LwhiqIp]У[E\6(ՏrJ+z󼩼DVLV~3 laD>-ķbF=*2!F<Q)J 𴜨Zu?+{,4J~,Z ߌmrޱ?rCrĔ̤_(N1O6ߓB84<"O,f?ސ(}F~xgs,w4DC+N ZfjLz"?^o']CcmC\iMk0]Fй%&u';Cblj)k0i$; d)1ټ}\u날.I+Ö;n>SDD2}9ف1K2lr2\$ ~%mBկi2Mf UBd  >jkqЊ M.~+xAYKSkݐjĖrwE/H|7$AC0أq +d ۛ2߱ }8`0.7Ζ͟TYMfN(%9RNE7.g,bZ=AT4 ;V'2pEgp!#~%Dw5=Ů#鸿kD~Y'm&D\JGF0.|QօOAtݣ'A T먏(cfm8Wy·EhNT-z󳲵q> ΊQ&"E1M|qTc[68Σҋ#32LX|X!wC#XN|-?©Y_pK=MgLd$=)-RQ |I3W,lA2E>ʅE/&&PGbuFX/ktLC%\W"QMvf 62{QOFȳtX U:G鼮ڄ?h{K*X xARܙ9ha1ah$J^%} spmJ7hjEX|“J䲊QRkTj'ߊs|~֐I+tH#$07{7f%|ǸU &%\Kς_A3|J{0 U ?R2x*=m搠z溷EҾ`/zrezD"ER(_] t^xwK/3JSMd {bcTxx22pyq:Lx-oA1˜wdٴh*+ݟ#8vZcQQ0>`ޭ˴1jւ#6ݥia!Vr`޾ADe\@Y&1o?p^x)!8ҬHdR7+ё?:7Q=sf(Rxw.!D{-"82W(]pNq꫹Za&2422Y|!޹ a[F>*rY.O#krVrB.mղ&@O`~tm[>֎3\Ɉ+yP\Cj䅄L~*eql ]F6 >vw0T -Q;E5F_a;;~۩,!a3EXyO#lϛ5<lld<~6UK\!m˹X18 p(q.m(LqY/rbMu=G 즶*23@J˂( oLg ?pvawio`{f ڊVoNzw1dUWIf4UWՓgk1ٚ[ͱtukҏp!_> stream xڬePݲ%SC#64иӸ4ҸO̝;qoU\;Wf; QVc1s0J:ػ202L\TxTn2ƶ3^ āVV @@ECGGLbeaupڻvT@- #(RHPv32[]4sgS{3Jsa%08M=M@Gg :MmI_ 9:;aKbl UY\yZ/ p0ퟒ[ٻ\2̬\mKl4\-3z3/?um]++W9# ߘc[X1/2s:뀨I9z̀pLCTfA[j]_%lm6 15y?2Yzn-࿳w{ 1p0rl"i 4Sr5=5̀ζV"|:13L58 k uWL"2tiU*QQO 'e{yX? ƮV=fFffH؛:Gjf[Mݜ*iX@S%SYuy#z},#E5Æj;1YTF͜I~z5KZ}pH w驕PHl<lh5'\~Z뚒XD{ wFS6AFlƙy0 3Z4HDoc` ֠xEcXz8[p:>S/Ku8&H2g֝@M0vrrk"H/V:TxdRp9 ;E@"NtA~7KvSFFOۍ;.3Jzy)x -RPAkV[yюNV{5LOS(, qG"SŞU7Չz7c)'.0:;њ(zE{O=Dzyb%o2Vە]6R;Ґd'KnV enmݧ#CR3Kj;W`󒶭.juXzbjH3jWDz0&L[qEOk uiuOZoTor9J@?5J|Ԋn+L7-7;:%lkCCn>w1f"W/w-ըi4sg=; Y%,Hg, )<WRʥ( _i%2cr~Ff(֡j؇a Jq#2R5tK~1BPJ(K00T\E{ڀ Ɉ3DJ*nDU"FdmG7 !Co{q1ơ)b!|┨ 3, ؕev,cR޻|aj@\"7\ >wa?K^xWWƯgO)S "@ m| =^Jz:>|9P5E(zӪhgsznU؈;ldY5#ڳmgS{1\,׍bʢV>,?f52ɠ4 Yܼ'|@wK!ۤ"+l*73@&R6`F"آZvSc}ec>C*b^,at~\=Z?,4a9,Ƣ?sh vBr cPmG)>k<6F9B6Bʅ~GOvFsw> %ijh:J}*j fa, n*=Jk-O!Ƶ&[N_(sA-r 7[J'r+jHF&~D+.yjv4j)d;>ccd9׹L6$kxrts`vc #uonXN_Eg,o N I _jr[͛@vh Dd(EkIOwA QOf|p>Б ΛyTBnE9JQIȒ>-݉l)k 12EESNq2OŷO Kvsw8V0ͅ ?dHK|T71ƤH|nx7P잪23ereň%%F`" WqHRapXֹ T"lXzFq7<^[+X:y:n*Lht_OfKbkPy>XNs&}9a3@:˗]F? {} \(pTNMYAqtң5A~A? Ǯ;p8},;0fN+> z}yyUbLpܤw #AVƶ^FwfC+Hu99 u= AZQy&*{(p)"܍+elr`=0r=xxtUeqӂC>!&1ժ_%HW5. ƪ UNAw}rI2ryF/RDZ+8$?\aLk^D+j˅4r$3q䦄^>NsOT!rP=#E˴N`NÚoK]j[8QR"8S& h|"{h돴K-xYbXZum/jqK+AM.EԘh.mKnZĸ?UHKiq+צ3W:{$ls|곂[?G [-9LX 㧍x=bx9Nj@z Dfzz :6|Xg>0@evpNYJY@OMs 句hW⏞VxkO+ii)=Z> P)s\㤊> e>S)JͮV3$׏[^ÀmDȉ埊f 5̤rga_|W֔qS~w6a!j'YAs?'(o<2.t jEj`khztCKk]j"s1HU-O 6no+SDQЯz*| ޯ֋A[8,_ɧP,Q>pkIfe5#7)3c'y#UE"L KU%87Kc.("2q`z6%Kss^FXEOs.n|z n?hYкr+3I0v}>cW5= ^k{W[]OIv!R٭24_!#߻l}uw?i=ܤ@S J. AT:~*y;f1sll4^ uķ9$2JmYGsif|16':1QӞB yUWa[)8MϬY;~ ʸ8 ԅ\&."J.lD3Kɐ#~x< <'95c$8>(6FB#,@VL~dllAVYT& s<Q7@קm׋UR&,y։k:p~+zSc.[4nLe)n<2*\ pD#䴌UlCb_:\^:@\4QQ3ݓxNf[7]b`?F{:*ȼjJQtyR Tʸ"q&w ono1)‹(Zu#_9.A=`Gi>t_] V+,qRrn-~!RkV]1 dEO!ӌzc)ke~1(^Ss`an^8Ɩ^. ̺kQ96ӘD >ir )܎Hg.Bud\hQX0,?N?hx *ZLA{'@uO>h:~1u9-vR1EQ!KUnplg`Z0bGLJ;S0+i$t*^dWG>`BHPgə6sv1ǝjnG|"F4ZeL~Y馍 :4kNLbLI%@t;%{1 NBQ46D˽&vsf4C{Y .9w5Vx*4ɑ[Kd>捷F MP.(}Bd평*zyl'<+QnB'qATL0PL@(ݢZmȆk3!"{#X(IIUS)sf|k/lƬnHx ģեskLB5yapP*%gPz]GJ N˸SC'XCM9,kg=R*U>Nmv"s/KAm6SHZGۃwҙVs7yHJH3?[~.c#]5H0s \e ^ xB횩V]wwnv/<7.j|o29'̢Yft_P}o2"KvʪJ 1evv؃Z^|Т}D ֠Od%y`Jnp=é]oHi&onxE.F9Sߪ5(̫@.`GA72[fŧ.K]a_4xuy̹،*7o_c_]E$?泃8‚7]j;c_;}|V-F­Vu9 tTkQh5(:&VZ:Y%S[Iߵ8f9~{"¸0MY3 !ܴE3ƊHk7,zLsx>D z3qFV# #\gFJ&CtmW/l,X@߇@KGƣZ ݓT(|xHϞH(G\H^]$դWQ2%yD"+jgB[r4f-cv^ TQ|šĥ0gf4}v*(xep4Î,]="s%Ծ6mBؙ6yQUЖ}/CN"^V^Z3UK WZX0H9s6;0,d9в}1Ȏ<9ojz4Q֢rsm?V0WTՕ¡:ƍai^4伦 LŅ8H *IC#=SΨ&E= VN +Ż`?ʹG4 ?mxt8'-:$CbR~/mAVUrT9V ^!.o3GƉ; ൃe RTFV:LB{=е^#=b/>BVڍ*at WAB4DNϻ81?EeY+dž+hf@0u0t|ѡ3Ov0| 鼗|gW<.{H"ՍWUMePo1xhp~9 čH^kE?}֞ɮMD{K b\*77Șѡ\͸x~ jc҂ߏbltm?e(LU2~GT';|n~XHv~+,KR; =ሢy`S҉Rx$+!(Ì#\)(ud~p:4ӄQ n Dg!oV#r_P_*Yhh)\za q[<31@g.NƢ51jQ9!6g8]rAɵ~|p_m!Y ox0'4 |ָjCǙDuʼn}yEb'M2D @Xt Wsa&کS^} s>S@ڄ<1 >MT[<V5n =UzA _,)b+* %X $pCέKLڗpn"CW{"*'YJ`3ݨI$Yq`mqGic.\ۇc(9v{D/܂b9n( C..eo*]vA׬W7ԛs-W0A;'!Wkc)b?}yA hI\4q؃|$rab="|D !ęD! [5= ,B*{oкT( gX2 A&D.٘>RJaԺ KY͌_@v"{]b^a =]-x )$.ĸM֛#s5 XYw=1}*XJG"ѠR`hZBW@NH S@Ȧ).ޖO5LI'e.ls@LO'0yYkEr/7ڢy=8s3xOiys{WCdImV3~.wN~;Su'K~OCtt3mW)˲ǟ"aÉ CgYl)wi:a͠`wKN7NOo;;D88ea:J/iͲټA3ͼˑ7y-HEynUVo>д-j#vuO//,Ű&UVxLT[QC)eTU\B¯lƦ/L !3Ub=ks xX* ,z EC6]ӄsWb#F!H>,W A~Do.bm+ u$ s|nDF7>D 'b%$#FB.xO f~潕1xӗoFWժdː%}R[[~6~b-)fbsVZttjٗ$ۥv6s^4}}}G]Xb 2;>wb<-r9!CnY:IZT 7Mu:w_qOrGP !Vѯ?7!?<l([L./ BeUT?Wɨ_뼔vl.0;/C p`}O$WԐ+lix@br2w?Y~ծ'w%}N&V c&==n$EZқ/髺VjsQX)jMf.iߴBiNO!uhm[vsL 鏟>y ʮ"Sx;!|/TlUubA#noNA6.ī'|}]t*wb;vPߩ4$hIY.{yb Wq8\ R<@$ ٰ*3 zL^a{c04!e .plSH{xe*~X®"mV#pyE57.O!y.pqt*"&hQ}c4[pqy!$ l8i-F@yvJ㭬lq\aG9{ZtrW0%>1]ln@}_QIن篳UkMse{p_\S7-(QtG W.zpp|Il>sIH-gi0`aC!OVO.Gz& 72[_nwa*/6C{|imbHЁ5۪v`F|+N&yKF+"n#v \N:PS)Y[Ӭk8R+Ykm'm0d!|ۺGuS V!ނAfQrޢ]؞oYh2|{ ޱ`YIOL/]3)4e%]˜2xau _~AQSu4@o |cUAXTiŽdg>M IO\AS7Mw w\`x/ @[Si͟6K QHK3W)r2O1· U-\tNF;¨$/CT/y?)FdѹӺ/Hcy<*n˺=bd{]of F^ǃ &%LnUu׺߲J!bs {>V!R!ix~Pq F}j s&u/bܶ+a%8 (0z v]褃=`ە^pq*8w&0c ŽboX~KS <V^tPVf0uRx)fFe!XLZH fEӛcf F'ʗA+IL H)*3l.yv;) ;6%e+LJ^^Nk} =Jt r GB.z,j_>-3=uW-?9Q˿0$PCarYJ{=Ǎ[gP>;Q;}E/8.e6p &q x6԰!ջT A Zw<7S;z,C <.xy}CWN8 5^Z(XNحy+M9,^Z$no<ξ4B/XiwF gB "x2S$bkِb.`2~ `ӡis58N y/x+'!p}IǖUɧYX^c6kw>m 9e ;Dw@EG>ӯ1?Rz" s3,"^뎠{u]7lq1^dEV/'.҄MJq74l쏕7cFU(X!U~P!&Dzk0kWTPHF,~.^^LAl5 N;bAH-ɞxb҂B:,C]|.k" ~B JV+s.ε[Jtk[ںwӗeR"J)uR#Ɖٗ~]=PZwl ]B\59WYi VBĪwH;E\(uzt g0d z_pNˤ% ekxΎ!ku/;Wwe:!.nʃ)ÈHDttrWK8q~*FS qsui,VcfU2g{GȦ.vwDDxZn*k~*ګt]BxT/G p@@'OW3 PT{B Wv:bF]eYIeF$!ٴs*z|1Rπ(]˃9,GH:84v;) yn.^]}鞳 řa^XGb2YIЭb1+;8* `uڳXH{^HD}sJy G''aӟ 0%ա\I\7D& $W7Y(¼MaljI-R &kGwH~ϫxvAU NS .kH:L hڝũHڥKx;NY'cuĽ͞{R:wD>u s6\xе?GdI5ҾFE:7;Lu0RБߍlbi1pwytE+'2p@HAjEr8R")RWaæeꚖ,^D4[5GFRybcQS*~Amka}~`)ZfjMSb}5&:ib>t\[ q55![{r6IY7b왏N t$hx VF1UX{rN{HS-j=r,HW= jfPHZ>O?w "Zm4{:)x47|.4(}u:CbOY,*-!- ?.gQPR`=*HF0#D A \zܰD8˾}H|B64"oPl[uZx&0/ eyb/YL$e_Pu Apqc |VÅLQ3VDdTJFI=~1 %1(:x-o\us)_OnM\WWd",i :[n)" AWp2FDl&a87"# aY8<Xg&Wrxg>PQZ!Jo4q6$?Οah.֕c? ֈAc "{ADFq\AEǮ#R$E-t4jI2w^p3چN4Iڎbf׋nfz>;E qn#Jj eVmn;j*#8m1 bEӯot p:YMڞ^AtzN7ؙ%unxg 7CpKl!G TĽS~2 걼i}DSRW'D#?7Q!++魌ڹ_/`tܽR8y»zBߐd`*#Oݮ]"Ң@H{iӀ*12dH%>L+U d)D@ސ}iH7c_6J!`FxQEIJ?յ׿X!-A$WfU%!A+=9MR #R0gr~/ *`4}xRsvʡűI Lz_<:wa X$3|;L-n!ZN/,`4ۙ̇Cz endstream endobj 9285 0 obj << /Length 494 /Filter /FlateDecode >> stream xmMo0 !Rz|UAa۪V&$E 6~=HUAgɯ~uo$ƛLD- t @ZcNt=YNk`T=Ro æeCڕ(>Պ AiZsn[6uc^0Xah\je?0bprOY[AKS|dۙoF)MZ}4W@{YmG;<9`;K (EytbabisbgEjq(po$}Idon-p!J m-O[L endstream endobj 9286 0 obj << /Length 696 /Filter /FlateDecode >> stream xmTMo0Wx$ ! 8l[jWHL7IPV=M̼ su;Uٛ=w]yil;<[[j<=?׾+v`&ߴț<^*;~&Q>MS >_P{=s@dkx;`VY`s4JaQܡn.Uu9\Y6><ٴ.Z.4>Dӗ}~r:-d0VWk,8yLһʮӮђ[*mLr?q 5F8@=@)& 8Rx uD\j2HV0CzL] bctI g$`htы0\F0s jd< I6zg W qȐ+#k .bsrbmXK7ǵH7Gnb>&jؐu1VljOu$՟qWS/%1{\xB!K(hHTЖ枃Jρϯv=k2UKς_:~$/ ~E+7ˢ/ l(/} -+ZXukoԝE?ZKq endstream endobj 9287 0 obj << /Length 695 /Filter /FlateDecode >> stream xmTMo0Wx$ ! 8l[jWHL7IPV=M̼ su;Uٛ=w]yil;<[[j<=?׾+v`&ߴț<^*;~&Q>MSǓ>u;q~:fc_0F)lGιmu f8Gӫ6b"!YUe.`M{My?IC4}+̝l/Bj*{pϻƲO('$ *{>J-9_eQ"V$)MP:^9 ^` br @ {@(\,RH&ti m+3ԅ ,;F$БzFFieD(0A1a8yΠFpnù[w6p@ )9r9b_ia|F-(:(nQHY^`nA|n(戥K}s\}sԑoA&vqc⠦ YK^ʛ!_my_)=^ ^{TGRw1RDž'xJzImi9j'pͽܳ/-_Z,N_: ~iyY2q,nЪ5QN Y58.] endstream endobj 9288 0 obj << /Length 695 /Filter /FlateDecode >> stream xmTMo0Wx$ ! 8l[jWHL7IPV=M̼ su;Uٛ=w]yil;<[[j<=?׾+v`&ߴț<^*;~&Q>MS>u;q~:fc_0F)lGιmu f8Gӫ6b"!YUe.`M{My?IC4}+̝l/Bj*{pϻƲO('$ *{>J-9_eQ"V$)MP:^9 ^` br @ {@(\,RH&ti m+3ԅ ,;F$БzFFieD(0A1a8yΠFpnù[w6p@ )9r9b_ia|F-(:(nQHY^`nA|n(戥K}s\}sԑoA&vqc⠦ YK^ʛ!_my_)=^ ^{TGRw1RDž'xJzImi9j'pͽܳ/-_Z,N_: ~iyY2q,nЪ5QN Y58.] endstream endobj 9289 0 obj << /Length 739 /Filter /FlateDecode >> stream xmUMo0WxvHUdCmU^!1H#x?gx]OTm$|͜s_Iss :L;<Sz==׾f`*_`ɫڟk3'iѴ}=M;7rfnj-eSӵOLg~8 )ok A8 $`I\3`Af<Z]! xNky"7 _㓧q H`nḱRONH=CpB:# =%888QA~!*zƜАT?!~> tw8y*sύ }nFE>7*QύR>7G];~<6OIyktg>O:yұϓN|I/|yIg>O:y҅ϓ.}2 L> stream xmUMo0WxvH UdC۪TBb B8߯{ .@=/ۙڽs{K;K.k6/k+[M'ҷ>dyӔKe'$cS`vfSfK}fƁVGGf\bu<19w|擬CTAW $rG]IyMsh$aW7y̟u? sK-`θtJ!'c83?NaO<Dg!;IX 0z)rЃ@kpBQ]^Z7! / U <ɉ#W m/%]cX! gȀhID8QN~ACT/sQQRs 穅ύ>7: F+}n4eE=zG~<6OɈy2kLd>O&y2ϓQ>OfdV>OF<dR'<>O)yJS*}𗏿tx>z{O->tՍ]*3>cC~ endstream endobj 9291 0 obj << /Length 900 /Filter /FlateDecode >> stream xmUMo:W5?$R. d9M eCkmCp;;w~>|3E_?O]5߶w]Occ]=~?}Oyh9%?۹׬B|Ɯ>);vw%g43>\ 6 EJ78 1{~`W(-;]%=xe_,b+-O;q\L}UI--=BKE1p[! Mߊyu>.N5K)Wb٬8i[_uʕMzQ)V(Txޢjy!Z2P="Zd0\ÃGR\).2*Шa!U,H`+j.5Nα@VK-x%3%AYӀzΚ>kP#5m0Woþj.ZT$X/)n)#Wo(oRZ $Kp4Z-b\1ܰJ P"GXQi/8k^Zq:Zs9dB )sL-7xJ`aɽ)f$1 dъcCZC<73JgznHȰYɚTa,_-O87}KԴܗLloK+gJ.GZyVc48Wt]:P~`rZq.n1] S/Pu7Ue:?&?!d&1yHn5)yғBx#1ޞ]Go׏M?X endstream endobj 9292 0 obj << /Length 900 /Filter /FlateDecode >> stream xmUMo:W5?$R. d9M eCkmCp;;w~>|3E_?O]5߶w]Occ]=~?}Oyh9%?۹׬B|Ɯ>);vw7{>oaI> ѲH8U/RǾ0ñ_x0ӅxBiE.͏S=/b_ixމbc4fi|8EXD_R4.GRQhV̪xvqڎXJfUıkM;rͭSlҏ֋jU,N2@ ",   T[<5 1"àcvG@mg K | +T|5flxZ1YP^ꠦdb}[ה_Q>kUbw88]k|'%Ǿjց{ g䈏rsqk:n87xIue.Aft0!?4ɳ4mFtӔ^z1?z .~lP}L endstream endobj 9293 0 obj << /Length 665 /Filter /FlateDecode >> stream xmTMk0WhFG*! miʲVZCcYy#9햅ļ{3񸟤e&Oo]&C]]Mq>zwt߉Ǯ)n.pCx?nڽVgx=itO"i [\l\WM}'ԭ̚t4pXeȉeU oq yM\-CnCW_Ey}wP dZz891euB)] W-\v\]~[S!8&+Zce"'2Ɍ5I@|"B2AQhSlLء28a}ɑFq5ҍnnbfǮCG= Wܢe$g;A,:sx l=NOTƘ$0_س/vЧQ%~Zx pX2]$^qnaK??q FqMyc0=) &l(mi,3|d &\c ]͹&ӈ9w{d-tx\ \cΜekqLJs?<@>qhx .׷8wl~1V<*m"mmDa endstream endobj 9294 0 obj << /Length 664 /Filter /FlateDecode >> stream xmTMo0WxvB+8l[jWHL7RI;onDo3ތ?n~<&Y$ŝK_IsE77E[^N\5sߖ;7|[lzmS_*7F?h3΃;mc-bB`ew\_7oK׽;(2Z.ETz}ܟ~o9V^MVK7-\f\S}[S!pcSs|TXo1/ȡ aeuC> stream xmTn0+Jb;!B Hv[jWHL7RI7vJwD/3ތ|{M=I|/ų;tnn\3pr ܹAboR1A+Z7k Cm $_D+!8u<u/$bTy{s4 b::MGҢ!YhH޽w66Z,^EǾr}ݼ۫-w{s d\crb/)ʝ}}ꢅKlkީr8)9*QK"&VZ 5ID b!"U\H(jm} ۄ @*&"C,jdkknn"cW}O= W¢mu|]CXz :3xl=΀WOTƘ$U ۊu':S9xT>&^s 1eΘOd~`xՌk?s׾G0N-۰o|e>ha>6h Z8sseY1:@++܊psqKoZ׺q=71cf endstream endobj 9296 0 obj << /Length 664 /Filter /FlateDecode >> stream xmTMo0WxvB+8l[+ML7RI;onDo3ތ?n~<&YվI|/ŋ;t硋nn\3<:Wj\=?-wn6pGۦ|Tnʽgxté7~qzxKlqrnX7UޞMjuSAxHiQ,'wͱ 1}hW7q{UEݥ-rG*F>NNL7u]tNhWS;wE )b,#TTHy=)9>*QKr7P:MȡQ^s$LD6aȑ*s.$S56`>ƄmÁ#TL 5kd}WXssc*zRh/#? bE$L|ږ8^y>eSQc̯bV̯cNa'_OAJ195kd3EH@8ܰ%~As*=F 0`{RLPh33Y$LƹǬ oqMsȼ tx\ \cΜ-eksL ?"@>qhx ׷=l~1֍>*]!MBa endstream endobj 9297 0 obj << /Length 665 /Filter /FlateDecode >> stream xmTn0C6U@"mTt@;olvR3ތm~<&YվI|+œ;t羋<]3;Wj|{}[ mmᆂMv{Kt=c_~B?zxoBS6wBJ)X7UaMuSxHiQV,4$O;nC-bD/OCnC_n^ѻs׽9X2Z.ET~{~ʶrn_~߼h!R,6ew*ؔb%k e+Kӄ$a"1x*s.$S56P>Ƅm„A Fs 5577vرϾ+uaя6R:!,əCxg+ѧy*JcL|*m:fvuiWUꧏɩ\g%<Ϛ"sÖ0_:3x0kjhyIYx0aCnOg3$cx0<<v5O#ܵu7A 6*sZ ZcΜ-ܠeYksL ?"@>qh|tngk;dGGM@c endstream endobj 9298 0 obj << /Length 665 /Filter /FlateDecode >> stream xmTn0C6U@"mTt@;olvR3ތm~<&YվI|+œ;t羋<]3;Wj|{}[ mmᆂMv{Kt=cߚ~B?zxoBS6wBJ)X7UaMuSxHiQV,4$O;nC-bD/OCnC_n^ѻs׽9X2Z.ET~{~ʶrn_~߼h!R,6ew*ؔb%k e+Kӄ$a"1x*s.$S56P>Ƅm„A Fs 5577vرϾ+uaя6R:!,əCxg+ѧy*JcL|*m:fvuiWUꧏɩ\g%<Ϛ"sÖ0_:3x0kjhyIYx0aCnOg3$cx0<<v5O#ܵu7A 6*sZ ZcΜ-ܠeYksL ?"@>qh|tngk;dGGMc endstream endobj 9299 0 obj << /Length 799 /Filter /FlateDecode >> stream xuUn@+HɁkc{!5&Q^ үル!zya/W7/~jyld}{9}N=C'u\W;oέO*k`~?''3Ɖt3\;WS]Q?SVk ]{9FSѤoG^ 32j$WC0h޼O~wC4Sy<&>U]Rn·ÛB~,{_=ڰfhm_}4zu|sH]Wb MLD!E!B FAC\dQQ(%T<#h^QqKƊL0cF F͌a._Q mPG9'+X38)+ι7\'~5:r%%Β뤧$1$܋a %aN*Atg&W̡`92/X[B|fAlI)dKdgI$[d$[H$[hv-|9~ddK%[w-t--d ~)BO)Rd dK|ɖNK)K)++Ζ]Rd]Oz͜|x8?<ᤥNO]?p@}_:h? endstream endobj 9300 0 obj << /Length 720 /Filter /FlateDecode >> stream x}TMo0+J6*ħöUSEj9߯ IVcf͏睟ݛ{)^؝}]u:vzyu|CW$nmmΑmq5)M{`qjS5M2үxO%r^q &\TƦkR@YwDoYia) SZM5_$$>kxq4|;o4vhwqB؝Bf#j{p7P_?{+4}+VYu}e}n.ˍggfjj{k:lF #QhJq  HQ/e.!Pp #]gQtVTv)#l-g!7'uӾ:[sI r.39uf *gQNxEqV11V啣Yq:54kDCZ+)]Ws8:а/9R\Qrz\8Ç]按Sp/ d8D(B!4׳030 =;fzÞJmw&^0C~/nS0GKW皠NdzG5cC)!=E^K<3Iò8ȿ q3NOg{ACt~Qn~ɸ\ %1.: *4hH`<4̶E hS endstream endobj 9301 0 obj << /Length 719 /Filter /FlateDecode >> stream x}TMo0+J6*ħöUSEj9߯ IVcf͏睟ݛ{)^؝}]u:vzyu|CW$nmmΑmq5)M{`qjS5MJJWG> stream xmSˎ0+$1$#8h@Bܰp`~ +8*=SJ]sCM&ESݮ`w z\ħmbo'ޚr028~}uHXz_z.XA_`1o"xR:bct\$7҈٘TmH@ ]W0ywznͩV+1r]oś}X 6g1ͭnm{!^ ' bނP48YhC`୤\UY=0ZĎiơ 7([4r;"A"e"qDgs"2dK$#В%#KDDNs5&]J[/G endstream endobj 9228 0 obj << /Type /ObjStm /N 100 /First 964 /Length 4529 /Filter /FlateDecode >> stream x\oƶCaϾp7n$N<2F#iڿsfH EQ>"p8,P^B+^(|Uay]8wUxAKpe Uk +Zd8B +K]HcKNj\!9eZA3ԽwRg P( k_Ϯ@W@@8gShú &@$TdaEVP)lpX2TPF@VbpD~ kZ4FFm0ZkXJ F9PPG_x.q]H%,.kЙs£@cAI ~4(Vu.1j#* !  !@ A)bDR0eHRABmBR*d B JJ:(Y`ƀ@c XA п0^:a9`]:8G{@=,DyAozM-8qc=VNA2A%"O8 H`'?J}/xsW3jv>aآ%;ZWϗfÑ)+TGUz``:wap0yy{K(VG;ABRNy)G64 Pw*!S As BHZXJvKqX3>H#'X5ٜyR:cʃܺH[y' d* \zOklQif Z1d $an8  )VL-rna(y=]YǢ])Mry-)b bhh5ޢ! [LffȝI#dF *s _CZc`RW8% 0[4ҡ$YQ(6v4hq # aH[qzB+-r9JM\mSk-&b}k޲%|-gmW}b{=*̈; "Pb'vX'Z69+dDS =t;{"G)|XrU8' >.YǷU.2Mδ[.)(ic1Nt$;0p)%$КmdVqخ:kߴ'mPa1[Tb !j5-OBХ2c"zg0G1I@>zrpX 22St#=Gσ-algXȰIk!./1]SfDוjrG9ۤ.0ZM}'9Mj@v&1F$0k-[z,ڣ5ے3m. G 4 5LUQ<yr ãXQZc@ y"O\`ix&^6 \:IJs[ \J%&ƀNd d4#yCml#ڡP*&}b?O8SEmJz:1CQ^^,c.s=̓fP1P%"/#G ONFc1`oRl,ojdt&K#IU.{(r@*|Q!@?.XGe+eYb/N%REuҎR){{|r:T-P{9 ۃ$b,gEջbz]?S?lw Zʆuz_4w@N&en4QS%†-`4V7$\Z\+k$ZIqR5`I64\JG,)'eʹq!efl_ %\9K'n]Fo9<nts¾noKp$:7=Z奟C_wƅl{M&!9sEm-B$a,BhXPHg~:Slh~5'}.+ZR4Zghp_chp)mO i6ߝPvRHbw )w9DhIsS3^3t_W 䙜O}3&~ Z{}Udftv@/1?N|:*C}xQ=J8*慎#=~-~š 2|PM?`g#=ztQݨE5~ ]?jQ;fc=e'Gsv b? v^7-]kWy9e|08mE5?rnM94PY9FՇE͐,~M3LG qntb#vX`Tab3vfU T OlF|l&I&`fx7aS6{v_Ϊ BHpBpzGs}~!anoF236gj( ߑh :*^km&M1!!` 5hʐ/\}ȎQ"D|% ѬrIJ?I D~.<q1!?‰?/zy]O7IŨ{eð /~~ 8C5wq 62Xn\>)DO1J&׽q^RBu;<كY_H2Ł̭am'x|X8!f p-~6~L:f3 7 cm\S6Nbx?=G$FfE|;97Ϟ_E9qaXw^:D!φj|&7/Dw#y}۹M/[-i̠,S:e f薾Fum~hl!Dp:B|V6+y*`4* e|sUx[=-H3mm;>҂!]kYY_qvק]娜,GX0gmF4/@?7b79g?s_).V%L%ϡfk񽖿ɲ[_Zw7N1ƍX< `.'j^*QD jVX(H^+ HbM2!2I ŐHQ$aծ=qF9n%̲9lnKoOjƿلC`.(XHfo`Fty`` (/KcG#[ΠbXPw?,i?*~hş7sp6_/ =+S]6<}=}3eݒ+7Ѵzޡvh9QRdDi(;Q+g*M4q ʬNy*Md}Ky>ɭN r&Jn.kh >ԁds4)ݥ()Z=?ԁ87;&;M+FI kH{8J~IKtۥWNcvg9ɆoGC8>݁ApW#Hl:YM/v$B됽9z;2;wŷ6QO> stream xڥˊ%z*00biƦo_RP,GI $-DjJDfW$Q%OL%QjR,)+b %U${IP*EBUT$'&eM 3Ӵ4UK~1"P Nǚ:'Z"@\+gX7F暪ARj1֖%#]ݒ !s``n8$ߣo\2ʀ , 5z=UqPn>i`eAm˥“B+`  (" T0Dz @կ 0ւ)sI^0j/NKF* bQ0.(%1a Va#fbpu(+7䙡 8cz2n03eR׾pEܤ ƚJ e+d$ ŦI5s=jVvHArJBHbU`sd};y~w߿ߧw?_9>|Z9>SI3V> @ /C?}\){8݆ }wɕ- XoF ӱ2nj+Gē#&jZ0x<1 >P@,;I5;t: 1dzTo24 0Qxd%!e5#¿ɕ/LA+Z}+[Or$#aDBWC GVeb෻g%3&`w;7Wᑞ#s8&\Y VW-rXfـ+@|UGVPd-ZbTSc@kiH $8=ԈRT*!L:DQ.dT|%7\IQ0qtع:Vz-j78^]\FO7'(uQYbeWW$P|?_;Ac~|5clKx-#Ͽ~/}?|9O?[ֿU ~r3Pr}Z;c.O;z%S,b0vIkCLdN1:b#Wb%z,yfxX)&g1ZN0\|3El'?`g `vt3]Nz  @d;2,t@&9g wh3ZMtPP&rPP&rPe`]9] 0%>Cw^Clׄy.g1^NLX9BlJ,?%1]x#6tK#Wb/b  wl3[Mz  @t`;:,t@'9 g @vx3ZOt@  h@;432323(;egyPvpn¼4+gtn´4"F ӹ ҄yׄi6a:7aZ00&L&LK]ل܄ii´k400-MvMfs Ӯ ltn´4a5aMM&L 5H endstream endobj 9315 0 obj << /Type /ObjStm /N 100 /First 912 /Length 2971 /Filter /FlateDecode >> stream xڭ\o#~_}oA+(<gb{HWC=y|ook0FRlH?dL֗ə?r0h4W"2⮬ pT,⁛4/"04f%N?rGwWp`A!ױ턃SMEzh"t~g+n]Fd}@lDĂ:s=cppr 5u=9b|9g9^apΣg8օ@JE s+er p% MA1&? C7'o1+1WpO d*5 Q8.E7AW/X-x׊n x`*"۫KzZ7ן;ek-ӏ?0z X70|9yf|s oxOd!sF pN&GkXKp`e,!rF!r@#d`9202` f G,V!e0K r>;IryQr`Y였'`$" Xj$d G@j$HHe"! qF@ A& "G@h@de$igNpz:>dT׎rJN\ݺ)YɡkX(;$i=mHYgotPv/wo_zzue?ۛϛo6?_cj0a{ώs{={_o_P[AmCg۸fm]}IXdv-}!#d+nG;s/-\".o5#߆?f;A!l{w;KD~9rln|,wnyv3'^ > 䋗r8G &َ;Lz1|Hw~خƒ9ntBFh{%l S0V^hŢH3\ :%/, rS5I%B+gj7#[ }0 `#jpJ() ;:L;E"[ œBRPE~G'U ʥ@weMV}+am*0VJeiur;>mNP5rDXoTgI2M1"w_.d%O$i{(1f2xcDZ퐺{4q_Y#3\Ra-x0|޾|{~_ MT9CyKC.a=I{Gt+#=JFz$AyCV9Cm:ٻ؛sg$)3{[,3ì1-LO=c0WkV.>w_}7ʺ d}V2R# B6aG(M"! HO( h5<@jAFKтI*EH8r)BCuJV_*P%P+bpd/tJY#II%%{F;d.:,r.t#0Kaj\ @IuYd ] HYbcY{d;yiVAV#\䋲JH .!=BhW'~RBG ie =PF]Hp2 +哱=[L6Fc,Į,;ÂJxZ8&O,Zu_6.O13u2ڼwjIFbq~eiAe|hnbtB΅(k#mTvbu[0BFl/GLRҬI4#;90װQ%ZGcT`|XEk 0Y| b䫸2RlLJ p¯ `ҲC<;)r*tJ5ǁzaF 2,o# 7㩇Ҏ_8'._PQH_a01a[;ʦ̓xNᷕqV@yI*j`I T ^|= tz[}U\TgӇ endstream endobj 9351 0 obj << /Type /ObjStm /N 100 /First 1073 /Length 5734 /Filter /FlateDecode >> stream xڭ]ݏ9 .}frw>8ݞ1v돒*RRIG+̚WFlӆ 5Rpgml23 Wv&7SڪptS?ӶpeWbf@l3'l9t3g|DVƧmLgZ+99Z:.hLED \:å !|$ppic \ oåm^ 3Tl%\"҂Ѵ&߂4uҌ4ҌAZ ^YAmi_,9. .E#_hpi8lZ4pi-QdCt#gKRå VbBåKp@l!fB%HҴ H M[hH3MTG4#3x$M րKf tJ 64 4 Z]ֶ"4H4^ qib(I FŻ1AhqAIgh7 B åK#.cڠ3r2]HKfcpi0= J*f (Tt ; !D%Hk4Hk F@T@Zl\4tiH{ B??GF?~ٯq[ssy\{wڜi?ovj~zgYf_0{I̒q#iu?(n~ѼjN|N/&.}l΅@T;_!V۩ "F1pCr9[WvW4MѲ:m.9jFL`"x <6"zJ UL +v7FZ4``f6k<||-&A4OF)IдZ}[ZDիEu%:RxJUʆdٻb #RUsDj{ai"oWcJxd*=.D}Yiv6h~XS*߲^ϔ9r{#kF{]تZFtԾѧ̔[WjrEPi܈ZZ6Df0žAv&ӒC?1&V'æ&&Qm2Jp wK\A3nGUGx_P~nvwA}Vq eDv + }̢.$?)[(?FfMXl l('T! o_x!=+K鿺9I6_6]7P9k٤ ۭ绛/.5Mu/C3声K?6`oYOZ5훰Y#boY ؏Z~7o36xyQr[ywyxqRS}wHq mJkں68Nr[[X|rqd \QKߖ+tIok+4V*ަb!ܡ7 pNeM[QLn X|lmݿ熪̪qhQ 1Ѥ!l?OU~bC@oqލ,@WmIe`n6 5n`i e;r4 4qd3(]Jbpdڲ^ >g@*Z}וP= d j(0DPgxڈ大EgU"/nv81;4O ?2ݥa7(|SM٧ûПin_e_<% ?vK08j޿u~IzoB4^2%t!D"@C3jXV8am;Vf`UVH4iLPZ^:WhRP%Wt+L0'>={mNJw3 ߯W^2T9?NdQ9S!vBJeS~w9|S[O9U { TxDI51u9NQbHTRؐT9VI~=/C+!5Lţ$)B{xfE{E^iخ;Lqz25tLnu"H䓼ܑ1GQݰ YTƓ$Aם4ƫtgXw Eb|ytGesYT[D[[qLvr ; LWeS䙉ej1vIE%t ċd z6stM p8&la-ْ -"4zBCaf]h΄uuQru~O2ڕȌƉMkeVnU!T)cekUX*UvVOŷ;+-3|Ǘ6ẞT*\Un\nکvJ<]+\:u-za̧oK_|Ue`S2:%`WjU!Mu*E͐7JM4!V.e&3jG5UK6_ܴȫzH^ś+b?.)i&=eDj'VէM>h o*I!O'l:>Uʺ"Vd V^I!xus܌Ȇ'>ҟ˷)]+Y=bͬdTgZbsuzvu9/ƒ*R-f]<ÛO]@E3-v,x ~4|) 2wG8`4 Ze>1v _o 2aN- /y Smd+X?l;Ua~n4oǷ٭l#$p&YXYj7B-|A̓& ňS9;ZH/%G%ІQb`龅;!?̷Ҏ?ۧMT+n:3#.Dk5RBRS2p:pF郏K0\pʹ:~+"Q ƥ?b^ 3RSt+LR%2y~hȍuA$FL٣ňy%3b_FUa+"_r(18 IӞt EvTmJ߆/ y1sr2QB6-8S|<{p6X$4ERIouxMX;zF[EcP//AZRc: hqVx@&M.1G%2T}6ޔnp}YȇD99 2lc%h endstream endobj 9452 0 obj << /Type /ObjStm /N 100 /First 1071 /Length 5596 /Filter /FlateDecode >> stream xڝ]mo8r>?fcN|I`qe7ٝ<>OZNw_"/XUɲTO⻨ڈUڨ*\UoM0+iPWv%lÕ[Iŧ~% :n%J\IkuVZvQNxϬL\Wƨ+}(JVvdUCV9:!+'MV gL<UT(G:EI>:eJҹ @pT9(JtK M 9F ` .`(2`̓F1yDd҃5P2< `Ivф Ȯ$ 2L ( . d\*W|¥ C]B ր.\52fwZdKk`J5.u2jk΄59( XX$%XSYn*r6\ZBKR!c¥X.!EJPju%Ok**x!G!1& R]AD` 2!8IV` |U&`R U@>^2Fջ$؇KfML ֬A|UN42P>Ç?}^qruI>6ߍq{t>~4o/Oj@ A C ?|F'@$$2cx?>͸9-aV3Az.I|3)axi-6dCvin/Ws㏔)+jٚT-D)DSn&<,w#<=l TccF4 =nP+j'ҡқ_>OQ#t=$o 90WNT'H$`Bx(qINT >l җJ TBaVjuM*VeۮkhgDNpxò]ڷĻ⽰zJ? Bdg:rܯ=;6b*0{ׯzG糰LR w?/͸ # 7u?I-Q'ߙ,KΣ@9KXt.3Dž~|9P'a;AW*0D2ɢlz<L*Lj~OQnhzõɀ$IV\BȢ*G"PCHlrnfjˇ&#t.HxtVX^`)JLU9ǔl#qq8ee} Kv T rޭI3ZI9$ )ێ읢=W%[\l>yzinCKn^&6p*m:0d[TM$7ݯ |ztGWx'lq_J|=z{7}: 3GKg\%/gUku\c4CƷz:j3lJqƑk%~ M^8&iNi&7m\pc_ScZ2"dTdQ2hOJ#+81QvYv߆p2Gy'IrjKz=+ggLLWk%pLũzW EMθ|^a2oֻplV|zف _0LQl d`{n`Y:R8semvLquĉ7V.g(Z\U&?5!`"Dz%eOꄵQ&.Pˏ/<|hO|I];~;7>Jd`0#kvxfvT뀹*a I ExJ%Kb%W* V馳r<U}Rl` eEA5l`Vz?3 q4&Tu# Pkuuv#WBFPGXe`=S ǀm_Pm_hW /I{mVz>;Y6l]]Q%X>Sw`J$G xX5.he]~Xl}QPUDhOBUI>-kx>t~ejx.sZfLZ'r^*6א mg'tCgs|Ǽw\o F(DՂ%R0V= WRvbmn0l_<#([*z(_mBbX-rrշa20rf?3|8/_JmhL3vEM¨)c ьfkVwdUX$~U]&h7_s@Fw>P@IcB˕_l[軎ql }'؞Ie^l3?u ;V"R(Oo3.+1t`o0tL>?}=@k;U+g\pXοz- M]NVVwD$b&Iitjjęc+_~k8zwU }|̽x'=]uL!LHSk_j|d -P㎱=:,k$syQ:֩/^Hl E]> %}CBa#K-V#zzQb!I_*t'GdG%Wp)~@jE~SDZ`kT/5ZFP=V*LJMG!+G1 )qm!GsɆRհۺ'}!m<OY5528vO%,OS zkm!@ώ[^GV?ir1*kg/k8PTL"8#Ԙ1=:0hN{Q]9ss++KgklRWap:r&ju3=tf\d\-܅+XI* @@*SQjPt;ȿ.nF<-H4X-Sɯ_!Ăd ~#mrT*Mȸ74y3&"![ SVolɁ(γx)wJu \\|Jf/ՖV?tJzG?LïK#:Q4am6.3x`*UY2r;}A8, 4T_ܝ֢ 񸼼jv_t:&bBi% U)=QcE7>nU87 ]^f{ G|*q呚_LL'rbL`rd#D:+]&'D!uYg&_ᭀx;ͨ"N9w"R'T(Jw?w VU:Yt_1#]e᜝TJӞb#HJU&66.@~ ðYbQ g*̾xηQU^JY=-OH^fb ).抷.mĕHwDDž=D"R8:%_HA4,/u,{r.B^36^Lv_ i-oۨ',W Ra,o_' q0e!%~vq>oEWz@4BQHފ"o%yȧhmIڑXYM ³јLt#mVhATvqrYW/7w;z~>7eө;H,2QUKᡱ wK u(ܭM9ISvj.Xjdt";3wLsY.8:7/H ՄԸ`bڱ R0&y"NB>6a-vnO?}Ot=#Kδ9^/'1O\ff+=@=yALgkB\~"AA ?:<"Mܵ؈K} endstream endobj 9553 0 obj << /Type /ObjStm /N 100 /First 1066 /Length 5656 /Filter /FlateDecode >> stream x][~k8; $,=HΜ v>ǂ'_"["}q*WE6on %B0 l !Wn!0/DЩ,,v 麨ÊB+PNw/J-"62ə WvaDghPW~aNl,s*XX#ɅNAM getÁs.) !"H'8P!7Qv]EN %ާ[P~ gUJZUFHQx %9!G"KtNd5k5Țt*9"ܫ gMizI{JL:RiZ4h&=0sDpGiIu|$*E%I'/`$$Kv"H&yE-[Wfꆐ*MHuQ HB3DUݺr~go88SJmRrٺ9@|>J@~90c&Fc_jQ~iR`O[n=&Ӯτ $g3$ y n:!ʃU7a ;㺬It\o $Z|90} =_sא+teV+m|ΩZtRU6Sy٦.TFrUo~ y`|INW 4%8e#F|ciXT>#RYTuyGt>=JN11# asa mY3fu8癏|6 K{H~N즰rA :/4sVnЍzēb7M*]%AoM7<(z x¶(y,n<:x{FGrF'|FfjaɉOԒ ~͕lk7]~5}C/2T J%|4JptEaq:q߯׫CZ V]ё?BA%pm)nS>&z "zyO bC7 IJ͢ϽA.UYF`ƵNzk~Pc, %)vZϊ:^ >'3R$H> 5 km٠^?1E ?)mb~e]w,/P_nZZe B;".lbL%v֗ b `x$rj!uvZ7pY&?˫1G" J vp/}"WçJhwYҁsFF(5L%ns jx\]9XwWa\x /oĕ7@5f0;ݪNx93 2Afa`Ģxdk6e7$'!S \~ln(p׸StB 馨]#|g.v:|JQ<S<+LY]*;lJY~ZnH LνN+S.(y`\:Y[}>5`ߔQQ޼y7X8/k9|% J~\==E6HU703䪷iqws9x@{lY NxO]!<i7"`W N7j:ۛLE?M;;rR Xy⻩ ?845WWk*$LԐcH`nqf^E54P9:85 qQ"ٛoTvufnSn䙱NumZPIWk6DyP&T $b#Z)rvFQu WME&3\XKUd:8N<"hL~߶7b6a!BRY:1u( e@=b~,q7absyܩtd"0 ё rb n_I*0 we9Sîw:ϬwBd&-:!脭j :4ٛBo>} _崹v苧_n6/S6aщs{}0Jb!{&JS4,x.22M[de"\ ixDHdp\m%F}3NLRP3&oz-ة< }]lLEdx~O;O;~U~X4Ziv]QYL_!(Ÿ3w{v0^o<n=cyǺ_~)[Zo޿eŽl-KzMquZ b8B/ ;$\^9LQ^ a \o) jp.! T;DI?D1\Eq (ó[PifGF+{,>_JiJ@Gh"'Bϫ7х_;m Ǝ̈́r^.rV>6oVt>췇4/\NjG$ E1*Om"%( t+~|~qB{CBXтEW2,B>ϰҳ lff-ʵ8j]W zԒO{ AXۢOHt i[JHDBZOR ?7 /W7 ) K@ʈW5PPɁ8jS/DKr-:*Zt٧\謁)k|/HBkS[D:*}/(Y*U f M0tid|iiqXka:sm߬[mij*p3SC!O;iˢ"R^ׂv3QQjK&qȽ$5p Pj^{nB^MM% vV&V旁r],6s~Z/x+vsplj9t5TAy[Q(=Z;lH|GN #:Bx b VVoEi]}gg&kuKIpũ/ 4ɋgk@຺:Pc01]|)(>fsp@wgIS ?Fn6d1:x&?9Rc"dz> stream xڝ\MoW1 g&$C6 rP,V"ˆd*M:9xwЏ&j8hUuE ڢtIkxK*i,I;~m2𔖜R3d-{*KVe!HZCɍ=͟+"c^]Qi*ک,%˰9,.6fS͘Mu)SK]+бԜ=uOi« sJ9zYZ0^KԖ&#w]Z}ї`i,63pPiDF^4w\Y1zӷFq#t}3$r~bgUh~߶͗QQno9KǮs|i RZ>hv]?}\OM&=w8#zxnޣ8h?b[%Zmv{;6`MF !lxjh&$0g*0Ug0Kϓy0AR+ LE;LnuHDLOկVN8;W+L @ůyH{( ´:NJV3 v60 \7 TƁs4ؚ|`4_x9qc^"Vgi諳Z8@40گWn?텫g#pz^%u*H Dp #^ q8AuqN܅8y2щ zIlےT8#\'voIgƶ}ݯ͌>}8X/l63Ȏgwcyhw$uH&9r2g$c<0ym3hvM~@ 4耖+fmdΧ$0]4hH9'ܑ/)(ZLԮ~b]=~+[ c(@+ ~3]s};XUr~)oTV횀7`s $΃m-Wg/ݴȽPoT  KmG$>WE\3&[%IZ_ ډ#n 6|-d=B[m̸qNT8)8|B]I $Wەo3dZ@w:7!vRwx{sjT8u0G = yYvٛjm TQyYսBt 7Dd\ym`^hS}G ݿ?Cu> v.ٽ|\+}b4NE`Tw'Ny'%3%IjUod6ʗ˷P9YHŨ!K;qI 7ĐHN. 7v=;WҶzR: q-Ⱦ| Qk6dL ^;L/58KQ58K^Gtt gv +08lbh&N-db֕H$$0 !0l5G9k@׀9!;00 s֠=]B憆0{JƘѯ.:Lx!1ER_[09Aw}/0 cp.[qcOMyz `TwQy Vb^畘]y ^ x;L{dzs 7b }#q4'kE4bC==F8J#nH4r~4O?$|2{H(4bCF= G,JtrB:Jc"(!<&xFO|SH7)H):[StP~)ʳ&/obxxjQ u8k{1cX1bhH)1b1 cx1{'rz% #donlXNxp#ONaS.qz oukmz;.N?hdټ;>ZװF4 ¯E@^p9LCæ%b]b1l=fa #/ry%C!E4 @tiÅāƴ1  v=EXI&"0pSИ94 11 q>Lc dd!dd!=FM{X !#y( {PL!!T4{R(zua Rڣ[\j {® O*, pqN{PfZOp<&A@aZixd(|0;0/B7bKd#x:IGҏFce-\ѐ:6(Y%1DŽu[<)Pb>B(1$7+1g/J< s|y5j}? Bӆ Cca1ub:OXcX2GjZ8=0S,{L 2bӏ>И1jZPcXbYcZ)1)1k5 jqp;I}̒ lo P`P?J!T- ;B]P_jGv N{vB`ģb0+vBy=/=T_? ؏E.R(/[By> stream xڕ\ێ]9n}WǸ޺"`0`jl]o=A>?R:~iEr}z<eцq1xpi=J|\QyG1b$1 =j#;jsG,v54Xzf_By與ېaB`"xc$m }HQ9Hs0W-%xW-oء ?TZK֏rXi&5\? C7RӾ?\ [ <()(JQs('=Yqj"g91Ű~z D#匡gdό|XÚ/=caN)wjujڪfx m1mZvfx<^C[뚯\Zhx-SZhUӡ!uںgx mrf1"2{G8hI&{ MώBoMCsCjIi$NQd={C6-\EF{mid̵ahG=,9 =%JhH6OA C8 -rI~ןϯ_~y~Z o$w Br\In)yx-[_۳? R^*$>s.%K^ʁ⅍+Ѝ@,ЍNkyne ;7#5SJ@N^ 9&zU6)/lӱY9YstWc\w#-[_ظ:Ţt`4>ȻyvwCYkF;'Via40ijyy y>qPBf'TsBu@λGxEZs+aہz`n607G9!@6{TB:oyKl-@w:;|Ri΍=vJRS0d@N`Mw {~ @9r6W ]%57[EnuLh%»tNEA:@=AדooVEoV'Z tW t7 om2N֎ZȻQ W蝂4^ߜk,U漐07JК K ;0\&<`B>HaB3ZR;'5Ғa0biLш(Y(}݉' F{hmOiF%C8\ ] ²y?OVozb,;0Fi1bI4c:ʄ$QhS%c 9/H H5$cEmXj|aEM\^I I4{,FRƐƍV_s#A/lįLS(:@'-{%-CIԂƋ1T3#Iz6E!ՏdwW9^ ;7#5I5q^Ɋtb"PVY|at"}}Y}P?k/lPN fhLOz6D. rB#9c7^Gnd$썋d!'̓0W` 8!=9!9 ȍTǭ!-Bhw͐9; 's1ݿ$cX3ʷEH͘9fɋ$sw>Փ1zu.|-B|[8@uι dȻЉIz;Nbt>@`t>@@6oX]F \ }pIODN=X*| z"tir.5fZĚKar"Yco=]Oj͘=Nz8= ]h71}mR @Ūs.l.@6S" )]O*ئj͊<1E i+hmyƋmR6NW"J  7 (zvmkR,JrM6m* ڨ6* ty݋5ITPMTͧEwrK9i\+\S_5Z Ҩ TFUrQ}PkRIT^0wvv`Nށ4ڹڟmR5d5r\8A3ѨLTƧ[nI'\/_\/_\dPNӀ4 ;0n it|++Xc~!y)zZ]O*Ȧ9Щ -,@7ڟmR6%ئqQ |b6:$hoI'lӹtN|N6:hXO*f~Uy76 76 >O6z}[kR\`1ئs] {6:oSۦXl \ւl:ׯ u*Xu5:l\XJK Tө5PMgt7pF<°umX LsНir_3wRoX; DsPy` :+e-4K(BdBڟmҒh ,tp[͐{#d )M,mD3c5^ ՈDSw)CNh$c mDSJe59D3S`%chH(O_bm۟;DѬtbU:$ks=͒lOڶ?i F  ]t`ӥ%g /ZжIK)WNRBʒjSٍݶR7ڟmҒjJ/w T%nY23 @76{Oڶ?iI5?Ҷi[RMᏴ-YٽJJΈxtcOڶ?i,4ayM1Kf&M1Si$s.si8D- S2qb-B{T]҉F[:!'8ub!'0rS 9;!oEAOZNd9"f)IBNcz3o'-fLG& 9YD3lVtcCNW2Fo0lOڶ?iI4c:ʩ$`'cɋd!y!%ьȋ$!1:VW gZOftjz2ˇ=? }vO?'"qE="Ag}'"1܌ Gڟmғl _{Mcd *{Ɛk0I۴;>A76-mima|O?`|};molooьzI'lӌft:qFhVkҷ< #`lLmt*ѩpFߴ|ͨmA6ZslAV9ƉND(8`o_fYP.h}Mvagbv i":"ė850veAz%-Ϭ |Do~(z 1xv,qew]Vmp u#YMO!n+;-ƯfߍׇWhOEm l|*W/yӋ˧_?qϿݽ{؊<&zɵc0-}~߬ǻo78a6ay?T`5Im_~9x+/}m"&m"ft#?|>޿O\C5ݷlmvo2a>a3dwmzۧi?XȌlL W}&3 :à3tfNOm+v閎޽ JPRg4OgnNA& 6Co^k|7v?z;?޽[FNxlc_]iO2 V>.||Z'>#ֆyX]ū'c9&cŘ^d*7/^/O113'% ̣}O PŠA>2WSʓ9\ ]Ay endstream endobj 9949 0 obj << /Producer (pdfTeX-1.40.24) /Author(\376\377\000D\000o\000u\000g\000l\000a\000s\000\040\000B\000a\000t\000e\000s\000;\000\040\000M\000a\000r\000t\000i\000n\000\040\000M\000a\000e\000c\000h\000l\000e\000r\000;\000\040\000M\000i\000k\000a\000e\000l\000\040\000J\000a\000g\000a\000n)/Title(\376\377\000M\000a\000t\000r\000i\000x\000:\000\040\000S\000p\000a\000r\000s\000e\000\040\000a\000n\000d\000\040\000D\000e\000n\000s\000e\000\040\000M\000a\000t\000r\000i\000x\000\040\000C\000l\000a\000s\000s\000e\000s\000\040\000a\000n\000d\000\040\000M\000e\000t\000h\000o\000d\000s)/Subject()/Creator(LaTeX with hyperref)/Keywords() /CreationDate (D:20240111093527+01'00') /ModDate (D:20240111093527+01'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022/CVE-2023-32700 patched) kpathsea version 6.3.4) >> endobj 9856 0 obj << /Type /ObjStm /N 93 /First 939 /Length 3272 /Filter /FlateDecode >> stream xڥے)ISrY]$eYvdU).$HʅMi$1$lSC#ɄPew5($!ol]FX+^E:VJUޫŕq6o9θy$lE yd Nt ~w^2>v2PIU˛V0D4!)ٛ Rd)}L(31TyM*ҍfW],V d(f+iD; i %Zp)Q+".uWs*1?ad+|t瑭ӵydT8rÒn..+F˪9]ᰠaү^_f~Uyu}r{zmD>yc=fϯ4%MRJTT@B {Z_׫UDH(R,z@xb5ni}Wp)GL9bED!}7cOό3 e,##"8BpdKrٟ/VEcQ3a"8N7Hcd=F0fDt8ov|}0d(\AiQP)I<FKYhvAyQP ID}p bLH^BP HGmǿ7rsty&/Up07U9Ϫ8XDa !0lfӬӶn7{ϯn:gg"Fh*81-c7B-@4AFdt;,}!b :<!%@TxdoUۉիwc 1M^E_1\Zx c7Fpc.p./n"߭{;t 0Q[P,λUw3]_M NE0\Ų{[t{Q=PD1bMtHbDmOU9 2EZ^q͚ns#F0b$$l۸Y̖AlO>!#02ŽXvj)/gm `Ș:8+]mS~z \7]~E[LNQe[dweR1PogB-0,&`F1KwXxc]?ߌ&wQh+b́=CU.?w=?Z`h|_걊8 E-<#(oYy|=m7njA^! g;ZPxU"m2XmϷOvME:gb! ;gGj;1u{x]DH@:T9Yozv޿_|Bu{NPYjwJ}{PgYS?4Ťv{8_-7U3;_(@y~\F~90;@!G8Ѱ}p5#PG 4ѰlUn @ ;I`M.Mۤάdp(ơP/^/ѷyqSoj?'] _qMݡ;7ݯŻue~eyq endstream endobj 9950 0 obj << /Type /XRef /Index [0 9951] /Size 9951 /W [1 3 1] /Root 9948 0 R /Info 9949 0 R /ID [ ] /Length 22901 /Filter /FlateDecode >> stream x$yTwܙ3sgp}}a}_}mX{RI?.I=D[0"cӦ=&9%9Iy}=<]{KAAA$k)XZXu(ܺkغ]Xݵ2XĺWJYwb *mE`u߭`q V[wZXgY\u;kqlug,nm֝XwѺSsպ֝X ‚׭;a od$mqau;fq'*,(^dQauo;bq/[^w~8`Y<_d],7nu,ںxˏ} nu0b㜱u{,Ɔ]e}BXbd;G R~uu;,FH׬bE]npsy]uomZxZкPvmxh] ݏuOxn3xns_usEfuy6Z|o;f]$Zh]{XNo2"ɺ֭Xwں57yU0e+[vB";{ju:娝}Ժ¢}tygOm>=jg]i%VZu-q-J[/X.~VCv}uYu.k~y[v}MFv yym>;]Nv+yAyi>zͺgF˝{yyn>zӺF죷{dSvѻyGwj[>uct_b-;nみN5q_[Һc-oɵ[uGm1D}._<Րl!o57-F _W)f]8l&;{/gC5׭K:5,AuvؚKԺW]XօWr*d1֝UںO]ŵκ֝wU֝6ZMgԜw̼Ssպ.'-VξKֺ`u[;x,]ݶݰǺŽo<?{~8`],CŶ[YaqGǬx'VbaƉ3s3,\YD/]vRZ`W X.vW3x嫧acO͡W?#x O)<^+{{o{|/w /@!A1@)A9 Xa a- 6A;IA90+^9譀Ck y85O:\ %'J8ppkaNm7t N'rwLP%p4f8Ck<;+}&w6V p18' 3py\+pupnmw܇cxOaKRPm;X{{Yop{m {!.w݁-pxFp4|vRx[ Gwz/%B >' _+|^7" Գ`D|_B*^ Vp/Wf/zIC6FY [ [0^mvx[߽Uy&xO ᙷ2y; OqlEDZK+*q]h}iؕV0pN)簱b 3? <\p . I .d.SQpnm><x 9p ^$>+ya&<3|"Iv[e{ xЮpa_$*{Wٸ)9+'lf&5ٮvMe".vnsۜ6qUEܨ|mv Ӯv+]9Үv+h ]4iMhE.vѴ]4:ګawEb܅غ:hҮvxc {w{(]9iWNr_b߂Tڥ.vK]*Ri-H[Ӥ/X $P~&RbCR]#銵s$?q{VB F+*K ߈[1,b0n=+7P+AT%8~)xxcboYNa8*tP}_v$?87uq8'3p΁C p.eW\j7܆;p}x'spW 5P=| >C4"6MҬBPNrK@ͲhE,6ՠfUܬfE4ǠM fm4kYhCм VQ ǘqI+<L^3y5ڼ3)4KY*q# fY40R fO82Ĩ,hF6Ѭfm4kYhF,e,fY4ˢY͜7J ߌǬf49JU,P<7YGקᄅjJoTܛ ]5ˬY\jW%,fI5KYR?ʢմE5-iQMjZTӢմE5-i1R݊=q-kQ\ZעlQ54sIB vr [bKoQ YȢגE]-.^/cX5l1>2ik΢Q ø E-lQf2[٢WE>:](E/ xQaT,M xL/l1n^f2[٢eE-jmQkZ[ڢŵ(Eq-kQ\Z(E/Af[}Ihw<\,*g+Ң|(E,g- J aEwzH%V_o @B%ć>Uࣞ#p>JF2B#LMI<\YbD##oTĶFt0F0"G$ɥ?7V2 $5^? }K6JʠV)U@&I`FY [ [$y>~,U vB|Dcx!8G8p N8 <\p . :T aG:- w0poE/}$?$jcx/uC8Z䟊{ o{|/"J*"2V%C%.1tyn]6{WQ4fmtiK]FZXA]RIJTҥ.tK%]*E,d% .t K ]u/NB K%]tIK*]RJu(IsMhD%.tK/]zK^ҥ.tK ]H,tХg.EtE1-7.t=16uХ.tK]&\ BIC BD/ŰLoNUߪ5C77@|pXW*vQU{ X~8qaE:ވkb83dI8Ǔwc܊CVŇN Yubo/>V]+p)\H7!F&n ><x 6w^kxo{:6h7g"/dAgj F 4JQh@%(F 4JQh ħi|:hAuШF4Q:hActӯq)ϓ_tl? 4?f$0.q K`o+T'ɳ>$Aǽ/̶`\zx^u:qa\ bø0.q1aømq[w|CƝa\ bø0.q1a\ bø0.q1ǩab0I`\%0.q ߱|3e˸7`\:qɏ{-BԽ$YxŸ,e1.q1a\ C| Jƿ=&|LT~JʠVJHAd0)\gWH:Xj#l,l-P y8 G lH ;>v;a}((pN)8 g,p %٢ߋp .Cw┾DwzW}|><x 9C|VsWހRᓏtŸywx(BZ%/~ K_Iz?߿_*'?>X֜@%/~Ow?t@|@$NM_:wSPDʱTyxz_kZJT/~K"n;M^'_%*WI;_/q$Oǩ #)qOrӯ~+_97[y zT%/~E+__!Ny.(2(^ }+`5 N9 *a]^R΀M9))<)gZ“2zu>SpY8ĐF-8~▯Upn:oX}Żp 7>879}LMAȄMff7qS؝5[>G |y2mnM%m>h+M/mziJTڤ&6IM*mRiJTڤ,/ M miH@&6 M miH@q{ziK[ a-ztꁏHfK)MmhSD"Ѧ6E)MmhSD"nr?2\mh:hAMpnY*NCoc6oc6(kNRqCV$&6 I6ۘncz ̅I_q>s^螣{.F鞣{5I`z92It+Ül[ I`Nsc9؟Wgl?sL1=9fv'Ӫy瘞cz9瘞cz9.usQ;GsQ;`N s^樝vKI?9瘞cz,⛽(9m.7Ngu.NяO|V[O79=Gs}o%I||U1_XWVjXivOu26f9 M Mmvn{a\ p 8-a8Gp$ӷ>@|xWծ$?{ߺ.܃#x O)< ^x 5V4ĸ"> qWyP\QY"ogCe@C$!VXbu!hq!h|( :DC:PARn\$!VÎh_uQ~wߡ} @Pyv%EI2Cq>5|\}nmw)x)H.}v}^+x o %S~[W[uױ_炨pTuw9[.Zץ*x8uMR'[$PJ^ݍŸ*Juʩ[ q"Q:ES|S:gR:miNuڨF6Q:miNuڨF6Q:miNuq%MOtbkhNuڨF6Q:micIx*H@RšmSzEN/uֱZjuU'E?T:5թNMu@9uʩSNrꜹ<`H] N SںIџޤR')L.S*RɔJT2)L)V'E෎SqSq]SO9~)/StO=EStO=gc;Ny LI`JS1I)gʦ\, W)1)LNoōJeJ*SRrJʾ?%) S*R SGx˔T2%)L jcJS^<fd1%)YLbJS22WŰE[qGOyz:t0)!M=Lb ʔLIoJzSқRɔJLcR},nu@aRݱ#ǥ0Q)U@\rT yPq&7C\󘃻>)IQ%G`]^ p18'$p9G.% W*\P 7&܂px15O| > aKفL/%b(`xFL;-bB(b{Ak ?`dA@v$E!mA `P:u0?A =뒢_a(bPA bà0(A1 E *bPTĠ"1AWu0A `P:u0A 6 oJ~'ydP Ƞ@2(A dP  ݃t=H ݃1Z|1jzG3g@!AҜV?%E>ʠV@ *`URZ>nql壂q!`#l,lP !oVv+wB\Ǽ\{?8wC{b-u\(yw<pNi8g p.eW\j˛n-p);DF|Fw? xb2[iO+rB |/+0?K &yU\5,a =0;0+b8L3=a~]>L0$<,a==S;"@0$ITZX!`#l,l-P ymvNGO~8#pIO8 <\p .{7C,5Q܀M$܅{pCx  ߀sgiἅ[8oἅ[\&Br -) n[n[n[n[n[n[n[n[n[n[n[n[Hn![Hn![Hn![Hn![Hn!%#[Hnqz -L0t -L0t -L0t ӭL2t+ӭL2tkqA<ӭL2WN2t+ӭL2t+ӭL2t+ӭL2t+ӭL2t+ӭqy1ӭL2t+ӭL2ݺ/),HW~%ӭL2t+ӭL2t+ӭLk[$mķ@ķ?ķJ|+ķJ|+ķJ|+ķre+WSqh@ZyJ|+ķJ|+ķ.OW},w|[@ZH\2[U eP+}U)U@:X&PY [ [P`;쀝 v0C>05C80p 8 4s;Tp.. In niə}0aDCp%Hcx`zޯW$7jMTQ@Hߝ𥝤vv/ccWǩ;ەS|I/vBӔIR{ (sZOi=i|i|i|i|i|imimirI?(;㿴㿴㿴tuܑ6c֓vșv ޞq{*qvvvvv藮љx,pvvvvv6]HU91iYiYiGiSI/ވ4Tj:&Ӑ##ct|Bh?6ҥҥc18'...tz+^16}_oE,ze׾+^~/RKm/Rk辰^{iƼ`+duܥKhzz|Kr/ɽ2؛O pKA/ӽ$LMW^zI%ޣIwb^zz=5MX*y˯޿}%~^V{ i%W9Iq^zWuU]zUs\+^1W b켠J6)^q߭sWePPk2aT*X .>LZX!`#l,l-Iߌ*aT=LSiCTʭIɊ=SpY89!fjW>+IɺqסnO*]qN)AL LWLW`O?LWY&ϫ|ߘ+|j]_ZjkeZ.k=ZkiZki]7`- ֲUIJ5ZKh)jsWKh-ZjZKh-V%%'F 5R)jKvjYeZ.k岖Z.k\+.k/=' "n XKc ZKc-4漛To ژ:ژ01\ƾ`- 2X`IkiZkiFHJ'j8`r:@Iߏ<``z `1Q$W7`_`zv6#~0L0=p47)6nj0` yH yj(/&%?e;񀙺8 y L]\p9`? tB1坤'~#n^;@|~nrӔ٢Rf9LyK bKbK8|8 2 5IO b& 1-AjtT| 0;*Iދ[!`2 ١V0֡<6;`'ݰ e80I_cpNALv N$%o9&R;t.RY_]k`Cpn- w.܃ǽ=GlذTn³^Kx:1=|`l ԧyM#0CG\Z1_銤d9~Bpk w_߷d!Ytxnd":ѡEth ƎIɯ=YtȢCE,:t!b:8w;e vNJ&]JCA/@GL% t(ll; ;` [di91AAG 06 &\.ĬڎI)ז.it/н@BB t/@fMRu 1, L/P@ Ƃg`/@3 D-LJx /0`_/H^ y; vE,رXؓV+ X{bH^c/E .{> j]vj]v+ICcz^c/hm .w^kxōaլ }K$PEP %P eP+`%G V0ւɄje`lMͰr*!U  `7쁽80p 8 4p2\p C5܀p n ><x yRz)P LG|/EaeRzh7'M'?}}=py=pyO]^hzaO:8ἇ{8ἇ{8ἇ{8ἇV{HY~̷q:Azb 81I:)s[)G=QD"zѣE(}Iߍ;H@z#G=E,zd#YȢG=E,zdwmhG=FK{ѣm Y뺸yȧ'&xh.B)MJʠVJXvIm[Y D=NJt7 f7WQ f ?˱P`;mN KJ~:h}bBbţp()'8'$pB y&n"\p5pn- w ڽ1`̂3 f,1`̂ fEi4fL u2f̘"0c)3̘T0cbLݤݏGsf1wசx_щkSy|u0**o )1,e1/y/ʙ'y>&%~();~Tͼhḑͼ@2N@ G2:`% tIe^*RʼT2/yKe^*RʼT< D3/y̋f^4ͼhE3/y̋f^4ͼhE3ymkc^ژмy]j^/z˼^ e^/z˼^2yKe^*RƼ615b^>^#ۦ@!A1@)D/I%e?Q`5嗌5 `/o-o3lJ1v}B| ėTakRV_ ^'8#pqp^闓p|u0)+sp.@~ . :T 0-[p]G 7I8|18| b`?FcL1=l18!s)ŝ?F' _+|lo`o`;8~<)gi|4A :hAtР4A :hAVE 7~ 7~ 7~ 7~ 7~ 7~ 7~ 7~ 7~ʤvQD$  4HA h@$  4HA h@$  4HA h@$  4HA hŬ?5,aaaaaѷѷѷѷѷѷѷѷѷ|NKSlL՟EhY+/f e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e ee e痷/UvYU6;Yz%PEP %P eP+`%VjXiX `=d`lMͰr*!; ?N~y<iURo~6 `7쁽80p 8 4p2\p C5܀p n ><x 9 ^;x ۓ_ >g_H`֏J`Vf%0+Y J`Vf%0+Y J`Vf%0+Y J`Vf%0[`;(bYg%~Yg%~Yg%~Yg%~Yg%~Yg%~Yg 5I\lIl$0+Y J`Vf%0+Y J`Vf%0+Y J`V{V5YgٟeYgٟee[ֻeoPPPVB *`5դlv>h]R^㫍 @B% v;a=~8#pq8'3py\+pupnmw܇cxO<^kxo{|/~Mt7DwMt7DwMt7DwM $eK;ͺV))_{-C$& 4IIMh@$$& 4IIMh@$$& 4IIMh@$$& 4IIMh@$$& 4IIMh@$$& 4IIMh@$$& 4IIMh@$$& 4IIMh@$$& 4IIMh@$$& 4IIMh3KX%,)bIKXRĒ"%E,)bIKXRĒ"8_|%Η8_|p^cٜ%_b%_b%_b%_b%_b%_b%_b%_b%_b%_b%_b%_b%_b%_b%_b%_b%_Z R.)W@!A1@)A9 Xa a- 6A6V p18'$=)\ݩ p.eW\j7܆;p}x<'sx/7j>gB7X~ȹ.ʺ+r˹.O\Os)]7Iʏ7eI͟tkr˹.kr˹.kr˹.kr˹.kr:py]u9\^sy]u9\^s˹.׫\TsQ]w^/r.˹.r˹.zr˹.\/˹.\/˹.zr.˹.׻")TO*{Ε^ .確r.˹.確r.˹.炼\\Os=]t9\Os=]t9= z%R7 B(b(R(rX+! VHZX!`#l,l-P ymvNa}A8 KʯueM6)9SpY8\KpUסnM܅{pCx IO}@$'> IO}@$'> IO}@$'> IO}@$'> IO}@$'> I0>8㼏>8㼏>8#/Mʟj?S}~}~}~}~}~}~}~}~}~߲J'W^IJʠVJHAհҰz a `+TB`lvn{apa8GpNi8g p.eW\j7܆;p}x<'sx/7j|p~9)t Og_?ٟfiٟfiٟfiٟfiٟfiٟfiٟfiٟfiٟfiٟfiٟfiٟfiٟfiٟfiٟfiٟfiٟfiٟfiٟfiٟfiٟfiٟfiٟf=| iΧ9|iΝP9 3p> 3p> 3p> 3p> 3p> 3p> 3p> 3p> 3p> 3p> 3p> 3$ϐG |oyw~7w~7w~7w~7w~7w~7w~7w~7w~7w~7w~7tw7ÿ|'6AuЭnt[:A/% fnfnfnfnfnfnfnfnfnf+Wި_ި_ި_ި_ި_ި_ި_ި_ި_ި_ި_ި_ި_ި_ި_ި_ި_ި_ި_ި_ި_ި_ި_ި_~}{|$m+?E1/-'P("((2(RP`54u"I?l{[}| @B% v;a=~8#pq8'3py\+pupnmw܇cxO<^kxo{|/m`ܶ)B(b(R(rX+! VHZX!`#l,l-P ymvNa}A8cpNI8 sp.E \kp܄; +8SޛT*㛤}SIj<X x 5 0__M}=?WSo/)(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((ꋮꋮꋮꋮꋮꋮꋮꋮꋮꋮꋮꋮꋮꋮꋮꋮꋮꋮꋮꋮꋮꋮ?/:̧G>95~{|////////////////////////MKw?;̉=z `?p8 8p N8 <\%\p57&܂p<܃#x O`3x/%ނ̓ݍotk_tm$CG :2tdБ#CG :2tdБ#CG M7: t(Q@G: t(Q@G: t(Q@G: t(Q@G: t(Q@G: t(Q@G: t(Q@G: t(Q@G: t(Q@Gna9sgϞ=g?{~9sgϞ=g0{nj;]UM:X`#a | [al;`jHa'|`7O380p 8 4p_% W*\pn- .!ށ#x O`3x/%@ (0P`@ V1~ A?~ A?~ A?~ A?~ A?~ A?~ A?~ A!2d>| A2d>| A̋̋̋̋̋̋̋̋̋~>7~wY5K                                                                                        ށ.LL5}wj;?aV,U!` u6F 66vԐ Nvng9|{ah_=#pq8',Gr yK \kpnM܅yk].gmYrv9k].gm^!g]Mr&9kI$gm6Yoݳ6Ytf:k3zI9k8 %/ BgmY[-t:k gtx`Ymuֶ:k`gm6Y v;kIziL51oDX0~IVgm^jgmY/Q`KY/ݭ/U5,_V?f/;;^/< 0fz)Ƭc̚<57kv xw?A7%\{2p`5o6>{jH5rtՃӱjOa|:^|Ӊjg?NV+֭NU+tZxtZƧՊtZW-W떍OٛDj~y W|7|_& ~xu6A_N'?O?K|U&&]??; !( ),Haag5[ouϋaE(E(6sx \fgq}xw^fx v*ux+2S<~Uej@Z_;Z_p\kB5&ךk-gkZkׂi @!&ٷF[{co}쭏>[oߒ%K-[޷o)R xQn{Q8xsk4xwMޭwz |+V[o |+V[o |+V[o |+V[o ˪S ^0i&M¤I4 &a$LI0i&M¤I4 &a$LI0i&M¤I4 &a$LI0i&M¤I4 &a$LI0i&M¤I4 &a$LI0i&M¤I4 &a$LI0i&M¤I4 &a$LI0i&M¤I&aVI0&?`LI0&?`LI0&?`LI0&?`LI0&s> p18'$p98"| 2\p 6܁0><X x 5 L?7Hɺ#Yw$dݑ]LYw$D$Yc$kd15FH#Yc$kd15FH#Yc$kd15FH#Yc$kd15FH#Yc$kd15FH#Yc$kd15FH#Yc$kd15FH#Yc$kd1CH@EHV"YY$+de,EHV"YY$+de,EHV"YY$+de,EvnťsKrxރi0 +a|#Xka lͰ> C05$Ȱ>]|_^CpQ8SpY8\/\+pu7܆;p܇cx sx/7L%k;7o|#F7o|#F7o|#F7o|#F7o|#F7o|#F7o|#F7o|#F7o|#F7o|#F7o|#F7oIߙZQ endstream endobj startxref 878856 %%EOF Matrix/build/vignette.rds0000644000176200001440000000064014547724214015166 0ustar liggesusersS]O0@ A1_ Q|.8ڹvoo[ױND}h{zo9Cϲ,r۲trj1ó\+GlpF莮KNpA}c0"e)yGY(u9X:YNaLeH1B /dT%gc:K$+窲>sIPWT)!}2'b S&e9n6kR Kд@+5j+aUuwˬ::^z\m kMi5RYήe*_Ua>u߿]QގfNHwOD8sR.[ڐҹ5Kel6l=rl6MFayS^hz}~ѩiMatrix/build/stage23.rdb0000644000176200001440000017504714547724103014603 0ustar liggesusers |YzH)n HARS-P-5-EHV7PPIlE3I#qNI؉sv96fͱlسU ,(JL#Q{߻|0EEIMG /-.Ծi2%}Qw~TE:' N61uWڗLQ^nf YܬIaݗ;L-[5_۵\Am8`kè>fdm~2=||+G. VChٚl{+v8WF.Ү_OdhvxQtf {b}cK}gڝ]V~,I#@^a𸨕,-nr6Tiqr%w/C,µkaꙪ C8 y"##KrŇ,_I;2G<ΐvdxnGyxgJTBU]kBv 5&x٤Sm%T,с 'B)yrBJ6'Ápށ֖xG%ŭtlzI֖NՖbYy7"k|)5OD*ݛf["tm#gw-,E.ݰ!Dlt!}<.aAd- KQTMngĢ\JPOuiRևrf 7mR*x٦ױe9!9OD*mMs8iH!xjG"\ӔX9 sni[k0jMӗ*6Go5Z/iiFOPmF}MMZ>*)UnGl#Ǒc#l#\na&&nmamSECKqc-j,SK=W'͒u{cXBGbc7OEK")e㑝1f8 t:X򆩙vqO FFˉ,\|  E7 E;5KY(8Jy&X(C|"GNYemtv9 ]$9m\k1y6",xZaB&آԷPmaX+K+.znIlPͶ d-r3pK\t^YG5ic9XdT3!:V.-CЮv-S[DځG!6Kt(e-Q V`V ?^/"ǀ7!ߔ{ĔY vV-RV1=h5w-39u8yH_]^̱1N+M'H"CkNY22Mtƀgi0~qNBńX񚲮t@< vvx|=y&VrPzd81%N߼:)+}ڎOvs:^yXU,=-V9g[G zrXݞeѩd:YtuLz(&軼Nvkg_D8e[v>ǩk[od­GRl9ala;qK^W:xz [a+#أud=~\rǧ GG!fՇ!otLP[H+uK{HẋoR-`׾Ww-Ԩ6'_,M!e~DmCXbMC236zۦ72ws&.zڂ{:~&>ox;\W~=܅4lIxLR<~#F3ORn'Hm{J,?//nڹ8/3d٫;h݄Jyt[@Gۂfou$|Y2}Zۭ?v+F_xwBN|hwwn4Z64)_[,q|moGȟ7/i)eU o8,9JR.fRG22b^yD4ΦCM('5_!c";nK^B̑v`>i79Cs+|vgW ^7{q%ƺ _^j9 l_^RƗ<7.rz9>VuKxpd 2)^tO.i\vC6Y}hqr0z ;Kx0l=kª#+X~N'V+=vԕ!v38d&ŇքG=(X/b[=ҙ;,ӟ5UeYm V,Xί_Ћy#oNͮ=-ȷלklB4حH,p[q7 yYA-#.ȢN`TꆗO݇]^,*GVҙY0L}SN',a0s?Pq%C퐇"Ge)HeVuCߜuȗz.76Xz%>ǥy3Kd<$rki[weoוHjZY^@.3Y_m^R7LBNJ0fz1MJ,{҈r =;= Ή g=R9cq; ,TQ`~dz}ۮED$ Yދ3fq0'eܧ?cc6cH]/d6zHo Z9"!7((pa:}VlXx3g3#c8]>rNf!B`JᇥӮBBJz)\,DCkYʔ"Q,4xi,qmJ'U]irϣ `g M [X+[f{ʸ{\K(e\xc> jg"ב%ǻ:nQgutЉi&+0˰iF9%E!$dE@j pBwR7\܊IdҿT7|9\`ԶcvP4O1&A@t~& &M)LՁ_L"v)#߰&2l(KaBVģ(״ff?w p&ȊԷP.:%K*Ȯ#nxc <H++R/mn%;R#Gg ՝uwY>YpY0 - 7YebU9@'dT*IBFNAjQFW!_fxR xЈd]:EuPq%*C՝x]U0{+1CѹF 4ȩ _=oӐ_f׽.=JX[mȷv0ҷ=iYyJtYj5DYȳϺ"84du}̰x|,oUD(ĥxPWv`/ޖ4DĠx6Dt4 ǀg ˗Ն4DD,0 !L|Cm @< xI)9nQ -WWu^H}[(: ;Ss|՝_eZƥ4$SD?x+"PIEh,y5Z B.K`I+#%|+[p⑎g3~eRڗ:vD~R 4yEEuMrbL!)M-D؈>!OG$V]4o%Bz5rio:dٻN4n! - dƐ⑤qk7 *ǃ8YGԅxeyX^T.U)z8yPDYίn6 zP9s^Jp SI2[̩yk_-.}l{ G3ܶE'h_J贷p*XPE{z NnE/Nƛnň_9y/E_Q]QW~(xZ_ _zy[i< xШ#]5911xU!=,'XaEdw!mn߃^9@T|Wا$^*:޹a/^edWKy*du穆R<g6I AeV0g90p4R9׽&a+j3I8Yh,l3&dq*~$ I_m*oG*$y$?ꢚ[̂]0 S0!E:!nA%gg! m_vګUE!ǛcsQsH)H' O(.jې~ˤw ߑ wG$'4^ NnO<38y@è9񚸝 RwmH$p zÜCǭ>=/kX4S6->w_nݭ?<ߒIA)BM[*l9+[F9s-R-FD±9 < axf3&4dXYi$DtpHsry*a-o&jq2d~IV^?g}!mU@<=[=v r2+tz~HPݾ4~H.m0E]TR sx,"q_=m<Y~Xf|w %B[o5et8 ,ߘgDrx|yݽat.>|`0>7!OpnN4y9R팚DpHǧk /i3?XX?(䣍XH]dFa*wT` =} ,X- @5|Վ۩W7yࢺq;^2޺o]UrwhS64f;_bKD0۷k2=F8շcAo:;tY{N'lesۼoGe̍_S+ q>@<-h5=a}EޖxO[ R< Y(p`wbx88}uHJNDB n?,6{j>Y#[!;uN8y\+ׇǵi$m'"*]QYޣ[u[3L׸ (KvFo2~K̩cOq^܄CH]'2dC]Hp4:,jjG Mf˅>@<- u&o)!^lRXHzaa_M6 7KfSeE7h".kv6YݐUɝV9q^['!9Ă&PiסH)]9a.PfP.SgIل.C_ݕҰ*`eM-~Ars/mRrCZÝV RN@%&Z.XcIkk/I!_Y<R@8I25𰤞LԌVt1C^c,x]`rRd'*קז{כ8p||$҈ wx#N`/^irkU+@Vw^51EeB3~CѪ|[HGB ;6Y?-$iA0꺅'K/x 16sR<ip v7br8y99 dZ׋dęnO-ox ~y$E? s@nP|kw;Q}ed ^o"5"+zۄP&p򴺈D<ўGf'R@<4z$p$@AxAu}i`ƠI]hDb Zr,nn[+U{'"fs[cL1#Ng#mԝ d!q(d#F4P%=S.Yt)'p q>iWD<9sҩ^׏-+aB\(*f֓DŽ"6@y%B?jDDV?~\ M?=J'Ugi.Bn%_з"9RӲ6:,Z9;Y0?;afWA8},י~!p43U8+nS?m_Dzi+(䨴9ݧb,^g3 )q&m谌!(sR 써:'G!*EiH?]I}4V|E9 YhRz dI}>HO}ŀ՗|^W":9s-j#~ DF\|zZ`-D< 5ޓH]'0 YȁktӪ+WE6YrՄN4,9%{Px&v&fOr2u]b9fH 򫤹BG/C6a5[~WFdW5X_&iE [Y xe/Njs$Ҕi;Rw8YT`U`ןI2dbw3Ґ*x`FH]'PUM˖6(OgLcmǝwY>"dQrܥͭ|rO86L4)%w!7>bj' O4?b!.9OM\5in$-m$>M܂+-- .A(UVl$غEmAY܂IؤNwdCj̝>WN/} U1wë;҈X*dcN+YߍrȟÑH]'p|+]3SR0I=BWeŜP{G: v{PsR[-9I ǜuvYNl: ^6Q{+[7a#a/"}?衢v;_#Iu1, NCK%gc}wMƧڎ7s=LBV7}h-g-m ,du35e[4eJG%"!CV{uFNF>C~_䣚!1;#*bB4u2wy֎4vqLA/et0 t 3H]$dAw7OI26M{,󋬍1(P=g4'߇|AA~$㈷L;f3JU2f K@4j}PASXRLBNJ{J$Nhn-pqނ,<ӕ+v!yc3_A]wz e{ ~7arZ>^d(BC%e{pls m`j !~v?& Y*: Y݆І1,dQN7ׅmp~&/CrsrpUMHB~*c«--td =(0:HKikiw˼Pш}UZ%HTg 7KoB^_>Jog!G8>SvCV AZe^Gcx,&T٤ dF>vxg˰X]Abֽc mK{MkY_OQ8`DA(|Q0s9x9Y(ica;FJm4ܵNCn]c05کӓ+Ëg i|DBV9s _xN\Exq%}+oIL!kqCkNRw8 YpwܙB+[t! P,qނ,6glĻ,OK7i.B߄=FGƒW4f/ts:WkO^jλFΰ7>H>%)937rήFs R(2&TRp|%EX"6BVw~Sc+W9^-Dp |F2UQn̖fnM .N@PTbr&duaP כ,p 7]itӢ {irL˽Զ-fnCxs Co|Dꆁ S:?Oà B"5Pgok9sFߎB B*71F]4YuU֜^Oo@VwX;A\n! uK 6 \,_3swHrH!,~"Rkc 9 <YuC ~z9tAt%jFO!M-(kp2fK[PIrBMt9mI~Ί.mac;/+~d Ks {.Y~, a${ {[Xu=%H^|A㇜zI!J\kГKj` Ql"lB#J j x!U;Y_ԇކ|"@<4DUWa6~]~-(DxPWPH]"j(nYPz5%wBD/C:?No@B?_6I37kuI/!e3qf83@<:gH(pN#JC/MZ\(_ B>އxgsΩi%'< 喑b1ۜF!GelS]=|QBl!CYPnxؖ8o5k-ԟnbY?]j3/gj7IOK_e'vgHdO~PS&3j;WфM8PGU,oNCzt4CCDp8.>@HwhHM-#5ҹO#(O!hOWBU6%ȗLp#^܄E\8 y F7~T.:6Yh\Gӂ'bNxk@ < Y++?Ax Pt;_#ӐȭhHMgk(OkP["Exf(#uaBd[?R F~T0:6YnHh^yru&~僰{*wGR?@{i&~q;mV{κ$wH|w iNvAkAH U7?d D$?Rlb[#lREԶGcl]x&tŬfs7ŃݿA( ɓ&%ĖoCݜ:YݕlIp4Sd m)B3@Cd 7%"u!˷D pZ^ ẘm%û0p 4;8l{l#qt.żj2[s`6kxW &!>%e@w!LQ}UV%2' WH]?<`1`rTY9!ā ȉe8yL(]t^I$*d#"[yB-e rxR@<4nżhnwN~3g rzӝĮ &=TU*P}>@<wy6mʬнխLX燿yڡ}i%HQ]kӤD~k fg}lufo"^Cᣚ]-8oa.]ʛ/eDdu-ۖ[.^܄u!7`|܂-}TSg=tW8mM .<;,7cQw"`wĐԝ! |ԝB_Ж+d=}b^ܦ#k=bxxp୿HpbQBӓx͗℻tRS5 :BWI/O믊%*lk](䬙3Y`ĢChd*5uu<591tq:ۺ?|`~qaHځyEos{7=_{X3SѲC|&$-#,6C^$9o Ŷ#aPھZuZr׬fm~Ӫ *EӾwF(ur_Խ["oݣ&3r]kƆ |c+7׾qV`!Ҷ(5 &<2QA57]NGIkg-76~kUL^aL3V, |Qli+O=_{ˏgpe%.>|`zV$v1On9{V|v-gv̲5JrteQ|m3뚥G鵮a87yH墺U)e5|7w˒%umm^}- DU$=,.{`b.o l܇`#jvObG!ձ;dvl,O ͜rw ɹU/x*u<5R+܌PnoӃ&1J:Br?|@JKjX>HN, R(bytXV{='v!6_QO o+YO!7sC{J&?).Ҥt0wZnǨCoj*Q$ w[ Z~Ұm:H[k琌 Wz!^vGѼ(i;|9Gw@."RA9{ŗ y/Q@VՔPfӄhH4MǝJrfrzI33!Lq '@{Bv]k+-_[j"J{YoAurW#"I7jWvkٔvY|{644;7/k1+/ymm5ioͧlm`"ⴛO?X? |Kk傭^yk-Sp \1w(AoN`͗]Nlx.NծWEWij8=e5_򚑳ޒ.7Y '߉}b޶um}-;VvP:ߴfz}xkmPuσzڭkyD/2] }{-.sm,LJwqwIu6ձ[:>W K_׊NH9SkƁ5۰szWd'5PW^Tr6ϣ2y]'tY3B>t~r\PUz&˽6ur1̻uʔ.uKu4‹Emjױ1|{+/ -)jʫ` U^zZ젓N75V׻Dẉz-dN‹zЂ]}k{ܫ@# {VQZӔrֳ3/eu^iH$ZD~Y(e#o7 Kzvr4٪@1Z?fĭkwyP[`k㎵B|VvBnk!~ &rhWuRuN昪:kTzޚ`[Ѳݮ[y29/6Nt誛jOn̓kSx²ճe#WAj|ݠG ;=`O~ױᓻc7~~E $Ǜn}gpwr`;grzi|u|i4V̖;ycԘaZױϒ~k󟫛/?4_us9]_6uu]\ُtzpذWvj>Zrl+pPk5 oAfCH=ѿH)^F5^4y'Ic"L2N]iԜgd odb:ӹ|ɬiyWw*RxyCN9[Q: }M}^7u9'3)d'D=SϦ_u,4RB8yB_ ~TX6s;2,t l>SϟNvU< ,Z|Wm;~r\{~TCUd,Gb5kJC"ݜ!N8RF8yNG}? v]휯PWt1 9vܫ$y{tF<]m G U,N%t4΢k? QF_:oNkز9NbJ=[1྾uo?/.ۻrLwٸk*):PY0YWH ]D0E_/"% SSE6T:#gH.{୯s+rزܙ$3=o!R`#1o64ϐC8/Pzl /wF?3['ֵ?p_lSx;YIQϷJG`g'2Vt`ihB+8+et4o2G[kҶc!ʹRpeq t QWzI./AK kHp(@Ry YC>r/@|Qdc)N|Kԟ8m5FH},x٪P#H37 cFL4NcVW7X>@<4Fт|Z8FG{ҡQ̕)ucYQu_ai&/s4~)S̹(} ^tdkAgK:`op:< YhlVlZہg Sk9:M;#IxV^Lu#x`I4iz^Fބ|Sy^n-y#XP4K10'eZIgf3M <;p4~^ ,礸lk!1Be)9̤x Es1ҳM.<.͋{|,x.^BժIZ/ꦥGr¥Zknp 2qu ,Mzo'"*/kpygLW5p*CͽHrI"6P`B-#'۞?~)ϮBt xQ#= BWZR<(']`z=d>X"ŀ _SV6Am!4Fׁ1 @<4RTU R%h 4r9r*Nw<ӻ($NTk u#7DMIz60_Z =Tl[IY;sY:E OԺ~[V;Dr rpo;dJ}PfC;zki,W42Nf8N(aƆ{{o8B׸DxB'LCivB՜iLtvXiBLY[r.K3[nΕw!sc6M;%uׁ-;%wG j'ݺG+KWF^u!re͒8raoq2E_KIܯ ,VpBl9 #33z2^: etS+eL_ei iozm ,[[7rݽzJ! ]~#twj@m'Rn`V"5 5}&;~W j=,-JĻMq 9}LC~40ќJܰݼwzS8V&Җ}#p$ ~>"J)-BYWՓ+Y{x&v4oBb;ށ,p7t~.x7Eq}v;,D={&}Ž֘x )G(pVHYkKp(]|,6Y;zI33:(1oE*K2Fl鸡zb?~e>-3)NNoIQd%T2d s/OvΎ?@vii"-;T| "<'#MɻBNVOI}9-]Ӑ5|Ng J2> 1Y0d CoiF'MG&^h9ݴy3I@WRg`VJ|-elӓSC:W1tމQNCd)R,?4#7>ڡdGg(<+ a}+K+ĺݾ55#eb·Uz/p򂴍C;S BX_9؛PnP6]_vB]a^xѳԈ{wAV\%xCjԻwG9 0pX5luA? ~)ZPc-ueR&uN tJfݔ7 ߊ"@8 Yq6 fS _Ytu"ux ixY4< YfGں   _qr^2N}S/20_>3lEy<#C+~0-D+YTUsSY eމTvv#-kpgm׶U ^LAVy(X  / 8y\ڍTelr^`hL I:#M)Y B>*'j̰K: ːg6XP0p 2>*@"4܄U. uGH⑤q=z=dr/g nt@F{xyw '"J l m&B "8y~;F!GՕD(LCN7 !$Iiuq6x9јނrXx9 ^C,dx @<=J  rímuC>,kļz78ka A2Ƅɺ IYcK&X]#pˀݟ 7SRw,4Rs\RN^F'QEדp %ò o۔^|mUP,?nHP4mґ lKuۦYŽW{-x[K\.㐅ꡐBԐED"dᒿ뛏G!~.]KI- 6dXԝwcXY %]T*yv2wH \iӍoLo =#AwgBxAen;$h u=kCV̕K2q8<Y]gKYC~J SWe9fyFV7mo' 32p4kw`NZGQy{Tw~v:83ѶK"<m~000 &c8d s?,0(p E$!LA M^_0NGdn ~z;2V ]=Q" E5. C/G{^"6i>fW=ii'(6Hi閶&rп5X"u[Y+#? ܋&{ tǂv-X^|5@^G"V#ېIdf.B(ms_lqEN@Vys5whC>.Jw7BnDxnlTȋxy`rTY&j du#_+~u,7~,xydȸ ڡ6 9)zʛԏl4]u?\6m…!XGB-Vn2(1 bE͢Ҝ Z% MM89\ǘ;V1X% fgA cTI$K)wGpg!V׾J#Kpk^, @ Q?s~PG=$ᦟ5 /BVmn)\0 !pM!!E0,&骯ឯޕnB%Zרᚄ/8~Pn'\!zoZD{YoPhzBC^^w" _[~.]ѯ/ /P%oѯ/ gu>*v[|I8 y~5{a _o~~5ה 3 /ADv8hAkw\Cow\.@^hAKKKN;t TiR۟G Qfk/\U,M,oCx$scEէ?62ZNr/Ao+:0NtӐӍcHe$Iiƹ;c 88յv_ Ta+Y858yK꺀))igfe]@VЂ;pUEP oS <Yh5vyBDU`I>^nef/i7&xx,_\n%V%pdB5gsQA.cUn QK 09x_&u> 't1d vDswܭ^bV*,R8/E^a6$: 8Y!nDcU\D^rɤŭ>R'Bu1V& nAMU¼DCfPuw v!G! \B.@9$9XB1c<txn>Ą7Gv[(:$vSSZk{.Tw=-^/R"PT2̌4Y洨b/ܭew± 8PA[TL]:D C H%P.r@.!OK[{s+r1\:0czr3p:ϯ,xߚX׉:WE̦ȝ2Ȭ Rwx2ثDehDQ-|eG!:+qj}a!Ş@<Ͱ:dp oeF,n@# CkJϴ.ʝ]4~Tf.wBѺ0 Wd3E&qwmGS;LCNK=((wTGD&ņN!K .Cn nHHZfWm7}ݸ~OK7QgwiLPlyr2c ;#i=;°lC6bKtG FlI.dbZG2 u+-cLL7zNS|oDw+/ t5LvI3r4bq4`2{xRz{YzN߰i1[p =:{'V+a97% /0q"#h&kA0YhvzhCL&iB>_CF%(JM'ptLDf yAc/5opZ8]˺K,MJtSd,{^y.~ctaP%&NQ,k%)PP8ͺ-uVF#h1` y]Z}Q(Q"w8 Yh + mg.;lyY>8ɪ cXë OB>X ;i;.#pb6(rWL'ж.>&EȋTcNoTlwnjR_\}ݼ>@o[T=z^)=#B},ӵ^u4Bh@W)D-x PZoC|TsAiνP#{Dv^#Nd#V!mHHk?p˜%dG +85!1`r\kFfːխrxߘޅ,4 OAo#!ߗ=r;Ǫ?:mQE){F~߸^ bU_q$*@>?hF!G槤0p (|~J: _Sf_Cj@[?{ ( o Cf#ÈAV!{I%BW^Hqeȭw7_X5}U}^,t4ⳞMԝ#m׀ŶV}T6p|0 |Hy'v'qbː7>{Ð0>OG +H Ȍ?~|G5㐏+/9*;!1; AVyiH!u'q*4&LFIFyEZMNKlrKE4duNԱFY,Po埄GFc\wf)x ae^s^?&lv'q; rT(dx@nŚ #-[>*[)g4+,sgПB *Cq շKhȘeo`rr =0w]L菷 yEa 9ݟԵ@~ЂG>PwG_ί;mZ蟃AZ,,Y{ f/<"dih'!Coܸ>w.lZYn.M_4!'NbVlIw.e";8)WP}_|4Ұh`e;&8\ذ_j>)BY|-wϨoM_ Ne `DXO=F&-qTUb;`=(:4YDS'UUU ]P -9cfi MrWiWU+~z|^VW L[Vnj0;YsKѭ:+HtN l~ϻ ݁#޼xta|8i>O_v7>[Z;ʓgImdzVD>x~=+Cd!Hפ=*XmqJ~gH?kqsQMvM.]tʔ U,1o|?V2 |ď'?{%LBN* JΧf=AKJO_PJGOA;8qvrs,157 :bοnn[^ΑlvBr;Bu>$ȡd#Bu=vɲiJNSC.Ң6eduӦi#z}iO Y ˵>W;1_# Y&7or{ >i:<*{a+l8bg'd~],_BK޲RLOV*s+ya,8U'{nWIY^w oA?7M[൞I&AIs@P]su&MZ.YnLn:9fUϖ3z/^7o۳Ÿe$g&F"Nʊ?AYzި˶ N4Cj{>M|n|̧V#UiV\yRrGV47EiќK۱Z;D6ۺe; !KUfؗt\2{i[Lc/{)(%R(ހ|C>DO'4o_Xtu_Kk؉T(N[8y]O^>q },u„f7>*nA?4i9QU4)4}5Mg'MN4͐\< B+kڦIn&>Ii&6kC:Mmdڦ}zUMoo&%ۦ}P]۔Ij&M)~#u n Nt}sڥfV׳ 62?9Œlnj̰q' C2椓qQߍŐ~﬘rH^&9yy\CtPD^ -|i^NA$p YhAĝ>* )`- auUݝl ,bB+ 7^& lhIn 3?{rҌN, 41OI8$*pb2Ŝ1pt֕8bY0?K$# HB:< DyU%opI8ڀ$LHBZyEuI0㣢Jm0Z믜@j>7`I8T""i4~?$TK|Tdn (`0recfY+B4L .5"L9nOUFܙj\5)´_D(E?7E)¤6w0䢺RDl1EU-p\ I$$Iz$|ʦxq8^T-J`_Jhq@bCM6!ILiq8Ud.Eǵ4Q*j[xvZ+mnjX颺;JZvM7ʦ1VXX 18 UxI%U1QE4]B MZ`v,}QO[1;dgr!: ~hI?d5TFZuY641u%;ğPPGLo8؅m-cLK&tAP4mVY[&d'qQ/%4W3\DܖNŝRN0JZƧ@ö6P6gP곋ѿel:FFmUrNne6i~yfYGn1ڦ?7).fUENG О}ѣN;H}'1.On2AaD;d]3 &w| 滺az͡xr'cS&SΓߥ75&F(db wJjؼ32y lP󝘝XzNyqclIMzMK!x0mhQTHN ڼjWM ܀4,KSKseanNzkTJ6A<XfGt3Trvnzib9+qì/%HC 9^XR@GG4СnŒ1h<::nE%TAA]qOWVz$r{~ N;߾DW;^?.;2Nwf&W:{W<\Nk$Pn3rɉ1^<} jT`P#ګ{MѬC P>TU^voAT+kHvD$Fݯ>~K~t6~׮~o󟫛/?4_]/lJ~m>~CJx^3pTTrQNMDߣ~yi ar 6e2t7tcW)1*>Z;kk]Mܴw@Ӵo;=||!G{*;A} `Ww:^a=^ycz}ýjNU=@<4%)LAaZW5۰s Ն!Y"G{\XPlV#3|i$%=-q)n@>Iֲ̓b=7.>!G>rs%:dOm\/%:ZkXGVp;tv aS:aΦ?lmIDQThf!C.6mKnp鮖Z t(m3A"sC/YcmR,xZPm\OЬ !mT[m{^Jd7 鰇ऄg i,j}HQd>r2&: | & wxLD8@<-Sz >N!mSe􁊏x$s%آ":[՚6 L3'#arR8 uÈ<[A"OLg!ϊ@~l}{LpZfq]w_GF/c%]k.99o:˾yN?!:~B' 6y|K!<`rZb@~gE߱G^е6^߰Y[$" < Y(F !bQ("x8yBwe:k _'V+X?{tm.c,hZI n`I;1︯[Fynӕ|,؃bj)cn9s E}#4<.@w孀JZWdW| -ːvuϲuDXf{y0p\ jJzg?p51+7.`rT!Պ>f3H& 3.ېo7I[;;͏0N«}S]={9(a]UW/$\t8y߸I 3i9t{x]NB&v1w+ mZsGi iij_Dpm<ށӰLԞ\^D/B(mvPt#K'á1TxuHJfE>\Yvx,u3xkp4 1P(CkUN ,2pO!wKS,!G" 4H"% < Ǥ,+%Z0'b\)\(M1^"5<plZ8NMWwaOOV7E= (rCk9T&YnEBQV]kBޮs (䨴w\beΝ*M[n.dH'T} ($\J+]q) Wa%\d3D}Mҝ`%1-b#SO)a>/%. 8U0!j_ q4};:Cς )y^YP S U-/ۅ>/e3a6 9rg]dIwVe4LCN+3ҁ8)bim$;V.bM,A_xl=;Txi%E㋚<+>Ҥ~J( G uMQWtX/ل i:奂=Jb5\$NGໄzct<{! {~{FFcǚֽ$'I*cϐ6! Ş5B D@2,fV-.ܓQ-a`dWUpYYC " FT\:;dC޾$^,nsE* Xe,w+hbCib6]gmS+"@Lе"#; ڰQikȺ w0 VdwNڵ9?1 d.p/mOMt+Њ2“y)*x .y ^Hj;=Ŏr*(gC>b㨏AƌSODB'! Upuv= ߥz0NP6@S(e;:^":1bBƁc~$ǕyƁm֋+b66-rAY:q(,2idܺ#:#Xvf&MЮڻC^,7 v_|YJ ><l#{ÐKT @[ĉ0Yüd,8S{zPBN{uӌo%= /(,C!c)8yP5urKE0 9-M|lئ ]9I%಄}UGReUrZdu C( cA0cysICŁvC*v,].#W!aBO&@xPP=5Do:}E}cxo,RLQ->1ý\ChRw8Y6Y^]t`=KmTdoA#b1䅖VI/B5U[bvDxƻ G*KZe"嬑q'pИe4o2[EN]sOۣyGGk9Y×+ PDiؒ"X^-nY]64'',GM3 q3?,WɽS vIN0r]G \{*dpjr6{q 1 /]O;-X߯)辈|Y WC6p  R@<4N[\IײێkV :DP{ۆԟ 藻} 9OMI)ht姒jFu%6tf(Fgyx5ԝ oAoYݙ\8:EK}l*Idбl]TcNpX-ɚۂh)k),LÖp}J\c/MJ>b "Ildf"v *kTF+*o[tEZqY* JRwX(;I?x\^,ve?p7ᛄm{ro >'zK\ENb"}m-2x Iƞ8U3ƆA?ENSVk "r8 y9fJg 4?YN:HKODpA]x ?RY*B~$ d ``8͠A"lxP6Dmv``{ PdtKiB5ކnvy߸ W%<YhLmoU /@x W%<(s/BVWgX{nxآі;(>I3t"^#\`>LK:xtThC^u9;}t'd! l]Wy7pT4H[nA/O o*nng;s|;l~X/gx/rMVB7\Jӟ]36ibiI9ۚ-e?zm85̦nKQ0cT2LG,_D}PrPMPes&u߻A&YͳG)F뛆zs7l7Mnfwoy}t~&{{ztxygh~uzЮ7{7Wzu/!v6ĪdcjD-qC23vȷfw>6֞jswzgwXHtodr|I }#v '{I#l&8 +|DXN2>ǀ!oxOuO@>!,Yu;-%r į4fŜ_Q@nEg^DVGaݮPOC>{+Dx%Nq;;ik{/h\NBVwY.ؚ7y=EmLue6G53Nc(iBT bu8\ȟ߶ /A C|H]72d\uwi!q0:dUg^꣚g 9.}+k,t\M[L&= /2–i{'{ӝ}t{"(h <;i>8 kԸ.ҩSS" | * a,"uuOjc(Ϝ14TUWWU]^?=Nha>/soτd&-~c+nu75GQ9%\vMRHtN ?lǞ+ zĻ]G/E+Y6ί<^ss݀!/C??6G5cCClmIz=Ɲ^g&1(iQn[L8 yZvkiV,n٘r ]IJ!:+X&JxZfJǠI,*z-tD$)(e/"tsH,?SK:%A1nd.|¡+G84>b(_'ӐOK+^Z^bTu5'bQj,nL8?"xA_ؽNLS3׸<n|E%8aꗲ2]Va B[RyG5}yO:Gl)I鱑KgImf=/;A,'fqO_)lyʩ֙ʰl~(- U =bex^3txjۉ {+F7Iaw'>OQq42ɕv|J o>{^Jz 6|}Tc](f̉^ৃT"JS0 Ais5˺>[mz^7dV9OY^{q6ʜM {Ý7N8yN:nW~ZTbu ]9!vd&M[KrIi[r͙ew;nT(Ɯ^ Hp_CJB~(Ra;bW+4F6u|& W/7L~ۓ_BQut<풮si{^$}@.e tzs!P| B?3߹Q'+(s ~1b@j`l>zA' {]/Vv} v :BK]:9KpS.#Y,ٺ]zW|wi?K㻴H|+@p.*9!.J0#TL_>):+[N1s'@xQdzNs'W#ä%I64B^<}*wrD&NBI(ZɤƯ7"w ||EiKۋيf@MNf+g^E'i TcBjH^$->&lm@;a+#}TV]~:*g[Pyut(_))i~_ni32VSizP%<7 7^{aӸ:f쎛_UVycڼoXfK37u'Huu=WxɝKN{>ҮIcM7OOO>uTq[d'Vh'T׬uI;CXV רjY/qj5q*I6tB n Jon?C=:zsXN ^޹sxp=ѩN8yN:(3x/sA!8 E'N4Ow"%K;tW]/?>)wP8f \,yvsw9wԏM&~G56G&~/ETU`&~BlIC;a+}TSo9e}Zi;pZEt#f: z4MIMx -4/вg %'(9(5/aPa%Iӵu*U,'pZY!0CJKq%2QBc[tՅǫĨ#ʩ2##JWD}T=7m/t} c'wz@1n]'_sTz;eXxQR`lSRf?N̏!: Z9Vޑgf٣/JVaׯlgn; q'䏃<xǟnxǔj*Y,V:Q%FgmӡpSq%<Ղ,9QMw8Vf4vOPi>ƎmZwAnNtFӡISIAbh4H@io34pgAP]ζtsZp˭$s`G8yHl-SӉFAshfyNßoYȳjURdVA?gWXj#*6ˣW;_sy*SjSا6+TE0JS!2𗠝Pj5?έZQY3qo'm#RإWH w}ޗ言;\]gQ̎󟫛/?4_]/lJ~m>~CF:94ٓ~w~Bu*>;{U|ZڿZvZ0.bkn;uS:=||$G{*ΤJԾxÌ˿;0rY2LڤJz}wsnM!,*BaYW5۰sԆ!dYD/,!4:>x~=&^S٬ iGfXTJzmǞq%l{!*sѮl!dXI}oxG-V,%TjYXG:GRRq 5Pz24P'>^z1dCu9*N[}G Hيn**vsɅs j UdHewS 5 P0k?5-}Y1؇Pmm+"LD,ԭ4EpؔHi\ђiOE+ D[[(N>-Zul%d*5}|U 吁v;吤-x9o*&Tkw~pjAO tctN飜^CuWoHJc<#=mք =3t@>ve zI];-Edh/[tv{wȘ{u&{yAIFrsëSxF>Zٚm4ΆxG*Z:[?TfSq ꤘLSS=M]]g!*tTprS% 48c%]yft+[t䡩"R]Tat ״I-?}ڎOvs:7eOg9g[G z܍Fd:g5_C7QF(u[,ooo-;5k} 2=zbѳ47Vқa^Hްu3QWMY!(FbT}j&>WWS!CS׋CXnSw}M:@EZpw@.bCY>DƮ#LSw-a7U՛S}vnO?7q|!idr|I #(gt EL^6^h9NVG$ hz?݄JC北sm6t|PWw`2s>EOHwu$x "^H6Oup>!LpR _,w}%j;;({f1oL,984\!H} ϻwi/$FXFuơP׬Z#qdxDrN]BmDBZQ_klikAvwu,ֽ},sx9K!"g x E=,pƊz)_ݵ;35oA%MƛbjШ:YǎzvǜD4,ReȻMf{2M$Ʉ9Yȼ\^Oځ]vTռW"Żs ,kU"!6}I[7Af~s,xe+B'3U_i/a;d}Ϩ4 s@Z]?@O/Pm?#~r9k[3LoQl&8Kv150h 6eOW#z[,3ނ,a̽!տ›rX< h@< !v6` {ortC߹1TxuNfw QJ\׹\$:4[e A 7tʳmnhhݲ D+x  [(b'"qx$"q3P d­)% T6M7m,gXXt#O FVE E] b{Q >P7(5ģؼ^i<,T~zQDg4E@uB3[d0vѫ 9\ w5NMV<2XŭӐO˷$3@Zeu+S24MTG.u >D-xěw AxRiŜnlݝ_y`ZG$.$m7;ɘ )keK۬txW|òtnF>|Ts,r+=mO7 d'ݵs2N?CzG>< <(լ˸αI K0?y<saM76!': Ȳe{mކ|[Mror/m#m 7XF˹w#6ʦ*׷g=Ot&d! "" @p H)w[AG򧗆nx6v}]а#>B!uS1O Xt(Kaj@*!l4=r@ظh2|D8:Pp13̬6bpOBOT љ E,l] 8 \S`K&yf( \,(QdkY%s8a>O`dn:8< Y-a<AVp/o[IOJ*)P{淕~0xV{bʞ`n lWKb7I $mL'm/$N@ٱX/G2@3@< yHUM-E7"6_G@TC W̤A(J5Y]o?_}آF-x_s7{! ^eshO{p{rl#-)Fdrq߳+v}6ZCVplB@'Ep]K裈X<d V9 YںyK6J<{al.-D1\`'&c ]<sc=wV =L@N(s-m$c[uQ oXKa-<ԧM墺&9_m'j㐅GBz' YNσz[hJN77-!5Fi{iu6= KަHC%\j /4$ӂaJB(,QB ex_NKxƻ ;<(m1+}ܭad9X L&w"Z~+ Wyd#ϸ.s R +mT:]SIUs.-.fuZSD%qdi}mi4˒e]ԲnnY$,][ޙ6.I5ꖺKdH ,ad!@$ /BlH6ds ȱ @B ^[*]򼣫?ci߻~Gλ>#}8yp}JCC s(xs^`\=GaNE[rמ.NҢep\^ ij6K4/;$уs|wdtu65k,g7f0Բ]KjjxHGZv` <֫n6~~o<~F,Ya/ky O2e R;(pI-{OR~|H0ڿ]r|TVý$st{2¦Kgfj`02?A<2ij=qcxR2UttIWp/26`+vOܪmX7~Mp0mاFfהՂKkkFl7p|P#υ+)/A՗>j qՇ3[ǖH҃x(xJDZrӎJ.ڠI96l9/titH8.զH1dk\5p\u,[ŗHEp紞 %Y5ׂ6*ےׁwym]' hlK\YP9 3΁BU:NPCy'U:Œӂ:5%QC wBz?50[ޏ̏yr߮[8{e'/ڦr*w\H6/s> @m2WϹ&Yzy)"J_=EzugZn3NOhs-U`ÀG^6wd8 ]6i˲612onQ)AB8 .yКlƴMѡsx3$$>&^WOBЂKk溱ELշ'/!15>Xu="a;x; <.A>QcS ["I'"UP\kgEjR@ѩPgEֆsn/"W<(}{O񙧢 fO Skģ<KuhS$<kS?OEBS.`%,P<\j{!Q W"Rlo)sZ3yCrivwMH΀y$@z i[e e?v^6p \j5+2zƁqx n2<.mI@OU-nr,ln <~F֮l2CuZ-\j p$fsIyT1,aEpCsPlIYq4xgsVr6gCfsG>l}9hJO璜q%pyUA/N'su}T9JE_ P9Uc{ a?!EMN6Z`vxڟYY7ٚQ0 冷8tL;i.KM,&zj"/oRъE/Vpm9 }j HG//;!;3Q8ͪKdn&Yr㮒3tUkŴ"r1 )\_VVw9Y@weo6ﮜJTos˞c\jDÀk`kB<7(rtHV0 /۠HVCRiĺp2W .,P9N}'8G7Mw%ܻa"z,[bp^BՎi+$#<̑Y` tJjuQrivwk4blk,-Lph[{2.7.d \ΐ_yErHN xZ䳔C50~\x) E2K9uo_ʩr`L2TOQ}WsblwI p\jQ_sӊ:d x\viH"`xPMNR15 Dv`2+XyjeKBRY\}s~[Zۙ=%dLԞhM")A`\jyA*n=Q"5Q x!_pޓ[yƓSҖQvOx6Il2p).)^H.垌!,Tt.EZx+ ( $j`\5@\Xމ-6ӢkvR0 d.u8ก8D75t2VHI' q'Q>:q7|0 ,n s7 %d -b@qDr $1k_zTbGx ߨ@j)T r 4K)v2?A<~/9YYkvKud ..0`>W/p \} O<\ 7'5 ߆m.Q`Y&B dx"pᾄ,TpE (\ s.(w9#DG&\ y )p Z-`@ j``…6 :Ž-V`xG2 p@zp|!\ ,%pEC)ԯONd@F &B dx"`;ᾄ,T`;E (X s,(w9+T`2ij_y_** 1$k@}c Gd׃xHf |T *?s,TPCQpOZՈ5d.<|0P/o8 Awz}wD$k|P@V{P`Ak'7(/! U>(k & tPp 5(pWߤXځdXz0F 50[{rAscAA!y*| ikzPPIAP` Vb;~=  Ec\W_8vS8G"< ~Z{(+io !!CဏV wT2KpHG< U>ud>A[ ucxR6 kyk:' x/PVH4}@R@8$g҃zd-# [uA>I&9^"FcS7(wvms5[ԉ~ESҾ4R#s8$f OݽZ0 >" l4Z]mғ.ou4g6ռa[e V6Y"ߟ?'mWq`\3EɐB&#mE@S^mi"z_봕1{ւ*J)K9:ܟ~Qv`'tf`/d &_R>qkn:1:egpH xthu"Ep xD!֠N^D Tlo+jYp>]*Q2@ʩ;A*B. r wS r 1>AM֩עU75d?7G*3T%AuR3)/J:eZ5EMbQtPGY3vfLp{Wկ{w?űYtXѨhE ܈\}Y KIKp \]3):s_/{kD.v\! @}Ռ nrW_c쁵ee|f_CZ F9  |[>2GK_|(Q*c8x\[H%1S9p42>b8mVRep6nQQ#nAsT_GN`/}$Km#Zp|2 I^c$p|Z#1ypĀ #u/zr\p*~u˖c3TЭwY{Oυt]/ղ`c˥D0 pԖLհ菡P E#|n*g-|\꩑5 tZJP>pZ(2Lt$(0 \"A+IHF"S(׀ e"h&72O <9VWi Rlo*kj`3kI mE"9Ab:Jxw|nKJKϴ;YutMRݜWLqB!_+̘{ faq*ns ph;')( DGE< .D!svp@T=$$ JS*F!u|izJ?瞱eȿ:87R4v./lA9pȥ<>=uMv}de @zdWknֶ224ԲMj\.Kti>!4p\}d$< 7<'Q^O'D+,iUV3}4A1#Nw`?0[>XGԛHr p \}Sn372mgFzlyKfYg4Xn"suVpq,tR<kIy geoZp\}IL=GS]ƤZ^&T!`\IKqs»ܳĤ ھEݣiVw47z!(dʃx$}tJUΏMEԓQ%-rBg-r$x\`I/"GV[6#d8.OGp[$PrYn~0kfsC9gbA<]/HJgUc;1,zMȓ9QڃI#/?/m?$ .eW/vmL9*<&i)p %7;"g?ۄUaX$%N00 .5')1pC!9S!Lm~YVe"UׁR~1SڮCN+N\50 ~XG!)$\OS=ȭYN6[v2 l˰5K?)h> Ԝa /ݟ?z`>?tӏ߳sLannn%~$"d8~9I&d|Lbfvrrffo-+o,.|絪E‡|w^}s9c|O`LF5J)Zv|cvuӶ s/s _^W:d 糟U>G?{ Ԫz_T 2Fa+J[}۵-?mS@l Y4ؿ Gֺ) o4ƫkl|-U+鐆 :gnG=csgcledݜ8x ϡp \n3¡2 &ȞuwJ*!x\g@U{6%{鸸ǐ>`\}Ms{-Y멙/XN8{ ģ /" +_/({btSӉTr闓RK˳._/`xTȨ,aSUKh7h`Yp̬F^jS%ޟ6} )w0Y^VտX4Z6\0o%U~BpJLфᴎB??*tHĆY{Sd߄Z7 G<(ߔyAo>F+a0 /f: az:&‚Dw$hZBzze='lX6Ĕ;'(#a)"qKCC죖#F`;Uٛ^LmsƆA}RJ/Kx ɢb<1cȶQD$w$cf#[Ѩ1_j 'շVM2ygQqyyvN>+N)~ GEY;1EmHbQƴC1e1U_S}Rۅ"ߟ"jfPi8}g(3287bC;z?~%IxtW=1̔+nb]}WsxQ5Z}c .fNFd+IN߷휕rsv;mgsvvtьp| 7qTBz?& 5n;nZ$|/w$s^*UN" ,x0|Lr_rݏ ϝBq*U~|Y| oq{r|z&|_y9?Kgi$sgi=RbBT^Cx)ҋ[F~iF1jey1 1'9!1Ax K#&J}(%D1h'X8O97NԌj̉RND-xNDNsi-+gc{{.=IL=ZZc{1ƽhE\kCx&3>|Ws=-ha⺱cSIAX (Sq7xx1ƞY3`pg"V\pz 阞oҙ+)HvJOEAwBŇh]UH었`VxlG_)Rx.Nש~_\I7ˑ..@PS|iMe2Bdzڼ7dsHhKz!:“c}hvWoZ3tQ߱b G vDYb$D&3Mw@Gُ}vA;ᅥOY=Vj"cgOeEUċ{K__Nj^̳NC#:a+v:yϒ-UF..acS|@$W O 8""_E(+;oE\\$b(hT5WѠX(t5h&7keBs/sf`n&͌iM3o +@9{I-3 /VEz:;`7"љGP_lePl uؑ!E3 "th5$]鎷bR"te;ҽJ r ǎtB*T B&Gs:U30lEOrU(o/:wtd^~JWܿGt߁֠ {k{bƳ7+V&4.N_Z5kg wfbN/ Ok_C_0Z[4 -{aai3x{tp|PpMatrix/tests/0000755000176200001440000000000014547724215012673 5ustar liggesusersMatrix/tests/matr-exp.R0000644000176200001440000000535514507035046014554 0ustar liggesusers## 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.R0000644000176200001440000003605114467060443014756 0ustar liggesuserslibrary(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("pcorMatrix") == "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") if(!(genC || symC || triC || diaC)) stop("does not extend one of 'general', 'symmetric', 'triangular', or 'diagonal'") 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, "pcorMatrix") ## ^^^ 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, "compMatrix")) { 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.R0000644000176200001440000000427314444520706014773 0ustar liggesusers### 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.R0000644000176200001440000001440714467053122014554 0ustar liggesusers### 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.R0000644000176200001440000017164614535165176014270 0ustar liggesusers#### 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.R0000644000176200001440000001442614503206514014221 0ustar liggesusers## 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.R0000644000176200001440000013734214473555676014650 0ustar liggesusers#### 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]) }) Matrix/tests/other-pkgs.R0000644000176200001440000001146414473555676015122 0ustar liggesusers####--------- 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.R0000644000176200001440000000701614473555676014753 0ustar liggesusers## 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.save0000644000176200001440000027631614473676533016336 0ustar liggesusers R version 4.3.1 Patched (2023-08-16 r84986) -- "Beagle Scouts" Copyright (C) 2023 The R Foundation for Statistical Computing Platform: aarch64-apple-darwin22.5.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.171 0.006 0.177 > > ## 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.046 0.002 0.048 > > ## 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.204 0.006 0.212 > > 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.062 0.001 0.063 > > 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.055 0.002 0.057 > > ##--- "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.058 0.002 0.059 > 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.183 0.003 0.186 > > > ## "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.044 0.001 0.045 > > ## 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.091 0.001 0.093 > 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.17 0.003 0.172 > > ## 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.109 0.004 0.114 > > ## 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.422 0.048 0.469 > 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.012 0 0.013 > > > ## 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.247 0.001 0.248 > > 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]) + }) > > proc.time() user system elapsed 2.359 0.112 2.471 Matrix/tests/validObj.R0000644000176200001440000001611614476733334014560 0ustar liggesuserslibrary(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", "compMatrix", "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.R0000644000176200001440000006757114545303537015353 0ustar liggesusers#### 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.R0000644000176200001440000001063314444520706015361 0ustar liggesusers#### 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.R0000644000176200001440000011562314500446564014471 0ustar liggesusers## 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.R0000644000176200001440000002007614470702707013734 0ustar liggesusers#### 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.R0000644000176200001440000003152414503206514016027 0ustar liggesusers## 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", pcorMatrix = "corMatrix", pCholesky = "Cholesky")[[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 = "pcorMatrix", Cholesky = "pCholesky")[[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, "pcorMatrix")) 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, "pcorMatrix")) 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.R0000644000176200001440000002241114467060443015721 0ustar liggesusers## 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.R0000644000176200001440000000347114444662477015075 0ustar liggesusers## 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.R0000644000176200001440000005361714523122502015610 0ustar liggesusers### 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 ## (x) behaved incorrectly in Matrix <= 1.4-1 ## for unit diagonal 'x' when f(0) == 0 and f(1) != 1 Dn <- list(c("a", "b"), c("A", "B")) udi <- new("ddiMatrix", Dim = c(2L, 2L), Dimnames = Dn, diag = "U") utC <- new("dtCMatrix", Dim = c(2L, 2L), Dimnames = Dn, diag = "U", p = integer(3L)) utr <- new("dtrMatrix", Dim = c(2L, 2L), Dimnames = Dn, diag = "U", x = double(4L)) sinu <- `dimnames<-`(sin(diag(2L)), Dn) for(u in list(udi, utC, utr)) stopifnot(identical(as(sin(u), "matrix"), sinu)) ## Originally in ../man/all-methods.Rd : M <- Matrix(1:12 +0, 3,4) all(M >= 1) # TRUE any(M < 0 ) # FALSE MN <- M; MN[2,3] <- NA; MN all(MN >= 0) # NA any(MN < 0) # NA any(MN < 0, na.rm = TRUE) # -> FALSE sM <- as(MN, "sparseMatrix") stopifnot(all(M >= 1), !any(M < 0), all.equal((sM >= 1), as(MN >= 1, "sparseMatrix")), ## MN: any(MN < 2), !all(MN < 5), is.na(all(MN >= 0)), is.na(any(MN < 0)), all(MN >= 0, na.rm=TRUE), !any(MN < 0, na.rm=TRUE), ## same for sM : any(sM < 2), !all(sM < 5), is.na(all(sM >= 0)), is.na(any(sM < 0)), all(sM >= 0, na.rm=TRUE), !any(sM < 0, na.rm=TRUE) ) ## prod() does not perform multiplies in row/column order : x4 <- new("dspMatrix", Dim = c(4L, 4L), x = c(171, 53, 79, 205, 100, 285, 98, 15, 99, 84)) p4 <- prod( x4) p4. <- prod(as(x4, "generalMatrix")) p4.. <- prod(as(x4, "matrix")) stopifnot(all.equal(p4, p4. , tolerance = 1e-15), all.equal(p4., p4.., tolerance = 1e-15)) all.equal(p4, p4. , tolerance = 0) all.equal(p4., p4.., tolerance = 0) .Machine[["sizeof.longdouble"]] cat('Time elapsed: ', proc.time(),'\n') # for ``statistical reasons'' �����������������������������������������������������������������������������������������������������������������Matrix/tests/bind.Rout.save�������������������������������������������������������������������������0000644�0001762�0000144�00000045017�14470702707�015423� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ R version 4.3.1 Patched (2023-08-08 r84910) -- "Beagle Scouts" Copyright (C) 2023 The R Foundation for Statistical Computing Platform: aarch64-apple-darwin22.5.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. > #### 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 Loading required package: tools > > ### --- 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) 3 x 8 Matrix of class "dgeMatrix" [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [1,] 1 4 7 10 10 40 70 100 [2,] 2 5 8 11 20 50 80 110 [3,] 3 6 9 12 30 60 90 120 3 x 8 Matrix of class "dgeMatrix" a b c d a b c d [1,] 1 4 7 10 101 104 107 110 [2,] 2 5 8 11 102 105 108 111 [3,] 3 6 9 12 103 106 109 112 3 x 8 Matrix of class "dgeMatrix" a b c d a b c d A 1 4 7 10 10 40 70 100 B 2 5 8 11 20 50 80 110 C 3 6 9 12 30 60 90 120 3 x 8 Matrix of class "dgeMatrix" a b c d a b c d A 1 4 7 10 2 8 14 20 B 2 5 8 11 4 10 16 22 C 3 6 9 12 6 12 18 24 3 x 5 Matrix of class "dgeMatrix" a b c d MM [1,] 1 4 7 10 -1 [2,] 2 5 8 11 -1 [3,] 3 6 9 12 -1 6 x 4 Matrix of class "dgeMatrix" [,1] [,2] [,3] [,4] [1,] 1 4 7 10 [2,] 2 5 8 11 [3,] 3 6 9 12 [4,] 10 40 70 100 [5,] 20 50 80 110 [6,] 30 60 90 120 6 x 4 Matrix of class "dgeMatrix" a b c d A 1 4 7 10 B 2 5 8 11 C 3 6 9 12 2 8 14 20 4 10 16 22 6 12 18 24 4 x 4 Matrix of class "dgeMatrix" a b c d R1 10 11 10 11 1 4 7 10 2 5 8 11 3 6 9 12 > > 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() 1 x 4 Matrix of class "dgeMatrix" [,1] [,2] [,3] [,4] [1,] 0 0 1 3 Warning message: In cbind.Matrix(x, y, deparse.level = 0L) : number of rows of result is not a multiple of vector length > as(rbind(0, Matrix(0+0:1, 1,2), 3:2), + "sparseMatrix") 3 x 2 sparse Matrix of class "dgCMatrix" [1,] . . [2,] . 1 [3,] 3 2 > cbind(M2, 10*M2[nrow(M2):1 ,])# keeps the rownames from the first 3 x 8 Matrix of class "dgeMatrix" a b c d a b c d A 1 4 7 10 30 60 90 120 B 2 5 8 11 20 50 80 110 C 3 6 9 12 10 40 70 100 > > (im <- cbind(I = 100, M)) 3 x 5 Matrix of class "dgeMatrix" I [1,] 100 1 4 7 10 [2,] 100 2 5 8 11 [3,] 100 3 6 9 12 > str(im) Formal class 'dgeMatrix' [package "Matrix"] with 4 slots ..@ Dim : int [1:2] 3 5 ..@ Dimnames:List of 2 .. ..$ : NULL .. ..$ : chr [1:5] "I" "" "" "" ... ..@ x : num [1:15] 100 100 100 1 2 3 4 5 6 7 ... ..@ factors : list() > (mi <- cbind(M2, I = 1000)) 3 x 5 Matrix of class "dgeMatrix" a b c d I A 1 4 7 10 1000 B 2 5 8 11 1000 C 3 6 9 12 1000 > str(mi) Formal class 'dgeMatrix' [package "Matrix"] with 4 slots ..@ Dim : int [1:2] 3 5 ..@ Dimnames:List of 2 .. ..$ : chr [1:3] "A" "B" "C" .. ..$ : chr [1:5] "a" "b" "c" "d" ... ..@ x : num [1:15] 1 2 3 4 5 6 7 8 9 10 ... ..@ factors : list() > (m1m <- cbind(M,I=100,M2)) 3 x 9 Matrix of class "dgeMatrix" I a b c d A 1 4 7 10 100 1 4 7 10 B 2 5 8 11 100 2 5 8 11 C 3 6 9 12 100 3 6 9 12 > showProc.time() Time (user system elapsed): 0.051 0.006 0.056 > > ## 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")) 4 x 4 sparse Matrix of class "dtTMatrix" (unitriangular) [1,] I . . . [2,] . I . . [3,] . . I . [4,] . . . I > D4C <- as(D4T, "CsparseMatrix") > c1 <- Matrix(0+0:3, 4, sparse=TRUE) ; r1 <- t(c1); r1 1 x 4 sparse Matrix of class "dgCMatrix" [1,] . 1 2 3 > > 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() Time (user system elapsed): 0.019 0 0.02 > > ### --- Sparse Matrices --- > > identical4(cbind(diag(4), diag(4)), + cbind(D4C, D4C), + cbind(D4T, D4C), + cbind(D4C, D4T)) [1] FALSE > nr <- 4 > nc <- 6 > m. <- matrix(rep_len(c(0, 2:-1), nr * nc), nr, nc) > M <- Matrix(m.) > (mC <- as(M, "CsparseMatrix")) 4 x 6 sparse Matrix of class "dgCMatrix" [1,] . -1 . 1 2 . [2,] 2 . -1 . 1 2 [3,] 1 2 . -1 . 1 [4,] . 1 2 . -1 . > (mT <- as(M, "TsparseMatrix")) 4 x 6 sparse Matrix of class "dgTMatrix" [1,] . -1 . 1 2 . [2,] 2 . -1 . 1 2 [3,] 1 2 . -1 . 1 [4,] . 1 2 . -1 . > 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") + } cbind (m, v= 0 ), class(m) : dgeMatrix ,. dgCMatrix ,. dgTMatrix ,. rbind (m, v= 0 ), class(m) : dgeMatrix ,. dgCMatrix ,. dgTMatrix ,. cbind (m, v= 2 ), class(m) : dgeMatrix ,. dgCMatrix ,. dgTMatrix ,. rbind (m, v= 2 ), class(m) : dgeMatrix ,. dgCMatrix ,. dgTMatrix ,. cbind (m, v= 1:0 ), class(m) : dgeMatrix ,. dgCMatrix ,. dgTMatrix ,. rbind (m, v= 1:0 ), class(m) : dgeMatrix ,. dgCMatrix ,. dgTMatrix ,. > showProc.time() Time (user system elapsed): 0.018 0.001 0.019 > > cbind(0, mC); cbind(mC, 0) 4 x 7 sparse Matrix of class "dgCMatrix" [1,] . . -1 . 1 2 . [2,] . 2 . -1 . 1 2 [3,] . 1 2 . -1 . 1 [4,] . . 1 2 . -1 . 4 x 7 sparse Matrix of class "dgCMatrix" [1,] . -1 . 1 2 . . [2,] 2 . -1 . 1 2 . [3,] 1 2 . -1 . 1 . [4,] . 1 2 . -1 . . > cbind(0, mT); cbind(mT, 2) 4 x 7 sparse Matrix of class "dgTMatrix" [1,] . . -1 . 1 2 . [2,] . 2 . -1 . 1 2 [3,] . 1 2 . -1 . 1 [4,] . . 1 2 . -1 . 4 x 7 sparse Matrix of class "dgTMatrix" [1,] . -1 . 1 2 . 2 [2,] 2 . -1 . 1 2 2 [3,] 1 2 . -1 . 1 2 [4,] . 1 2 . -1 . 2 > cbind(diag(nr), mT) 4 x 10 sparse Matrix of class "dgTMatrix" [1,] 1 . . . . -1 . 1 2 . [2,] . 1 . . 2 . -1 . 1 2 [3,] . . 1 . 1 2 . -1 . 1 [4,] . . . 1 . 1 2 . -1 . > stopifnot(identical(t(cbind(diag(nr), mT)), + rbind(diag(nr), t(mT)))) > (cc <- cbind(mC, 0,7,0, diag(nr), 0)) 4 x 14 sparse Matrix of class "dgCMatrix" [1,] . -1 . 1 2 . . 7 . 1 . . . . [2,] 2 . -1 . 1 2 . 7 . . 1 . . . [3,] 1 2 . -1 . 1 . 7 . . . 1 . . [4,] . 1 2 . -1 . . 7 . . . . 1 . > 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) 4 x 15 sparse Matrix of class "dgCMatrix" [1,] . -1 . 1 2 . 1 . -100 . 100 200 . . . [2,] 2 . -1 . 1 2 1 200 . -100 . 100 200 . 1 [3,] 1 2 . -1 . 1 1 100 200 . -100 . 100 . 2 [4,] . 1 2 . -1 . 1 . 100 200 . -100 . . . > cbind(mT, 1, 0, mT+10*mT, 0, 0:2) 4 x 16 sparse Matrix of class "dgCMatrix" [1,] . -1 . 1 2 . 1 . . -11 . 11 22 . . . [2,] 2 . -1 . 1 2 1 . 22 . -11 . 11 22 . 1 [3,] 1 2 . -1 . 1 1 . 11 22 . -11 . 11 . 2 [4,] . 1 2 . -1 . 1 . . 11 22 . -11 . . . > 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) 4 x 15 sparse Matrix of class "dgCMatrix" a b c d e f one a b c d e f zero A . -1 . 1 2 . 1 . -100 . 100 200 . . . B 2 . -1 . 1 2 1 200 . -100 . 100 200 . 1 C 1 2 . -1 . 1 1 100 200 . -100 . 100 . 2 D . 1 2 . -1 . 1 . 100 200 . -100 . . . > cbind(mC, one, 100*mC, zero, 0:2, deparse.level=0)# no "zero", "one" 4 x 15 sparse Matrix of class "dgCMatrix" a b c d e f a b c d e f A . -1 . 1 2 . 1 . -100 . 100 200 . . . B 2 . -1 . 1 2 1 200 . -100 . 100 200 . 1 C 1 2 . -1 . 1 1 100 200 . -100 . 100 . 2 D . 1 2 . -1 . 1 . 100 200 . -100 . . . > cbind(mC, one, 100*mC, zero, 0:2, deparse.level=2)# even "0:2" 4 x 15 sparse Matrix of class "dgCMatrix" a b c d e f one a b c d e f zero 0:2 A . -1 . 1 2 . 1 . -100 . 100 200 . . . B 2 . -1 . 1 2 1 200 . -100 . 100 200 . 1 C 1 2 . -1 . 1 1 100 200 . -100 . 100 . 2 D . 1 2 . -1 . 1 . 100 200 . -100 . . . > cbind(mT, one, zero, mT+10*mT, zero, 0:2) 4 x 16 sparse Matrix of class "dgCMatrix" a b c d e f one zero a b c d e f zero A . -1 . 1 2 . 1 . . -11 . 11 22 . . . B 2 . -1 . 1 2 1 . 22 . -11 . 11 22 . 1 C 1 2 . -1 . 1 1 . 11 22 . -11 . 11 . 2 D . 1 2 . -1 . 1 . . 11 22 . -11 . . . > > > ## 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")) 6 x 5 sparse Matrix of class "lgRMatrix" [,1] [,2] [,3] [,4] [,5] | . . . . . | . . . . . | . . . . . | . . . . . | v5 . | . | . 5 x 6 sparse Matrix of class "lgCMatrix" v5 [1,] . | . . . . [2,] | . | . . . [3,] . . . | . . [4,] | . . . | . [5,] . . . . . | > > ## print() / show() of non-structural zeros: > (m <- Matrix(c(0, 0, 2:0), 3, 5)) 3 x 5 sparse Matrix of class "dgCMatrix" [,1] [,2] [,3] [,4] [,5] [1,] . 1 . . 2 [2,] . . 2 . 1 [3,] 2 . 1 . . > (m2 <- cbind(m,m)) 3 x 10 sparse Matrix of class "dgCMatrix" [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [1,] . 1 . . 2 . 1 . . 2 [2,] . . 2 . 1 . . 2 . 1 [3,] 2 . 1 . . 2 . 1 . . > (m4 <- rbind(m2,m2)) 6 x 10 sparse Matrix of class "dgCMatrix" [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [1,] . 1 . . 2 . 1 . . 2 [2,] . . 2 . 1 . . 2 . 1 [3,] 2 . 1 . . 2 . 1 . . [4,] . 1 . . 2 . 1 . . 2 [5,] . . 2 . 1 . . 2 . 1 [6,] 2 . 1 . . 2 . 1 . . > diag(m4) [1] 0 0 1 0 1 2 > for(i in 1:6) { + m4[i, i ] <- i + m4[i,i+1] <- 0 + } > m4 ## now show some non-structural zeros: 6 x 10 sparse Matrix of class "dgCMatrix" [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [1,] 1 . . . 2 . 1 . . 2 [2,] . 2 . . 1 . . 2 . 1 [3,] 2 . 3 . . 2 . 1 . . [4,] . 1 . 4 . . 1 . . 2 [5,] . . 2 . 5 . . 2 . 1 [6,] 2 . 1 . . 6 . 1 . . > > ## 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)) 5 x 6 sparse Matrix of class "dgCMatrix" [,1] [,2] [,3] [,4] [,5] [,6] [1,] 10 . . . . 1 [2,] . 20 . . . 1 [3,] . . 30 . . 1 [4,] . . . 40 . 1 [5,] . . . . 50 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)) 8 x 6 sparse Matrix of class "dgCMatrix" [,1] [,2] [,3] [,4] [,5] [,6] [1,] 1 1 1 1 1 1 [2,] . . . . . . [3,] 10 . . . . 1 [4,] . 20 . . . 1 [5,] . . 30 . . 1 [6,] . . . 40 . 1 [7,] . . . . 50 1 [8,] . . . . . . > stopifnotValid(D5.1, "dgCMatrix") > stopifnotValid(print(rbind2(Matrix(1:10, 2,5), D5)), "dgRMatrix") 7 x 5 sparse Matrix of class "dgRMatrix" [,1] [,2] [,3] [,4] [,5] [1,] 1 3 5 7 9 [2,] 2 4 6 8 10 [3,] 10 . . . . [4,] . 20 . . . [5,] . . 30 . . [6,] . . . 40 . [7,] . . . . 50 > stopifnotValid(print(cbind2(Matrix(10:1, 5,2), D5.1)), "dgCMatrix") 5 x 8 sparse Matrix of class "dgCMatrix" [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [1,] 10 5 10 . . . . 1 [2,] 9 4 . 20 . . . 1 [3,] 8 3 . . 30 . . 1 [4,] 7 2 . . . 40 . 1 [5,] 6 1 . . . . 50 1 > stopifnotValid(zz <- cbind2(z42, C86), "dgCMatrix") > stopifnot(identical(zz, cbind2(s42, C86))) > > ## Using "nMatrix" > (m1 <- sparseMatrix(1:3, 1:3)) # ngCMatrix 3 x 3 sparse Matrix of class "ngCMatrix" [,1] [,2] [,3] [1,] | . . [2,] . | . [3,] . . | > 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() Time (user system elapsed): 0.06 0.003 0.063 > > proc.time() user system elapsed 0.609 0.039 0.646 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/tests/base-matrix-fun.R����������������������������������������������������������������������0000644�0001762�0000144�00000003223�14444662477�016027� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#### Thanks to the manipulation in base namespace, see ../R/zzz.R , #### all the functions (in 'base' or namespaces that import it) #### starting with something like #### " x <- as.matrix(x) " or " X <- as.array(X) " #### will work for 'Matrix'-matrices ## for R_DEFAULT_PACKAGES=NULL : library(stats) library(utils) library(Matrix) data(KNex, package = "Matrix") mm <- KNex$mm str(m1 <- mm[1:500, 1:200]) m11 <- m1[1:100, 1:20] ## These now work thanks to using our as.matrix(): str(D1 <- dist(m11)) str(rs <- apply(m1, 1, sum)) stopifnot(identical(kappa(Matrix(2:5, 2)), kappa(matrix(2:5, 2)))) ## used to seg.fault, PR#7984, ## because qr() was calling the wrong as.matrix() ## also matplot() or pairs(). ## a regression test for as.matrix.dist(.) still working data(USJudgeRatings, package = "datasets") stopifnot(c(43, 43) == dim(as.matrix(d <- dist(USJudgeRatings)))) m <- Matrix(0:5, 3, 2) (m2 <- Matrix(diag(c(3,1)))) (m3 <- crossprod(t(m))) # <- that's an S4 method; nothing "base" str( svd(m) ) str( lapply(eigen(m3), zapsmall)) ### outer() used to work thanks to as.array() -- up to R 2.2.1 ## no longer, because the definition of outer has changed -- FIXME? ## Whould work by providing an as.vector(.) method ## *and* is.array(.) \-> TRUE which may be too strong ##--> For %o%: "need" to make outer(.,.) an S3 generic ## *and* provide Matrix S3 methods ## stopifnot(identical(outer(m, m2), ## outer(as(m,"matrix"), as(m2,"matrix"))), ## identical(outer(m3, m2), ## outer(as(m3,"matrix"), as(m2,"matrix")))) cat('Time elapsed: ', proc.time(),'\n') # for ``statistical reasons'' �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/�����������������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14547724215�012320� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/cs.c�������������������������������������������������������������������������������������0000644�0001762�0000144�00000252152�14511400105�013054� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "cs.h" /* C = alpha*A + beta*B */ cs *cs_add (const cs *A, const cs *B, double alpha, double beta) { csi p, j, nz = 0, anz, *Cp, *Ci, *Bp, m, n, bnz, *w, values ; double *x, *Bx, *Cx ; cs *C ; if (!CS_CSC (A) || !CS_CSC (B)) return (NULL) ; /* check inputs */ if (A->m != B->m || A->n != B->n) return (NULL) ; m = A->m ; anz = A->p [A->n] ; n = B->n ; Bp = B->p ; Bx = B->x ; bnz = Bp [n] ; w = cs_calloc (m, sizeof (csi)) ; /* get workspace */ values = (A->x != NULL) && (Bx != NULL) ; x = values ? cs_malloc (m, sizeof (double)) : NULL ; /* get workspace */ C = cs_spalloc (m, n, anz + bnz, values, 0) ; /* allocate result*/ if (!C || !w || (values && !x)) return (cs_done (C, w, x, 0)) ; Cp = C->p ; Ci = C->i ; Cx = C->x ; for (j = 0 ; j < n ; j++) { Cp [j] = nz ; /* column j of C starts here */ nz = cs_scatter (A, j, alpha, w, x, j+1, C, nz) ; /* alpha*A(:,j)*/ nz = cs_scatter (B, j, beta, w, x, j+1, C, nz) ; /* beta*B(:,j) */ if (values) for (p = Cp [j] ; p < nz ; p++) Cx [p] = x [Ci [p]] ; } Cp [n] = nz ; /* finalize the last column of C */ cs_sprealloc (C, 0) ; /* remove extra space from C */ return (cs_done (C, w, x, 1)) ; /* success; free workspace, return C */ } /* clear w */ static csi cs_wclear (csi mark, csi lemax, csi *w, csi n) { csi k ; if (mark < 2 || (mark + lemax < 0)) { for (k = 0 ; k < n ; k++) if (w [k] != 0) w [k] = 1 ; mark = 2 ; } return (mark) ; /* at this point, w [0..n-1] < mark holds */ } /* keep off-diagonal entries; drop diagonal entries */ static csi cs_diag (csi i, csi j, double aij, void *other) { return (i != j) ; } /* p = amd(A+A') if symmetric is true, or amd(A'A) otherwise */ csi *cs_amd (csi order, const cs *A) /* order 0:natural, 1:Chol, 2:LU, 3:QR */ { cs *C, *A2, *AT ; csi *Cp, *Ci, *last, *W, *len, *nv, *next, *P, *head, *elen, *degree, *w, *hhead, *ATp, *ATi, d, dk, dext, lemax = 0, e, elenk, eln, i, j, k, k1, k2, k3, jlast, ln, dense, nzmax, mindeg = 0, nvi, nvj, nvk, mark, wnvi, ok, cnz, nel = 0, p, p1, p2, p3, p4, pj, pk, pk1, pk2, pn, q, n, m, t ; csi h ; /* --- Construct matrix C ----------------------------------------------- */ if (!CS_CSC (A) || order <= 0 || order > 3) return (NULL) ; /* check */ AT = cs_transpose (A, 0) ; /* compute A' */ if (!AT) return (NULL) ; m = A->m ; n = A->n ; dense = CS_MAX (16, 10 * sqrt ((double) n)) ; /* find dense threshold */ dense = CS_MIN (n-2, dense) ; if (order == 1 && n == m) { C = cs_add (A, AT, 0, 0) ; /* C = A+A' */ } else if (order == 2) { ATp = AT->p ; /* drop dense columns from AT */ ATi = AT->i ; for (p2 = 0, j = 0 ; j < m ; j++) { p = ATp [j] ; /* column j of AT starts here */ ATp [j] = p2 ; /* new column j starts here */ if (ATp [j+1] - p > dense) continue ; /* skip dense col j */ for ( ; p < ATp [j+1] ; p++) ATi [p2++] = ATi [p] ; } ATp [m] = p2 ; /* finalize AT */ A2 = cs_transpose (AT, 0) ; /* A2 = AT' */ C = A2 ? cs_multiply (AT, A2) : NULL ; /* C=A'*A with no dense rows */ cs_spfree (A2) ; } else { C = cs_multiply (AT, A) ; /* C=A'*A */ } cs_spfree (AT) ; if (!C) return (NULL) ; cs_fkeep (C, &cs_diag, NULL) ; /* drop diagonal entries */ Cp = C->p ; cnz = Cp [n] ; P = cs_malloc (n+1, sizeof (csi)) ; /* allocate result */ W = cs_malloc (8*(n+1), sizeof (csi)) ; /* get workspace */ t = cnz + cnz/5 + 2*n ; /* add elbow room to C */ if (!P || !W || !cs_sprealloc (C, t)) return (cs_idone (P, C, W, 0)) ; len = W ; nv = W + (n+1) ; next = W + 2*(n+1) ; head = W + 3*(n+1) ; elen = W + 4*(n+1) ; degree = W + 5*(n+1) ; w = W + 6*(n+1) ; hhead = W + 7*(n+1) ; last = P ; /* use P as workspace for last */ /* --- Initialize quotient graph ---------------------------------------- */ for (k = 0 ; k < n ; k++) len [k] = Cp [k+1] - Cp [k] ; len [n] = 0 ; nzmax = C->nzmax ; Ci = C->i ; for (i = 0 ; i <= n ; i++) { head [i] = -1 ; /* degree list i is empty */ last [i] = -1 ; next [i] = -1 ; hhead [i] = -1 ; /* hash list i is empty */ nv [i] = 1 ; /* node i is just one node */ w [i] = 1 ; /* node i is alive */ elen [i] = 0 ; /* Ek of node i is empty */ degree [i] = len [i] ; /* degree of node i */ } mark = cs_wclear (0, 0, w, n) ; /* clear w */ elen [n] = -2 ; /* n is a dead element */ Cp [n] = -1 ; /* n is a root of assembly tree */ w [n] = 0 ; /* n is a dead element */ /* --- Initialize degree lists ------------------------------------------ */ for (i = 0 ; i < n ; i++) { d = degree [i] ; if (d == 0) /* node i is empty */ { elen [i] = -2 ; /* element i is dead */ nel++ ; Cp [i] = -1 ; /* i is a root of assembly tree */ w [i] = 0 ; } else if (d > dense) /* node i is dense */ { nv [i] = 0 ; /* absorb i into element n */ elen [i] = -1 ; /* node i is dead */ nel++ ; Cp [i] = CS_FLIP (n) ; nv [n]++ ; } else { if (head [d] != -1) last [head [d]] = i ; next [i] = head [d] ; /* put node i in degree list d */ head [d] = i ; } } while (nel < n) /* while (selecting pivots) do */ { /* --- Select node of minimum approximate degree -------------------- */ for (k = -1 ; mindeg < n && (k = head [mindeg]) == -1 ; mindeg++) ; if (next [k] != -1) last [next [k]] = -1 ; head [mindeg] = next [k] ; /* remove k from degree list */ elenk = elen [k] ; /* elenk = |Ek| */ nvk = nv [k] ; /* # of nodes k represents */ nel += nvk ; /* nv[k] nodes of A eliminated */ /* --- Garbage collection ------------------------------------------- */ if (elenk > 0 && cnz + mindeg >= nzmax) { for (j = 0 ; j < n ; j++) { if ((p = Cp [j]) >= 0) /* j is a live node or element */ { Cp [j] = Ci [p] ; /* save first entry of object */ Ci [p] = CS_FLIP (j) ; /* first entry is now CS_FLIP(j) */ } } for (q = 0, p = 0 ; p < cnz ; ) /* scan all of memory */ { if ((j = CS_FLIP (Ci [p++])) >= 0) /* found object j */ { Ci [q] = Cp [j] ; /* restore first entry of object */ Cp [j] = q++ ; /* new pointer to object j */ for (k3 = 0 ; k3 < len [j]-1 ; k3++) Ci [q++] = Ci [p++] ; } } cnz = q ; /* Ci [cnz...nzmax-1] now free */ } /* --- Construct new element ---------------------------------------- */ dk = 0 ; nv [k] = -nvk ; /* flag k as in Lk */ p = Cp [k] ; pk1 = (elenk == 0) ? p : cnz ; /* do in place if elen[k] == 0 */ pk2 = pk1 ; for (k1 = 1 ; k1 <= elenk + 1 ; k1++) { if (k1 > elenk) { e = k ; /* search the nodes in k */ pj = p ; /* list of nodes starts at Ci[pj]*/ ln = len [k] - elenk ; /* length of list of nodes in k */ } else { e = Ci [p++] ; /* search the nodes in e */ pj = Cp [e] ; ln = len [e] ; /* length of list of nodes in e */ } for (k2 = 1 ; k2 <= ln ; k2++) { i = Ci [pj++] ; if ((nvi = nv [i]) <= 0) continue ; /* node i dead, or seen */ dk += nvi ; /* degree[Lk] += size of node i */ nv [i] = -nvi ; /* negate nv[i] to denote i in Lk*/ Ci [pk2++] = i ; /* place i in Lk */ if (next [i] != -1) last [next [i]] = last [i] ; if (last [i] != -1) /* remove i from degree list */ { next [last [i]] = next [i] ; } else { head [degree [i]] = next [i] ; } } if (e != k) { Cp [e] = CS_FLIP (k) ; /* absorb e into k */ w [e] = 0 ; /* e is now a dead element */ } } if (elenk != 0) cnz = pk2 ; /* Ci [cnz...nzmax] is free */ degree [k] = dk ; /* external degree of k - |Lk\i| */ Cp [k] = pk1 ; /* element k is in Ci[pk1..pk2-1] */ len [k] = pk2 - pk1 ; elen [k] = -2 ; /* k is now an element */ /* --- Find set differences ----------------------------------------- */ mark = cs_wclear (mark, lemax, w, n) ; /* clear w if necessary */ for (pk = pk1 ; pk < pk2 ; pk++) /* scan 1: find |Le\Lk| */ { i = Ci [pk] ; if ((eln = elen [i]) <= 0) continue ;/* skip if elen[i] empty */ nvi = -nv [i] ; /* nv [i] was negated */ wnvi = mark - nvi ; for (p = Cp [i] ; p <= Cp [i] + eln - 1 ; p++) /* scan Ei */ { e = Ci [p] ; if (w [e] >= mark) { w [e] -= nvi ; /* decrement |Le\Lk| */ } else if (w [e] != 0) /* ensure e is a live element */ { w [e] = degree [e] + wnvi ; /* 1st time e seen in scan 1 */ } } } /* --- Degree update ------------------------------------------------ */ for (pk = pk1 ; pk < pk2 ; pk++) /* scan2: degree update */ { i = Ci [pk] ; /* consider node i in Lk */ p1 = Cp [i] ; p2 = p1 + elen [i] - 1 ; pn = p1 ; for (h = 0, d = 0, p = p1 ; p <= p2 ; p++) /* scan Ei */ { e = Ci [p] ; if (w [e] != 0) /* e is an unabsorbed element */ { dext = w [e] - mark ; /* dext = |Le\Lk| */ if (dext > 0) { d += dext ; /* sum up the set differences */ Ci [pn++] = e ; /* keep e in Ei */ h += e ; /* compute the hash of node i */ } else { Cp [e] = CS_FLIP (k) ; /* aggressive absorb. e->k */ w [e] = 0 ; /* e is a dead element */ } } } elen [i] = pn - p1 + 1 ; /* elen[i] = |Ei| */ p3 = pn ; p4 = p1 + len [i] ; for (p = p2 + 1 ; p < p4 ; p++) /* prune edges in Ai */ { j = Ci [p] ; if ((nvj = nv [j]) <= 0) continue ; /* node j dead or in Lk */ d += nvj ; /* degree(i) += |j| */ Ci [pn++] = j ; /* place j in node list of i */ h += j ; /* compute hash for node i */ } if (d == 0) /* check for mass elimination */ { Cp [i] = CS_FLIP (k) ; /* absorb i into k */ nvi = -nv [i] ; dk -= nvi ; /* |Lk| -= |i| */ nvk += nvi ; /* |k| += nv[i] */ nel += nvi ; nv [i] = 0 ; elen [i] = -1 ; /* node i is dead */ } else { degree [i] = CS_MIN (degree [i], d) ; /* update degree(i) */ Ci [pn] = Ci [p3] ; /* move first node to end */ Ci [p3] = Ci [p1] ; /* move 1st el. to end of Ei */ Ci [p1] = k ; /* add k as 1st element in of Ei */ len [i] = pn - p1 + 1 ; /* new len of adj. list of node i */ h = ((h<0) ? (-h):h) % n ; /* finalize hash of i */ next [i] = hhead [h] ; /* place i in hash bucket */ hhead [h] = i ; last [i] = h ; /* save hash of i in last[i] */ } } /* scan2 is done */ degree [k] = dk ; /* finalize |Lk| */ lemax = CS_MAX (lemax, dk) ; mark = cs_wclear (mark+lemax, lemax, w, n) ; /* clear w */ /* --- Supernode detection ------------------------------------------ */ for (pk = pk1 ; pk < pk2 ; pk++) { i = Ci [pk] ; if (nv [i] >= 0) continue ; /* skip if i is dead */ h = last [i] ; /* scan hash bucket of node i */ i = hhead [h] ; hhead [h] = -1 ; /* hash bucket will be empty */ for ( ; i != -1 && next [i] != -1 ; i = next [i], mark++) { ln = len [i] ; eln = elen [i] ; for (p = Cp [i]+1 ; p <= Cp [i] + ln-1 ; p++) w [Ci [p]] = mark; jlast = i ; for (j = next [i] ; j != -1 ; ) /* compare i with all j */ { ok = (len [j] == ln) && (elen [j] == eln) ; for (p = Cp [j] + 1 ; ok && p <= Cp [j] + ln - 1 ; p++) { if (w [Ci [p]] != mark) ok = 0 ; /* compare i and j*/ } if (ok) /* i and j are identical */ { Cp [j] = CS_FLIP (i) ; /* absorb j into i */ nv [i] += nv [j] ; nv [j] = 0 ; elen [j] = -1 ; /* node j is dead */ j = next [j] ; /* delete j from hash bucket */ next [jlast] = j ; } else { jlast = j ; /* j and i are different */ j = next [j] ; } } } } /* --- Finalize new element------------------------------------------ */ for (p = pk1, pk = pk1 ; pk < pk2 ; pk++) /* finalize Lk */ { i = Ci [pk] ; if ((nvi = -nv [i]) <= 0) continue ;/* skip if i is dead */ nv [i] = nvi ; /* restore nv[i] */ d = degree [i] + dk - nvi ; /* compute external degree(i) */ d = CS_MIN (d, n - nel - nvi) ; if (head [d] != -1) last [head [d]] = i ; next [i] = head [d] ; /* put i back in degree list */ last [i] = -1 ; head [d] = i ; mindeg = CS_MIN (mindeg, d) ; /* find new minimum degree */ degree [i] = d ; Ci [p++] = i ; /* place i in Lk */ } nv [k] = nvk ; /* # nodes absorbed into k */ if ((len [k] = p-pk1) == 0) /* length of adj list of element k*/ { Cp [k] = -1 ; /* k is a root of the tree */ w [k] = 0 ; /* k is now a dead element */ } if (elenk != 0) cnz = p ; /* free unused space in Lk */ } /* --- Postordering ----------------------------------------------------- */ for (i = 0 ; i < n ; i++) Cp [i] = CS_FLIP (Cp [i]) ;/* fix assembly tree */ for (j = 0 ; j <= n ; j++) head [j] = -1 ; for (j = n ; j >= 0 ; j--) /* place unordered nodes in lists */ { if (nv [j] > 0) continue ; /* skip if j is an element */ next [j] = head [Cp [j]] ; /* place j in list of its parent */ head [Cp [j]] = j ; } for (e = n ; e >= 0 ; e--) /* place elements in lists */ { if (nv [e] <= 0) continue ; /* skip unless e is an element */ if (Cp [e] != -1) { next [e] = head [Cp [e]] ; /* place e in list of its parent */ head [Cp [e]] = e ; } } for (k = 0, i = 0 ; i <= n ; i++) /* postorder the assembly tree */ { if (Cp [i] == -1) k = cs_tdfs (i, k, head, next, P, w) ; } return (cs_idone (P, C, W, 1)) ; } /* L = chol (A, [pinv parent cp]), pinv is optional */ csn *cs_chol (const cs *A, const css *S) { double d, lki, *Lx, *x, *Cx ; csi top, i, p, k, n, *Li, *Lp, *cp, *pinv, *s, *c, *parent, *Cp, *Ci ; cs *L, *C, *E ; csn *N ; if (!CS_CSC (A) || !S || !S->cp || !S->parent) return (NULL) ; n = A->n ; N = cs_calloc (1, sizeof (csn)) ; /* allocate result */ c = cs_malloc (2*n, sizeof (csi)) ; /* get csi workspace */ x = cs_malloc (n, sizeof (double)) ; /* get double workspace */ cp = S->cp ; pinv = S->pinv ; parent = S->parent ; C = pinv ? cs_symperm (A, pinv, 1) : ((cs *) A) ; E = pinv ? C : NULL ; /* E is alias for A, or a copy E=A(p,p) */ if (!N || !c || !x || !C) return (cs_ndone (N, E, c, x, 0)) ; s = c + n ; Cp = C->p ; Ci = C->i ; Cx = C->x ; N->L = L = cs_spalloc (n, n, cp [n], 1, 0) ; /* allocate result */ if (!L) return (cs_ndone (N, E, c, x, 0)) ; Lp = L->p ; Li = L->i ; Lx = L->x ; for (k = 0 ; k < n ; k++) Lp [k] = c [k] = cp [k] ; for (k = 0 ; k < n ; k++) /* compute L(k,:) for L*L' = C */ { /* --- Nonzero pattern of L(k,:) ------------------------------------ */ top = cs_ereach (C, k, parent, s, c) ; /* find pattern of L(k,:) */ x [k] = 0 ; /* x (0:k) is now zero */ for (p = Cp [k] ; p < Cp [k+1] ; p++) /* x = full(triu(C(:,k))) */ { if (Ci [p] <= k) x [Ci [p]] = Cx [p] ; } d = x [k] ; /* d = C(k,k) */ x [k] = 0 ; /* clear x for k+1st iteration */ /* --- Triangular solve --------------------------------------------- */ for ( ; top < n ; top++) /* solve L(0:k-1,0:k-1) * x = C(:,k) */ { i = s [top] ; /* s [top..n-1] is pattern of L(k,:) */ lki = x [i] / Lx [Lp [i]] ; /* L(k,i) = x (i) / L(i,i) */ x [i] = 0 ; /* clear x for k+1st iteration */ for (p = Lp [i] + 1 ; p < c [i] ; p++) { x [Li [p]] -= Lx [p] * lki ; } d -= lki * lki ; /* d = d - L(k,i)*L(k,i) */ p = c [i]++ ; Li [p] = k ; /* store L(k,i) in column i */ Lx [p] = lki ; } /* --- Compute L(k,k) ----------------------------------------------- */ if (d <= 0) return (cs_ndone (N, E, c, x, 0)) ; /* not pos def */ p = c [k]++ ; Li [p] = k ; /* store L(k,k) = sqrt (d) in column k */ Lx [p] = sqrt (d) ; } Lp [n] = cp [n] ; /* finalize L */ return (cs_ndone (N, E, c, x, 1)) ; /* success: free E,s,x; return N */ } /* x=A\b where A is symmetric positive definite; b overwritten with solution */ csi cs_cholsol (csi order, const cs *A, double *b) { double *x ; css *S ; csn *N ; csi n, ok ; if (!CS_CSC (A) || !b) return (0) ; /* check inputs */ n = A->n ; S = cs_schol (order, A) ; /* ordering and symbolic analysis */ N = cs_chol (A, S) ; /* numeric Cholesky factorization */ x = cs_malloc (n, sizeof (double)) ; /* get workspace */ ok = (S && N && x) ; if (ok) { cs_ipvec (S->pinv, b, x, n) ; /* x = P*b */ cs_lsolve (N->L, x) ; /* x = L\x */ cs_ltsolve (N->L, x) ; /* x = L'\x */ cs_pvec (S->pinv, x, b, n) ; /* b = P'*x */ } cs_free (x) ; cs_sfree (S) ; cs_nfree (N) ; return (ok) ; } /* C = compressed-column form of a triplet matrix T */ cs *cs_compress (const cs *T) { csi m, n, nz, p, k, *Cp, *Ci, *w, *Ti, *Tj ; double *Cx, *Tx ; cs *C ; if (!CS_TRIPLET (T)) return (NULL) ; /* check inputs */ m = T->m ; n = T->n ; Ti = T->i ; Tj = T->p ; Tx = T->x ; nz = T->nz ; C = cs_spalloc (m, n, nz, Tx != NULL, 0) ; /* allocate result */ w = cs_calloc (n, sizeof (csi)) ; /* get workspace */ if (!C || !w) return (cs_done (C, w, NULL, 0)) ; /* out of memory */ Cp = C->p ; Ci = C->i ; Cx = C->x ; for (k = 0 ; k < nz ; k++) w [Tj [k]]++ ; /* column counts */ cs_cumsum (Cp, w, n) ; /* column pointers */ for (k = 0 ; k < nz ; k++) { Ci [p = w [Tj [k]]++] = Ti [k] ; /* A(i,j) is the pth entry in C */ if (Cx) Cx [p] = Tx [k] ; } return (cs_done (C, w, NULL, 1)) ; /* success; free w and return C */ } /* column counts of LL'=A or LL'=A'A, given parent & post ordering */ #define HEAD(k,j) (ata ? head [k] : j) #define NEXT(J) (ata ? next [J] : -1) static void init_ata (cs *AT, const csi *post, csi *w, csi **head, csi **next) { csi i, k, p, m = AT->n, n = AT->m, *ATp = AT->p, *ATi = AT->i ; *head = w+4*n, *next = w+5*n+1 ; for (k = 0 ; k < n ; k++) w [post [k]] = k ; /* invert post */ for (i = 0 ; i < m ; i++) { for (k = n, p = ATp[i] ; p < ATp[i+1] ; p++) k = CS_MIN (k, w [ATi[p]]); (*next) [i] = (*head) [k] ; /* place row i in linked list k */ (*head) [k] = i ; } } csi *cs_counts (const cs *A, const csi *parent, const csi *post, csi ata) { csi i, j, k, n, m, J, s, p, q, jleaf, *ATp, *ATi, *maxfirst, *prevleaf, *ancestor, *head = NULL, *next = NULL, *colcount, *w, *first, *delta ; cs *AT ; if (!CS_CSC (A) || !parent || !post) return (NULL) ; /* check inputs */ m = A->m ; n = A->n ; s = 4*n + (ata ? (n+m+1) : 0) ; delta = colcount = cs_malloc (n, sizeof (csi)) ; /* allocate result */ w = cs_malloc (s, sizeof (csi)) ; /* get workspace */ AT = cs_transpose (A, 0) ; /* AT = A' */ if (!AT || !colcount || !w) return (cs_idone (colcount, AT, w, 0)) ; ancestor = w ; maxfirst = w+n ; prevleaf = w+2*n ; first = w+3*n ; for (k = 0 ; k < s ; k++) w [k] = -1 ; /* clear workspace w [0..s-1] */ for (k = 0 ; k < n ; k++) /* find first [j] */ { j = post [k] ; delta [j] = (first [j] == -1) ? 1 : 0 ; /* delta[j]=1 if j is a leaf */ for ( ; j != -1 && first [j] == -1 ; j = parent [j]) first [j] = k ; } ATp = AT->p ; ATi = AT->i ; if (ata) init_ata (AT, post, w, &head, &next) ; for (i = 0 ; i < n ; i++) ancestor [i] = i ; /* each node in its own set */ for (k = 0 ; k < n ; k++) { j = post [k] ; /* j is the kth node in postordered etree */ if (parent [j] != -1) delta [parent [j]]-- ; /* j is not a root */ for (J = HEAD (k,j) ; J != -1 ; J = NEXT (J)) /* J=j for LL'=A case */ { for (p = ATp [J] ; p < ATp [J+1] ; p++) { i = ATi [p] ; q = cs_leaf (i, j, first, maxfirst, prevleaf, ancestor, &jleaf); if (jleaf >= 1) delta [j]++ ; /* A(i,j) is in skeleton */ if (jleaf == 2) delta [q]-- ; /* account for overlap in q */ } } if (parent [j] != -1) ancestor [j] = parent [j] ; } for (j = 0 ; j < n ; j++) /* sum up delta's of each child */ { if (parent [j] != -1) colcount [parent [j]] += colcount [j] ; } return (cs_idone (colcount, AT, w, 1)) ; /* success: free workspace */ } /* p [0..n] = cumulative sum of c [0..n-1], and then copy p [0..n-1] into c */ double cs_cumsum (csi *p, csi *c, csi n) { csi i, nz = 0 ; double nz2 = 0 ; if (!p || !c) return (-1) ; /* check inputs */ for (i = 0 ; i < n ; i++) { p [i] = nz ; nz += c [i] ; nz2 += c [i] ; /* also in double to avoid csi overflow */ c [i] = p [i] ; /* also copy p[0..n-1] back into c[0..n-1]*/ } p [n] = nz ; return (nz2) ; /* return sum (c [0..n-1]) */ } /* depth-first-search of the graph of a matrix, starting at node j */ csi cs_dfs (csi j, cs *G, csi top, csi *xi, csi *pstack, const csi *pinv) { csi i, p, p2, done, jnew, head = 0, *Gp, *Gi ; if (!CS_CSC (G) || !xi || !pstack) return (-1) ; /* check inputs */ Gp = G->p ; Gi = G->i ; xi [0] = j ; /* initialize the recursion stack */ while (head >= 0) { j = xi [head] ; /* get j from the top of the recursion stack */ jnew = pinv ? (pinv [j]) : j ; if (!CS_MARKED (Gp, j)) { CS_MARK (Gp, j) ; /* mark node j as visited */ pstack [head] = (jnew < 0) ? 0 : CS_UNFLIP (Gp [jnew]) ; } done = 1 ; /* node j done if no unvisited neighbors */ p2 = (jnew < 0) ? 0 : CS_UNFLIP (Gp [jnew+1]) ; for (p = pstack [head] ; p < p2 ; p++) /* examine all neighbors of j */ { i = Gi [p] ; /* consider neighbor node i */ if (CS_MARKED (Gp, i)) continue ; /* skip visited node i */ pstack [head] = p ; /* pause depth-first search of node j */ xi [++head] = i ; /* start dfs at node i */ done = 0 ; /* node j is not done */ break ; /* break, to start dfs (i) */ } if (done) /* depth-first search at node j is done */ { head-- ; /* remove j from the recursion stack */ xi [--top] = j ; /* and place in the output stack */ } } return (top) ; } /* breadth-first search for coarse decomposition (C0,C1,R1 or R0,R3,C3) */ static csi cs_bfs (const cs *A, csi n, csi *wi, csi *wj, csi *queue, const csi *imatch, const csi *jmatch, csi mark) { csi *Ap, *Ai, head = 0, tail = 0, j, i, p, j2 ; cs *C ; for (j = 0 ; j < n ; j++) /* place all unmatched nodes in queue */ { if (imatch [j] >= 0) continue ; /* skip j if matched */ wj [j] = 0 ; /* j in set C0 (R0 if transpose) */ queue [tail++] = j ; /* place unmatched col j in queue */ } if (tail == 0) return (1) ; /* quick return if no unmatched nodes */ C = (mark == 1) ? ((cs *) A) : cs_transpose (A, 0) ; if (!C) return (0) ; /* bfs of C=A' to find R3,C3 from R0 */ Ap = C->p ; Ai = C->i ; while (head < tail) /* while queue is not empty */ { j = queue [head++] ; /* get the head of the queue */ for (p = Ap [j] ; p < Ap [j+1] ; p++) { i = Ai [p] ; if (wi [i] >= 0) continue ; /* skip if i is marked */ wi [i] = mark ; /* i in set R1 (C3 if transpose) */ j2 = jmatch [i] ; /* traverse alternating path to j2 */ if (wj [j2] >= 0) continue ;/* skip j2 if it is marked */ wj [j2] = mark ; /* j2 in set C1 (R3 if transpose) */ queue [tail++] = j2 ; /* add j2 to queue */ } } if (mark != 1) cs_spfree (C) ; /* free A' if it was created */ return (1) ; } /* collect matched rows and columns into p and q */ static void cs_matched (csi n, const csi *wj, const csi *imatch, csi *p, csi *q, csi *cc, csi *rr, csi set, csi mark) { csi kc = cc [set], j ; csi kr = rr [set-1] ; for (j = 0 ; j < n ; j++) { if (wj [j] != mark) continue ; /* skip if j is not in C set */ p [kr++] = imatch [j] ; q [kc++] = j ; } cc [set+1] = kc ; rr [set] = kr ; } /* collect unmatched rows into the permutation vector p */ static void cs_unmatched (csi m, const csi *wi, csi *p, csi *rr, csi set) { csi i, kr = rr [set] ; for (i = 0 ; i < m ; i++) if (wi [i] == 0) p [kr++] = i ; rr [set+1] = kr ; } /* return 1 if row i is in R2 */ static csi cs_rprune (csi i, csi j, double aij, void *other) { csi *rr = (csi *) other ; return (i >= rr [1] && i < rr [2]) ; } /* Given A, compute coarse and then fine dmperm */ csd *cs_dmperm (const cs *A, csi seed) { csi m, n, i, j, k, cnz, nc, *jmatch, *imatch, *wi, *wj, *pinv, *Cp, *Ci, *ps, *rs, nb1, nb2, *p, *q, *cc, *rr, *r, *s, ok ; cs *C ; csd *D, *scc ; /* --- Maximum matching ------------------------------------------------- */ if (!CS_CSC (A)) return (NULL) ; /* check inputs */ m = A->m ; n = A->n ; D = cs_dalloc (m, n) ; /* allocate result */ if (!D) return (NULL) ; p = D->p ; q = D->q ; r = D->r ; s = D->s ; cc = D->cc ; rr = D->rr ; jmatch = cs_maxtrans (A, seed) ; /* max transversal */ imatch = jmatch + m ; /* imatch = inverse of jmatch */ if (!jmatch) return (cs_ddone (D, NULL, jmatch, 0)) ; /* --- Coarse decomposition --------------------------------------------- */ wi = r ; wj = s ; /* use r and s as workspace */ for (j = 0 ; j < n ; j++) wj [j] = -1 ; /* unmark all cols for bfs */ for (i = 0 ; i < m ; i++) wi [i] = -1 ; /* unmark all rows for bfs */ cs_bfs (A, n, wi, wj, q, imatch, jmatch, 1) ; /* find C1, R1 from C0*/ ok = cs_bfs (A, m, wj, wi, p, jmatch, imatch, 3) ; /* find R3, C3 from R0*/ if (!ok) return (cs_ddone (D, NULL, jmatch, 0)) ; cs_unmatched (n, wj, q, cc, 0) ; /* unmatched set C0 */ cs_matched (n, wj, imatch, p, q, cc, rr, 1, 1) ; /* set R1 and C1 */ cs_matched (n, wj, imatch, p, q, cc, rr, 2, -1) ; /* set R2 and C2 */ cs_matched (n, wj, imatch, p, q, cc, rr, 3, 3) ; /* set R3 and C3 */ cs_unmatched (m, wi, p, rr, 3) ; /* unmatched set R0 */ cs_free (jmatch) ; /* --- Fine decomposition ----------------------------------------------- */ pinv = cs_pinv (p, m) ; /* pinv=p' */ if (!pinv) return (cs_ddone (D, NULL, NULL, 0)) ; C = cs_permute (A, pinv, q, 0) ;/* C=A(p,q) (it will hold A(R2,C2)) */ cs_free (pinv) ; if (!C) return (cs_ddone (D, NULL, NULL, 0)) ; Cp = C->p ; nc = cc [3] - cc [2] ; /* delete cols C0, C1, and C3 from C */ if (cc [2] > 0) for (j = cc [2] ; j <= cc [3] ; j++) Cp [j-cc[2]] = Cp [j] ; C->n = nc ; if (rr [2] - rr [1] < m) /* delete rows R0, R1, and R3 from C */ { cs_fkeep (C, cs_rprune, rr) ; cnz = Cp [nc] ; Ci = C->i ; if (rr [1] > 0) for (k = 0 ; k < cnz ; k++) Ci [k] -= rr [1] ; } C->m = nc ; scc = cs_scc (C) ; /* find strongly connected components of C*/ if (!scc) return (cs_ddone (D, C, NULL, 0)) ; /* --- Combine coarse and fine decompositions --------------------------- */ ps = scc->p ; /* C(ps,ps) is the permuted matrix */ rs = scc->r ; /* kth block is rs[k]..rs[k+1]-1 */ nb1 = scc->nb ; /* # of blocks of A(R2,C2) */ for (k = 0 ; k < nc ; k++) wj [k] = q [ps [k] + cc [2]] ; for (k = 0 ; k < nc ; k++) q [k + cc [2]] = wj [k] ; for (k = 0 ; k < nc ; k++) wi [k] = p [ps [k] + rr [1]] ; for (k = 0 ; k < nc ; k++) p [k + rr [1]] = wi [k] ; nb2 = 0 ; /* create the fine block partitions */ r [0] = s [0] = 0 ; if (cc [2] > 0) nb2++ ; /* leading coarse block A (R1, [C0 C1]) */ for (k = 0 ; k < nb1 ; k++) /* coarse block A (R2,C2) */ { r [nb2] = rs [k] + rr [1] ; /* A (R2,C2) splits into nb1 fine blocks */ s [nb2] = rs [k] + cc [2] ; nb2++ ; } if (rr [2] < m) { r [nb2] = rr [2] ; /* trailing coarse block A ([R3 R0], C3) */ s [nb2] = cc [3] ; nb2++ ; } r [nb2] = m ; s [nb2] = n ; D->nb = nb2 ; cs_dfree (scc) ; return (cs_ddone (D, C, NULL, 1)) ; } static csi cs_tol (csi i, csi j, double aij, void *tol) { return (fabs (aij) > *((double *) tol)) ; } csi cs_droptol (cs *A, double tol) { return (cs_fkeep (A, &cs_tol, &tol)) ; /* keep all large entries */ } static csi cs_nonzero (csi i, csi j, double aij, void *other) { return (aij != 0) ; } csi cs_dropzeros (cs *A) { return (cs_fkeep (A, &cs_nonzero, NULL)) ; /* keep all nonzero entries */ } /* remove duplicate entries from A */ csi cs_dupl (cs *A) { csi i, j, p, q, nz = 0, n, m, *Ap, *Ai, *w ; double *Ax ; if (!CS_CSC (A)) return (0) ; /* check inputs */ m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; w = cs_malloc (m, sizeof (csi)) ; /* get workspace */ if (!w) return (0) ; /* out of memory */ for (i = 0 ; i < m ; i++) w [i] = -1 ; /* row i not yet seen */ for (j = 0 ; j < n ; j++) { q = nz ; /* column j will start at q */ for (p = Ap [j] ; p < Ap [j+1] ; p++) { i = Ai [p] ; /* A(i,j) is nonzero */ if (w [i] >= q) { Ax [w [i]] += Ax [p] ; /* A(i,j) is a duplicate */ } else { w [i] = nz ; /* record where row i occurs */ Ai [nz] = i ; /* keep A(i,j) */ Ax [nz++] = Ax [p] ; } } Ap [j] = q ; /* record start of column j */ } Ap [n] = nz ; /* finalize A */ cs_free (w) ; /* free workspace */ return (cs_sprealloc (A, 0)) ; /* remove extra space from A */ } /* add an entry to a triplet matrix; return 1 if ok, 0 otherwise */ csi cs_entry (cs *T, csi i, csi j, double x) { if (!CS_TRIPLET (T) || i < 0 || j < 0) return (0) ; /* check inputs */ if (T->nz >= T->nzmax && !cs_sprealloc (T,2*(T->nzmax))) return (0) ; if (T->x) T->x [T->nz] = x ; T->i [T->nz] = i ; T->p [T->nz++] = j ; T->m = CS_MAX (T->m, i+1) ; T->n = CS_MAX (T->n, j+1) ; return (1) ; } /* find nonzero pattern of Cholesky L(k,1:k-1) using etree and triu(A(:,k)) */ csi cs_ereach (const cs *A, csi k, const csi *parent, csi *s, csi *w) { csi i, p, n, len, top, *Ap, *Ai ; if (!CS_CSC (A) || !parent || !s || !w) return (-1) ; /* check inputs */ top = n = A->n ; Ap = A->p ; Ai = A->i ; CS_MARK (w, k) ; /* mark node k as visited */ for (p = Ap [k] ; p < Ap [k+1] ; p++) { i = Ai [p] ; /* A(i,k) is nonzero */ if (i > k) continue ; /* only use upper triangular part of A */ for (len = 0 ; !CS_MARKED (w,i) ; i = parent [i]) /* traverse up etree*/ { s [len++] = i ; /* L(k,i) is nonzero */ CS_MARK (w, i) ; /* mark i as visited */ } while (len > 0) s [--top] = s [--len] ; /* push path onto stack */ } for (p = top ; p < n ; p++) CS_MARK (w, s [p]) ; /* unmark all nodes */ CS_MARK (w, k) ; /* unmark node k */ return (top) ; /* s [top..n-1] contains pattern of L(k,:)*/ } /* compute the etree of A (using triu(A), or A'A without forming A'A */ csi *cs_etree (const cs *A, csi ata) { csi i, k, p, m, n, inext, *Ap, *Ai, *w, *parent, *ancestor, *prev ; if (!CS_CSC (A)) return (NULL) ; /* check inputs */ m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; parent = cs_malloc (n, sizeof (csi)) ; /* allocate result */ w = cs_malloc (n + (ata ? m : 0), sizeof (csi)) ; /* get workspace */ if (!w || !parent) return (cs_idone (parent, NULL, w, 0)) ; ancestor = w ; prev = w + n ; if (ata) for (i = 0 ; i < m ; i++) prev [i] = -1 ; for (k = 0 ; k < n ; k++) { parent [k] = -1 ; /* node k has no parent yet */ ancestor [k] = -1 ; /* nor does k have an ancestor */ for (p = Ap [k] ; p < Ap [k+1] ; p++) { i = ata ? (prev [Ai [p]]) : (Ai [p]) ; for ( ; i != -1 && i < k ; i = inext) /* traverse from i to k */ { inext = ancestor [i] ; /* inext = ancestor of i */ ancestor [i] = k ; /* path compression */ if (inext == -1) parent [i] = k ; /* no anc., parent is k */ } if (ata) prev [Ai [p]] = k ; } } return (cs_idone (parent, NULL, w, 1)) ; } /* drop entries for which fkeep(A(i,j)) is false; return nz if OK, else -1 */ csi cs_fkeep (cs *A, csi (*fkeep) (csi, csi, double, void *), void *other) { csi j, p, nz = 0, n, *Ap, *Ai ; double *Ax ; if (!CS_CSC (A) || !fkeep) return (-1) ; /* check inputs */ n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; for (j = 0 ; j < n ; j++) { p = Ap [j] ; /* get current location of col j */ Ap [j] = nz ; /* record new location of col j */ for ( ; p < Ap [j+1] ; p++) { if (fkeep (Ai [p], j, Ax ? Ax [p] : 1, other)) { if (Ax) Ax [nz] = Ax [p] ; /* keep A(i,j) */ Ai [nz++] = Ai [p] ; } } } Ap [n] = nz ; /* finalize A */ cs_sprealloc (A, 0) ; /* remove extra space from A */ return (nz) ; } /* y = A*x+y */ csi cs_gaxpy (const cs *A, const double *x, double *y) { csi p, j, n, *Ap, *Ai ; double *Ax ; if (!CS_CSC (A) || !x || !y) return (0) ; /* check inputs */ n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; for (j = 0 ; j < n ; j++) { for (p = Ap [j] ; p < Ap [j+1] ; p++) { y [Ai [p]] += Ax [p] * x [j] ; } } return (1) ; } /* apply the ith Householder vector to x */ csi cs_happly (const cs *V, csi i, double beta, double *x) { csi p, *Vp, *Vi ; double *Vx, tau = 0 ; if (!CS_CSC (V) || !x) return (0) ; /* check inputs */ Vp = V->p ; Vi = V->i ; Vx = V->x ; for (p = Vp [i] ; p < Vp [i+1] ; p++) /* tau = v'*x */ { tau += Vx [p] * x [Vi [p]] ; } tau *= beta ; /* tau = beta*(v'*x) */ for (p = Vp [i] ; p < Vp [i+1] ; p++) /* x = x - v*tau */ { x [Vi [p]] -= Vx [p] * tau ; } return (1) ; } /* create a Householder reflection [v,beta,s]=house(x), overwrite x with v, * where (I-beta*v*v')*x = s*e1. See Algo 5.1.1, Golub & Van Loan, 3rd ed. */ double cs_house (double *x, double *beta, csi n) { double s, sigma = 0 ; csi i ; if (!x || !beta) return (-1) ; /* check inputs */ for (i = 1 ; i < n ; i++) sigma += x [i] * x [i] ; if (sigma == 0) { s = fabs (x [0]) ; /* s = |x(0)| */ (*beta) = (x [0] <= 0) ? 2 : 0 ; x [0] = 1 ; } else { s = sqrt (x [0] * x [0] + sigma) ; /* s = norm (x) */ x [0] = (x [0] <= 0) ? (x [0] - s) : (-sigma / (x [0] + s)) ; (*beta) = -1. / (s * x [0]) ; } return (s) ; } /* x(p) = b, for dense vectors x and b; p=NULL denotes identity */ csi cs_ipvec (const csi *p, const double *b, double *x, csi n) { csi k ; if (!x || !b) return (0) ; /* check inputs */ for (k = 0 ; k < n ; k++) x [p ? p [k] : k] = b [k] ; return (1) ; } /* consider A(i,j), node j in ith row subtree and return lca(jprev,j) */ csi cs_leaf (csi i, csi j, const csi *first, csi *maxfirst, csi *prevleaf, csi *ancestor, csi *jleaf) { csi q, s, sparent, jprev ; if (!first || !maxfirst || !prevleaf || !ancestor || !jleaf) return (-1) ; *jleaf = 0 ; if (i <= j || first [j] <= maxfirst [i]) return (-1) ; /* j not a leaf */ maxfirst [i] = first [j] ; /* update max first[j] seen so far */ jprev = prevleaf [i] ; /* jprev = previous leaf of ith subtree */ prevleaf [i] = j ; *jleaf = (jprev == -1) ? 1: 2 ; /* j is first or subsequent leaf */ if (*jleaf == 1) return (i) ; /* if 1st leaf, q = root of ith subtree */ for (q = jprev ; q != ancestor [q] ; q = ancestor [q]) ; for (s = jprev ; s != q ; s = sparent) { sparent = ancestor [s] ; /* path compression */ ancestor [s] = q ; } return (q) ; /* q = least common ancester (jprev,j) */ } /* load a triplet matrix from a file */ cs *cs_load (FILE *f) { double i, j ; /* use double for integers to avoid csi conflicts */ double x ; cs *T ; if (!f) return (NULL) ; /* check inputs */ T = cs_spalloc (0, 0, 1, 1, 1) ; /* allocate result */ while (fscanf (f, "%lg %lg %lg\n", &i, &j, &x) == 3) { if (!cs_entry (T, (csi) i, (csi) j, x)) return (cs_spfree (T)) ; } return (T) ; } /* solve Lx=b where x and b are dense. x=b on input, solution on output. */ csi cs_lsolve (const cs *L, double *x) { csi p, j, n, *Lp, *Li ; double *Lx ; if (!CS_CSC (L) || !x) return (0) ; /* check inputs */ n = L->n ; Lp = L->p ; Li = L->i ; Lx = L->x ; for (j = 0 ; j < n ; j++) { x [j] /= Lx [Lp [j]] ; for (p = Lp [j]+1 ; p < Lp [j+1] ; p++) { x [Li [p]] -= Lx [p] * x [j] ; } } return (1) ; } /* solve L'x=b where x and b are dense. x=b on input, solution on output. */ csi cs_ltsolve (const cs *L, double *x) { csi p, j, n, *Lp, *Li ; double *Lx ; if (!CS_CSC (L) || !x) return (0) ; /* check inputs */ n = L->n ; Lp = L->p ; Li = L->i ; Lx = L->x ; for (j = n-1 ; j >= 0 ; j--) { for (p = Lp [j]+1 ; p < Lp [j+1] ; p++) { x [j] -= Lx [p] * x [Li [p]] ; } x [j] /= Lx [Lp [j]] ; } return (1) ; } /* [L,U,pinv]=lu(A, [q lnz unz]). lnz and unz can be guess */ csn *cs_lu (const cs *A, const css *S, double tol) { cs *L, *U ; csn *N ; double pivot, *Lx, *Ux, *x, a, t ; csi *Lp, *Li, *Up, *Ui, *pinv, *xi, *q, n, ipiv, k, top, p, i, col, lnz,unz; if (!CS_CSC (A) || !S) return (NULL) ; /* check inputs */ n = A->n ; q = S->q ; lnz = S->lnz ; unz = S->unz ; x = cs_malloc (n, sizeof (double)) ; /* get double workspace */ xi = cs_malloc (2*n, sizeof (csi)) ; /* get csi workspace */ N = cs_calloc (1, sizeof (csn)) ; /* allocate result */ if (!x || !xi || !N) return (cs_ndone (N, NULL, xi, x, 0)) ; N->L = L = cs_spalloc (n, n, lnz, 1, 0) ; /* allocate result L */ N->U = U = cs_spalloc (n, n, unz, 1, 0) ; /* allocate result U */ N->pinv = pinv = cs_malloc (n, sizeof (csi)) ; /* allocate result pinv */ if (!L || !U || !pinv) return (cs_ndone (N, NULL, xi, x, 0)) ; Lp = L->p ; Up = U->p ; for (i = 0 ; i < n ; i++) x [i] = 0 ; /* clear workspace */ for (i = 0 ; i < n ; i++) pinv [i] = -1 ; /* no rows pivotal yet */ for (k = 0 ; k <= n ; k++) Lp [k] = 0 ; /* no cols of L yet */ lnz = unz = 0 ; for (k = 0 ; k < n ; k++) /* compute L(:,k) and U(:,k) */ { /* --- Triangular solve --------------------------------------------- */ Lp [k] = lnz ; /* L(:,k) starts here */ Up [k] = unz ; /* U(:,k) starts here */ if ((lnz + n > L->nzmax && !cs_sprealloc (L, 2*L->nzmax + n)) || (unz + n > U->nzmax && !cs_sprealloc (U, 2*U->nzmax + n))) { return (cs_ndone (N, NULL, xi, x, 0)) ; } Li = L->i ; Lx = L->x ; Ui = U->i ; Ux = U->x ; col = q ? (q [k]) : k ; top = cs_spsolve (L, A, col, xi, x, pinv, 1) ; /* x = L\A(:,col) */ /* --- Find pivot --------------------------------------------------- */ ipiv = -1 ; a = -1 ; for (p = top ; p < n ; p++) { i = xi [p] ; /* x(i) is nonzero */ if (pinv [i] < 0) /* row i is not yet pivotal */ { if ((t = fabs (x [i])) > a) { a = t ; /* largest pivot candidate so far */ ipiv = i ; } } else /* x(i) is the entry U(pinv[i],k) */ { Ui [unz] = pinv [i] ; Ux [unz++] = x [i] ; } } if (ipiv == -1 || a <= 0) return (cs_ndone (N, NULL, xi, x, 0)) ; /* tol=1 for partial pivoting; tol<1 gives preference to diagonal */ if (pinv [col] < 0 && fabs (x [col]) >= a*tol) ipiv = col ; /* --- Divide by pivot ---------------------------------------------- */ pivot = x [ipiv] ; /* the chosen pivot */ Ui [unz] = k ; /* last entry in U(:,k) is U(k,k) */ Ux [unz++] = pivot ; pinv [ipiv] = k ; /* ipiv is the kth pivot row */ Li [lnz] = ipiv ; /* first entry in L(:,k) is L(k,k) = 1 */ Lx [lnz++] = 1 ; for (p = top ; p < n ; p++) /* L(k+1:n,k) = x / pivot */ { i = xi [p] ; if (pinv [i] < 0) /* x(i) is an entry in L(:,k) */ { Li [lnz] = i ; /* save unpermuted row in L */ Lx [lnz++] = x [i] / pivot ; /* scale pivot column */ } x [i] = 0 ; /* x [0..n-1] = 0 for next k */ } } /* --- Finalize L and U ------------------------------------------------- */ Lp [n] = lnz ; Up [n] = unz ; Li = L->i ; /* fix row indices of L for final pinv */ for (p = 0 ; p < lnz ; p++) Li [p] = pinv [Li [p]] ; cs_sprealloc (L, 0) ; /* remove extra space from L and U */ cs_sprealloc (U, 0) ; return (cs_ndone (N, NULL, xi, x, 1)) ; /* success */ } /* x=A\b where A is unsymmetric; b overwritten with solution */ csi cs_lusol (csi order, const cs *A, double *b, double tol) { double *x ; css *S ; csn *N ; csi n, ok ; if (!CS_CSC (A) || !b) return (0) ; /* check inputs */ n = A->n ; S = cs_sqr (order, A, 0) ; /* ordering and symbolic analysis */ N = cs_lu (A, S, tol) ; /* numeric LU factorization */ x = cs_malloc (n, sizeof (double)) ; /* get workspace */ ok = (S && N && x) ; if (ok) { cs_ipvec (N->pinv, b, x, n) ; /* x = b(p) */ cs_lsolve (N->L, x) ; /* x = L\x */ cs_usolve (N->U, x) ; /* x = U\x */ cs_ipvec (S->q, x, b, n) ; /* b(q) = x */ } cs_free (x) ; cs_sfree (S) ; cs_nfree (N) ; return (ok) ; } #ifdef MATLAB_MEX_FILE #define malloc mxMalloc #define free mxFree #define realloc mxRealloc #define calloc mxCalloc #endif /* wrapper for malloc */ void *cs_malloc (csi n, size_t size) { return (malloc (CS_MAX (n,1) * size)) ; } /* wrapper for calloc */ void *cs_calloc (csi n, size_t size) { return (calloc (CS_MAX (n,1), size)) ; } /* wrapper for free */ void *cs_free (void *p) { if (p) free (p) ; /* free p if it is not already NULL */ return (NULL) ; /* return NULL to simplify the use of cs_free */ } /* wrapper for realloc */ void *cs_realloc (void *p, csi n, size_t size, csi *ok) { void *pnew ; pnew = realloc (p, CS_MAX (n,1) * size) ; /* realloc the block */ *ok = (pnew != NULL) ; /* realloc fails if pnew is NULL */ return ((*ok) ? pnew : p) ; /* return original p if failure */ } /* find an augmenting path starting at column k and extend the match if found */ static void cs_augment (csi k, const cs *A, csi *jmatch, csi *cheap, csi *w, csi *js, csi *is, csi *ps) { csi found = 0, p, i = -1, *Ap = A->p, *Ai = A->i, head = 0, j ; js [0] = k ; /* start with just node k in jstack */ while (head >= 0) { /* --- Start (or continue) depth-first-search at node j ------------- */ j = js [head] ; /* get j from top of jstack */ if (w [j] != k) /* 1st time j visited for kth path */ { w [j] = k ; /* mark j as visited for kth path */ for (p = cheap [j] ; p < Ap [j+1] && !found ; p++) { i = Ai [p] ; /* try a cheap assignment (i,j) */ found = (jmatch [i] == -1) ; } cheap [j] = p ; /* start here next time j is traversed*/ if (found) { is [head] = i ; /* column j matched with row i */ break ; /* end of augmenting path */ } ps [head] = Ap [j] ; /* no cheap match: start dfs for j */ } /* --- Depth-first-search of neighbors of j ------------------------- */ for (p = ps [head] ; p < Ap [j+1] ; p++) { i = Ai [p] ; /* consider row i */ if (w [jmatch [i]] == k) continue ; /* skip jmatch [i] if marked */ ps [head] = p + 1 ; /* pause dfs of node j */ is [head] = i ; /* i will be matched with j if found */ js [++head] = jmatch [i] ; /* start dfs at column jmatch [i] */ break ; } if (p == Ap [j+1]) head-- ; /* node j is done; pop from stack */ } /* augment the match if path found: */ if (found) for (p = head ; p >= 0 ; p--) jmatch [is [p]] = js [p] ; } /* find a maximum transveral */ csi *cs_maxtrans (const cs *A, csi seed) /*[jmatch [0..m-1]; imatch [0..n-1]]*/ { csi i, j, k, n, m, p, n2 = 0, m2 = 0, *Ap, *jimatch, *w, *cheap, *js, *is, *ps, *Ai, *Cp, *jmatch, *imatch, *q ; cs *C ; if (!CS_CSC (A)) return (NULL) ; /* check inputs */ n = A->n ; m = A->m ; Ap = A->p ; Ai = A->i ; w = jimatch = cs_calloc (m+n, sizeof (csi)) ; /* allocate result */ if (!jimatch) return (NULL) ; for (k = 0, j = 0 ; j < n ; j++) /* count nonempty rows and columns */ { n2 += (Ap [j] < Ap [j+1]) ; for (p = Ap [j] ; p < Ap [j+1] ; p++) { w [Ai [p]] = 1 ; k += (j == Ai [p]) ; /* count entries already on diagonal */ } } if (k == CS_MIN (m,n)) /* quick return if diagonal zero-free */ { jmatch = jimatch ; imatch = jimatch + m ; for (i = 0 ; i < k ; i++) jmatch [i] = i ; for ( ; i < m ; i++) jmatch [i] = -1 ; for (j = 0 ; j < k ; j++) imatch [j] = j ; for ( ; j < n ; j++) imatch [j] = -1 ; return (cs_idone (jimatch, NULL, NULL, 1)) ; } for (i = 0 ; i < m ; i++) m2 += w [i] ; C = (m2 < n2) ? cs_transpose (A,0) : ((cs *) A) ; /* transpose if needed */ if (!C) return (cs_idone (jimatch, (m2 < n2) ? C : NULL, NULL, 0)) ; n = C->n ; m = C->m ; Cp = C->p ; jmatch = (m2 < n2) ? jimatch + n : jimatch ; imatch = (m2 < n2) ? jimatch : jimatch + m ; w = cs_malloc (5*n, sizeof (csi)) ; /* get workspace */ if (!w) return (cs_idone (jimatch, (m2 < n2) ? C : NULL, w, 0)) ; cheap = w + n ; js = w + 2*n ; is = w + 3*n ; ps = w + 4*n ; for (j = 0 ; j < n ; j++) cheap [j] = Cp [j] ; /* for cheap assignment */ for (j = 0 ; j < n ; j++) w [j] = -1 ; /* all columns unflagged */ for (i = 0 ; i < m ; i++) jmatch [i] = -1 ; /* nothing matched yet */ q = cs_randperm (n, seed) ; /* q = random permutation */ for (k = 0 ; k < n ; k++) /* augment, starting at column q[k] */ { cs_augment (q ? q [k]: k, C, jmatch, cheap, w, js, is, ps) ; } cs_free (q) ; for (j = 0 ; j < n ; j++) imatch [j] = -1 ; /* find row match */ for (i = 0 ; i < m ; i++) if (jmatch [i] >= 0) imatch [jmatch [i]] = i ; return (cs_idone (jimatch, (m2 < n2) ? C : NULL, w, 1)) ; } #if csi == int # define csi_MAX INT_MAX #else # error "Need INT_MAX analogue of csi type" #endif /* C = A*B */ cs *cs_multiply (const cs *A, const cs *B) { csi p, j, nz = 0, anz, *Cp, *Ci, *Bp, m, n, bnz, *w, values, *Bi ; double *x, *Bx, *Cx ; cs *C ; if (!CS_CSC (A) || !CS_CSC (B)) return (NULL) ; /* check inputs */ if (A->n != B->m) return (NULL) ; m = A->m ; anz = A->p [A->n] ; n = B->n ; Bp = B->p ; Bi = B->i ; Bx = B->x ; bnz = Bp [n] ; w = cs_calloc (m, sizeof (csi)) ; /* get workspace */ values = (A->x != NULL) && (Bx != NULL) ; x = values ? cs_malloc (m, sizeof (double)) : NULL ; /* get workspace */ C = cs_spalloc (m, n, anz + bnz, values, 0) ; /* allocate result */ if (!C || !w || (values && !x)) return (cs_done (C, w, x, 0)) ; Cp = C->p ; for (j = 0 ; j < n ; j++) { if (C->nzmax > (csi_MAX - m)/2 || // 2*C->nzmax + m overflows (nz + m > C->nzmax && !cs_sprealloc (C, 2*(C->nzmax)+m))) { warning("Too many non-zeros in sparse product: Out of memory"); return (cs_done (C, w, x, 0)) ; /* out of memory */ } Ci = C->i ; Cx = C->x ; /* C->i and C->x may be reallocated */ Cp [j] = nz ; /* column j of C starts here */ for (p = Bp [j] ; p < Bp [j+1] ; p++) { nz = cs_scatter (A, Bi [p], Bx ? Bx [p] : 1, w, x, j+1, C, nz) ; } if (values) for (p = Cp [j] ; p < nz ; p++) Cx [p] = x [Ci [p]] ; } Cp [n] = nz ; /* finalize the last column of C */ cs_sprealloc (C, 0) ; /* remove extra space from C */ return (cs_done (C, w, x, 1)) ; /* success; free workspace, return C */ } /* 1-norm of a sparse matrix = max (sum (abs (A))), largest column sum */ double cs_norm (const cs *A) { csi p, j, n, *Ap ; double *Ax, norm = 0, s ; if (!CS_CSC (A) || !A->x) return (-1) ; /* check inputs */ n = A->n ; Ap = A->p ; Ax = A->x ; for (j = 0 ; j < n ; j++) { for (s = 0, p = Ap [j] ; p < Ap [j+1] ; p++) s += fabs (Ax [p]) ; norm = CS_MAX (norm, s) ; } return (norm) ; } /* C = A(p,q) where p and q are permutations of 0..m-1 and 0..n-1. */ cs *cs_permute (const cs *A, const csi *pinv, const csi *q, csi values) { csi t, j, k, nz = 0, m, n, *Ap, *Ai, *Cp, *Ci ; double *Cx, *Ax ; cs *C ; if (!CS_CSC (A)) return (NULL) ; /* check inputs */ m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; C = cs_spalloc (m, n, Ap [n], values && Ax != NULL, 0) ; /* alloc result */ if (!C) return (cs_done (C, NULL, NULL, 0)) ; /* out of memory */ Cp = C->p ; Ci = C->i ; Cx = C->x ; for (k = 0 ; k < n ; k++) { Cp [k] = nz ; /* column k of C is column q[k] of A */ j = q ? (q [k]) : k ; for (t = Ap [j] ; t < Ap [j+1] ; t++) { if (Cx) Cx [nz] = Ax [t] ; /* row i of A is row pinv[i] of C */ Ci [nz++] = pinv ? (pinv [Ai [t]]) : Ai [t] ; } } Cp [n] = nz ; /* finalize the last column of C */ return (cs_done (C, NULL, NULL, 1)) ; } /* pinv = p', or p = pinv' */ csi *cs_pinv (csi const *p, csi n) { csi k, *pinv ; if (!p) return (NULL) ; /* p = NULL denotes identity */ pinv = cs_malloc (n, sizeof (csi)) ; /* allocate result */ if (!pinv) return (NULL) ; /* out of memory */ for (k = 0 ; k < n ; k++) pinv [p [k]] = k ;/* invert the permutation */ return (pinv) ; /* return result */ } /* post order a forest */ csi *cs_post (const csi *parent, csi n) { csi j, k = 0, *post, *w, *head, *next, *stack ; if (!parent) return (NULL) ; /* check inputs */ post = cs_malloc (n, sizeof (csi)) ; /* allocate result */ w = cs_malloc (3*n, sizeof (csi)) ; /* get workspace */ if (!w || !post) return (cs_idone (post, NULL, w, 0)) ; head = w ; next = w + n ; stack = w + 2*n ; for (j = 0 ; j < n ; j++) head [j] = -1 ; /* empty linked lists */ for (j = n-1 ; j >= 0 ; j--) /* traverse nodes in reverse order*/ { if (parent [j] == -1) continue ; /* j is a root */ next [j] = head [parent [j]] ; /* add j to list of its parent */ head [parent [j]] = j ; } for (j = 0 ; j < n ; j++) { if (parent [j] != -1) continue ; /* skip j if it is not a root */ k = cs_tdfs (j, k, head, next, post, stack) ; } return (cs_idone (post, NULL, w, 1)) ; /* success; free w, return post */ } /* print a sparse matrix; use %g for integers to avoid differences with csi */ csi cs_print (const cs *A, csi brief) { csi p, j, m, n, nzmax, nz, *Ap, *Ai ; double *Ax ; if (!A) { printf ("(null)\n") ; return (0) ; } m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; nzmax = A->nzmax ; nz = A->nz ; printf ("CSparse Version %d.%d.%d, %s. %s\n", CS_VER, CS_SUBVER, CS_SUBSUB, CS_DATE, CS_COPYRIGHT) ; if (nz < 0) { printf ("%g-by-%g, nzmax: %g nnz: %g, 1-norm: %g\n", (double) m, (double) n, (double) nzmax, (double) (Ap [n]), cs_norm (A)) ; for (j = 0 ; j < n ; j++) { printf (" col %g : locations %g to %g\n", (double) j, (double) (Ap [j]), (double) (Ap [j+1]-1)) ; for (p = Ap [j] ; p < Ap [j+1] ; p++) { printf (" %g : %g\n", (double) (Ai [p]), Ax ? Ax [p] : 1) ; if (brief && p > 20) { printf (" ...\n") ; return (1) ; } } } } else { printf ("triplet: %g-by-%g, nzmax: %g nnz: %g\n", (double) m, (double) n, (double) nzmax, (double) nz) ; for (p = 0 ; p < nz ; p++) { printf (" %g %g : %g\n", (double) (Ai [p]), (double) (Ap [p]), Ax ? Ax [p] : 1) ; if (brief && p > 20) { printf (" ...\n") ; return (1) ; } } } return (1) ; } /* x = b(p), for dense vectors x and b; p=NULL denotes identity */ csi cs_pvec (const csi *p, const double *b, double *x, csi n) { csi k ; if (!x || !b) return (0) ; /* check inputs */ for (k = 0 ; k < n ; k++) x [k] = b [p ? p [k] : k] ; return (1) ; } /* sparse QR factorization [V,beta,pinv,R] = qr (A) */ csn *cs_qr (const cs *A, const css *S) { double *Rx, *Vx, *Ax, *x, *Beta ; csi i, k, p, n, vnz, p1, top, m2, len, col, rnz, *s, *leftmost, *Ap, *Ai, *parent, *Rp, *Ri, *Vp, *Vi, *w, *pinv, *q ; cs *R, *V ; csn *N ; // the result if (!CS_CSC (A) || !S) return (NULL) ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; q = S->q ; parent = S->parent ; pinv = S->pinv ; m2 = S->m2 ; vnz = S->lnz ; rnz = S->unz ; leftmost = S->leftmost ; w = cs_malloc (m2+n, sizeof (csi)) ; /* get csi workspace */ x = cs_malloc (m2, sizeof (double)) ; /* get double workspace */ N = cs_calloc (1, sizeof (csn)) ; /* allocate result */ if (!w || !x || !N) return (cs_ndone (N, NULL, w, x, 0)) ; s = w + m2 ; /* s is size n */ for (k = 0 ; k < m2 ; k++) x [k] = 0 ; /* clear workspace x */ N->L = V = cs_spalloc (m2, n, vnz, 1, 0) ; /* allocate result V */ N->U = R = cs_spalloc (m2, n, rnz, 1, 0) ; /* allocate result R */ N->B = Beta = cs_malloc (n, sizeof (double)) ; /* allocate result Beta */ if (!R || !V || !Beta) return (cs_ndone (N, NULL, w, x, 0)) ; Rp = R->p ; Ri = R->i ; Rx = R->x ; Vp = V->p ; Vi = V->i ; Vx = V->x ; for (i = 0 ; i < m2 ; i++) w [i] = -1 ; /* clear w, to mark nodes */ rnz = 0 ; vnz = 0 ; for (k = 0 ; k < n ; k++) /* compute V and R */ { Rp [k] = rnz ; /* R(:,k) starts here */ Vp [k] = p1 = vnz ; /* V(:,k) starts here */ w [k] = k ; /* add V(k,k) to pattern of V */ Vi [vnz++] = k ; top = n ; col = q ? q [k] : k ; for (p = Ap [col] ; p < Ap [col+1] ; p++) /* find R(:,k) pattern */ { i = leftmost [Ai [p]] ; /* i = min(find(A(i,q))) */ for (len = 0 ; w [i] != k ; i = parent [i]) /* traverse up to k */ { s [len++] = i ; w [i] = k ; } while (len > 0) s [--top] = s [--len] ; /* push path on stack */ i = pinv [Ai [p]] ; /* i = permuted row of A(:,col) */ x [i] = Ax [p] ; /* x (i) = A(:,col) */ if (i > k && w [i] < k) /* pattern of V(:,k) = x (k+1:m) */ { Vi [vnz++] = i ; /* add i to pattern of V(:,k) */ w [i] = k ; } } for (p = top ; p < n ; p++) /* for each i in pattern of R(:,k) */ { i = s [p] ; /* R(i,k) is nonzero */ cs_happly (V, i, Beta [i], x) ; /* apply (V(i),Beta(i)) to x */ Ri [rnz] = i ; /* R(i,k) = x(i) */ Rx [rnz++] = x [i] ; x [i] = 0 ; if (parent [i] == k) vnz = cs_scatter (V, i, 0, w, NULL, k, V, vnz); } for (p = p1 ; p < vnz ; p++) /* gather V(:,k) = x */ { Vx [p] = x [Vi [p]] ; x [Vi [p]] = 0 ; } Ri [rnz] = k ; /* R(k,k) = norm (x) */ Rx [rnz++] = cs_house (Vx+p1, Beta+k, vnz-p1) ; /* [v,beta]=house(x) */ } Rp [n] = rnz ; /* finalize R */ Vp [n] = vnz ; /* finalize V */ return (cs_ndone (N, NULL, w, x, 1)) ; /* success */ } /* x=A\b where A can be rectangular; b overwritten with solution */ csi cs_qrsol (csi order, const cs *A, double *b) { double *x ; css *S ; csn *N ; cs *AT = NULL ; csi k, m, n, ok ; if (!CS_CSC (A) || !b) return (0) ; /* check inputs */ n = A->n ; m = A->m ; if (m >= n) { S = cs_sqr (order, A, 1) ; /* ordering and symbolic analysis */ N = cs_qr (A, S) ; /* numeric QR factorization */ x = cs_calloc (S ? S->m2 : 1, sizeof (double)) ; /* get workspace */ ok = (S && N && x) ; if (ok) { cs_ipvec (S->pinv, b, x, m) ; /* x(0:m-1) = b(p(0:m-1) */ for (k = 0 ; k < n ; k++) /* apply Householder refl. to x */ { cs_happly (N->L, k, N->B [k], x) ; } cs_usolve (N->U, x) ; /* x = R\x */ cs_ipvec (S->q, x, b, n) ; /* b(q(0:n-1)) = x(0:n-1) */ } } else { AT = cs_transpose (A, 1) ; /* Ax=b is underdetermined */ S = cs_sqr (order, AT, 1) ; /* ordering and symbolic analysis */ N = cs_qr (AT, S) ; /* numeric QR factorization of A' */ x = cs_calloc (S ? S->m2 : 1, sizeof (double)) ; /* get workspace */ ok = (AT && S && N && x) ; if (ok) { cs_pvec (S->q, b, x, m) ; /* x(q(0:m-1)) = b(0:m-1) */ cs_utsolve (N->U, x) ; /* x = R'\x */ for (k = m-1 ; k >= 0 ; k--) /* apply Householder refl. to x */ { cs_happly (N->L, k, N->B [k], x) ; } cs_pvec (S->pinv, x, b, n) ; /* b(0:n-1) = x(p(0:n-1)) */ } } cs_free (x) ; cs_sfree (S) ; cs_nfree (N) ; cs_spfree (AT) ; return (ok) ; } /* return a random permutation vector, the identity perm, or p = n-1:-1:0. * seed = -1 means p = n-1:-1:0. seed = 0 means p = identity. otherwise * p = random permutation. */ /* * NB: We use R's RNG *and* its state; i.e., if seed is not -1 or 0, * == 'seed' is *not* used at all in this version of cs_randperm() ! */ csi *cs_randperm (csi n, csi seed) { csi *p, k, j, t ; if (seed == 0) return (NULL) ; /* return p = NULL (identity) */ p = cs_malloc (n, sizeof (csi)) ; /* allocate result */ if (!p) return (NULL) ; /* out of memory */ for (k = 0 ; k < n ; k++) p [k] = n-k-1 ; if (seed == -1) return (p) ; /* return reverse permutation */ GetRNGstate();/* <- for R package Matrix srand (seed) ; .* get new random number seed */ for (k = 0 ; k < n ; k++) { j = k + (int)(unif_rand() * (n-k)); // j = rand integer in range k to n-1 t = p [j] ; /* swap p[k] and p[j] */ p [j] = p [k] ; p [k] = t ; } PutRNGstate(); // <- R package Matrix return (p) ; } /* xi [top...n-1] = nodes reachable from graph of G*P' via nodes in B(:,k). * xi [n...2n-1] used as workspace */ csi cs_reach (cs *G, const cs *B, csi k, csi *xi, const csi *pinv) { csi p, n, top, *Bp, *Bi, *Gp ; if (!CS_CSC (G) || !CS_CSC (B) || !xi) return (-1) ; /* check inputs */ n = G->n ; Bp = B->p ; Bi = B->i ; Gp = G->p ; top = n ; for (p = Bp [k] ; p < Bp [k+1] ; p++) { if (!CS_MARKED (Gp, Bi [p])) /* start a dfs at unmarked node i */ { top = cs_dfs (Bi [p], G, top, xi, xi+n, pinv) ; } } for (p = top ; p < n ; p++) CS_MARK (Gp, xi [p]) ; /* restore G */ return (top) ; } /* x = x + beta * A(:,j), where x is a dense vector and A(:,j) is sparse */ csi cs_scatter (const cs *A, csi j, double beta, csi *w, double *x, csi mark, cs *C, csi nz) { csi i, p, *Ap, *Ai, *Ci ; double *Ax ; if (!CS_CSC (A) || !w || !CS_CSC (C)) return (-1) ; /* check inputs */ Ap = A->p ; Ai = A->i ; Ax = A->x ; Ci = C->i ; for (p = Ap [j] ; p < Ap [j+1] ; p++) { i = Ai [p] ; /* A(i,j) is nonzero */ if (w [i] < mark) { w [i] = mark ; /* i is new entry in column j */ Ci [nz++] = i ; /* add i to pattern of C(:,j) */ if (x) x [i] = beta * Ax [p] ; /* x(i) = beta*A(i,j) */ } else if (x) x [i] += beta * Ax [p] ; /* i exists in C(:,j) already */ } return (nz) ; } /* find the strongly connected components of a square matrix */ csd *cs_scc (cs *A) /* matrix A temporarily modified, then restored */ { csi n, i, k, b, nb = 0, top, *xi, *pstack, *p, *r, *Ap, *ATp, *rcopy, *Blk ; cs *AT ; csd *D ; if (!CS_CSC (A)) return (NULL) ; /* check inputs */ n = A->n ; Ap = A->p ; D = cs_dalloc (n, 0) ; /* allocate result */ AT = cs_transpose (A, 0) ; /* AT = A' */ xi = cs_malloc (2*n+1, sizeof (csi)) ; /* get workspace */ if (!D || !AT || !xi) return (cs_ddone (D, AT, xi, 0)) ; Blk = xi ; rcopy = pstack = xi + n ; p = D->p ; r = D->r ; ATp = AT->p ; top = n ; for (i = 0 ; i < n ; i++) /* first dfs(A) to find finish times (xi) */ { if (!CS_MARKED (Ap, i)) top = cs_dfs (i, A, top, xi, pstack, NULL) ; } for (i = 0 ; i < n ; i++) CS_MARK (Ap, i) ; /* restore A; unmark all nodes*/ top = n ; nb = n ; for (k = 0 ; k < n ; k++) /* dfs(A') to find strongly connnected comp */ { i = xi [k] ; /* get i in reverse order of finish times */ if (CS_MARKED (ATp, i)) continue ; /* skip node i if already ordered */ r [nb--] = top ; /* node i is the start of a component in p */ top = cs_dfs (i, AT, top, p, pstack, NULL) ; } r [nb] = 0 ; /* first block starts at zero; shift r up */ for (k = nb ; k <= n ; k++) r [k-nb] = r [k] ; D->nb = nb = n-nb ; /* nb = # of strongly connected components */ for (b = 0 ; b < nb ; b++) /* sort each block in natural order */ { for (k = r [b] ; k < r [b+1] ; k++) Blk [p [k]] = b ; } for (b = 0 ; b <= nb ; b++) rcopy [b] = r [b] ; for (i = 0 ; i < n ; i++) p [rcopy [Blk [i]]++] = i ; return (cs_ddone (D, AT, xi, 1)) ; } /* ordering and symbolic analysis for a Cholesky factorization */ css *cs_schol (csi order, const cs *A) { csi n, *c, *post, *P ; cs *C ; css *S ; if (!CS_CSC (A)) return (NULL) ; /* check inputs */ n = A->n ; S = cs_calloc (1, sizeof (css)) ; /* allocate result S */ if (!S) return (NULL) ; /* out of memory */ P = cs_amd (order, A) ; /* P = amd(A+A'), or natural */ S->pinv = cs_pinv (P, n) ; /* find inverse permutation */ cs_free (P) ; if (order && !S->pinv) return (cs_sfree (S)) ; C = cs_symperm (A, S->pinv, 0) ; /* C = spones(triu(A(P,P))) */ S->parent = cs_etree (C, 0) ; /* find etree of C */ post = cs_post (S->parent, n) ; /* postorder the etree */ c = cs_counts (C, S->parent, post, 0) ; /* find column counts of chol(C) */ cs_free (post) ; cs_spfree (C) ; S->cp = cs_malloc (n+1, sizeof (csi)) ; /* allocate result S->cp */ S->unz = S->lnz = cs_cumsum (S->cp, c, n) ; /* find column pointers for L */ cs_free (c) ; return ((S->lnz >= 0) ? S : cs_sfree (S)) ; } /* solve Gx=b(:,k), where G is either upper (lo=0) or lower (lo=1) triangular */ csi cs_spsolve (cs *G, const cs *B, csi k, csi *xi, double *x, const csi *pinv, csi lo) { csi j, J, p, q, px, top, n, *Gp, *Gi, *Bp, *Bi ; double *Gx, *Bx ; if (!CS_CSC (G) || !CS_CSC (B) || !xi || !x) return (-1) ; Gp = G->p ; Gi = G->i ; Gx = G->x ; n = G->n ; Bp = B->p ; Bi = B->i ; Bx = B->x ; top = cs_reach (G, B, k, xi, pinv) ; /* xi[top..n-1]=Reach(B(:,k)) */ for (p = top ; p < n ; p++) x [xi [p]] = 0 ; /* clear x */ for (p = Bp [k] ; p < Bp [k+1] ; p++) x [Bi [p]] = Bx [p] ; /* scatter B */ for (px = top ; px < n ; px++) { j = xi [px] ; /* x(j) is nonzero */ J = pinv ? (pinv [j]) : j ; /* j maps to col J of G */ if (J < 0) continue ; /* column J is empty */ x [j] /= Gx [lo ? (Gp [J]) : (Gp [J+1]-1)] ;/* x(j) /= G(j,j) */ p = lo ? (Gp [J]+1) : (Gp [J]) ; /* lo: L(j,j) 1st entry */ q = lo ? (Gp [J+1]) : (Gp [J+1]-1) ; /* up: U(j,j) last entry */ for ( ; p < q ; p++) { x [Gi [p]] -= Gx [p] * x [j] ; /* x(i) -= G(i,j) * x(j) */ } } return (top) ; /* return top of stack */ } /* compute nnz(V) = S->lnz, S->pinv, S->leftmost, S->m2 from A and S->parent */ static csi cs_vcount (const cs *A, css *S) { csi i, k, p, pa, n = A->n, m = A->m, *Ap = A->p, *Ai = A->i, *next, *head, *tail, *nque, *pinv, *leftmost, *w, *parent = S->parent ; S->pinv = pinv = cs_malloc (m+n, sizeof (csi)) ; /* allocate pinv, */ S->leftmost = leftmost = cs_malloc (m, sizeof (csi)) ; /* and leftmost */ w = cs_malloc (m+3*n, sizeof (csi)) ; /* get workspace */ if (!pinv || !w || !leftmost) { cs_free (w) ; /* pinv and leftmost freed later */ return (0) ; /* out of memory */ } next = w ; head = w + m ; tail = w + m + n ; nque = w + m + 2*n ; for (k = 0 ; k < n ; k++) head [k] = -1 ; /* queue k is empty */ for (k = 0 ; k < n ; k++) tail [k] = -1 ; for (k = 0 ; k < n ; k++) nque [k] = 0 ; for (i = 0 ; i < m ; i++) leftmost [i] = -1 ; for (k = n-1 ; k >= 0 ; k--) { for (p = Ap [k] ; p < Ap [k+1] ; p++) { leftmost [Ai [p]] = k ; /* leftmost[i] = min(find(A(i,:)))*/ } } for (i = m-1 ; i >= 0 ; i--) /* scan rows in reverse order */ { pinv [i] = -1 ; /* row i is not yet ordered */ k = leftmost [i] ; if (k == -1) continue ; /* row i is empty */ if (nque [k]++ == 0) tail [k] = i ; /* first row in queue k */ next [i] = head [k] ; /* put i at head of queue k */ head [k] = i ; } S->lnz = 0 ; S->m2 = m ; for (k = 0 ; k < n ; k++) /* find row permutation and nnz(V)*/ { i = head [k] ; /* remove row i from queue k */ S->lnz++ ; /* count V(k,k) as nonzero */ if (i < 0) i = S->m2++ ; /* add a fictitious row */ pinv [i] = k ; /* associate row i with V(:,k) */ if (--nque [k] <= 0) continue ; /* skip if V(k+1:m,k) is empty */ S->lnz += nque [k] ; /* nque [k] is nnz (V(k+1:m,k)) */ if ((pa = parent [k]) != -1) /* move all rows to parent of k */ { if (nque [pa] == 0) tail [pa] = tail [k] ; next [tail [k]] = head [pa] ; head [pa] = next [i] ; nque [pa] += nque [k] ; } } for (i = 0 ; i < m ; i++) if (pinv [i] < 0) pinv [i] = k++ ; cs_free (w) ; return (1) ; } /* symbolic ordering and analysis for QR or LU */ css *cs_sqr (csi order, const cs *A, csi qr) { csi n, k, ok = 1, *post ; css *S ; if (!CS_CSC (A)) return (NULL) ; /* check inputs */ n = A->n ; S = cs_calloc (1, sizeof (css)) ; /* allocate result S */ if (!S) return (NULL) ; /* out of memory */ S->q = cs_amd (order, A) ; /* fill-reducing ordering */ if (order && !S->q) return (cs_sfree (S)) ; if (qr) /* QR symbolic analysis */ { cs *C = order ? cs_permute (A, NULL, S->q, 0) : ((cs *) A) ; S->parent = cs_etree (C, 1) ; /* etree of C'*C, where C=A(:,q) */ post = cs_post (S->parent, n) ; S->cp = cs_counts (C, S->parent, post, 1) ; /* col counts chol(C'*C) */ cs_free (post) ; ok = C && S->parent && S->cp && cs_vcount (C, S) ; if (ok) for (S->unz = 0, k = 0 ; k < n ; k++) S->unz += S->cp [k] ; if (order) cs_spfree (C) ; } else { S->unz = 4*(A->p [n]) + n ; /* for LU factorization only, */ S->lnz = S->unz ; /* guess nnz(L) and nnz(U) */ } return (ok ? S : cs_sfree (S)) ; /* return result S */ } /* C = A(p,p) where A and C are symmetric the upper part stored; pinv not p */ cs *cs_symperm (const cs *A, const csi *pinv, csi values) { csi i, j, p, q, i2, j2, n, *Ap, *Ai, *Cp, *Ci, *w ; double *Cx, *Ax ; cs *C ; if (!CS_CSC (A)) return (NULL) ; /* check inputs */ n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; C = cs_spalloc (n, n, Ap [n], values && (Ax != NULL), 0) ; /* alloc result*/ w = cs_calloc (n, sizeof (csi)) ; /* get workspace */ if (!C || !w) return (cs_done (C, w, NULL, 0)) ; /* out of memory */ Cp = C->p ; Ci = C->i ; Cx = C->x ; for (j = 0 ; j < n ; j++) /* count entries in each column of C */ { j2 = pinv ? pinv [j] : j ; /* column j of A is column j2 of C */ for (p = Ap [j] ; p < Ap [j+1] ; p++) { i = Ai [p] ; if (i > j) continue ; /* skip lower triangular part of A */ i2 = pinv ? pinv [i] : i ; /* row i of A is row i2 of C */ w [CS_MAX (i2, j2)]++ ; /* column count of C */ } } cs_cumsum (Cp, w, n) ; /* compute column pointers of C */ for (j = 0 ; j < n ; j++) { j2 = pinv ? pinv [j] : j ; /* column j of A is column j2 of C */ for (p = Ap [j] ; p < Ap [j+1] ; p++) { i = Ai [p] ; if (i > j) continue ; /* skip lower triangular part of A*/ i2 = pinv ? pinv [i] : i ; /* row i of A is row i2 of C */ Ci [q = w [CS_MAX (i2, j2)]++] = CS_MIN (i2, j2) ; if (Cx) Cx [q] = Ax [p] ; } } return (cs_done (C, w, NULL, 1)) ; /* success; free workspace, return C */ } /* depth-first search and postorder of a tree rooted at node j */ csi cs_tdfs (csi j, csi k, csi *head, const csi *next, csi *post, csi *stack) { csi i, p, top = 0 ; if (!head || !next || !post || !stack) return (-1) ; /* check inputs */ stack [0] = j ; /* place j on the stack */ while (top >= 0) /* while (stack is not empty) */ { p = stack [top] ; /* p = top of stack */ i = head [p] ; /* i = youngest child of p */ if (i == -1) { top-- ; /* p has no unordered children left */ post [k++] = p ; /* node p is the kth postordered node */ } else { head [p] = next [i] ; /* remove i from children of p */ stack [++top] = i ; /* start dfs on child node i */ } } return (k) ; } /* C = A' */ cs *cs_transpose (const cs *A, csi values) { csi p, q, j, *Cp, *Ci, n, m, *Ap, *Ai, *w ; double *Cx, *Ax ; cs *C ; if (!CS_CSC (A)) return (NULL) ; /* check inputs */ m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; C = cs_spalloc (n, m, Ap [n], values && Ax, 0) ; /* allocate result */ w = cs_calloc (m, sizeof (csi)) ; /* get workspace */ if (!C || !w) return (cs_done (C, w, NULL, 0)) ; /* out of memory */ Cp = C->p ; Ci = C->i ; Cx = C->x ; for (p = 0 ; p < Ap [n] ; p++) w [Ai [p]]++ ; /* row counts */ cs_cumsum (Cp, w, m) ; /* row pointers */ for (j = 0 ; j < n ; j++) { for (p = Ap [j] ; p < Ap [j+1] ; p++) { Ci [q = w [Ai [p]]++] = j ; /* place A(i,j) as entry C(j,i) */ if (Cx) Cx [q] = Ax [p] ; } } return (cs_done (C, w, NULL, 1)) ; /* success; free w and return C */ } /* sparse Cholesky update/downdate, L*L' + sigma*w*w' (sigma = +1 or -1) */ csi cs_updown (cs *L, csi sigma, const cs *C, const csi *parent) { csi n, p, f, j, *Lp, *Li, *Cp, *Ci ; double *Lx, *Cx, alpha, beta = 1, delta, gamma, w1, w2, *w, beta2 = 1 ; if (!CS_CSC (L) || !CS_CSC (C) || !parent) return (0) ; /* check inputs */ Lp = L->p ; Li = L->i ; Lx = L->x ; n = L->n ; Cp = C->p ; Ci = C->i ; Cx = C->x ; if ((p = Cp [0]) >= Cp [1]) return (1) ; /* return if C empty */ w = cs_malloc (n, sizeof (double)) ; /* get workspace */ if (!w) return (0) ; /* out of memory */ f = Ci [p] ; for ( ; p < Cp [1] ; p++) f = CS_MIN (f, Ci [p]) ; /* f = min (find (C)) */ for (j = f ; j != -1 ; j = parent [j]) w [j] = 0 ; /* clear workspace w */ for (p = Cp [0] ; p < Cp [1] ; p++) w [Ci [p]] = Cx [p] ; /* w = C */ for (j = f ; j != -1 ; j = parent [j]) /* walk path f up to root */ { p = Lp [j] ; alpha = w [j] / Lx [p] ; /* alpha = w(j) / L(j,j) */ beta2 = beta*beta + sigma*alpha*alpha ; if (beta2 <= 0) break ; /* not positive definite */ beta2 = sqrt (beta2) ; delta = (sigma > 0) ? (beta / beta2) : (beta2 / beta) ; gamma = sigma * alpha / (beta2 * beta) ; Lx [p] = delta * Lx [p] + ((sigma > 0) ? (gamma * w [j]) : 0) ; beta = beta2 ; for (p++ ; p < Lp [j+1] ; p++) { w1 = w [Li [p]] ; w [Li [p]] = w2 = w1 - alpha * Lx [p] ; Lx [p] = delta * Lx [p] + gamma * ((sigma > 0) ? w1 : w2) ; } } cs_free (w) ; return (beta2 > 0) ; } /* solve Ux=b where x and b are dense. x=b on input, solution on output. */ csi cs_usolve (const cs *U, double *x) { csi p, j, n, *Up, *Ui ; double *Ux ; if (!CS_CSC (U) || !x) return (0) ; /* check inputs */ n = U->n ; Up = U->p ; Ui = U->i ; Ux = U->x ; for (j = n-1 ; j >= 0 ; j--) { x [j] /= Ux [Up [j+1]-1] ; for (p = Up [j] ; p < Up [j+1]-1 ; p++) { x [Ui [p]] -= Ux [p] * x [j] ; } } return (1) ; } /* allocate a sparse matrix (triplet form or compressed-column form) */ cs *cs_spalloc (csi m, csi n, csi nzmax, csi values, csi triplet) { cs *A = cs_calloc (1, sizeof (cs)) ; /* allocate the cs struct */ if (!A) return (NULL) ; /* out of memory */ A->m = m ; /* define dimensions and nzmax */ A->n = n ; A->nzmax = nzmax = CS_MAX (nzmax, 1) ; A->nz = triplet ? 0 : -1 ; /* allocate triplet or comp.col */ A->p = cs_malloc (triplet ? nzmax : n+1, sizeof (csi)) ; A->i = cs_malloc (nzmax, sizeof (csi)) ; A->x = values ? cs_malloc (nzmax, sizeof (double)) : NULL ; return ((!A->p || !A->i || (values && !A->x)) ? cs_spfree (A) : A) ; } /* change the max # of entries sparse matrix */ csi cs_sprealloc (cs *A, csi nzmax) { csi ok, oki, okj = 1, okx = 1 ; if (!A) return (0) ; if (nzmax <= 0) nzmax = (CS_CSC (A)) ? (A->p [A->n]) : A->nz ; nzmax = CS_MAX (nzmax, 1) ; A->i = cs_realloc (A->i, nzmax, sizeof (csi), &oki) ; if (CS_TRIPLET (A)) A->p = cs_realloc (A->p, nzmax, sizeof (csi), &okj) ; if (A->x) A->x = cs_realloc (A->x, nzmax, sizeof (double), &okx) ; ok = (oki && okj && okx) ; if (ok) A->nzmax = nzmax ; return (ok) ; } /* free a sparse matrix */ cs *cs_spfree (cs *A) { if (!A) return (NULL) ; /* do nothing if A already NULL */ cs_free (A->p) ; cs_free (A->i) ; cs_free (A->x) ; return ((cs *) cs_free (A)) ; /* free the cs struct and return NULL */ } /* free a numeric factorization */ csn *cs_nfree (csn *N) { if (!N) return (NULL) ; /* do nothing if N already NULL */ cs_spfree (N->L) ; cs_spfree (N->U) ; cs_free (N->pinv) ; cs_free (N->B) ; return ((csn *) cs_free (N)) ; /* free the csn struct and return NULL */ } /* free a symbolic factorization */ css *cs_sfree (css *S) { if (!S) return (NULL) ; /* do nothing if S already NULL */ cs_free (S->pinv) ; cs_free (S->q) ; cs_free (S->parent) ; cs_free (S->cp) ; cs_free (S->leftmost) ; return ((css *) cs_free (S)) ; /* free the css struct and return NULL */ } /* allocate a cs_dmperm or cs_scc result */ csd *cs_dalloc (csi m, csi n) { csd *D ; D = cs_calloc (1, sizeof (csd)) ; if (!D) return (NULL) ; D->p = cs_malloc (m, sizeof (csi)) ; D->r = cs_malloc (m+6, sizeof (csi)) ; D->q = cs_malloc (n, sizeof (csi)) ; D->s = cs_malloc (n+6, sizeof (csi)) ; return ((!D->p || !D->r || !D->q || !D->s) ? cs_dfree (D) : D) ; } /* free a cs_dmperm or cs_scc result */ csd *cs_dfree (csd *D) { if (!D) return (NULL) ; /* do nothing if D already NULL */ cs_free (D->p) ; cs_free (D->q) ; cs_free (D->r) ; cs_free (D->s) ; return ((csd *) cs_free (D)) ; /* free the csd struct and return NULL */ } /* free workspace and return a sparse matrix result */ cs *cs_done (cs *C, void *w, void *x, csi ok) { cs_free (w) ; /* free workspace */ cs_free (x) ; return (ok ? C : cs_spfree (C)) ; /* return result if OK, else free it */ } /* free workspace and return csi array result */ csi *cs_idone (csi *p, cs *C, void *w, csi ok) { cs_spfree (C) ; /* free temporary matrix */ cs_free (w) ; /* free workspace */ return (ok ? p : (csi *) cs_free (p)) ; /* return result, or free it */ } /* free workspace and return a numeric factorization (Cholesky, LU, or QR) */ csn *cs_ndone (csn *N, cs *C, void *w, void *x, csi ok) { cs_spfree (C) ; /* free temporary matrix */ cs_free (w) ; /* free workspace */ cs_free (x) ; return (ok ? N : cs_nfree (N)) ; /* return result if OK, else free it */ } /* free workspace and return a csd result */ csd *cs_ddone (csd *D, cs *C, void *w, csi ok) { cs_spfree (C) ; /* free temporary matrix */ cs_free (w) ; /* free workspace */ return (ok ? D : cs_dfree (D)) ; /* return result if OK, else free it */ } /* solve U'x=b where x and b are dense. x=b on input, solution on output. */ csi cs_utsolve (const cs *U, double *x) { csi p, j, n, *Up, *Ui ; double *Ux ; if (!CS_CSC (U) || !x) return (0) ; /* check inputs */ n = U->n ; Up = U->p ; Ui = U->i ; Ux = U->x ; for (j = 0 ; j < n ; j++) { for (p = Up [j] ; p < Up [j+1]-1 ; p++) { x [j] -= Ux [p] * x [Ui [p]] ; } x [j] /= Ux [Up [j+1]-1] ; } return (1) ; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/Syms.h�����������������������������������������������������������������������������������0000644�0001762�0000144�00000000521�14505616476�013425� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������SEXP Matrix_DimNamesSym, Matrix_DimSym, Matrix_LSym, Matrix_QSym, Matrix_RSym, Matrix_TSym, Matrix_USym, Matrix_VSym, Matrix_betaSym, Matrix_diagSym, Matrix_factorsSym, Matrix_iSym, Matrix_jSym, Matrix_lengthSym, Matrix_marginSym, Matrix_pSym, Matrix_permSym, Matrix_qSym, Matrix_sdSym, Matrix_uploSym, Matrix_xSym; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/Matrix-win.def���������������������������������������������������������������������������0000644�0001762�0000144�00000000052�14510016544�015021� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������LIBRARY Matrix.dll EXPORTS R_init_Matrix ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/attrib.c���������������������������������������������������������������������������������0000644�0001762�0000144�00000012624�14512321002�013731� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "Mdefines.h" #include "attrib.h" /* .... Dimnames .................................................... */ int DimNames_is_trivial(SEXP dn) { return isNull(VECTOR_ELT(dn, 0)) && isNull(VECTOR_ELT(dn, 1)) && isNull(getAttrib(dn, R_NamesSymbol)); } int DimNames_is_symmetric(SEXP dn) { SEXP rn, cn, ndn; const char *nrn, *ncn; int n; return !((!isNull(rn = VECTOR_ELT(dn, 0)) && !isNull(cn = VECTOR_ELT(dn, 1)) && rn != cn && ((n = LENGTH(rn)) != LENGTH(cn) || !equal_character_vectors(rn, cn, n))) || ((!isNull(ndn = getAttrib(dn, R_NamesSymbol)) && *(nrn = CHAR(STRING_ELT(ndn, 0))) != '\0' && *(ncn = CHAR(STRING_ELT(ndn, 1))) != '\0' && strcmp(nrn, ncn) != 0))); } SEXP R_DimNames_is_symmetric(SEXP dn) { return ScalarLogical(DimNames_is_symmetric(dn)); } void symDN(SEXP dest, SEXP src, int J /* -1|0|1 */) { SEXP s; if (J < 0) { if (!isNull(s = VECTOR_ELT(src, J = 1)) || !isNull(s = VECTOR_ELT(src, J = 0))) { SET_VECTOR_ELT(dest, 0, s); SET_VECTOR_ELT(dest, 1, s); } else { J = 1; } } else { if (!isNull(s = VECTOR_ELT(src, J))) { SET_VECTOR_ELT(dest, 0, s); SET_VECTOR_ELT(dest, 1, s); } } PROTECT(s = getAttrib(src, R_NamesSymbol)); if (!isNull(s)) { SEXP destnms = PROTECT(allocVector(STRSXP, 2)); if (*CHAR(s = STRING_ELT(s, J)) != '\0') { SET_STRING_ELT(destnms, 0, s); SET_STRING_ELT(destnms, 1, s); } setAttrib(dest, R_NamesSymbol, destnms); UNPROTECT(1); } UNPROTECT(1); return; } void revDN(SEXP dest, SEXP src) { SEXP s; if (!isNull(s = VECTOR_ELT(src, 0))) SET_VECTOR_ELT(dest, 1, s); if (!isNull(s = VECTOR_ELT(src, 1))) SET_VECTOR_ELT(dest, 0, s); PROTECT(s = getAttrib(src, R_NamesSymbol)); if (!isNull(s)) { SEXP srcnms = s, destnms = PROTECT(allocVector(STRSXP, 2)); if (*CHAR(s = STRING_ELT(srcnms, 0)) != '\0') SET_STRING_ELT(destnms, 1, s); if (*CHAR(s = STRING_ELT(srcnms, 1)) != '\0') SET_STRING_ELT(destnms, 0, s); setAttrib(dest, R_NamesSymbol, destnms); UNPROTECT(1); } UNPROTECT(1); return; } SEXP R_symDN(SEXP dn) { if (DimNames_is_trivial(dn)) return dn; SEXP newdn = PROTECT(allocVector(VECSXP, 2)); symDN(newdn, dn, -1); UNPROTECT(1); return newdn; } SEXP R_revDN(SEXP dn) { if (DimNames_is_trivial(dn)) return dn; SEXP newdn = PROTECT(allocVector(VECSXP, 2)); revDN(newdn, dn); UNPROTECT(1); return newdn; } SEXP get_symmetrized_DimNames(SEXP obj, int J) { SEXP dn = PROTECT(GET_SLOT(obj, Matrix_DimNamesSym)); if (DimNames_is_trivial(dn)) { UNPROTECT(1); return dn; } SEXP newdn = PROTECT(allocVector(VECSXP, 2)); symDN(newdn, dn, J); UNPROTECT(2); return newdn; } SEXP get_reversed_DimNames(SEXP obj) { SEXP dn = PROTECT(GET_SLOT(obj, Matrix_DimNamesSym)); if (DimNames_is_trivial(dn)) { UNPROTECT(1); return dn; } SEXP newdn = PROTECT(allocVector(VECSXP, 2)); revDN(newdn, dn); UNPROTECT(2); return newdn; } void set_symmetrized_DimNames(SEXP obj, SEXP dn, int J) { if (!DimNames_is_trivial(dn)) { SEXP newdn = PROTECT(allocVector(VECSXP, 2)); symDN(newdn, dn, J); SET_SLOT(obj, Matrix_DimNamesSym, newdn); UNPROTECT(1); } return; } void set_reversed_DimNames(SEXP obj, SEXP dn) { if (!DimNames_is_trivial(dn)) { SEXP newdn = PROTECT(allocVector(VECSXP, 2)); revDN(newdn, dn); SET_SLOT(obj, Matrix_DimNamesSym, newdn); UNPROTECT(1); } return; } /* .... factors ..................................................... */ static int strmatch(const char *x, SEXP valid) { int i, n = LENGTH(valid); for (i = 0; i < n; ++i) if (strcmp(x, CHAR(STRING_ELT(valid, i))) == 0) return i; return -1; } static SEXP append_to_named_list(SEXP x, const char *nm, SEXP val) { PROTECT(val); R_xlen_t n = XLENGTH(x); SEXP y = PROTECT(allocVector(VECSXP, n + 1)), ny = PROTECT(allocVector(STRSXP, n + 1)), nval = PROTECT(mkChar(nm)); if (n > 0) { SEXP nx = PROTECT(getAttrib(x, R_NamesSymbol)); R_xlen_t i; for (i = 0; i < n; ++i) { SET_VECTOR_ELT( y, i, VECTOR_ELT( x, i)); SET_STRING_ELT(ny, i, STRING_ELT(nx, i)); } UNPROTECT(1); } SET_VECTOR_ELT( y, n, val); SET_STRING_ELT(ny, n, nval); setAttrib(y, R_NamesSymbol, ny); UNPROTECT(4); return y; } SEXP get_factor(SEXP obj, const char *nm) { SEXP factors = PROTECT(GET_SLOT(obj, Matrix_factorsSym)), val = R_NilValue; if (LENGTH(factors) > 0) { SEXP valid = PROTECT(getAttrib(factors, R_NamesSymbol)); int i = strmatch(nm, valid); if (i >= 0) val = VECTOR_ELT(factors, i); UNPROTECT(1); } UNPROTECT(1); return val; } void set_factor(SEXP obj, const char *nm, SEXP val) { PROTECT(val); SEXP factors; PROTECT_INDEX pid; PROTECT_WITH_INDEX(factors = GET_SLOT(obj, Matrix_factorsSym), &pid); if (LENGTH(factors) > 0) { SEXP valid = PROTECT(getAttrib(factors, R_NamesSymbol)); int i = strmatch(nm, valid); UNPROTECT(1); if (i >= 0) { SET_VECTOR_ELT(factors, i, val); UNPROTECT(2); return; } } REPROTECT(factors = append_to_named_list(factors, nm, val), pid); SET_SLOT(obj, Matrix_factorsSym, factors); UNPROTECT(2); return; } SEXP R_set_factor(SEXP obj, SEXP nm, SEXP val, SEXP warn) { if (TYPEOF(nm) != STRSXP || LENGTH(nm) < 1 || (nm = STRING_ELT(nm, 0)) == NA_STRING) error(_("invalid factor name")); else if (TYPEOF(getAttrib(obj, Matrix_factorsSym)) == VECSXP) set_factor(obj, CHAR(nm), val); else if (asLogical(warn) != 0) warning(_("attempt to set factor on %s without '%s' slot"), "Matrix", "factors"); return val; } ������������������������������������������������������������������������������������������������������������Matrix/src/subscript.c������������������������������������������������������������������������������0000644�0001762�0000144�00000145213�14503225712�014476� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "Mdefines.h" #include "subscript.h" #define F_X( _X_) (_X_) #define F_ND(_X_) ((_X_) ? 1 : 0) #define F_NS(_X_) 1 #define AR21_UP(i, j, m) i + j + ( j * ( j - 1)) / 2 #define AR21_LO(i, j, m) i + (j * m + j * (m - j - 1)) / 2 static SEXP unpackedMatrix_subscript_1ary(SEXP x, SEXP w, const char *cl) { #define SUB1_START(_SEXPTYPE_) \ SEXPTYPE typ = _SEXPTYPE_; \ R_xlen_t l = 0, len = XLENGTH(w); \ SEXP res = allocVector(typ, len); \ if (len == 0) \ return res; \ PROTECT(res); \ \ SEXP dim = PROTECT(GET_SLOT(x, Matrix_DimSym)); \ int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; \ Matrix_int_fast64_t mn64 = (Matrix_int_fast64_t) m * n; \ UNPROTECT(1); #define SUB1_START_EXTRA(_SEXPTYPE_) \ SUB1_START(_SEXPTYPE_); \ \ int ge = cl[1] == 'g', tr = cl[1] == 't', upper = 1, nonunit = 1; \ if (!ge) { \ SEXP uplo = PROTECT(GET_SLOT(x, Matrix_uploSym)); \ upper = *CHAR(STRING_ELT(uplo, 0)) == 'U'; \ UNPROTECT(1); \ if (tr) { \ SEXP diag = PROTECT(GET_SLOT(x, Matrix_diagSym)); \ nonunit = *CHAR(STRING_ELT(diag, 0)) == 'N'; \ UNPROTECT(1); \ } \ } SUB1_START_EXTRA(kindToType(cl[0])); #define SUB1_CASES(_SUB1_N_, _SUB1_X_, _F_N_, _F_X_) \ do { \ switch (cl[0]) { \ case 'n': \ _SUB1_N_(int, LOGICAL, NA_LOGICAL, 0, 1, _F_N_); \ break; \ case 'l': \ _SUB1_X_(int, LOGICAL, NA_LOGICAL, 0, 1, _F_X_); \ break; \ case 'i': \ _SUB1_X_(int, INTEGER, NA_INTEGER, 0, 1, _F_X_); \ break; \ case 'd': \ _SUB1_X_(double, REAL, NA_REAL, 0.0, 1.0, _F_X_); \ break; \ case 'z': \ _SUB1_X_(Rcomplex, COMPLEX, \ Matrix_zna, Matrix_zzero, Matrix_zone, _F_X_); \ break; \ default: \ break; \ } \ } while (0) #define SUB1_N(_CTYPE_, _PTR_, _NA_, _ZERO_, _ONE_, _F_) \ do { \ _CTYPE_ *pres = _PTR_(res); \ if (TYPEOF(w) == INTSXP) { \ int *pw = INTEGER(w); \ if (mn64 >= INT_MAX) { \ /* index is never out of bounds */ \ SUB1_LOOP((pw[l] == NA_INTEGER), \ _NA_, _ZERO_, _ONE_, _F_, Matrix_int_fast64_t); \ } else { \ int mn = m * n; \ SUB1_LOOP((pw[l] == NA_INTEGER || pw[l] > mn), \ _NA_, _ZERO_, _ONE_, _F_, int); \ } \ } else { \ double *pw = REAL(w); \ if (mn64 >= 0x1.0p+53) \ /* m*n may not be exactly representable as double */ \ /* but it does not exceed INT_MAX * INT_MAX */ \ SUB1_LOOP((ISNAN(pw[l]) || pw[l] >= 0x1.0p+62 || \ (Matrix_int_fast64_t) pw[l] > mn64), \ _NA_, _ZERO_, _ONE_, _F_, Matrix_int_fast64_t); \ else { \ double mn1a = (double) m * n + 1.0; \ SUB1_LOOP((ISNAN(pw[l]) || pw[l] >= mn1a), \ _NA_, _ZERO_, _ONE_, _F_, Matrix_int_fast64_t); \ } \ } \ } while (0) #define SUB1_X(_CTYPE_, _PTR_, _NA_, _ZERO_, _ONE_, _F_) \ do { \ PROTECT(x = GET_SLOT(x, Matrix_xSym)); \ _CTYPE_ *px = _PTR_(x); \ SUB1_N(_CTYPE_, _PTR_, _NA_, _ZERO_, _ONE_, _F_); \ UNPROTECT(1); \ } while (0) #define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_, _INT_) \ do { \ _INT_ index, i_, j_; \ for (l = 0; l < len; ++l) { \ if (_NA_SUBSCRIPT_) \ pres[l] = _NA_; \ else { \ index = (_INT_) pw[l] - 1; \ if (ge) \ pres[l] = _F_(px[index]); \ else { \ i_ = index % m; \ j_ = index / m; \ if (tr) { \ if ((upper) ? i_ > j_ : i_ < j_) \ pres[l] = _ZERO_; \ else if (!nonunit && i_ == j_) \ pres[l] = _ONE_; \ else \ pres[l] = _F_(px[index]); \ } else { \ if ((upper) ? i_ > j_ : i_ < j_) \ pres[l] = _F_(px[i_ * m + j_]); \ else \ pres[l] = _F_(px[index]); \ } \ } \ } \ } \ } while (0) SUB1_CASES(SUB1_X, SUB1_X, F_ND, F_X); #undef SUB1_LOOP UNPROTECT(1); return res; } static SEXP packedMatrix_subscript_1ary(SEXP x, SEXP w, const char *cl) { SUB1_START_EXTRA(kindToType(cl[0])); #define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_, _INT_) \ do { \ _INT_ index, i_, j_; \ for (l = 0; l < len; ++l) { \ if (_NA_SUBSCRIPT_) \ pres[l] = _NA_; \ else { \ index = (_INT_) pw[l] - 1; \ i_ = index % m; \ j_ = index / m; \ if (tr) { \ if (upper) { \ if (i_ > j_) \ pres[l] = _ZERO_; \ else if (!nonunit && i_ == j_) \ pres[l] = _ONE_; \ else \ pres[l] = _F_(px[AR21_UP(i_, j_, m)]); \ } else { \ if (i_ < j_) \ pres[l] = _ZERO_; \ else if (!nonunit && i_ == j_) \ pres[l] = _ONE_; \ else \ pres[l] = _F_(px[AR21_LO(i_, j_, m)]); \ } \ } else { \ if (upper) { \ if (i_ > j_) \ pres[l] = _F_(px[AR21_UP(j_, i_, m)]); \ else \ pres[l] = _F_(px[AR21_UP(i_, j_, m)]); \ } else { \ if (i_ < j_) \ pres[l] = _F_(px[AR21_LO(j_, i_, m)]); \ else \ pres[l] = _F_(px[AR21_LO(i_, j_, m)]); \ } \ } \ } \ } \ } while (0) SUB1_CASES(SUB1_X, SUB1_X, F_ND, F_X); #undef SUB1_LOOP UNPROTECT(1); return res; } static SEXP CsparseMatrix_subscript_1ary(SEXP x, SEXP w, const char *cl) { SUB1_START(kindToType(cl[0])); SEXP p = PROTECT(GET_SLOT(x, Matrix_pSym)), i = PROTECT(GET_SLOT(x, Matrix_iSym)); int *pp = INTEGER(p), *pi = INTEGER(i), i_, j_, j, k = 0, kend; #define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_, _INT_) \ do { \ _INT_ index; \ if (_NA_SUBSCRIPT_) \ j = -1; \ else { \ index = (_INT_) pw[l] - 1; \ i_ = (int) (index % m); \ j_ = j = (int) (index / m); \ } \ while (j >= 0) { \ k = pp[j]; \ kend = pp[j + 1]; \ while (k < kend && j_ == j) { \ if (pi[k] < i_) \ ++k; \ else { \ if (pi[k] > i_) \ pres[l] = _ZERO_; \ else \ pres[l] = _F_(px[k]); \ ++l; \ if (l == len || _NA_SUBSCRIPT_) \ j_ = -1; \ else { \ index = (_INT_) pw[l] - 1; \ i_ = (int) (index % m); \ j_ = (int) (index / m); \ } \ } \ } \ while (j_ == j) { \ pres[l] = _ZERO_; \ ++l; \ if (l == len || _NA_SUBSCRIPT_) \ j_ = -1; \ else { \ index = (_INT_) pw[l] - 1; \ i_ = (int) (index % m); \ j_ = (int) (index / m); \ } \ } \ j = j_; \ } \ while (l < len) { \ pres[l] = _NA_; \ ++l; \ } \ } while (0) SUB1_CASES(SUB1_N, SUB1_X, F_NS, F_X); #undef SUB1_LOOP UNPROTECT(3); return res; } static SEXP RsparseMatrix_subscript_1ary(SEXP x, SEXP w, const char *cl) { SUB1_START(kindToType(cl[0])); SEXP p = PROTECT(GET_SLOT(x, Matrix_pSym)), j = PROTECT(GET_SLOT(x, Matrix_jSym)); int *pp = INTEGER(p), *pj = INTEGER(j), i, i_, j_, k = 0, kend; #define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_, _INT_) \ do { \ _INT_ index; \ if (_NA_SUBSCRIPT_) \ i = -1; \ else { \ index = (_INT_) pw[l] - 1; \ i_ = i = (int) (index % m); \ j_ = (int) (index / m); \ } \ while (i >= 0) { \ k = pp[i]; \ kend = pp[i + 1]; \ while (k < kend && i_ == i) { \ if (pj[k] < j_) \ ++k; \ else { \ if (pj[k] > j_) \ pres[l] = _ZERO_; \ else \ pres[l] = _F_(px[k]); \ ++l; \ if (l == len || _NA_SUBSCRIPT_) \ i_ = -1; \ else { \ index = (_INT_) pw[l] - 1; \ i_ = (int) (index % m); \ j_ = (int) (index / m); \ } \ } \ } \ while (i_ == i) { \ pres[l] = _ZERO_; \ ++l; \ if (l == len || _NA_SUBSCRIPT_) \ i_ = -1; \ else { \ index = (_INT_) pw[l] - 1; \ i_ = (int) (index % m); \ j_ = (int) (index / m); \ } \ } \ i = i_; \ } \ while (l < len) { \ pres[l] = _NA_; \ ++l; \ } \ } while (0) SUB1_CASES(SUB1_N, SUB1_X, F_NS, F_X); #undef SUB1_LOOP UNPROTECT(3); return res; } static SEXP diagonalMatrix_subscript_1ary(SEXP x, SEXP w, const char *cl) { SUB1_START(kindToType(cl[0])); SEXP diag = PROTECT(GET_SLOT(x, Matrix_diagSym)); int nonunit = *CHAR(STRING_ELT(diag, 0)) == 'N'; UNPROTECT(1); Matrix_int_fast64_t index, n1a = (Matrix_int_fast64_t) n + 1; #define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_, _INT_) \ do { \ for (l = 0; l < len; ++l) { \ if (_NA_SUBSCRIPT_) \ pres[l] = _NA_; \ else if ((index = (Matrix_int_fast64_t) pw[l] - 1) % n1a != 0) \ pres[l] = _ZERO_; \ else if (!nonunit) \ pres[l] = _ONE_; \ else \ pres[l] = _F_(px[index / n1a]); \ } \ } while (0) SUB1_CASES(SUB1_X, SUB1_X, F_ND, F_X); #undef SUB1_LOOP UNPROTECT(1); return res; } static SEXP indMatrix_subscript_1ary(SEXP x, SEXP w) { SUB1_START(LGLSXP); SEXP perm = PROTECT(GET_SLOT(x, Matrix_permSym)); int *pperm = INTEGER(perm), i_, j_; SEXP margin = PROTECT(GET_SLOT(x, Matrix_marginSym)); int mg = INTEGER(margin)[0] - 1; UNPROTECT(1); #define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_, _INT_) \ do { \ _INT_ index; \ for (l = 0; l < len; ++l) { \ if (_NA_SUBSCRIPT_) \ pres[l] = _NA_; \ else { \ index = (_INT_) pw[l] - 1; \ i_ = (int) (index % m); \ j_ = (int) (index / m); \ if (!mg) \ pres[l] = j_ == pperm[i_] - 1; \ else \ pres[l] = i_ == pperm[j_] - 1; \ } \ } \ } while (0) SUB1_N(int, LOGICAL, NA_LOGICAL, 0, 1, ); #undef SUB1_LOOP #undef SUB1_N #undef SUB1_START #undef SUB1_START_EXTRA UNPROTECT(2); return res; } /* x[i] with 'i' of type "integer" or "double" {i >= 1 or NA} */ SEXP R_subscript_1ary(SEXP x, SEXP i) { static const char *valid[] = { VALID_NONVIRTUAL_MATRIX, "" }; int ivalid = R_check_class_etc(x, valid); if (ivalid < 0) ERROR_INVALID_CLASS(x, __func__); ivalid += VALID_NONVIRTUAL_SHIFT(ivalid, 1); const char *cl = valid[ivalid]; validObject(x, cl); switch (cl[2]) { case 'e': case 'y': case 'r': return unpackedMatrix_subscript_1ary(x, i, cl); case 'p': return packedMatrix_subscript_1ary(x, i, cl); /* NB: for [CRT], the caller must preprocess 'x' and 'i'; symmetric and unit triangular 'x' are not handled specially, and it is assumed for speed that 'i' is sorted by row [R] or column [CT] with NA last */ case 'C': return CsparseMatrix_subscript_1ary(x, i, cl); case 'R': return RsparseMatrix_subscript_1ary(x, i, cl); case 'T': { char cl_[] = "..CMatrix"; cl_[0] = cl[0]; cl_[1] = cl[1]; /* defined in ./coerce.c : */ SEXP sparse_as_Csparse(SEXP, const char *); x = sparse_as_Csparse(x, cl); PROTECT(x); x = CsparseMatrix_subscript_1ary(x, i, cl_); UNPROTECT(1); return x; } case 'i': return diagonalMatrix_subscript_1ary(x, i, cl); default: return indMatrix_subscript_1ary(x, i); } } static SEXP unpackedMatrix_subscript_1ary_mat(SEXP x, SEXP w, const char *cl) { #define SUB1_START(_SEXPTYPE_) \ SEXPTYPE typ = _SEXPTYPE_; \ int l = 0, len = (int) (XLENGTH(w) / 2); \ SEXP res = allocVector(typ, len); \ if (len == 0) \ return res; \ PROTECT(res); \ int *pw0 = INTEGER(w), *pw1 = pw0 + len; #define SUB1_START_EXTRA(_SEXPTYPE_) \ SUB1_START(_SEXPTYPE_); \ \ SEXP dim = PROTECT(GET_SLOT(x, Matrix_DimSym)); \ int m = INTEGER(dim)[0]; \ UNPROTECT(1); \ \ int ge = cl[1] == 'g', tr = cl[1] == 't', upper = 1, nonunit = 1; \ if (!ge) { \ SEXP uplo = PROTECT(GET_SLOT(x, Matrix_uploSym)); \ upper = *CHAR(STRING_ELT(uplo, 0)) == 'U'; \ UNPROTECT(1); \ if (tr) { \ SEXP diag = PROTECT(GET_SLOT(x, Matrix_diagSym)); \ nonunit = *CHAR(STRING_ELT(diag, 0)) == 'N'; \ UNPROTECT(1); \ } \ } SUB1_START_EXTRA(kindToType(cl[0])); Matrix_int_fast64_t i_, j_; #define SUB1_N(_CTYPE_, _PTR_, _NA_, _ZERO_, _ONE_, _F_) \ do { \ _CTYPE_ *pres = _PTR_(res); \ SUB1_LOOP((pw0[l] == NA_INTEGER || pw1[l] == NA_INTEGER), \ _NA_, _ZERO_, _ONE_, _F_); \ } while (0) #define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_) \ do { \ for (l = 0; l < len; ++l) { \ if (_NA_SUBSCRIPT_) \ pres[l] = _NA_; \ else { \ i_ = pw0[l] - 1; \ j_ = pw1[l] - 1; \ if (ge) \ pres[l] = _F_(px[j_ * m + i_]); \ else if (tr) { \ if ((upper) ? i_ > j_ : i_ < j_) \ pres[l] = _ZERO_; \ else if (!nonunit && i_ == j_) \ pres[l] = _ONE_; \ else \ pres[l] = _F_(px[j_ * m + i_]); \ } else { \ if ((upper) ? i_ > j_ : i_ < j_) \ pres[l] = _F_(px[i_ * m + j_]); \ else \ pres[l] = _F_(px[j_ * m + i_]); \ } \ } \ } \ } while (0) SUB1_CASES(SUB1_X, SUB1_X, F_ND, F_X); #undef SUB1_LOOP UNPROTECT(1); return res; } static SEXP packedMatrix_subscript_1ary_mat(SEXP x, SEXP w, const char *cl) { SUB1_START_EXTRA(kindToType(cl[0])); Matrix_int_fast64_t i_, j_; #define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_) \ do { \ for (l = 0; l < len; ++l) { \ if (_NA_SUBSCRIPT_) \ pres[l] = _NA_; \ else { \ i_ = pw0[l] - 1; \ j_ = pw1[l] - 1; \ if (tr) { \ if (upper) { \ if (i_ > j_) \ pres[l] = _ZERO_; \ else if (!nonunit && i_ == j_) \ pres[l] = _ONE_; \ else \ pres[l] = _F_(px[AR21_UP(i_, j_, m)]); \ } else { \ if (i_ < j_) \ pres[l] = _ZERO_; \ else if (!nonunit && i_ == j_) \ pres[l] = _ONE_; \ else \ pres[l] = _F_(px[AR21_LO(i_, j_, m)]); \ } \ } else { \ if (upper) { \ if (i_ > j_) \ pres[l] = _F_(px[AR21_UP(j_, i_, m)]); \ else \ pres[l] = _F_(px[AR21_UP(i_, j_, m)]); \ } else { \ if (i_ < j_) \ pres[l] = _F_(px[AR21_LO(j_, i_, m)]); \ else \ pres[l] = _F_(px[AR21_LO(i_, j_, m)]); \ } \ } \ } \ } \ } while (0) SUB1_CASES(SUB1_X, SUB1_X, F_ND, F_X); #undef SUB1_LOOP UNPROTECT(1); return res; } static SEXP CsparseMatrix_subscript_1ary_mat(SEXP x, SEXP w, const char *cl) { SUB1_START(kindToType(cl[0])); SEXP p = PROTECT(GET_SLOT(x, Matrix_pSym)), i = PROTECT(GET_SLOT(x, Matrix_iSym)); int *pp = INTEGER(p), *pi = INTEGER(i), i_, j_, j, k = 0, kend; #define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_) \ do { \ if (_NA_SUBSCRIPT_) \ j = -1; \ else { \ i_ = pw0[l] - 1; \ j_ = j = pw1[l] - 1; \ } \ while (j >= 0) { \ k = pp[j]; \ kend = pp[j + 1]; \ while (k < kend && j_ == j) { \ if (pi[k] < i_) \ ++k; \ else { \ if (pi[k] > i_) \ pres[l] = _ZERO_; \ else \ pres[l] = _F_(px[k]); \ ++l; \ if (l == len || _NA_SUBSCRIPT_) \ j_ = -1; \ else { \ i_ = pw0[l] - 1; \ j_ = pw1[l] - 1; \ } \ } \ } \ while (j_ == j) { \ pres[l] = _ZERO_; \ ++l; \ if (l == len || _NA_SUBSCRIPT_) \ j_ = -1; \ else { \ i_ = pw0[l] - 1; \ j_ = pw1[l] - 1; \ } \ } \ j = j_; \ } \ while (l < len) { \ pres[l] = _NA_; \ ++l; \ } \ } while (0) SUB1_CASES(SUB1_N, SUB1_X, F_NS, F_X); #undef SUB1_LOOP UNPROTECT(3); return res; } static SEXP RsparseMatrix_subscript_1ary_mat(SEXP x, SEXP w, const char *cl) { SUB1_START(kindToType(cl[0])); SEXP p = PROTECT(GET_SLOT(x, Matrix_pSym)), j = PROTECT(GET_SLOT(x, Matrix_jSym)); int *pp = INTEGER(p), *pj = INTEGER(j), i, i_, j_, k = 0, kend; #define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_) \ do { \ if (_NA_SUBSCRIPT_) \ i = -1; \ else { \ i_ = i = pw0[l] - 1; \ j_ = pw1[l] - 1; \ } \ while (i >= 0) { \ k = pp[i]; \ kend = pp[i + 1]; \ while (k < kend && i_ == i) { \ if (pj[k] < j_) \ ++k; \ else { \ if (pj[k] > j_) \ pres[l] = _ZERO_; \ else \ pres[l] = _F_(px[k]); \ ++l; \ if (l == len || _NA_SUBSCRIPT_) \ i_ = -1; \ else { \ i_ = pw0[l] - 1; \ j_ = pw1[l] - 1; \ } \ } \ } \ while (i_ == i) { \ pres[l] = _ZERO_; \ ++l; \ if (l == len || _NA_SUBSCRIPT_) \ i_ = -1; \ else { \ i_ = pw0[l] - 1; \ j_ = pw1[l] - 1; \ } \ } \ i = i_; \ } \ while (l < len) { \ pres[l] = _NA_; \ ++l; \ } \ } while (0) SUB1_CASES(SUB1_N, SUB1_X, F_NS, F_X); #undef SUB1_LOOP UNPROTECT(3); return res; } static SEXP diagonalMatrix_subscript_1ary_mat(SEXP x, SEXP w, const char *cl) { SUB1_START(kindToType(cl[0])); SEXP diag = PROTECT(GET_SLOT(x, Matrix_diagSym)); int nonunit = *CHAR(STRING_ELT(diag, 0)) == 'N'; UNPROTECT(1); #define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_) \ do { \ for (l = 0; l < len; ++l) { \ if (_NA_SUBSCRIPT_) \ pres[l] = _NA_; \ else if (pw0[l] != pw1[l]) \ pres[l] = _ZERO_; \ else if (!nonunit) \ pres[l] = _ONE_; \ else \ pres[l] = _F_(px[pw0[l] - 1]); \ } \ } while (0) SUB1_CASES(SUB1_X, SUB1_X, F_ND, F_X); #undef SUB1_LOOP UNPROTECT(1); return res; } static SEXP indMatrix_subscript_1ary_mat(SEXP x, SEXP w) { SUB1_START(LGLSXP); SEXP perm = PROTECT(GET_SLOT(x, Matrix_permSym)); int *pperm = INTEGER(perm); SEXP margin = PROTECT(GET_SLOT(x, Matrix_marginSym)); int mg = INTEGER(margin)[0] - 1; UNPROTECT(1); #define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_) \ do { \ for (l = 0; l < len; ++l) { \ if (_NA_SUBSCRIPT_) \ pres[l] = _NA_; \ else if (!mg) \ pres[l] = pw1[l] == pperm[pw0[l] - 1]; \ else \ pres[l] = pw0[l] == pperm[pw1[l] - 1]; \ } \ } while (0) SUB1_N(int, LOGICAL, NA_LOGICAL, 0, 1, ); #undef SUB1_LOOP #undef SUB1_N #undef SUB1_X #undef SUB1_CASES #undef SUB1_START #undef SUB1_START_EXTRA UNPROTECT(2); return res; } /* x[i] with 'i' of type "integer" and dimensions c(.,2) {i[,1] in 1:m or NA, i[,2] in 1:n or NA} */ SEXP R_subscript_1ary_mat(SEXP x, SEXP i) { static const char *valid[] = { VALID_NONVIRTUAL_MATRIX, "" }; int ivalid = R_check_class_etc(x, valid); if (ivalid < 0) ERROR_INVALID_CLASS(x, __func__); ivalid += VALID_NONVIRTUAL_SHIFT(ivalid, 1); const char *cl = valid[ivalid]; validObject(x, cl); switch (cl[2]) { case 'e': case 'y': case 'r': return unpackedMatrix_subscript_1ary_mat(x, i, cl); case 'p': return packedMatrix_subscript_1ary_mat(x, i, cl); /* NB: for [CRT], the caller must preprocess 'x' and 'i'; symmetric and unit triangular 'x' are not handled specially, and it is assumed for speed that 'i' is sorted by row [R] or column [CT] with NA (incl. out-of-bounds indices) last */ case 'C': return CsparseMatrix_subscript_1ary_mat(x, i, cl); case 'R': return RsparseMatrix_subscript_1ary_mat(x, i, cl); case 'T': { char cl_[] = "..CMatrix"; cl_[0] = cl[0]; cl_[1] = cl[1]; /* defined in ./coerce.c : */ SEXP sparse_as_Csparse(SEXP, const char *); x = sparse_as_Csparse(x, cl); PROTECT(x); x = CsparseMatrix_subscript_1ary_mat(x, i, cl_); UNPROTECT(1); return x; } case 'i': return diagonalMatrix_subscript_1ary_mat(x, i, cl); default: return indMatrix_subscript_1ary_mat(x, i); } } static int keep_tr(int *pi, int *pj, int n, int upper, int nonunit, int checkNA) { int k, ident = memcmp(pi, pj, n * sizeof(int)) == 0; if (checkNA) { if (ident) { for (k = 0; k < n; ++k) if (pi[k] == NA_INTEGER) return 0; } else { for (k = 0; k < n; ++k) if (pi[k] == NA_INTEGER || pj[k] == NA_INTEGER) return 0; } } int r = (upper) ? 1 : -1; if (ident) { /* triangular iff monotone; unit diagonal is preserved */ if (n >= 2) { if (pi[0] == pi[1]) return 0; else if (pi[0] < pi[1]) { for (k = 2; k < n; ++k) if (pi[k - 1] >= pi[k]) return 0; /* up->up, lo->lo */ } else { for (k = 2; k < n; ++k) if (pi[k - 1] <= pi[k]) return 0; /* up->lo, lo->up */ r = -r; } } if (!nonunit) r *= 2; return r; } else { /* brute force ... */ int ki, kj, j_; if (upper) { for (kj = 0; kj < n; ++kj) for (ki = kj + 1, j_ = pj[kj]; ki < n; ++ki) if (pi[ki] <= j_) goto LO; /* up->up */ return r; LO: for (kj = 0; kj < n; ++kj) for (ki = 0, j_ = pj[kj]; ki < kj; ++ki) if (pi[ki] <= j_) return 0; /* up->lo */ return -r; } else { for (kj = 0; kj < n; ++kj) for (ki = 0, j_ = pj[kj]; ki < kj; ++ki) if (pi[ki] >= j_) goto UP; /* lo->lo */ return r; UP: for (kj = 0; kj < n; ++kj) for (ki = kj + 1, j_ = pj[kj]; ki < n; ++ki) if (pi[ki] >= j_) return 0; /* lo->up */ return -r; } } } static int keep_sy(int *pi, int *pj, int n, int upper, int checkNA) { if (memcmp(pi, pj, n * sizeof(int)) != 0) return 0; int k, r = (upper) ? 1 : -1; if (checkNA) { for (k = 0; k < n; ++k) if (pi[k] == NA_INTEGER) return r; } if (n >= 2) { /* triangular iff monotone */ if (pi[0] == pi[1]) return r; else if (pi[0] < pi[1]) { for (k = 2; k < n; ++k) if (pi[k - 1] >= pi[k]) return r; /* up->up, lo->lo */ } else { for (k = 2; k < n; ++k) if (pi[k - 1] <= pi[k]) return r; /* up->lo, lo->up */ r = -r; } } return 2 * r; } static int keep_di(int *pi, int *pj, int n, int nonunit, int checkNA, int lwork) { int k, ident = memcmp(pi, pj, n * sizeof(int)) == 0; if (checkNA) { if (ident) { for (k = 0; k < n; ++k) if (pi[k] == NA_INTEGER) return 0; } else { for (k = 0; k < n; ++k) if (pi[k] == NA_INTEGER || pj[k] == NA_INTEGER) return 0; } } if (ident) { /* diagonal iff no duplicates; unit diagonal is preserved */ char *work; Matrix_Calloc(work, lwork, char); --work; for (k = 0; k < n; ++k) { if (work[pi[k]]) return 0; work[pi[k]] = 1; } ++work; Matrix_Free(work, lwork); return (nonunit) ? 1 : 2; } else { /* brute force ... */ int ki, kj, j_; for (kj = 0; kj < n; ++kj) { j_ = pj[kj]; for (ki = 0; ki < kj; ++ki) if (pi[ki] == j_) return 0; for (ki = kj + 1; ki < n; ++ki) if (pi[ki] == j_) return 0; } return 1; } } static void sort_cr(SEXP obj, const char *cl) { SEXP dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[(cl[2] == 'C') ? 0 : 1], n = pdim[(cl[2] == 'C') ? 1 : 0], r = (m < n) ? n : m; UNPROTECT(1); /* dim */ SEXP iSym = (cl[2] == 'C') ? Matrix_iSym : Matrix_jSym, p = PROTECT(GET_SLOT(obj, Matrix_pSym)), i = PROTECT(GET_SLOT(obj, iSym)); int *pp = INTEGER(p), *pi = INTEGER(i); int i_, j_, k, kend, nnz = pp[n], *workA, *workB, *workC; size_t lwork = (size_t) m + 1 + r + nnz; Matrix_Calloc(workA, lwork, int); workB = workA + m + 1; workC = workB + r; #define SORT_LOOP(_MASK_) \ do { \ ++workA; \ for (k = 0; k < nnz; ++k) \ ++workA[pi[k]]; \ --workA; \ \ for (i_ = 1; i_ < m; ++i_) \ workA[i_] = workB[i_] = workB[i_ - 1] + workA[i_]; \ workA[m] = nnz; \ \ ++pp; \ k = 0; \ for (j_ = 0; j_ < n; ++j_) { \ kend = pp[j_]; \ while (k < kend) { \ i_ = pi[k]; \ workC[workB[i_]] = j_; \ _MASK_(workD[workB[i_]] = px[k]); \ ++workB[i_]; \ ++k; \ } \ } \ --pp; \ \ for (j_ = 0; j_ < n; ++j_) \ workB[j_] = pp[j_]; \ \ ++workA; \ k = 0; \ for (i_ = 0; i_ < m; ++i_) { \ kend = workA[i_]; \ while (k < kend) { \ j_ = workC[k]; \ pi[workB[j_]] = i_; \ _MASK_(px[workB[j_]] = workD[k]); \ ++workB[j_]; \ ++k; \ } \ } \ --workA; \ } while (0) #define SORT(_CTYPE_, _PTR_) \ do { \ _CTYPE_ *px = _PTR_(x), *workD; \ Matrix_Calloc(workD, nnz, _CTYPE_); \ SORT_LOOP(SHOW); \ Matrix_Free(workD, nnz); \ } while (0) if (cl[0] == 'n') SORT_LOOP(HIDE); else { SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)); switch (cl[0]) { case 'l': SORT(int, LOGICAL); break; case 'i': SORT(int, INTEGER); break; case 'd': SORT(double, REAL); break; case 'z': SORT(Rcomplex, COMPLEX); break; default: break; } UNPROTECT(1); /* x */ } #undef SORT_LOOP #undef SORT Matrix_Free(workA, lwork); UNPROTECT(2); /* i, p */ return; } #define XIJ_GE( _X_, _I_, _J_, _M_, _ZERO_, _ONE_) \ *(_X_ + _J_ * _M_ + _I_) #define XIJ_TR_U_N(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \ ((_I_ <= _J_) \ ? XIJ_GE(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \ : _ZERO_) #define XIJ_TR_U_U(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \ ((_I_ < _J_) \ ? XIJ_GE(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \ : ((_I_ == _J_) ? _ONE_ : _ZERO_)) #define XIJ_TR_L_N(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \ ((_I_ >= _J_) \ ? XIJ_GE(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \ : _ZERO_) #define XIJ_TR_L_U(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \ ((_I_ > _J_) \ ? XIJ_GE(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \ : ((_I_ == _J_) ? _ONE_ : _ZERO_)) #define XIJ_TP_U_N(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \ ((_I_ <= _J_) \ ? *(_X_ + AR21_UP(_I_, _J_, _M_)) \ : _ZERO_) #define XIJ_TP_U_U(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \ ((_I_ < _J_) \ ? *(_X_ + AR21_UP(_I_, _J_, _M_)) \ : ((_I_ == _J_) ? _ONE_ : _ZERO_)) #define XIJ_TP_L_N(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \ ((_I_ >= _J_) \ ? *(_X_ + AR21_LO(_I_, _J_, _M_)) \ : _ZERO_) #define XIJ_TP_L_U(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \ ((_I_ > _J_) \ ? *(_X_ + AR21_LO(_I_, _J_, _M_)) \ : ((_I_ == _J_) ? _ONE_ : _ZERO_)) #define XIJ_SY_U( _X_, _I_, _J_, _M_, _ZERO_, _ONE_) \ ((_I_ <= _J_) \ ? XIJ_GE(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \ : XIJ_GE(_X_, _J_, _I_, _M_, _ZERO_, _ONE_)) #define XIJ_SY_L( _X_, _I_, _J_, _M_, _ZERO_, _ONE_) \ ((_I_ >= _J_) \ ? XIJ_GE(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \ : XIJ_GE(_X_, _J_, _I_, _M_, _ZERO_, _ONE_)) #define XIJ_SP_U( _X_, _I_, _J_, _M_, _ZERO_, _ONE_) \ ((_I_ <= _J_) \ ? *(_X_ + AR21_UP(_I_, _J_, _M_)) \ : *(_X_ + AR21_UP(_J_, _I_, _M_))) #define XIJ_SP_L( _X_, _I_, _J_, _M_, _ZERO_, _ONE_) \ ((_I_ >= _J_) \ ? *(_X_ + AR21_LO(_I_, _J_, _M_)) \ : *(_X_ + AR21_LO(_J_, _I_, _M_))) static SEXP unpackedMatrix_subscript_2ary(SEXP x, SEXP i, SEXP j, const char *cl) { #define SUB2_START \ SEXP dim = PROTECT(GET_SLOT(x, Matrix_DimSym)); \ int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; \ UNPROTECT(1); /* dim */ \ \ int ki, kj, \ mi = i == R_NilValue, \ mj = j == R_NilValue, \ ni = (mi) ? m : LENGTH(i), \ nj = (mj) ? n : LENGTH(j), \ *pi = (mi) ? NULL : INTEGER(i), \ *pj = (mj) ? NULL : INTEGER(j); #define SUB2_START_EXTRA(_E_, _R_, _Y_, _DENSE_) \ SUB2_START; \ \ int upper = 1, nonunit = 1, keep = 0; \ SEXP uplo, diag; \ if (cl[1] != 'g') { \ PROTECT(uplo = GET_SLOT(x, Matrix_uploSym)); \ upper = *CHAR(STRING_ELT(uplo, 0)) == 'U'; \ UNPROTECT(1); /* uplo */ \ if (cl[1] == 't') { \ PROTECT(diag = GET_SLOT(x, Matrix_diagSym)); \ nonunit = *CHAR(STRING_ELT(diag, 0)) == 'N'; \ UNPROTECT(1); /* diag */ \ } \ } \ \ char cl_[] = "...Matrix"; \ cl_[0] = cl[0]; \ cl_[1] = 'g'; \ cl_[2] = _E_; \ if (cl[1] != 'g' && !(mi || mj) && ni == nj) { \ if (cl[1] == 't') { \ keep = keep_tr(pi, pj, ni, upper, nonunit, _DENSE_); \ if (keep != 0) { \ cl_[1] = 't'; \ cl_[2] = _R_; \ } \ } else { \ keep = keep_sy(pi, pj, ni, upper, 0); \ if ((_DENSE_) ? keep != 0 : keep < -1 || keep > 1) { \ cl_[1] = 's'; \ cl_[2] = _Y_; \ } \ } \ } \ SEXP res = PROTECT(newObject(cl_)); \ \ PROTECT(dim = GET_SLOT(res, Matrix_DimSym)); \ pdim = INTEGER(dim); \ pdim[0] = ni; \ pdim[1] = nj; \ UNPROTECT(1); /* dim */ \ \ if ((cl[1] != 's') ? keep < 0 : keep < -1) { \ PROTECT(uplo = GET_SLOT(res, Matrix_uploSym)); \ SEXP uplo_ = PROTECT(mkChar("L")); \ SET_STRING_ELT(uplo, 0, uplo_); \ UNPROTECT(2); /* uplo_, uplo */ \ } \ if (cl[1] == 't' && (keep < -1 || keep > 1)) { \ PROTECT(diag = GET_SLOT(res, Matrix_diagSym)); \ SEXP diag_ = PROTECT(mkChar("U")); \ SET_STRING_ELT(diag, 0, diag_); \ UNPROTECT(2); /* diag_, diag */ \ } SUB2_START_EXTRA('e', 'r', 'y', 1); double ninj = (double) ni * nj; if (ninj > R_XLEN_T_MAX) error(_("attempt to allocate vector of length exceeding %s"), "R_XLEN_T_MAX"); SEXP x0 = PROTECT(GET_SLOT(x, Matrix_xSym)), x1 = PROTECT(allocVector(TYPEOF(x0), (R_xlen_t) ninj)); int i_, j_; Matrix_int_fast64_t m_ = m; #define SUB2_CASES(_SUB2_) \ do { \ switch (cl[0]) { \ case 'n': \ case 'l': \ _SUB2_(int, LOGICAL, NA_LOGICAL, 0, 1); \ break; \ case 'i': \ _SUB2_(int, INTEGER, NA_INTEGER, 0, 1); \ break; \ case 'd': \ _SUB2_(double, REAL, NA_REAL, 0.0, 1.0); \ break; \ case 'z': \ _SUB2_(Rcomplex, COMPLEX, \ Matrix_zna, Matrix_zzero, Matrix_zone); \ break; \ default: \ break; \ } \ } while (0) #define SUB2(_CTYPE_, _PTR_, _NA_, _ZERO_, _ONE_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \ if (cl_[1] == 'g') { \ if (cl[1] == 'g') \ SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \ XIJ_GE, , , _NA_, _ZERO_, _ONE_); \ else if (cl[1] == 't') { \ if (upper) { \ if (nonunit) \ SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \ XIJ_TR_U_N, , , _NA_, _ZERO_, _ONE_); \ else \ SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \ XIJ_TR_U_U, , , _NA_, _ZERO_, _ONE_); \ } else { \ if (nonunit) \ SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \ XIJ_TR_L_N, , , _NA_, _ZERO_, _ONE_); \ else \ SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \ XIJ_TR_L_U, , , _NA_, _ZERO_, _ONE_); \ } \ } else { \ if (upper) \ SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \ XIJ_SY_U, , , _NA_, _ZERO_, _ONE_); \ else \ SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \ XIJ_SY_L, , , _NA_, _ZERO_, _ONE_); \ } \ } else if (cl_[1] == 't') { \ Matrix_memset(px1, 0, XLENGTH(x1), sizeof(_CTYPE_)); \ if (upper) { \ if (nonunit) { \ if (keep > 0) \ SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \ XIJ_TR_U_N, , px1 += ni - kj - 1, \ _NA_, _ZERO_, _ONE_); \ else \ SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \ XIJ_TR_U_N, px1 += kj, , \ _NA_, _ZERO_, _ONE_); \ } else { \ if (keep > 0) \ SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \ XIJ_TR_U_U, , px1 += ni - kj - 1, \ _NA_, _ZERO_, _ONE_); \ else \ SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \ XIJ_TR_U_U, px1 += kj, , \ _NA_, _ZERO_, _ONE_); \ } \ } else { \ if (nonunit) { \ if (keep > 0) \ SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \ XIJ_TR_L_N, , px1 += ni - kj - 1, \ _NA_, _ZERO_, _ONE_); \ else \ SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \ XIJ_TR_L_N, px1 += kj, , \ _NA_, _ZERO_, _ONE_); \ } else { \ if (keep > 0) \ SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \ XIJ_TR_L_U, , px1 += ni - kj - 1, \ _NA_, _ZERO_, _ONE_); \ else \ SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \ XIJ_TR_L_U, px1 += kj, , \ _NA_, _ZERO_, _ONE_); \ } \ } \ } else { \ Matrix_memset(px1, 0, XLENGTH(x1), sizeof(_CTYPE_)); \ if (upper) { \ if (keep > 0) \ SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \ XIJ_SY_U, , px1 += ni - kj - 1, \ _NA_, _ZERO_, _ONE_); \ else \ SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \ XIJ_SY_U, px1 += kj, , \ _NA_, _ZERO_, _ONE_); \ } else { \ if (keep > 0) \ SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \ XIJ_SY_L, , px1 += ni - kj - 1, \ _NA_, _ZERO_, _ONE_); \ else \ SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \ XIJ_SY_L, px1 += kj, , \ _NA_, _ZERO_, _ONE_); \ } \ } \ } while (0) #define SUB2_LOOP(_FOR_, _XIJ_, _JUMP1_, _JUMP2_, \ _NA_, _ZERO_, _ONE_) \ do { \ for (kj = 0; kj < nj; ++kj) { \ if (mj) \ j_ = kj; \ else { \ j_ = pj[kj]; \ if (j_ != NA_INTEGER) \ j_ -= 1; \ else { \ _JUMP1_; \ _FOR_ { \ *(px1++) = _NA_; \ } \ _JUMP2_; \ continue; \ } \ } \ _JUMP1_; \ _FOR_ { \ if (mi) \ i_ = ki; \ else { \ i_ = pi[ki]; \ if (i_ != NA_INTEGER) \ i_ -= 1; \ else { \ *(px1++) = _NA_; \ continue; \ } \ } \ *(px1++) = _XIJ_(px0, i_, j_, m_, _ZERO_, _ONE_); \ } \ _JUMP2_; \ } \ } while (0) SUB2_CASES(SUB2); #undef SUB2 SET_SLOT(res, Matrix_xSym, x1); UNPROTECT(3); /* x1, x0, res */ return res; } static SEXP packedMatrix_subscript_2ary(SEXP x, SEXP i, SEXP j, const char *cl) { SUB2_START_EXTRA('e', 'p', 'p', 1); double ninj = (double) ni * nj, ninj_ = (keep) ? 0.5 * (ninj + ni) : ninj; if (ninj_ > R_XLEN_T_MAX) error(_("attempt to allocate vector of length exceeding %s"), "R_XLEN_T_MAX"); SEXP x0 = PROTECT(GET_SLOT(x, Matrix_xSym)), x1 = PROTECT(allocVector(TYPEOF(x0), (R_xlen_t) ninj_)); int i_, j_; Matrix_int_fast64_t m_ = m; #define SUB2(_CTYPE_, _PTR_, _NA_, _ZERO_, _ONE_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \ if (cl_[1] == 'g') { \ if (cl[1] == 't') { \ if (upper) { \ if (nonunit) \ SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \ XIJ_TP_U_N, , , _NA_, _ZERO_, _ONE_); \ else \ SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \ XIJ_TP_U_U, , , _NA_, _ZERO_, _ONE_); \ } else { \ if (nonunit) \ SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \ XIJ_TP_L_N, , , _NA_, _ZERO_, _ONE_); \ else \ SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \ XIJ_TP_L_U, , , _NA_, _ZERO_, _ONE_); \ } \ } else { \ if (upper) \ SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \ XIJ_SP_U, , , _NA_, _ZERO_, _ONE_); \ else \ SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \ XIJ_SP_L, , , _NA_, _ZERO_, _ONE_); \ } \ } else if (cl_[1] == 't') { \ if (upper) { \ if (nonunit) { \ if (keep > 0) \ SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \ XIJ_TP_U_N, , , _NA_, _ZERO_, _ONE_); \ else \ SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \ XIJ_TP_U_N, , , _NA_, _ZERO_, _ONE_); \ } else { \ if (keep > 0) \ SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \ XIJ_TP_U_U, , , _NA_, _ZERO_, _ONE_); \ else \ SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \ XIJ_TP_U_U, , , _NA_, _ZERO_, _ONE_); \ } \ } else { \ if (nonunit) { \ if (keep > 0) \ SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \ XIJ_TP_L_N, , , _NA_, _ZERO_, _ONE_); \ else \ SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \ XIJ_TP_L_N, , , _NA_, _ZERO_, _ONE_); \ } else { \ if (keep > 0) \ SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \ XIJ_TP_L_U, , , _NA_, _ZERO_, _ONE_); \ else \ SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \ XIJ_TP_L_U, , , _NA_, _ZERO_, _ONE_); \ } \ } \ } else { \ if (upper) { \ if (keep > 0) \ SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \ XIJ_SP_U, , , _NA_, _ZERO_, _ONE_); \ else \ SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \ XIJ_SP_U, , , _NA_, _ZERO_, _ONE_); \ } else { \ if (keep > 0) \ SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \ XIJ_SP_L, , , _NA_, _ZERO_, _ONE_); \ else \ SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \ XIJ_SP_L, , , _NA_, _ZERO_, _ONE_); \ } \ } \ } while (0) SUB2_CASES(SUB2); #undef SUB2_LOOP #undef SUB2 SET_SLOT(res, Matrix_xSym, x1); UNPROTECT(3); /* x1, x0, res */ return res; } static SEXP CsparseMatrix_subscript_2ary(SEXP x, SEXP i, SEXP j, const char *cl) { SUB2_START_EXTRA('C', 'C', 'C', 0); if (cl[1] != 'g' && cl_[1] == 'g') { /* defined in ./coerce.c : */ SEXP sparse_as_general(SEXP, const char *); x = sparse_as_general(x, cl); } PROTECT(x); SEXP p0 = PROTECT(GET_SLOT(x, Matrix_pSym)), i0 = PROTECT(GET_SLOT(x, Matrix_iSym)), p1 = PROTECT(allocVector(INTSXP, (R_xlen_t) nj + 1)), i1 = NULL; int *pp0 = INTEGER(p0), *pi0 = INTEGER(i0), *pp1 = INTEGER(p1), *pi1 = NULL, d, k, kend, doSort = 0; Matrix_int_fast64_t nnz = 0; *(pp1++) = 0; #define SUB2_FINISH \ if (nnz > INT_MAX) \ error(_("%s too dense for %s; would have more than %s nonzero entries"), \ "x[i,j]", "[CR]sparseMatrix", "2^31-1"); \ \ PROTECT(i1 = allocVector(INTSXP, (R_xlen_t) nnz)); \ pi1 = INTEGER(i1); \ \ if (cl[0] == 'n') \ SUB2_LOOP(HIDE); \ else { \ SEXP x0 = PROTECT(GET_SLOT(x, Matrix_xSym)), \ x1 = PROTECT(allocVector(TYPEOF(x0), (R_xlen_t) nnz)); \ SUB2_CASES(SUB2); \ SET_SLOT(res, Matrix_xSym, x1); \ UNPROTECT(2); /* x1, x0 */ \ } #define SUB2(_CTYPE_, _PTR_, _NA_, _ZERO_, _ONE_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \ SUB2_LOOP(SHOW); \ } while (0) if (mi) { for (kj = 0; kj < nj; ++kj) { nnz += pp0[pj[kj]] - pp0[pj[kj] - 1]; pp1[kj] = (int) nnz; } #define SUB2_LOOP(_MASK_) \ do { \ for (kj = 0; kj < nj; ++kj) { \ k = pp0[pj[kj] - 1]; \ kend = pp0[pj[kj]]; \ d = kend - k; \ if (d) { \ Matrix_memcpy(pi1, pi0 + k, d, sizeof(int)); \ pi1 += d; \ _MASK_(Matrix_memcpy(px1, px0 + k, d, sizeof(*px1))); \ _MASK_(px1 += d); \ } \ } \ } while (0) SUB2_FINISH; #undef SUB2_LOOP } else { int *workA, *workB, *workC; size_t lwork = (size_t) m + m + ni; Matrix_Calloc(workA, lwork, int); workB = workA + m; workC = workB + m; /* workA[ i] : size of the set { ki : pi[ki] - 1 == i } workB[ i] : smallest ki such that pi[ki] - 1 == i workC[ki] : smallest ki' > ki such that pi[ki'] == pi[ki] */ int i_, j_, i_prev = m; for (ki = ni - 1; ki >= 0; --ki) { i_ = pi[ki] - 1; ++workA[i_]; workC[ki] = workB[i_]; workB[i_] = ki; if (i_ > i_prev) doSort = 1; i_prev = i_; } for (kj = 0; kj < nj; ++kj) { j_ = (mj) ? kj : pj[kj] - 1; k = pp0[j_]; kend = pp0[j_ + 1]; while (k < kend) { nnz += workA[pi0[k]]; ++k; } pp1[kj] = (int) nnz; } #define SUB2_LOOP(_MASK_) \ do { \ for (kj = 0; kj < nj; ++kj) { \ j_ = (mj) ? kj : pj[kj] - 1; \ k = pp0[j_]; \ kend = pp0[j_ + 1]; \ while (k < kend) { \ i_ = pi0[k]; \ d = workA[i_]; \ ki = workB[i_]; \ while (d--) { \ *(pi1++) = ki; \ _MASK_(*(px1++) = px0[k]); \ ki = workC[ki]; \ } \ ++k; \ } \ } \ } while (0) SUB2_FINISH; #undef SUB2_LOOP Matrix_Free(workA, lwork); } #undef SUB2_FINISH SET_SLOT(res, Matrix_pSym, p1); SET_SLOT(res, Matrix_iSym, i1); UNPROTECT(4); /* i1, p1, i0, p0 */ if (doSort) sort_cr(res, cl); if (cl[1] == 's' && (keep == -1 || keep == 1)) { /* defined in ./sparse.c : */ SEXP sparse_force_symmetric(SEXP, const char *, char); res = sparse_force_symmetric(res, cl_, (keep == 1) ? 'U' : 'L'); } UNPROTECT(2); /* x, res */ return res; } static SEXP RsparseMatrix_subscript_2ary(SEXP x, SEXP i, SEXP j, const char *cl) { SUB2_START_EXTRA('R', 'R', 'R', 0); if (cl[1] != 'g' && cl_[1] == 'g') { /* defined in ./coerce.c : */ SEXP sparse_as_general(SEXP, const char *); x = sparse_as_general(x, cl); } PROTECT(x); SEXP p0 = PROTECT(GET_SLOT(x, Matrix_pSym)), j0 = PROTECT(GET_SLOT(x, Matrix_jSym)), p1 = PROTECT(allocVector(INTSXP, (R_xlen_t) ni + 1)), j1 = NULL; int *pp0 = INTEGER(p0), *pj0 = INTEGER(j0), *pp1 = INTEGER(p1), *pj1 = NULL, d, k, kend, doSort = 0; Matrix_int_fast64_t nnz = 0; *(pp1++) = 0; #define SUB2_FINISH \ if (nnz > INT_MAX) \ error(_("%s too dense for %s; would have more than %s nonzero entries"), \ "x[i,j]", "[CR]sparseMatrix", "2^31-1"); \ \ PROTECT(j1 = allocVector(INTSXP, (R_xlen_t) nnz)); \ pj1 = INTEGER(j1); \ \ if (cl[0] == 'n') \ SUB2_LOOP(HIDE); \ else { \ SEXP x0 = PROTECT(GET_SLOT(x, Matrix_xSym)), \ x1 = PROTECT(allocVector(TYPEOF(x0), (R_xlen_t) nnz)); \ SUB2_CASES(SUB2); \ SET_SLOT(res, Matrix_xSym, x1); \ UNPROTECT(2); /* x1, x0 */ \ } if (mj) { for (ki = 0; ki < ni; ++ki) { nnz += pp0[pi[ki]] - pp0[pi[ki] - 1]; pp1[ki] = (int) nnz; } #define SUB2_LOOP(_MASK_) \ do { \ for (ki = 0; ki < ni; ++ki) { \ k = pp0[pi[ki] - 1]; \ kend = pp0[pi[ki]]; \ d = kend - k; \ if (d) { \ Matrix_memcpy(pj1, pj0 + k, d, sizeof(int)); \ pj1 += d; \ _MASK_(Matrix_memcpy(px1, px0 + k, d, sizeof(*px1))); \ _MASK_(px1 += d); \ } \ } \ } while (0) SUB2_FINISH; #undef SUB2_LOOP } else { int *workA, *workB, *workC; size_t lwork = (size_t) n + n + nj; Matrix_Calloc(workA, lwork, int); workB = workA + n; workC = workB + n; /* workA[ j] : size of the set { kj : pj[kj] - 1 == j } workB[ j] : smallest ki such that pj[kj] - 1 == j workC[kj] : smallest kj' > kj such that pj[kj'] == pj[kj] */ int i_, j_, j_prev = n; for (kj = nj - 1; kj >= 0; --kj) { j_ = pj[kj] - 1; ++workA[j_]; workC[kj] = workB[j_]; workB[j_] = kj; if (j_ > j_prev) doSort = 1; j_prev = j_; } for (ki = 0; ki < ni; ++ki) { i_ = (mi) ? ki : pi[ki] - 1; k = pp0[i_]; kend = pp0[i_ + 1]; while (k < kend) { nnz += workA[pj0[k]]; ++k; } pp1[ki] = (int) nnz; } #define SUB2_LOOP(_MASK_) \ do { \ for (ki = 0; ki < ni; ++ki) { \ i_ = (mi) ? ki : pi[ki] - 1; \ k = pp0[i_]; \ kend = pp0[i_ + 1]; \ while (k < kend) { \ j_ = pj0[k]; \ d = workA[j_]; \ kj = workB[j_]; \ while (d--) { \ *(pj1++) = kj; \ _MASK_(*(px1++) = px0[k]); \ kj = workC[kj]; \ } \ ++k; \ } \ } \ } while (0) SUB2_FINISH; #undef SUB2_LOOP Matrix_Free(workA, lwork); } #undef SUB2_FINISH #undef SUB2 SET_SLOT(res, Matrix_pSym, p1); SET_SLOT(res, Matrix_jSym, j1); UNPROTECT(4); /* j1, p1, j0, p0 */ if (doSort) sort_cr(res, cl); if (cl[1] == 's' && (keep == -1 || keep == 1)) { /* defined in ./sparse.c : */ SEXP sparse_force_symmetric(SEXP, const char *, char); res = sparse_force_symmetric(res, cl_, (keep == 1) ? 'U' : 'L'); } UNPROTECT(2); /* x, res */ return res; } static SEXP diagonalMatrix_subscript_2ary(SEXP x, SEXP i, SEXP j, const char *cl) { SUB2_START; int nonunit = 1, keep = 0; SEXP diag = PROTECT(GET_SLOT(x, Matrix_diagSym)); nonunit = *CHAR(STRING_ELT(diag, 0)) == 'N'; UNPROTECT(1); /* diag */ char cl_[] = ".gCMatrix"; cl_[0] = cl[0]; if (!(mi || mj) && ni == nj) { keep = keep_di(pi, pj, ni, nonunit, 0, m); if (keep > 0) { cl_[1] = 'd'; cl_[2] = 'i'; } } SEXP res = PROTECT(newObject(cl_)); PROTECT(dim = GET_SLOT(res, Matrix_DimSym)); pdim = INTEGER(dim); pdim[0] = (int) ni; pdim[1] = (int) nj; UNPROTECT(1); /* dim */ if (keep > 1) { PROTECT(diag = GET_SLOT(res, Matrix_diagSym)); SEXP diag_ = PROTECT(mkChar("U")); SET_STRING_ELT(diag, 0, diag_); UNPROTECT(2); /* diag_, diag */ } else if (keep > 0) { SEXP x0 = PROTECT(GET_SLOT(x, Matrix_xSym)), x1 = PROTECT(allocVector(TYPEOF(x0), ni)); int j_; #define SUB2(_CTYPE_, _PTR_, _NA_, _ZERO_, _ONE_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \ while (ni--) \ *(px1++) = \ (*(pi++) != (j_ = *(pj++))) \ ? _ZERO_ \ : ((nonunit) ? px0[j_ - 1] : _ONE_); \ } while (0) SUB2_CASES(SUB2); #undef SUB2 SET_SLOT(res, Matrix_xSym, x1); UNPROTECT(2); /* x0, x1 */ } else { SEXP x0 = PROTECT(GET_SLOT(x, Matrix_xSym)); char *work = NULL; int j_; if (nonunit) { Matrix_Calloc(work, n, char); #define SUB2_WORK(_CTYPE_, _PTR_, _ISNZ_) \ do { \ _CTYPE_ *px0 = _PTR_(x0); \ for (j_ = 0; j_ < n; ++j_) \ work[j_] = _ISNZ_(px0[j_]); \ } while (0) switch (cl[0]) { case 'n': SUB2_WORK(int, LOGICAL, ISNZ_PATTERN); break; case 'l': SUB2_WORK(int, LOGICAL, ISNZ_LOGICAL); break; case 'i': SUB2_WORK(int, INTEGER, ISNZ_INTEGER); break; case 'd': SUB2_WORK(double, REAL, ISNZ_REAL); break; case 'z': SUB2_WORK(Rcomplex, COMPLEX, ISNZ_COMPLEX); break; default: break; } #undef SUB2_WORK } SEXP p1 = PROTECT(allocVector(INTSXP, (R_xlen_t) nj + 1)); int *pp1 = INTEGER(p1); *(pp1++) = 0; for (kj = 0; kj < nj; ++kj) { pp1[kj] = 0; j_ = (mj) ? kj : pj[kj] - 1; if (!nonunit || work[j_]) { if (mi) { for (ki = 0; ki < ni; ++ki) if (ki == j_) ++pp1[kj]; } else { for (ki = 0; ki < ni; ++ki) if (pi[ki] - 1 == j_) ++pp1[kj]; } if (pp1[kj] > INT_MAX - pp1[kj - 1]) { if (nonunit) Matrix_Free(work, n); error(_("%s too dense for %s; would have more than %s nonzero entries"), "x[i,j]", "[CR]sparseMatrix", "2^31-1"); } } pp1[kj] += pp1[kj-1]; } SEXP i1 = PROTECT(allocVector(INTSXP, pp1[nj - 1])), x1 = PROTECT(allocVector(TYPEOF(x0), pp1[nj - 1])); int *pi1 = INTEGER(i1); #define SUB2(_CTYPE_, _PTR_, _NA_, _ZERO_, _ONE_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \ for (kj = 0; kj < nj; ++kj) { \ j_ = (mj) ? kj : pj[kj] - 1; \ if (!nonunit || work[j_]) { \ for (ki = 0; ki < ni; ++ki) { \ if (((mi) ? ki : pi[ki] - 1) == j_) { \ *(pi1++) = ki; \ *(px1++) = (nonunit) ? px0[j_] : _ONE_; \ } \ } \ } \ } \ } while (0) SUB2_CASES(SUB2); #undef SUB2 SET_SLOT(res, Matrix_pSym, p1); SET_SLOT(res, Matrix_iSym, i1); SET_SLOT(res, Matrix_xSym, x1); UNPROTECT(4); /* x1, x0, i1, p1 */ if (nonunit) Matrix_Free(work, n); } UNPROTECT(1); /* res */ return res; } static SEXP indMatrix_subscript_2ary(SEXP x, SEXP i, SEXP j, const char *cl) { PROTECT_INDEX pidA; PROTECT_WITH_INDEX(x, &pidA); PROTECT_INDEX pidB; SEXP perm0 = GET_SLOT(x, Matrix_permSym); int *pperm0 = INTEGER(perm0); PROTECT_WITH_INDEX(perm0, &pidB); SEXP margin = PROTECT(GET_SLOT(x, Matrix_marginSym)); int mg = INTEGER(margin)[0] - 1; SEXP dim = PROTECT(GET_SLOT(x, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[mg], n = pdim[!mg]; UNPROTECT(1); /* dim */ if (mg) { SEXP i_tmp = i; i = j; j = i_tmp; } int ki, kj, mi = i == R_NilValue, mj = j == R_NilValue, ni = (mi) ? m : LENGTH(i), nj = (mj) ? n : LENGTH(j), *pi = (mi) ? NULL : INTEGER(i), *pj = (mj) ? NULL : INTEGER(j), isP = cl[0] == 'p'; if (!mi) { isP = isP && ni == m; if (isP) { char *work; Matrix_Calloc(work, m, char); --work; /* now 1-indexed */ for (ki = 0; ki < ni; ++ki) { if (work[pi[ki]]) { isP = 0; break; } work[pi[ki]] = 1; } ++work; /* now 0-indexed */ Matrix_Free(work, m); } x = newObject((isP) ? "pMatrix" : "indMatrix"); REPROTECT(x, pidA); PROTECT(dim = GET_SLOT(x, Matrix_DimSym)); pdim = INTEGER(dim); pdim[ mg] = ni; pdim[!mg] = n; UNPROTECT(1); /* dim */ if (mg) SET_SLOT(x, Matrix_marginSym, margin); SEXP perm1 = PROTECT(allocVector(INTSXP, ni)); int *pperm1 = INTEGER(perm1); --pperm0; /* now 1-indexed */ for (ki = 0; ki < ni; ++ki) pperm1[ki] = pperm0[pi[ki]]; SET_SLOT(x, Matrix_permSym, perm1); UNPROTECT(1); /* perm1 */ perm0 = perm1; pperm0 = pperm1; REPROTECT(perm0, pidB); m = ni; } if (!mj) { isP = isP && nj == n; if (isP) { char *work; Matrix_Calloc(work, nj, char); --work; /* now 1-indexed */ for (kj = 0; kj < nj; ++kj) { if (work[pj[kj]]) { isP = 0; break; } work[pj[kj]] = 1; } ++work; /* now 0-indexed */ Matrix_Free(work, nj); } x = newObject((isP) ? "pMatrix" : ((!mg) ? "ngCMatrix" : "ngRMatrix")); REPROTECT(x, pidA); PROTECT(dim = GET_SLOT(x, Matrix_DimSym)); pdim = INTEGER(dim); pdim[ mg] = m; pdim[!mg] = nj; UNPROTECT(1); /* dim */ if (isP) { SEXP perm1 = PROTECT(allocVector(INTSXP, nj)); int *pperm1 = INTEGER(perm1), *work; Matrix_Calloc(work, nj, int); --work; /* now 1-indexed */ for (kj = 0; kj < nj; ++kj) work[pj[kj]] = kj + 1; for (kj = 0; kj < nj; ++kj) pperm1[kj] = work[pperm0[kj]]; ++work; /* now 0-indexed */ Matrix_Free(work, nj); SET_SLOT(x, Matrix_permSym, perm1); UNPROTECT(1); /* perm1 */ } else { int *workA, *workB, *workC; size_t lwork = (size_t) n + n + m; Matrix_Calloc(workA, lwork, int); workB = workA + n; workC = workB + n; --workA; /* now 1-indexed */ --workB; /* now 1-indexed */ SEXP p1 = PROTECT(allocVector(INTSXP, (R_xlen_t) nj + 1)); int *pp1 = INTEGER(p1), k, kend; /* 1. Compute old column counts in 'workA' */ for (k = 0; k < m; ++k) ++workA[pperm0[k]]; /* 2. Compute new column pointers in 'pp1' */ *(pp1++) = 0; for (kj = 0; kj < nj; ++kj) { pp1[kj] = workA[pj[kj]]; if (pp1[kj] > INT_MAX - pp1[kj - 1]) error(_("%s too dense for %s; would have more than %s nonzero entries"), \ "x[i,j]", "[CR]sparseMatrix", "2^31-1"); \ pp1[kj] += pp1[kj - 1]; } /* 3. Compute old column pointers in 'workB' and copy to 'workA' */ workB[1] = 0; for (k = 1; k < n; ++k) { workB[k + 1] = workB[k] + workA[k]; workA[k] = workB[k]; } workA[n] = workB[n]; /* 4. Sort old row indices into 'workC' */ for (k = 0; k < m; ++k) workC[workA[pperm0[k]]++] = k; SEXP i1 = PROTECT(allocVector(INTSXP, pp1[nj - 1])); int *pi1 = INTEGER(i1), pos; /* 5. Copy row indices from 'workC' to 'pi1' */ k = 0; for (kj = 0; kj < nj; ++kj) { kend = pp1[kj]; pos = workB[pj[kj]]; while (k < kend) pi1[k++] = workC[pos++]; } ++workA; /* now 0-indexed */ Matrix_Free(workA, lwork); SET_SLOT(x, Matrix_pSym, p1); SET_SLOT(x, (!mg) ? Matrix_iSym : Matrix_jSym, i1); UNPROTECT(2); /* i1, p1 */ } n = nj; } #undef SUB2_CASES #undef SUB2_START #undef SUB2_START_EXTRA UNPROTECT(3); /* margin, perm0, x */ return x; } /* x[i,j,drop=FALSE] with 'i' and 'j' of type "integer" and length not exceeding 2^31-1 {'i' in 1:m or NA, 'j' in 1:n or NA} ... but _not_ handling 'Dimnames' */ SEXP R_subscript_2ary(SEXP x, SEXP i, SEXP j) { if (i == R_NilValue && j == R_NilValue) return x; static const char *valid[] = { VALID_NONVIRTUAL_MATRIX, "" }; int ivalid = R_check_class_etc(x, valid); if (ivalid < 0) ERROR_INVALID_CLASS(x, __func__); ivalid += VALID_NONVIRTUAL_SHIFT(ivalid, 0); const char *cl = valid[ivalid]; validObject(x, cl); switch (cl[2]) { case 'e': case 'y': case 'r': return unpackedMatrix_subscript_2ary(x, i, j, cl); case 'p': return packedMatrix_subscript_2ary(x, i, j, cl); default: break; } static SEXP anyNA = NULL; if (!anyNA) anyNA = install("anyNA"); SEXP call = PROTECT(lang2(anyNA, R_NilValue)), value; #define ERROR_IF_ANYNA(_I_) \ do { \ if ((_I_) != R_NilValue) { \ SETCADR(call, _I_); \ PROTECT(value = eval(call, R_BaseEnv)); \ if (asLogical(value)) \ error(_("NA subscripts in %s not supported for '%s' inheriting from %s"), \ "x[i,j]", "x", "sparseMatrix"); \ UNPROTECT(1); \ } \ } while (0) ERROR_IF_ANYNA(i); ERROR_IF_ANYNA(j); #undef ERROR_IF_ANYNA UNPROTECT(1); switch (cl[2]) { case 'C': return CsparseMatrix_subscript_2ary(x, i, j, cl); case 'R': return RsparseMatrix_subscript_2ary(x, i, j, cl); case 'T': { char cl_[] = "..CMatrix"; cl_[0] = cl[0]; cl_[1] = cl[1]; /* defined in ./coerce.c : */ SEXP sparse_as_Csparse(SEXP, const char *); SEXP sparse_as_Tsparse(SEXP, const char *); x = sparse_as_Csparse(x, cl); PROTECT(x); x = CsparseMatrix_subscript_2ary(x, i, j, cl_); UNPROTECT(1); PROTECT(x); x = sparse_as_Tsparse(x, valid[R_check_class_etc(x, valid)]); UNPROTECT(1); return x; } case 'i': return diagonalMatrix_subscript_2ary(x, i, j, cl); default: return indMatrix_subscript_2ary(x, i, j, cl); } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/chm_common.h�����������������������������������������������������������������������������0000644�0001762�0000144�00000002504�14531175657�014614� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_CHM_COMMON_H #define MATRIX_CHM_COMMON_H #include "cholmod-etc.h" cholmod_factor * sexp_as_cholmod_factor (cholmod_factor *, SEXP); cholmod_sparse * sexp_as_cholmod_sparse (cholmod_sparse *, SEXP, Rboolean, Rboolean); cholmod_triplet * sexp_as_cholmod_triplet(cholmod_triplet *, SEXP, Rboolean); cholmod_dense * sexp_as_cholmod_dense (cholmod_dense *, SEXP); cholmod_dense *numeric_as_cholmod_dense (cholmod_dense *, double *, int, int); SEXP cholmod_factor_as_sexp (cholmod_factor *, int); SEXP cholmod_sparse_as_sexp (cholmod_sparse *, int, int, int, const char *, SEXP); SEXP cholmod_triplet_as_sexp(cholmod_triplet *, int, int, int, const char *, SEXP); SEXP cholmod_dense_as_sexp (cholmod_dense *, int); double cholmod_factor_ldetA (cholmod_factor *); cholmod_factor *cholmod_factor_update(cholmod_factor *, cholmod_sparse *, double); int R_cholmod_start (cholmod_common *); int R_cholmod_finish(cholmod_common *); SEXP R_cholmod_common_envini(SEXP); void R_cholmod_common_envset(void); void R_cholmod_common_envget(void); #endif /* MATRIX_CHM_COMMON_H */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/kappa.h����������������������������������������������������������������������������������0000644�0001762�0000144�00000001027�14503212600�013543� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_KAPPA_H #define MATRIX_KAPPA_H #include SEXP dgeMatrix_norm(SEXP, SEXP); SEXP dsyMatrix_norm(SEXP, SEXP); SEXP dspMatrix_norm(SEXP, SEXP); SEXP dtrMatrix_norm(SEXP, SEXP); SEXP dtpMatrix_norm(SEXP, SEXP); SEXP dgeMatrix_rcond(SEXP, SEXP, SEXP); SEXP dsyMatrix_rcond(SEXP, SEXP, SEXP); SEXP dspMatrix_rcond(SEXP, SEXP, SEXP); SEXP dpoMatrix_rcond(SEXP, SEXP, SEXP); SEXP dppMatrix_rcond(SEXP, SEXP, SEXP); SEXP dtrMatrix_rcond(SEXP, SEXP); SEXP dtpMatrix_rcond(SEXP, SEXP); #endif /* MATRIX_KAPPA_H */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/sparseVector.h���������������������������������������������������������������������������0000644�0001762�0000144�00000000237�14503212600�015131� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_SPARSEVECTOR_H #define MATRIX_SPARSEVECTOR_H #include SEXP v2spV(SEXP); SEXP CR2spV(SEXP); #endif /* MATRIX_SPARSEVECTOR_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/factorizations.h�������������������������������������������������������������������������0000644�0001762�0000144�00000001120�14504476335�015522� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_FACTORIZATIONS_H #define MATRIX_FACTORIZATIONS_H #include SEXP dgeMatrix_trf(SEXP, SEXP); SEXP dsyMatrix_trf(SEXP, SEXP); SEXP dspMatrix_trf(SEXP, SEXP); SEXP dpoMatrix_trf(SEXP, SEXP, SEXP, SEXP); SEXP dppMatrix_trf(SEXP, SEXP); SEXP dgCMatrix_trf(SEXP, SEXP, SEXP, SEXP); SEXP dgCMatrix_orf(SEXP, SEXP, SEXP); SEXP dpCMatrix_trf(SEXP, SEXP, SEXP, SEXP, SEXP); SEXP BunchKaufman_expand(SEXP, SEXP); SEXP CHMfactor_diag_get(SEXP, SEXP); SEXP CHMfactor_update(SEXP, SEXP, SEXP); SEXP CHMfactor_updown(SEXP, SEXP, SEXP); #endif /* MATRIX_FACTORIZATIONS_H */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/dense.h����������������������������������������������������������������������������������0000644�0001762�0000144�00000002227�14503222575�013564� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_DENSE_H #define MATRIX_DENSE_H #include SEXP dense_band(SEXP, const char *, int, int); SEXP R_dense_band(SEXP, SEXP, SEXP); SEXP dense_diag_get(SEXP, const char *, int); SEXP R_dense_diag_get(SEXP, SEXP); SEXP dense_diag_set(SEXP, const char *, SEXP, int); SEXP R_dense_diag_set(SEXP, SEXP); SEXP dense_transpose(SEXP, const char *); SEXP R_dense_transpose(SEXP); SEXP dense_force_symmetric(SEXP, const char *, char); SEXP R_dense_force_symmetric(SEXP, SEXP); SEXP dense_symmpart(SEXP, const char *); SEXP R_dense_symmpart(SEXP); SEXP dense_skewpart(SEXP, const char *); SEXP R_dense_skewpart(SEXP); int dense_is_symmetric(SEXP, const char *, int); SEXP R_dense_is_symmetric(SEXP, SEXP); int dense_is_triangular(SEXP, const char *, int); SEXP R_dense_is_triangular(SEXP, SEXP); int dense_is_diagonal(SEXP, const char *); SEXP R_dense_is_diagonal(SEXP); SEXP dense_marginsum(SEXP, const char *, int, int, int); SEXP R_dense_marginsum(SEXP, SEXP, SEXP, SEXP); SEXP dense_sum(SEXP, const char *, int); SEXP R_dense_sum(SEXP, SEXP); SEXP dense_prod(SEXP, const char *, int); SEXP R_dense_prod(SEXP, SEXP); #endif /* MATRIX_DENSE_H */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/cs-etc.h���������������������������������������������������������������������������������0000644�0001762�0000144�00000005011�14516234475�013644� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_CS_ETC_H #define MATRIX_CS_ETC_H #include #include "cs.h" #define MCS_PATTERN 0 #define MCS_REAL 1 #define MCS_COMPLEX 2 #define MCS_XTYPE_GET( ) Matrix_cs_xtype #define MCS_XTYPE_SET(_VALUE_) Matrix_cs_xtype = _VALUE_ extern int Matrix_cs_xtype; typedef struct Matrix_cs_sparse { int nzmax; int m; int n; int *p; int *i; void *x; /* (double *) or (double _Complex *) */ int nz; int xtype; /* Matrix-only */ } Matrix_cs; typedef struct Matrix_cs_symbolic { int *pinv; int *q; int *parent; int *cp; int *leftmost; int m2; double lnz; double unz; } Matrix_css; typedef struct Matrix_cs_numeric { Matrix_cs *L; /* (cs_di *) or (cs_ci *) */ Matrix_cs *U; /* (cs_di *) or (cs_ci *) */ int *pinv; double *B; } Matrix_csn; typedef struct Matrix_cs_dmperm_results { int *p; int *q; int *r; int *s; int nb; int rr[5]; int cc[5]; } Matrix_csd; Matrix_cs *M2CXS(SEXP, int); SEXP CXS2M(Matrix_cs *, int, char); /* Wrappers for the functions that we use at least once : */ Matrix_csd *Matrix_cs_dfree (Matrix_csd *); Matrix_csd *Matrix_cs_dmperm (const Matrix_cs *, int); int Matrix_cs_dropzeros (Matrix_cs *); void *Matrix_cs_free (void *); int Matrix_cs_happly (const Matrix_cs *, int, double, void *); int Matrix_cs_ipvec (const int *, const void *, void *, int); int Matrix_cs_lsolve (const Matrix_cs *, void *); Matrix_csn *Matrix_cs_lu (const Matrix_cs *, const Matrix_css *, double); int Matrix_cs_lusol (int, const Matrix_cs *, void *, double); Matrix_csn *Matrix_cs_nfree (Matrix_csn *); Matrix_cs *Matrix_cs_permute (const Matrix_cs *, const int *, const int *, int); int *Matrix_cs_pinv (const int *, int); int Matrix_cs_pvec (const int *, const void *, void *, int); Matrix_csn *Matrix_cs_qr (const Matrix_cs *, const Matrix_css *); int Matrix_cs_qrsol (int, const Matrix_cs *, void *); Matrix_css *Matrix_cs_sfree (Matrix_css *); Matrix_cs *Matrix_cs_spalloc (int, int, int, int, int); Matrix_cs *Matrix_cs_speye (int, int, int, int); Matrix_cs *Matrix_cs_spfree (Matrix_cs *); int Matrix_cs_sprealloc (Matrix_cs *, int); int Matrix_cs_spsolve (Matrix_cs *, const Matrix_cs *, int, int *, void *, const int *, int); Matrix_css *Matrix_cs_sqr (int, const Matrix_cs *, int); Matrix_cs *Matrix_cs_transpose (const Matrix_cs *, int); int Matrix_cs_usolve (const Matrix_cs *, void *); #endif /* MATRIX_CS_ETC_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/cholmod-etc.c����������������������������������������������������������������������������0000644�0001762�0000144�00000025525�14546174764�014702� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "Mdefines.h" #include "idz.h" #include "cholmod-etc.h" cholmod_common c ; cholmod_common cl; cholmod_factor *M2CHF(SEXP obj, int values) { cholmod_factor *L = (cholmod_factor *) R_alloc(1, sizeof(cholmod_factor)); memset(L, 0, sizeof(cholmod_factor)); SEXP dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)), type = PROTECT(GET_SLOT(obj, install("type"))), perm = PROTECT(GET_SLOT(obj, Matrix_permSym)), colcount = PROTECT(GET_SLOT(obj, install("colcount"))), x = PROTECT(getAttrib(obj, Matrix_xSym)); L->n = INTEGER(dim)[0]; L->minor = L->n; /* FIXME: could be wrong for obj <- new(...) */ L->ordering = INTEGER(type)[0]; if (L->ordering != CHOLMOD_NATURAL) L->Perm = INTEGER(perm); else { /* cholmod_check_factor allows L->Perm == NULL, but cholmod_copy_factor does not test, so it segfaults ... */ int n = (int) L->n, *Perm = (int *) R_alloc(L->n, sizeof(int)); for (int j = 0; j < n; ++j) Perm[j] = j; L->Perm = Perm; } L->ColCount = INTEGER(colcount); L->is_super = INTEGER(type)[2]; if (L->is_super) { L->is_ll = 1; L->is_monotonic = 1; SEXP super = PROTECT(GET_SLOT(obj, install("super"))), pi = PROTECT(GET_SLOT(obj, install("pi"))), px = PROTECT(GET_SLOT(obj, install("px"))), s = PROTECT(GET_SLOT(obj, install("s"))); L->super = INTEGER(super); L->pi = INTEGER(pi); L->px = INTEGER(px); L->s = INTEGER(s); L->nsuper = LENGTH(super) - 1; L->ssize = ((int *) L->pi)[L->nsuper]; L->xsize = ((int *) L->px)[L->nsuper]; L->maxcsize = INTEGER(type)[4]; L->maxesize = INTEGER(type)[5]; UNPROTECT(4); } else { L->is_ll = INTEGER(type)[1]; L->is_monotonic = INTEGER(type)[3]; if (values && x != R_NilValue) { SEXP p = PROTECT(GET_SLOT(obj, Matrix_pSym)), i = PROTECT(GET_SLOT(obj, Matrix_iSym)), nz = PROTECT(GET_SLOT(obj, install("nz"))), nxt = PROTECT(GET_SLOT(obj, install("nxt"))), prv = PROTECT(GET_SLOT(obj, install("prv"))); L->p = INTEGER(p); L->i = INTEGER(i); L->nz = INTEGER(nz); L->next = INTEGER(nxt); L->prev = INTEGER(prv); L->nzmax = ((int *) L->p)[L->n]; UNPROTECT(5); } } L->itype = CHOLMOD_INT; L->dtype = CHOLMOD_DOUBLE; if (values && x != R_NilValue) { switch (TYPEOF(x)) { case CPLXSXP: L->x = COMPLEX(x); L->xtype = CHOLMOD_COMPLEX; break; case REALSXP: L->x = REAL(x); L->xtype = CHOLMOD_REAL; break; default: ERROR_INVALID_TYPE(x, __func__); break; } } UNPROTECT(5); return L; } cholmod_sparse *M2CHS(SEXP obj, int values) { cholmod_sparse *A = (cholmod_sparse *) R_alloc(1, sizeof(cholmod_sparse)); memset(A, 0, sizeof(cholmod_sparse)); SEXP dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)), p = PROTECT(GET_SLOT(obj, Matrix_pSym)), i = PROTECT(GET_SLOT(obj, Matrix_iSym)), x = PROTECT(getAttrib(obj, Matrix_xSym)); A->nrow = INTEGER(dim)[0]; A->ncol = INTEGER(dim)[1]; A->p = INTEGER(p); A->i = INTEGER(i); A->nzmax = ((int *) A->p)[A->ncol]; A->stype = 0; A->itype = CHOLMOD_INT; A->xtype = CHOLMOD_PATTERN; A->dtype = CHOLMOD_DOUBLE; A->sorted = 1; A->packed = 1; if (values && x != R_NilValue) { switch (TYPEOF(x)) { case CPLXSXP: A->x = COMPLEX(x); A->xtype = CHOLMOD_COMPLEX; break; case REALSXP: A->x = REAL(x); A->xtype = CHOLMOD_REAL; break; default: ERROR_INVALID_TYPE(x, __func__); break; } } UNPROTECT(4); return A; } cholmod_dense *M2CHD(SEXP obj, int trans) { cholmod_dense *A = (cholmod_dense *) R_alloc(1, sizeof(cholmod_dense)); memset(A, 0, sizeof(cholmod_dense)); SEXP dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)), x = PROTECT(GET_SLOT(obj, Matrix_xSym)); int m = INTEGER(dim)[0], n = INTEGER(dim)[1]; A->nrow = ((trans) ? n : m); A->ncol = ((trans) ? m : n); A->nzmax = A->nrow * A->ncol; A->d = A->nrow; A->dtype = CHOLMOD_DOUBLE; switch (TYPEOF(x)) { case CPLXSXP: { Rcomplex *px = COMPLEX(x); if (!trans) A->x = px; else { Rcomplex *py = R_Calloc(A->nzmax, Rcomplex); ztranspose2(py, px, m, n); A->x = py; /* NB: caller must do R_Free(A->x) */ } A->xtype = CHOLMOD_COMPLEX; break; } case REALSXP: { double *px = REAL(x); if (!trans) A->x = px; else { double *py = R_Calloc(A->nzmax, double); dtranspose2(py, px, m, n); A->x = py; /* NB: caller must do R_Free(A->x) */ } A->xtype = CHOLMOD_REAL; break; } default: ERROR_INVALID_TYPE(x, __func__); break; } UNPROTECT(2); return A; } SEXP CHF2M(cholmod_factor *L, int values) { if (L->itype != CHOLMOD_INT) error(_("wrong '%s'"), "itype"); if (values && L->xtype != CHOLMOD_REAL && L->xtype != CHOLMOD_COMPLEX) error(_("wrong '%s'"), "xtype"); if (values && L->dtype != CHOLMOD_DOUBLE) error(_("wrong '%s'"), "dtype"); if (L->n > INT_MAX) error(_("dimensions cannot exceed %s"), "2^31-1"); if (L->super) { if (L->maxcsize > INT_MAX) error(_("'%s' would overflow type \"%s\""), "maxcsize", "integer"); } else { if (L->n == INT_MAX) error(_("n+1 would overflow type \"%s\""), "integer"); } if (L->minor < L->n) { if (L->is_ll) error(_("leading principal minor of order %d is not positive"), (int) L->minor + 1); else error(_("leading principal minor of order %d is zero"), (int) L->minor + 1); } char cl[] = ".CHM....."; cl[0] = (!values) ? 'n' : ((L->xtype == CHOLMOD_COMPLEX) ? 'z' : 'd'); memcpy(cl + 4, (L->is_super) ? "super" : "simpl", 5); SEXP obj = PROTECT(newObject(cl)), dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)); INTEGER(dim)[0] = INTEGER(dim)[1] = (int) L->n; if (L->ordering != CHOLMOD_NATURAL) { SEXP perm = PROTECT(allocVector(INTSXP, L->n)); Matrix_memcpy(INTEGER(perm), L->Perm, L->n, sizeof(int)); SET_SLOT(obj, Matrix_permSym, perm); UNPROTECT(1); } SEXP type = PROTECT(allocVector(INTSXP, 6)), colcount = PROTECT(allocVector(INTSXP, L->n)); INTEGER(type)[0] = L->ordering; INTEGER(type)[1] = (L->is_super) ? 1 : L->is_ll; INTEGER(type)[2] = (L->is_super) ? 1 : 0; INTEGER(type)[3] = (L->is_super) ? 1 : L->is_monotonic; INTEGER(type)[4] = (L->is_super) ? (int) L->maxcsize : 0; INTEGER(type)[5] = (L->is_super) ? (int) L->maxesize : 0; Matrix_memcpy(INTEGER(colcount), L->ColCount, L->n, sizeof(int)); SET_SLOT(obj, install("type"), type); SET_SLOT(obj, install("colcount"), colcount); if (L->is_super) { SEXP super = PROTECT(allocVector(INTSXP, L->nsuper + 1)), pi = PROTECT(allocVector(INTSXP, L->nsuper + 1)), px = PROTECT(allocVector(INTSXP, L->nsuper + 1)), s = PROTECT(allocVector(INTSXP, L->ssize)); Matrix_memcpy(INTEGER(super), L->super, L->nsuper + 1, sizeof(int)); Matrix_memcpy(INTEGER(pi), L->pi, L->nsuper + 1, sizeof(int)); Matrix_memcpy(INTEGER(px), L->px, L->nsuper + 1, sizeof(int)); Matrix_memcpy(INTEGER(s), L->s, L->ssize, sizeof(int)); SET_SLOT(obj, install("super"), super); SET_SLOT(obj, install("pi"), pi); SET_SLOT(obj, install("px"), px); SET_SLOT(obj, install("s"), s); UNPROTECT(4); } else if (values) { SEXP p = PROTECT(allocVector(INTSXP, L->n + 1)), i = PROTECT(allocVector(INTSXP, L->nzmax)), nz = PROTECT(allocVector(INTSXP, L->n)), nxt = PROTECT(allocVector(INTSXP, L->n + 2)), prv = PROTECT(allocVector(INTSXP, L->n + 2)); Matrix_memcpy(INTEGER(p), L->p, L->n + 1, sizeof(int)); Matrix_memcpy(INTEGER(i), L->i, L->nzmax, sizeof(int)); Matrix_memcpy(INTEGER(nz), L->nz, L->n, sizeof(int)); Matrix_memcpy(INTEGER(nxt), L->next, L->n + 2, sizeof(int)); Matrix_memcpy(INTEGER(prv), L->prev, L->n + 2, sizeof(int)); SET_SLOT(obj, Matrix_pSym, p); SET_SLOT(obj, Matrix_iSym, i); SET_SLOT(obj, install("nz"), nz); SET_SLOT(obj, install("nxt"), nxt); SET_SLOT(obj, install("prv"), prv); UNPROTECT(5); } if (values) { SEXP x; R_xlen_t nx = (R_xlen_t) ((L->is_super) ? L->xsize : L->nzmax); if (L->xtype == CHOLMOD_COMPLEX) { PROTECT(x = allocVector(CPLXSXP, nx)); Matrix_memcpy(COMPLEX(x), L->x, nx, sizeof(Rcomplex)); } else { PROTECT(x = allocVector(REALSXP, nx)); Matrix_memcpy(REAL(x), L->x, nx, sizeof(double)); } SET_SLOT(obj, Matrix_xSym, x); UNPROTECT(1); } UNPROTECT(4); return obj; } SEXP CHS2M(cholmod_sparse *A, int values, char shape) { if (A->itype != CHOLMOD_INT) error(_("wrong '%s'"), "itype"); if (values && A->xtype != CHOLMOD_REAL && A->xtype != CHOLMOD_COMPLEX) error(_("wrong '%s'"), "xtype"); if (values && A->dtype != CHOLMOD_DOUBLE) error(_("wrong '%s'"), "dtype"); if (A->nrow > INT_MAX || A->ncol > INT_MAX) error(_("dimensions cannot exceed %s"), "2^31-1"); if (A->stype != 0 || !A->sorted || !A->packed) cholmod_sort(A, &c); char cl[] = "..CMatrix"; cl[0] = (!values) ? 'n' : ((A->xtype == CHOLMOD_COMPLEX) ? 'z' : 'd'); cl[1] = shape; int m = (int) A->nrow, n = (int) A->ncol, nnz = ((int *) A->p)[A->ncol]; R_xlen_t n1a = (R_xlen_t) n + 1; SEXP obj = PROTECT(newObject(cl)), dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)), p = PROTECT(allocVector(INTSXP, n1a)), i = PROTECT(allocVector(INTSXP, nnz)); INTEGER(dim)[0] = m; INTEGER(dim)[1] = n; Matrix_memcpy(INTEGER(p), A->p, n1a, sizeof(int)); Matrix_memcpy(INTEGER(i), A->i, nnz, sizeof(int)); SET_SLOT(obj, Matrix_pSym, p); SET_SLOT(obj, Matrix_iSym, i); if (values) { SEXP x; if (A->xtype == CHOLMOD_COMPLEX) { PROTECT(x = allocVector(CPLXSXP, nnz)); Matrix_memcpy(COMPLEX(x), A->x, nnz, sizeof(Rcomplex)); } else { PROTECT(x = allocVector(REALSXP, nnz)); Matrix_memcpy(REAL(x), A->x, nnz, sizeof(double)); } SET_SLOT(obj, Matrix_xSym, x); UNPROTECT(1); } UNPROTECT(4); return obj; } SEXP CHD2M(cholmod_dense *A, int trans, char shape) { if (A->xtype != CHOLMOD_REAL && A->xtype != CHOLMOD_COMPLEX) error(_("wrong '%s'"), "xtype"); if (A->dtype != CHOLMOD_DOUBLE) error(_("wrong '%s'"), "dtype"); if (A->d != A->nrow) /* MJ: currently no need to support this case */ error(_("leading dimension not equal to number of rows")); if (A->nrow > INT_MAX || A->ncol > INT_MAX) error(_("dimensions cannot exceed %s"), "2^31-1"); int m = (int) A->nrow, n = (int) A->ncol; if ((Matrix_int_fast64_t) m * n > R_XLEN_T_MAX) error(_("attempt to allocate vector of length exceeding %s"), "R_XLEN_T_MAX"); char cl[] = "...Matrix"; cl[0] = (A->xtype == CHOLMOD_COMPLEX) ? 'z' : 'd'; cl[1] = shape; cl[2] = (shape == 'g') ? 'e' : ((shape == 's') ? 'y' : ((shape == 'p') ? 'o' : 'r')); SEXP obj = PROTECT(newObject(cl)), dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)); INTEGER(dim)[0] = (trans) ? n : m; INTEGER(dim)[1] = (trans) ? m : n; SEXP x; if (A->xtype == CHOLMOD_COMPLEX) { PROTECT(x = allocVector(CPLXSXP, (R_xlen_t) m * n)); Rcomplex *px = COMPLEX(x), *py = (Rcomplex *) A->x; if (!trans) Matrix_memcpy(px, py, (R_xlen_t) m * n, sizeof(Rcomplex)); else ztranspose2(px, py, m, n); } else { PROTECT(x = allocVector(REALSXP, (R_xlen_t) m * n)); double *px = REAL(x), *py = (double *) A->x; if (!trans) Matrix_memcpy(px, py, (R_xlen_t) m * n, sizeof(double)); else dtranspose2(px, py, m, n); } SET_SLOT(obj, Matrix_xSym, x); UNPROTECT(3); return obj; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/solve.h����������������������������������������������������������������������������������0000644�0001762�0000144�00000001032�14504476335�013615� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_SOLVE_H #define MATRIX_SOLVE_H #include SEXP denseLU_solve(SEXP, SEXP); SEXP BunchKaufman_solve(SEXP, SEXP); SEXP Cholesky_solve(SEXP, SEXP); SEXP dtrMatrix_solve(SEXP, SEXP); SEXP sparseLU_solve(SEXP, SEXP, SEXP); #if 0 /* MJ: we use 'sparseQR_matmult' instead */ SEXP sparseQR_solve(SEXP, SEXP, SEXP); #endif SEXP CHMfactor_solve(SEXP, SEXP, SEXP, SEXP); SEXP dtCMatrix_solve(SEXP, SEXP, SEXP); SEXP sparseQR_matmult(SEXP, SEXP, SEXP, SEXP, SEXP); #endif /* MATRIX_SOLVE_H */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/dgCMatrix.h������������������������������������������������������������������������������0000644�0001762�0000144�00000000337�14503212600�014334� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_DGCMATRIX_H #define MATRIX_DGCMATRIX_H #include SEXP dgCMatrix_lusol(SEXP, SEXP); SEXP dgCMatrix_qrsol(SEXP, SEXP, SEXP); SEXP dgCMatrix_cholsol(SEXP, SEXP); #endif /* MATRIX_DGCMATRIX_H */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/determinant.h����������������������������������������������������������������������������0000644�0001762�0000144�00000000577�14505043347�015006� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_DETERMINANT_H #define MATRIX_DETERMINANT_H #include SEXP denseLU_determinant(SEXP, SEXP); SEXP BunchKaufman_determinant(SEXP, SEXP); SEXP Cholesky_determinant(SEXP, SEXP); SEXP sparseLU_determinant(SEXP, SEXP); SEXP sparseQR_determinant(SEXP, SEXP); SEXP CHMfactor_determinant(SEXP, SEXP, SEXP); #endif /* MATRIX_DETERMINANT_H */ ���������������������������������������������������������������������������������������������������������������������������������Matrix/src/factorizations.c�������������������������������������������������������������������������0000644�0001762�0000144�00000055473�14511304746�015533� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "Lapack-etc.h" #include "cs-etc.h" #include "cholmod-etc.h" #include "Mdefines.h" #include "factorizations.h" /* defined in ./attrib.c : */ SEXP get_factor(SEXP, const char *); void set_factor(SEXP, const char *, SEXP); static SEXP dgeMatrix_trf_(SEXP obj, int warn) { SEXP val = PROTECT(newObject("denseLU")), dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)), dimnames = PROTECT(GET_SLOT(obj, Matrix_DimNamesSym)); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1], r = (m < n) ? m : n; SET_SLOT(val, Matrix_DimSym, dim); SET_SLOT(val, Matrix_DimNamesSym, dimnames); if (r > 0) { SEXP perm = PROTECT(allocVector(INTSXP, r)), x = PROTECT(GET_SLOT(obj, Matrix_xSym)), y = PROTECT(allocVector(TYPEOF(x), XLENGTH(x))); int *pperm = INTEGER(perm), info; #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(x) == CPLXSXP) { Rcomplex *px = COMPLEX(x), *py = COMPLEX(y); Matrix_memcpy(py, px, XLENGTH(y), sizeof(Rcomplex)); F77_CALL(zgetrf)(&m, &n, py, &m, pperm, &info); ERROR_LAPACK_2(zgetrf, info, warn, U); } else { #endif double *px = REAL(x), *py = REAL(y); Matrix_memcpy(py, px, XLENGTH(y), sizeof(double)); F77_CALL(dgetrf)(&m, &n, py, &m, pperm, &info); ERROR_LAPACK_2(dgetrf, info, warn, U); #ifdef MATRIX_ENABLE_ZMATRIX } #endif SET_SLOT(val, Matrix_permSym, perm); SET_SLOT(val, Matrix_xSym, y); UNPROTECT(3); /* y, x, perm */ } UNPROTECT(3); /* dimnames, dim, val */ return val; } static SEXP dsyMatrix_trf_(SEXP obj, int warn) { SEXP val = PROTECT(newObject("BunchKaufman")), dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)), dimnames = PROTECT(GET_SLOT(obj, Matrix_DimNamesSym)), uplo = PROTECT(GET_SLOT(obj, Matrix_uploSym)); int n = INTEGER(dim)[1]; char ul = *CHAR(STRING_ELT(uplo, 0)); SET_SLOT(val, Matrix_DimSym, dim); set_symmetrized_DimNames(val, dimnames, -1); SET_SLOT(val, Matrix_uploSym, uplo); if (n > 0) { SEXP perm = PROTECT(allocVector(INTSXP, n)), x = PROTECT(GET_SLOT(obj, Matrix_xSym)), y = PROTECT(allocVector(TYPEOF(x), XLENGTH(x))); int *pperm = INTEGER(perm), info, lwork = -1; #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(x) == CPLXSXP) { Rcomplex *px = COMPLEX(x), *py = COMPLEX(y), tmp, *work; Matrix_memset(py, 0, XLENGTH(y), sizeof(Rcomplex)); F77_CALL(zlacpy)(&ul, &n, &n, px, &n, py, &n FCONE); F77_CALL(zsytrf)(&ul, &n, py, &n, pperm, &tmp, &lwork, &info FCONE); lwork = (int) tmp.r; Matrix_Calloc(work, lwork, Rcomplex); F77_CALL(zsytrf)(&ul, &n, py, &n, pperm, work, &lwork, &info FCONE); Matrix_Free(work, lwork); ERROR_LAPACK_2(zsytrf, info, warn, D); } else { #endif double *px = REAL(x), *py = REAL(y), tmp, *work; Matrix_memset(py, 0, XLENGTH(y), sizeof(double)); F77_CALL(dlacpy)(&ul, &n, &n, px, &n, py, &n FCONE); F77_CALL(dsytrf)(&ul, &n, py, &n, pperm, &tmp, &lwork, &info FCONE); lwork = (int) tmp; Matrix_Calloc(work, lwork, double); F77_CALL(dsytrf)(&ul, &n, py, &n, pperm, work, &lwork, &info FCONE); Matrix_Free(work, lwork); ERROR_LAPACK_2(dsytrf, info, warn, D); #ifdef MATRIX_ENABLE_ZMATRIX } #endif SET_SLOT(val, Matrix_permSym, perm); SET_SLOT(val, Matrix_xSym, y); UNPROTECT(3); /* y, x, perm */ } UNPROTECT(4); /* uplo, dimnames, dim, val */ return val; } static SEXP dspMatrix_trf_(SEXP obj, int warn) { SEXP val = PROTECT(newObject("pBunchKaufman")), dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)), dimnames = PROTECT(GET_SLOT(obj, Matrix_DimNamesSym)), uplo = PROTECT(GET_SLOT(obj, Matrix_uploSym)); int n = INTEGER(dim)[1]; char ul = *CHAR(STRING_ELT(uplo, 0)); SET_SLOT(val, Matrix_DimSym, dim); set_symmetrized_DimNames(val, dimnames, -1); SET_SLOT(val, Matrix_uploSym, uplo); if (n > 0) { SEXP perm = PROTECT(allocVector(INTSXP, n)), x = PROTECT(GET_SLOT(obj, Matrix_xSym)), y = PROTECT(allocVector(TYPEOF(x), XLENGTH(x))); int *pperm = INTEGER(perm), info; #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(x) == CPLXSXP) { Rcomplex *px = COMPLEX(x), *py = COMPLEX(y); Matrix_memcpy(py, px, XLENGTH(y), sizeof(Rcomplex)); F77_CALL(zsptrf)(&ul, &n, py, pperm, &info FCONE); ERROR_LAPACK_2(zsptrf, info, warn, D); } else { #endif double *px = REAL(x), *py = REAL(y); Matrix_memcpy(py, px, XLENGTH(y), sizeof(double)); F77_CALL(dsptrf)(&ul, &n, py, pperm, &info FCONE); ERROR_LAPACK_2(dsptrf, info, warn, D); #ifdef MATRIX_ENABLE_ZMATRIX } #endif SET_SLOT(val, Matrix_permSym, perm); SET_SLOT(val, Matrix_xSym, y); UNPROTECT(3); /* y, x, perm */ } UNPROTECT(4); /* uplo, dimnames, dim, val */ return val; } static SEXP dpoMatrix_trf_(SEXP obj, int warn, int pivot, double tol) { SEXP val = PROTECT(newObject("Cholesky")), dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)), dimnames = PROTECT(GET_SLOT(obj, Matrix_DimNamesSym)), uplo = PROTECT(GET_SLOT(obj, Matrix_uploSym)); int n = INTEGER(dim)[1]; char ul = *CHAR(STRING_ELT(uplo, 0)); SET_SLOT(val, Matrix_DimSym, dim); set_symmetrized_DimNames(val, dimnames, -1); SET_SLOT(val, Matrix_uploSym, uplo); if (n > 0) { SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)), y = PROTECT(allocVector(TYPEOF(x), XLENGTH(x))); int info; #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(x) == CPLXSXP) { Rcomplex *px = COMPLEX(x), *py = COMPLEX(y); Matrix_memset(py, 0, XLENGTH(y), sizeof(Rcomplex)); F77_CALL(zlacpy)(&ul, &n, &n, px, &n, py, &n FCONE); if (!pivot) { F77_CALL(zpotrf)(&ul, &n, py, &n, &info FCONE); ERROR_LAPACK_3(zpotrf, info, warn, 6); } else { SEXP perm = PROTECT(allocVector(INTSXP, n)); int *pperm = INTEGER(perm), rank; Rcomplex *work = (Rcomplex *) R_alloc((size_t) 2 * n, sizeof(Rcomplex)); F77_CALL(zpstrf)(&ul, &n, py, &n, pperm, &rank, &tol, work, &info FCONE); ERROR_LAPACK_4(zpstrf, info, rank, warn); if (info > 0) { int j, d = n - rank; py += (R_xlen_t) rank * n + rank; for (j = rank; j < n; ++j) { Matrix_memset(py, 0, d, sizeof(Rcomplex)); py += n; } } SET_SLOT(val, Matrix_permSym, perm); UNPROTECT(1); /* perm */ } } else { #endif double *px = REAL(x), *py = REAL(y); Matrix_memset(py, 0, XLENGTH(y), sizeof(double)); F77_CALL(dlacpy)(&ul, &n, &n, px, &n, py, &n FCONE); if (!pivot) { F77_CALL(dpotrf)(&ul, &n, py, &n, &info FCONE); ERROR_LAPACK_3(dpotrf, info, warn, 6); } else { SEXP perm = PROTECT(allocVector(INTSXP, n)); int *pperm = INTEGER(perm), rank; double *work = (double *) R_alloc((size_t) 2 * n, sizeof(double)); F77_CALL(dpstrf)(&ul, &n, py, &n, pperm, &rank, &tol, work, &info FCONE); ERROR_LAPACK_4(dpstrf, info, rank, warn); if (info > 0) { int j, d = n - rank; py += (R_xlen_t) rank * n + rank; for (j = rank; j < n; ++j) { Matrix_memset(py, 0, d, sizeof(double)); py += n; } } SET_SLOT(val, Matrix_permSym, perm); UNPROTECT(1); /* perm */ } #ifdef MATRIX_ENABLE_ZMATRIX } #endif SET_SLOT(val, Matrix_xSym, y); UNPROTECT(2); /* y, x */ } UNPROTECT(4); /* uplo, dimnames, dim, val */ return val; } static SEXP dppMatrix_trf_(SEXP obj, int warn) { SEXP val = PROTECT(newObject("pCholesky")), dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)), dimnames = PROTECT(GET_SLOT(obj, Matrix_DimNamesSym)), uplo = PROTECT(GET_SLOT(obj, Matrix_uploSym)); int n = INTEGER(dim)[1]; char ul = *CHAR(STRING_ELT(uplo, 0)); SET_SLOT(val, Matrix_DimSym, dim); set_symmetrized_DimNames(val, dimnames, -1); SET_SLOT(val, Matrix_uploSym, uplo); if (n > 0) { SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)), y = PROTECT(allocVector(TYPEOF(x), XLENGTH(x))); int info; #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(x) == CPLXSXP) { Rcomplex *px = COMPLEX(x), *py = COMPLEX(y); Matrix_memcpy(py, px, XLENGTH(y), sizeof(Rcomplex)); F77_CALL(zpptrf)(&ul, &n, py, &info FCONE); ERROR_LAPACK_3(zpptrf, info, warn, 6); } else { #endif double *px = REAL(x), *py = REAL(y); Matrix_memcpy(py, px, XLENGTH(y), sizeof(double)); F77_CALL(dpptrf)(&ul, &n, py, &info FCONE); ERROR_LAPACK_3(dpptrf, info, warn, 6); #ifdef MATRIX_ENABLE_ZMATRIX } #endif SET_SLOT(val, Matrix_xSym, y); UNPROTECT(2); /* y, x */ } UNPROTECT(4); /* uplo, dimnames, dim, val */ return val; } SEXP dgeMatrix_trf(SEXP obj, SEXP warn) { SEXP val = get_factor(obj, "denseLU"); if (isNull(val)) { PROTECT(val = dgeMatrix_trf_(obj, asInteger(warn))); set_factor(obj, "denseLU", val); UNPROTECT(1); } return val; } SEXP dsyMatrix_trf(SEXP obj, SEXP warn) { SEXP val = get_factor(obj, "BunchKaufman"); if (isNull(val)) { PROTECT(val = dsyMatrix_trf_(obj, asInteger(warn))); set_factor(obj, "BunchKaufman", val); UNPROTECT(1); } return val; } SEXP dspMatrix_trf(SEXP obj, SEXP warn) { SEXP val = get_factor(obj, "pBunchKaufman"); if (isNull(val)) { PROTECT(val = dspMatrix_trf_(obj, asInteger(warn))); set_factor(obj, "pBunchKaufman", val); UNPROTECT(1); } return val; } SEXP dpoMatrix_trf(SEXP obj, SEXP warn, SEXP pivot, SEXP tol) { int pivot_ = asLogical(pivot); SEXP val = get_factor(obj, (pivot_) ? "Cholesky~" : "Cholesky"); if (isNull(val)) { double tol_ = asReal(tol); PROTECT(val = dpoMatrix_trf_(obj, asInteger(warn), pivot_, tol_)); set_factor(obj, (pivot_) ? "Cholesky~" : "Cholesky", val); UNPROTECT(1); } return val; } SEXP dppMatrix_trf(SEXP obj, SEXP warn) { SEXP val = get_factor(obj, "pCholesky"); if (isNull(val)) { PROTECT(val = dppMatrix_trf_(obj, asInteger(warn))); set_factor(obj, "pCholesky", val); UNPROTECT(1); } return val; } #define DO_FREE(_A_, _S_, _N_) \ do { \ if (!(_A_)) \ _A_ = Matrix_cs_spfree(_A_); \ if (!(_S_)) \ _S_ = Matrix_cs_sfree (_S_); \ if (!(_N_)) \ _N_ = Matrix_cs_nfree (_N_); \ } while (0) #define DO_SORT(_A_) \ do { \ Matrix_cs_dropzeros(_A_); \ T = Matrix_cs_transpose(_A_, 1); \ if (!T) { \ DO_FREE(T, *S, *N); \ return 0; \ } \ _A_ = Matrix_cs_spfree(_A_); \ _A_ = Matrix_cs_transpose(T, 1); \ if (!(_A_)) { \ DO_FREE(T, *S, *N); \ return 0; \ } \ T = Matrix_cs_spfree(T); \ } while (0) static int dgCMatrix_trf_(const Matrix_cs *A, Matrix_css **S, Matrix_csn **N, int order, double tol) { Matrix_cs *T = NULL; if (!(*S = Matrix_cs_sqr(order, A, 0)) || !(*N = Matrix_cs_lu(A, *S, tol))) { DO_FREE(T, *S, *N); return 0; } DO_SORT((*N)->L); DO_SORT((*N)->U); return 1; } SEXP dgCMatrix_trf(SEXP obj, SEXP order, SEXP tol, SEXP doError) { double tol_ = asReal(tol); if (ISNAN(tol_)) error(_("'%s' is not a number"), "tol"); int order_ = asInteger(order); if (order_ == NA_INTEGER) order_ = (tol_ == 1.0) ? 2 : 1; else if (order_ < 0 || order_ > 3) order_ = 0; SEXP val = get_factor(obj, (order_) ? "sparseLU~" : "sparseLU"); if (!isNull(val)) return val; PROTECT(val = newObject("sparseLU")); Matrix_cs *A = M2CXS(obj, 1); MCS_XTYPE_SET(A->xtype); Matrix_css *S = NULL; Matrix_csn *N = NULL; int *P = NULL; if (A->m != A->n) error(_("LU factorization of m-by-n %s requires m == n"), ".gCMatrix"); if (!dgCMatrix_trf_(A, &S, &N, order_, tol_) || !(P = Matrix_cs_pinv(N->pinv, A->m))) { if (!P) { S = Matrix_cs_sfree(S); N = Matrix_cs_nfree(N); } if (asLogical(doError)) error(_("LU factorization of %s failed: out of memory or near-singular"), ".gCMatrix"); /* Defensive code will check with is(., "sparseLU") : */ UNPROTECT(1); /* val */ return ScalarLogical(NA_LOGICAL); } SEXP dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)); SET_SLOT(val, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(obj, Matrix_DimNamesSym)); SET_SLOT(val, Matrix_DimNamesSym, dimnames); UNPROTECT(1); /* dimnames */ SEXP L = PROTECT(CXS2M(N->L, 1, 't')), U = PROTECT(CXS2M(N->U, 1, 't')), uplo = PROTECT(mkString("L")); SET_SLOT(L, Matrix_uploSym, uplo); SET_SLOT(val, Matrix_LSym, L); SET_SLOT(val, Matrix_USym, U); UNPROTECT(3); /* uplo, U, L */ SEXP p = PROTECT(allocVector(INTSXP, A->m)); Matrix_memcpy(INTEGER(p), P, A->m, sizeof(int)); SET_SLOT(val, Matrix_pSym, p); UNPROTECT(1); /* p */ if (order_ > 0) { SEXP q = PROTECT(allocVector(INTSXP, A->n)); Matrix_memcpy(INTEGER(q), S->q, A->n, sizeof(int)); SET_SLOT(val, Matrix_qSym, q); UNPROTECT(1); /* q */ } S = Matrix_cs_sfree(S); N = Matrix_cs_nfree(N); P = Matrix_cs_free(P); set_factor(obj, (order_) ? "sparseLU~" : "sparseLU", val); UNPROTECT(1); /* val */ return val; } static int dgCMatrix_orf_(const Matrix_cs *A, Matrix_css **S, Matrix_csn **N, int order) { Matrix_cs *T = NULL; if (!(*S = Matrix_cs_sqr(order, A, 1)) || !(*N = Matrix_cs_qr(A, *S))) { DO_FREE(T, *S, *N); return 0; } DO_SORT((*N)->L); DO_SORT((*N)->U); return 1; } SEXP dgCMatrix_orf(SEXP obj, SEXP order, SEXP doError) { int order_ = asInteger(order); if (order_ < 0 || order_ > 3) order_ = 0; SEXP val = get_factor(obj, (order_) ? "sparseQR~" : "sparseQR"); if (!isNull(val)) return val; PROTECT(val = newObject("sparseQR")); Matrix_cs *A = M2CXS(obj, 1); MCS_XTYPE_SET(A->xtype); Matrix_css *S = NULL; Matrix_csn *N = NULL; int *P = NULL; if (A->m < A->n) error(_("QR factorization of m-by-n %s requires m >= n"), ".gCMatrix"); if (!dgCMatrix_orf_(A, &S, &N, order_) || !(P = Matrix_cs_pinv(S->pinv, S->m2))) { if (!P) { S = Matrix_cs_sfree(S); N = Matrix_cs_nfree(N); } if (asLogical(doError)) error(_("QR factorization of %s failed: out of memory"), ".gCMatrix"); /* Defensive code will check with is(., "sparseQR") : */ UNPROTECT(1); /* val */ return ScalarLogical(NA_LOGICAL); } SEXP dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)); SET_SLOT(val, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(obj, Matrix_DimNamesSym)); SET_SLOT(val, Matrix_DimNamesSym, dimnames); UNPROTECT(1); /* dimnames */ SEXP V = PROTECT(CXS2M(N->L, 1, 'g')), R = PROTECT(CXS2M(N->U, 1, 'g')); SET_SLOT(val, Matrix_VSym, V); SET_SLOT(val, Matrix_RSym, R); UNPROTECT(2); /* R, V */ SEXP beta = PROTECT(allocVector(REALSXP, A->n)); Matrix_memcpy(REAL(beta), N->B, A->n, sizeof(double)); SET_SLOT(val, Matrix_betaSym, beta); UNPROTECT(1); /* beta */ SEXP p = PROTECT(allocVector(INTSXP, S->m2)); Matrix_memcpy(INTEGER(p), P, S->m2, sizeof(int)); SET_SLOT(val, Matrix_pSym, p); UNPROTECT(1); /* p */ if (order_ > 0) { SEXP q = PROTECT(allocVector(INTSXP, A->n)); Matrix_memcpy(INTEGER(q), S->q, A->n, sizeof(int)); SET_SLOT(val, Matrix_qSym, q); UNPROTECT(1); /* q */ } S = Matrix_cs_sfree(S); N = Matrix_cs_nfree(N); P = Matrix_cs_free(P); set_factor(obj, (order_) ? "sparseQR~" : "sparseQR", val); UNPROTECT(1); /* val */ return val; } #undef DO_FREE #undef DO_SORT static int dpCMatrix_trf_(cholmod_sparse *A, cholmod_factor **L, int perm, int ldl, int super, double mult) { /* defined in ./chm_common.c : */ void R_cholmod_common_envget(void); void R_cholmod_common_envset(void); R_cholmod_common_envset(); if (*L == NULL) { if (perm == 0) { c.nmethods = 1; c.method[0].ordering = CHOLMOD_NATURAL; c.postorder = 0; } c.supernodal = (super == NA_LOGICAL) ? CHOLMOD_AUTO : ((super != 0) ? CHOLMOD_SUPERNODAL : CHOLMOD_SIMPLICIAL); *L = cholmod_analyze(A, &c); } if (super == NA_LOGICAL) super = (*L)->is_super; if (super != 0) ldl = 0; c.final_asis = 0; c.final_super = super != 0; c.final_ll = ldl == 0; c.final_pack = 1; c.final_monotonic = 1; double beta[2]; beta[0] = mult; beta[1] = 0.0; int res = cholmod_factorize_p(A, beta, NULL, 0, *L, &c); R_cholmod_common_envget(); return res; } SEXP dpCMatrix_trf(SEXP obj, SEXP perm, SEXP ldl, SEXP super, SEXP mult) { int perm_ = asLogical(perm), ldl_ = asLogical(ldl), super_ = asLogical(super); double mult_ = asReal(mult); if (!R_FINITE(mult_)) error(_("'%s' is not a number or not finite"), "mult"); SEXP trf = R_NilValue; char nm[] = "spdCholesky"; if (perm_) nm[1] = 'P'; if (super_ != NA_LOGICAL && super_ != 0) ldl_ = 0; if (super_ == NA_LOGICAL || super_ == 0) { if (ldl_) nm[2] = 'D'; trf = get_factor(obj, nm); } if (isNull(trf) && (super_ == NA_LOGICAL || super_ != 0)) { nm[0] = 'S'; nm[2] = 'd'; trf = get_factor(obj, nm); } int cached = !isNull(trf); if (cached && mult_ == 0.0) return trf; PROTECT_INDEX pid; PROTECT_WITH_INDEX(trf, &pid); cholmod_sparse *A = M2CHS(obj, 1); cholmod_factor *L = NULL; SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = *CHAR(STRING_ELT(uplo, 0)); A->stype = (ul == 'U') ? 1 : -1; if (cached) { L = M2CHF(trf, 1); L = cholmod_copy_factor(L, &c); dpCMatrix_trf_(A, &L, perm_, ldl_, super_, mult_); } else { dpCMatrix_trf_(A, &L, perm_, ldl_, super_, mult_); if (super_ == NA_LOGICAL) { nm[0] = (L->is_super) ? 'S' : 's'; nm[2] = (L->is_ll ) ? 'd' : 'D'; } } REPROTECT(trf = CHF2M(L, 1), pid); cholmod_free_factor(&L, &c); SEXP dimnames = PROTECT(GET_SLOT(obj, Matrix_DimNamesSym)); set_symmetrized_DimNames(trf, dimnames, -1); UNPROTECT(1); /* dimnames */ if (!cached && mult_ == 0.0) set_factor(obj, nm, trf); UNPROTECT(1); /* trf */ return trf; } SEXP BunchKaufman_expand(SEXP obj, SEXP packed) { SEXP P_ = PROTECT(newObject("pMatrix")), T_ = PROTECT(newObject("dtCMatrix")), D_ = PROTECT(newObject("dsCMatrix")), dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)); int i, j, s, n = INTEGER(dim)[0]; R_xlen_t n1a = (R_xlen_t) n + 1; if (n > 0) { SET_SLOT(P_, Matrix_DimSym, dim); SET_SLOT(T_, Matrix_DimSym, dim); SET_SLOT(D_, Matrix_DimSym, dim); } UNPROTECT(1); /* dim */ SEXP uplo = PROTECT(GET_SLOT(obj, Matrix_uploSym)); int upper = *CHAR(STRING_ELT(uplo, 0)) == 'U'; if (!upper) { SET_SLOT(T_, Matrix_uploSym, uplo); SET_SLOT(D_, Matrix_uploSym, uplo); } UNPROTECT(1); /* uplo */ SEXP diag = PROTECT(mkString("U")); SET_SLOT(T_, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ SEXP pivot = PROTECT(GET_SLOT(obj, Matrix_permSym)), D_p = PROTECT(allocVector(INTSXP, n1a)); int *ppivot = INTEGER(pivot), *D_pp = INTEGER(D_p), b = n, dp = (upper) ? 1 : 2; D_pp[0] = 0; j = 0; while (j < n) { if (ppivot[j] > 0) { D_pp[j+1] = D_pp[j] + 1; j += 1; } else { D_pp[j+1] = D_pp[j] + dp; D_pp[j+2] = D_pp[j] + 3; j += 2; --b; } } SET_SLOT(D_, Matrix_pSym, D_p); UNPROTECT(1); /* D_p */ SEXP P, P_perm, T, T_p, T_i, T_x, D_i = PROTECT(allocVector(INTSXP, D_pp[n])), D_x = PROTECT(allocVector(REALSXP, D_pp[n])), x = PROTECT(GET_SLOT(obj, Matrix_xSym)); int *P_pperm, *T_pp, *T_pi, *D_pi = INTEGER(D_i); double *T_px, *D_px = REAL(D_x), *px = REAL(x); int unpacked = !asLogical(packed); R_xlen_t len = (R_xlen_t) 2 * b + 1, k = (upper) ? len - 2 : 0; SEXP res = PROTECT(allocVector(VECSXP, len)); j = 0; while (b--) { s = (ppivot[j] > 0) ? 1 : 2; dp = (upper) ? j : n - j - s; PROTECT(P = duplicate(P_)); PROTECT(P_perm = allocVector(INTSXP, n)); PROTECT(T = duplicate(T_)); PROTECT(T_p = allocVector(INTSXP, n1a)); PROTECT(T_i = allocVector(INTSXP, (R_xlen_t) s * dp)); PROTECT(T_x = allocVector(REALSXP, (R_xlen_t) s * dp)); P_pperm = INTEGER(P_perm); T_pp = INTEGER(T_p); T_pi = INTEGER(T_i); T_px = REAL(T_x); T_pp[0] = 0; for (i = 0; i < j; ++i) { T_pp[i+1] = 0; P_pperm[i] = i + 1; } for (i = j; i < j+s; ++i) { T_pp[i+1] = T_pp[i] + dp; P_pperm[i] = i + 1; } for (i = j+s; i < n; ++i) { T_pp[i+1] = T_pp[i]; P_pperm[i] = i + 1; } if (s == 1) { P_pperm[j] = ppivot[j]; P_pperm[ppivot[j]-1] = j + 1; } else if (upper) { P_pperm[j] = -ppivot[j]; P_pperm[-ppivot[j]-1] = j + 1; } else { P_pperm[j+1] = -ppivot[j]; P_pperm[-ppivot[j]-1] = j + 2; } if (upper) { for (i = 0; i < j; ++i) { *(T_pi++) = i; *(T_px++) = *(px++); } *(D_pi++) = j; *(D_px++) = *(px++); ++j; if (unpacked) px += n - j; if (s == 2) { for (i = 0; i < j-1; ++i) { *(T_pi++) = i; *(T_px++) = *(px++); } *(D_pi++) = j - 1; *(D_pi++) = j; *(D_px++) = *(px++); *(D_px++) = *(px++); ++j; if (unpacked) px += n - j; } } else { if (s == 2) { *(D_pi++) = j; *(D_pi++) = j + 1; *(D_px++) = *(px++); *(D_px++) = *(px++); for (i = j+2; i < n; ++i) { *(T_pi++) = i; *(T_px++) = *(px++); } ++j; if (unpacked) px += j; } *(D_pi++) = j; *(D_px++) = *(px++); for (i = j+1; i < n; ++i) { *(T_pi++) = i; *(T_px++) = *(px++); } ++j; if (unpacked) px += j; } SET_SLOT(P, Matrix_permSym, P_perm); SET_SLOT(T, Matrix_pSym, T_p); SET_SLOT(T, Matrix_iSym, T_i); SET_SLOT(T, Matrix_xSym, T_x); if (upper) { SET_VECTOR_ELT(res, k-1, P); SET_VECTOR_ELT(res, k , T); k -= 2; } else { SET_VECTOR_ELT(res, k , P); SET_VECTOR_ELT(res, k+1, T); k += 2; } UNPROTECT(6); /* T_x, T_i, T_p, T, P_perm, P */ } SET_SLOT(D_, Matrix_iSym, D_i); SET_SLOT(D_, Matrix_xSym, D_x); SET_VECTOR_ELT(res, len-1, D_); UNPROTECT(8); /* res, x, D_x, D_i, pivot, D_, T_, P_ */ return res; } SEXP CHMfactor_diag_get(SEXP obj, SEXP square) { cholmod_factor *L = M2CHF(obj, 1); int n = (int) L->n, square_ = asLogical(square); SEXP y = PROTECT(allocVector(REALSXP, n)); double *py = REAL(y); if (L->is_super) { int k, j, nc, nsuper = (int) L->nsuper, *psuper = (int *) L->super, *ppi = (int *) L->pi, *ppx = (int *) L->px; double *px = (double *) L->x, *px_; R_xlen_t nr1a; for (k = 0; k < nsuper; ++k) { nc = psuper[k+1] - psuper[k]; nr1a = (R_xlen_t) (ppi[k+1] - ppi[k]) + 1; px_ = px + ppx[k]; for (j = 0; j < nc; ++j) { *py = *px_; if (square_) *py *= *py; ++py; px_ += nr1a; } } } else { square_ = square_ && L->is_ll; int j, *pp = (int *) L->p; double *px = (double *) L->x; for (j = 0; j < n; ++j) { *py = px[pp[j]]; if (square_) *py *= *py; ++py; } } UNPROTECT(1); return y; } SEXP CHMfactor_update(SEXP obj, SEXP parent, SEXP mult) { /* defined in ./objects.c : */ char Matrix_shape(SEXP); double mult_ = asReal(mult); if (!R_FINITE(mult_)) error(_("'%s' is not a number or not finite"), "mult"); cholmod_factor *L = cholmod_copy_factor(M2CHF(obj, 1), &c); cholmod_sparse *A = M2CHS(parent, 1); if (Matrix_shape(parent) == 's') { SEXP uplo = GET_SLOT(parent, Matrix_uploSym); char ul = *CHAR(STRING_ELT(uplo, 0)); A->stype = (ul == 'U') ? 1 : -1; } dpCMatrix_trf_(A, &L, 0, !L->is_ll, L->is_super, mult_); SEXP res = PROTECT(CHF2M(L, 1)); cholmod_free_factor(&L, &c); SEXP dimnames = PROTECT(GET_SLOT(obj, Matrix_DimNamesSym)); SET_SLOT(res, Matrix_DimNamesSym, dimnames); UNPROTECT(1); UNPROTECT(1); return res; } SEXP CHMfactor_updown(SEXP obj, SEXP parent, SEXP update) { /* defined in ./objects.c : */ char Matrix_shape(SEXP); cholmod_factor *L = cholmod_copy_factor(M2CHF(obj, 1), &c); cholmod_sparse *A = M2CHS(parent, 1); if (Matrix_shape(parent) == 's') { SEXP uplo = GET_SLOT(parent, Matrix_uploSym); char ul = *CHAR(STRING_ELT(uplo, 0)); A->stype = (ul == 'U') ? 1 : -1; } cholmod_updown(asLogical(update) != 0, A, L, &c); SEXP res = PROTECT(CHF2M(L, 1)); cholmod_free_factor(&L, &c); SEXP dimnames = PROTECT(GET_SLOT(obj, Matrix_DimNamesSym)); SET_SLOT(res, Matrix_DimNamesSym, dimnames); UNPROTECT(1); UNPROTECT(1); return res; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/solve.c����������������������������������������������������������������������������������0000644�0001762�0000144�00000070663�14512321002�013603� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "Lapack-etc.h" #include "cs-etc.h" #include "cholmod-etc.h" #include "Mdefines.h" #include "idz.h" #include "solve.h" static void solveDN(SEXP rdn, SEXP adn, SEXP bdn) { SEXP s; if (!isNull(s = VECTOR_ELT(adn, 1))) SET_VECTOR_ELT(rdn, 0, s); if (!isNull(s = VECTOR_ELT(bdn, 1))) SET_VECTOR_ELT(rdn, 1, s); PROTECT(adn = getAttrib(adn, R_NamesSymbol)); PROTECT(bdn = getAttrib(bdn, R_NamesSymbol)); if(!isNull(adn) || !isNull(bdn)) { PROTECT(s = allocVector(STRSXP, 2)); if (!isNull(adn)) SET_STRING_ELT(s, 0, STRING_ELT(adn, 1)); if (!isNull(bdn)) SET_STRING_ELT(s, 1, STRING_ELT(bdn, 1)); setAttrib(rdn, R_NamesSymbol, s); UNPROTECT(1); } UNPROTECT(2); return; } SEXP denseLU_solve(SEXP a, SEXP b) { #define SOLVE_START \ SEXP adim = GET_SLOT(a, Matrix_DimSym); \ int *padim = INTEGER(adim), m = padim[0], n = padim[1]; \ if (m != n) \ error(_("'%s' is not square"), "a"); \ if (!isNull(b)) { \ SEXP bdim = GET_SLOT(b, Matrix_DimSym); \ int *pbdim = INTEGER(bdim); \ if (pbdim[0] != m) \ error(_("dimensions of '%s' and '%s' are inconsistent"), \ "a", "b"); \ n = pbdim[1]; \ } #define SOLVE_FINISH \ SEXP rdimnames = PROTECT(GET_SLOT(r, Matrix_DimNamesSym)), \ adimnames = PROTECT(GET_SLOT(a, Matrix_DimNamesSym)); \ if (isNull(b)) \ revDN(rdimnames, adimnames); \ else { \ SEXP bdimnames = PROTECT(GET_SLOT(b, Matrix_DimNamesSym)); \ solveDN(rdimnames, adimnames, bdimnames); \ UNPROTECT(1); /* bdimnames */ \ } \ UNPROTECT(2); /* adimnames, rdimnames */ SOLVE_START; SEXP ax = PROTECT(GET_SLOT(a, Matrix_xSym)); char rcl[] = ".geMatrix"; rcl[0] = (TYPEOF(ax) == CPLXSXP) ? 'z' : 'd'; SEXP r = PROTECT(newObject(rcl)); SEXP rdim = GET_SLOT(r, Matrix_DimSym); int *prdim = INTEGER(rdim); prdim[0] = m; prdim[1] = n; if (m > 0) { SEXP apivot = PROTECT(GET_SLOT(a, Matrix_permSym)), rx; int info; if (isNull(b)) { rx = duplicate(ax); PROTECT(rx); int lwork = -1; #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(ax) == CPLXSXP) { Rcomplex work0, *work = &work0; F77_CALL(zgetri)(&m, COMPLEX(rx), &m, INTEGER(apivot), work, &lwork, &info); ERROR_LAPACK_1(zgetri, info); lwork = (int) work0.r; work = (Rcomplex *) R_alloc((size_t) lwork, sizeof(Rcomplex)); F77_CALL(zgetri)(&m, COMPLEX(rx), &m, INTEGER(apivot), work, &lwork, &info); ERROR_LAPACK_2(zgetri, info, 2, U); } else { #endif double work0, *work = &work0; F77_CALL(dgetri)(&m, REAL(rx), &m, INTEGER(apivot), work, &lwork, &info); ERROR_LAPACK_1(dgetri, info); lwork = (int) work0; work = (double *) R_alloc((size_t) lwork, sizeof(double )); F77_CALL(dgetri)(&m, REAL(rx), &m, INTEGER(apivot), work, &lwork, &info); ERROR_LAPACK_2(dgetri, info, 2, U); #ifdef MATRIX_ENABLE_ZMATRIX } #endif } else { SEXP bx = PROTECT(GET_SLOT(b, Matrix_xSym)); rx = duplicate(bx); UNPROTECT(1); /* bx */ PROTECT(rx); #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(ax) == CPLXSXP) { F77_CALL(zgetrs)("N", &m, &n, COMPLEX(ax), &m, INTEGER(apivot), COMPLEX(rx), &m, &info FCONE); ERROR_LAPACK_1(zgetrs, info); } else { #endif F77_CALL(dgetrs)("N", &m, &n, REAL(ax), &m, INTEGER(apivot), REAL(rx), &m, &info FCONE); ERROR_LAPACK_1(dgetrs, info); #ifdef MATRIX_ENABLE_ZMATRIX } #endif } SET_SLOT(r, Matrix_xSym, rx); UNPROTECT(2); /* rx, apivot */ } SOLVE_FINISH; UNPROTECT(2); /* r, ax */ return r; } SEXP BunchKaufman_solve(SEXP a, SEXP b) { SOLVE_START; SEXP ax = PROTECT(GET_SLOT(a, Matrix_xSym)); int unpacked = (Matrix_int_fast64_t) m * m <= R_XLEN_T_MAX && XLENGTH(ax) == (R_xlen_t) m * m; char rcl[] = "...Matrix"; rcl[0] = (TYPEOF(ax) == CPLXSXP) ? 'z' : 'd'; if (!isNull(b)) { rcl[1] = 'g'; rcl[2] = 'e'; } else { rcl[1] = 's'; rcl[2] = (unpacked) ? 'y' : 'p'; } SEXP r = PROTECT(newObject(rcl)); SEXP rdim = GET_SLOT(r, Matrix_DimSym); int *prdim = INTEGER(rdim); prdim[0] = m; prdim[1] = n; SEXP auplo = GET_SLOT(a, Matrix_uploSym); char aul = CHAR(STRING_ELT(auplo, 0))[0]; if (isNull(b) && aul != 'U') { PROTECT(auplo); SET_SLOT(r, Matrix_uploSym, auplo); UNPROTECT(1); /* auplo */ } if (m > 0) { SEXP apivot = PROTECT(GET_SLOT(a, Matrix_permSym)), rx; int info; if (isNull(b)) { rx = duplicate(ax); PROTECT(rx); #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(ax) == CPLXSXP) { Rcomplex *work = (Rcomplex *) R_alloc((size_t) m, sizeof(Rcomplex)); if (unpacked) { F77_CALL(zsytri)(&aul, &m, COMPLEX(rx), &m, INTEGER(apivot), work, &info FCONE); ERROR_LAPACK_2(zsytri, info, 2, D); } else { F77_CALL(zsptri)(&aul, &m, COMPLEX(rx), INTEGER(apivot), work, &info FCONE); ERROR_LAPACK_2(zsptri, info, 2, D); } } else { #endif double *work = (double *) R_alloc((size_t) m, sizeof(double )); if (unpacked) { F77_CALL(dsytri)(&aul, &m, REAL(rx), &m, INTEGER(apivot), work, &info FCONE); ERROR_LAPACK_2(dsytri, info, 2, D); } else { F77_CALL(dsptri)(&aul, &m, REAL(rx), INTEGER(apivot), work, &info FCONE); ERROR_LAPACK_2(dsptri, info, 2, D); } #ifdef MATRIX_ENABLE_ZMATRIX } #endif } else { SEXP bx = PROTECT(GET_SLOT(b, Matrix_xSym)); rx = duplicate(bx); UNPROTECT(1); /* bx */ PROTECT(rx); #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(ax) == CPLXSXP) { if (unpacked) { F77_CALL(zsytrs)(&aul, &m, &n, COMPLEX(ax), &m, INTEGER(apivot), COMPLEX(rx), &m, &info FCONE); ERROR_LAPACK_1(zsytrs, info); } else { F77_CALL(zsptrs)(&aul, &m, &n, COMPLEX(ax), INTEGER(apivot), COMPLEX(rx), &m, &info FCONE); ERROR_LAPACK_1(zsptrs, info); } } else { #endif if (unpacked) { F77_CALL(dsytrs)(&aul, &m, &n, REAL(ax), &m, INTEGER(apivot), REAL(rx), &m, &info FCONE); ERROR_LAPACK_1(dsytrs, info); } else { F77_CALL(dsptrs)(&aul, &m, &n, REAL(ax), INTEGER(apivot), REAL(rx), &m, &info FCONE); ERROR_LAPACK_1(dsptrs, info); } #ifdef MATRIX_ENABLE_ZMATRIX } #endif } SET_SLOT(r, Matrix_xSym, rx); UNPROTECT(2); /* rx, apivot */ } SOLVE_FINISH; UNPROTECT(2); /* r, ax */ return r; } SEXP Cholesky_solve(SEXP a, SEXP b) { SOLVE_START; SEXP ax = PROTECT(GET_SLOT(a, Matrix_xSym)); int unpacked = (Matrix_int_fast64_t) m * m <= R_XLEN_T_MAX && XLENGTH(ax) == (R_xlen_t) m * m; char rcl[] = "...Matrix"; rcl[0] = (TYPEOF(ax) == CPLXSXP) ? 'z' : 'd'; if (!isNull(b)) { rcl[1] = 'g'; rcl[2] = 'e'; } else { rcl[1] = 'p'; rcl[2] = (unpacked) ? 'o' : 'p'; } SEXP r = PROTECT(newObject(rcl)); SEXP rdim = GET_SLOT(r, Matrix_DimSym); int *prdim = INTEGER(rdim); prdim[0] = m; prdim[1] = n; SEXP auplo = GET_SLOT(a, Matrix_uploSym); char aul = CHAR(STRING_ELT(auplo, 0))[0]; if (isNull(b) && aul != 'U') { PROTECT(auplo); SET_SLOT(r, Matrix_uploSym, auplo); UNPROTECT(1); /* auplo */ } if (m > 0) { SEXP rx, aperm = PROTECT(getAttrib(a, Matrix_permSym)); int info, pivoted = TYPEOF(aperm) == INTSXP && LENGTH(aperm) > 0; if (isNull(b)) { rx = duplicate(ax); PROTECT(rx); #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(ax) == CPLXSXP) { if (unpacked) { F77_CALL(zpotri)(&aul, &m, COMPLEX(rx), &m, &info FCONE); ERROR_LAPACK_2(zpotri, info, 2, L); if (pivoted) zsymperm2(COMPLEX(rx), n, aul, INTEGER(aperm), 1, 1); } else { F77_CALL(zpptri)(&aul, &m, COMPLEX(rx), &info FCONE); ERROR_LAPACK_2(zpptri, info, 2, L); if (pivoted) { /* FIXME: zsymperm2 supporting packed matrices */ double *work; size_t lwork = (size_t) n * n; Matrix_Calloc(work, lwork, Rcomplex); zunpack1 (work, COMPLEX(rx), n, aul, 'N'); zsymperm2(work, n, aul, INTEGER(aperm), 1, 1); zpack2 (COMPLEX(rx), work, n, aul, 'N'); Matrix_Free(work, lwork); } } } else { #endif if (unpacked) { F77_CALL(dpotri)(&aul, &m, REAL(rx), &m, &info FCONE); ERROR_LAPACK_2(dpotri, info, 2, L); if (pivoted) dsymperm2( REAL(rx), n, aul, INTEGER(aperm), 1, 1); } else { F77_CALL(dpptri)(&aul, &m, REAL(rx), &info FCONE); ERROR_LAPACK_2(dpptri, info, 2, L); if (pivoted) { /* FIXME: dsymperm2 supporting packed matrices */ double *work; size_t lwork = (size_t) n * n; Matrix_Calloc(work, lwork, double); dunpack1 (work, REAL(rx), n, aul, 'N'); dsymperm2(work, n, aul, INTEGER(aperm), 1, 1); dpack2 ( REAL(rx), work, n, aul, 'N'); Matrix_Free(work, lwork); } } #ifdef MATRIX_ENABLE_ZMATRIX } #endif } else { SEXP bx = PROTECT(GET_SLOT(b, Matrix_xSym)); rx = duplicate(bx); UNPROTECT(1); /* bx */ PROTECT(rx); #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(ax) == CPLXSXP) { if (pivoted) zrowperm2(COMPLEX(rx), m, n, INTEGER(aperm), 1, 0); if (unpacked) { F77_CALL(zpotrs)(&aul, &m, &n, COMPLEX(ax), &m, COMPLEX(rx), &m, &info FCONE); ERROR_LAPACK_1(zpotrs, info); } else { F77_CALL(zpptrs)(&aul, &m, &n, COMPLEX(ax), COMPLEX(rx), &m, &info FCONE); ERROR_LAPACK_1(zpptrs, info); } if (pivoted) zrowperm2(COMPLEX(rx), m, n, INTEGER(aperm), 1, 1); } else { #endif if (pivoted) drowperm2( REAL(rx), m, n, INTEGER(aperm), 1, 0); if (unpacked) { F77_CALL(dpotrs)(&aul, &m, &n, REAL(ax), &m, REAL(rx), &m, &info FCONE); ERROR_LAPACK_1(dpotrs, info); } else { F77_CALL(dpptrs)(&aul, &m, &n, REAL(ax), REAL(rx), &m, &info FCONE); ERROR_LAPACK_1(dpptrs, info); } if (pivoted) drowperm2( REAL(rx), m, n, INTEGER(aperm), 1, 1); #ifdef MATRIX_ENABLE_ZMATRIX } #endif } SET_SLOT(r, Matrix_xSym, rx); UNPROTECT(2); /* rx, aperm */ } SOLVE_FINISH; UNPROTECT(2); /* r, ax */ return r; } SEXP dtrMatrix_solve(SEXP a, SEXP b) { SOLVE_START; SEXP ax = PROTECT(GET_SLOT(a, Matrix_xSym)); int unpacked = (Matrix_int_fast64_t) m * m <= R_XLEN_T_MAX && XLENGTH(ax) == (R_xlen_t) m * m; char rcl[] = "...Matrix"; rcl[0] = (TYPEOF(ax) == CPLXSXP) ? 'z' : 'd'; if (!isNull(b)) { rcl[1] = 'g'; rcl[2] = 'e'; } else { rcl[1] = 't'; rcl[2] = (unpacked) ? 'r' : 'p'; } SEXP r = PROTECT(newObject(rcl)); SEXP rdim = GET_SLOT(r, Matrix_DimSym); int *prdim = INTEGER(rdim); prdim[0] = m; prdim[1] = n; SEXP auplo = GET_SLOT(a, Matrix_uploSym); char aul = CHAR(STRING_ELT(auplo, 0))[0]; if (isNull(b) && aul != 'U') { PROTECT(auplo); SET_SLOT(r, Matrix_uploSym, auplo); UNPROTECT(1); /* auplo */ } SEXP adiag = GET_SLOT(a, Matrix_diagSym); char adi = CHAR(STRING_ELT(adiag, 0))[0]; if (isNull(b) && adi != 'N') { PROTECT(adiag); SET_SLOT(r, Matrix_diagSym, adiag); UNPROTECT(1); /* adiag */ } if (m > 0) { SEXP rx; int info; if (isNull(b)) { rx = duplicate(ax); PROTECT(rx); #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(ax) == CPLXSXP) { if (unpacked) { F77_CALL(ztrtri)(&aul, &adi, &m, COMPLEX(rx), &m, &info FCONE FCONE); ERROR_LAPACK_2(ztrtri, info, 2, A); } else { F77_CALL(ztptri)(&aul, &adi, &m, COMPLEX(rx), &info FCONE FCONE); ERROR_LAPACK_2(ztptri, info, 2, A); } } else { #endif if (unpacked) { F77_CALL(dtrtri)(&aul, &adi, &m, REAL(rx), &m, &info FCONE FCONE); ERROR_LAPACK_2(dtrtri, info, 2, A); } else { F77_CALL(dtptri)(&aul, &adi, &m, REAL(rx), &info FCONE FCONE); ERROR_LAPACK_2(dtptri, info, 2, A); } #ifdef MATRIX_ENABLE_ZMATRIX } #endif } else { SEXP bx = PROTECT(GET_SLOT(b, Matrix_xSym)); rx = duplicate(bx); UNPROTECT(1); /* bx */ PROTECT(rx); #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(ax) == CPLXSXP) { if (unpacked) { F77_CALL(ztrtrs)(&aul, "N", &adi, &m, &n, COMPLEX(ax), &m, COMPLEX(rx), &m, &info FCONE FCONE FCONE); ERROR_LAPACK_1(ztrtrs, info); } else { F77_CALL(ztptrs)(&aul, "N", &adi, &m, &n, COMPLEX(ax), COMPLEX(rx), &m, &info FCONE FCONE FCONE); ERROR_LAPACK_1(ztptrs, info); } } else { #endif if (unpacked) { F77_CALL(dtrtrs)(&aul, "N", &adi, &m, &n, REAL(ax), &m, REAL(rx), &m, &info FCONE FCONE FCONE); ERROR_LAPACK_1(dtrtrs, info); } else { // https://bugs.r-project.org/show_bug.cgi?id=18534 F77_CALL(dtptrs)(&aul, "N", &adi, &m, &n, REAL(ax), REAL(rx), &m, &info # ifdef usePR18534fix FCONE FCONE FCONE); # else FCONE FCONE); # endif ERROR_LAPACK_1(dtptrs, info); } #ifdef MATRIX_ENABLE_ZMATRIX } #endif } SET_SLOT(r, Matrix_xSym, rx); UNPROTECT(1); /* rx */ } SOLVE_FINISH; UNPROTECT(2); /* r, ax */ return r; } #define IF_COMPLEX(_IF_, _ELSE_) \ ((MCS_XTYPE_GET() == MCS_COMPLEX) ? (_IF_) : (_ELSE_)) SEXP sparseLU_solve(SEXP a, SEXP b, SEXP sparse) { #define ERROR_SOLVE_OOM(_ACL_, _BCL_) \ error(_("%s(<%s>, <%s>) failed: out of memory"), "solve", _ACL_, _BCL_) SOLVE_START; SEXP r, aL = PROTECT(GET_SLOT(a, Matrix_LSym)), aU = PROTECT(GET_SLOT(a, Matrix_USym)), ap = PROTECT(GET_SLOT(a, Matrix_pSym)), aq = PROTECT(GET_SLOT(a, Matrix_qSym)); int i, j, *pap = (LENGTH(ap)) ? INTEGER(ap) : NULL, *paq = (LENGTH(aq)) ? INTEGER(aq) : NULL; Matrix_cs *L = M2CXS(aL, 1), *U = M2CXS(aU, 1); MCS_XTYPE_SET(L->xtype); if (!asLogical(sparse)) { char rcl[] = ".geMatrix"; rcl[0] = IF_COMPLEX('z', 'd'); PROTECT(r = newObject(rcl)); SEXP rdim = GET_SLOT(r, Matrix_DimSym); int *prdim = INTEGER(rdim); prdim[0] = m; prdim[1] = n; R_xlen_t mn = (R_xlen_t) m * n; SEXP rx = PROTECT(allocVector(IF_COMPLEX(CPLXSXP, REALSXP), mn)); if (isNull(b)) { #define SOLVE_DENSE_1(_CTYPE_, _PTR_, _ONE_) \ do { \ _CTYPE_ *prx = _PTR_(rx), \ *work = (_CTYPE_ *) R_alloc((size_t) m, sizeof(_CTYPE_)); \ Matrix_memset(prx, 0, mn, sizeof(_CTYPE_)); \ for (j = 0; j < n; ++j) { \ prx[j] = _ONE_; \ Matrix_cs_pvec(pap, prx, work, m); \ Matrix_cs_lsolve(L, work); \ Matrix_cs_usolve(U, work); \ Matrix_cs_ipvec(paq, work, prx, m); \ prx += m; \ } \ } while (0) #ifdef MATRIX_ENABLE_ZMATRIX if (MCS_XTYPE_GET() == MCS_COMPLEX) SOLVE_DENSE_1(Rcomplex, COMPLEX, Matrix_zone); else #endif SOLVE_DENSE_1(double, REAL, 1.0); #undef SOLVE_DENSE_1 } else { SEXP bx = PROTECT(GET_SLOT(b, Matrix_xSym)); #define SOLVE_DENSE_2(_CTYPE_, _PTR_) \ do { \ _CTYPE_ *prx = _PTR_(rx), *pbx = _PTR_(bx), \ *work = (_CTYPE_ *) R_alloc((size_t) m, sizeof(_CTYPE_)); \ for (j = 0; j < n; ++j) { \ Matrix_cs_pvec(pap, pbx, work, m); \ Matrix_cs_lsolve(L, work); \ Matrix_cs_usolve(U, work); \ Matrix_cs_ipvec(paq, work, prx, m); \ prx += m; \ pbx += m; \ } \ } while (0) #ifdef MATRIX_ENABLE_ZMATRIX if (MCS_XTYPE_GET() == MCS_COMPLEX) SOLVE_DENSE_2(Rcomplex, COMPLEX); else #endif SOLVE_DENSE_2(double, REAL); #undef SOLVE_DENSE_2 UNPROTECT(1); /* bx */ } SET_SLOT(r, Matrix_xSym, rx); UNPROTECT(1); /* rx */ } else { Matrix_cs *B = NULL, *X = NULL; if (isNull(b)) { B = Matrix_cs_speye(m, m, 1, 0); if (B && pap) for (i = 0; i < m; ++i) B->i[pap[i]] = i; } else { B = M2CXS(b, 1); if (B && pap) { int *papinv = Matrix_cs_pinv(pap, m); if (!papinv) ERROR_SOLVE_OOM("sparseLU", ".gCMatrix"); B = Matrix_cs_permute(B, papinv, NULL, 1); papinv = Matrix_cs_free(papinv); } } if (!B) ERROR_SOLVE_OOM("sparseLU", ".gCMatrix"); int Bfr = isNull(b) || pap; int k, top, nz, nzmax, *iwork = (int *) R_alloc((size_t) 2 * m, sizeof(int)); #define SOLVE_SPARSE_TRIANGULAR(_CTYPE_, _A_, _ALO_, _BFR_, _ACL_, _BCL_) \ do { \ X = Matrix_cs_spalloc(m, n, B->nzmax, 1, 0); \ if (!X) { \ if (_BFR_) \ B = Matrix_cs_spfree(B); \ ERROR_SOLVE_OOM(_ACL_, _BCL_); \ } \ _CTYPE_ *X__x = (_CTYPE_ *) X->x; \ X->p[0] = nz = 0; \ nzmax = X->nzmax; \ for (j = 0, k = 0; j < n; ++j) { \ top = Matrix_cs_spsolve(_A_, B, j, iwork, work, NULL, _ALO_); \ if (m - top > INT_MAX - nz) { \ if (_BFR_) \ B = Matrix_cs_spfree(B); \ X = Matrix_cs_spfree(X); \ error(_("attempt to construct %s with more than %s nonzero elements"), \ "sparseMatrix", "2^31-1"); \ } \ nz += m - top; \ if (nz > nzmax) { \ nzmax = (nz <= INT_MAX / 2) ? 2 * nz : INT_MAX; \ if (!Matrix_cs_sprealloc(X, nzmax)) { \ if (_BFR_) \ B = Matrix_cs_spfree(B); \ X = Matrix_cs_spfree(X); \ ERROR_SOLVE_OOM(_ACL_, _BCL_); \ } \ X__x = (_CTYPE_ *) X->x; \ } \ X->p[j + 1] = nz; \ if (_ALO_) { \ for (i = top; i < m; ++i) { \ X->i[k] = iwork[i] ; \ X__x[k] = work[iwork[i]]; \ ++k; \ } \ } else { \ for (i = m - 1; i >= top; --i) { \ X->i[k] = iwork[i] ; \ X__x[k] = work[iwork[i]]; \ ++k; \ } \ } \ } \ if (_BFR_) \ B = Matrix_cs_spfree(B); \ B = X; \ } while (0) #define SOLVE_SPARSE(_CTYPE_) \ do { \ _CTYPE_ *work = (_CTYPE_ *) R_alloc((size_t) m, sizeof(_CTYPE_)); \ SOLVE_SPARSE_TRIANGULAR(_CTYPE_, L, 1, Bfr, \ "sparseLU", ".gCMatrix"); \ SOLVE_SPARSE_TRIANGULAR(_CTYPE_, U, 0, 1, \ "sparseLU", ".gCMatrix"); \ } while (0) #ifdef MATRIX_ENABLE_ZMATRIX if (MCS_XTYPE_GET() == MCS_COMPLEX) SOLVE_SPARSE(Rcomplex); else #endif SOLVE_SPARSE(double); #undef SOLVE_SPARSE if (paq) { X = Matrix_cs_permute(B, paq, NULL, 1); B = Matrix_cs_spfree(B); if (!X) ERROR_SOLVE_OOM("sparseLU", ".gCMatrix"); B = X; } /* Drop zeros from B and sort it : */ Matrix_cs_dropzeros(B); X = Matrix_cs_transpose(B, 1); B = Matrix_cs_spfree(B); if (!X) ERROR_SOLVE_OOM("sparseLU", ".gCMatrix"); B = Matrix_cs_transpose(X, 1); X = Matrix_cs_spfree(X); if (!B) ERROR_SOLVE_OOM("sparseLU", ".gCMatrix"); PROTECT(r = CXS2M(B, 1, 'g')); B = Matrix_cs_spfree(B); } SOLVE_FINISH; UNPROTECT(5); /* r, aq, ap, aU, aL */ return r; } static int strmatch(const char *x, const char **valid) { int i = 0; while (valid[i][0] != '\0') { if (strcmp(x, valid[i]) == 0) return i; ++i; } return -1; } SEXP CHMfactor_solve(SEXP a, SEXP b, SEXP sparse, SEXP system) { static const char *valid[] = { "A", "LDLt", "LD", "DLt", "L", "Lt", "D", "P", "Pt", "" }; int ivalid = -1; if (TYPEOF(system) != STRSXP || LENGTH(system) < 1 || (system = STRING_ELT(system, 0)) == NA_STRING || (ivalid = strmatch(CHAR(system), valid)) < 0) error(_("invalid '%s' to '%s'"), "system", __func__); SOLVE_START; SEXP r; int j; cholmod_factor *L = M2CHF(a, 1); if (!asLogical(sparse)) { cholmod_dense *B = NULL, *X = NULL; if (isNull(b)) { B = cholmod_allocate_dense(m, n, m, L->xtype, &c); if (!B) ERROR_SOLVE_OOM("CHMfactor", ".geMatrix"); R_xlen_t m1a = (R_xlen_t) m + 1; #define EYE(_CTYPE_, _ONE_) \ do { \ _CTYPE_ *B__x = (_CTYPE_ *) B->x; \ Matrix_memset(B__x, 0, (R_xlen_t) m * n, sizeof(_CTYPE_)); \ for (j = 0; j < n; ++j) { \ *B__x = _ONE_; \ B__x += m1a; \ } \ } while (0) #ifdef MATRIX_ENABLE_ZMATRIX if (L->xtype == CHOLMOD_COMPLEX) EYE(Rcomplex, Matrix_zone); else #endif EYE(double, 1.0); #undef EYE X = cholmod_solve(ivalid, L, B, &c); cholmod_free_dense(&B, &c); if (!X) ERROR_SOLVE_OOM("CHMfactor", ".geMatrix"); PROTECT(r = CHD2M(X, 0, (ivalid < 2) ? 'p' : ((ivalid < 7) ? 't' : 'g'))); } else { B = M2CHD(b, 0); X = cholmod_solve(ivalid, L, B, &c); if (!X) ERROR_SOLVE_OOM("CHMfactor", ".geMatrix"); PROTECT(r = CHD2M(X, 0, 'g')); } cholmod_free_dense(&X, &c); } else { cholmod_sparse *B = NULL, *X = NULL; if (isNull(b)) { B = cholmod_speye(m, n, L->xtype, &c); if (!B) ERROR_SOLVE_OOM("CHMfactor", ".gCMatrix"); X = cholmod_spsolve(ivalid, L, B, &c); cholmod_free_sparse(&B, &c); if (X && ivalid < 7) { X->stype = (ivalid == 2 || ivalid == 4) ? -1 : 1; cholmod_sort(X, &c); } if (!X) ERROR_SOLVE_OOM("CHMfactor", ".gCMatrix"); PROTECT(r = CHS2M(X, 1, (ivalid < 2) ? 's' : ((ivalid < 7) ? 't' : 'g'))); } else { B = M2CHS(b, 1); X = cholmod_spsolve(ivalid, L, B, &c); if (!X) ERROR_SOLVE_OOM("CHMfactor", ".gCMatrix"); PROTECT(r = CHS2M(X, 1, 'g')); } cholmod_free_sparse(&X, &c); } if (isNull(b) && (ivalid == 2 || ivalid == 4)) { SEXP uplo = PROTECT(mkString("L")); SET_SLOT(r, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ } SOLVE_FINISH; UNPROTECT(1); /* r */ return r; } SEXP dtCMatrix_solve(SEXP a, SEXP b, SEXP sparse) { SOLVE_START; SEXP r, auplo = PROTECT(GET_SLOT(a, Matrix_uploSym)); char aul = *CHAR(STRING_ELT(auplo, 0)); int i, j; Matrix_cs *A = M2CXS(a, 1); MCS_XTYPE_SET(A->xtype); if (!asLogical(sparse)) { char rcl[] = "...Matrix"; rcl[0] = IF_COMPLEX('z', 'd'); rcl[1] = (isNull(b)) ? 't' : 'g'; rcl[2] = (isNull(b)) ? 'r' : 'e'; PROTECT(r = newObject(rcl)); SEXP rdim = GET_SLOT(r, Matrix_DimSym); int *prdim = INTEGER(rdim); prdim[0] = m; prdim[1] = n; R_xlen_t mn = (R_xlen_t) m * n; SEXP rx = PROTECT(allocVector(IF_COMPLEX(CPLXSXP, REALSXP), mn)); if (isNull(b)) { #define SOLVE_DENSE_1(_CTYPE_, _PTR_, _ONE_) \ do { \ _CTYPE_ *prx = _PTR_(rx); \ Matrix_memset(prx, 0, mn, sizeof(_CTYPE_)); \ for (j = 0; j < n; ++j) { \ prx[j] = _ONE_; \ if (aul == 'U') \ Matrix_cs_usolve(A, prx); \ else \ Matrix_cs_lsolve(A, prx); \ prx += m; \ } \ } while (0) #ifdef MATRIX_ENABLE_ZMATRIX if (MCS_XTYPE_GET() == MCS_COMPLEX) SOLVE_DENSE_1(Rcomplex, COMPLEX, Matrix_zone); else #endif SOLVE_DENSE_1(double, REAL, 1.0); #undef SOLVE_DENSE_1 } else { SEXP bx = PROTECT(GET_SLOT(b, Matrix_xSym)); #define SOLVE_DENSE_2(_CTYPE_, _PTR_) \ do { \ _CTYPE_ *prx = _PTR_(rx), *pbx = _PTR_(bx); \ Matrix_memcpy(prx, pbx, mn, sizeof(_CTYPE_)); \ for (j = 0; j < n; ++j) { \ if (aul == 'U') \ Matrix_cs_usolve(A, prx); \ else \ Matrix_cs_lsolve(A, prx); \ prx += m; \ } \ } while (0) #ifdef MATRIX_ENABLE_ZMATRIX if (MCS_XTYPE_GET() == MCS_COMPLEX) SOLVE_DENSE_2(Rcomplex, COMPLEX); else #endif SOLVE_DENSE_2(double, REAL); #undef SOLVE_DENSE_2 UNPROTECT(1); /* bx */ } SET_SLOT(r, Matrix_xSym, rx); UNPROTECT(1); /* rx */ } else { Matrix_cs *B = NULL, *X = NULL; if (isNull(b)) B = Matrix_cs_speye(m, m, 1, 0); else B = M2CXS(b, 1); if (!B) ERROR_SOLVE_OOM("sparseLU", ".gCMatrix"); int k, top, nz, nzmax, *iwork = (int *) R_alloc((size_t) 2 * m, sizeof(int)); #define SOLVE_SPARSE(_CTYPE_) \ do { \ _CTYPE_ *work = (_CTYPE_ *) R_alloc((size_t) m, sizeof(_CTYPE_)); \ SOLVE_SPARSE_TRIANGULAR(_CTYPE_, A, aul != 'U', isNull(b), \ ".tCMatrix", ".gCMatrix"); \ } while (0) #ifdef MATRIX_ENABLE_ZMATRIX if (MCS_XTYPE_GET() == MCS_COMPLEX) SOLVE_SPARSE(Rcomplex); else #endif SOLVE_SPARSE(double); #undef SOLVE_SPARSE /* Drop zeros from B and sort it : */ Matrix_cs_dropzeros(B); X = Matrix_cs_transpose(B, 1); B = Matrix_cs_spfree(B); if (!X) ERROR_SOLVE_OOM(".tCMatrix", ".gCMatrix"); B = Matrix_cs_transpose(X, 1); X = Matrix_cs_spfree(X); if (!B) ERROR_SOLVE_OOM(".tCMatrix", ".gCMatrix"); PROTECT(r = CXS2M(B, 1, (isNull(b)) ? 't' : 'g')); B = Matrix_cs_spfree(B); } if (isNull(b)) SET_SLOT(r, Matrix_uploSym, auplo); SOLVE_FINISH; UNPROTECT(2); /* r, auplo */ return r; } SEXP sparseQR_matmult(SEXP qr, SEXP y, SEXP op, SEXP complete, SEXP yxjj) { SEXP V = PROTECT(GET_SLOT(qr, Matrix_VSym)); Matrix_cs *V_ = M2CXS(V, 1); MCS_XTYPE_SET(V_->xtype); SEXP beta = PROTECT(GET_SLOT(qr, Matrix_betaSym)); double *pbeta = REAL(beta); SEXP p = PROTECT(GET_SLOT(qr, Matrix_pSym)); int *pp = (LENGTH(p) > 0) ? INTEGER(p) : NULL; int m = V_->m, r = V_->n, n, i, j, op_ = asInteger(op), nprotect = 5; SEXP yx; if (isNull(y)) { n = (asLogical(complete)) ? m : r; R_xlen_t mn = (R_xlen_t) m * n, m1a = (R_xlen_t) m + 1; PROTECT(yx = allocVector(IF_COMPLEX(CPLXSXP, REALSXP), mn)); #define EYE(_CTYPE_, _PTR_, _ONE_) \ do { \ _CTYPE_ *pyx = _PTR_(yx); \ Matrix_memset(pyx, 0, mn, sizeof(_CTYPE_)); \ if (isNull(yxjj)) { \ for (j = 0; j < n; ++j) { \ *pyx = _ONE_; \ pyx += m1a; \ } \ } else if (TYPEOF(yxjj) == TYPEOF(yx) && XLENGTH(yxjj) >= n) { \ _CTYPE_ *pyxjj = _PTR_(yxjj); \ for (j = 0; j < n; ++j) { \ *pyx = *pyxjj; \ pyx += m1a; \ pyxjj += 1; \ } \ } else \ error(_("invalid '%s' to '%s'"), "yxjj", __func__); \ } while (0) #ifdef MATRIX_ENABLE_ZMATRIX if (MCS_XTYPE_GET() == MCS_COMPLEX) EYE(Rcomplex, COMPLEX, Matrix_zone); else #endif EYE(double, REAL, 1.0); #undef EYE } else { SEXP ydim = GET_SLOT(y, Matrix_DimSym); int *pydim = INTEGER(ydim); if (pydim[0] != m) error(_("dimensions of '%s' and '%s' are inconsistent"), "qr", "y"); n = pydim[1]; PROTECT(yx = GET_SLOT(y, Matrix_xSym)); } char acl[] = ".geMatrix"; acl[0] = IF_COMPLEX('z', 'd'); SEXP a = PROTECT(newObject(acl)); SEXP adim = GET_SLOT(a, Matrix_DimSym); int *padim = INTEGER(adim); padim[0] = (op_ != 0) ? m : r; padim[1] = n; SEXP ax; if (isNull(y) && padim[0] == m) ax = yx; else { R_xlen_t mn = (R_xlen_t) padim[0] * padim[1]; PROTECT(ax = allocVector(IF_COMPLEX(CPLXSXP, REALSXP), mn)); ++nprotect; } #define MATMULT(_CTYPE_, _PTR_) \ do { \ _CTYPE_ *pyx = _PTR_(yx), *pax = _PTR_(ax), *work = NULL; \ if (op_ < 5) \ work = (_CTYPE_ *) R_alloc((size_t) m, sizeof(_CTYPE_)); \ switch (op_) { \ case 0: /* qr.coef : A = P2 R1^{-1} Q1' P1 y */ \ { \ SEXP R = PROTECT(GET_SLOT(qr, Matrix_RSym)), \ q = PROTECT(GET_SLOT(qr, Matrix_qSym)); \ Matrix_cs *R_ = M2CXS(R, 1); \ int *pq = (LENGTH(q) > 0) ? INTEGER(q) : NULL; \ for (j = 0; j < n; ++j) { \ Matrix_cs_pvec(pp, pyx, work, m); \ for (i = 0; i < r; ++i) \ Matrix_cs_happly(V_, i, pbeta[i], work); \ Matrix_cs_usolve(R_, work); \ Matrix_cs_ipvec(pq, work, pax, r); \ pyx += m; \ pax += r; \ } \ UNPROTECT(2); /* q, R */ \ break; \ } \ case 1: /* qr.fitted : A = P1' Q1 Q1' P1 y */ \ for (j = 0; j < n; ++j) { \ Matrix_cs_pvec(pp, pyx, work, m); \ for (i = 0; i < r; ++i) \ Matrix_cs_happly(V_, i, pbeta[i], work); \ if (r < m) \ Matrix_memset(work + r, 0, m - r, sizeof(_CTYPE_)); \ for (i = r - 1; i >= 0; --i) \ Matrix_cs_happly(V_, i, pbeta[i], work); \ Matrix_cs_ipvec(pp, work, pax, m); \ pyx += m; \ pax += m; \ } \ break; \ case 2: /* qr.resid : A = P1' Q2 Q2' P1 y */ \ for (j = 0; j < n; ++j) { \ Matrix_cs_pvec(pp, pyx, work, m); \ for (i = 0; i < r; ++i) \ Matrix_cs_happly(V_, i, pbeta[i], work); \ if (r > 0) \ Matrix_memset(work, 0, r, sizeof(_CTYPE_)); \ for (i = r - 1; i >= 0; --i) \ Matrix_cs_happly(V_, i, pbeta[i], work); \ Matrix_cs_ipvec(pp, work, pax, m); \ pyx += m; \ pax += m; \ } \ break; \ case 3: /* qr.qty {w/ perm.} : A = Q' P1 y */ \ for (j = 0; j < n; ++j) { \ Matrix_cs_pvec(pp, pyx, work, m); \ Matrix_memcpy(pax, work, m, sizeof(_CTYPE_)); \ for (i = 0; i < r; ++i) \ Matrix_cs_happly(V_, i, pbeta[i], pax); \ pyx += m; \ pax += m; \ } \ break; \ case 4: /* qr.qy {w/ perm.} : A = P1' Q y */ \ for (j = 0; j < n; ++j) { \ Matrix_memcpy(work, pyx, m, sizeof(_CTYPE_)); \ for (i = r - 1; i >= 0; --i) \ Matrix_cs_happly(V_, i, pbeta[i], work); \ Matrix_cs_ipvec(pp, work, pax, m); \ pyx += m; \ pax += m; \ } \ break; \ case 5: /* qr.qty {w/o perm.} : A = Q' y */ \ if (ax != yx) \ Matrix_memcpy(pax, pyx, (R_xlen_t) m * n, sizeof(_CTYPE_)); \ for (j = 0; j < n; ++j) { \ for (i = 0; i < r; ++i) \ Matrix_cs_happly(V_, i, pbeta[i], pax); \ pax += m; \ } \ break; \ case 6: /* qr.qy {w/o perm.} : A = Q y */ \ if (ax != yx) \ Matrix_memcpy(pax, pyx, (R_xlen_t) m * n, sizeof(_CTYPE_)); \ for (j = 0; j < n; ++j) { \ for (i = r - 1; i >= 0; --i) \ Matrix_cs_happly(V_, i, pbeta[i], pax); \ pax += m; \ } \ break; \ default: \ error(_("invalid '%s' to '%s'"), "op", __func__); \ break; \ } \ } while (0) #ifdef MATRIX_ENABLE_ZMATRIX if (MCS_XTYPE_GET() == MCS_COMPLEX) MATMULT(Rcomplex, COMPLEX); else #endif MATMULT(double, REAL); SET_SLOT(a, Matrix_xSym, ax); UNPROTECT(nprotect); /* ax, a, yx, p, beta, V */ return a; } �����������������������������������������������������������������������������Matrix/src/idz.h������������������������������������������������������������������������������������0000644�0001762�0000144�00000003264�14503216573�013257� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_IDZ_H #define MATRIX_IDZ_H #include #define IDZ \ TEMPLATE(i, int); \ TEMPLATE(d, double); \ TEMPLATE(z, Rcomplex); #define TEMPLATE(_PREFIX_, _CTYPE_) \ void _PREFIX_ ## \ rowperm2(_CTYPE_ *, int, int, int *, int, int) IDZ #undef TEMPLATE #define TEMPLATE(_PREFIX_, _CTYPE_) \ void _PREFIX_ ## \ symperm2(_CTYPE_ *, int, char, int *, int, int) IDZ #undef TEMPLATE #define TEMPLATE(_PREFIX_, _CTYPE_) \ void _PREFIX_ ## \ pack2(_CTYPE_ *, const _CTYPE_ *, int, char, char) IDZ #undef TEMPLATE #define TEMPLATE(_PREFIX_, _CTYPE_) \ void _PREFIX_ ## \ unpack1(_CTYPE_ *, const _CTYPE_ *, int, char, char) IDZ #undef TEMPLATE #define TEMPLATE(_PREFIX_, _CTYPE_) \ void _PREFIX_ ## \ transpose2(_CTYPE_ *, const _CTYPE_ *, int, int) IDZ #undef TEMPLATE #define TEMPLATE(_PREFIX_, _CTYPE_) \ void _PREFIX_ ## \ transpose1(_CTYPE_ *, const _CTYPE_ *, int, char) IDZ #undef TEMPLATE #define TEMPLATE(_PREFIX_, _CTYPE_) \ void _PREFIX_ ## \ syforce2(_CTYPE_ *, int, char) IDZ #undef TEMPLATE #define TEMPLATE(_PREFIX_, _CTYPE_) \ void _PREFIX_ ## \ trforce2(_CTYPE_ *, int, int, char, char) IDZ #undef TEMPLATE #define TEMPLATE(_PREFIX_, _CTYPE_) \ void _PREFIX_ ## \ band2(_CTYPE_ *, int, int, int, int, char) IDZ #undef TEMPLATE #define TEMPLATE(_PREFIX_, _CTYPE_) \ void _PREFIX_ ## \ band1(_CTYPE_ *, int, int, int, char, char) IDZ #undef TEMPLATE #define TEMPLATE(_PREFIX_, _CTYPE_) \ void _PREFIX_ ## \ dcpy2(_CTYPE_ *, const _CTYPE_ *, int, R_xlen_t, char, char) IDZ #undef TEMPLATE #define TEMPLATE(_PREFIX_, _CTYPE_) \ void _PREFIX_ ## \ dcpy1(_CTYPE_ *, const _CTYPE_ *, int, R_xlen_t, char, char, char) IDZ #undef TEMPLATE #undef IDZ #endif /* MATRIX_IDZ_H */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/perm.h�����������������������������������������������������������������������������������0000644�0001762�0000144�00000000346�14503225712�013425� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_PERM_H #define MATRIX_PERM_H #include SEXP R_isPerm(SEXP, SEXP); SEXP R_signPerm(SEXP, SEXP); SEXP R_invertPerm(SEXP, SEXP, SEXP); SEXP R_asPerm(SEXP, SEXP, SEXP, SEXP); #endif /* MATRIX_PERM_H */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/cs.h�������������������������������������������������������������������������������������0000644�0001762�0000144�00000014607�13652535054�013103� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _CS_H #define _CS_H #include #include #include // needed for FILE: #include #include // For use with R package 'Matrix' (NA_REAL, warning(), REprintf(), ..) # include # include # include # include # define printf Rprintf #ifdef MATLAB_MEX_FILE #include "mex.h" #endif #define CS_VER 3 /* CSparse Version */ #define CS_SUBVER 2 #define CS_SUBSUB 0 #define CS_DATE "Sept 12, 2017" /* CSparse release date */ #define CS_COPYRIGHT "Copyright (c) Timothy A. Davis, 2006-2016" #ifdef MATLAB_MEX_FILE #undef csi #define csi mwSignedIndex #endif // Matrix pkg: #define csi int #ifndef csi #define csi ptrdiff_t #endif /* --- primary CSparse routines and data structures ------------------------- */ typedef struct cs_sparse /* matrix in compressed-column or triplet form */ { csi nzmax ; /* maximum number of entries */ csi m ; /* number of rows */ csi n ; /* number of columns */ csi *p ; /* column pointers (size n+1) or col indices (size nzmax) */ csi *i ; /* row indices, size nzmax */ double *x ; /* numerical values, size nzmax */ csi nz ; /* # of entries in triplet matrix, -1 for compressed-col */ } cs ; cs *cs_add (const cs *A, const cs *B, double alpha, double beta) ; csi cs_cholsol (csi order, const cs *A, double *b) ; cs *cs_compress (const cs *T) ; csi cs_dupl (cs *A) ; csi cs_entry (cs *T, csi i, csi j, double x) ; csi cs_gaxpy (const cs *A, const double *x, double *y) ; cs *cs_load (FILE *f) ; csi cs_lusol (csi order, const cs *A, double *b, double tol) ; cs *cs_multiply (const cs *A, const cs *B) ; double cs_norm (const cs *A) ; csi cs_print (const cs *A, csi brief) ; csi cs_qrsol (csi order, const cs *A, double *b) ; cs *cs_transpose (const cs *A, csi values) ; /* utilities */ void *cs_calloc (csi n, size_t size) ; void *cs_free (void *p) ; void *cs_realloc (void *p, csi n, size_t size, csi *ok) ; cs *cs_spalloc (csi m, csi n, csi nzmax, csi values, csi triplet) ; cs *cs_spfree (cs *A) ; csi cs_sprealloc (cs *A, csi nzmax) ; void *cs_malloc (csi n, size_t size) ; /* --- secondary CSparse routines and data structures ----------------------- */ typedef struct cs_symbolic /* symbolic Cholesky, LU, or QR analysis */ { csi *pinv ; /* inverse row perm. for QR, fill red. perm for Chol */ csi *q ; /* fill-reducing column permutation for LU and QR */ csi *parent ; /* elimination tree for Cholesky and QR */ csi *cp ; /* column pointers for Cholesky, row counts for QR */ csi *leftmost ; /* leftmost[i] = min(find(A(i,:))), for QR */ csi m2 ; /* # of rows for QR, after adding fictitious rows */ double lnz ; /* # entries in L for LU or Cholesky; in V for QR */ double unz ; /* # entries in U for LU; in R for QR */ } css ; typedef struct cs_numeric /* numeric Cholesky, LU, or QR factorization */ { cs *L ; /* L for LU and Cholesky, V for QR */ cs *U ; /* U for LU, R for QR, not used for Cholesky */ csi *pinv ; /* partial pivoting for LU */ double *B ; /* beta [0..n-1] for QR */ } csn ; typedef struct cs_dmperm_results /* cs_dmperm or cs_scc output */ { csi *p ; /* size m, row permutation */ csi *q ; /* size n, column permutation */ csi *r ; /* size nb+1, block k is rows r[k] to r[k+1]-1 in A(p,q) */ csi *s ; /* size nb+1, block k is cols s[k] to s[k+1]-1 in A(p,q) */ csi nb ; /* # of blocks in fine dmperm decomposition */ csi rr [5] ; /* coarse row decomposition */ csi cc [5] ; /* coarse column decomposition */ } csd ; csi *cs_amd (csi order, const cs *A) ; csn *cs_chol (const cs *A, const css *S) ; csd *cs_dmperm (const cs *A, csi seed) ; csi cs_droptol (cs *A, double tol) ; csi cs_dropzeros (cs *A) ; csi cs_happly (const cs *V, csi i, double beta, double *x) ; csi cs_ipvec (const csi *p, const double *b, double *x, csi n) ; csi cs_lsolve (const cs *L, double *x) ; csi cs_ltsolve (const cs *L, double *x) ; csn *cs_lu (const cs *A, const css *S, double tol) ; cs *cs_permute (const cs *A, const csi *pinv, const csi *q, csi values) ; csi *cs_pinv (const csi *p, csi n) ; csi cs_pvec (const csi *p, const double *b, double *x, csi n) ; csn *cs_qr (const cs *A, const css *S) ; css *cs_schol (csi order, const cs *A) ; css *cs_sqr (csi order, const cs *A, csi qr) ; cs *cs_symperm (const cs *A, const csi *pinv, csi values) ; csi cs_updown (cs *L, csi sigma, const cs *C, const csi *parent) ; csi cs_usolve (const cs *U, double *x) ; csi cs_utsolve (const cs *U, double *x) ; /* utilities */ css *cs_sfree (css *S) ; csn *cs_nfree (csn *N) ; csd *cs_dfree (csd *D) ; /* --- tertiary CSparse routines -------------------------------------------- */ csi *cs_counts (const cs *A, const csi *parent, const csi *post, csi ata) ; double cs_cumsum (csi *p, csi *c, csi n) ; csi cs_dfs (csi j, cs *G, csi top, csi *xi, csi *pstack, const csi *pinv) ; csi cs_ereach (const cs *A, csi k, const csi *parent, csi *s, csi *w) ; csi *cs_etree (const cs *A, csi ata) ; csi cs_fkeep (cs *A, csi (*fkeep) (csi, csi, double, void *), void *other) ; double cs_house (double *x, double *beta, csi n) ; csi cs_leaf (csi i, csi j, const csi *first, csi *maxfirst, csi *prevleaf, csi *ancestor, csi *jleaf) ; csi *cs_maxtrans (const cs *A, csi seed) ; csi *cs_post (const csi *parent, csi n) ; csi *cs_randperm (csi n, csi seed) ; csi cs_reach (cs *G, const cs *B, csi k, csi *xi, const csi *pinv) ; csi cs_scatter (const cs *A, csi j, double beta, csi *w, double *x, csi mark, cs *C, csi nz) ; csd *cs_scc (cs *A) ; csi cs_spsolve (cs *G, const cs *B, csi k, csi *xi, double *x, const csi *pinv, csi lo) ; csi cs_tdfs (csi j, csi k, csi *head, const csi *next, csi *post, csi *stack) ; /* utilities */ csd *cs_dalloc (csi m, csi n) ; csd *cs_ddone (csd *D, cs *C, void *w, csi ok) ; cs *cs_done (cs *C, void *w, void *x, csi ok) ; csi *cs_idone (csi *p, cs *C, void *w, csi ok) ; csn *cs_ndone (csn *N, cs *C, void *w, void *x, csi ok) ; #define CS_MAX(a,b) (((a) > (b)) ? (a) : (b)) #define CS_MIN(a,b) (((a) < (b)) ? (a) : (b)) #define CS_FLIP(i) (-(i)-2) #define CS_UNFLIP(i) (((i) < 0) ? CS_FLIP(i) : (i)) #define CS_MARKED(w,j) (w [j] < 0) #define CS_MARK(w,j) { w [j] = CS_FLIP (w [j]) ; } #define CS_CSC(A) (A && (A->nz == -1)) #define CS_TRIPLET(A) (A && (A->nz >= 0)) #endif �������������������������������������������������������������������������������������������������������������������������Matrix/src/sparseVector.c���������������������������������������������������������������������������0000644�0001762�0000144�00000012321�14503225712�015131� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "Mdefines.h" #include "sparseVector.h" SEXP v2spV(SEXP from) { SEXP to = NULL, length = NULL, i = NULL, x = NULL; R_xlen_t n_ = XLENGTH(from); #define V2SPV(_KIND_, _NZ_, \ _CTYPE1_, _SEXPTYPE1_, _PTR1_, \ _CTYPE2_, _SEXPTYPE2_, _PTR2_) \ do { \ PROTECT(to = newObject(#_KIND_ "sparseVector")); \ _CTYPE1_ *py = _PTR1_(from); \ for (k = 0; k < n; ++k) \ if (_NZ_(py[k])) \ ++nnz; \ PROTECT(i = allocVector(_SEXPTYPE2_, nnz)); \ PROTECT(x = allocVector(_SEXPTYPE1_, nnz)); \ _CTYPE2_ *pi = _PTR2_(i); \ _CTYPE1_ *px = _PTR1_(x); \ for (k = 0; k < n; ++k) { \ if (_NZ_(py[k])) { \ *(pi++) = (_CTYPE2_) (k + 1); \ *(px++) = py[k]; \ } \ } \ } while (0) #define V2SPV_CASES(_CTYPE2_, _SEXPTYPE2_, _PTR2_) \ do { \ switch (TYPEOF(from)) { \ case LGLSXP: \ V2SPV(l, ISNZ_LOGICAL, int, LGLSXP, LOGICAL, \ _CTYPE2_, _SEXPTYPE2_, _PTR2_); \ break; \ case INTSXP: \ V2SPV(i, ISNZ_INTEGER, int, INTSXP, INTEGER, \ _CTYPE2_, _SEXPTYPE2_, _PTR2_); \ break; \ case REALSXP: \ V2SPV(d, ISNZ_REAL, double, REALSXP, REAL, \ _CTYPE2_, _SEXPTYPE2_, _PTR2_); \ break; \ case CPLXSXP: \ V2SPV(z, ISNZ_COMPLEX, Rcomplex, CPLXSXP, COMPLEX, \ _CTYPE2_, _SEXPTYPE2_, _PTR2_); \ break; \ default: \ ERROR_INVALID_TYPE(from, __func__); \ break; \ } \ } while (0) if (n_ <= INT_MAX) { int k, n = (int) n_, nnz = 0; PROTECT(length = ScalarInteger(n)); V2SPV_CASES(int, INTSXP, INTEGER); } else { R_xlen_t k, n = n_, nnz = 0; PROTECT(length = ScalarReal((double) n)); V2SPV_CASES(double, REALSXP, REAL); } #undef V2SPV_CASES #undef V2SPV SET_SLOT(to, Matrix_lengthSym, length); SET_SLOT(to, Matrix_iSym, i); SET_SLOT(to, Matrix_xSym, x); UNPROTECT(4); /* x, i, length, to */ return to; } SEXP CR2spV(SEXP from) { static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); const char *cl = valid[ivalid]; SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; Matrix_int_fast64_t mn = (Matrix_int_fast64_t) m * n; UNPROTECT(1); /* dim */ if (mn > 0x1.0p+53) error(_("%s length cannot exceed %s"), "sparseVector", "2^53"); /* defined in ./coerce.c : */ SEXP sparse_as_general(SEXP, const char *); PROTECT(from = sparse_as_general(from, cl)); char vcl[] = ".sparseVector"; vcl[0] = cl[0]; SEXP to = PROTECT(newObject(vcl)); SEXP p = PROTECT(GET_SLOT(from, Matrix_pSym)); int *pp = INTEGER(p), nnz = (cl[2] == 'C') ? pp[n] : pp[m]; SEXP vlength, vi; if (mn <= INT_MAX) { PROTECT(vlength = ScalarInteger(m * n)); PROTECT(vi = allocVector(INTSXP, nnz)); } else { PROTECT(vlength = ScalarReal((double) m * n)); PROTECT(vi = allocVector(REALSXP, nnz)); } SET_SLOT(to, Matrix_lengthSym, vlength); SET_SLOT(to, Matrix_iSym, vi); if (cl[2] == 'C') { SEXP i = PROTECT(GET_SLOT(from, Matrix_iSym)); int *pi = INTEGER(i), k, kend, j; if (TYPEOF(vi) == INTSXP) { int *pvi = INTEGER(vi), mj1a = 1; for (j = 0, k = 0; j < n; ++j) { kend = *(++pp); while (k < kend) { *(pvi++) = mj1a + *(pi++); ++k; } mj1a += m; } } else { double *pvi = REAL(vi), mj1a = 1.0, m_ = (double) m; for (j = 0, k = 0; j < n; ++j) { kend = *(++pp); while (k < kend) { *(pvi++) = mj1a + (double) *(pi++); ++k; } mj1a += m_; } } if (cl[0] != 'n') { SEXP vx = PROTECT(GET_SLOT(from, Matrix_xSym)); SET_SLOT(to, Matrix_xSym, vx); UNPROTECT(1); /* vx */ } UNPROTECT(1); /* i */ } else { SEXP j = PROTECT(GET_SLOT(from, Matrix_jSym)); int *pj = INTEGER(j), k, kend, tmp, *work; Matrix_Calloc(work, n, int); for (k = 0; k < nnz; ++k) work[pj[k]]++; nnz = 0; for (k = 0; k < n; ++k) { tmp = work[k]; work[k] = nnz; nnz += tmp; } #define R2SPV(_CTYPE_, _PTR_, _MASK_) \ do { \ _MASK_(_CTYPE_ *px = _PTR_(x )); \ _MASK_(_CTYPE_ *pvx = _PTR_(vx)); \ if (TYPEOF(vi) == INTSXP) { \ int *pvi = INTEGER(vi), i; \ k = 0; \ for (i = 1; i <= m; i += 1) { \ kend = *(++pp); \ while (k < kend) { \ pvi[work[pj[k]]] = m * pj[k] + i; \ _MASK_(pvx[work[pj[k]]] = px[k]); \ work[pj[k++]]++; \ } \ } \ } else { \ double *pvi = REAL(vi), i_, m_ = (double) m; \ k = 0; \ for (i_ = 1.0; i_ <= m_; i_ += 1.0) { \ kend = *(++pp); \ while (k < kend) { \ pvi[work[pj[k]]] = m_ * pj[k] + i_; \ _MASK_(pvx[work[pj[k]]] = px[k]); \ work[pj[k++]]++; \ } \ } \ } \ } while (0) if (cl[0] == 'n') R2SPV(, , HIDE); else { SEXP x = PROTECT(GET_SLOT(from, Matrix_xSym)), vx = PROTECT(allocVector(TYPEOF(x), XLENGTH(x))); switch (TYPEOF(x)) { case LGLSXP: R2SPV(int, LOGICAL, SHOW); break; case INTSXP: R2SPV(int, INTEGER, SHOW); break; case REALSXP: R2SPV(double, REAL, SHOW); break; case CPLXSXP: R2SPV(Rcomplex, COMPLEX, SHOW); break; default: break; } SET_SLOT(to, Matrix_xSym, vx); UNPROTECT(2); /* vx, x */ } #undef R2SV UNPROTECT(1); /* j */ Matrix_Free(work, n); } UNPROTECT(5); /* vi, vlength, p, to, from */ return to; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/init.c�����������������������������������������������������������������������������������0000644�0001762�0000144�00000024035�14546175103�013426� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "Mdefines.h" #include "Csparse.h" #include "abIndex.h" #include "attrib.h" #include "bind.h" #include "chm_common.h" #include "coerce.h" #include "dense.h" #include "determinant.h" #include "dgCMatrix.h" #include "dgeMatrix.h" #include "factorizations.h" #include "kappa.h" #include "objects.h" #include "perm.h" #include "products.h" #include "solve.h" #include "sparse.h" #include "sparseVector.h" #include "subscript.h" #include "utils-R.h" #include "validity.h" #include #include #include "Syms.h" Rcomplex Matrix_zzero, Matrix_zone, Matrix_zna; #define CALLDEF(name, n) {#name, (DL_FUNC) &name, n} #define EXTDEF(name, n) {#name, (DL_FUNC) &name, n} #define RREGDEF(name ) R_RegisterCCallable("Matrix", #name, (DL_FUNC) name) static R_CallMethodDef CallEntries[] = { CALLDEF(m_encodeInd, 4), CALLDEF(m_encodeInd2, 5), CALLDEF(Matrix_rle_i, 2), CALLDEF(Matrix_rle_d, 2), CALLDEF(tCsparse_diag, 2), CALLDEF(nCsparse_subassign, 4), CALLDEF(lCsparse_subassign, 4), CALLDEF(iCsparse_subassign, 4), CALLDEF(dCsparse_subassign, 4), CALLDEF(zCsparse_subassign, 4), CALLDEF(Csparse_dmperm, 3), CALLDEF(Csparse_MatrixMarket, 2), CALLDEF(Matrix_expand_pointers, 1), CALLDEF(R_all0, 1), CALLDEF(R_any0, 1), CALLDEF(compressed_non_0_ij, 2), CALLDEF(dgCMatrix_lusol, 2), CALLDEF(dgCMatrix_qrsol, 3), CALLDEF(dgCMatrix_cholsol, 2), CALLDEF(dgeMatrix_Schur, 3), CALLDEF(dgeMatrix_exp, 1), CALLDEF(CsparseMatrix_validate_maybe_sorting, 1), CALLDEF(Matrix_validate, 1), CALLDEF(MatrixFactorization_validate, 1), CALLDEF(nMatrix_validate, 1), CALLDEF(lMatrix_validate, 1), CALLDEF(iMatrix_validate, 1), CALLDEF(dMatrix_validate, 1), CALLDEF(zMatrix_validate, 1), CALLDEF(compMatrix_validate, 1), CALLDEF(symmetricMatrix_validate, 1), CALLDEF(triangularMatrix_validate, 1), CALLDEF(diagonalMatrix_validate, 1), CALLDEF(indMatrix_validate, 1), CALLDEF(pMatrix_validate, 1), CALLDEF(CsparseMatrix_validate, 1), CALLDEF(RsparseMatrix_validate, 1), CALLDEF(TsparseMatrix_validate, 1), CALLDEF(sCMatrix_validate, 1), CALLDEF(tCMatrix_validate, 1), CALLDEF(sRMatrix_validate, 1), CALLDEF(tRMatrix_validate, 1), CALLDEF(sTMatrix_validate, 1), CALLDEF(tTMatrix_validate, 1), CALLDEF(xgCMatrix_validate, 1), CALLDEF(xsCMatrix_validate, 1), CALLDEF(xtCMatrix_validate, 1), CALLDEF(xgRMatrix_validate, 1), CALLDEF(xsRMatrix_validate, 1), CALLDEF(xtRMatrix_validate, 1), CALLDEF(xgTMatrix_validate, 1), CALLDEF(xsTMatrix_validate, 1), CALLDEF(xtTMatrix_validate, 1), CALLDEF(unpackedMatrix_validate, 1), CALLDEF(packedMatrix_validate, 1), CALLDEF(dpoMatrix_validate, 1), CALLDEF(dppMatrix_validate, 1), CALLDEF(corMatrix_validate, 1), CALLDEF(pcorMatrix_validate, 1), CALLDEF(sparseVector_validate, 1), CALLDEF(lsparseVector_validate, 1), CALLDEF(isparseVector_validate, 1), CALLDEF(dsparseVector_validate, 1), CALLDEF(zsparseVector_validate, 1), CALLDEF(denseLU_validate, 1), CALLDEF(sparseLU_validate, 1), CALLDEF(sparseQR_validate, 1), CALLDEF(BunchKaufman_validate, 1), CALLDEF(pBunchKaufman_validate, 1), CALLDEF(Cholesky_validate, 1), CALLDEF(pCholesky_validate, 1), CALLDEF(CHMfactor_validate, 1), CALLDEF(CHMsimpl_validate, 1), CALLDEF(CHMsuper_validate, 1), CALLDEF(dCHMsimpl_validate, 1), CALLDEF(dCHMsuper_validate, 1), CALLDEF(Schur_validate, 1), CALLDEF(R_Dim_validate, 1), CALLDEF(R_DimNames_validate, 2), CALLDEF(R_DimNames_fixup, 1), CALLDEF(R_DimNames_is_symmetric, 1), CALLDEF(R_symDN, 1), CALLDEF(R_revDN, 1), CALLDEF(R_Matrix_nonvirtual, 2), CALLDEF(R_Matrix_kind, 1), CALLDEF(R_Matrix_shape, 1), CALLDEF(R_Matrix_repr, 1), CALLDEF(R_index_triangle, 4), CALLDEF(R_index_diagonal, 3), CALLDEF(R_nnz, 3), CALLDEF(R_isPerm, 2), CALLDEF(R_signPerm, 2), CALLDEF(R_invertPerm, 3), CALLDEF(R_asPerm, 4), CALLDEF(R_set_factor, 4), CALLDEF(R_subscript_1ary, 2), CALLDEF(R_subscript_1ary_mat, 2), CALLDEF(R_subscript_2ary, 3), CALLDEF(R_dense_band, 3), CALLDEF(R_dense_diag_get, 2), CALLDEF(R_dense_diag_set, 2), CALLDEF(R_dense_transpose, 1), CALLDEF(R_dense_force_symmetric, 2), CALLDEF(R_dense_symmpart, 1), CALLDEF(R_dense_skewpart, 1), CALLDEF(R_dense_is_symmetric, 2), CALLDEF(R_dense_is_triangular, 2), CALLDEF(R_dense_is_diagonal, 1), CALLDEF(R_dense_marginsum, 4), CALLDEF(R_dense_sum, 2), CALLDEF(R_dense_prod, 2), CALLDEF(R_sparse_drop0, 2), CALLDEF(R_sparse_diag_U2N, 1), CALLDEF(R_sparse_diag_N2U, 1), CALLDEF(R_sparse_band, 3), CALLDEF(R_sparse_diag_get, 2), CALLDEF(R_sparse_diag_set, 2), CALLDEF(R_sparse_transpose, 2), CALLDEF(R_sparse_force_symmetric, 2), CALLDEF(R_sparse_symmpart, 1), CALLDEF(R_sparse_skewpart, 1), CALLDEF(R_sparse_is_symmetric, 2), CALLDEF(R_sparse_is_triangular, 2), CALLDEF(R_sparse_is_diagonal, 1), CALLDEF(R_sparse_marginsum, 5), CALLDEF(R_sparse_sum, 2), CALLDEF(R_sparse_prod, 2), CALLDEF(Tsparse_aggregate, 1), CALLDEF(R_dense_matmult, 4), CALLDEF(R_sparse_matmult, 6), CALLDEF(R_diagonal_matmult, 5), CALLDEF(dgeMatrix_trf, 2), CALLDEF(dsyMatrix_trf, 2), CALLDEF(dspMatrix_trf, 2), CALLDEF(dpoMatrix_trf, 4), CALLDEF(dppMatrix_trf, 2), CALLDEF(dgCMatrix_trf, 4), CALLDEF(dgCMatrix_orf, 3), CALLDEF(dpCMatrix_trf, 5), CALLDEF(BunchKaufman_expand, 2), CALLDEF(denseLU_determinant, 2), CALLDEF(BunchKaufman_determinant, 2), CALLDEF(Cholesky_determinant, 2), CALLDEF(sparseLU_determinant, 2), CALLDEF(sparseQR_determinant, 2), CALLDEF(CHMfactor_determinant, 3), CALLDEF(denseLU_solve, 2), CALLDEF(BunchKaufman_solve, 2), CALLDEF(Cholesky_solve, 2), CALLDEF(dtrMatrix_solve, 2), CALLDEF(sparseLU_solve, 3), CALLDEF(CHMfactor_solve, 4), CALLDEF(dtCMatrix_solve, 3), CALLDEF(sparseQR_matmult, 5), CALLDEF(CHMfactor_diag_get, 2), CALLDEF(CHMfactor_update, 3), CALLDEF(CHMfactor_updown, 3), CALLDEF(dgeMatrix_norm, 2), CALLDEF(dsyMatrix_norm, 2), CALLDEF(dspMatrix_norm, 2), CALLDEF(dtrMatrix_norm, 2), CALLDEF(dtpMatrix_norm, 2), CALLDEF(dgeMatrix_rcond, 3), CALLDEF(dsyMatrix_rcond, 3), CALLDEF(dspMatrix_rcond, 3), CALLDEF(dpoMatrix_rcond, 3), CALLDEF(dppMatrix_rcond, 3), CALLDEF(dtrMatrix_rcond, 2), CALLDEF(dtpMatrix_rcond, 2), CALLDEF(v2spV, 1), CALLDEF(CR2spV, 1), CALLDEF(R_vector_as_dense, 8), CALLDEF(R_matrix_as_dense, 5), CALLDEF(R_sparse_as_dense, 2), CALLDEF(R_diagonal_as_dense, 5), CALLDEF(R_index_as_dense, 2), CALLDEF(R_vector_as_sparse, 8), CALLDEF(R_matrix_as_sparse, 5), CALLDEF(R_dense_as_sparse, 2), CALLDEF(R_diagonal_as_sparse, 5), CALLDEF(R_index_as_sparse, 3), CALLDEF(R_dense_as_kind, 2), CALLDEF(R_sparse_as_kind, 2), CALLDEF(R_diagonal_as_kind, 2), CALLDEF(R_index_as_kind, 2), CALLDEF(R_dense_as_general, 1), CALLDEF(R_sparse_as_general, 1), CALLDEF(R_dense_as_unpacked, 1), CALLDEF(R_dense_as_packed, 3), CALLDEF(R_sparse_as_Csparse, 1), CALLDEF(R_sparse_as_Rsparse, 1), CALLDEF(R_sparse_as_Tsparse, 1), CALLDEF(R_Matrix_as_vector, 1), CALLDEF(R_Matrix_as_matrix, 1), CALLDEF(R_Matrix_as_unpacked, 1), CALLDEF(R_Matrix_as_packed, 1), CALLDEF(R_Matrix_as_Csparse, 1), CALLDEF(R_Matrix_as_Rsparse, 1), CALLDEF(R_Matrix_as_Tsparse, 1), CALLDEF(R_Matrix_as_kind, 3), CALLDEF(R_Matrix_as_general, 2), CALLDEF(R_Matrix_version, 0), CALLDEF(R_cholmod_common_envini, 1), {NULL, NULL, 0} }; static const R_ExternalMethodDef ExtEntries[] = { EXTDEF(Mmatrix, 7), EXTDEF(R_bind, -1), {NULL, NULL, 0} }; void attribute_visible R_init_Matrix(DllInfo *info) { R_registerRoutines(info, NULL, CallEntries, NULL, ExtEntries); R_useDynamicSymbols(info, FALSE); /* These are callable from other packages' C code: */ /* CHOLMOD: */ RREGDEF(cholmod_aat); RREGDEF(cholmod_add); RREGDEF(cholmod_allocate_dense); RREGDEF(cholmod_allocate_sparse); RREGDEF(cholmod_allocate_triplet); RREGDEF(cholmod_analyze); RREGDEF(cholmod_analyze_p); RREGDEF(cholmod_band_inplace); RREGDEF(cholmod_change_factor); RREGDEF(cholmod_copy); RREGDEF(cholmod_copy_dense); RREGDEF(cholmod_copy_factor); RREGDEF(cholmod_copy_sparse); RREGDEF(cholmod_defaults); RREGDEF(cholmod_dense_to_sparse); RREGDEF(cholmod_factor_to_sparse); RREGDEF(cholmod_factorize); RREGDEF(cholmod_factorize_p); RREGDEF(cholmod_finish); RREGDEF(cholmod_free_dense); RREGDEF(cholmod_free_factor); RREGDEF(cholmod_free_sparse); RREGDEF(cholmod_free_triplet); RREGDEF(cholmod_nnz); RREGDEF(cholmod_scale); RREGDEF(cholmod_sdmult); RREGDEF(cholmod_solve); RREGDEF(cholmod_solve2); RREGDEF(cholmod_sort); RREGDEF(cholmod_sparse_to_dense); RREGDEF(cholmod_sparse_to_triplet); RREGDEF(cholmod_speye); RREGDEF(cholmod_spsolve); RREGDEF(cholmod_ssmult); RREGDEF(cholmod_start); RREGDEF(cholmod_submatrix); RREGDEF(cholmod_transpose); RREGDEF(cholmod_triplet_to_sparse); RREGDEF(cholmod_updown); RREGDEF(cholmod_vertcat); /* Matrix: */ RREGDEF(sexp_as_cholmod_factor); RREGDEF(sexp_as_cholmod_sparse); RREGDEF(sexp_as_cholmod_triplet); RREGDEF(sexp_as_cholmod_dense); RREGDEF(numeric_as_cholmod_dense); RREGDEF(cholmod_factor_as_sexp); RREGDEF(cholmod_sparse_as_sexp); RREGDEF(cholmod_triplet_as_sexp); RREGDEF(cholmod_dense_as_sexp); RREGDEF(cholmod_factor_ldetA); RREGDEF(cholmod_factor_update); Matrix_DimNamesSym = install("Dimnames"); Matrix_DimSym = install("Dim"); Matrix_LSym = install("L"); Matrix_QSym = install("Q"); Matrix_RSym = install("R"); Matrix_TSym = install("T"); Matrix_USym = install("U"); Matrix_VSym = install("V"); Matrix_betaSym = install("beta"); Matrix_diagSym = install("diag"); Matrix_factorsSym = install("factors"); Matrix_iSym = install("i"); Matrix_jSym = install("j"); Matrix_lengthSym = install("length"); Matrix_marginSym = install("margin"); Matrix_pSym = install("p"); Matrix_permSym = install("perm"); Matrix_qSym = install("q"); Matrix_sdSym = install("sd"); Matrix_uploSym = install("uplo"); Matrix_xSym = install("x"); Matrix_zzero.r = 0.0; Matrix_zone.r = 1.0; Matrix_zna.r = NA_REAL; Matrix_zzero.i = 0.0; Matrix_zone.i = 0.0; Matrix_zna.i = NA_REAL; R_cholmod_start(&c); return; } void R_unload_Matrix(DllInfo *info) { R_cholmod_finish(&c); return; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/sparse.c���������������������������������������������������������������������������������0000644�0001762�0000144�00000272731�14535466244�013777� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include /* fabs, hypot */ #include "Mdefines.h" #include "sparse.h" SEXP sparse_drop0(SEXP from, const char *class, double tol) { if (class[0] == 'n') return from; SEXP to, x0 = PROTECT(GET_SLOT(from, Matrix_xSym)); #define TOLBASED_ISNZ_REAL(_X_) \ (ISNA_REAL(_X_) || fabs(_X_) > tol) #define TOLBASED_ISNZ_COMPLEX(_X_) \ (ISNA_COMPLEX(_X_) || hypot((_X_).r, (_X_).i) > tol) #define DROP0_CASES(_DO_) \ do { \ switch (class[0]) { \ case 'l': \ _DO_(int, LOGICAL, ISNZ_LOGICAL); \ break; \ case 'i': \ _DO_(int, INTEGER, ISNZ_INTEGER); \ break; \ case 'd': \ if (tol > 0.0) \ _DO_(double, REAL, TOLBASED_ISNZ_REAL); \ else \ _DO_(double, REAL, ISNZ_REAL); \ break; \ case 'z': \ if (tol > 0.0) \ _DO_(Rcomplex, COMPLEX, TOLBASED_ISNZ_COMPLEX); \ else \ _DO_(Rcomplex, COMPLEX, ISNZ_COMPLEX); \ break; \ default: \ break; \ } \ } while (0) if (class[2] != 'T') { SEXP p0 = PROTECT(GET_SLOT(from, Matrix_pSym)); int *pp0 = INTEGER(p0), k, n = (int) (XLENGTH(p0) - 1), nnz0 = pp0[n], nnz1 = 0; #undef DROP0_LOOP1 #define DROP0_LOOP1(_CTYPE_, _PTR_, _ISNZ_) \ do { \ _CTYPE_ *px0 = _PTR_(x0); \ for (k = 0; k < nnz0; ++k) { \ if (_ISNZ_(*px0)) \ ++nnz1; \ ++px0; \ } \ } while (0) DROP0_CASES(DROP0_LOOP1); if (nnz1 == nnz0) { UNPROTECT(2); /* p0, x0 */ return from; } PROTECT(to = newObject(class)); SEXP iSym = (class[2] == 'C') ? Matrix_iSym : Matrix_jSym, i0 = PROTECT(GET_SLOT(from, iSym)), p1 = PROTECT(allocVector(INTSXP, (R_xlen_t) n + 1)), i1 = PROTECT(allocVector(INTSXP, nnz1)), x1 = PROTECT(allocVector(TYPEOF(x0), nnz1)); int *pi0 = INTEGER(i0), *pp1 = INTEGER(p1), *pi1 = INTEGER(i1), j, kend; pp0++; *(pp1++) = 0; SET_SLOT(to, Matrix_pSym, p1); SET_SLOT(to, iSym, i1); SET_SLOT(to, Matrix_xSym, x1); #undef DROP0_LOOP2 #define DROP0_LOOP2(_CTYPE_, _PTR_, _ISNZ_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \ for (j = 0, k = 0; j < n; ++j) { \ pp1[j] = pp1[j - 1]; \ kend = pp0[j]; \ while (k < kend) { \ if (_ISNZ_(*px0)) { \ ++pp1[j]; \ *(pi1++) = *pi0; \ *(px1++) = *px0; \ } \ ++k; ++pi0; ++px0; \ } \ } \ } while (0) DROP0_CASES(DROP0_LOOP2); UNPROTECT(7); /* x1, i1, p1, i0, to, p0, x0 */ } else { R_xlen_t k, nnz0 = XLENGTH(x0), nnz1 = 0; DROP0_CASES(DROP0_LOOP1); if (nnz1 == nnz0) { UNPROTECT(1); /* x0 */ return from; } PROTECT(to = newObject(class)); SEXP i0 = PROTECT(GET_SLOT(from, Matrix_iSym)), j0 = PROTECT(GET_SLOT(from, Matrix_jSym)), i1 = PROTECT(allocVector(INTSXP, nnz1)), j1 = PROTECT(allocVector(INTSXP, nnz1)), x1 = PROTECT(allocVector(TYPEOF(x0), nnz1)); int *pi0 = INTEGER(i0), *pj0 = INTEGER(j0), *pi1 = INTEGER(i1), *pj1 = INTEGER(j1); SET_SLOT(to, Matrix_iSym, i1); SET_SLOT(to, Matrix_jSym, j1); SET_SLOT(to, Matrix_xSym, x1); #undef DROP0_LOOP2 #define DROP0_LOOP2(_CTYPE_, _PTR_, _ISNZ_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \ for (k = 0; k < nnz0; ++k) { \ if (_ISNZ_(*px0)) { \ *(pi1++) = *pi0; \ *(pj1++) = *pj0; \ *(px1++) = *px0; \ } \ ++pi0; ++pj0; ++px0; \ } \ } while (0) DROP0_CASES(DROP0_LOOP2); UNPROTECT(7); /* x1, j1, i1, j0, i0, to, x0 */ } PROTECT(to); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; if (m != n || n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); SET_SLOT(to, Matrix_DimNamesSym, dimnames); UNPROTECT(1); /* dimnames */ if (class[1] != 'g') { SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); char ul = *CHAR(STRING_ELT(uplo, 0)); if (ul != 'U') SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ } if (class[1] == 't') { SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); char di = *CHAR(STRING_ELT(diag, 0)); if (di != 'N') SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ } else { SEXP factors = PROTECT(GET_SLOT(from, Matrix_factorsSym)); if (LENGTH(factors) > 0) SET_SLOT(to, Matrix_factorsSym, factors); UNPROTECT(1); /* factors */ } #undef TOLBASED_ISNZ_REAL #undef TOLBASED_ISNZ_COMPLEX #undef DROP0_CASES #undef DROP0_LOOP1 #undef DROP0_LOOP2 UNPROTECT(1); /* to */ return to; } /* drop0(<[CRT]sparseMatrix>, tol) */ SEXP R_sparse_drop0(SEXP from, SEXP tol) { static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); double tol_; if (TYPEOF(tol) != REALSXP || LENGTH(tol) < 1 || ISNAN(tol_ = REAL(tol)[0])) error(_("'%s' is not a number"), "tol"); return sparse_drop0(from, valid[ivalid], tol_); } SEXP sparse_diag_U2N(SEXP from, const char *class) { if (class[1] != 't') return from; SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); char di = *CHAR(STRING_ELT(diag, 0)); UNPROTECT(1); /* diag */ if (di == 'N') return from; SEXP val = PROTECT(ScalarLogical(1)); from = R_sparse_diag_set(from, val); UNPROTECT(1); /* val */ return from; } /* diagU2N(<[CRT]sparseMatrix>), parallel to R-level ..diagU2N(), though that is more general, working for _all_ Matrix */ SEXP R_sparse_diag_U2N(SEXP from) { static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); return sparse_diag_U2N(from, valid[ivalid]); } SEXP sparse_diag_N2U(SEXP from, const char *class) { if (class[1] != 't') return from; SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); char di = *CHAR(STRING_ELT(diag, 0)); UNPROTECT(1); /* diag */ if (di != 'N') return from; SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int n = INTEGER(dim)[0]; UNPROTECT(1); /* dim */ if (n == 0) PROTECT(from = duplicate(from)); else { SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); char ul = *CHAR(STRING_ELT(uplo, 0)); UNPROTECT(1); /* uplo */ if (ul == 'U') PROTECT(from = sparse_band(from, class, 1, n - 1)); else PROTECT(from = sparse_band(from, class, 1 - n, -1)); } PROTECT(diag = mkString("U")); SET_SLOT(from, Matrix_diagSym, diag); UNPROTECT(2); /* diag, from */ return from; } /* diagN2U(<[CRT]sparseMatrix>), parallel to R-level ..diagN2U(), though that is more general, working for _all_ Matrix */ SEXP R_sparse_diag_N2U(SEXP from) { static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); return sparse_diag_N2U(from, valid[ivalid]); } SEXP sparse_band(SEXP from, const char *class, int a, int b) { SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; UNPROTECT(1); /* dim */ /* Need tri[ul](<0-by-0>) and tri[ul](<1-by-1>) to be triangularMatrix */ if (a <= 1 - m && b >= n - 1 && (class[1] == 't' || m != n || m > 1 || n > 1)) return from; int ge = 0, sy = 0, tr = 0; ge = m != n || !((tr = a >= 0 || b <= 0 || class[1] == 't') || (sy = a == -b && class[1] == 's')); char ul0 = 'U', ul1 = 'U', di = 'N'; if (class[1] != 'g') { SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); ul0 = *CHAR(STRING_ELT(uplo, 0)); UNPROTECT(1); /* uplo */ if (class[1] == 't') { /* Be fast if band contains entire triangle */ if ((ul0 == 'U') ? (a <= 0 && b >= n - 1) : (b >= 0 && a <= 1 - m)) return from; else if (a <= 0 && b >= 0) { SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); di = *CHAR(STRING_ELT(diag, 0)); UNPROTECT(1); /* diag */ } } } /* band(, a, b) is equivalent to t(band(t(), -b, -a)) ! */ if (class[2] == 'R') { int r; r = m; m = n; n = r; r = a; a = -b; b = -r; ul0 = (ul0 == 'U') ? 'L' : 'U'; from = sparse_transpose(from, class, 1); } PROTECT(from); char cl[] = "...Matrix"; cl[0] = class[0]; cl[1] = (ge) ? 'g' : ((tr) ? 't' : 's'); cl[2] = (class[2] == 'R') ? 'C' : class[2]; SEXP to = PROTECT(newObject(cl)); dim = GET_SLOT(to, Matrix_DimSym); pdim = INTEGER(dim); pdim[0] = m; pdim[1] = n; SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); if (class[1] != 's' || sy) SET_SLOT(to, Matrix_DimNamesSym, dimnames); else set_symmetrized_DimNames(to, dimnames, -1); UNPROTECT(1); /* dimnames */ if (!ge) { ul1 = (tr && class[1] != 't') ? ((a >= 0) ? 'U' : 'L') : ul0; if (ul1 != 'U') { SEXP uplo = PROTECT(mkString("L")); SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ } if (di != 'N') { SEXP diag = PROTECT(mkString("U")); SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ } } /* It remains to set some subset of 'p', 'i', 'j', 'x' ... */ #define BAND_CASES \ do { \ switch (class[0]) { \ case 'l': \ BAND_SUBCASES(int, LOGICAL, SHOW); \ break; \ case 'i': \ BAND_SUBCASES(int, INTEGER, SHOW); \ break; \ case 'd': \ BAND_SUBCASES(double, REAL, SHOW); \ break; \ case 'z': \ BAND_SUBCASES(Rcomplex, COMPLEX, SHOW); \ break; \ default: \ break; \ } \ } while (0) if (class[2] != 'T') { SEXP p0 = PROTECT(GET_SLOT(from, Matrix_pSym)), i0 = PROTECT(GET_SLOT(from, Matrix_iSym)), p1 = PROTECT(allocVector(INTSXP, (R_xlen_t) n + 1)); int *pp0 = INTEGER(p0), *pi0 = INTEGER(i0), *pp1 = INTEGER(p1), d, j, k, kend, nnz0 = pp0[n], nnz1 = 0; pp0++; *(pp1++) = 0; SET_SLOT(to, Matrix_pSym, p1); if (class[1] == 's' && !sy) { Matrix_memset(pp1, 0, n, sizeof(int)); for (j = 0, k = 0; j < n; ++j) { kend = pp0[j]; while (k < kend) { if ((d = j - pi0[k]) >= a && d <= b) ++pp1[j]; if (d != 0 && -d >= a && -d <= b) ++pp1[pi0[k]]; ++k; } } for (j = 0; j < n; ++j) { nnz1 += pp1[j]; pp1[j] = nnz1; } } else { for (j = 0, k = 0; j < n; ++j) { kend = pp0[j]; while (k < kend) { if ((d = j - pi0[k]) >= a && d <= b) ++nnz1; ++k; } pp1[j] = nnz1; } } if (nnz1 == nnz0 && (class[1] != 's' || sy)) { /* No need to allocate in this case: band has all nonzero elements */ SET_SLOT(to, Matrix_iSym, i0); if (class[0] != 'n') { SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)); SET_SLOT(to, Matrix_xSym, x0); UNPROTECT(1); /* x0 */ } if (class[2] == 'R') to = sparse_transpose(to, cl, 1); UNPROTECT(5); /* p1, i0, p0, to, from */ return to; } SEXP i1 = PROTECT(allocVector(INTSXP, nnz1)); int *pi1 = INTEGER(i1); SET_SLOT(to, Matrix_iSym, i1); #undef BAND_SUBCASES #define BAND_SUBCASES(_CTYPE_, _PTR_, _MASK_) \ do { \ _MASK_(_CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1)); \ if (class[1] == 's' && !sy) { \ int *pp1_; \ Matrix_Calloc(pp1_, n, int); \ Matrix_memcpy(pp1_, pp1 - 1, n, sizeof(int)); \ for (j = 0, k = 0; j < n; ++j) { \ kend = pp0[j]; \ while (k < kend) { \ if ((d = j - pi0[k]) >= a && d <= b) { \ pi1[pp1_[j]] = pi0[k]; \ _MASK_(px1[pp1_[j]] = px0[k]); \ ++pp1_[j]; \ } \ if (d != 0 && -d >= a && -d <= b) { \ pi1[pp1_[pi0[k]]] = j; \ _MASK_(px1[pp1_[pi0[k]]] = px0[k]); \ ++pp1_[pi0[k]]; \ } \ ++k; \ } \ } \ Matrix_Free(pp1_, n); \ } else { \ for (j = 0, k = 0; j < n; ++j) { \ kend = pp0[j]; \ while (k < kend) { \ if ((d = j - pi0[k]) >= a && d <= b) { \ *(pi1++) = pi0[k]; \ _MASK_(*(px1++) = px0[k]); \ } \ ++k; \ } \ } \ } \ } while (0) if (class[0] == 'n') BAND_SUBCASES(int, LOGICAL, HIDE); else { SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)), x1 = PROTECT(allocVector(TYPEOF(x0), nnz1)); SET_SLOT(to, Matrix_xSym, x1); BAND_CASES; UNPROTECT(2); /* x1, x0 */ } if (class[2] == 'R') to = sparse_transpose(to, cl, 1); } else { SEXP i0 = PROTECT(GET_SLOT(from, Matrix_iSym)), j0 = PROTECT(GET_SLOT(from, Matrix_jSym)); int *pi0 = INTEGER(i0), *pj0 = INTEGER(j0), d; R_xlen_t k, nnz0 = XLENGTH(i0), nnz1 = 0; if (class[1] == 's' && !sy) { for (k = 0; k < nnz0; ++k) { if ((d = pj0[k] - pi0[k]) >= a && d <= b) ++nnz1; if (d != 0 && -d >= a && -d <= b) ++nnz1; } } else { for (k = 0; k < nnz0; ++k) { if ((d = pj0[k] - pi0[k]) >= a && d <= b) ++nnz1; } } if (nnz1 == nnz0 && (class[1] != 's' || sy)) { /* No need to allocate in this case: band has all nonzero elements */ SET_SLOT(to, Matrix_iSym, i0); SET_SLOT(to, Matrix_jSym, j0); if (class[0] != 'n') { SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)); SET_SLOT(to, Matrix_xSym, x0); UNPROTECT(1); /* x0 */ } UNPROTECT(4); /* j0, i0, to, from */ return to; } SEXP i1 = PROTECT(allocVector(INTSXP, nnz1)), j1 = PROTECT(allocVector(INTSXP, nnz1)); int *pi1 = INTEGER(i1), *pj1 = INTEGER(j1); SET_SLOT(to, Matrix_iSym, i1); SET_SLOT(to, Matrix_jSym, j1); #undef BAND_SUBCASES #define BAND_SUBCASES(_CTYPE_, _PTR_, _MASK_) \ do { \ _MASK_(_CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1)); \ if (class[1] == 's' && !sy) { \ for (k = 0; k < nnz0; ++k) { \ if ((d = pj0[k] - pi0[k]) >= a && d <= b) { \ *(pi1++) = pi0[k]; \ *(pj1++) = pj0[k]; \ _MASK_(*(px1++) = px0[k]); \ } \ if (d != 0 && -d >= a && -d <= b) { \ *(pi1++) = pj0[k]; \ *(pj1++) = pi0[k]; \ _MASK_(*(px1++) = px0[k]); \ } \ } \ } else { \ for (k = 0; k < nnz0; ++k) { \ if ((d = pj0[k] - pi0[k]) >= a && d <= b) { \ *(pi1++) = pi0[k]; \ *(pj1++) = pj0[k]; \ _MASK_(*(px1++) = px0[k]); \ } \ } \ } \ } while (0) if (class[0] == 'n') BAND_SUBCASES(int, LOGICAL, HIDE); else { SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)), x1 = PROTECT(allocVector(TYPEOF(x0), nnz1)); SET_SLOT(to, Matrix_xSym, x1); BAND_CASES; UNPROTECT(2); /* x1, x0 */ } } #undef BAND_CASES #undef BAND_SUBCASES UNPROTECT(6); return to; } /* band(<[CRT]sparseMatrix>, k1, k2), tri[ul](<[CRT]sparseMatrix>, k) */ /* NB: argument validation more or less copied from R_dense_band() */ SEXP R_sparse_band(SEXP from, SEXP k1, SEXP k2) { static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; UNPROTECT(1); int a, b; if (k1 == R_NilValue) // tril() a = -m ; // was (m > 0) ? 1 - m : 0; else if ((a = asInteger(k1)) == NA_INTEGER || a < -m || a > n) error(_("'%s' (%d) must be an integer from %s (%d) to %s (%d)"), "k1", a, "-Dim[1]", -m, "Dim[2]", n); if (k2 == R_NilValue) // triu() b = n; // was (n > 0) ? n - 1 : 0; else if ((b = asInteger(k2)) == NA_INTEGER || b < -m || b > n) error(_("'%s' (%d) must be an integer from %s (%d) to %s (%d)"), "k2", b, "-Dim[1]", -m, "Dim[2]", n); else if (b < a) error(_("'%s' (%d) must be less than or equal to '%s' (%d)"), "k1", a, "k2", b); return sparse_band(from, valid[ivalid], a, b); } SEXP sparse_diag_get(SEXP obj, const char *class, int names) { SEXP dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1], r = (m < n) ? m : n; UNPROTECT(1); /* dim */ char ul = 'U', di = 'N'; if (class[1] != 'g') { SEXP uplo = PROTECT(GET_SLOT(obj, Matrix_uploSym)); ul = *CHAR(STRING_ELT(uplo, 0)); UNPROTECT(1); /* uplo */ if (class[1] == 't') { SEXP diag = PROTECT(GET_SLOT(obj, Matrix_diagSym)); di = *CHAR(STRING_ELT(diag, 0)); UNPROTECT(1); /* diag */ } } SEXP res = PROTECT(allocVector(kindToType(class[0]), r)); #define DG_CASES \ do { \ switch (class[0]) { \ case 'n': \ case 'l': \ DG_LOOP(int, LOGICAL, SHOW, FIRSTOF, INCREMENT_LOGICAL, 0, 1); \ break; \ case 'i': \ DG_LOOP(int, INTEGER, SHOW, FIRSTOF, INCREMENT_INTEGER, 0, 1); \ break; \ case 'd': \ DG_LOOP(double, REAL, SHOW, FIRSTOF, INCREMENT_REAL, 0.0, 1.0); \ break; \ case 'z': \ DG_LOOP(Rcomplex, COMPLEX, SHOW, FIRSTOF, INCREMENT_COMPLEX, Matrix_zzero, Matrix_zone); \ break; \ default: \ break; \ } \ } while (0) if (di != 'N') { int j; #undef DG_LOOP #define DG_LOOP(_CTYPE_, _PTR_, _MASK_, _REPLACE_, _INCREMENT_, _ZERO_, _ONE_) \ do { \ _CTYPE_ *pres = _PTR_(res); \ for (j = 0; j < r; ++j) \ *(pres++) = _ONE_; \ } while (0) DG_CASES; } else if (class[2] != 'T') { SEXP iSym = (class[2] == 'C') ? Matrix_iSym : Matrix_jSym, p0 = PROTECT(GET_SLOT(obj, Matrix_pSym)), i0 = PROTECT(GET_SLOT(obj, iSym)); int j, k, kend, *pp0 = INTEGER(p0), *pi0 = INTEGER(i0); pp0++; #undef DG_LOOP #define DG_LOOP(_CTYPE_, _PTR_, _MASK_, _REPLACE_, _INCREMENT_, _ZERO_, _ONE_) \ do { \ _MASK_(_CTYPE_ *px0 = _PTR_(x0)); \ _CTYPE_ *pres = _PTR_(res); \ if (class[1] == 'g') { \ for (j = 0, k = 0; j < r; ++j) { \ pres[j] = _ZERO_; \ kend = pp0[j]; \ while (k < kend) { \ if (pi0[k] != j) \ ++k; \ else { \ pres[j] = _REPLACE_(px0[k], 1); \ k = kend; \ } \ } \ } \ } else if ((class[2] == 'C') == (ul != 'U')) { \ for (j = 0, k = 0; j < r; ++j) { \ kend = pp0[j]; \ pres[j] = (k < kend && pi0[k] == j) \ ? _REPLACE_(px0[k], 1) : _ZERO_; \ k = kend; \ } \ } else { \ for (j = 0, k = 0; j < r; ++j) { \ kend = pp0[j]; \ pres[j] = (k < kend && pi0[kend - 1] == j) \ ? _REPLACE_(px0[kend - 1], 1) : _ZERO_; \ k = kend; \ } \ } \ } while (0) if (class[0] == 'n') { DG_LOOP(int, LOGICAL, HIDE, SECONDOF, , 0, 1); } else { SEXP x0 = PROTECT(GET_SLOT(obj, Matrix_xSym)); DG_CASES; UNPROTECT(1); /* x0 */ } UNPROTECT(2); /* i0, p0 */ } else { SEXP i0 = PROTECT(GET_SLOT(obj, Matrix_iSym)), j0 = PROTECT(GET_SLOT(obj, Matrix_jSym)); int *pi0 = INTEGER(i0), *pj0 = INTEGER(j0); R_xlen_t k, nnz0 = XLENGTH(i0); #undef DG_LOOP #define DG_LOOP(_CTYPE_, _PTR_, _MASK_, _REPLACE_, _INCREMENT_, _ZERO_, _ONE_) \ do { \ _MASK_(_CTYPE_ *px0 = _PTR_(x0)); \ _CTYPE_ *pres = _PTR_(res); \ Matrix_memset(pres, 0, r, sizeof(_CTYPE_)); \ for (k = 0; k < nnz0; ++k) { \ if (*pi0 == *pj0) \ _INCREMENT_(pres[*pi0], (*px0)); \ ++pi0; ++pj0; _MASK_(++px0); \ } \ } while (0) if (class[0] == 'n') DG_LOOP(int, LOGICAL, HIDE, SECONDOF, INCREMENT_PATTERN, 0, 1); else { SEXP x0 = PROTECT(GET_SLOT(obj, Matrix_xSym)); DG_CASES; UNPROTECT(1); /* x0 */ } UNPROTECT(2); /* j0, i0 */ } #undef DG_CASES #undef DG_LOOP if (names) { /* NB: The logic here must be adjusted once the validity method for 'symmetricMatrix' enforces symmetric 'Dimnames' */ SEXP dn = PROTECT(GET_SLOT(obj, Matrix_DimNamesSym)), rn = VECTOR_ELT(dn, 0), cn = VECTOR_ELT(dn, 1); if (cn == R_NilValue) { if (class[1] == 's' && rn != R_NilValue) setAttrib(res, R_NamesSymbol, rn); } else { if (class[1] == 's') setAttrib(res, R_NamesSymbol, cn); else if (rn != R_NilValue && (rn == cn || equal_character_vectors(rn, cn, r))) setAttrib(res, R_NamesSymbol, (r == m) ? rn : cn); } UNPROTECT(1); /* dn */ } UNPROTECT(1); /* res */ return res; } /* diag(<[CRT]sparseMatrix>, names=) */ SEXP R_sparse_diag_get(SEXP obj, SEXP names) { static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, "" }; int ivalid = R_check_class_etc(obj, valid); if (ivalid < 0) ERROR_INVALID_CLASS(obj, __func__); int names_; if (TYPEOF(names) != LGLSXP || LENGTH(names) < 1 || (names_ = LOGICAL(names)[0]) == NA_LOGICAL) error(_("'%s' must be %s or %s"), "names", "TRUE", "FALSE"); return sparse_diag_get(obj, valid[ivalid], names_); } SEXP sparse_diag_set(SEXP from, const char *class, SEXP value) { SEXP to = PROTECT(newObject(class)); int v = LENGTH(value) != 1, full = 0; SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1], r = (m < n) ? m : n; if (m != n || n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); SET_SLOT(to, Matrix_DimNamesSym, dimnames); UNPROTECT(1); /* dimnames */ char ul = 'U', di = 'N'; if (class[1] != 'g') { SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); ul = *CHAR(STRING_ELT(uplo, 0)); if (ul != 'U') SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ if (class[1] == 't') { SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); di = *CHAR(STRING_ELT(diag, 0)); UNPROTECT(1); /* diag */ } } #define DS_CASES \ do { \ switch (class[0]) { \ case 'n': \ case 'l': \ DS_LOOP(int, LOGICAL, SHOW, ISNZ_LOGICAL); \ break; \ case 'i': \ DS_LOOP(int, INTEGER, SHOW, ISNZ_INTEGER); \ break; \ case 'd': \ DS_LOOP(double, REAL, SHOW, ISNZ_REAL); \ break; \ case 'z': \ DS_LOOP(Rcomplex, COMPLEX, SHOW, ISNZ_COMPLEX); \ break; \ default: \ break; \ } \ } while (0) if (class[2] != 'T') { int n_ = (class[2] == 'C') ? n : m; SEXP iSym = (class[2] == 'C') ? Matrix_iSym : Matrix_jSym, p0 = PROTECT(GET_SLOT(from, Matrix_pSym)), i0 = PROTECT(GET_SLOT(from, iSym)), p1 = PROTECT(allocVector(INTSXP, (R_xlen_t) n_ + 1)); SET_SLOT(to, Matrix_pSym, p1); int *pp0 = INTEGER(p0), *pp1 = INTEGER(p1), *pi0 = INTEGER(i0), j, k, kend, nd0 = 0, nd1 = 0; pp0++; *(pp1++) = 0; if (class[1] == 'g') { for (j = 0, k = 0; j < r; ++j) { kend = pp0[j]; while (k < kend) { if (pi0[k] < j) ++k; else { if (pi0[k] == j) ++nd0; k = kend; } } pp1[j] = kend - nd0; } for (j = r; j < n_; ++j) pp1[j] = pp0[j] - nd0; } else if (di != 'N') { for (j = 0; j < n_; ++j) pp1[j] = pp0[j]; } else if ((class[2] == 'C') == (ul == 'U')) { for (j = 0, k = 0; j < n_; ++j) { kend = pp0[j]; if (k < kend && pi0[kend - 1] == j) ++nd0; k = kend; pp1[j] = kend - nd0; } } else { for (j = 0, k = 0; j < n_; ++j) { kend = pp0[j]; if (k < kend && pi0[k] == j) ++nd0; k = kend; pp1[j] = kend - nd0; } } #undef DS_LOOP #define DS_LOOP(_CTYPE_, _PTR_, _MASK_, _ISNZ_) \ do { \ _CTYPE_ *pvalue = _PTR_(value); \ if (v) { \ for (j = 0; j < r; ++j) { \ if (_ISNZ_(pvalue[j])) \ ++nd1; \ pp1[j] += nd1; \ } \ for (j = r; j < n_; ++j) \ pp1[j] += nd1; \ } else if (_ISNZ_(pvalue[0])) { \ full = 1; \ for (j = 0; j < r; ++j) \ pp1[j] += ++nd1; \ for (j = r; j < n_; ++j) \ pp1[j] += nd1; \ } \ } while (0) DS_CASES; if (nd1 - nd0 > INT_MAX - pp0[n_ - 1]) error(_("%s cannot exceed %s"), "p[length(p)]", "2^31-1"); SEXP i1 = PROTECT(allocVector(INTSXP, pp1[n_ - 1])); SET_SLOT(to, iSym, i1); int *pi1 = INTEGER(i1); #undef DS_LOOP #define DS_LOOP(_CTYPE_, _PTR_, _MASK_, _ISNZ_) \ do { \ _MASK_(_CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1)); \ _CTYPE_ *pvalue = _PTR_(value); \ for (j = 0, k = 0; j < r; ++j) { \ kend = pp0[j]; \ while (k < kend && pi0[k] < j) { \ *(pi1++) = pi0[k] ; \ _MASK_(*(px1++) = px0[k]); \ ++k; \ } \ if (k < kend && pi0[k] == j) \ ++k; \ if ((v) ? _ISNZ_(pvalue[j]) : full) { \ *(pi1++) = j ; \ _MASK_(*(px1++) = (v) ? pvalue[j] : pvalue[0]); \ } \ while (k < kend) { \ *(pi1++) = pi0[k] ; \ _MASK_(*(px1++) = px0[k]); \ ++k; \ } \ } \ for (j = r; j < n_; ++j) { \ kend = pp0[j]; \ while (k < kend) { \ *(pi1++) = pi0[k] ; \ _MASK_(*(px1++) = px0[k]); \ ++k; \ } \ } \ } while (0) if (class[0] == 'n') DS_LOOP(int, LOGICAL, HIDE, ISNZ_LOGICAL); else { SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)), x1 = PROTECT(allocVector(TYPEOF(x0), pp1[n_ - 1])); SET_SLOT(to, Matrix_xSym, x1); DS_CASES; UNPROTECT(2); /* x1, x0 */ } UNPROTECT(4); /* i1, p1, i0, p0 */ } else { SEXP i0 = PROTECT(GET_SLOT(from, Matrix_iSym)), j0 = PROTECT(GET_SLOT(from, Matrix_jSym)); int *pi0 = INTEGER(i0), *pj0 = INTEGER(j0), j, nd0 = 0, nd1 = 0; R_xlen_t k, nnz0 = XLENGTH(i0), nnz1 = nnz0; if (di == 'N') for (k = 0; k < nnz0; ++k) if (pi0[k] == pj0[k]) ++nd0; #undef DS_LOOP #define DS_LOOP(_CTYPE_, _PTR_, _MASK_, _ISNZ_) \ do { \ _CTYPE_ *pvalue = _PTR_(value); \ if (v) { \ for (j = 0; j < r; ++j) \ if (_ISNZ_(pvalue[j])) \ ++nd1; \ } else if (_ISNZ_(pvalue[0])) { \ full = 1; \ nd1 = r; \ } \ } while (0) DS_CASES; if (nd1 - nd0 > R_XLEN_T_MAX - nnz0) error(_("%s cannot exceed %s"), "length(i)", "R_XLEN_T_MAX"); nnz1 += nd1 - nd0; SEXP i1 = PROTECT(allocVector(INTSXP, nnz1)), j1 = PROTECT(allocVector(INTSXP, nnz1)); SET_SLOT(to, Matrix_iSym, i1); SET_SLOT(to, Matrix_jSym, j1); int *pi1 = INTEGER(i1), *pj1 = INTEGER(j1); #undef DS_LOOP #define DS_LOOP(_CTYPE_, _PTR_, _MASK_, _ISNZ_) \ do { \ _MASK_(_CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1)); \ _CTYPE_ *pvalue = _PTR_(value); \ for (k = 0; k < nnz0; ++k) { \ if (pi0[k] != pj0[k]) { \ *(pi1++) = pi0[k]; \ *(pj1++) = pj0[k]; \ _MASK_(*(px1++) = px0[k]); \ } \ } \ if (v) { \ for (j = 0; j < r; ++j) { \ if (_ISNZ_(pvalue[j])) { \ *(pi1++) = *(pj1++) = j; \ _MASK_(*(px1++) = pvalue[j]); \ } \ } \ } else if (full) { \ for (j = 0; j < r; ++j) { \ *(pi1++) = *(pj1++) = j; \ _MASK_(*(px1++) = pvalue[0]); \ } \ } \ } while (0) if (class[0] == 'n') DS_LOOP(int, LOGICAL, HIDE, ISNZ_LOGICAL); else { SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)), x1 = PROTECT(allocVector(TYPEOF(x0), nnz1)); SET_SLOT(to, Matrix_xSym, x1); DS_CASES; UNPROTECT(2); /* x1, x0 */ } UNPROTECT(4); /* j1, i1, j0, i0 */ } #undef DS_CASES #undef DS_LOOP UNPROTECT(1); /* to */ return to; } /* diag(<[CRT]sparseMatrix>) <- value */ SEXP R_sparse_diag_set(SEXP from, SEXP value) { static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); const char *class = valid[ivalid]; SEXPTYPE tx = kindToType(class[0]), tv = TYPEOF(value); switch (tv) { case LGLSXP: case INTSXP: case REALSXP: case CPLXSXP: break; default: error(_("replacement diagonal has incompatible type \"%s\""), type2char(tv)); break; } SEXP dim = GET_SLOT(from, Matrix_DimSym); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1], r = (m < n) ? m : n; R_xlen_t len = XLENGTH(value); if (len != 1 && len != r) error(_("replacement diagonal has wrong length")); if (tv <= tx) { PROTECT(from); PROTECT(value = coerceVector(value, tx)); } else { /* defined in ./coerce.c : */ SEXP sparse_as_kind(SEXP, const char *, char); #ifndef MATRIX_ENABLE_IMATRIX if (tv == INTSXP) { PROTECT(from = sparse_as_kind(from, class, 'd')); PROTECT(value = coerceVector(value, REALSXP)); } else { #endif PROTECT(from = sparse_as_kind(from, class, typeToKind(tv))); PROTECT(value); #ifndef MATRIX_ENABLE_IMATRIX } #endif class = valid[R_check_class_etc(from, valid)]; } from = sparse_diag_set(from, class, value); UNPROTECT(2); return from; } SEXP sparse_transpose(SEXP from, const char *class, int lazy) { SEXP to; if (class[2] == 'T' || !lazy) PROTECT(to = newObject(class)); else { char cl[] = "...Matrix"; cl[0] = class[0]; cl[1] = class[1]; cl[2] = (class[2] == 'C') ? 'R' : 'C'; PROTECT(to = newObject(cl)); } SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; if (m != n) { UNPROTECT(1); /* dim */ PROTECT(dim = GET_SLOT(to, Matrix_DimSym)); pdim = INTEGER(dim); pdim[0] = n; pdim[1] = m; } else if (n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); if (class[1] == 's') SET_SLOT(to, Matrix_DimNamesSym, dimnames); else set_reversed_DimNames(to, dimnames); UNPROTECT(1); /* dimnames */ if (class[1] != 'g') { SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); char ul = *CHAR(STRING_ELT(uplo, 0)); UNPROTECT(1); /* uplo */ if (ul == 'U') { PROTECT(uplo = mkString("L")); SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ } if (class[1] == 't') { SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); char di = *CHAR(STRING_ELT(diag, 0)); if (di != 'N') SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ } else { SEXP factors = PROTECT(GET_SLOT(from, Matrix_factorsSym)); if (LENGTH(factors) > 0) SET_SLOT(to, Matrix_factorsSym, factors); UNPROTECT(1); /* factors */ } } /* It remains to set some subset of 'p', 'i', 'j', and 'x' ... */ if (class[2] == 'T') { /* No need to allocate in this case: need only reverse 'i' and 'j' */ SEXP i0 = PROTECT(GET_SLOT(from, Matrix_iSym)), j0 = PROTECT(GET_SLOT(from, Matrix_jSym)); SET_SLOT(to, Matrix_iSym, j0); SET_SLOT(to, Matrix_jSym, i0); UNPROTECT(2); /* j0, i0 */ if (class[0] != 'n') { SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)); SET_SLOT(to, Matrix_xSym, x0); UNPROTECT(1); /* x */ } UNPROTECT(1); /* to */ return to; } /* Now dealing only with [CR]sparseMatrix ... */ SEXP iSym = (class[2] == 'C') ? Matrix_iSym : Matrix_jSym, p0 = PROTECT(GET_SLOT(from, Matrix_pSym)), i0 = PROTECT(GET_SLOT(from, iSym)); if (lazy) { /* No need to allocate in this case: need only reverse 'i' and 'j' */ SEXP jSym = (class[2] == 'C') ? Matrix_jSym : Matrix_iSym; SET_SLOT(to, Matrix_pSym, p0); SET_SLOT(to, jSym, i0); UNPROTECT(2); /* i0, p0 */ if (class[0] != 'n') { SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)); SET_SLOT(to, Matrix_xSym, x0); UNPROTECT(1); /* x */ } UNPROTECT(1); /* to */ return to; } int m_ = (class[2] == 'C') ? m : n, n_ = (class[2] == 'C') ? n : m; SEXP p1 = PROTECT(allocVector(INTSXP, (R_xlen_t) m_ + 1)), i1 = PROTECT(allocVector(INTSXP, INTEGER(p0)[n_])); SET_SLOT(to, Matrix_pSym, p1); SET_SLOT(to, iSym, i1); /* defined in ./coerce.c : */ void trans(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, int, int); if (class[0] == 'n') trans(p0, i0, NULL, p1, i1, NULL, m_, n_); else { SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)), x1 = PROTECT(allocVector(TYPEOF(x0), INTEGER(p0)[n_])); SET_SLOT(to, Matrix_xSym, x1); trans(p0, i0, x0, p1, i1, x1, m_, n_); UNPROTECT(2); /* x1, x0 */ } UNPROTECT(5); /* i1, p1, i0, p0, to */ return to; } /* t(<[CRT]sparseMatrix>) */ SEXP R_sparse_transpose(SEXP from, SEXP lazy) { static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); int lazy_; if (TYPEOF(lazy) != LGLSXP || LENGTH(lazy) < 1 || (lazy_ = LOGICAL(lazy)[0]) == NA_LOGICAL) error(_("invalid '%s' to '%s'"), "lazy", __func__); return sparse_transpose(from, valid[ivalid], lazy_); } SEXP sparse_force_symmetric(SEXP from, const char *class, char ul) { char ul0 = 'U', ul1 = 'U'; if (class[1] != 'g') { SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); ul0 = ul1 = *CHAR(STRING_ELT(uplo, 0)); UNPROTECT(1); /* uplo */ } if (ul != '\0') ul1 = ul; if (class[1] == 's') { /* .s[CRT]Matrix */ if (ul0 == ul1) return from; SEXP to = PROTECT(sparse_transpose(from, class, 0)); if (class[0] == 'z') { /* Need _conjugate_ transpose */ SEXP x1 = PROTECT(GET_SLOT(to, Matrix_xSym)); conjugate(x1); UNPROTECT(1); /* x1 */ } UNPROTECT(1) /* to */; return to; } /* Now handling just .[gt][CRT]Matrix ... */ char cl[] = ".s.Matrix"; cl[0] = class[0]; cl[2] = class[2]; SEXP to = PROTECT(newObject(cl)); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), n = pdim[0]; if (pdim[1] != n) error(_("attempt to symmetrize a non-square matrix")); if (n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); set_symmetrized_DimNames(to, dimnames, -1); UNPROTECT(1); /* dimnames */ if (ul1 != 'U') { SEXP uplo = PROTECT(mkString("L")); SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ } char di = 'N'; if (class[1] == 't') { SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); di = *CHAR(STRING_ELT(diag, 0)); UNPROTECT(1); /* diag */ } /* It remains to set some subset of 'p', 'i', 'j', and 'x' ... */ #define FS_CASES \ do { \ switch (class[0]) { \ case 'l': \ FS_SUBCASES(int, LOGICAL, SHOW, 1); \ break; \ case 'i': \ FS_SUBCASES(int, INTEGER, SHOW, 1); \ break; \ case 'd': \ FS_SUBCASES(double, REAL, SHOW, 1.0); \ break; \ case 'z': \ FS_SUBCASES(Rcomplex, COMPLEX, SHOW, Matrix_zone); \ break; \ default: \ break; \ } \ } while (0) if (class[1] == 't' && di == 'N' && ul0 == ul1) { /* No need to allocate in this case: we have the triangle we want */ if (class[2] != 'T') { SEXP p0 = PROTECT(GET_SLOT(from, Matrix_pSym)); SET_SLOT(to, Matrix_pSym, p0); UNPROTECT(1); /* p0 */ } if (class[2] != 'R') { SEXP i0 = PROTECT(GET_SLOT(from, Matrix_iSym)); SET_SLOT(to, Matrix_iSym, i0); UNPROTECT(1); /* i0 */ } if (class[2] != 'C') { SEXP j0 = PROTECT(GET_SLOT(from, Matrix_jSym)); SET_SLOT(to, Matrix_jSym, j0); UNPROTECT(1); /* j0 */ } if (class[0] != 'n') { SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)); SET_SLOT(to, Matrix_xSym, x0); UNPROTECT(1); /* x0 */ } UNPROTECT(1); /* to */ return to; } else if (class[2] != 'T') { /* Symmetrizing square .[gt][CR]Matrix ... */ SEXP iSym = (class[2] == 'C') ? Matrix_iSym : Matrix_jSym, p0 = PROTECT(GET_SLOT(from, Matrix_pSym)), p1 = PROTECT(allocVector(INTSXP, (R_xlen_t) n + 1)), i0 = PROTECT(GET_SLOT(from, iSym)); int j, k, kend, *pp0 = INTEGER(p0), *pp1 = INTEGER(p1), *pi0 = INTEGER(i0), nnz0 = pp0[n], nnz1 = 0; pp0++; *(pp1++) = 0; SET_SLOT(to, Matrix_pSym, p1); /* Counting number of nonzero elements in triangle, by "column" ... */ if (class[1] == 't') { if (di != 'N') { /* Have triangular matrix with unit diagonal */ if (ul0 != ul1) { /* Returning identity matrix */ for (j = 0; j < n; ++j) pp1[j] = ++nnz1; } else { /* Returning symmetric matrix with unit diagonal */ for (j = 0; j < n; ++j) pp1[j] = ++nnz1 + pp0[j]; nnz1 += nnz0; } } else if (ul0 == ((class[2] == 'C') ? 'U' : 'L')) { /* Have triangular matrix with non-unit "trailing" diagonal and returning diagonal part */ for (j = 0; j < n; ++j) { if (pp0[j - 1] < pp0[j] && pi0[pp0[j] - 1] == j) ++nnz1; pp1[j] = nnz1; } } else { /* Have triangular matrix with non-unit "leading" diagonal and returning diagonal part */ for (j = 0; j < n; ++j) { if (pp0[j - 1] < pp0[j] && pi0[pp0[j - 1]] == j) ++nnz1; pp1[j] = nnz1; } } } else if (ul1 == ((class[2] == 'C') ? 'U' : 'L')) { /* Have general matrix and returning upper triangle */ for (j = 0, k = 0; j < n; ++j) { kend = pp0[j]; while (k < kend) { if (pi0[k] <= j) ++nnz1; ++k; } pp1[j] = nnz1; } } else { /* Have general matrix and returning lower triangle */ for (j = 0, k = 0; j < n; ++j) { kend = pp0[j]; while (k < kend) { if (pi0[k] >= j) ++nnz1; ++k; } pp1[j] = nnz1; } } /* Now allocating and filling out slots ... */ SEXP i1 = PROTECT(allocVector(INTSXP, nnz1)); int *pi1 = INTEGER(i1); SET_SLOT(to, iSym, i1); #undef FS_SUBCASES #define FS_SUBCASES(_CTYPE_, _PTR_, _MASK_, _ONE_) \ do { \ _MASK_(_CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1)); \ if (class[1] == 't') { \ if (di != 'N') { \ /* Have triangular matrix with unit diagonal */ \ if (ul0 != ul1) { \ /* Returning identity matrix */ \ for (j = 0; j < n; ++j) { \ *(pi1++) = j; \ _MASK_(*(px1++) = _ONE_); \ } \ } else if (ul0 == ((class[2] == 'C') ? 'U' : 'L')) { \ /* Returning symmetric matrix */ \ /* with unit "trailing" diagonal */ \ for (j = 0, k = 0; j < n; ++j) { \ kend = pp0[j]; \ while (k < kend) { \ *(pi1++) = pi0[k]; \ _MASK_(*(px1++) = px0[k]); \ ++k; \ } \ *(pi1++) = j; \ _MASK_(*(px1++) = _ONE_); \ } \ } else { \ /* Returning symmetric matrix */ \ /* with unit "leading" diagonal */ \ for (j = 0, k = 0; j < n; ++j) { \ *(pi1++) = j; \ _MASK_(*(px1++) = _ONE_); \ kend = pp0[j]; \ while (k < kend) { \ *(pi1++) = pi0[k]; \ _MASK_(*(px1++) = px0[k]); \ ++k; \ } \ } \ } \ } else if (ul0 == ((class[2] == 'C') ? 'U' : 'L')) { \ /* Have triangular matrix with non-unit "trailing" */ \ /* diagonal and returning diagonal part */ \ for (j = 0; j < n; ++j) { \ if (pp0[j - 1] < pp0[j] && pi0[pp0[j] - 1] == j) { \ *(pi1++) = j; \ _MASK_(*(px1++) = px0[pp0[j] - 1]); \ } \ } \ } else { \ /* Have triangular matrix with non-unit "leading" */ \ /* diagonal and returning diagonal part */ \ for (j = 0; j < n; ++j) { \ if (pp0[j - 1] < pp0[j] && pi0[pp0[j - 1]] == j) { \ *(pi1++) = j; \ _MASK_(*(px1++) = px0[pp0[j - 1]]); \ } \ } \ } \ } else if (ul1 == ((class[2] == 'C') ? 'U' : 'L')) { \ /* Have general matrix and returning upper triangle */ \ for (j = 0, k = 0; j < n; ++j) { \ kend = pp0[j]; \ while (k < kend) { \ if (pi0[k] <= j) { \ *(pi1++) = pi0[k]; \ _MASK_(*(px1++) = px0[k]); \ } \ ++k; \ } \ } \ } else { \ /* Have general matrix and returning lower triangle */ \ for (j = 0, k = 0; j < n; ++j) { \ kend = pp0[j]; \ while (k < kend) { \ if (pi0[k] >= j) { \ *(pi1++) = pi0[k]; \ _MASK_(*(px1++) = px0[k]); \ } \ ++k; \ } \ } \ } \ } while (0) if (class[0] == 'n') FS_SUBCASES(int, LOGICAL, HIDE, 1); else { SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)), x1 = PROTECT(allocVector(TYPEOF(x0), nnz1)); SET_SLOT(to, Matrix_xSym, x1); FS_CASES; UNPROTECT(2); /* x1, x0 */ } } else { /* Symmetrizing square .[gt]TMatrix ... */ SEXP i0 = PROTECT(GET_SLOT(from, Matrix_iSym)), j0 = PROTECT(GET_SLOT(from, Matrix_jSym)); int *pi0 = INTEGER(i0), *pj0 = INTEGER(j0); R_xlen_t j, k, nnz0 = XLENGTH(i0), nnz1 = 0; /* Counting number of nonzero elements in triangle ... */ if (class[1] == 't' && di != 'N') nnz1 = (ul0 == ul1) ? n + nnz0 : n; else { if (ul1 == 'U') { for (k = 0; k < nnz0; ++k) if (pi0[k] <= pj0[k]) ++nnz1; } else { for (k = 0; k < nnz0; ++k) if (pi0[k] >= pj0[k]) ++nnz1; } } /* Now allocating and filling out slots ... */ SEXP i1 = PROTECT(allocVector(INTSXP, nnz1)), j1 = PROTECT(allocVector(INTSXP, nnz1)); int *pi1 = INTEGER(i1), *pj1 = INTEGER(j1); SET_SLOT(to, Matrix_iSym, i1); SET_SLOT(to, Matrix_jSym, j1); #undef FS_SUBCASES #define FS_SUBCASES(_CTYPE_, _PTR_, _MASK_, _ONE_) \ do { \ _MASK_(_CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1)); \ if (class[1] == 't' && di != 'N') { \ if (ul0 == ul1) { \ Matrix_memcpy(pi1, pi0, nnz0, sizeof(int)); \ Matrix_memcpy(pj1, pj0, nnz0, sizeof(int)); \ _MASK_(Matrix_memcpy(px1, px0, nnz0, sizeof(_CTYPE_))); \ pi1 += nnz0; \ pj1 += nnz0; \ _MASK_(px1 += nnz0); \ } \ for (j = 0; j < n; ++j) { \ *(pi1++) = *(pj1++) = j; \ _MASK_(*(px1++) = _ONE_); \ } \ } else { \ if (ul1 == 'U') { \ for (k = 0; k < nnz0; ++k) { \ if (pi0[k] <= pj0[k]) { \ *(pi1++) = pi0[k]; \ *(pj1++) = pj0[k]; \ _MASK_(*(px1++) = px0[k]); \ } \ } \ } else { \ for (k = 0; k < nnz0; ++k) { \ if (pi0[k] <= pj0[k]) { \ *(pi1++) = pi0[k]; \ *(pj1++) = pj0[k]; \ _MASK_(*(px1++) = px0[k]); \ } \ } \ } \ } \ } while (0) if (class[0] == 'n') FS_SUBCASES(int, LOGICAL, HIDE, 1); else { SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)), x1 = PROTECT(allocVector(TYPEOF(x0), nnz1)); SET_SLOT(to, Matrix_xSym, x1); FS_CASES; UNPROTECT(2); /* x1, x0 */ } } #undef FS_CASES #undef FS_SUBCASES UNPROTECT(5); return to; } /* forceSymmetric(<[CRT]sparseMatrix>, uplo) */ SEXP R_sparse_force_symmetric(SEXP from, SEXP uplo) { static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); char ul = '\0'; if (uplo != R_NilValue) { if (TYPEOF(uplo) != STRSXP || LENGTH(uplo) < 1 || (uplo = STRING_ELT(uplo, 0)) == NA_STRING || ((ul = *CHAR(uplo)) != 'U' && ul != 'L')) error(_("invalid '%s' to '%s'"), "uplo", __func__); } return sparse_force_symmetric(from, valid[ivalid], ul); } SEXP sparse_symmpart(SEXP from, const char *class) { if (class[0] != 'z' && class[0] != 'd') { /* defined in ./coerce.c : */ SEXP sparse_as_kind(SEXP, const char *, char); from = sparse_as_kind(from, class, 'd'); } if (class[0] != 'z' && class[1] == 's') return from; PROTECT_INDEX pid; PROTECT_WITH_INDEX(from, &pid); char cl[] = ".s.Matrix"; cl[0] = (class[0] != 'z') ? 'd' : 'z'; cl[2] = class[2]; SEXP to = PROTECT(newObject(cl)); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), n = pdim[0]; if (pdim[1] != n) error(_("attempt to get symmetric part of non-square matrix")); if (n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); if (class[1] == 's') SET_SLOT(to, Matrix_DimNamesSym, dimnames); else set_symmetrized_DimNames(to, dimnames, -1); UNPROTECT(1); /* dimnames */ char ul = 'U', di = 'N'; if (class[1] != 'g') { SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); ul = *CHAR(STRING_ELT(uplo, 0)); if (ul != 'U') SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ if (class[1] == 't') { SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); di = *CHAR(STRING_ELT(diag, 0)); UNPROTECT(1); /* diag */ } } else if (class[2] == 'R') { SEXP uplo = PROTECT(mkString("L")); ul = 'L'; SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ } if (class[2] != 'T') { SEXP iSym = (class[2] == 'C') ? Matrix_iSym : Matrix_jSym, p0 = PROTECT(GET_SLOT(from, Matrix_pSym)), i0 = PROTECT(GET_SLOT(from, iSym)), x0 = PROTECT(GET_SLOT(from, Matrix_xSym)); int j, k, kend, *pp0 = INTEGER(p0) + 1, *pi0 = INTEGER(i0), nnz = pp0[n - 1]; if (class[1] == 'g') { cl[1] = 'g'; REPROTECT(from = sparse_transpose(from, cl, 0), pid); SEXP p1 = PROTECT(allocVector(INTSXP, (R_xlen_t) n + 1)), p0_ = PROTECT(GET_SLOT(from, Matrix_pSym)), i0_ = PROTECT(GET_SLOT(from, iSym)), x0_ = PROTECT(GET_SLOT(from, Matrix_xSym)); int k_, kend_, *pp0_ = INTEGER(p0_) + 1, *pi0_ = INTEGER(i0_), *pp1 = INTEGER(p1); *(pp1++) = 0; for (j = 0, k = 0, k_ = 0; j < n; ++j) { kend = pp0[j]; kend_ = pp0_[j]; pp1[j] = pp1[j - 1]; while (k < kend) { if (pi0[k] > j) k = kend; else { while (k_ < kend_ && pi0_[k_] < pi0[k]) { ++pp1[j]; ++k_; } ++pp1[j]; if (k_ < kend_ && pi0_[k_] == pi0[k]) ++k_; ++k; } } while (k_ < kend_) { if (pi0_[k_] > j) k_ = kend_; else { ++pp1[j]; ++k_; } } } SEXP i1 = PROTECT(allocVector(INTSXP, pp1[n - 1])), x1 = PROTECT(allocVector(kindToType(cl[0]), pp1[n - 1])); int *pi1 = INTEGER(i1); #undef SP_LOOP #define SP_LOOP(_CTYPE_, _PTR_, _ASSIGN_, _INCREMENT_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1), \ *px0_ = _PTR_(x0_); \ for (j = 0, k = 0, k_ = 0; j < n; ++j) { \ kend = pp0[j]; \ kend_ = pp0_[j]; \ while (k < kend) { \ if (pi0[k] > j) \ k = kend; \ else { \ while (k_ < kend_ && pi0_[k_] < pi0[k]) { \ *pi1 = pi0_[k_]; \ _ASSIGN_((*px1), 0.5 * px0_[k_]); \ ++k_; ++pi1; ++px1; \ } \ *pi1 = pi0[k]; \ _ASSIGN_((*px1), 0.5 * px0[k]); \ if (k_ < kend_ && pi0_[k_] == pi0[k]) { \ _INCREMENT_((*px1), 0.5 * px0_[k_]); \ ++k_; \ } \ ++k; ++pi1; ++px1; \ } \ } \ while (k_ < kend_) { \ if (pi0_[k_] > j) \ k_ = kend_; \ else { \ *pi1 = pi0_[k_]; \ _ASSIGN_((*px1), 0.5 * px0_[k_]); \ ++k_; ++pi1; ++px1; \ } \ } \ } \ } while (0) if (cl[0] == 'd') SP_LOOP(double, REAL, ASSIGN_REAL, INCREMENT_REAL); else SP_LOOP(Rcomplex, COMPLEX, ASSIGN_COMPLEX, INCREMENT_COMPLEX); SET_SLOT(to, Matrix_pSym, p1); SET_SLOT(to, iSym, i1); SET_SLOT(to, Matrix_xSym, x1); UNPROTECT(6); /* x1, i1, p1, x0_, i0_, p0_ */ } else if (class[1] == 't') { int leading = (class[2] == 'C') == (ul != 'U'); if (di == 'N') { SEXP x1 = PROTECT(allocVector(kindToType(cl[0]), nnz)); #undef SP_LOOP #define SP_LOOP(_CTYPE_, _PTR_, _ASSIGN_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \ if (leading) { \ for (j = 0, k = 0; j < n; ++j) { \ kend = pp0[j]; \ if (k < kend) { \ if (pi0[k] == j) \ *px1 = *px0; \ else \ _ASSIGN_((*px1), 0.5 * (*px0)); \ ++k, ++px0; ++px1; \ while (k < kend) { \ _ASSIGN_((*px1), 0.5 * (*px0)); \ ++k; ++px0; ++px1; \ } \ } \ } \ } else { \ for (j = 0, k = 0; j < n; ++j) { \ kend = pp0[j]; \ if (k < kend) { \ while (k < kend - 1) { \ _ASSIGN_((*px1), 0.5 * (*px0)); \ ++k; ++px0; ++px1; \ } \ if (pi0[k] == j) \ *px1 = *px0; \ else \ _ASSIGN_((*px1), 0.5 * (*px0)); \ ++k; ++px0; ++px1; \ } \ } \ } \ } while (0) if (cl[0] == 'd') SP_LOOP(double, REAL, ASSIGN_REAL); else SP_LOOP(Rcomplex, COMPLEX, ASSIGN_COMPLEX); SET_SLOT(to, Matrix_pSym, p0); SET_SLOT(to, iSym, i0); SET_SLOT(to, Matrix_xSym, x1); UNPROTECT(1); /* x1 */ } else { nnz += n; SEXP p1 = PROTECT(allocVector(INTSXP, (R_xlen_t) n + 1)), i1 = PROTECT(allocVector(INTSXP, nnz)), x1 = PROTECT(allocVector(kindToType(cl[0]), nnz)); int *pp1 = INTEGER(p1), *pi1 = INTEGER(i1); *(pp1++) = 0; #undef SP_LOOP #define SP_LOOP(_CTYPE_, _PTR_, _ASSIGN_, _ONE_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \ if (leading) { \ for (j = 0, k = 0; j < n; ++j) { \ kend = pp0[j]; \ pp1[j] = pp1[j - 1] + kend - k + 1; \ *pi1 = j; \ _ASSIGN_((*px1), _ONE_); \ ++pi1, ++px1; \ while (k < kend) { \ *pi1 = *pi0; \ _ASSIGN_((*px1), 0.5 * (*px0)); \ ++k; ++pi0; ++pi1; ++px0; ++px1; \ } \ } \ } else { \ for (j = 0, k = 0; j < n; ++j) { \ kend = pp0[j]; \ pp1[j] = pp1[j - 1] + kend - k + 1; \ while (k < kend) { \ *pi1 = *pi0; \ _ASSIGN_((*px1), 0.5 * (*px0)); \ ++k; ++pi0; ++pi1; ++px0; ++px1; \ } \ *pi1 = j; \ _ASSIGN_((*px1), _ONE_); \ ++pi1; ++px1; \ } \ } \ } while (0) if (cl[0] == 'd') SP_LOOP(double, REAL, ASSIGN_REAL, 1.0); else SP_LOOP(Rcomplex, COMPLEX, ASSIGN_COMPLEX, Matrix_zone); SET_SLOT(to, Matrix_pSym, p1); SET_SLOT(to, iSym, i1); SET_SLOT(to, Matrix_xSym, x1); UNPROTECT(3); /* p1, i1, x1 */ } } else { SET_SLOT(to, Matrix_pSym, p0); SET_SLOT(to, iSym, i0); if (cl[0] == 'd') SET_SLOT(to, Matrix_xSym, x0); else { /* Symmetric part of Hermitian matrix is real part */ SEXP x1 = PROTECT(duplicate(x0)); zeroIm(x1); SET_SLOT(to, Matrix_xSym, x1); UNPROTECT(1); /* x1 */ } } UNPROTECT(3); /* x0, i0, p0 */ } else { SEXP i0 = PROTECT(GET_SLOT(from, Matrix_iSym)), j0 = PROTECT(GET_SLOT(from, Matrix_jSym)), x0 = PROTECT(GET_SLOT(from, Matrix_xSym)); int *pi0 = INTEGER(i0), *pj0 = INTEGER(j0); R_xlen_t k, nnz = XLENGTH(i0); if (class[1] == 'g') { SEXP i1 = PROTECT(allocVector(INTSXP, nnz)), j1 = PROTECT(allocVector(INTSXP, nnz)), x1 = PROTECT(allocVector(kindToType(cl[0]), nnz)); int *pi1 = INTEGER(i1), *pj1 = INTEGER(j1); #undef SP_LOOP #define SP_LOOP(_CTYPE_, _PTR_, _ASSIGN_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \ for (k = 0; k < nnz; ++k) { \ if (*pi0 == *pj0) { \ *pi1 = *pi0; \ *pj1 = *pj0; \ *px1 = *px0; \ } else if (*pi0 < *pj0) { \ *pi1 = *pi0; \ *pj1 = *pj0; \ _ASSIGN_((*px1), 0.5 * (*px0)); \ } else { \ *pi1 = *pj0; \ *pj1 = *pi0; \ _ASSIGN_((*px1), 0.5 * (*px0)); \ } \ ++pi0; ++pi1; ++pj0; ++pj1; ++px0; ++px1; \ } \ } while (0) if (cl[0] == 'd') SP_LOOP(double, REAL, ASSIGN_REAL); else SP_LOOP(Rcomplex, COMPLEX, ASSIGN_COMPLEX); SET_SLOT(to, Matrix_iSym, i1); SET_SLOT(to, Matrix_jSym, j1); SET_SLOT(to, Matrix_xSym, x1); UNPROTECT(3); /* x1, j1, i1 */ } else if (class[1] == 't') { if (di == 'N') { SEXP x1 = PROTECT(allocVector(kindToType(cl[0]), nnz)); #undef SP_LOOP #define SP_LOOP(_CTYPE_, _PTR_, _ASSIGN_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \ for (k = 0; k < nnz; ++k) { \ if (*pi0 == *pj0) \ *px1 = *px0; \ else \ _ASSIGN_((*px1), 0.5 * (*px0)); \ ++px0; ++px1; \ } \ } while (0) if (cl[0] == 'd') SP_LOOP(double, REAL, ASSIGN_REAL); else SP_LOOP(Rcomplex, COMPLEX, ASSIGN_COMPLEX); SET_SLOT(to, Matrix_iSym, i0); SET_SLOT(to, Matrix_jSym, j0); SET_SLOT(to, Matrix_xSym, x1); UNPROTECT(1); /* x1 */ } else { SEXP i1 = PROTECT(allocVector(INTSXP, nnz + n)), j1 = PROTECT(allocVector(INTSXP, nnz + n)), x1 = PROTECT(allocVector(kindToType(cl[0]), nnz + n)); int j, *pi1 = INTEGER(i1), *pj1 = INTEGER(j1); #undef SP_LOOP #define SP_LOOP(_CTYPE_, _PTR_, _ASSIGN_, _ONE_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \ for (k = 0; k < nnz; ++k) { \ *pi1 = *pi0; \ *pj1 = *pj0; \ _ASSIGN_((*px1), 0.5 * (*px0)); \ ++pi0; ++pi1; ++pj0; ++pj1; ++px0; ++px1; \ } \ for (j = 0; j < n; ++j) { \ *pi1 = *pj1 = j; \ _ASSIGN_((*px1), _ONE_); \ ++pi1; ++pj1; ++px1; \ } \ } while (0) if (cl[0] == 'd') SP_LOOP(double, REAL, ASSIGN_REAL, 1.0); else SP_LOOP(Rcomplex, COMPLEX, ASSIGN_COMPLEX, Matrix_zone); SET_SLOT(to, Matrix_iSym, i1); SET_SLOT(to, Matrix_jSym, j1); SET_SLOT(to, Matrix_xSym, x1); UNPROTECT(3); /* x1, j1, i1 */ } } else { SET_SLOT(to, Matrix_iSym, i0); SET_SLOT(to, Matrix_jSym, j0); if (cl[0] == 'd') SET_SLOT(to, Matrix_xSym, x0); else { /* Symmetric part of Hermitian matrix is real part */ SEXP x1 = PROTECT(duplicate(x0)); zeroIm(x1); SET_SLOT(to, Matrix_xSym, x1); UNPROTECT(1); /* x1 */ } } UNPROTECT(3); /* x0, j0, i1 */ } UNPROTECT(2); /* to, from */ return to; } /* symmpart(<[CRT]sparseMatrix>) */ SEXP R_sparse_symmpart(SEXP from) { static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); return sparse_symmpart(from, valid[ivalid]); } SEXP sparse_skewpart(SEXP from, const char *class) { if (class[0] != 'z' && class[0] != 'd') { /* defined in ./coerce.c : */ SEXP sparse_as_kind(SEXP, const char *, char); from = sparse_as_kind(from, class, 'd'); } PROTECT_INDEX pid; PROTECT_WITH_INDEX(from, &pid); char cl[] = "...Matrix"; cl[0] = (class[0] != 'z') ? 'd' : 'z'; cl[1] = (class[1] != 's') ? 'g' : 's'; cl[2] = class[2]; SEXP to = PROTECT(newObject(cl)); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), n = pdim[0]; if (pdim[1] != n) error(_("attempt to get skew-symmetric part of non-square matrix")); if (n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); if (class[1] == 's') SET_SLOT(to, Matrix_DimNamesSym, dimnames); else set_symmetrized_DimNames(to, dimnames, -1); UNPROTECT(1); /* dimnames */ if (class[1] == 's') { SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); char ul = *CHAR(STRING_ELT(uplo, 0)); if (ul != 'U') SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ /* Skew-symmetric part of Hermitian matrix is imaginary part */ if (class[0] != 'z') { if (class[2] != 'T') { SEXP p1 = PROTECT(allocVector(INTSXP, (R_xlen_t) n + 1)); int *pp1 = INTEGER(p1); Matrix_memset(pp1, 0, (R_xlen_t) n + 1, sizeof(int)); SET_SLOT(to, Matrix_pSym, p1); UNPROTECT(1); /* p1 */ } } else { if (class[2] != 'T') { SEXP p0 = PROTECT(GET_SLOT(from, Matrix_pSym)); SET_SLOT(to, Matrix_pSym, p0); UNPROTECT(1); /* p0 */ } if (class[2] != 'R') { SEXP i0 = PROTECT(GET_SLOT(from, Matrix_iSym)); SET_SLOT(to, Matrix_iSym, i0); UNPROTECT(1); /* i0 */ } if (class[2] != 'C') { SEXP j0 = PROTECT(GET_SLOT(from, Matrix_jSym)); SET_SLOT(to, Matrix_jSym, j0); UNPROTECT(1); /* j0 */ } SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)), x1 = PROTECT(duplicate(x0)); zeroRe(x1); SET_SLOT(to, Matrix_xSym, x1); UNPROTECT(2); /* x1, x0 */ } } else if (class[2] != 'T') { SEXP iSym = (class[2] == 'C') ? Matrix_iSym : Matrix_jSym, p0 = PROTECT(GET_SLOT(from, Matrix_pSym)), i0 = PROTECT(GET_SLOT(from, iSym)), x0 = PROTECT(GET_SLOT(from, Matrix_xSym)), p1 = PROTECT(allocVector(INTSXP, (R_xlen_t) n + 1)); int j, k, kend, k_, kend_, *pp0 = INTEGER(p0), *pi0 = INTEGER(i0), *pp1 = INTEGER(p1); pp0++; *(pp1++) = 0; REPROTECT(from = sparse_transpose(from, cl, 0), pid); SEXP p0_ = PROTECT(GET_SLOT(from, Matrix_pSym)), i0_ = PROTECT(GET_SLOT(from, iSym)), x0_ = PROTECT(GET_SLOT(from, Matrix_xSym)); int *pp0_ = INTEGER(p0_), *pi0_ = INTEGER(i0_), *pp1_; pp0_++; Matrix_Calloc(pp1_, n, int); for (j = 0, k = 0, k_ = 0; j < n; ++j) { kend = pp0[j]; kend_ = pp0_[j]; while (k < kend) { if (pi0[k] >= j) k = kend; else { while (k_ < kend_ && pi0_[k_] < pi0[k]) { ++pp1_[j]; ++pp1_[pi0_[k_]]; ++k_; } ++pp1_[j]; ++pp1_[pi0[k]]; if (k_ < kend_ && pi0_[k_] == pi0[k]) ++k_; ++k; } } while (k_ < kend_) { if (pi0_[k_] >= j) k_ = kend_; else { ++pp1_[j]; ++pp1_[pi0_[k_]]; ++k_; } } } for (j = 0; j < n; ++j) { pp1[j] = pp1[j - 1] + pp1_[j]; pp1_[j] = pp1[j - 1]; } SEXP i1 = PROTECT(allocVector(INTSXP, pp1[n - 1])), x1 = PROTECT(allocVector(kindToType(cl[0]), pp1[n - 1])); int *pi1 = INTEGER(i1); #undef SP_LOOP #define SP_LOOP(_CTYPE_, _PTR_, _ASSIGN_, _INCREMENT_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1), \ *px0_ = _PTR_(x0_); \ for (j = 0, k = 0, k_ = 0; j < n; ++j) { \ kend = pp0[j]; \ kend_ = pp0_[j]; \ while (k < kend) { \ if (pi0[k] >= j) \ k = kend; \ else { \ while (k_ < kend_ && pi0_[k_] < pi0[k]) { \ pi1[pp1_[j]] = pi0_[k_]; \ _ASSIGN_(px1[pp1_[j]], -0.5 * px0_[k_]); \ pi1[pp1_[pi0_[k_]]] = j; \ _ASSIGN_(px1[pp1_[pi0_[k_]]], -px1[pp1_[j]]); \ ++pp1_[j]; \ ++pp1_[pi0_[k_]]; \ ++k_; \ } \ pi1[pp1_[j]] = pi0[k]; \ _ASSIGN_(px1[pp1_[j]], 0.5 * px0[k]); \ if (k_ < kend_ && pi0_[k_] == pi0[k]) { \ _INCREMENT_(px1[pp1_[j]], -0.5 * px0_[k_]); \ ++k_; \ } \ pi1[pp1_[pi0[k]]] = j; \ _ASSIGN_(px1[pp1_[pi0[k]]], -px1[pp1_[j]]); \ ++pp1_[j]; \ ++pp1_[pi0[k]]; \ ++k; \ } \ } \ while (k_ < kend_) { \ if (pi0_[k_] >= j) \ k_ = kend_; \ else { \ pi1[pp1_[j]] = pi0_[k_]; \ _ASSIGN_(px1[pp1_[j]], -0.5 * px0_[k_]); \ pi1[pp1_[pi0_[k_]]] = j; \ _ASSIGN_(px1[pp1_[pi0_[k_]]], -px1[pp1_[j]]); \ ++pp1_[j]; \ ++pp1_[pi0_[k_]]; \ ++k_; \ } \ } \ } \ } while (0) if (cl[0] == 'd') SP_LOOP(double, REAL, ASSIGN_REAL, INCREMENT_REAL); else SP_LOOP(Rcomplex, COMPLEX, ASSIGN_COMPLEX, INCREMENT_COMPLEX); Matrix_Free(pp1_, n); SET_SLOT(to, Matrix_pSym, p1); SET_SLOT(to, iSym, i1); SET_SLOT(to, Matrix_xSym, x1); UNPROTECT(9); /* x1, i1, p1, x0, i0, p0, x0_, i0_, p0_ */ } else { SEXP i0 = PROTECT(GET_SLOT(from, Matrix_iSym)), j0 = PROTECT(GET_SLOT(from, Matrix_jSym)), x0 = PROTECT(GET_SLOT(from, Matrix_xSym)); int *pi0 = INTEGER(i0), *pj0 = INTEGER(j0); R_xlen_t k, nnz0 = XLENGTH(i0), nnz1 = nnz0; for (k = 0; k < nnz0; ++k) if (pi0[k] == pj0[k]) --nnz1; nnz1 *= 2; SEXP i1 = PROTECT(allocVector(INTSXP, nnz1)), j1 = PROTECT(allocVector(INTSXP, nnz1)), x1 = PROTECT(allocVector(kindToType(cl[0]), nnz1)); int *pi1 = INTEGER(i1), *pj1 = INTEGER(j1); #undef SP_LOOP #define SP_LOOP(_CTYPE_, _PTR_, _ASSIGN_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \ for (k = 0; k < nnz0; ++k) { \ if (*pi0 != *pj0) { \ *pi1 = *pi0; \ *pj1 = *pj0; \ _ASSIGN_((*px1), 0.5 * (*px0)); \ ++pi1; ++pj1; ++px1; \ *pi1 = *pj0; \ *pj1 = *pi0; \ _ASSIGN_((*px1), -0.5 * (*px0)); \ ++pi1; ++pj1; ++px1; \ } \ ++pi0; ++pj0; ++px0; \ } \ } while (0) if (cl[0] == 'd') SP_LOOP(double, REAL, ASSIGN_REAL); else SP_LOOP(Rcomplex, COMPLEX, ASSIGN_COMPLEX); SET_SLOT(to, Matrix_iSym, i1); SET_SLOT(to, Matrix_jSym, j1); SET_SLOT(to, Matrix_xSym, x1); UNPROTECT(6); /* x1, j1, i1, x0, j0, i0 */ } #undef SP_LOOP UNPROTECT(2); /* to, from */ return to; } /* skewpart(<[CRT]sparseMatrix>) */ SEXP R_sparse_skewpart(SEXP from) { static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); return sparse_skewpart(from, valid[ivalid]); } int sparse_is_symmetric(SEXP obj, const char *class, int checkDN) { if (class[1] == 's') return 1; if (checkDN) { SEXP dimnames = GET_SLOT(obj, Matrix_DimNamesSym); if (!DimNames_is_symmetric(dimnames)) return 0; } if (class[1] == 't') return sparse_is_diagonal(obj, class); SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), n = pdim[0]; if (pdim[1] != n) return 0; if (n <= 1) return 1; if (class[2] == 'T') { /* defined in ./coerce.c : */ SEXP sparse_as_Csparse(SEXP, const char *); obj = sparse_as_Csparse(obj, class); } PROTECT(obj); SEXP iSym = (class[2] != 'R') ? Matrix_iSym : Matrix_jSym, p0 = PROTECT(GET_SLOT(obj, Matrix_pSym)), i0 = PROTECT(GET_SLOT(obj, iSym)); int i, j, k, kend, *pp_, *pp0 = INTEGER(p0) + 1, *pi0 = INTEGER(i0); Matrix_Calloc(pp_, n, int); Matrix_memcpy(pp_, pp0 - 1, n, sizeof(int)); int ans = 0; #define IS_LOOP(_CTYPE_, _PTR_, _MASK_, _NOTREAL_, _NOTCONJ_) \ do { \ _MASK_(_CTYPE_ *px0 = _PTR_(x0)); \ for (j = 0, k = 0; j < n; ++j) { \ kend = pp0[j]; \ while (k < kend) { \ i = pi0[k]; \ if (i >= j) { \ if (i == j) { \ if (_NOTREAL_(px0[k])) \ goto finish; \ ++pp_[j]; \ } \ k = kend; \ } else { \ if (pp_[i] == pp0[i] || pi0[pp_[i]] != j || \ _NOTCONJ_(px0[k], px0[pp_[i]])) \ goto finish; \ ++pp_[i]; \ ++pp_[j]; \ ++k; \ } \ } \ } \ } while (0) #undef NOTCONJ_PATTERN #define NOTCONJ_PATTERN(_X_, _Y_) 0 /* For all X[i,j], i >= j, we require: o that X[j,i] exists o that X[j,i] == Conj(X[i,j]) o that Im(X[j,i]) == 0 if i == j */ if (class[0] == 'n') IS_LOOP(int, LOGICAL, HIDE, NOTREAL_PATTERN, NOTCONJ_PATTERN); else { SEXP x0 = GET_SLOT(obj, Matrix_xSym); switch (class[0]) { case 'l': IS_LOOP(int, LOGICAL, SHOW, NOTREAL_LOGICAL, NOTCONJ_LOGICAL); break; case 'i': IS_LOOP(int, INTEGER, SHOW, NOTREAL_INTEGER, NOTCONJ_INTEGER); break; case 'd': IS_LOOP(double, REAL, SHOW, NOTREAL_REAL, NOTCONJ_REAL); break; case 'z': IS_LOOP(Rcomplex, COMPLEX, SHOW, NOTREAL_COMPLEX, NOTCONJ_COMPLEX); break; default: break; } } /* We further require that the upper and lower triangles have the same number of entries ... */ for (j = 0; j < n; ++j) if (pp_[j] != pp0[j]) goto finish; ans = 1; finish: Matrix_Free(pp_, n); UNPROTECT(3); /* i0, p0, obj */ #undef IS_LOOP return ans; } /* isSymmetric(<[CRT]sparseMatrix>, checkDN, tol = 0) NB: requires symmetric nonzero pattern TODO: support 'tol', 'scale' arguments and bypass all.equal ?? */ SEXP R_sparse_is_symmetric(SEXP obj, SEXP checkDN) { static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, "" }; int ivalid = R_check_class_etc(obj, valid); if (ivalid < 0) ERROR_INVALID_CLASS(obj, __func__); int checkDN_; if (TYPEOF(checkDN) != LGLSXP || LENGTH(checkDN) < 1 || (checkDN_ = LOGICAL(checkDN)[0]) == NA_LOGICAL) error(_("'%s' must be %s or %s"), "checkDN", "TRUE", "FALSE"); return ScalarLogical(sparse_is_symmetric(obj, valid[ivalid], checkDN_)); } int sparse_is_triangular(SEXP obj, const char *class, int upper) { if (class[1] == 't') { SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = *CHAR(STRING_ELT(uplo, 0)); if (upper == NA_LOGICAL || (upper != 0) == (ul == 'U')) return (ul == 'U') ? 1 : -1; else if (sparse_is_diagonal(obj, class)) return (ul == 'U') ? -1 : 1; else return 0; } if (class[1] == 's') { if (!sparse_is_diagonal(obj, class)) return 0; SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = *CHAR(STRING_ELT(uplo, 0)); if (upper == NA_LOGICAL) return (ul == 'U') ? 1 : -1; else return (upper != 0) ? 1 : -1; } SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), n = pdim[0]; if (pdim[1] != n) return 0; if (n <= 1) return (upper != 0) ? 1 : -1; if (class[2] != 'T') { SEXP iSym = (class[2] == 'C') ? Matrix_iSym : Matrix_jSym, p0 = PROTECT(GET_SLOT(obj, Matrix_pSym)), i0 = PROTECT(GET_SLOT(obj, iSym)); UNPROTECT(2); /* i0, p0 */ int j, k, kend, *pp0 = INTEGER(p0) + 1, *pi0 = INTEGER(i0); if (upper == NA_LOGICAL) { /* Examine last entry in each "column" */ for (j = 0, k = 0; j < n; ++j) { kend = pp0[j]; if (k < kend && pi0[kend - 1] > j) break; k = kend; } if (j == n) return (class[2] == 'C') ? 1 : -1; /* Examine first entry in each "column" */ for (j = 0, k = 0; j < n; ++j) { kend = pp0[j]; if (k < kend && pi0[k] < j) break; k = kend; } if (j == n) return (class[2] == 'C') ? -1 : 1; return 0; } else if ((class[2] == 'C') == (upper != 0)) { /* Examine last entry in each "column" */ for (j = 0, k = 0; j < n; ++j) { kend = pp0[j]; if (k < kend && pi0[kend - 1] > j) return 0; k = kend; } return (class[2] == 'C') ? 1 : -1; } else { /* Examine first entry in each "column" */ for (j = 0, k = 0; j < n; ++j) { kend = pp0[j]; if (k < kend && pi0[k] < j) return 0; k = kend; } return (class[2] == 'C') ? -1 : 1; } } else { SEXP i0 = PROTECT(GET_SLOT(obj, Matrix_iSym)), j0 = PROTECT(GET_SLOT(obj, Matrix_jSym)); UNPROTECT(2); /* i0, j0 */ int *pi0 = INTEGER(i0), *pj0 = INTEGER(j0); R_xlen_t k, nnz0 = XLENGTH(i0); if (upper == NA_LOGICAL) { for (k = 0; k < nnz0; ++k) if (pi0[k] > pj0[k]) break; if (k == nnz0) return 1; for (k = 0; k < nnz0; ++k) if (pi0[k] < pj0[k]) break; if (k == nnz0) return -1; return 0; } else if (upper != 0) { for (k = 0; k < nnz0; ++k) if (pi0[k] > pj0[k]) return 0; return 1; } else { for (k = 0; k < nnz0; ++k) if (pi0[k] < pj0[k]) return 0; return -1; } } } /* isTriangular(<[CRT]sparseMatrix>, upper) NB: requires triangular nonzero pattern */ SEXP R_sparse_is_triangular(SEXP obj, SEXP upper) { static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, "" }; int ivalid = R_check_class_etc(obj, valid); if (ivalid < 0) ERROR_INVALID_CLASS(obj, __func__); if (TYPEOF(upper) != LGLSXP || LENGTH(upper) < 1) error(_("'%s' must be %s or %s or %s"), "upper", "TRUE", "FALSE", "NA"); int upper_ = LOGICAL(upper)[0]; int ans_ = sparse_is_triangular(obj, valid[ivalid], upper_); SEXP ans = allocVector(LGLSXP, 1); LOGICAL(ans)[0] = ans_ != 0; if (upper_ == NA_LOGICAL && ans_ != 0) { PROTECT(ans); static SEXP kindSym = NULL; SEXP kindVal = PROTECT(mkString((ans_ > 0) ? "U" : "L")); if (!kindSym) kindSym = install("kind"); setAttrib(ans, kindSym, kindVal); UNPROTECT(2); } return ans; } int sparse_is_diagonal(SEXP obj, const char *class) { SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), n = pdim[0]; if (pdim[1] != n) return 0; if (n <= 1) return 1; if (class[2] != 'T') { SEXP iSym = (class[2] == 'C') ? Matrix_iSym : Matrix_jSym, p0 = PROTECT(GET_SLOT(obj, Matrix_pSym)), i0 = PROTECT(GET_SLOT(obj, iSym)); UNPROTECT(2); /* i0, p0 */ int j, k, kend, *pp0 = INTEGER(p0) + 1, *pi0 = INTEGER(i0); for (j = 0, k = 0; j < n; ++j) { kend = pp0[j]; if (kend - k > 1 || (kend - k == 1 && pi0[k] != j)) return 0; k = kend; } return 1; } else { SEXP i0 = PROTECT(GET_SLOT(obj, Matrix_iSym)), j0 = PROTECT(GET_SLOT(obj, Matrix_jSym)); UNPROTECT(2); /* i0, j0 */ int *pi0 = INTEGER(i0), *pj0 = INTEGER(j0); R_xlen_t k, nnz0 = XLENGTH(i0); for (k = 0; k < nnz0; ++k) if (*(pi0++) != *(pj0++)) return 0; return 1; } } /* isDiagonal(<[CRT]sparseMatrix>) NB: requires diagonal nonzero pattern */ SEXP R_sparse_is_diagonal(SEXP obj) { static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, "" }; int ivalid = R_check_class_etc(obj, valid); if (ivalid < 0) ERROR_INVALID_CLASS(obj, __func__); return ScalarLogical(sparse_is_diagonal(obj, valid[ivalid])); } #define MAP(_I_) work[_I_] #define NOMAP(_I_) _I_ #define CAST_PATTERN(_X_) 1 #define CAST_LOGICAL(_X_) (_X_ != 0) #define CAST_INTEGER(_X_) _X_ #define CAST_REAL(_X_) _X_ #define CAST_COMPLEX(_X_) _X_ #define SUM_CASES(_MAP_) \ do { \ if (class[0] == 'n') { \ if (mean) \ SUM_LOOP(int, LOGICAL, double, REAL, HIDE, \ 0.0, 1.0, NA_REAL, ISNA_PATTERN, \ _MAP_, CAST_PATTERN, INCREMENT_REAL, SCALE2_REAL); \ else \ SUM_LOOP(int, LOGICAL, int, INTEGER, HIDE, \ 0, 1, NA_INTEGER, ISNA_PATTERN, \ _MAP_, CAST_PATTERN, INCREMENT_INTEGER, SCALE2_REAL); \ } else { \ SEXP x0 = PROTECT(GET_SLOT(obj, Matrix_xSym)); \ switch (class[0]) { \ case 'l': \ if (mean) \ SUM_LOOP(int, LOGICAL, double, REAL, SHOW, \ 0.0, 1.0, NA_REAL, ISNA_LOGICAL, \ _MAP_, CAST_LOGICAL, INCREMENT_REAL, SCALE2_REAL); \ else \ SUM_LOOP(int, LOGICAL, int, INTEGER, SHOW, \ 0, 1, NA_INTEGER, ISNA_LOGICAL, \ _MAP_, CAST_LOGICAL, INCREMENT_INTEGER, SCALE2_REAL); \ break; \ case 'i': \ SUM_LOOP(int, INTEGER, double, REAL, SHOW, \ 0.0, 1.0, NA_REAL, ISNA_INTEGER, \ _MAP_, CAST_INTEGER, INCREMENT_REAL, SCALE2_REAL); \ break; \ case 'd': \ SUM_LOOP(double, REAL, double, REAL, SHOW, \ 0.0, 1.0, NA_REAL, ISNA_REAL, \ _MAP_, CAST_REAL, INCREMENT_REAL, SCALE2_REAL); \ break; \ case 'z': \ SUM_LOOP(Rcomplex, COMPLEX, Rcomplex, COMPLEX, SHOW, \ Matrix_zzero, Matrix_zone, Matrix_zna, ISNA_COMPLEX, \ _MAP_, CAST_COMPLEX, INCREMENT_COMPLEX, SCALE2_COMPLEX); \ break; \ default: \ break; \ } \ UNPROTECT(1); /* x0 */ \ } \ } while (0) #define SUM_TYPEOF(c) (c == 'z') ? CPLXSXP : ((mean || c == 'd' || c == 'i') ? REALSXP : INTSXP) static void Csparse_colsum(SEXP obj, const char *class, int m, int n, char di, int narm, int mean, SEXP res) { int narm_ = narm && mean && class[0] != 'n'; SEXP p0 = PROTECT(GET_SLOT(obj, Matrix_pSym)); int *pp0 = INTEGER(p0) + 1, j, k, kend, nnz1 = n, count = -1; if (IS_S4_OBJECT(res)) { if (di == 'N') { nnz1 = 0; for (j = 0; j < n; ++j) if (pp0[j - 1] < pp0[j]) ++nnz1; } SEXP j1 = PROTECT(allocVector(INTSXP, nnz1)), x1 = PROTECT(allocVector(SUM_TYPEOF(class[0]), nnz1)); SET_SLOT(res, Matrix_iSym, j1); SET_SLOT(res, Matrix_xSym, x1); int *pj1 = INTEGER(j1); if (di != 'N') for (j = 0; j < n; ++j) *(pj1++) = j + 1; else for (j = 0; j < n; ++j) if (pp0[j - 1] < pp0[j]) *(pj1++) = j + 1; #define SUM_LOOP(_CTYPE0_, _PTR0_, _CTYPE1_, _PTR1_, _MASK_, \ _ZERO_, _ONE_, _NA_, _ISNA_, \ _MAP_, _CAST_, _INCREMENT_, _SCALE2_) \ do { \ _MASK_(_CTYPE0_ *px0 = _PTR0_(x0)); \ _CTYPE1_ *px1 = _PTR1_(x1) , tmp; \ for (j = 0, k = 0; j < n; ++j) { \ kend = pp0[j]; \ if (k < kend || nnz1 == n) { \ *px1 = (di != 'N') ? _ONE_ : _ZERO_; \ if (mean) \ count = m; \ while (k < kend) { \ if (_ISNA_(*px0)) { \ if (!narm) \ *px1 = _NA_; \ else if (narm_) \ --count; \ } else { \ tmp = _CAST_(*px0); \ _INCREMENT_((*px1), tmp); \ } \ _MASK_(++px0); \ ++k; \ } \ if (mean) \ _SCALE2_((*px1), count); \ ++px1; \ } \ } \ } while (0) SUM_CASES(MAP); UNPROTECT(2); /* x1, j1 */ } else { SEXP x1 = res; SUM_CASES(NOMAP); } #undef SUM_LOOP UNPROTECT(1); /* p0 */ return; } static void Csparse_rowsum(SEXP obj, const char *class, int m, int n, char di, int narm, int mean, SEXP res, SEXP iSym) { int narm_ = narm && mean && class[0] != 'n'; SEXP p0 = PROTECT(GET_SLOT(obj, Matrix_pSym)), i0 = PROTECT(GET_SLOT(obj, iSym)); int *pp0 = INTEGER(p0) + 1, *pi0 = INTEGER(i0), i, j, k, kend, nnz0 = pp0[n - 1], nnz1 = m; if (IS_S4_OBJECT(res)) { int *work; Matrix_Calloc(work, m, int); if (di != 'N') for (i = 0; i < m; ++i) work[i] = i; else { if (class[1] != 's') { for (k = 0; k < nnz0; ++k) ++work[pi0[k]]; } else { for (j = 0, k = 0; j < n; ++j) { kend = pp0[j]; while (k < kend) { ++work[pi0[k]]; if (pi0[k] != j) ++work[ j]; ++k; } } } nnz1 = 0; for (i = 0; i < m; ++i) work[i] = (work[i]) ? nnz1++ : -1; } SEXP i1 = PROTECT(allocVector(INTSXP, nnz1)), x1 = PROTECT(allocVector(SUM_TYPEOF(class[0]), nnz1)); SET_SLOT(res, Matrix_iSym, i1); SET_SLOT(res, Matrix_xSym, x1); int *pi1 = INTEGER(i1); if (narm_) for (i = 0; i < nnz1; ++i) pi1[i] = n; #define SUM_LOOP(_CTYPE0_, _PTR0_, _CTYPE1_, _PTR1_, _MASK_, \ _ZERO_, _ONE_, _NA_, _ISNA_, \ _MAP_, _CAST_, _INCREMENT_, _SCALE2_) \ do { \ _MASK_(_CTYPE0_ *px0 = _PTR0_(x0)); \ _CTYPE1_ *px1 = _PTR1_(x1) ; \ _CTYPE1_ tmp = (di != 'N') ? _ONE_ : _ZERO_; \ for (i = 0; i < nnz1; ++i) \ px1[i] = tmp; \ if (class[1] != 's') { \ for (k = 0; k < nnz0; ++k) { \ if (_ISNA_(px0[k])) { \ if (!narm) \ px1[_MAP_(pi0[k])] = _NA_; \ else if (narm_) \ --pi1[_MAP_(pi0[k])]; \ } else { \ tmp = _CAST_(px0[k]); \ _INCREMENT_(px1[_MAP_(pi0[k])], tmp); \ } \ } \ } else { \ int off; \ for (j = 0, k = 0; j < n; ++j) { \ kend = pp0[j]; \ while (k < kend) { \ off = pi0[k] != j; \ if (_ISNA_(px0[k])) { \ if (!narm) { \ px1[_MAP_(pi0[k])] = _NA_; \ if (off) \ px1[_MAP_( j)] = _NA_; \ } else if (narm_) { \ --pi1[_MAP_(pi0[k])]; \ if (off) \ --pi1[_MAP_( j)]; \ } \ } else { \ tmp = _CAST_(px0[k]); \ _INCREMENT_(px1[_MAP_(pi0[k])], tmp); \ if (off) \ _INCREMENT_(px1[_MAP_( j)], tmp); \ } \ ++k; \ } \ } \ } \ if (mean) { \ if (narm_) \ for (i = 0; i < nnz1; ++i) \ _SCALE2_(px1[i], pi1[i]); \ else \ for (i = 0; i < nnz1; ++i) \ _SCALE2_(px1[i], n); \ } \ } while (0) SUM_CASES(MAP); for (i = 0; i < m; ++i) if (work[i] >= 0) *(pi1++) = i + 1; Matrix_Free(work, m); UNPROTECT(2); /* x1, i1 */ } else { SEXP x1 = res; int *pi1 = NULL; if (narm_) { Matrix_Calloc(pi1, m, int); for (i = 0; i < m; ++i) pi1[i] = n; } SUM_CASES(NOMAP); if (narm_) Matrix_Free(pi1, m); } #undef SUM_LOOP UNPROTECT(2); /* i0, p0 */ return; } static void Tsparse_colsum(SEXP obj, const char *class, int m, int n, char di, int narm, int mean, SEXP res, SEXP iSym, SEXP jSym) { int narm_ = narm && mean && class[0] != 'n'; if (narm_) obj = Tsparse_aggregate(obj); PROTECT(obj); SEXP i0 = PROTECT(GET_SLOT(obj, iSym)), j0 = PROTECT(GET_SLOT(obj, jSym)); int *pi0 = INTEGER(i0), *pj0 = INTEGER(j0), j, nnz1 = n; R_xlen_t k, nnz0 = XLENGTH(i0); if (IS_S4_OBJECT(res)) { int *work; Matrix_Calloc(work, n, int); if (di != 'N') for (j = 0; j < n; ++j) work[j] = j; else { if (class[1] != 's') { for (k = 0; k < nnz0; ++k) ++work[pj0[k]]; } else { for (k = 0; k < nnz0; ++k) { ++work[pj0[k]]; if (pi0[k] != pj0[k]) ++work[pi0[k]]; } } nnz1 = 0; for (j = 0; j < n; ++j) work[j] = (work[j]) ? nnz1++ : -1; } SEXP j1 = PROTECT(allocVector(INTSXP, nnz1)), x1 = PROTECT(allocVector(SUM_TYPEOF(class[0]), nnz1)); SET_SLOT(res, Matrix_iSym, j1); SET_SLOT(res, Matrix_xSym, x1); int *pj1 = INTEGER(j1); if (narm_) for (j = 0; j < nnz1; ++j) pj1[j] = m; #define SUM_LOOP(_CTYPE0_, _PTR0_, _CTYPE1_, _PTR1_, _MASK_, \ _ZERO_, _ONE_, _NA_, _ISNA_, \ _MAP_, _CAST_, _INCREMENT_, _SCALE2_) \ do { \ _MASK_(_CTYPE0_ *px0 = _PTR0_(x0)); \ _CTYPE1_ *px1 = _PTR1_(x1) ; \ _CTYPE1_ tmp = (di != 'N') ? _ONE_ : _ZERO_; \ for (j = 0; j < nnz1; ++j) \ px1[j] = tmp; \ if (class[1] != 's') { \ for (k = 0; k < nnz0; ++k) { \ if (_ISNA_(px0[k])) { \ if (!narm) \ px1[_MAP_(pj0[k])] = _NA_; \ else if (narm_) \ --pj1[_MAP_(pj0[k])]; \ } else { \ tmp = _CAST_(px0[k]); \ _INCREMENT_(px1[_MAP_(pj0[k])], tmp); \ } \ } \ } else { \ int off; \ for (k = 0; k < nnz0; ++k) { \ off = pi0[k] != pj0[k]; \ if (_ISNA_(px0[k])) { \ if (!narm) { \ px1[_MAP_(pj0[k])] = _NA_; \ if (off) \ px1[_MAP_(pi0[k])] = _NA_; \ } else if (narm_) { \ --pj1[_MAP_(pj0[k])]; \ if (off) \ --pj1[_MAP_(pi0[k])]; \ } \ } else { \ tmp = _CAST_(px0[k]); \ _INCREMENT_(px1[_MAP_(pj0[k])], tmp); \ if (off) \ _INCREMENT_(px1[_MAP_(pi0[k])], tmp); \ } \ } \ } \ if (mean) { \ if (narm_) \ for (j = 0; j < nnz1; ++j) \ _SCALE2_(px1[j], pj1[j]); \ else \ for (j = 0; j < nnz1; ++j) \ _SCALE2_(px1[j], m); \ } \ } while (0) SUM_CASES(MAP); for (j = 0; j < n; ++j) if (work[j] >= 0) *(pj1++) = j + 1; Matrix_Free(work, n); UNPROTECT(2); /* x1, j1 */ } else { SEXP x1 = res; int *pj1 = NULL; if (narm_) Matrix_Calloc(pj1, n, int); SUM_CASES(NOMAP); if (narm_) Matrix_Free(pj1, n); } #undef SUM_LOOP UNPROTECT(3); /* j0, i0, obj */ return; } SEXP sparse_marginsum(SEXP obj, const char *class, int margin, int narm, int mean, int sparse) { SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1], r = (margin == 0) ? m : n; SEXP res; SEXPTYPE type = SUM_TYPEOF(class[0]); if (sparse) { char cl[] = ".sparseVector"; cl[0] = (type == CPLXSXP) ? 'z' : ((type == REALSXP) ? 'd' : 'i'); PROTECT(res = newObject(cl)); SEXP length = PROTECT(ScalarInteger(r)); SET_SLOT(res, Matrix_lengthSym, length); UNPROTECT(1); /* length */ } else { PROTECT(res = allocVector(type, r)); SEXP dimnames = (class[1] != 's') ? GET_SLOT(obj, Matrix_DimNamesSym) : get_symmetrized_DimNames(obj, -1), marnames = VECTOR_ELT(dimnames, margin); if (marnames != R_NilValue) { PROTECT(marnames); setAttrib(res, R_NamesSymbol, marnames); UNPROTECT(1); /* marnames */ } } char di = 'N'; if (class[1] == 't') { SEXP diag = GET_SLOT(obj, Matrix_diagSym); di = *CHAR(STRING_ELT(diag, 0)); } if (margin == 0) { if (class[2] == 'C') { Csparse_rowsum(obj, class, m, n, di, narm, mean, res, Matrix_iSym); } else if (class[2] == 'R') { if (class[1] != 's') Csparse_colsum(obj, class, n, m, di, narm, mean, res); else Csparse_rowsum(obj, class, n, m, di, narm, mean, res, Matrix_jSym); } else { Tsparse_colsum(obj, class, n, m, di, narm, mean, res, Matrix_jSym, Matrix_iSym); } } else { if (class[2] == 'C') { if (class[1] != 's') Csparse_colsum(obj, class, m, n, di, narm, mean, res); else Csparse_rowsum(obj, class, m, n, di, narm, mean, res, Matrix_iSym); } else if (class[2] == 'R') { Csparse_rowsum(obj, class, n, m, di, narm, mean, res, Matrix_jSym); } else { Tsparse_colsum(obj, class, m, n, di, narm, mean, res, Matrix_iSym, Matrix_jSym); } } UNPROTECT(1); /* res */ return res; } /* (row|col)(Sums|Means)(<[CRT]sparseMatrix>) */ SEXP R_sparse_marginsum(SEXP obj, SEXP margin, SEXP narm, SEXP mean, SEXP sparse) { static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, "" }; int ivalid = R_check_class_etc(obj, valid); if (ivalid < 0) ERROR_INVALID_CLASS(obj, __func__); int margin_; if (TYPEOF(margin) != INTSXP || LENGTH(margin) < 1 || ((margin_ = INTEGER(margin)[0]) != 0 && margin_ != 1)) error(_("'%s' must be %d or %d"), "margin", 0, 1); int narm_; if (TYPEOF(narm) != LGLSXP || LENGTH(narm) < 1 || (narm_ = LOGICAL(narm)[0]) == NA_LOGICAL) error(_("'%s' must be %s or %s"), "narm", "TRUE", "FALSE"); int mean_; if (TYPEOF(mean) != LGLSXP || LENGTH(mean) < 1 || (mean_ = LOGICAL(mean)[0]) == NA_LOGICAL) error(_("'%s' must be %s or %s"), "mean", "TRUE", "FALSE"); int sparse_; if (TYPEOF(sparse) != LGLSXP || LENGTH(sparse) < 1 || (sparse_ = LOGICAL(sparse)[0]) == NA_LOGICAL) error(_("'%s' must be %s or %s"), "sparse", "TRUE", "FALSE"); return sparse_marginsum(obj, valid[ivalid], margin_, narm_, mean_, sparse_); } #undef SUM_CASES #undef SUM_TYPEOF #define TRY_INCREMENT(_LABEL_) \ do { \ if ((s >= 0) \ ? ( t <= MATRIX_INT_FAST64_MAX - s) \ : (-t <= s - MATRIX_INT_FAST64_MIN)) { \ s += t; \ t = 0; \ count = 0; \ } else { \ over = 1; \ goto _LABEL_; \ } \ } while (0) #define LONGDOUBLE_AS_DOUBLE(v) \ (v > DBL_MAX) ? R_PosInf : ((v < -DBL_MAX) ? R_NegInf : (double) v); SEXP sparse_sum(SEXP obj, const char *class, int narm) { if (class[2] == 'T') obj = Tsparse_aggregate(obj); PROTECT(obj); SEXP res; if (!narm && (class[0] == 'l' || class[0] == 'i')) { SEXP x = GET_SLOT(obj, Matrix_xSym); int *px = (class[0] == 'l') ? LOGICAL(x) : INTEGER(x); R_xlen_t nx = XLENGTH(x); while (nx--) { if (*px == NA_INTEGER) { res = allocVector(INTSXP, 1); INTEGER(res)[0] = NA_INTEGER; UNPROTECT(1); /* obj */ return res; } ++px; } } SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; char di = 'N'; if (class[1] == 't') { SEXP diag = GET_SLOT(obj, Matrix_diagSym); di = *CHAR(STRING_ELT(diag, 0)); } int symmetric = class[1] == 's'; if (class[2] != 'T') { SEXP iSym = (class[2] == 'C') ? Matrix_iSym : Matrix_jSym, p = PROTECT(GET_SLOT(obj, Matrix_pSym)), i = PROTECT(GET_SLOT(obj, iSym)); int *pp = INTEGER(p) + 1, *pi = INTEGER(i), j_, k = 0, kend, n_ = (class[2] == 'C') ? n : m; if (class[0] == 'n') { Matrix_int_fast64_t nnz = pp[n_ - 1]; if (di != 'N') nnz += n; if (symmetric) { SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = *CHAR(STRING_ELT(uplo, 0)); nnz *= 2; for (j_ = 0; j_ < n_; ++j_) { kend = pp[j_]; if (k < kend && pi[(ul == 'U') ? kend - 1 : k] == j_) --nnz; k = kend; } } if (nnz <= INT_MAX) { res = allocVector(INTSXP, 1); INTEGER(res)[0] = (int) nnz; } else { res = allocVector(REALSXP, 1); REAL(res)[0] = (double) nnz; } UNPROTECT(3); /* i, p, obj */ return res; } SEXP x = GET_SLOT(obj, Matrix_xSym); UNPROTECT(2); /* i, p */ if (class[0] == 'z') { Rcomplex *px = COMPLEX(x); long double zr = (di == 'N') ? 0.0L : n, zi = 0.0L; for (j_ = 0; j_ < n_; ++j_) { kend = pp[j_]; while (k < kend) { if (!(narm && (ISNAN(px[k].r) || ISNAN(px[k].i)))) { zr += (symmetric && pi[k] != j_) ? 2.0L * px[k].r : px[k].r; zi += (symmetric && pi[k] != j_) ? 2.0L * px[k].i : px[k].i; } ++k; } } res = allocVector(CPLXSXP, 1); COMPLEX(res)[0].r = LONGDOUBLE_AS_DOUBLE(zr); COMPLEX(res)[0].i = LONGDOUBLE_AS_DOUBLE(zi); } else if (class[0] == 'd') { double *px = REAL(x); long double zr = (di == 'N') ? 0.0L : n; for (j_ = 0; j_ < n_; ++j_) { kend = pp[j_]; while (k < kend) { if (!(narm && ISNAN(px[k]))) zr += (symmetric && pi[k] != j_) ? 2.0L * px[k] : px[k]; ++k; } } res = allocVector(REALSXP, 1); REAL(res)[0] = LONGDOUBLE_AS_DOUBLE(zr); } else { int *px = (class[0] == 'l') ? LOGICAL(x) : INTEGER(x); Matrix_int_fast64_t s = (di == 'N') ? 0LL : n, t = 0LL; unsigned int count = 0; int over = 0; for (j_ = 0; j_ < n_; ++j_) { kend = pp[j_]; while (k < kend) { if (!narm || px[k] != NA_INTEGER) { int d = (symmetric && pi[k] != j_) ? 2 : 1; if (count > UINT_MAX - d) TRY_INCREMENT(ifoverC); t += (d == 2) ? 2LL * px[k] : px[k]; count += d; } ++k; } } TRY_INCREMENT(ifoverC); ifoverC: if (over) { long double zr = (long double) s + (long double) t; for (; j_ < n_; ++j_) { kend = pp[j_]; while (k < kend) { if (!narm || px[k] != NA_INTEGER) zr += (symmetric && pi[k] != j_) ? 2.0L * px[k] : px[k]; ++k; } } res = allocVector(REALSXP, 1); REAL(res)[0] = LONGDOUBLE_AS_DOUBLE(zr); } else if (s > INT_MIN && s <= INT_MAX) { res = allocVector(INTSXP, 1); INTEGER(res)[0] = (int) s; } else { res = allocVector(REALSXP, 1); REAL(res)[0] = (double) s; } } } else { SEXP i = PROTECT(GET_SLOT(obj, Matrix_iSym)), j = PROTECT(GET_SLOT(obj, Matrix_jSym)); int *pi = INTEGER(i), *pj = INTEGER(j); R_xlen_t k, kend = XLENGTH(i); if (class[0] == 'n') { Matrix_int_fast64_t nnz = (Matrix_int_fast64_t) kend; if (di != 'N') nnz += n; if (symmetric) { nnz *= 2; for (k = 0; k < kend; ++k) if (pi[k] == pj[k]) --nnz; } if (nnz <= INT_MAX) { res = allocVector(INTSXP, 1); INTEGER(res)[0] = (int) nnz; } else { res = allocVector(REALSXP, 1); REAL(res)[0] = (double) nnz; } UNPROTECT(3); /* j, i, obj */ return res; } SEXP x = GET_SLOT(obj, Matrix_xSym); UNPROTECT(2); /* j, i */ if (class[0] == 'z') { Rcomplex *px = COMPLEX(x); long double zr = (di == 'N') ? 0.0L : n, zi = 0.0L; for (k = 0; k < kend; ++k) if (!(narm && (ISNAN(px[k].r) || ISNAN(px[k].i)))) { zr += (symmetric && pi[k] != pj[k]) ? 2.0L * px[k].r : px[k].r; zi += (symmetric && pi[k] != pj[k]) ? 2.0L * px[k].i : px[k].i; } res = allocVector(CPLXSXP, 1); COMPLEX(res)[0].r = LONGDOUBLE_AS_DOUBLE(zr); COMPLEX(res)[0].i = LONGDOUBLE_AS_DOUBLE(zi); } else if (class[0] == 'd') { double *px = REAL(x); long double zr = (di == 'N') ? 0.0L : n; for (k = 0; k < kend; ++k) if (!(narm && ISNAN(px[k]))) zr += (symmetric && pi[k] != pj[k]) ? 2.0L * px[k] : px[k]; res = allocVector(REALSXP, 1); REAL(res)[0] = LONGDOUBLE_AS_DOUBLE(zr); } else { int *px = (class[0] == 'i') ? INTEGER(x) : LOGICAL(x); Matrix_int_fast64_t s = (di == 'N') ? 0LL : n, t = 0LL; unsigned int count = 0; int over = 0; for (k = 0; k < kend; ++k) { if (!narm || px[k] != NA_INTEGER) { int d = (symmetric && pi[k] != pj[k]) ? 2 : 1; if (count > UINT_MAX - d) TRY_INCREMENT(ifoverT); t += (d == 2) ? 2LL * px[k] : px[k]; count += d; } } TRY_INCREMENT(ifoverT); ifoverT: if (over) { long double zr = (long double) s + (long double) t; for (; k < kend; ++k) if (!(narm && px[k] == NA_INTEGER)) zr += (symmetric && pi[k] != pj[k]) ? 2.0L * px[k] : px[k]; res = allocVector(REALSXP, 1); REAL(res)[0] = LONGDOUBLE_AS_DOUBLE(zr); } else if (s > INT_MIN && s <= INT_MAX) { res = allocVector(INTSXP, 1); INTEGER(res)[0] = (int) s; } else { res = allocVector(REALSXP, 1); REAL(res)[0] = (double) s; } } } UNPROTECT(1); /* obj */ return res; } /* sum(<[CRT]sparseMatrix>) */ SEXP R_sparse_sum(SEXP obj, SEXP narm) { static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, "" }; int ivalid = R_check_class_etc(obj, valid); if (ivalid < 0) ERROR_INVALID_CLASS(obj, __func__); int narm_; if (TYPEOF(narm) != LGLSXP || LENGTH(narm) < 1 || (narm_ = LOGICAL(narm)[0]) == NA_LOGICAL) error(_("'%s' must be %s or %s"), "narm", "TRUE", "FALSE"); return sparse_sum(obj, valid[ivalid], narm_); } SEXP sparse_prod(SEXP obj, const char *class, int narm) { if (class[2] == 'T') obj = Tsparse_aggregate(obj); PROTECT(obj); SEXP res = PROTECT(allocVector((class[0] == 'z') ? CPLXSXP : REALSXP, 1)); SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; char ul = 'U', di = 'N'; if (class[1] != 'g') { SEXP uplo = GET_SLOT(obj, Matrix_uploSym); ul = *CHAR(STRING_ELT(uplo, 0)); if (class[1] == 't') { SEXP diag = GET_SLOT(obj, Matrix_diagSym); di = *CHAR(STRING_ELT(diag, 0)); } } int symmetric = (class[1] != 's') ? 0 : (((class[2] == 'C') == (ul == 'U')) ? 1 : -1); long double zr = 1.0L, zi = 0.0L; Matrix_int_fast64_t mn = (Matrix_int_fast64_t) m * n, nnz, nnzmax = (symmetric) ? (mn + n) / 2 : mn; if (class[2] != 'T') { SEXP iSym = (class[2] == 'C') ? Matrix_iSym : Matrix_jSym, p = PROTECT(GET_SLOT(obj, Matrix_pSym)), i = PROTECT(GET_SLOT(obj, iSym)); int *pp = INTEGER(p) + 1, *pi = INTEGER(i), i_, j_, k = 0, kend, m_ = (class[2] == 'C') ? m : n, n_ = (class[2] == 'C') ? n : m, seen0 = 0; nnz = pp[n_ - 1]; if (di != 'N') nnz += n; if (class[0] == 'n') { REAL(res)[0] = (nnz == nnzmax) ? 1.0 : 0.0; UNPROTECT(4); /* i, p, res, obj */ return res; } SEXP x = GET_SLOT(obj, Matrix_xSym); UNPROTECT(2); /* i, p */ if (class[0] == 'z') { Rcomplex *px = COMPLEX(x); long double zr0, zi0; for (j_ = 0; j_ < n_; ++j_) { kend = pp[j_]; if (seen0 || kend - k == m_) { while (k < kend) { if (!(narm && (ISNAN(px[k].r) || ISNAN(px[k].i)))) { zr0 = zr; zi0 = zi; zr = zr0 * px[k].r - zi0 * px[k].i; zi = zr0 * px[k].i + zi0 * px[k].r; if (symmetric && pi[k] != j_) { zr0 = zr; zi0 = zi; zr = zr0 * px[k].r - zi0 * px[k].i; zi = zr0 * px[k].i + zi0 * px[k].r; } } ++k; } } else { int i0 = (symmetric >= 0) ? 0 : j_, i1 = (symmetric <= 0) ? m_ : j_ + 1; for (i_ = i0; i_ < i1; ++i_) { if (seen0 || (k < kend && pi[k] == i_)) { if (k >= kend) break; if (!(narm && (ISNAN(px[k].r) || ISNAN(px[k].i)))) { zr0 = zr; zi0 = zi; zr = zr0 * px[k].r - zi0 * px[k].i; zi = zr0 * px[k].i + zi0 * px[k].r; if (symmetric && pi[k] != j_) { zr0 = zr; zi0 = zi; zr = zr0 * px[k].r - zi0 * px[k].i; zi = zr0 * px[k].i + zi0 * px[k].r; } } ++k; } else if (di == 'N' || i_ != j_) { zr *= 0.0L; zi *= 0.0L; seen0 = 1; } } } } } else if (class[0] == 'd') { double *px = REAL(x); for (j_ = 0; j_ < n_; ++j_) { kend = pp[j_]; if (seen0 || kend - k == m_) { while (k < kend) { if (!(narm && ISNAN(px[k]))) zr *= (symmetric && pi[k] != j_) ? (long double) px[k] * px[k] : px[k]; ++k; } } else { int i0 = (symmetric >= 0) ? 0 : j_, i1 = (symmetric <= 0) ? m_ : j_ + 1; for (i_ = i0; i_ < i1; ++i_) { if (seen0 || (k < kend && pi[k] == i_)) { if (k >= kend) break; if (!(narm && ISNAN(px[k]))) zr *= (symmetric && pi[k] != j_) ? (long double) px[k] * px[k] : px[k]; ++k; } else if (di == 'N' || i_ != j_) { zr *= 0.0L; seen0 = 1; } } } } } else { int *px = (class[0] == 'l') ? LOGICAL(x) : INTEGER(x); for (j_ = 0; j_ < n_; ++j_) { kend = pp[j_]; if (seen0 || kend - k == m_) { while (k < kend) { if (px[k] != NA_INTEGER) zr *= (symmetric && pi[k] != j_) ? (long double) px[k] * px[k] : px[k]; else if (!narm) zr *= NA_REAL; ++k; } } else { int i0 = (symmetric >= 0) ? 0 : j_, i1 = (symmetric <= 0) ? m_ : j_ + 1; for (i_ = i0; i_ < i1; ++i_) { if (seen0 || (k < kend && pi[k] == i_)) { if (k >= kend) break; if (px[k] != NA_INTEGER) zr *= (symmetric && pi[k] != j_) ? (long double) px[k] * px[k] : px[k]; else if (!narm) zr *= NA_REAL; ++k; } else if (di == 'N' || i_ != j_) { zr *= 0.0L; seen0 = 1; } } } } } } else { SEXP i = PROTECT(GET_SLOT(obj, Matrix_iSym)), j = PROTECT(GET_SLOT(obj, Matrix_jSym)); int *pi = INTEGER(i), *pj = INTEGER(j); R_xlen_t k, kend = XLENGTH(i); nnz = (Matrix_int_fast64_t) kend; if (di != 'N') nnz += n; if (class[0] == 'n') { REAL(res)[0] = (nnz == nnzmax) ? 1.0 : 0.0; UNPROTECT(4); /* j, i, res, obj */ return res; } if (nnz < nnzmax) zr = 0.0; SEXP x = GET_SLOT(obj, Matrix_xSym); UNPROTECT(2); /* j, i */ if (class[0] == 'z') { Rcomplex *px = COMPLEX(x); long double zr0, zi0; for (k = 0; k < kend; ++k) if (!(narm && (ISNAN(px[k].r) || ISNAN(px[k].i)))) { zr0 = zr; zi0 = zi; zr = zr0 * px[k].r - zi0 * px[k].i; zi = zr0 * px[k].i + zi0 * px[k].r; if (symmetric && pi[k] != pj[k]) { zr0 = zr; zi0 = zi; zr = zr0 * px[k].r - zi0 * px[k].i; zi = zr0 * px[k].i + zi0 * px[k].r; } } } else if (class[0] == 'd') { double *px = REAL(x); for (k = 0; k < kend; ++k) if (!(narm && ISNAN(px[k]))) zr *= (symmetric && pi[k] != pj[k]) ? (long double) px[k] * px[k] : px[k]; } else { int *px = (class[0] == 'l') ? LOGICAL(x) : INTEGER(x); for (k = 0; k < kend; ++k) if (px[k] != NA_INTEGER) zr *= (symmetric && pi[k] != pj[k]) ? (long double) px[k] * px[k] : px[k]; else if (!narm) zr *= NA_REAL; } } if (class[0] == 'z') { COMPLEX(res)[0].r = LONGDOUBLE_AS_DOUBLE(zr); COMPLEX(res)[0].i = LONGDOUBLE_AS_DOUBLE(zi); } else REAL(res)[0] = LONGDOUBLE_AS_DOUBLE(zr); UNPROTECT(2); /* res, obj */ return res; } /* prod(<[CRT]sparseMatrix>) */ SEXP R_sparse_prod(SEXP obj, SEXP narm) { static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, "" }; int ivalid = R_check_class_etc(obj, valid); if (ivalid < 0) ERROR_INVALID_CLASS(obj, __func__); int narm_; if (TYPEOF(narm) != LGLSXP || LENGTH(narm) < 1 || (narm_ = LOGICAL(narm)[0]) == NA_LOGICAL) error(_("'%s' must be %s or %s"), "narm", "TRUE", "FALSE"); return sparse_prod(obj, valid[ivalid], narm_); } #undef TRY_INCREMENT #undef LONGDOUBLE_AS_DOUBLE SEXP Tsparse_aggregate(SEXP from) { static const char *valid[] = { VALID_TSPARSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); const char *cl = valid[ivalid]; SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; UNPROTECT(1); /* dim */ SEXP to, i0 = PROTECT(GET_SLOT(from, Matrix_iSym)), j0 = PROTECT(GET_SLOT(from, Matrix_jSym)), i1 = NULL, j1 = NULL; /* defined in ./coerce.c : */ void taggr(SEXP, SEXP, SEXP, SEXP *, SEXP *, SEXP *, int, int); if (cl[0] == 'n') { taggr(j0, i0, NULL, &j1, &i1, NULL, n, m); if (!i1) { UNPROTECT(2); /* j0, i0 */ return from; } PROTECT(i1); PROTECT(j1); PROTECT(to = newObject(cl)); SET_SLOT(to, Matrix_iSym, i1); SET_SLOT(to, Matrix_jSym, j1); UNPROTECT(5); /* to, j1, i1, j0, i0 */ } else { SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)), x1 = NULL; taggr(j0, i0, x0, &j1, &i1, &x1, n, m); if (!i1) { UNPROTECT(3); /* x0, j0, i0 */ return from; } PROTECT(i1); PROTECT(j1); PROTECT(x1); PROTECT(to = newObject(cl)); SET_SLOT(to, Matrix_iSym, i1); SET_SLOT(to, Matrix_jSym, j1); SET_SLOT(to, Matrix_xSym, x1); UNPROTECT(7); /* to, x1, j1, i1, x0, j0, i0 */ } PROTECT(to); if (m != n || n > 0) { PROTECT(dim = GET_SLOT(to, Matrix_DimSym)); pdim = INTEGER(dim); pdim[0] = m; pdim[1] = n; UNPROTECT(1); /* dim */ } SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); SET_SLOT(to, Matrix_DimNamesSym, dimnames); UNPROTECT(1); /* dimnames */ if (cl[1] != 'g') { SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); char ul = *CHAR(STRING_ELT(uplo, 0)); if (ul != 'U') SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ } if (cl[1] == 't') { SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); char di = *CHAR(STRING_ELT(diag, 0)); if (di != 'N') SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ } else { SEXP factors = PROTECT(GET_SLOT(from, Matrix_factorsSym)); if (LENGTH(factors) > 0) SET_SLOT(to, Matrix_factorsSym, factors); UNPROTECT(1); /* factors */ } UNPROTECT(1); /* to */ return to; } ���������������������������������������Matrix/src/chm_common.c�����������������������������������������������������������������������������0000644�0001762�0000144�00000113207�14546174764�014616� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "Mdefines.h" #include "chm_common.h" /* NB: mostly parallel to CsparseMatrix_validate in ./validity.c */ SEXP checkpi(SEXP p, SEXP i, int m, int n) { #define MKMS(_FORMAT_, ...) mkString(Matrix_sprintf(_FORMAT_, __VA_ARGS__)) if (TYPEOF(p) != INTSXP) return MKMS(_("'%s' slot is not of type \"%s\""), "p", "integer"); if (XLENGTH(p) - 1 != n) return MKMS(_("'%s' slot does not have length %s"), "p", "Dim[2]+1"); int *pp = INTEGER(p); if (pp[0] != 0) return MKMS(_("first element of '%s' slot is not 0"), "p"); int j; for (j = 1; j <= n; ++j) { if (pp[j] == NA_INTEGER) return MKMS(_("'%s' slot contains NA"), "p"); if (pp[j] < pp[j - 1]) return MKMS(_("'%s' slot is not nondecreasing"), "p"); if (pp[j] - pp[j - 1] > m) return MKMS(_("first differences of '%s' slot exceed %s"), "p", "Dim[1]"); } if (TYPEOF(i) != INTSXP) return MKMS(_("'%s' slot is not of type \"%s\""), "i", "integer"); if (XLENGTH(i) < pp[n]) return MKMS(_("'%s' slot has length less than %s"), "i", "p[length(p)]"); int *pi = INTEGER(i), k, kend, ik, i0, sorted = 1; for (j = 1, k = 0; j <= n; ++j) { kend = pp[j]; i0 = -1; while (k < kend) { ik = pi[k]; if (ik == NA_INTEGER) return MKMS(_("'%s' slot contains NA"), "i"); if (ik < 0 || ik >= m) return MKMS(_("'%s' slot has elements not in {%s}"), "i", "0,...,Dim[1]-1"); if (ik < i0) sorted = 0; else if (ik == i0) return MKMS(_("'%s' slot is not increasing within columns after sorting"), "i"); i0 = ik; ++k; } } SEXP ans = allocVector(LGLSXP, 1); LOGICAL(ans)[0] = sorted; return ans; } /** * Coerce from CHMfactor to (cholmod_factor *) * * Sets the members of a pointed-to cholmod_factor struct, using "data" * obtained from slots of a CHMfactor. The result should _not_ be * freed using cholmod_free_factor, as the resulting members point to * memory controlled by R, not by CHOLMOD. * * @param L a pointer to a cholmod_factor struct, to be modified in-place. * @param from an S4 object inheriting from virtual class CHMfactor. * * @return L. */ /* NB: mostly parallel to M2CHF in ./cholmod-etc.c */ cholmod_factor *sexp_as_cholmod_factor(cholmod_factor *L, SEXP from) { static const char *valid[] = { "dCHMsuper", "dCHMsimpl", "nCHMsuper", "nCHMsimpl", "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); const char *class = valid[ivalid]; memset(L, 0, sizeof(cholmod_factor)); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)), type = PROTECT(GET_SLOT(from, install("type"))), perm = PROTECT(GET_SLOT(from, Matrix_permSym)), colcount = PROTECT(GET_SLOT(from, install("colcount"))); L->n = INTEGER(dim)[0]; L->minor = L->n; /* FIXME: could be wrong for from <- new(...) */ L->ordering = INTEGER(type)[0]; if (L->ordering != CHOLMOD_NATURAL) L->Perm = INTEGER(perm); else { /* cholmod_check_factor allows L->Perm == NULL, but cholmod_copy_factor does not test, so it segfaults ... */ int n = (int) L->n, *Perm = (int *) R_alloc(L->n, sizeof(int)); for (int j = 0; j < n; ++j) Perm[j] = j; L->Perm = Perm; } L->ColCount = INTEGER(colcount); L->is_super = INTEGER(type)[2]; if (L->is_super) { L->is_ll = 1; L->is_monotonic = 1; SEXP super = PROTECT(GET_SLOT(from, install("super"))), pi = PROTECT(GET_SLOT(from, install("pi"))), px = PROTECT(GET_SLOT(from, install("px"))), s = PROTECT(GET_SLOT(from, install("s"))); L->super = INTEGER(super); L->pi = INTEGER(pi); L->px = INTEGER(px); L->s = INTEGER(s); L->nsuper = LENGTH(super) - 1; L->ssize = ((int *) L->pi)[L->nsuper]; L->xsize = ((int *) L->px)[L->nsuper]; L->maxcsize = INTEGER(type)[4]; L->maxesize = INTEGER(type)[5]; UNPROTECT(4); } else { L->is_ll = INTEGER(type)[1]; L->is_monotonic = INTEGER(type)[3]; if (class[0] != 'n') { SEXP p = PROTECT(GET_SLOT(from, Matrix_pSym)), i = PROTECT(GET_SLOT(from, Matrix_iSym)), nz = PROTECT(GET_SLOT(from, install("nz"))), nxt = PROTECT(GET_SLOT(from, install("nxt"))), prv = PROTECT(GET_SLOT(from, install("prv"))); L->p = INTEGER(p); L->i = INTEGER(i); L->nz = INTEGER(nz); L->next = INTEGER(nxt); L->prev = INTEGER(prv); L->nzmax = ((int *) L->p)[L->n]; UNPROTECT(5); } } L->itype = CHOLMOD_INT; L->dtype = CHOLMOD_DOUBLE; if (class[0] != 'n') { SEXP x = GET_SLOT(from, Matrix_xSym); switch (TYPEOF(x)) { case CPLXSXP: L->x = COMPLEX(x); L->xtype = CHOLMOD_COMPLEX; break; case REALSXP: L->x = REAL(x); L->xtype = CHOLMOD_REAL; break; default: ERROR_INVALID_TYPE(x, __func__); break; } } if (!cholmod_check_factor(L, &c)) error(_("'%s' failed in '%s'"), "cholmod_check_factor", __func__); UNPROTECT(4); return L; } /** * Coerce from CsparseMatrix to (cholmod_sparse *) * * Sets the members of a pointed-to cholmod_sparse struct, using "data" * obtained from slots of a CsparseMatrix. The result should _not_ be * freed using cholmod_free_sparse, as the resulting members point to * memory controlled by R, not by CHOLMOD. * * @param A a pointer to a cholmod_sparse struct, to be modified in-place. * @param from an S4 object inheriting from virtual class CsparseMatrix. * @param checkUnit a boolean indicating if the unit diagonal of formally * unit triangular CsparseMatrix should be allocated. * @param sortInPlace a boolean indicating if unsorted CsparseMatrix * should be sorted in place to avoid an allocation. * * @return A. */ /* NB: mostly parallel to M2CHS in ./cholmod-etc.c */ cholmod_sparse *sexp_as_cholmod_sparse(cholmod_sparse *A, SEXP from, Rboolean checkUnit, Rboolean sortInPlace) { /* MJ: Do users really ever pass invalid 'from' ... ? If not, then the code here could be simplified tremendously ... */ static const char *valid[] = { "dgCMatrix", "dsCMatrix", "dtCMatrix", "lgCMatrix", "lsCMatrix", "ltCMatrix", "ngCMatrix", "nsCMatrix", "ntCMatrix", "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); const char *class = valid[ivalid]; memset(A, 0, sizeof(cholmod_sparse)); SEXP dim = GET_SLOT(from, Matrix_DimSym); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; SEXP p = PROTECT(GET_SLOT(from, Matrix_pSym)), i = PROTECT(GET_SLOT(from, Matrix_iSym)), cpi = PROTECT(checkpi(p, i, m, n)); if (TYPEOF(cpi) != LGLSXP) error(_("'%s' failed in '%s': %s"), "checkpi", __func__, CHAR(STRING_ELT(cpi, 0))); int *pp = INTEGER(p), *pi = INTEGER(i), sorted = LOGICAL(cpi)[0]; size_t np = (size_t) XLENGTH(p), ni = (size_t) XLENGTH(i); if (!sorted && !sortInPlace) { int *tmp; tmp = (int *) R_alloc(np, sizeof(int)); memcpy(tmp, pp, np * sizeof(int)); pp = tmp; tmp = (int *) R_alloc(ni, sizeof(int)); memcpy(tmp, pi, ni * sizeof(int)); pi = tmp; } A->nrow = m; A->ncol = n; A->p = pp; A->i = pi; A->nzmax = ni; A->stype = 0; A->itype = CHOLMOD_INT; A->xtype = CHOLMOD_PATTERN; A->dtype = CHOLMOD_DOUBLE; A->sorted = LOGICAL(cpi)[0]; A->packed = 1; if (ni > pp[n]) { /* overallocated */ A->packed = 0; int *tmp = (int *) R_alloc(n, sizeof(int)); for (int j = 0; j < n; ++j) tmp[j] = pp[j + 1] - pp[j]; A->nz = tmp; } if (class[1] == 's') { SEXP uplo = GET_SLOT(from, Matrix_uploSym); char ul = *CHAR(STRING_ELT(uplo, 0)); A->stype = (ul == 'U') ? 1 : -1; } if (class[0] != 'n') { SEXP x = PROTECT(GET_SLOT(from, Matrix_xSym)); size_t nx = (size_t) XLENGTH(x); switch (class[0]) { case 'l': case 'i': { int *px = (TYPEOF(x) == LGLSXP) ? LOGICAL(x) : INTEGER(x); double *rtmp = (double *) R_alloc(nx, sizeof(double)); for (size_t ix = 0; ix < nx; ++ix) rtmp[ix] = (px[ix] == NA_INTEGER) ? NA_REAL : (double) px[ix]; A->x = rtmp; A->xtype = CHOLMOD_REAL; break; } case 'd': { double *px = REAL(x); if (!sorted && !sortInPlace) { double *rtmp = (double *) R_alloc(nx, sizeof(double)); memcpy(rtmp, px, nx * sizeof(double)); px = rtmp; } A->x = px; A->xtype = CHOLMOD_REAL; break; } case 'z': { Rcomplex *px = COMPLEX(x); if (!sorted && !sortInPlace) { Rcomplex *rtmp = (Rcomplex *) R_alloc(nx, sizeof(Rcomplex)); memcpy(rtmp, px, nx * sizeof(Rcomplex)); px = rtmp; } A->x = px; A->xtype = CHOLMOD_COMPLEX; break; } default: break; } UNPROTECT(1); /* x */ } if (!sorted && !cholmod_sort(A, &c)) error(_("'%s' failed in '%s'"), "cholmod_sort", __func__); if (checkUnit && class[1] == 't' && n > 0) { SEXP diag = GET_SLOT(from, Matrix_diagSym); char di = *CHAR(STRING_ELT(diag, 0)); if (di != 'N') { double one[] = { 1.0, 0.0 }; cholmod_sparse *eye = cholmod_speye(n, n, A->xtype, &c), *A1a = cholmod_add(A, eye, one, one, 1, 1, &c); memcpy(A, A1a, sizeof(cholmod_sparse)); A->p = (int *) R_alloc(A1a->ncol + 1, sizeof(int)); memcpy(A->p, A1a->p, (A1a->ncol + 1) * sizeof(int)); A->i = (int *) R_alloc(A1a->nzmax, sizeof(int)); memcpy(A->i, A1a->i, A1a->nzmax * sizeof(int)); if (A1a->xtype != CHOLMOD_PATTERN) { size_t size = (A1a->xtype == CHOLMOD_REAL) ? sizeof(double) : sizeof(Rcomplex); A->x = R_alloc(A1a->nzmax, size); memcpy(A->x, A1a->x, A1a->nzmax * size); } cholmod_free_sparse(&eye, &c); cholmod_free_sparse(&A1a, &c); } } UNPROTECT(3); /* cpi, i, p */ return A; } /** * Coerce from TsparseMatrix to (cholmod_triplet *) * * Sets the members of a pointed-to cholmod_triplet struct, using "data" * obtained from slots of a TsparseMatrix. The result should _not_ be * freed using cholmod_free_sparse, as the resulting members point to * memory controlled by R, not by CHOLMOD. * * @param A a pointer to a cholmod_triplet struct, to be modified in-place. * @param from an S4 object inheriting from virtual class TsparseMatrix. * @param checkUnit a boolean indicating if the unit diagonal of formally * unit triangular TsparseMatrix should be allocated. * * @return A. */ cholmod_triplet *sexp_as_cholmod_triplet(cholmod_triplet *A, SEXP from, Rboolean checkUnit) { static const char *valid[] = { "dgTMatrix", "dsTMatrix", "dtTMatrix", "lgTMatrix", "lsTMatrix", "ltTMatrix", "ngTMatrix", "nsTMatrix", "ntTMatrix", "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); const char *class = valid[ivalid]; memset(A, 0, sizeof(cholmod_triplet)); SEXP dim = GET_SLOT(from, Matrix_DimSym); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; SEXP i = PROTECT(GET_SLOT(from, Matrix_pSym)), j = PROTECT(GET_SLOT(from, Matrix_iSym)); int *pi = INTEGER(i), *pj = INTEGER(j); size_t nnz0 = (size_t) XLENGTH(i), nnz1 = nnz0; if (checkUnit && class[1] == 't') { SEXP diag = GET_SLOT(from, Matrix_diagSym); char di = *CHAR(STRING_ELT(diag, 0)); if (di != 'N') nnz1 += n; } if (nnz0 < nnz1) { int *tmp; tmp = (int *) R_alloc(nnz1, sizeof(int)); memcpy(tmp, pi, nnz1 * sizeof(int)); pi = tmp; tmp = (int *) R_alloc(nnz1, sizeof(int)); memcpy(tmp, pj, nnz1 * sizeof(int)); pj = tmp; pi += nnz0; pj += nnz0; for (int d = 0; d < n; ++d) *(pi++) = *(pj++) = d; pi -= nnz1; pj -= nnz1; } A->nrow = m; A->ncol = n; A->i = pi; A->j = pj; A->nzmax = nnz1; A->nnz = nnz1; A->stype = 0; A->itype = CHOLMOD_INT; A->xtype = CHOLMOD_PATTERN; A->dtype = CHOLMOD_DOUBLE; if (class[1] == 's') { SEXP uplo = GET_SLOT(from, Matrix_uploSym); char ul = *CHAR(STRING_ELT(uplo, 0)); A->stype = (ul == 'U') ? 1 : -1; } if (class[0] != 'n') { SEXP x = PROTECT(GET_SLOT(from, Matrix_xSym)); switch (class[0]) { case 'l': case 'i': { int *px = (TYPEOF(x) == LGLSXP) ? LOGICAL(x) : INTEGER(x); double *rtmp = (double *) R_alloc(nnz1, sizeof(double)); for (size_t k = 0; k < nnz0; ++k) rtmp[k] = (px[k] == NA_INTEGER) ? NA_REAL : (double) px[k]; for (size_t k = nnz0; k < nnz1; ++k) rtmp[k] = 1.0; A->x = rtmp; A->xtype = CHOLMOD_REAL; break; } case 'd': { double *px = REAL(x); if (nnz0 < nnz1) { double *rtmp = (double *) R_alloc(nnz1, sizeof(double)); memcpy(rtmp, px, nnz0 * sizeof(double)); for (size_t k = nnz0; k < nnz1; ++k) rtmp[k] = 1.0; px = rtmp; } A->x = px; A->xtype = CHOLMOD_REAL; break; } case 'z': { Rcomplex *px = COMPLEX(x); if (nnz0 < nnz1) { Rcomplex *rtmp = (Rcomplex *) R_alloc(nnz1, sizeof(Rcomplex)); memcpy(rtmp, px, nnz0 * sizeof(Rcomplex)); for (size_t k = nnz0; k < nnz1; ++k) rtmp[k] = Matrix_zone; px = rtmp; } A->x = px; A->xtype = CHOLMOD_COMPLEX; break; } default: break; } UNPROTECT(1); /* x */ } UNPROTECT(2); /* j, i */ return A; } /** * Coerce from [nlidz]geMatrix or vector to (cholmod_dense *) * * Sets the members of a pointed-to cholmod_dense struct, using "data" * obtained from slots of a [nlidz]geMatrix. The result should _not_ be * freed using cholmod_free_dense, as the resulting members point to * memory controlled by R, not by CHOLMOD. * * @param A a pointer to a cholmod_dense struct, to be modified in-place. * @param from an S4 object inheriting from class [nlidz]geMatrix _or_ * a traditional vector of type "logical", "integer", "double", or * "complex" (to be handled as a 1-column matrix if not a matrix). * * @return A. */ /* NB: mostly parallel to M2CHD in ./cholmod-etc.c */ cholmod_dense *sexp_as_cholmod_dense(cholmod_dense *A, SEXP from) { static const char *valid[] = { "dgeMatrix", "lgeMatrix", "ngeMatrix", "" }; int ivalid = R_check_class_etc(from, valid); memset(A, 0, sizeof(cholmod_dense)); int m, n; if (ivalid < 0) { switch (TYPEOF(from)) { case LGLSXP: case INTSXP: case REALSXP: case CPLXSXP: break; default: ERROR_INVALID_TYPE(from, __func__); break; } SEXP dim = getAttrib(from, R_DimSymbol); if (TYPEOF(dim) == INTSXP && LENGTH(dim) == 2) { m = INTEGER(dim)[0]; n = INTEGER(dim)[1]; } else { m = LENGTH(from); n = 1; } } else { SEXP dim = GET_SLOT(from, Matrix_DimSym); m = INTEGER(dim)[0]; n = INTEGER(dim)[1]; from = GET_SLOT(from, Matrix_xSym); } A->nrow = m; A->ncol = n; A->nzmax = A->nrow * A->ncol; A->d = A->nrow; A->dtype = CHOLMOD_DOUBLE; size_t nx = (size_t) XLENGTH(from); switch (TYPEOF(from)) { case LGLSXP: case INTSXP: { int *px = (TYPEOF(from) == LGLSXP) ? LOGICAL(from) : INTEGER(from), pattern = ivalid == 2; double *rtmp = (double *) R_alloc(nx + 1, sizeof(double)); for (size_t ix = 0; ix < nx; ++ix) rtmp[ix] = (px[ix] == NA_INTEGER) ? ((pattern) ? 1.0 : NA_REAL) : (double) px[ix]; A->x = rtmp; A->xtype = CHOLMOD_REAL; break; } case REALSXP: A->x = REAL(from); A->xtype = CHOLMOD_REAL; break; case CPLXSXP: A->x = COMPLEX(from); A->xtype = CHOLMOD_COMPLEX; break; default: ERROR_INVALID_TYPE(from, __func__); break; } return A; } /** * Coerce from (double *) to (cholmod_dense *) with given dimensions * * An analogue of base::matrix(data, nrow, ncol), * where typeof(data)=="double" and length(data)==nrow*ncol. * * @param A a pointer to a cholmod_dense struct, to be modified in-place. * @param data a pointer to an nrow*ncol*sizeof(double) block of memory. * @param nrow the desired number of rows. * @param ncol the desired number of columns. * * @return A. */ cholmod_dense *numeric_as_cholmod_dense(cholmod_dense *A, double *data, int nrow, int ncol) { memset(A, 0, sizeof(cholmod_dense)); A->nrow = nrow; A->ncol = ncol; A->nzmax = A->nrow * A->ncol; A->d = A->nrow; A->x = data; A->xtype = CHOLMOD_REAL; A->dtype = CHOLMOD_DOUBLE; return A; } /** * Coerce from (cholmod_factor *) to CHMfactor * * Allocates an S4 object inheriting from virtual class CHMfactor * and copies into the slots from members of a pointed-to cholmod_factor * struct. The specific class of the result is determined by struct * members xtype and is_super. * * @param L a pointer to a cholmod_factor struct. * @param doFree a flag indicating if and how to free L before returning. * (0) don't free, (>0) free with cholmod_free_factor, (<0) free with * R_Free. * * @return A CHMfactor. */ /* NB: mostly parallel to CHF2M in ./cholmod-etc.c */ SEXP cholmod_factor_as_sexp(cholmod_factor *L, int doFree) { #define FREE_THEN(_EXPR_) \ do { \ if (doFree != 0) { \ if (doFree < 0) \ R_Free(L); \ else if (L->itype == CHOLMOD_INT) \ cholmod_free_factor(&L, &c); \ else \ cholmod_l_free_factor(&L, &cl); \ _EXPR_; \ } \ } while (0) if (L->itype != CHOLMOD_INT) FREE_THEN(error(_("wrong '%s'"), "itype")); if (L->xtype != CHOLMOD_PATTERN && L->xtype != CHOLMOD_REAL && L->xtype != CHOLMOD_COMPLEX) FREE_THEN(error(_("wrong '%s'"), "xtype")); if (L->dtype != CHOLMOD_DOUBLE) FREE_THEN(error(_("wrong '%s'"), "dtype")); if (L->n > INT_MAX) FREE_THEN(error(_("dimensions cannot exceed %s"), "2^31-1")); if (L->super) { if (L->maxcsize > INT_MAX) FREE_THEN(error(_("'%s' would overflow type \"%s\""), "maxcsize", "integer")); } else { if (L->n == INT_MAX) FREE_THEN(error(_("n+1 would overflow type \"%s\""), "integer")); } if (L->minor < L->n) { if (L->is_ll) FREE_THEN(error(_("leading principal minor of order %d is not positive"), (int) L->minor + 1)); else FREE_THEN(error(_("leading principal minor of order %d is zero"), (int) L->minor + 1)); } char class[] = ".CHM....."; class[0] = (L->xtype == CHOLMOD_PATTERN) ? 'n' : ((L->xtype == CHOLMOD_COMPLEX) ? 'z' : 'd'); memcpy(class + 4, (L->is_super) ? "super" : "simpl", 5); SEXP to = PROTECT(newObject(class)), dim = PROTECT(GET_SLOT(to, Matrix_DimSym)); INTEGER(dim)[0] = INTEGER(dim)[1] = (int) L->n; if (L->ordering != CHOLMOD_NATURAL) { SEXP perm = PROTECT(allocVector(INTSXP, L->n)); memcpy(INTEGER(perm), L->Perm, L->n * sizeof(int)); SET_SLOT(to, Matrix_permSym, perm); UNPROTECT(1); } SEXP type = PROTECT(allocVector(INTSXP, 6)), colcount = PROTECT(allocVector(INTSXP, L->n)); INTEGER(type)[0] = L->ordering; INTEGER(type)[1] = (L->is_super) ? 1 : L->is_ll; INTEGER(type)[2] = (L->is_super) ? 1 : 0; INTEGER(type)[3] = (L->is_super) ? 1 : L->is_monotonic; INTEGER(type)[4] = (L->is_super) ? (int) L->maxcsize : 0; INTEGER(type)[5] = (L->is_super) ? (int) L->maxesize : 0; memcpy(INTEGER(colcount), L->ColCount, L->n * sizeof(int)); SET_SLOT(to, install("type"), type); SET_SLOT(to, install("colcount"), colcount); if (L->is_super) { SEXP super = PROTECT(allocVector(INTSXP, L->nsuper + 1)), pi = PROTECT(allocVector(INTSXP, L->nsuper + 1)), px = PROTECT(allocVector(INTSXP, L->nsuper + 1)), s = PROTECT(allocVector(INTSXP, L->ssize)); memcpy(INTEGER(super), L->super, (L->nsuper + 1) * sizeof(int)); memcpy(INTEGER(pi), L->pi, (L->nsuper + 1) * sizeof(int)); memcpy(INTEGER(px), L->px, (L->nsuper + 1) * sizeof(int)); memcpy(INTEGER(s), L->s, L->ssize * sizeof(int)); SET_SLOT(to, install("super"), super); SET_SLOT(to, install("pi"), pi); SET_SLOT(to, install("px"), px); SET_SLOT(to, install("s"), s); UNPROTECT(4); } else if (L->xtype != CHOLMOD_PATTERN) { SEXP p = PROTECT(allocVector(INTSXP, L->n + 1)), i = PROTECT(allocVector(INTSXP, L->nzmax)), nz = PROTECT(allocVector(INTSXP, L->n)), nxt = PROTECT(allocVector(INTSXP, L->n + 2)), prv = PROTECT(allocVector(INTSXP, L->n + 2)); memcpy(INTEGER(p), L->p, (L->n + 1) * sizeof(int)); memcpy(INTEGER(i), L->i, L->nzmax * sizeof(int)); memcpy(INTEGER(nz), L->nz, L->n * sizeof(int)); memcpy(INTEGER(nxt), L->next, (L->n + 2) * sizeof(int)); memcpy(INTEGER(prv), L->prev, (L->n + 2) * sizeof(int)); SET_SLOT(to, Matrix_pSym, p); SET_SLOT(to, Matrix_iSym, i); SET_SLOT(to, install("nz"), nz); SET_SLOT(to, install("nxt"), nxt); SET_SLOT(to, install("prv"), prv); UNPROTECT(5); } if (L->xtype != CHOLMOD_PATTERN) { SEXP x; R_xlen_t nx = (R_xlen_t) ((L->is_super) ? L->xsize : L->nzmax); if (L->xtype == CHOLMOD_COMPLEX) { PROTECT(x = allocVector(CPLXSXP, nx)); memcpy(COMPLEX(x), L->x, (size_t) nx * sizeof(Rcomplex)); } else { PROTECT(x = allocVector(REALSXP, nx)); memcpy(REAL(x), L->x, (size_t) nx * sizeof(double)); } SET_SLOT(to, Matrix_xSym, x); UNPROTECT(1); } FREE_THEN(); #undef FREE_THEN UNPROTECT(4); return to; } /** * Coerce from (cholmod_sparse *) to CsparseMatrix * * Allocates an S4 object inheriting from virtual class CsparseMatrix * and copies into the slots from members of a pointed-to cholmod_sparse * struct. The specific class of the result is determined by struct * members xtype and stype and by arguments ttype and doLogic. * * @param A a pointer to a cholmod_sparse struct. * @param doFree a flag indicating if and how to free A before returning. * (0) don't free, (>0) free with cholmod_free_sparse, (<0) free with * R_Free. * @param ttype a flag indicating if the result should be a .tCMatrix. * (0) not .tCMatrix, (>0) .tCMatrix with uplo="U", (<0) .tCMatrix * with uplo="L". If ttype=0, then the result is a .gCMatrix or * .sCMatrix depending on stype. (0) .gCMatrix, (>0) .sCMatrix with * uplo="U", (<0) .sCMatrix with uplo="L". * @param doLogic a flag indicating if the result should be a l.CMatrix * if xtype=CHOLMOD_REAL. * @param diagString a null-terminated string or NULL. The diag slot * of a .tCMatrix result is "N" if and only if diagString is NULL * or diagString[0] is 'N'. * @param dimnames an R object specifying the Dimnames slot of the result, * unused if not a list of length 2. * * @return A CsparseMatrix. */ /* NB: mostly parallel to CHS2M in ./cholmod-etc.c */ SEXP cholmod_sparse_as_sexp(cholmod_sparse *A, int doFree, int ttype, int doLogic, const char *diagString, SEXP dimnames) { #define FREE_THEN(_EXPR_) \ do { \ if (doFree != 0) { \ if (doFree < 0) \ R_Free(A); \ else if (A->itype == CHOLMOD_INT) \ cholmod_free_sparse(&A, &c); \ else \ cholmod_l_free_sparse(&A, &cl); \ _EXPR_; \ } \ } while (0) if (A->itype != CHOLMOD_INT) FREE_THEN(error(_("wrong '%s'"), "itype")); if (A->xtype != CHOLMOD_PATTERN && A->xtype != CHOLMOD_REAL && A->xtype != CHOLMOD_COMPLEX) FREE_THEN(error(_("wrong '%s'"), "xtype")); if (A->dtype != CHOLMOD_DOUBLE) FREE_THEN(error(_("wrong '%s'"), "dtype")); if (A->nrow > INT_MAX || A->ncol > INT_MAX) FREE_THEN(error(_("dimensions cannot exceed %s"), "2^31-1")); if (A->stype != 0 || !A->sorted || !A->packed) cholmod_sort(A, &c); int m = (int) A->nrow, n = (int) A->ncol, nnz = ((int *) A->p)[A->ncol]; R_xlen_t n1a = (R_xlen_t) n + 1; char class[] = "..CMatrix"; class[0] = (A->xtype == CHOLMOD_PATTERN) ? 'n' : ((A->xtype == CHOLMOD_COMPLEX) ? 'z' : ((doLogic) ? 'l' : 'd')); class[1] = (ttype != 0) ? 't' : ((A->stype != 0) ? 's' : 'g'); SEXP to = PROTECT(newObject(class)), dim = PROTECT(GET_SLOT(to, Matrix_DimSym)), p = PROTECT(allocVector(INTSXP, n1a)), i = PROTECT(allocVector(INTSXP, nnz)); INTEGER(dim)[0] = m; INTEGER(dim)[1] = n; memcpy(INTEGER(p), A->p, (size_t) n1a * sizeof(int)); memcpy(INTEGER(i), A->i, (size_t) nnz * sizeof(int)); SET_SLOT(to, Matrix_pSym, p); SET_SLOT(to, Matrix_iSym, i); if (A->xtype != CHOLMOD_PATTERN) { SEXP x; if (A->xtype == CHOLMOD_COMPLEX) { PROTECT(x = allocVector(CPLXSXP, nnz)); memcpy(COMPLEX(x), A->x, (size_t) nnz * sizeof(Rcomplex)); } else if (!doLogic) { PROTECT(x = allocVector(REALSXP, nnz)); memcpy(REAL(x), A->x, (size_t) nnz * sizeof(double)); } else { PROTECT(x = allocVector(LGLSXP, nnz)); int *px = LOGICAL(x); double *py = (double *) A->x; for (int k = 0; k < nnz; ++k) px[k] = (ISNAN(py[k])) ? NA_LOGICAL : (py[k] != 0.0); } SET_SLOT(to, Matrix_xSym, x); UNPROTECT(1); } if (ttype < 0 || A->stype < 0) { SEXP uplo = PROTECT(mkString("L")); SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); } if (ttype != 0 && diagString && diagString[0] != 'N') { SEXP diag = PROTECT(mkString("U")); SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); } if (TYPEOF(dimnames) == VECSXP && LENGTH(dimnames) == 2) SET_SLOT(to, Matrix_DimNamesSym, dimnames); FREE_THEN(); #undef FREE_THEN UNPROTECT(4); return to; } /** * Coerce from (cholmod_triplet *) to TsparseMatrix * * Allocates an S4 object inheriting from virtual class TsparseMatrix * and copies into the slots from members of a pointed-to cholmod_triplet * struct. The specific class of the result is determined by struct * members xtype and stype and by arguments ttype and doLogic. * * @param A a pointer to a cholmod_triplet struct. * @param doFree a flag indicating if and how to free A before returning. * (0) don't free, (>0) free with cholmod_free_triplet, (<0) free with * R_Free. * @param ttype a flag indicating if the result should be a .tTMatrix. * (0) not .tTMatrix, (>0) .tTMatrix with uplo="U", (<0) .tTMatrix * with uplo="L". If ttype=0, then the result is a .gTMatrix or * .sTMatrix depending on stype. (0) .gTMatrix, (>0) .sTMatrix with * uplo="U", (<0) .sTMatrix with uplo="L". * @param doLogic a flag indicating if the result should be an l.TMatrix * if xtype=CHOLMOD_REAL. * @param diagString a null-terminated string or NULL. The diag slot * of a .tTMatrix result is "N" if and only if diagString is NULL * or diagString[0] is 'N'. * @param dimnames an R object specifying the Dimnames slot of the result, * unused if not a list of length 2. * * @return A TsparseMatrix. */ SEXP cholmod_triplet_as_sexp(cholmod_triplet *A, int doFree, int ttype, int doLogic, const char *diagString, SEXP dimnames) { #define FREE_THEN(_EXPR_) \ do { \ if (doFree != 0) { \ if (doFree < 0) \ R_Free(A); \ else if (A->itype == CHOLMOD_INT) \ cholmod_free_triplet(&A, &c); \ else \ cholmod_l_free_triplet(&A, &cl); \ _EXPR_; \ } \ } while (0) if (A->itype != CHOLMOD_INT) FREE_THEN(error(_("wrong '%s'"), "itype")); if (A->xtype != CHOLMOD_PATTERN && A->xtype != CHOLMOD_REAL && A->xtype != CHOLMOD_COMPLEX) FREE_THEN(error(_("wrong '%s'"), "xtype")); if (A->dtype != CHOLMOD_DOUBLE) FREE_THEN(error(_("wrong '%s'"), "dtype")); if (A->nrow > INT_MAX || A->ncol > INT_MAX) FREE_THEN(error(_("dimensions cannot exceed %s"), "2^31-1")); int m = (int) A->nrow, n = (int) A->ncol; R_xlen_t nnz = (R_xlen_t) A->nnz; char class[] = "..TMatrix"; class[0] = (A->xtype == CHOLMOD_PATTERN) ? 'n' : ((A->xtype == CHOLMOD_COMPLEX) ? 'z' : ((doLogic) ? 'l' : 'd')); class[1] = (ttype != 0) ? 't' : ((A->stype != 0) ? 's' : 'g'); SEXP to = PROTECT(newObject(class)), dim = PROTECT(GET_SLOT(to, Matrix_DimSym)), i = PROTECT(allocVector(INTSXP, nnz)), j = PROTECT(allocVector(INTSXP, nnz)); INTEGER(dim)[0] = m; INTEGER(dim)[1] = n; memcpy(INTEGER(i), A->i, (size_t) nnz * sizeof(int)); memcpy(INTEGER(j), A->j, (size_t) nnz * sizeof(int)); if (A->stype != 0) { int tmp, *pi = INTEGER(i), *pj = INTEGER(j); for (R_xlen_t k = 0; k < nnz; ++k) { tmp = pi[k]; pi[k] = pj[k]; pj[k] = tmp; } } SET_SLOT(to, Matrix_iSym, i); SET_SLOT(to, Matrix_jSym, j); if (A->xtype != CHOLMOD_PATTERN) { SEXP x; if (A->xtype == CHOLMOD_COMPLEX) { PROTECT(x = allocVector(CPLXSXP, nnz)); memcpy(COMPLEX(x), A->x, (size_t) nnz * sizeof(Rcomplex)); } else if (!doLogic) { PROTECT(x = allocVector(REALSXP, nnz)); memcpy(REAL(x), A->x, (size_t) nnz * sizeof(double)); } else { PROTECT(x = allocVector(LGLSXP, nnz)); int *px = LOGICAL(x); double *py = (double *) A->x; for (R_xlen_t k = 0; k < nnz; ++k) px[k] = (ISNAN(py[k])) ? NA_LOGICAL : (py[k] != 0.0); } SET_SLOT(to, Matrix_xSym, x); UNPROTECT(1); } if (ttype < 0 || A->stype < 0) { SEXP uplo = PROTECT(mkString("L")); SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); } if (ttype != 0 && diagString && diagString[0] != 'N') { SEXP diag = PROTECT(mkString("U")); SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); } if (TYPEOF(dimnames) == VECSXP && LENGTH(dimnames) == 2) SET_SLOT(to, Matrix_DimNamesSym, dimnames); FREE_THEN(); #undef FREE_THEN UNPROTECT(4); return to; } /** * Coerce from (cholmod_dense *) to [dz]geMatrix * * Allocates an S4 object of class [dz]geMatrix * and copies into the slots from members of a pointed-to cholmod_dense * struct. The specific class of the result is determined by struct * member xtype. * * @param A a pointer to a cholmod_dense struct. * @param doFree a flag indicating if and how to free A before returning. * (0) don't free, (>0) free with cholmod_free_dense, (<0) free with * R_Free. * * @return A [dz]geMatrix. */ /* NB: mostly parallel to CHD2M in ./cholmod-etc.c */ SEXP cholmod_dense_as_sexp(cholmod_dense *A, int doFree) { #define FREE_THEN(_EXPR_) \ do { \ if (doFree != 0) { \ if (doFree < 0) \ R_Free(A); \ else \ cholmod_free_dense(&A, &c); \ _EXPR_; \ } \ } while (0) if (A->xtype != CHOLMOD_REAL && A->xtype != CHOLMOD_COMPLEX) FREE_THEN(error(_("wrong '%s'"), "xtype")); if (A->dtype != CHOLMOD_DOUBLE) FREE_THEN(error(_("wrong '%s'"), "dtype")); if (A->d != A->nrow) /* MJ: currently no need to support this case */ FREE_THEN(error(_("leading dimension not equal to number of rows"))); if (A->nrow > INT_MAX || A->ncol > INT_MAX) FREE_THEN(error(_("dimensions cannot exceed %s"), "2^31-1")); int m = (int) A->nrow, n = (int) A->ncol; if ((Matrix_int_fast64_t) m * n > R_XLEN_T_MAX) FREE_THEN(error(_("attempt to allocate vector of length exceeding %s"), "R_XLEN_T_MAX")); char class[] = ".geMatrix"; class[0] = (A->xtype == CHOLMOD_COMPLEX) ? 'z' : 'd'; SEXP to = PROTECT(newObject(class)), dim = PROTECT(GET_SLOT(to, Matrix_DimSym)); INTEGER(dim)[0] = m; INTEGER(dim)[1] = n; SEXP x; if (A->xtype == CHOLMOD_COMPLEX) { PROTECT(x = allocVector(CPLXSXP, (R_xlen_t) m * n)); memcpy(COMPLEX(x), A->x, (size_t) m * n * sizeof(Rcomplex)); } else { PROTECT(x = allocVector(REALSXP, (R_xlen_t) m * n)); memcpy(REAL(x), A->x, (size_t) m * n * sizeof(double)); } SET_SLOT(to, Matrix_xSym, x); FREE_THEN(); #undef FREE_THEN UNPROTECT(3); return to; } /** * Log determinant from Cholesky factorization * * Computes log(det(A)) given the Cholesky factorization of A as * P1 * A * P1' = L1 * D * L1' = L * L', L = L1 * sqrt(D). The * result is computed as sum(log(diag(D))) or 2*sum(log(diag(L))), * depending on members is_super and is_ll of the supplied struct. * Note that CHOLMOD does not require diag(D) to be positive and * that this routine does not check (FIXME). * * @param L a pointer to a cholmod_factor struct. It is assumed that * L->xtype=CHOLMOD_REAL. */ double cholmod_factor_ldetA(cholmod_factor *L) { int i, j, p; double ans = 0; if (L->is_super) { int *lpi = (int *) L->pi, *lsup = (int *) L->super; for (i = 0; i < L->nsuper; i++) { int nrp1 = 1 + lpi[i + 1] - lpi[i], nc = lsup[i + 1] - lsup[i]; double *x = (double *) L->x + ((int *) L->px)[i]; for (R_xlen_t jn = 0, j = 0; j < nc; j++, jn += nrp1) ans += 2.0 * log(fabs(x[jn])); } } else { int *li = (int *) L->i, *lp = (int *) L->p; double *lx = (double *) L->x; for (j = 0; j < L->n; j++) { for (p = lp[j]; li[p] != j && p < lp[j + 1]; p++) ; if (li[p] != j) { error(_("invalid simplicial Cholesky factorization: structural zero on main diagonal in column %d"), j); break; } ans += log(lx[p] * ((L->is_ll) ? lx[p] : 1.0)); } } return ans; } /** * Update a Cholesky factorization * * Updates in-place the Cholesky factorization of a symmetric matrix * X+alpha*I with the Cholesky factorization of * (1) A+beta*I, where A is a symmetric matrix sharing the nonzero pattern * of X, or * (2) A*A'+beta*I, where A is a general matrix sharing the nonzero pattern * of Y, assuming that X = Y*Y'. * * @param L a pointer to a cholmod_factor struct, to be modified in-place. * @param A a pointer to a cholmod_sparse struct. * @param beta a multiplier, typically positive, to guarantee strict * diagonal dominance. * * @return L. */ cholmod_factor *cholmod_factor_update(cholmod_factor *L, cholmod_sparse *A, double beta) { int ll = L->is_ll; double z[2]; z[0] = beta; z[1] = 0.0; if (!cholmod_factorize_p(A, z, NULL, 0, L, &c)) error(_("'%s' failed in '%s'"), "cholmod_factorize_p", __func__); if (L->is_ll != ll && !cholmod_change_factor(L->xtype, ll, L->is_super, 1, 1, L, &c)) error(_("'%s' failed in '%s'"), "cholmod_change_factor", __func__); return L; } #if 0 static int R_cholmod_print_function(const char *fmt, ...) { va_list(ap); va_start(ap, fmt); Rprintf((char *) fmt, ap); va_end(ap); return 0; } #endif static void R_cholmod_error_handler(int status, const char *file, int line, const char *message) { R_cholmod_common_envget(); if (status < 0) error(_("CHOLMOD error '%s' at file '%s', line %d"), message, file, line); else warning(_("CHOLMOD warning '%s' at file '%s', line %d"), message, file, line); } int R_cholmod_start(cholmod_common *Common) { int ans = cholmod_start(Common); if (!ans) error(_("'%s' failed in '%s'"), "cholmod_start", __func__); #if 0 /* No longer, with SuiteSparse 5.7.1 : */ Common->print_function = # if 0 R_cholmod_print_function; # else NULL; # endif #endif Common->error_handler = R_cholmod_error_handler; return ans; } int R_cholmod_finish(cholmod_common *Common) { int ans = cholmod_finish(Common); if (!ans) error(_("'%s' failed in '%s'"), "cholmod_finish", __func__); return ans; } SEXP cholmod_common_env; static SEXP dboundSym, grow0Sym, grow1Sym, grow2Sym, maxrankSym, supernodal_switchSym, supernodalSym, final_asisSym, final_superSym, final_llSym, final_packSym, final_monotonicSym, final_resymbolSym, prefer_zomplexSym, prefer_upperSym, quick_return_if_not_posdefSym, nmethodsSym, postorderSym, m0_ordSym; SEXP R_cholmod_common_envini(SEXP rho) { if (!isEnvironment(rho)) ERROR_INVALID_TYPE(rho, __func__); cholmod_common_env = rho; dboundSym = install("dbound"); grow0Sym = install("grow0"); grow1Sym = install("grow1"); grow2Sym = install("grow2"); maxrankSym = install("maxrank"); supernodal_switchSym = install("supernodal_switch"); supernodalSym = install("supernodal"); final_asisSym = install("final_asis"); final_superSym = install("final_super"); final_llSym = install("final_ll"); final_packSym = install("final_pack"); final_monotonicSym = install("final_monotonic"); final_resymbolSym = install("final_resymbol"); prefer_zomplexSym = install("final_zomplex"); prefer_upperSym = install("final_upper"); quick_return_if_not_posdefSym = install("quick_return_if_not_posdef"); nmethodsSym = install("nmethods"); postorderSym = install("postorder"); m0_ordSym = install("m0.ord"); R_cholmod_common_envset(); return R_NilValue; } void R_cholmod_common_envset(void) { SEXP rho = cholmod_common_env, tmp; #define SET_FRAME_FROM_MEMBER(_MEMBER_, _KIND_) \ do { \ PROTECT(tmp = Scalar ## _KIND_(c. _MEMBER_)); \ defineVar(_MEMBER_ ## Sym, tmp, rho); \ UNPROTECT(1); \ } while (0) SET_FRAME_FROM_MEMBER(dbound, Real); SET_FRAME_FROM_MEMBER(grow0, Real); SET_FRAME_FROM_MEMBER(grow1, Real); SET_FRAME_FROM_MEMBER(grow2, Integer); SET_FRAME_FROM_MEMBER(maxrank, Integer); SET_FRAME_FROM_MEMBER(supernodal_switch, Real); SET_FRAME_FROM_MEMBER(supernodal, Logical); SET_FRAME_FROM_MEMBER(final_asis, Logical); SET_FRAME_FROM_MEMBER(final_super, Logical); SET_FRAME_FROM_MEMBER(final_ll, Logical); SET_FRAME_FROM_MEMBER(final_pack, Logical); SET_FRAME_FROM_MEMBER(final_monotonic, Logical); SET_FRAME_FROM_MEMBER(final_resymbol, Logical); SET_FRAME_FROM_MEMBER(prefer_zomplex, Logical); SET_FRAME_FROM_MEMBER(prefer_upper, Logical); SET_FRAME_FROM_MEMBER(quick_return_if_not_posdef, Logical); SET_FRAME_FROM_MEMBER(nmethods, Integer); SET_FRAME_FROM_MEMBER(postorder, Logical); PROTECT(tmp = ScalarInteger(c.method[0].ordering)); defineVar(m0_ordSym, tmp, rho); UNPROTECT(1); return; } void R_cholmod_common_envget(void) { SEXP rho = cholmod_common_env, tmp; #define GET_MEMBER_FROM_FRAME(_MEMBER_, _KIND_) \ do { \ PROTECT(tmp = findVarInFrame(rho, _MEMBER_ ## Sym)); \ c. _MEMBER_ = as ## _KIND_(tmp); \ UNPROTECT(1); \ } while (0) GET_MEMBER_FROM_FRAME(dbound, Real); GET_MEMBER_FROM_FRAME(grow0, Real); GET_MEMBER_FROM_FRAME(grow1, Real); GET_MEMBER_FROM_FRAME(grow2, Integer); GET_MEMBER_FROM_FRAME(maxrank, Integer); GET_MEMBER_FROM_FRAME(supernodal_switch, Real); GET_MEMBER_FROM_FRAME(supernodal, Logical); GET_MEMBER_FROM_FRAME(final_asis, Logical); GET_MEMBER_FROM_FRAME(final_super, Logical); GET_MEMBER_FROM_FRAME(final_ll, Logical); GET_MEMBER_FROM_FRAME(final_pack, Logical); GET_MEMBER_FROM_FRAME(final_monotonic, Logical); GET_MEMBER_FROM_FRAME(final_resymbol, Logical); GET_MEMBER_FROM_FRAME(prefer_zomplex, Logical); GET_MEMBER_FROM_FRAME(prefer_upper, Logical); GET_MEMBER_FROM_FRAME(quick_return_if_not_posdef, Logical); GET_MEMBER_FROM_FRAME(nmethods, Integer); GET_MEMBER_FROM_FRAME(postorder, Logical); PROTECT(tmp = findVarInFrame(rho, m0_ordSym)); c.method[0].ordering = asInteger(tmp); UNPROTECT(1); return; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/attrib.h���������������������������������������������������������������������������������0000644�0001762�0000144�00000000337�14503225712�013747� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_ATTRIB_H #define MATRIX_ATTRIB_H #include SEXP R_DimNames_is_symmetric(SEXP); SEXP R_symDN(SEXP); SEXP R_revDN(SEXP); SEXP R_set_factor(SEXP, SEXP, SEXP, SEXP); #endif /* MATRIX_ATTRIB_H */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/cholmod-etc.h����������������������������������������������������������������������������0000644�0001762�0000144�00000000740�14511304746�014662� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_CHOLMOD_ETC_H #define MATRIX_CHOLMOD_ETC_H #include #include "SuiteSparse_config/SuiteSparse_config.h" #include "CHOLMOD/Include/cholmod.h" extern cholmod_common c ; extern cholmod_common cl; cholmod_factor *M2CHF(SEXP, int); cholmod_sparse *M2CHS(SEXP, int); cholmod_dense *M2CHD(SEXP, int); SEXP CHF2M(cholmod_factor *, int); SEXP CHS2M(cholmod_sparse *, int, char); SEXP CHD2M(cholmod_dense *, int, char); #endif /* MATRIX_CHOLMOD_ETC_H */ ��������������������������������Matrix/src/Mdefines.h�������������������������������������������������������������������������������0000644�0001762�0000144�00000022213�14516024403�014207� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_MDEFINES_H #define MATRIX_MDEFINES_H #include "version.h" #define Matrix_Domain "Matrix" #define Matrix_CallocThreshold 8192 #define Matrix_ErrorBufferSize 4096 /* NB: system headers should come before R headers */ #ifdef __GLIBC__ /* ensure that strdup() and others are declared when string.h is included : */ # define _POSIX_C_SOURCE 200809L #endif #include #include #include #include #ifdef INT_FAST64_MAX typedef int_fast64_t Matrix_int_fast64_t; # define MATRIX_INT_FAST64_MIN INT_FAST64_MIN # define MATRIX_INT_FAST64_MAX INT_FAST64_MAX #else typedef long long Matrix_int_fast64_t; # define MATRIX_INT_FAST64_MIN LLONG_MIN # define MATRIX_INT_FAST64_MAX LLONG_MAX #endif #ifndef STRICT_R_HEADERS # define STRICT_R_HEADERS #endif #include #include /* Copy and paste from WRE : */ #ifdef ENABLE_NLS # include # define _(String) dgettext(Matrix_Domain, String) #else # define _(String) (String) # define dngettext(Domain, String, StringP, N) ((N == 1) ? String : StringP) #endif /* Copy and paste from Defn.h : */ /* 'alloca' is neither C99 nor POSIX */ #ifdef __GNUC__ /* This covers GNU, Clang and Intel compilers */ /* #undef needed in case some other header, e.g. malloc.h, already did this */ # undef alloca # define alloca(x) __builtin_alloca((x)) #else # ifdef HAVE_ALLOCA_H /* This covers native compilers on Solaris and AIX */ # include # endif /* It might have been defined via some other standard header, e.g. stdlib.h */ # if !HAVE_DECL_ALLOCA extern void *alloca(size_t); # endif #endif #define Matrix_Calloc(_VAR_, _N_, _CTYPE_) \ do { \ if (_N_ >= Matrix_CallocThreshold) \ _VAR_ = R_Calloc(_N_, _CTYPE_); \ else { \ _VAR_ = (_CTYPE_ *) alloca((size_t) (_N_) * sizeof(_CTYPE_)); \ R_CheckStack(); \ memset(_VAR_, 0, (size_t) (_N_) * sizeof(_CTYPE_)); \ } \ } while (0) #define Matrix_Free(_VAR_, _N_) \ do { \ if (_N_ >= Matrix_CallocThreshold) \ R_Free(_VAR_); \ } while (0) /* Copy and paste from now-deprecated Rdefines.h : */ #ifndef R_DEFINES_H # define GET_SLOT(x, what) R_do_slot(x, what) # define SET_SLOT(x, what, value) R_do_slot_assign(x, what, value) #endif /* Often used symbols, defined in ./init.c */ extern #include "Syms.h" /* Often used numbers, defined in ./init.c */ extern Rcomplex Matrix_zzero, Matrix_zone, Matrix_zna; /* 0+0i, 1+0i, NA+NAi */ #define MINOF(x, y) ((x < y) ? x : y) #define MAXOF(x, y) ((x < y) ? y : x) #define FIRSTOF(x, y) (x) #define SECONDOF(x, y) (y) #define ISNA_PATTERN(_X_) (0) #define ISNA_LOGICAL(_X_) ((_X_) == NA_LOGICAL) #define ISNA_INTEGER(_X_) ((_X_) == NA_INTEGER) #define ISNA_REAL(_X_) (ISNAN(_X_)) #define ISNA_COMPLEX(_X_) (ISNAN((_X_).r) || ISNAN((_X_).i)) #define ISNZ_PATTERN(_X_) ((_X_) != 0) #define ISNZ_LOGICAL(_X_) ((_X_) != 0) #define ISNZ_INTEGER(_X_) ((_X_) != 0) #define ISNZ_REAL(_X_) ((_X_) != 0.0) #define ISNZ_COMPLEX(_X_) ((_X_).r != 0.0 || (_X_).i != 0.0) #define STRICTLY_ISNZ_PATTERN(_X_) \ ( ISNZ_PATTERN(_X_)) #define STRICTLY_ISNZ_LOGICAL(_X_) \ (!ISNA_LOGICAL(_X_) && ISNZ_LOGICAL(_X_)) #define STRICTLY_ISNZ_INTEGER(_X_) \ (!ISNA_INTEGER(_X_) && ISNZ_INTEGER(_X_)) #define STRICTLY_ISNZ_REAL(_X_) \ (!ISNA_REAL( _X_) && ISNZ_REAL( _X_)) #define STRICTLY_ISNZ_COMPLEX(_X_) \ (!ISNA_COMPLEX(_X_) && ISNZ_COMPLEX(_X_)) #define NOTREAL_PATTERN(_X_) 0 #define NOTREAL_LOGICAL(_X_) 0 #define NOTREAL_INTEGER(_X_) 0 #define NOTREAL_REAL(_X_) 0 #define NOTREAL_COMPLEX(_X_) (_X_.i != 0.0) #define NOTCONJ_PATTERN(_X_, _Y_) \ ((_X_ != 0) != (_Y_ != 0)) #define NOTCONJ_LOGICAL(_X_, _Y_) \ (_X_ != _Y_) #define NOTCONJ_INTEGER(_X_, _Y_) \ (_X_ != _Y_) #define NOTCONJ_REAL(_X_, _Y_) \ ((ISNAN(_X_)) ? !ISNAN(_Y_) : ISNAN(_Y_) || _X_ != _Y_) #define NOTCONJ_COMPLEX(_X_, _Y_) \ (((ISNAN(_X_.r)) ? !ISNAN(_Y_.r) : ISNAN(_Y_.r) || _X_.r != _Y_.r) || \ ((ISNAN(_X_.i)) ? !ISNAN(_Y_.i) : ISNAN(_Y_.i) || _X_.r != -_Y_.r)) #define INCREMENT_PATTERN(_X_, _Y_) \ do { \ _X_ = 1; \ } while (0) #define INCREMENT_LOGICAL(_X_, _Y_) \ do { \ if (_Y_ == NA_LOGICAL) { \ if (_X_ == 0) \ _X_ = NA_LOGICAL; \ } else if (_Y_ != 0) \ _X_ = 1; \ } while (0) #define INCREMENT_INTEGER(_X_, _Y_) \ do { \ if (_X_ != NA_INTEGER) { \ if (_Y_ == NA_INTEGER) \ _X_ = NA_INTEGER; \ else if ((_Y_ < 0) \ ? (_X_ <= INT_MIN - _Y_) \ : (_X_ > INT_MAX - _Y_)) { \ warning(_("NAs produced by integer overflow")); \ _X_ = NA_INTEGER; \ } else \ _X_ += _Y_; \ } \ } while (0) #define INCREMENT_REAL(_X_, _Y_) \ do { \ _X_ += _Y_; \ } while (0) #define INCREMENT_COMPLEX(_X_, _Y_) \ do { \ _X_.r += _Y_.r; \ _X_.i += _Y_.i; \ } while (0) #define ASSIGN_REAL(_X_, _Y_) \ do { _X_ = _Y_ ; } while (0) #define ASSIGN_COMPLEX(_X_, _Y_) \ do { _X_.r = _Y_.r; _X_.i = _Y_.i; } while (0) #define SCALE1_REAL(_X_, _A_) \ do { _X_ *= _A_; } while (0) #define SCALE1_COMPLEX(_X_, _A_) \ do { _X_.r *= _A_; _X_.i *= _A_; } while (0) #define SCALE2_REAL(_X_, _A_) \ do { _X_ /= _A_; } while (0) #define SCALE2_COMPLEX(_X_, _A_) \ do { _X_.r /= _A_; _X_.i /= _A_; } while (0) #define PACKED_AR21_UP(i, j) \ ((R_xlen_t) ((i) + ((Matrix_int_fast64_t) (j) * ( (j) + 1)) / 2)) #define PACKED_AR21_LO(i, j, m2) \ ((R_xlen_t) ((i) + ((Matrix_int_fast64_t) (j) * ((m2) - (j) - 1)) / 2)) #define PACKED_LENGTH(m) \ ((R_xlen_t) ((m) + ((Matrix_int_fast64_t) (m) * ( (m) - 1)) / 2)) #define SHOW(...) __VA_ARGS__ #define HIDE(...) #define ERROR_INVALID_TYPE(_X_, _FUNC_) \ error(_("invalid type \"%s\" in '%s'"), \ type2char(TYPEOF(_X_)), _FUNC_) #define ERROR_INVALID_CLASS(_X_, _FUNC_) \ do { \ if (!OBJECT(_X_)) \ ERROR_INVALID_TYPE(_X_, _FUNC_); \ else { \ SEXP class = PROTECT(getAttrib(_X_, R_ClassSymbol)); \ error(_("invalid class \"%s\" in '%s'"), \ CHAR(STRING_ELT(class, 0)), _FUNC_); \ UNPROTECT(1); \ } \ } while (0) #define VALID_NONVIRTUAL_MATRIX \ /* 0 */ "dpoMatrix", "dppMatrix", \ /* 2 */ "corMatrix", "pcorMatrix", \ /* 4 */ "pMatrix", "indMatrix", \ /* 6 */ "ngCMatrix", "ngRMatrix", "ngTMatrix", "ngeMatrix", "ndiMatrix", \ /* 11 */ "nsCMatrix", "nsRMatrix", "nsTMatrix", "nsyMatrix", "nspMatrix", \ /* 16 */ "ntCMatrix", "ntRMatrix", "ntTMatrix", "ntrMatrix", "ntpMatrix", \ /* 21 */ "lgCMatrix", "lgRMatrix", "lgTMatrix", "lgeMatrix", "ldiMatrix", \ /* 26 */ "lsCMatrix", "lsRMatrix", "lsTMatrix", "lsyMatrix", "lspMatrix", \ /* 31 */ "ltCMatrix", "ltRMatrix", "ltTMatrix", "ltrMatrix", "ltpMatrix", \ /* 36 */ "igCMatrix", "igRMatrix", "igTMatrix", "igeMatrix", "idiMatrix", \ /* 41 */ "isCMatrix", "isRMatrix", "isTMatrix", "isyMatrix", "ispMatrix", \ /* 46 */ "itCMatrix", "itRMatrix", "itTMatrix", "itrMatrix", "itpMatrix", \ /* 51 */ "dgCMatrix", "dgRMatrix", "dgTMatrix", "dgeMatrix", "ddiMatrix", \ /* 56 */ "dsCMatrix", "dsRMatrix", "dsTMatrix", "dsyMatrix", "dspMatrix", \ /* 61 */ "dtCMatrix", "dtRMatrix", "dtTMatrix", "dtrMatrix", "dtpMatrix", \ /* 66 */ "zgCMatrix", "zgRMatrix", "zgTMatrix", "zgeMatrix", "zdiMatrix", \ /* 71 */ "zsCMatrix", "zsRMatrix", "zsTMatrix", "zsyMatrix", "zspMatrix", \ /* 76 */ "ztCMatrix", "ztRMatrix", "ztTMatrix", "ztrMatrix", "ztpMatrix" #define VALID_NONVIRTUAL_VECTOR \ /* 81 */ "nsparseVector", "lsparseVector", "isparseVector", \ "dsparseVector", "zsparseVector" #define VALID_NONVIRTUAL VALID_NONVIRTUAL_MATRIX, VALID_NONVIRTUAL_VECTOR /* dpoMatrix->dsyMatrix, etc. */ #define VALID_NONVIRTUAL_SHIFT(i, pToInd) \ ((i >= 5) ? 0 : ((i >= 4) ? pToInd != 0 : ((i >= 2) ? 57 : 59))) #define VALID_DENSE \ "ngeMatrix", "nsyMatrix", "nspMatrix", "ntrMatrix", "ntpMatrix", \ "lgeMatrix", "lsyMatrix", "lspMatrix", "ltrMatrix", "ltpMatrix", \ "igeMatrix", "isyMatrix", "ispMatrix", "itrMatrix", "itpMatrix", \ "dgeMatrix", "dsyMatrix", "dspMatrix", "dtrMatrix", "dtpMatrix", \ "zgeMatrix", "zsyMatrix", "zspMatrix", "ztrMatrix", "ztpMatrix" #define VALID_CSPARSE \ "ngCMatrix", "nsCMatrix", "ntCMatrix", \ "lgCMatrix", "lsCMatrix", "ltCMatrix", \ "igCMatrix", "isCMatrix", "itCMatrix", \ "dgCMatrix", "dsCMatrix", "dtCMatrix", \ "zgCMatrix", "zsCMatrix", "ztCMatrix" #define VALID_RSPARSE \ "ngRMatrix", "nsRMatrix", "ntRMatrix", \ "lgRMatrix", "lsRMatrix", "ltRMatrix", \ "igRMatrix", "isRMatrix", "itRMatrix", \ "dgRMatrix", "dsRMatrix", "dtRMatrix", \ "zgRMatrix", "zsRMatrix", "ztRMatrix" #define VALID_TSPARSE \ "ngTMatrix", "nsTMatrix", "ntTMatrix", \ "lgTMatrix", "lsTMatrix", "ltTMatrix", \ "igTMatrix", "isTMatrix", "itTMatrix", \ "dgTMatrix", "dsTMatrix", "dtTMatrix", \ "zgTMatrix", "zsTMatrix", "ztTMatrix" #define VALID_DIAGONAL \ "ndiMatrix", "ldiMatrix", "idiMatrix", "ddiMatrix", "zdiMatrix" /* What we want declared "everywhere" : */ #include "utils.h" SEXP newObject(const char *); void validObject(SEXP, const char *); char typeToKind(SEXPTYPE); SEXPTYPE kindToType(char); size_t kindToSize(char); int DimNames_is_trivial(SEXP); int DimNames_is_symmetric(SEXP); void symDN(SEXP, SEXP, int); void revDN(SEXP, SEXP); SEXP get_symmetrized_DimNames(SEXP, int); SEXP get_reversed_DimNames(SEXP); void set_symmetrized_DimNames(SEXP, SEXP, int); void set_reversed_DimNames(SEXP, SEXP); #endif /* MATRIX_MDEFINES_H */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/utils.c����������������������������������������������������������������������������������0000644�0001762�0000144�00000007676�14504647603�013642� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include /* vsnprintf */ #include "Mdefines.h" #include "utils.h" /* memset() but passing length and size rather than their product which can overflow size_t ... hence _safer_ than Memzero() */ void *Matrix_memset(void *dest, int ch, R_xlen_t length, size_t size) { if (dest && length > 0 && size > 0) { char *dest_ = (char *) dest; size_t N = SIZE_MAX / size; #if (SIZE_MAX < R_XLEN_T_MAX) R_xlen_t S_M = (R_xlen_t) SIZE_MAX; if (length <= S_M) { #endif /* 'length' is representable as size_t : */ size_t n = (size_t) length; if (n <= N) memset(dest_, ch, n * size); else { size_t d = N * size; while (n > N) { memset(dest_, ch, d); dest_ += d; n -= d; } memset(dest_, ch, n * size); } #if (SIZE_MAX < R_XLEN_T_MAX) } else { /* 'length' would overflow size_t : */ size_t n, d = N * size; while (length > S_M) { n = SIZE_MAX; while (n > N) { memset(dest_, ch, d); dest_ += d; n -= d; } memset(dest_, ch, n * size); length -= S_M; } n = (size_t) length; while (n > N) { memset(dest_, ch, d); dest_ += d; n -= d; } memset(dest_, ch, n * size); } #endif } return dest; } /* memcpy() but passing length and size rather than their product which can overflow size_t ... hence _safer_ than Memcpy() */ void *Matrix_memcpy(void *dest, const void *src, R_xlen_t length, size_t size) { if (dest && src && length > 0 && size > 0) { char *dest_ = (char *) dest; const char *src_ = (const char *) src; size_t N = SIZE_MAX / size; #if (SIZE_MAX < R_XLEN_T_MAX) R_xlen_t S_M = (R_xlen_t) SIZE_MAX; if (length <= S_M) { #endif /* 'length' is representable as size_t : */ size_t n = (size_t) length; if (n <= N) memcpy(dest_, src_, n * size); else { size_t d = N * size; while (n > N) { memcpy(dest_, src_, d); dest_ += d; src_ += d; n -= d; } memcpy(dest_, src_, n * size); } #if (SIZE_MAX < R_XLEN_T_MAX) } else { /* 'length' would overflow size_t : */ size_t n, d = N * size; while (length > S_M) { n = SIZE_MAX; while (n > N) { memcpy(dest_, src_, d); dest_ += d; src_ += d; n -= d; } memcpy(dest_, src_, n * size); length -= S_M; } n = (size_t) length; while (n > N) { memcpy(dest_, src_, d); dest_ += d; n -= d; } memcpy(dest_, src_, n * size); } #endif } return dest; } char *Matrix_sprintf(const char *format, ...) { char *buf = R_alloc(Matrix_ErrorBufferSize, sizeof(char)); va_list args; va_start(args, format); vsnprintf(buf, Matrix_ErrorBufferSize, format, args); va_end(args); return buf; } int equal_character_vectors(SEXP s1, SEXP s2, int n) { /* FIXME? not distinguishing between NA_STRING and "NA" */ for (int i = 0; i < n; ++i) if (strcmp(CHAR(STRING_ELT(s1, i)), CHAR(STRING_ELT(s2, i))) != 0) return 0; return 1; } void conjugate(SEXP x) { Rcomplex *px = COMPLEX(x); R_xlen_t nx = XLENGTH(x); while (nx--) { (*px).i = -(*px).i; ++px; } return; } void zeroRe(SEXP x) { Rcomplex *px = COMPLEX(x); R_xlen_t nx = XLENGTH(x); while (nx--) { (*px).r = 0.0; ++px; } return; } void zeroIm(SEXP x) { Rcomplex *px = COMPLEX(x); R_xlen_t nx = XLENGTH(x); while (nx--) { (*px).i = 0.0; ++px; } return; } void naToOne(SEXP x) { R_xlen_t i, n = XLENGTH(x); switch (TYPEOF(x)) { case LGLSXP: { int *px = LOGICAL(x); for (i = 0; i < n; ++i, ++px) if (*px == NA_LOGICAL) *px = 1; break; } case INTSXP: { int *px = INTEGER(x); for (i = 0; i < n; ++i, ++px) if (*px == NA_INTEGER) *px = 1; break; } case REALSXP: { double *px = REAL(x); for (i = 0; i < n; ++i, ++px) if (ISNAN(*px)) *px = 1.0; break; } case CPLXSXP: { Rcomplex *px = COMPLEX(x); for (i = 0; i < n; ++i, ++px) if (ISNAN((*px).r) || ISNAN((*px).i)) *px = Matrix_zone; break; } default: ERROR_INVALID_TYPE(x, __func__); break; } return; } ������������������������������������������������������������������Matrix/src/kappa.c����������������������������������������������������������������������������������0000644�0001762�0000144�00000032554�14511400105�013545� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "Lapack-etc.h" #include "Mdefines.h" #include "kappa.h" static char La_norm_type(SEXP s) { #define ARGNAME "type" if (TYPEOF(s) != STRSXP) error(_("argument '%s' is not of type \"%s\""), ARGNAME, "character"); if (LENGTH(s) == 0) error(_("argument '%s' has length %d"), ARGNAME, 0); const char *type = CHAR(STRING_ELT(s, 0)); if (type[0] == '\0' || type[1] != '\0') error(_("argument '%s' (\"%s\") does not have string length %d"), ARGNAME, type, 1); char t = '\0'; switch (type[0]) { case 'M': case 'm': t = 'M'; break; case 'O': case 'o': case '1': t = 'O'; break; case 'I': case 'i': t = 'I'; break; case 'F': case 'f': case 'E': case 'e': t = 'F'; break; default: error(_("argument '%s' (\"%s\") is not \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", or \"%s\""), ARGNAME, type, "M", "O", "1", "I", "F", "E"); break; } return t; #undef ARGNAME } static char La_rcond_type(SEXP s) { #define ARGNAME "norm" if (TYPEOF(s) != STRSXP) error(_("argument '%s' is not of type \"%s\""), ARGNAME, "character"); if (LENGTH(s) == 0) error(_("argument '%s' has length %d"), ARGNAME, 0); const char *type = CHAR(STRING_ELT(s, 0)); if (type[0] == '\0' || type[1] != '\0') error(_("argument '%s' (\"%s\") does not have string length %d"), ARGNAME, type, 1); char t = '\0'; switch (type[0]) { case 'O': case 'o': case '1': t = 'O'; break; case 'I': case 'i': t = 'I'; break; default: error(_("argument '%s' (\"%s\") is not \"%s\", \"%s\", or \"%s\""), ARGNAME, type, "O", "1", "I"); break; } return t; #undef ARGNAME } SEXP dgeMatrix_norm(SEXP obj, SEXP type) { char t = La_norm_type(type); SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; if (m == 0 || n == 0) return ScalarReal(0.0); SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)); double norm, *work = NULL; if (t == 'I') work = (double *) R_alloc((size_t) m, sizeof(double)); #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(x) == CPLXSXP) norm = F77_CALL(zlange)(&t, &m, &n, COMPLEX(x), &m, work FCONE); else #endif norm = F77_CALL(dlange)(&t, &m, &n, REAL(x), &m, work FCONE); UNPROTECT(1); /* x */ return ScalarReal(norm); } SEXP dsyMatrix_norm(SEXP obj, SEXP type) { char t = La_norm_type(type); SEXP dim = GET_SLOT(obj, Matrix_DimSym); int n = INTEGER(dim)[1]; if (n == 0) return ScalarReal(0.0); SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = *CHAR(STRING_ELT(uplo, 0)); SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)); double norm, *work = NULL; if (t == 'O' || t == 'I') work = (double *) R_alloc((size_t) n, sizeof(double)); #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(x) == CPLXSXP) norm = F77_CALL(zlansy)(&t, &ul, &n, COMPLEX(x), &n, work FCONE FCONE); else #endif norm = F77_CALL(dlansy)(&t, &ul, &n, REAL(x), &n, work FCONE FCONE); UNPROTECT(1); /* x */ return ScalarReal(norm); } SEXP dspMatrix_norm(SEXP obj, SEXP type) { char t = La_norm_type(type); SEXP dim = GET_SLOT(obj, Matrix_DimSym); int n = INTEGER(dim)[1]; if (n == 0) return ScalarReal(0.0); SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = CHAR(STRING_ELT(uplo, 0))[0]; SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)); double norm, *work = NULL; if (t == 'O' || t == 'I') work = (double *) R_alloc((size_t) n, sizeof(double)); #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(x) == CPLXSXP) norm = F77_CALL(zlansp)(&t, &ul, &n, COMPLEX(x), work FCONE FCONE); else #endif norm = F77_CALL(dlansp)(&t, &ul, &n, REAL(x), work FCONE FCONE); UNPROTECT(1); /* x */ return ScalarReal(norm); } SEXP dtrMatrix_norm(SEXP obj, SEXP type) { char t = La_norm_type(type); SEXP dim = GET_SLOT(obj, Matrix_DimSym); int n = INTEGER(dim)[0]; if (n == 0) return ScalarReal(0.0); SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = CHAR(STRING_ELT(uplo, 0))[0]; SEXP diag = GET_SLOT(obj, Matrix_diagSym); char di = CHAR(STRING_ELT(diag, 0))[0]; SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)); double norm, *work = NULL; if (t == 'I') work = (double *) R_alloc((size_t) n, sizeof(double)); #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(x) == CPLXSXP) norm = F77_CALL(zlantr)(&t, &ul, &di, &n, &n, COMPLEX(x), &n, work FCONE FCONE FCONE); else #endif norm = F77_CALL(dlantr)(&t, &ul, &di, &n, &n, REAL(x), &n, work FCONE FCONE FCONE); UNPROTECT(1); /* x */ return ScalarReal(norm); } SEXP dtpMatrix_norm(SEXP obj, SEXP type) { char t = La_norm_type(type); SEXP dim = GET_SLOT(obj, Matrix_DimSym); int n = INTEGER(dim)[0]; if (n == 0) return ScalarReal(0.0); SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = CHAR(STRING_ELT(uplo, 0))[0]; SEXP diag = GET_SLOT(obj, Matrix_diagSym); char di = CHAR(STRING_ELT(diag, 0))[0]; SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)); double norm, *work = NULL; if (t == 'I') work = (double *) R_alloc((size_t) n, sizeof(double)); #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(x) == CPLXSXP) norm = F77_CALL(zlantp)(&t, &ul, &di, &n, COMPLEX(x), work FCONE FCONE FCONE); else #endif norm = F77_CALL(dlantp)(&t, &ul, &di, &n, REAL(x), work FCONE FCONE FCONE); UNPROTECT(1); /* x */ return ScalarReal(norm); } SEXP dgeMatrix_rcond(SEXP obj, SEXP trf, SEXP type) { char t = La_rcond_type(type); SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; if (m != n) error(_("%s(%s) is undefined: '%s' is not square"), "rcond", "x", "x"); if (n == 0) return(ScalarReal(R_PosInf)); SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)), y = PROTECT(GET_SLOT(trf, Matrix_xSym)); double norm, rcond; int info; double * work = (double *) R_alloc((size_t) 4 * n, sizeof(double)); #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(x) == CPLXSXP) { double *rwork = (double *) R_alloc((size_t) 2 * n, sizeof(double)); norm = F77_CALL(zlange)(&t, &n, &n, COMPLEX(x), &n, work FCONE); F77_CALL(zgecon)(&t, &n, COMPLEX(y), &n, &norm, &rcond, (Rcomplex *) work, rwork, &info FCONE); } else { #endif int *iwork = (int *) R_alloc((size_t) n, sizeof(int )); norm = F77_CALL(dlange)(&t, &n, &n, REAL(x), &n, work FCONE); F77_CALL(dgecon)(&t, &n, REAL(y), &n, &norm, &rcond, (double *) work, iwork, &info FCONE); #ifdef MATRIX_ENABLE_ZMATRIX } #endif UNPROTECT(2); /* x, y */ return ScalarReal(rcond); } SEXP dsyMatrix_rcond(SEXP obj, SEXP trf, SEXP type) { char t = La_rcond_type(type); SEXP dim = GET_SLOT(obj, Matrix_DimSym); int n = INTEGER(dim)[0]; if (n == 0) return(ScalarReal(R_PosInf)); SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = CHAR(STRING_ELT(uplo, 0))[0]; SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)), y = PROTECT(GET_SLOT(trf, Matrix_xSym)), pivot = PROTECT(GET_SLOT(trf, Matrix_permSym)); double norm, rcond; int info; #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(x) == CPLXSXP) { double * work = (double *) R_alloc((size_t) 4 * n, sizeof(double)); norm = F77_CALL(zlansy)(&t, &ul, &n, COMPLEX(x), &n, work FCONE FCONE); F77_CALL(zsycon)( &ul, &n, COMPLEX(y), &n, INTEGER(pivot), &norm, &rcond, (Rcomplex *) work, &info FCONE); } else { #endif double * work = (double *) R_alloc((size_t) 2 * n, sizeof(double)); int *iwork = (int *) R_alloc((size_t) n, sizeof(int )); norm = F77_CALL(dlansy)(&t, &ul, &n, REAL(x), &n, work FCONE FCONE); F77_CALL(dsycon)( &ul, &n, REAL(y), &n, INTEGER(pivot), &norm, &rcond, (double *) work, iwork, &info FCONE); #ifdef MATRIX_ENABLE_ZMATRIX } #endif UNPROTECT(3); /* x, y, pivot */ return ScalarReal(rcond); } SEXP dspMatrix_rcond(SEXP obj, SEXP trf, SEXP type) { char t = La_rcond_type(type); SEXP dim = GET_SLOT(obj, Matrix_DimSym); int n = INTEGER(dim)[0]; if (n == 0) return(ScalarReal(R_PosInf)); SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = CHAR(STRING_ELT(uplo, 0))[0]; SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)), y = PROTECT(GET_SLOT(trf, Matrix_xSym)), pivot = PROTECT(GET_SLOT(trf, Matrix_permSym)); double norm, rcond; int info; #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(x) == CPLXSXP) { double * work = (double *) R_alloc((size_t) 4 * n, sizeof(double)); norm = F77_CALL(zlansp)(&t, &ul, &n, COMPLEX(x), work FCONE FCONE); F77_CALL(zspcon)( &ul, &n, COMPLEX(y), INTEGER(pivot), &norm, &rcond, (Rcomplex *) work, &info FCONE); } else { #endif double * work = (double *) R_alloc((size_t) 2 * n, sizeof(double)); int *iwork = (int *) R_alloc((size_t) n, sizeof(int )); norm = F77_CALL(dlansp)(&t, &ul, &n, REAL(x), work FCONE FCONE); F77_CALL(dspcon)( &ul, &n, REAL(y), INTEGER(pivot), &norm, &rcond, (double *) work, iwork, &info FCONE); #ifdef MATRIX_ENABLE_ZMATRIX } #endif UNPROTECT(3); /* x, y, pivot */ return ScalarReal(rcond); } SEXP dpoMatrix_rcond(SEXP obj, SEXP trf, SEXP type) { char t = La_rcond_type(type); SEXP dim = GET_SLOT(obj, Matrix_DimSym); int n = INTEGER(dim)[0]; if (n == 0) return(ScalarReal(R_PosInf)); SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = CHAR(STRING_ELT(uplo, 0))[0]; SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)), y = PROTECT(GET_SLOT(trf, Matrix_xSym)); double norm, rcond; int info; #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(x) == CPLXSXP) { double * work = (double *) R_alloc((size_t) 4 * n, sizeof(double)); double *rwork = (double *) R_alloc((size_t) n, sizeof(double)); norm = F77_CALL(zlansy)(&t, &ul, &n, COMPLEX(x), &n, work FCONE FCONE); F77_CALL(zpocon)( &ul, &n, COMPLEX(y), &n, &norm, &rcond, (Rcomplex *) work, rwork, &info FCONE); } else { #endif double * work = (double *) R_alloc((size_t) 3 * n, sizeof(double)); int *iwork = (int *) R_alloc((size_t) n, sizeof(int )); norm = F77_CALL(dlansy)(&t, &ul, &n, REAL(x), &n, work FCONE FCONE); F77_CALL(dpocon)( &ul, &n, REAL(y), &n, &norm, &rcond, (double *) work, iwork, &info FCONE); #ifdef MATRIX_ENABLE_ZMATRIX } #endif UNPROTECT(2); /* x, y */ return ScalarReal(rcond); } SEXP dppMatrix_rcond(SEXP obj, SEXP trf, SEXP type) { char t = La_rcond_type(type); SEXP dim = GET_SLOT(obj, Matrix_DimSym); int n = INTEGER(dim)[0]; if (n == 0) return(ScalarReal(R_PosInf)); SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = CHAR(STRING_ELT(uplo, 0))[0]; SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)), y = PROTECT(GET_SLOT(trf, Matrix_xSym)); double norm, rcond; int info; #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(x) == CPLXSXP) { double * work = (double *) R_alloc((size_t) 4 * n, sizeof(double)); double *rwork = (double *) R_alloc((size_t) n, sizeof(double)); norm = F77_CALL(zlansp)(&t, &ul, &n, COMPLEX(x), work FCONE FCONE); F77_CALL(zppcon)( &ul, &n, COMPLEX(y), &norm, &rcond, (Rcomplex *) work, rwork, &info FCONE); } else { #endif double * work = (double *) R_alloc((size_t) 3 * n, sizeof(double)); int *iwork = (int *) R_alloc((size_t) n, sizeof(int )); norm = F77_CALL(dlansp)(&t, &ul, &n, REAL(x), work FCONE FCONE); F77_CALL(dppcon)( &ul, &n, REAL(y), &norm, &rcond, (double *) work, iwork, &info FCONE); #ifdef MATRIX_ENABLE_ZMATRIX } #endif UNPROTECT(2); /* x, y */ return ScalarReal(rcond); } SEXP dtrMatrix_rcond(SEXP obj, SEXP type) { char t = La_rcond_type(type); SEXP dim = GET_SLOT(obj, Matrix_DimSym); int n = INTEGER(dim)[0]; if (n == 0) return(ScalarReal(R_PosInf)); SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = CHAR(STRING_ELT(uplo, 0))[0]; SEXP diag = GET_SLOT(obj, Matrix_diagSym); char di = CHAR(STRING_ELT(diag, 0))[0]; SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)); double rcond; int info; #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(x) == CPLXSXP) { double * work = (double *) R_alloc((size_t) 4 * n, sizeof(double)); double *rwork = (double *) R_alloc((size_t) n, sizeof(double)); F77_CALL(ztrcon)(&t, &ul, &di, &n, COMPLEX(x), &n, &rcond, (Rcomplex *) work, rwork, &info FCONE FCONE FCONE); } else { #endif double * work = (double *) R_alloc((size_t) 3 * n, sizeof(double)); int *iwork = (int *) R_alloc((size_t) n, sizeof(int )); F77_CALL(dtrcon)(&t, &ul, &di, &n, REAL(x), &n, &rcond, (double *) work, iwork, &info FCONE FCONE FCONE); #ifdef MATRIX_ENABLE_ZMATRIX } #endif UNPROTECT(1); /* x */ return ScalarReal(rcond); } SEXP dtpMatrix_rcond(SEXP obj, SEXP type) { char t = La_rcond_type(type); SEXP dim = GET_SLOT(obj, Matrix_DimSym); int n = INTEGER(dim)[0]; if (n == 0) return(ScalarReal(R_PosInf)); SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = CHAR(STRING_ELT(uplo, 0))[0]; SEXP diag = GET_SLOT(obj, Matrix_diagSym); char di = CHAR(STRING_ELT(diag, 0))[0]; SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)); double rcond; int info; #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(x) == CPLXSXP) { double * work = (double *) R_alloc((size_t) 4 * n, sizeof(double)); double *rwork = (double *) R_alloc((size_t) n, sizeof(double)); F77_CALL(ztpcon)(&t, &ul, &di, &n, COMPLEX(x), &rcond, (Rcomplex *) work, rwork, &info FCONE FCONE FCONE); } else { #endif double * work = (double *) R_alloc((size_t) 3 * n, sizeof(double)); int *iwork = (int *) R_alloc((size_t) n, sizeof(int )); F77_CALL(dtpcon)(&t, &ul, &di, &n, REAL(x), &rcond, (double *) work, iwork, &info FCONE FCONE FCONE); #ifdef MATRIX_ENABLE_ZMATRIX } #endif UNPROTECT(1); /* x */ return ScalarReal(rcond); } ����������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/bind.c�����������������������������������������������������������������������������������0000644�0001762�0000144�00000056334�14511521056�013400� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "Mdefines.h" #include "coerce.h" #include "bind.h" static const char *valid[] = { VALID_NONVIRTUAL_MATRIX, "" }; static SEXP tagWasVector = NULL; static void scanArgs(SEXP args, SEXP exprs, int margin, int level, int *rdim, int *rdimnames, char *kind, char *repr) { SEXP a, e, s, tmp; int nS4 = 0, nDense = 0, anyCsparse = 0, anyRsparse = 0, anyTsparse = 0, anyDiagonal = 0, anyN = 0, anyL = 0, anyI = 0, anyD = 0, anyZ = 0, i, ivalid, *sdim; R_xlen_t slen; const char *scl; rdim[!margin] = -1; rdim[ margin] = 0; rdimnames[0] = rdimnames[1] = 0; for (a = args; a != R_NilValue; a = CDR(a)) { s = CAR(a); if (s == R_NilValue) continue; if (TYPEOF(s) == S4SXP) { ++nS4; ivalid = R_check_class_etc(s, valid); if (ivalid < 0) { if (margin) ERROR_INVALID_CLASS(s, "cbind.Matrix"); else ERROR_INVALID_CLASS(s, "rbind.Matrix"); } scl = valid[ivalid + VALID_NONVIRTUAL_SHIFT(ivalid, 1)]; tmp = GET_SLOT(s, Matrix_DimSym); sdim = INTEGER(tmp); if (rdim[!margin] < 0) rdim[!margin] = sdim[!margin]; else if (sdim[!margin] != rdim[!margin]) { if (margin) error(_("number of rows of matrices must match")); else error(_("number of columns of matrices must match")); } if (sdim[margin] > INT_MAX - rdim[margin]) error(_("dimensions cannot exceed %s"), "2^31-1"); rdim[margin] += sdim[margin]; if (!rdimnames[0] || !rdimnames[1]) { tmp = GET_SLOT(s, Matrix_DimNamesSym); if (scl[1] == 's') { if (VECTOR_ELT(tmp, 0) != R_NilValue || VECTOR_ELT(tmp, 1) != R_NilValue) rdimnames[0] = rdimnames[1] = 1; } else for (i = 0; i < 2; ++i) if (!rdimnames[i] && VECTOR_ELT(tmp, i) != R_NilValue) rdimnames[i] = 1; } switch (scl[0]) { case 'n': anyN = 1; break; case 'l': anyL = 1; break; case 'i': if (scl[2] != 'd') anyI = 1; break; case 'd': anyD = 1; break; case 'z': anyZ = 1; break; default: break; } switch (scl[2]) { case 'e': case 'y': case 'r': case 'p': ++nDense; break; case 'C': anyCsparse = 1; break; case 'R': anyRsparse = 1; break; case 'T': { /* defined in ./sparse.c : */ SEXP Tsparse_aggregate(SEXP); SETCAR(a, Tsparse_aggregate(s)); anyTsparse = 1; break; } case 'i': anyDiagonal = 1; break; case 'd': if (INTEGER(GET_SLOT(s, Matrix_marginSym))[0] - 1 != margin) { anyN = 1; if (margin) anyCsparse = 1; else anyRsparse = 1; } break; default: break; } } else { switch (TYPEOF(s)) { case LGLSXP: anyL = 1; break; case INTSXP: anyI = 1; break; case REALSXP: anyD = 1; break; case CPLXSXP: anyZ = 1; break; default: if (margin) ERROR_INVALID_TYPE(s, "cbind.Matrix"); else ERROR_INVALID_TYPE(s, "rbind.Matrix"); break; } tmp = getAttrib(s, R_DimSymbol); if (TYPEOF(tmp) == INTSXP && LENGTH(tmp) == 2) { sdim = INTEGER(tmp); if (rdim[!margin] < 0) rdim[!margin] = sdim[!margin]; else if (rdim[!margin] != sdim[!margin]) { if (margin) error(_("number of rows of matrices must match")); else error(_("number of columns of matrices must match")); } if (sdim[margin] > INT_MAX - rdim[margin]) error(_("dimensions cannot exceed %s"), "2^31-1"); rdim[margin] += sdim[margin]; if (!rdimnames[0] || !rdimnames[1]) { tmp = getAttrib(s, R_DimNamesSymbol); if (tmp != R_NilValue) for (i = 0; i < 2; ++i) if (!rdimnames[i] && VECTOR_ELT(tmp, i) != R_NilValue) rdimnames[i] = 1; } } } } if (rdim[!margin] < 0) { /* Arguments are all vectors or NULL */ R_xlen_t maxlen = -1; for (a = args; a != R_NilValue; a = CDR(a)) { s = CAR(a); if (s == R_NilValue) continue; slen = XLENGTH(s); if (slen > INT_MAX) error(_("dimensions cannot exceed %s"), "2^31-1"); else if (slen > maxlen) maxlen = slen; } if (maxlen < 0) /* Arguments are all NULL */ return; rdim[!margin] = (int) maxlen; } for (a = args, e = exprs; a != R_NilValue; a = CDR(a), e = CDR(e)) { s = CAR(a); if ((s == R_NilValue && rdim[!margin] > 0) || TYPEOF(s) == S4SXP) continue; if (s == R_NilValue) rdim[margin] += 1; else { tmp = getAttrib(s, R_DimSymbol); if (TYPEOF(tmp) == INTSXP && LENGTH(tmp) == 2) continue; slen = XLENGTH(s); if (slen == 0 && rdim[!margin] > 0) continue; if (rdim[margin] == INT_MAX) error(_("dimensions cannot exceed %s"), "2^31-1"); rdim[margin] += 1; if (slen > rdim[!margin] || rdim[!margin] % (int) slen) { if (margin) warning(_("number of rows of result is not a multiple of vector length")); else warning(_("number of columns of result is not a multiple of vector length")); } if (!rdimnames[!margin] && slen == rdim[!margin]) { tmp = getAttrib(s, R_NamesSymbol); if (tmp != R_NilValue) rdimnames[!margin] = 1; } } if (!rdimnames[margin]) { if (TAG(a) != R_NilValue || level == 2 || (level == 1 && TYPEOF(CAR(e)) == SYMSXP)) rdimnames[margin] = 1; } } if (anyZ) *kind = 'z'; #ifndef MATRIX_ENABLE_IMATRIX else if (anyD || anyI) *kind = 'd'; #else else if (anyD) *kind = 'd'; else if (anyI) *kind = 'i'; #endif else if (anyL) *kind = 'l'; else if (anyN) *kind = 'n'; else *kind = '\0'; if (nDense == nS4) *repr = 'e'; else if (nDense == 0) { if (anyCsparse && anyRsparse) *repr = (margin) ? 'C' : 'R'; else if (anyCsparse) *repr = 'C'; else if (anyRsparse) *repr = 'R'; else if (anyTsparse) *repr = 'T'; else if (anyDiagonal) *repr = (margin) ? 'C' : 'R'; else *repr = '\0'; } else { /* The length of the result is at most INT_MAX * INT_MAX, which cannot overflow Matrix_int_fast64_t as long as R builds require sizeof(int) equal to 4 */ Matrix_int_fast64_t nnz = 0, len = 0, snnz = 0, slen = 0; for (a = args; a != R_NilValue && nnz < INT_MAX; a = CDR(a)) { s = CAR(a); if (TYPEOF(s) != S4SXP) continue; ivalid = R_check_class_etc(s, valid); scl = valid[ivalid + VALID_NONVIRTUAL_SHIFT(ivalid, 1)]; PROTECT(tmp = GET_SLOT(s, Matrix_DimSym)); sdim = INTEGER(tmp); slen = (Matrix_int_fast64_t) sdim[0] * sdim[1]; switch (scl[2]) { case 'e': case 'y': case 'r': case 'p': snnz = (scl[1] != 't') ? slen : ((slen + sdim[0]) / 2); break; case 'C': case 'R': { SEXP p = PROTECT(GET_SLOT(s, Matrix_pSym)); int *pp = INTEGER(p), n = sdim[(scl[2] == 'C') ? 1 : 0]; snnz = pp[n]; if (scl[1] == 's') { SEXP iSym = (scl[2] == 'C') ? Matrix_iSym : Matrix_jSym, i = PROTECT(GET_SLOT(s, iSym)); int *pi = INTEGER(i), j; snnz *= 2; if (*CHAR(STRING_ELT(GET_SLOT(s, Matrix_uploSym), 0)) == 'U') { for (j = 0; j < n; ++j) if (pp[j] < pp[j + 1] && pi[pp[j + 1] - 1] == j) --snnz; } else { for (j = 0; j < n; ++j) if (pp[j] < pp[j + 1] && pi[pp[j]] == j) --snnz; } UNPROTECT(1); } else if (scl[1] == 't' && *CHAR(STRING_ELT(GET_SLOT(s, Matrix_diagSym), 0)) != 'N') snnz += sdim[0]; UNPROTECT(1); break; } case 'T': { SEXP i = PROTECT(GET_SLOT(s, Matrix_iSym)); snnz = XLENGTH(i); if (scl[1] == 's') { SEXP j = PROTECT(GET_SLOT(s, Matrix_jSym)); int *pi = INTEGER(i), *pj = INTEGER(j); R_xlen_t k = XLENGTH(i); snnz *= 2; while (k--) if (*(pi++) == *(pj++)) --snnz; UNPROTECT(1); } else if (scl[1] == 't' && *CHAR(STRING_ELT(GET_SLOT(s, Matrix_diagSym), 0)) != 'N') snnz += sdim[0]; UNPROTECT(1); break; } case 'i': snnz = sdim[0]; break; case 'd': snnz = XLENGTH(GET_SLOT(s, Matrix_permSym)); break; default: break; } nnz += snnz; len += slen; UNPROTECT(1); } if (nnz > INT_MAX || nnz > len / 2) *repr = 'e'; else if (anyCsparse && anyRsparse) *repr = (margin) ? 'C' : 'R'; else if (anyCsparse) *repr = 'C'; else if (anyRsparse) *repr = 'R'; else if (anyTsparse) *repr = 'T'; else *repr = (margin) ? 'C' : 'R'; } return; } static void coerceArgs(SEXP args, int margin, int *rdim, char kind, char repr) { SEXP a, s, t, tmp; int ivalid, isM; char scl_[] = "...Matrix"; const char *scl; for (a = args; a != R_NilValue; a = CDR(a)) { s = CAR(a); t = TAG(a); SET_TAG(a, R_NilValue); /* to be replaced only if 's' is a vector */ if (s == R_NilValue) continue; PROTECT_INDEX pid; PROTECT_WITH_INDEX(s, &pid); if (TYPEOF(s) == S4SXP) { ivalid = R_check_class_etc(s, valid); scl = valid[ivalid + VALID_NONVIRTUAL_SHIFT(ivalid, 1)]; switch (scl[2]) { case 'e': case 'y': case 'r': case 'p': switch (repr) { case 'e': REPROTECT(s = dense_as_kind(s, scl, kind, 0), pid); scl_[0] = kind; scl_[1] = scl[1]; scl_[2] = scl[2]; REPROTECT(s = dense_as_general( s, scl_, kindToType(kind) == kindToType(scl[0])), pid); break; case 'C': case 'R': case 'T': REPROTECT(s = dense_as_sparse(s, scl, repr), pid); scl_[0] = scl[0]; scl_[1] = scl[1]; scl_[2] = repr; REPROTECT(s = sparse_as_kind(s, scl_, kind), pid); scl_[0] = kind; REPROTECT(s = sparse_as_general(s, scl_), pid); break; default: break; } break; case 'C': case 'R': case 'T': REPROTECT(s = sparse_as_kind(s, scl, kind), pid); scl_[0] = kind; scl_[1] = scl[1]; scl_[2] = scl[2]; REPROTECT(s = sparse_as_general(s, scl_), pid); scl_[1] = 'g'; switch (repr) { case 'e': REPROTECT(s = sparse_as_dense(s, scl_, 0), pid); break; case 'C': REPROTECT(s = sparse_as_Csparse(s, scl_), pid); break; case 'R': REPROTECT(s = sparse_as_Rsparse(s, scl_), pid); break; case 'T': REPROTECT(s = sparse_as_Tsparse(s, scl_), pid); break; default: break; } break; case 'i': switch (repr) { case 'e': REPROTECT(s = diagonal_as_dense(s, scl_, kind, 'g', 0, '\0'), pid); break; case 'C': case 'R': case 'T': REPROTECT(s = diagonal_as_sparse(s, scl_, kind, 'g', repr, '\0'), pid); break; default: break; } break; case 'd': switch (repr) { case 'e': REPROTECT(s = index_as_dense(s, scl, kind), pid); break; case 'C': case 'R': case 'T': REPROTECT(s = index_as_sparse(s, scl, kind, repr), pid); break; default: break; } break; default: break; } } else { tmp = getAttrib(s, R_DimSymbol); isM = TYPEOF(tmp) == INTSXP && LENGTH(tmp) == 2; if (!isM) { if (rdim[!margin] > 0 && XLENGTH(s) == 0) { UNPROTECT(1); continue; } SET_TAG(a, (t != R_NilValue) ? t : tagWasVector); } if (TYPEOF(s) != kindToType(kind)) REPROTECT(s = coerceVector(s, kindToType(kind)), pid); if (repr != 'e') { if (!isM && XLENGTH(s) != rdim[!margin]) { static SEXP replen = NULL; if (!replen) replen = install("rep_len"); SEXP lengthout = PROTECT(ScalarInteger(rdim[!margin])), call = PROTECT(lang3(replen, s, lengthout)); REPROTECT(s = eval(call, R_GlobalEnv), pid); UNPROTECT(2); } scl_[1] = 'g'; scl_[2] = repr; REPROTECT(s = matrix_as_sparse(s, scl_, '\0', '\0', !margin), pid); } } SETCAR(a, s); UNPROTECT(1); } return; } static void bindArgs(SEXP args, int margin, SEXP res, int *rdim, char kind, char repr) { SEXP a, s; #define BIND_CASES(_BIND_) \ do { \ switch (kind) { \ case 'l': \ _BIND_(int, LOGICAL, SHOW); \ break; \ case 'i': \ _BIND_(int, INTEGER, SHOW); \ break; \ case 'd': \ _BIND_(double, REAL, SHOW); \ break; \ case 'z': \ _BIND_(Rcomplex, COMPLEX, SHOW); \ break; \ default: \ break; \ } \ } while (0) if (repr == 'e') { if (rdim[0] == 0 || rdim[1] == 0) return; int k, m = rdim[0], n = rdim[1]; R_xlen_t mn = (R_xlen_t) m * n; SEXP x = PROTECT(allocVector(kindToType(kind), mn)), tmp; SET_SLOT(res, Matrix_xSym, x); #define BIND_E(_CTYPE_, _PTR_, _MASK_) \ do { \ _CTYPE_ *px = _PTR_(x), *ps; \ for (a = args; a != R_NilValue; a = CDR(a)) { \ s = CAR(a); \ if (s == R_NilValue) \ continue; \ if (TYPEOF(s) != S4SXP) \ tmp = getAttrib(s, R_DimSymbol); \ else { \ s = GET_SLOT(s, Matrix_xSym); \ tmp = NULL; \ } \ mn = XLENGTH(s); \ ps = _PTR_(s); \ if (margin) { \ if (!tmp || (TYPEOF(tmp) == INTSXP && LENGTH(tmp) == 2)) { \ Matrix_memcpy(px, ps, mn, sizeof(_CTYPE_)); \ px += mn; \ } else if (mn >= m) { \ Matrix_memcpy(px, ps, m , sizeof(_CTYPE_)); \ px += m; \ } else if (mn == 1) { \ _CTYPE_ v = ps[0]; \ for (k = 0; k < m; ++k) \ *(px++) = v; \ } else { \ int mn_ = (int) mn; \ for (k = 0; k < rdim[0]; ++k) \ *(px++) = ps[k % mn_]; \ } \ } else { \ _CTYPE_ *py = px; \ if (!tmp || (TYPEOF(tmp) == INTSXP && LENGTH(tmp) == 2)) { \ m = (int) (mn / n); \ for (k = 0; k < n; ++k) { \ Matrix_memcpy(py, ps, m, sizeof(_CTYPE_)); \ py += rdim[0]; \ ps += m; \ } \ px += m; \ } else if (mn >= n) { \ for (k = 0; k < n; ++k) { \ *py = *ps; \ py += rdim[0]; \ ps += 1; \ } \ px += 1; \ } else if (mn == 1) { \ _CTYPE_ v = ps[0]; \ for (k = 0; k < n; ++k) { \ *py = v; \ py += rdim[0]; \ } \ px += 1; \ } else { \ int mn_ = (int) mn; \ for (k = 0; k < n; ++k) { \ *py = ps[k % mn_]; \ py += rdim[0]; \ } \ px += 1; \ } \ } \ } \ } while (0) if (kind == 'n') BIND_E(int, LOGICAL, SHOW); else BIND_CASES(BIND_E); UNPROTECT(1); } else if ((repr == 'C' && margin) || (repr == 'R' && !margin)) { SEXP p = PROTECT(allocVector(INTSXP, (R_xlen_t) rdim[margin] + 1)); int *pp = INTEGER(p); SET_SLOT(res, Matrix_pSym, p); if (rdim[0] == 0 || rdim[1] == 0) { Matrix_memset(pp, 0, (R_xlen_t) rdim[margin] + 1, sizeof(int)); UNPROTECT(1); return; } SEXP sp; int *psp, j, n, nnz = 0; *(pp++) = nnz = 0; for (a = args; a != R_NilValue; a = CDR(a)) { s = CAR(a); if (s == R_NilValue) continue; sp = GET_SLOT(s, Matrix_pSym); psp = INTEGER(sp); n = (int) (XLENGTH(sp) - 1); if (psp[n] > INT_MAX - nnz) error(_("%s cannot exceed %s"), "p[length(p)]", "2^31-1"); for (j = 0; j < n; ++j) *(pp++) = nnz = nnz + (psp[j + 1] - psp[j]); } SEXP i = PROTECT(allocVector(INTSXP, nnz)), si, iSym = (repr == 'C') ? Matrix_iSym : Matrix_jSym; int *pi = INTEGER(i), *psi; SET_SLOT(res, iSym, i); #define BIND_C1R0(_CTYPE_, _PTR_, _MASK_) \ do { \ _MASK_(_CTYPE_ *px = _PTR_(x), *psx); \ for (a = args; a != R_NilValue; a = CDR(a)) { \ s = CAR(a); \ if (s == R_NilValue) \ continue; \ PROTECT(sp = GET_SLOT(s, Matrix_pSym)); \ PROTECT(si = GET_SLOT(s, iSym)); \ _MASK_(PROTECT(sx = GET_SLOT(s, Matrix_xSym))); \ psp = INTEGER(sp); \ psi = INTEGER(si); \ _MASK_(psx = _PTR_(sx)); \ n = (int) (XLENGTH(sp) - 1); \ Matrix_memcpy(pi, psi, psp[n], sizeof(int)); \ _MASK_(Matrix_memcpy(px, psx, psp[n], sizeof(_CTYPE_))); \ pi += psp[n]; \ _MASK_(px += psp[n]); \ _MASK_(UNPROTECT(1)); \ UNPROTECT(2); \ } \ } while (0) if (kind == 'n') BIND_C1R0(int, LOGICAL, HIDE); else { SEXP x = PROTECT(allocVector(kindToType(kind), nnz)), sx; SET_SLOT(res, Matrix_xSym, x); BIND_CASES(BIND_C1R0); UNPROTECT(1); } UNPROTECT(2); } else if ((repr == 'C' && !margin) || (repr == 'R' && margin)) { SEXP p = PROTECT(allocVector(INTSXP, (R_xlen_t) rdim[!margin] + 1)); int *pp = INTEGER(p); SET_SLOT(res, Matrix_pSym, p); Matrix_memset(pp, 0, (R_xlen_t) rdim[!margin] + 1, sizeof(int)); if (rdim[0] == 0 || rdim[1] == 0) { UNPROTECT(1); return; } SEXP sp; int *psp, j, n = rdim[!margin]; ++pp; for (a = args; a != R_NilValue; a = CDR(a)) { s = CAR(a); if (s == R_NilValue) continue; sp = GET_SLOT(s, Matrix_pSym); psp = INTEGER(sp) + 1; if (n > 0 && psp[n - 1] > INT_MAX - pp[n - 1]) error(_("%s cannot exceed %s"), "p[length(p)]", "2^31-1"); for (j = 0; j < n; ++j) pp[j] += psp[j]; } --pp; int nnz = pp[n]; SEXP i = PROTECT(allocVector(INTSXP, nnz)), si, iSym = (repr == 'C') ? Matrix_iSym : Matrix_jSym; int *pi = INTEGER(i), *psi, *work, k, kend, pos = 0; SET_SLOT(res, iSym, i); Matrix_Calloc(work, n, int); Matrix_memcpy(work, pp, n, sizeof(int)); #define BIND_C0R1(_CTYPE_, _PTR_, _MASK_) \ do { \ _MASK_(_CTYPE_ *px = _PTR_(x), *psx); \ for (a = args; a != R_NilValue; a = CDR(a)) { \ s = CAR(a); \ if (s == R_NilValue) \ continue; \ PROTECT(sp = GET_SLOT(s, Matrix_pSym)); \ PROTECT(si = GET_SLOT(s, iSym)); \ _MASK_(PROTECT(sx = GET_SLOT(s, Matrix_xSym))); \ psp = INTEGER(sp); \ psi = INTEGER(si); \ _MASK_(psx = _PTR_(sx)); \ for (j = 0, k = 0; j < n; ++j) { \ kend = psp[j + 1]; \ while (k < kend) { \ pi[work[j]] = *(psi++) + pos; \ _MASK_(px[work[j]] = *(psx++)); \ work[j]++; \ ++k; \ } \ } \ _MASK_(UNPROTECT(1)); \ UNPROTECT(2); \ pos += INTEGER(GET_SLOT(s, Matrix_DimSym))[margin]; \ } \ } while (0) if (kind == 'n') BIND_C0R1(int, LOGICAL, HIDE); else { SEXP x = PROTECT(allocVector(kindToType(kind), nnz)), sx; SET_SLOT(res, Matrix_xSym, x); BIND_CASES(BIND_C0R1); UNPROTECT(1); } UNPROTECT(2); Matrix_Free(work, n); } else if (repr == 'T') { if (rdim[0] == 0 || rdim[1] == 0) return; R_xlen_t k, nnz = 0; for (a = args; a != R_NilValue; a = CDR(a)) { s = CAR(a); if (s == R_NilValue) continue; k = XLENGTH(GET_SLOT(s, Matrix_iSym)); if (k > R_XLEN_T_MAX - nnz) error(_("attempt to allocate vector of length exceeding %s"), "R_XLEN_T_MAX"); nnz += k; } SEXP si, sj, i = PROTECT(allocVector(INTSXP, nnz)), j = PROTECT(allocVector(INTSXP, nnz)); int *psi, *psj, *pi = INTEGER(i), *pj = INTEGER(j), pos = 0; SET_SLOT(res, Matrix_iSym, i); SET_SLOT(res, Matrix_jSym, j); #define BIND_T(_CTYPE_, _PTR_, _MASK_) \ do { \ _MASK_(_CTYPE_ *px = _PTR_(x), *psx); \ for (a = args; a != R_NilValue; a = CDR(a)) { \ s = CAR(a); \ if (s == R_NilValue) \ continue; \ PROTECT(si = GET_SLOT(s, Matrix_iSym)); \ PROTECT(sj = GET_SLOT(s, Matrix_jSym)); \ _MASK_(PROTECT(sx = GET_SLOT(s, Matrix_xSym))); \ psi = INTEGER(si); \ psj = INTEGER(sj); \ _MASK_(psx = _PTR_(sx)); \ k = XLENGTH(si); \ if (margin) { \ while (k--) { \ *(pi++) = *(psi++); \ *(pj++) = *(psj++) + pos; \ _MASK_(*(px++) = *(psx++)); \ } \ } else { \ while (k--) { \ *(pi++) = *(psi++) + pos; \ *(pj++) = *(psj++); \ _MASK_(*(px++) = *(psx++)); \ } \ } \ _MASK_(UNPROTECT(1)); \ UNPROTECT(2); \ pos += INTEGER(GET_SLOT(s, Matrix_DimSym))[margin]; \ } \ } while (0) if (kind == 'n') BIND_T(int, LOGICAL, HIDE); else { SEXP x = PROTECT(allocVector(kindToType(kind), nnz)), sx; SET_SLOT(res, Matrix_xSym, x); BIND_CASES(BIND_T); UNPROTECT(1); } UNPROTECT(2); } else { SEXP p = PROTECT(allocVector(INTSXP, rdim[margin])), sp; int *pp = INTEGER(p); for (a = args; a != R_NilValue; a = CDR(a)) { s = CAR(a); if (s == R_NilValue) continue; sp = GET_SLOT(s, Matrix_permSym); Matrix_memcpy(pp, INTEGER(sp), LENGTH(sp), sizeof(int)); pp += LENGTH(sp); } SET_SLOT(res, Matrix_permSym, p); UNPROTECT(1); if (margin) INTEGER(GET_SLOT(res, Matrix_marginSym))[0] = 2; } #undef BIND_CASES #undef BIND_E #undef BIND_C1R0 #undef BIND_C0R1 #undef BIND_T return; } static SEXP bind(SEXP args, SEXP exprs, int margin, int level) { if (!tagWasVector) tagWasVector = install(".__WAS_VECTOR__."); /* for now, a hack */ int rdim[2], rdimnames[2]; char kind = '\0', repr = '\0'; scanArgs(args, exprs, margin, level, rdim, rdimnames, &kind, &repr); if (rdim[!margin] < 0) /* Arguments are all NULL */ return R_NilValue; if (repr == 'e' && (Matrix_int_fast64_t) rdim[0] * rdim[1] > R_XLEN_T_MAX) error(_("attempt to allocate vector of length exceeding %s"), "R_XLEN_T_MAX"); char rcl[] = "...Matrix"; if (kind == '\0' || repr == '\0') { if (kind != repr) error(_("should never happen ...")); rcl[0] = 'i'; rcl[1] = 'n'; rcl[2] = 'd'; } else { rcl[0] = kind; rcl[1] = 'g'; rcl[2] = repr; coerceArgs(args, margin, rdim, kind, repr); } SEXP res = PROTECT(newObject(rcl)); bindArgs(args, margin, res, rdim, kind, repr); SEXP dim = PROTECT(GET_SLOT(res, Matrix_DimSym)); INTEGER(dim)[0] = rdim[0]; INTEGER(dim)[1] = rdim[1]; UNPROTECT(1); if (rdimnames[0] || rdimnames[1]) { SEXP dimnames = PROTECT(GET_SLOT(res, Matrix_DimNamesSym)), marnames = R_NilValue, nms[2], nms_, a, e, s, tmp; int i, ivalid, r = -1, pos = 0, nprotect = 1; const char *scl; if (rdimnames[margin]) { PROTECT(marnames = allocVector(STRSXP, rdim[margin])); ++nprotect; SET_VECTOR_ELT(dimnames, margin, marnames); } for (a = args, e = exprs; a != R_NilValue; a = CDR(a), e = CDR(e)) { s = CAR(a); if (s == R_NilValue && rdim[!margin] > 0) continue; nms[0] = nms[1] = R_NilValue; if (TYPEOF(s) == S4SXP) { ivalid = R_check_class_etc(s, valid); scl = valid[ivalid + VALID_NONVIRTUAL_SHIFT(ivalid, 1)]; tmp = GET_SLOT(s, Matrix_DimSym); r = INTEGER(tmp)[margin]; tmp = GET_SLOT(s, Matrix_DimNamesSym); if (scl[1] == 's') { if ((nms_ = VECTOR_ELT(tmp, 1)) != R_NilValue || (nms_ = VECTOR_ELT(tmp, 0)) != R_NilValue) nms[0] = nms[1] = nms_; } else for (i = 0; i < 2; ++i) nms[i] = VECTOR_ELT(tmp, i); } else { tmp = getAttrib(s, R_DimSymbol); if (TYPEOF(tmp) == INTSXP && LENGTH(tmp) == 2) { r = INTEGER(tmp)[margin]; tmp = getAttrib(s, R_DimNamesSymbol); if (tmp != R_NilValue) for (i = 0; i < 2; ++i) nms[i] = VECTOR_ELT(tmp, i); } else if (rdim[!margin] == 0 || XLENGTH(s) > 0) { r = 1; if (rdim[!margin] > 0 && XLENGTH(s) == rdim[!margin]) nms[!margin] = getAttrib(s, R_NamesSymbol); } } if (TAG(a) != R_NilValue) { /* only if 's' is or was a vector */ if (TAG(a) != tagWasVector) nms[margin] = coerceVector(TAG(a), STRSXP); else if (level == 2) { PROTECT(nms_ = allocVector(EXPRSXP, 1)); SET_VECTOR_ELT(nms_, 0, CAR(e)); nms[margin] = coerceVector(nms_, STRSXP); UNPROTECT(1); } else if (level == 1 && TYPEOF(CAR(e)) == SYMSXP) nms[margin] = coerceVector(CAR(e), STRSXP); } if (rdimnames[!margin] && nms[!margin] != R_NilValue) { SET_VECTOR_ELT(dimnames, !margin, nms[!margin]); rdimnames[!margin] = 0; if (!rdimnames[margin]) break; } if (rdimnames[ margin] && nms[ margin] != R_NilValue) for (i = 0; i < r; ++i) SET_STRING_ELT(marnames, pos + i, STRING_ELT(nms[margin], i)); pos += r; } UNPROTECT(nprotect); } UNPROTECT(1); return res; } SEXP R_bind(SEXP args) { SEXP level, margin, exprs; args = CDR(args); level = CAR(args); args = CDR(args); margin = CAR(args); args = CDR(args); exprs = CAR(args); return bind(CDR(args), CDR(exprs), asInteger(margin), asInteger(level)); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/coerce.c���������������������������������������������������������������������������������0000644�0001762�0000144�00000341361�14515650276�013734� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include /* trunc */ #include "Mdefines.h" #include "idz.h" #include "coerce.h" SEXP vector_as_dense(SEXP from, const char *zzz, char ul, char di, int m, int n, int byrow, SEXP dimnames) { SEXPTYPE tf = TYPEOF(from); char cl[] = "...Matrix"; cl[0] = (zzz[0] == '.') ? typeToKind(tf) : ((zzz[0] == ',') ? ((tf == CPLXSXP) ? 'z' : 'd') : zzz[0]); cl[1] = zzz[1]; cl[2] = zzz[2]; #ifndef MATRIX_ENABLE_IMATRIX if (cl[0] == 'i') cl[0] = 'd'; #endif SEXPTYPE tt = kindToType(cl[0]); PROTECT(from = coerceVector(from, tt)); if (cl[1] != 'g' && m != n) error(_("attempt to construct non-square %s"), (cl[1] == 's') ? "symmetricMatrix" : "triangularMatrix"); Matrix_int_fast64_t mn = (Matrix_int_fast64_t) m * n; if (((cl[2] != 'p') ? mn : (mn + n) / 2) > R_XLEN_T_MAX) error(_("attempt to allocate vector of length exceeding %s"), "R_XLEN_T_MAX"); SEXP to = PROTECT(newObject(cl)); SEXP dim = GET_SLOT(to, Matrix_DimSym); int *pdim = INTEGER(dim); pdim[0] = m; pdim[1] = n; if (cl[1] != 's') SET_SLOT(to, Matrix_DimNamesSym, dimnames); else set_symmetrized_DimNames(to, dimnames, -1); if (cl[1] != 'g' && ul != 'U') { SEXP uplo = PROTECT(mkString("L")); SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); } if (cl[1] == 't' && di != 'N') { SEXP diag = PROTECT(mkString("U")); SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); } /* FIXME: add argument 'new' and conditionally avoid allocation */ SEXP x = PROTECT(allocVector(tt, (cl[2] != 'p') ? mn : (mn + n) / 2)); R_xlen_t k, r = XLENGTH(from); int i, j, recycle = r < mn; #define VAD_SUBCASES(_PREFIX_, _CTYPE_, _PTR_, _NA_) \ do { \ _CTYPE_ *dest = _PTR_(x), *src = _PTR_(from); \ if (r == 0) { \ while (mn-- > 0) \ *(dest++) = _NA_; \ } else if (r == 1) { \ while (mn-- > 0) \ *(dest++) = *src; \ } else if (cl[2] != 'p') { \ if (!recycle) { \ if (!byrow) \ Matrix_memcpy(dest, src, mn, sizeof(_CTYPE_)); \ else \ _PREFIX_ ## transpose2(dest, src, n, m); \ } else { \ if (!byrow) { \ k = 0; \ while (mn-- > 0) { \ if (k == r) k = 0; \ *(dest++) = src[k++]; \ } \ } else { \ for (j = 0; j < n; ++j) { \ k = j; \ for (i = 0; i < m; ++i) { \ k %= r; \ *(dest++) = src[k]; \ k += n; \ } \ } \ } \ } \ } else if (ul == 'U') { \ if (!byrow) { \ k = 0; \ for (j = 0; j < n; ++j) { \ for (i = 0; i <= j; ++i) { \ if (recycle) k %= r; \ *(dest++) = src[k++]; \ } \ k += n - j - 1; \ } \ } else { \ for (j = 0; j < n; ++j) { \ k = j; \ for (i = 0; i <= j; ++i) { \ if (recycle) k %= r; \ *(dest++) = src[k]; \ k += n; \ } \ } \ } \ } else { \ if (!byrow) { \ k = 0; \ for (j = 0; j < n; ++j) { \ for (i = j; i < n; ++i) { \ if (recycle) k %= r; \ *(dest++) = src[k++]; \ } \ k += j + 1; \ } \ } else { \ R_xlen_t d = 0; \ for (j = 0; j < n; ++j) { \ k = j + d; \ for (i = 0; i <= j; ++i) { \ if (recycle) k %= r; \ *(dest++) = src[k]; \ k += n; \ } \ d += n; \ } \ } \ } \ } while (0) switch (tt) { case LGLSXP: VAD_SUBCASES(i, int, LOGICAL, NA_LOGICAL); break; case INTSXP: VAD_SUBCASES(i, int, INTEGER, NA_INTEGER); break; case REALSXP: VAD_SUBCASES(d, double, REAL, NA_REAL); break; case CPLXSXP: VAD_SUBCASES(z, Rcomplex, COMPLEX, Matrix_zna); break; default: break; } #undef VAD_SUBCASES SET_SLOT(to, Matrix_xSym, x); UNPROTECT(3); return to; } SEXP R_vector_as_dense(SEXP from, SEXP zzz, SEXP uplo, SEXP diag, SEXP m, SEXP n, SEXP byrow, SEXP dimnames) { switch (TYPEOF(from)) { case LGLSXP: case INTSXP: case REALSXP: case CPLXSXP: break; default: ERROR_INVALID_TYPE(from, __func__); break; } const char *zzz_; if (TYPEOF(zzz) != STRSXP || LENGTH(zzz) < 1 || (zzz = STRING_ELT(zzz, 0)) == NA_STRING || (zzz_ = CHAR(zzz))[0] == '\0' || (zzz_ )[1] == '\0' || !((zzz_[1] == 'g' && (zzz_[2] == 'e' )) || (zzz_[1] == 's' && (zzz_[2] == 'y' || zzz_[2] == 'p')) || (zzz_[1] == 't' && (zzz_[2] == 'r' || zzz_[2] == 'p')))) error(_("second argument of '%s' does not specify a subclass of %s"), __func__, "denseMatrix"); char ul = 'U', di = 'N'; if (zzz_[1] != 'g') { if (TYPEOF(uplo) != STRSXP || LENGTH(uplo) < 1 || (uplo = STRING_ELT(uplo, 0)) == NA_STRING || ((ul = *CHAR(uplo)) != 'U' && ul != 'L')) error(_("'%s' must be \"%s\" or \"%s\""), "uplo", "U", "L"); } if (zzz_[1] == 't') { if (TYPEOF(diag) != STRSXP || LENGTH(diag) < 1 || (diag = STRING_ELT(diag, 0)) == NA_STRING || ((di = *CHAR(diag)) != 'N' && di != 'U')) error(_("'%s' must be \"%s\" or \"%s\""), "diag", "N", "U"); } int m_ = -1; if (m != R_NilValue) { if (TYPEOF(m) == INTSXP) { int tmp; if (LENGTH(m) >= 1 && (tmp = INTEGER(m)[0]) != NA_INTEGER && tmp >= 0) m_ = tmp; } else if (TYPEOF(m) == REALSXP) { double tmp; if (LENGTH(m) >= 1 && !ISNAN(tmp = REAL(m)[0]) && tmp >= 0.0) { if (trunc(tmp) > INT_MAX) error(_("dimensions cannot exceed %s"), "2^31-1"); m_ = (int) tmp; } } if (m_ < 0) error(_("invalid '%s' to '%s'"), "m", __func__); } int n_ = -1; if (n != R_NilValue) { if (TYPEOF(n) == INTSXP) { int tmp; if (LENGTH(n) >= 1 && (tmp = INTEGER(n)[0]) != NA_INTEGER && tmp >= 0) n_ = tmp; } else if (TYPEOF(n) == REALSXP) { double tmp; if (LENGTH(n) >= 1 && !ISNAN(tmp = REAL(n)[0]) && tmp >= 0.0) { if (trunc(tmp) > INT_MAX) error(_("dimensions cannot exceed %s"), "2^31-1"); n_ = (int) tmp; } } if (n_ < 0) error(_("invalid '%s' to '%s'"), "n", __func__); } int byrow_; if (TYPEOF(byrow) != LGLSXP || LENGTH(byrow) < 1 || (byrow_ = LOGICAL(byrow)[0]) == NA_LOGICAL) error(_("'%s' must be %s or %s"), "byrow", "TRUE", "FALSE"); if (dimnames != R_NilValue) if (TYPEOF(dimnames) != VECSXP || LENGTH(dimnames) != 2) error(_("invalid '%s' to '%s'"), "dimnames", __func__); R_xlen_t vlen_ = XLENGTH(from); if (zzz_[1] != 'g' && (m_ < 0) != (n_ < 0)) { if (m_ < 0) m_ = n_; else n_ = m_; } else if (m_ < 0 && n_ < 0) { if (vlen_ > INT_MAX) error(_("dimensions cannot exceed %s"), "2^31-1"); m_ = (int) vlen_; n_ = 1; } else if (m_ < 0) { if (vlen_ > (Matrix_int_fast64_t) INT_MAX * n_) { if (n_ == 0) error(_("nonempty vector supplied for empty matrix")); else error(_("dimensions cannot exceed %s"), "2^31-1"); } m_ = (n_ == 0) ? 0 : vlen_ / n_ + (vlen_ % n_ != 0); } else if (n_ < 0) { if (vlen_ > (Matrix_int_fast64_t) m_ * INT_MAX) { if (m_ == 0) error(_("nonempty vector supplied for empty matrix")); else error(_("dimensions cannot exceed %s"), "2^31-1"); } n_ = (m_ == 0) ? 0 : vlen_ / m_ + (vlen_ % m_ != 0); } Matrix_int_fast64_t mlen_ = (Matrix_int_fast64_t) m_ * n_; if (vlen_ <= 1) /* do nothing */ ; else if (mlen_ == 0) warning(_("nonempty vector supplied for empty matrix")); else if (vlen_ > mlen_) warning(_("vector length (%lld) exceeds matrix length (%d * %d)"), (long long) vlen_, m_, n_); else if (mlen_ % vlen_ != 0) warning(_("matrix length (%d * %d) is not a multiple of vector length (%lld)"), m_, n_, (long long) vlen_); return vector_as_dense(from, zzz_, ul, di, m_, n_, byrow_, dimnames); } SEXP matrix_as_dense(SEXP from, const char *zzz, char ul, char di, int trans, int new) { SEXPTYPE tf = TYPEOF(from); char cl[] = "...Matrix"; cl[0] = (zzz[0] == '.') ? typeToKind(tf) : ((zzz[0] == ',') ? ((tf == CPLXSXP) ? 'z' : 'd') : zzz[0]); cl[1] = zzz[1]; cl[2] = zzz[2]; #ifndef MATRIX_ENABLE_IMATRIX if (cl[0] == 'i') cl[0] = 'd'; #endif SEXPTYPE tt = kindToType(cl[0]); PROTECT(from = coerceVector(from, tt)); SEXP to = PROTECT(newObject(cl)); int nprotect = 2; SEXP dim = getAttrib(from, R_DimSymbol), dimnames; int *pdim, isM, m, n, doDN; R_xlen_t mn = XLENGTH(from); isM = TYPEOF(dim) == INTSXP && LENGTH(dim) == 2; if (isM) { pdim = INTEGER(dim); m = pdim[0]; n = pdim[1]; if (m != n || n > 0) { dim = GET_SLOT(to, Matrix_DimSym); pdim = INTEGER(dim); pdim[0] = m; pdim[1] = n; } PROTECT(dimnames = getAttrib(from, R_DimNamesSymbol)); ++nprotect; doDN = dimnames != R_NilValue; } else { if (mn > INT_MAX) error(_("dimensions cannot exceed %s"), "2^31-1"); dim = GET_SLOT(to, Matrix_DimSym); pdim = INTEGER(dim); if (trans) { pdim[0] = m = 1; pdim[1] = n = (int) mn; } else { pdim[0] = m = (int) mn; pdim[1] = n = 1; } SEXP nms = PROTECT(getAttrib(from, R_NamesSymbol)); ++nprotect; doDN = nms != R_NilValue; if (doDN) { PROTECT(dimnames = allocVector(VECSXP, 2)); ++nprotect; SET_VECTOR_ELT(dimnames, trans ? 1 : 0, nms); } } if (cl[1] != 'g' && m != n) error(_("attempt to construct non-square %s"), (cl[1] == 's') ? "symmetricMatrix" : "triangularMatrix"); if (doDN) { if (cl[1] != 's') SET_SLOT(to, Matrix_DimNamesSym, dimnames); else set_symmetrized_DimNames(to, dimnames, -1); } if (cl[1] != 'g' && ul != 'U') { SEXP uplo = PROTECT(mkString("L")); SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ } if (cl[1] == 't' && di != 'N') { SEXP diag = PROTECT(mkString("U")); SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ } SEXP x; if (cl[2] != 'p') { if (new <= 0 || (new <= 1 && ATTRIB(from) == R_NilValue) || !MAYBE_REFERENCED(from)) { if (ATTRIB(from) != R_NilValue && new >= 1) { /* 'from' has attributes and no references : */ SET_ATTRIB(from, R_NilValue); if (OBJECT(from)) SET_OBJECT(from, 0); } x = from; } else { PROTECT(x = allocVector(tt, mn)); ++nprotect; switch (tt) { case LGLSXP: Matrix_memcpy(LOGICAL(x), LOGICAL(from), mn, sizeof(int)); break; case INTSXP: Matrix_memcpy(INTEGER(x), INTEGER(from), mn, sizeof(int)); break; case REALSXP: Matrix_memcpy(REAL(x), REAL(from), mn, sizeof(double)); break; case CPLXSXP: Matrix_memcpy(COMPLEX(x), COMPLEX(from), mn, sizeof(Rcomplex)); break; default: break; } } } else { PROTECT(x = allocVector(tt, (mn - n) / 2 + n)); ++nprotect; switch (tt) { case LGLSXP: ipack2(LOGICAL(x), LOGICAL(from), n, ul, di); break; case INTSXP: ipack2(INTEGER(x), INTEGER(from), n, ul, di); break; case REALSXP: dpack2(REAL(x), REAL(from), n, ul, di); break; case CPLXSXP: zpack2(COMPLEX(x), COMPLEX(from), n, ul, di); break; default: break; } } SET_SLOT(to, Matrix_xSym, x); UNPROTECT(nprotect); return to; } /* as(, ".(ge|sy|sp|tr|tp)Matrix") */ SEXP R_matrix_as_dense(SEXP from, SEXP zzz, SEXP uplo, SEXP diag, SEXP trans) { switch (TYPEOF(from)) { case LGLSXP: case INTSXP: case REALSXP: case CPLXSXP: break; default: ERROR_INVALID_TYPE(from, __func__); break; } const char *zzz_; if (TYPEOF(zzz) != STRSXP || LENGTH(zzz) < 1 || (zzz = STRING_ELT(zzz, 0)) == NA_STRING || (zzz_ = CHAR(zzz))[0] == '\0' || (zzz_ )[1] == '\0' || !((zzz_[1] == 'g' && (zzz_[2] == 'e' )) || (zzz_[1] == 's' && (zzz_[2] == 'y' || zzz_[2] == 'p')) || (zzz_[1] == 't' && (zzz_[2] == 'r' || zzz_[2] == 'p')))) error(_("second argument of '%s' does not specify a subclass of %s"), __func__, "denseMatrix"); char ul = 'U', di = 'N'; if (zzz_[1] != 'g') { if (TYPEOF(uplo) != STRSXP || LENGTH(uplo) < 1 || (uplo = STRING_ELT(uplo, 0)) == NA_STRING || ((ul = *CHAR(uplo)) != 'U' && ul != 'L')) error(_("'%s' must be \"%s\" or \"%s\""), "uplo", "U", "L"); } if (zzz_[1] == 't') { if (TYPEOF(diag) != STRSXP || LENGTH(diag) < 1 || (diag = STRING_ELT(diag, 0)) == NA_STRING || ((di = *CHAR(diag)) != 'N' && di != 'U')) error(_("'%s' must be \"%s\" or \"%s\""), "diag", "N", "U"); } int trans_; if (TYPEOF(trans) != LGLSXP || LENGTH(trans) < 1 || (trans_ = LOGICAL(trans)[0]) == NA_LOGICAL) error(_("'%s' must be %s or %s"), "trans", "TRUE", "FALSE"); return matrix_as_dense(from, zzz_, ul, di, trans_, 1); } SEXP sparse_as_dense(SEXP from, const char *class, int packed) { packed = packed && class[1] != 'g'; char cl[] = "...Matrix"; cl[0] = class[0]; cl[1] = class[1]; cl[2] = (packed) ? 'p' : ((class[1] == 'g') ? 'e' : ((class[1] == 's') ? 'y' : 'r')); SEXP to = PROTECT(newObject(cl)); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; Matrix_int_fast64_t len = (Matrix_int_fast64_t) m * n; if (packed) len = (len + n) / 2; if (len > R_XLEN_T_MAX) error(_("attempt to allocate vector of length exceeding %s"), "R_XLEN_T_MAX"); if (class[2] != 'C' && packed && len > R_XLEN_T_MAX) error(_("coercing n-by-n %s to %s is not supported for n*n exceeding %s"), "[RT]sparseMatrix", "packedMatrix", "R_XLEN_T_MAX"); double bytes = (double) len * kindToSize(cl[0]); if (bytes > 0x1.0p+30 /* 1 GiB */) warning(_("sparse->dense coercion: allocating vector of size %0.1f GiB"), 0x1.0p-30 * bytes); if (m != n || n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); SET_SLOT(to, Matrix_DimNamesSym, dimnames); UNPROTECT(1); /* dimnames */ char ul = 'U', di = 'N'; if (class[1] != 'g') { SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); ul = *CHAR(STRING_ELT(uplo, 0)); if (ul != 'U') SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ if (class[1] == 't') { SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); di = *CHAR(STRING_ELT(diag, 0)); if (di != 'N') SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ } } /* It remains to fill 'x' ... */ SEXP x1 = PROTECT(allocVector(kindToType(class[0]), (R_xlen_t) len)), p0, i0, j0; int *pp, *pi, *pj, nprotect = 2; p0 = i0 = j0 = NULL; pp = pi = pj = NULL; SET_SLOT(to, Matrix_xSym, x1); if (class[2] != 'T') { PROTECT(p0 = GET_SLOT(from, Matrix_pSym)); ++nprotect; pp = INTEGER(p0) + 1; } if (class[2] != 'R') { PROTECT(i0 = GET_SLOT(from, Matrix_iSym)); ++nprotect; pi = INTEGER(i0); } if (class[2] != 'C') { PROTECT(j0 = GET_SLOT(from, Matrix_jSym)); ++nprotect; pj = INTEGER(j0); } #define SAD_CASES \ do { \ switch (class[0]) { \ case 'l': \ SAD_SUBCASES(int, LOGICAL, SHOW, FIRSTOF, INCREMENT_LOGICAL, 1); \ break; \ case 'i': \ SAD_SUBCASES(int, INTEGER, SHOW, FIRSTOF, INCREMENT_INTEGER, 1); \ break; \ case 'd': \ SAD_SUBCASES(double, REAL, SHOW, FIRSTOF, INCREMENT_REAL, 1.0); \ break; \ case 'z': \ SAD_SUBCASES(Rcomplex, COMPLEX, SHOW, FIRSTOF, INCREMENT_COMPLEX, Matrix_zone); \ break; \ default: \ break; \ } \ } while (0) #define SAD_SUBCASES(_CTYPE_, _PTR_, _MASK_, _REPLACE_, _INCREMENT_, _ONE_) \ do { \ _MASK_(_CTYPE_ *px0 = _PTR_(x0)); \ _CTYPE_ *px1 = _PTR_(x1) ; \ Matrix_memset(px1, 0, len, sizeof(_CTYPE_)); \ if (!packed) { \ /* .(ge|sy|tr)Matrix */ \ SAD_SUBSUBCASES(SAD_LOOP_C2NP, SAD_LOOP_R2NP, SAD_LOOP_T2NP, \ _MASK_, _REPLACE_, _INCREMENT_); \ if (class[1] == 't' && di != 'N') { \ px1 = _PTR_(x1); \ R_xlen_t n1a = (R_xlen_t) n + 1; \ for (int d = 0; d < n; ++d, px1 += n1a) \ *px1 = _ONE_; \ } \ } else if (ul == 'U') { \ /* upper triangular .(sp|tp)Matrix */ \ SAD_SUBSUBCASES(SAD_LOOP_C2UP, SAD_LOOP_R2UP, SAD_LOOP_T2UP, \ _MASK_, _REPLACE_, _INCREMENT_); \ if (class[1] == 't' && di != 'N') { \ px1 = _PTR_(x1); \ for (int d = 0; d < n; px1 += (++d) + 1) \ *px1 = _ONE_; \ } \ } else { \ /* lower triangular .(sp|tp)Matrix */ \ SAD_SUBSUBCASES(SAD_LOOP_C2LP, SAD_LOOP_R2LP, SAD_LOOP_T2LP, \ _MASK_, _REPLACE_, _INCREMENT_); \ if (class[1] == 't' && di != 'N') { \ px1 = _PTR_(x1); \ for (int d = 0; d < n; px1 += n - (d++)) \ *px1 = _ONE_; \ } \ } \ } while (0) #define SAD_SUBSUBCASES(_LOOP_C_, _LOOP_R_, _LOOP_T_, _MASK_, _REPLACE_, _INCREMENT_) \ do { \ switch (class[2]) { \ case 'C': \ { \ int j, k, kend; \ _LOOP_C_(_MASK_, _REPLACE_, _INCREMENT_); \ break; \ } \ case 'R': \ { \ int i, k, kend; \ _LOOP_R_(_MASK_, _REPLACE_, _INCREMENT_); \ break; \ } \ case 'T': \ { \ R_xlen_t index, k, nnz = XLENGTH(i0); \ _LOOP_T_(_MASK_, _REPLACE_, _INCREMENT_); \ break; \ } \ default: \ break; \ } \ } while (0) #define SAD_LOOP_C2NP(_MASK_, _REPLACE_, _INCREMENT_) \ do { \ for (j = 0, k = 0; j < n; ++j, px1 += m) { \ kend = pp[j]; \ while (k < kend) { \ px1[*pi] = _REPLACE_(*px0, 1); \ ++k; ++pi; _MASK_(++px0); \ } \ } \ } while (0) #define SAD_LOOP_C2UP(_MASK_, _REPLACE_, _INCREMENT_) \ do { \ for (j = 0, k = 0; j < n; px1 += (++j)) { \ kend = pp[j]; \ while (k < kend) { \ px1[*pi] = _REPLACE_(*px0, 1); \ ++k; ++pi; _MASK_(++px0); \ } \ } \ } while (0) #define SAD_LOOP_C2LP(_MASK_, _REPLACE_, _INCREMENT_) \ do { \ for (j = 0, k = 0; j < n; px1 += n - (j++)) { \ kend = pp[j]; \ while (k < kend) { \ px1[*pi - j] = _REPLACE_(*px0, 1); \ ++k; ++pi; _MASK_(++px0); \ } \ } \ } while (0) #define SAD_LOOP_R2NP(_MASK_, _REPLACE_, _INCREMENT_) \ do { \ R_xlen_t m1 = (R_xlen_t) m; \ for (i = 0, k = 0; i < m; ++i, ++px1) { \ kend = pp[i]; \ while (k < kend) { \ px1[m1 * *pj] = _REPLACE_(*px0, 1); \ ++k; ++pj; _MASK_(++px0); \ } \ } \ } while (0) #define SAD_LOOP_R2UP(_MASK_, _REPLACE_, _INCREMENT_) \ do { \ for (i = 0, k = 0; i < n; ++i) { \ kend = pp[i]; \ while (k < kend) { \ px1[PACKED_AR21_UP(i, *pj)] = _REPLACE_(*px0, 1); \ ++k; ++pj; _MASK_(++px0); \ } \ } \ } while (0) #define SAD_LOOP_R2LP(_MASK_, _REPLACE_, _INCREMENT_) \ do { \ R_xlen_t n2 = (R_xlen_t) n * 2; \ for (i = 0, k = 0; i < n; ++i) { \ kend = pp[i]; \ while (k < kend) { \ px1[PACKED_AR21_LO(i, *pj, n2)] = _REPLACE_(*px0, 1); \ ++k; ++pj; _MASK_(++px0); \ } \ } \ } while (0) #define SAD_LOOP_T2NP(_MASK_, _REPLACE_, _INCREMENT_) \ do { \ R_xlen_t m1 = (R_xlen_t) m; \ for (k = 0; k < nnz; ++k) { \ index = m1 * *pj + *pi; \ _INCREMENT_(px1[index], (*px0)); \ ++pi; ++pj; _MASK_(++px0); \ } \ } while (0) #define SAD_LOOP_T2UP(_MASK_, _REPLACE_, _INCREMENT_) \ do { \ for (k = 0; k < nnz; ++k) { \ index = PACKED_AR21_UP(*pi, *pj); \ _INCREMENT_(px1[index], (*px0)); \ ++pi; ++pj; _MASK_(++px0); \ } \ } while (0) #define SAD_LOOP_T2LP(_MASK_, _REPLACE_, _INCREMENT_) \ do { \ R_xlen_t n2 = (R_xlen_t) n * 2; \ for (k = 0; k < nnz; ++k) { \ index = PACKED_AR21_LO(*pi, *pj, n2); \ _INCREMENT_(px1[index], (*px0)); \ ++pi; ++pj; _MASK_(++px0); \ } \ } while (0) if (class[0] == 'n') SAD_SUBCASES(int, LOGICAL, HIDE, SECONDOF, INCREMENT_PATTERN, 1); else { SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)); SAD_CASES; UNPROTECT(1); /* x0 */ } #undef SAD_CASES #undef SAD_SUBCASES #undef SAD_SUBSUBCASES #undef SAD_LOOP_C2NP #undef SAD_LOOP_C2UP #undef SAD_LOOP_C2LP #undef SAD_LOOP_R2NP #undef SAD_LOOP_R2UP #undef SAD_LOOP_R2LP #undef SAD_LOOP_T2NP #undef SAD_LOOP_T2UP #undef SAD_LOOP_T2LP UNPROTECT(nprotect); return to; } /* as(<[CRT]sparseMatrix>, "(un)?packedMatrix") */ SEXP R_sparse_as_dense(SEXP from, SEXP packed) { static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); int packed_; if (TYPEOF(packed) != LGLSXP || LENGTH(packed) < 1 || (packed_ = LOGICAL(packed)[0]) == NA_LOGICAL) error(_("'%s' must be %s or %s"), "packed", "TRUE", "FALSE"); return sparse_as_dense(from, valid[ivalid], packed_); } SEXP diagonal_as_dense(SEXP from, const char *class, char kind, char shape, int packed, char ul) { char cl[] = "...Matrix"; cl[0] = (kind == '.') ? class[0] : ((kind == ',') ? ((class[0] == 'z') ? 'z' : 'd') : kind); cl[1] = shape; cl[2] = (cl[1] == 'g') ? 'e' : ((packed) ? 'p' : ((cl[1] == 's') ? 'y' : 'r')); SEXP to = PROTECT(newObject(cl)); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int n = INTEGER(dim)[0]; Matrix_int_fast64_t len = (Matrix_int_fast64_t) n * n; if (len > R_XLEN_T_MAX) error(_("attempt to allocate vector of length exceeding %s"), "R_XLEN_T_MAX"); double bytes = (double) len * kindToSize(cl[0]); if (bytes > 0x1.0p+30 /* 1 GiB */) warning(_("sparse->dense coercion: allocating vector of size %0.1f GiB"), 0x1.0p-30 * bytes); if (n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); if (cl[1] == 's') set_symmetrized_DimNames(to, dimnames, -1); else SET_SLOT(to, Matrix_DimNamesSym, dimnames); UNPROTECT(1); /* dimnames */ if (cl[1] != 'g' && ul != 'U') { SEXP uplo = PROTECT(mkString("L")); SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ } SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); char di = *CHAR(STRING_ELT(diag, 0)); if (cl[1] == 't' && di != 'N') SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)); if (class[0] != cl[0]) { if (class[0] == 'n' && cl[0] == 'l') x0 = duplicate(x0); else x0 = coerceVector(x0, kindToType(cl[0])); if (class[0] == 'n') naToOne(x0); UNPROTECT(1); /* x0 */ PROTECT(x0); } SEXP x1 = PROTECT(allocVector(TYPEOF(x0), (R_xlen_t) len)); SET_SLOT(to, Matrix_xSym, x1); #define DAD_SUBCASES(_PREFIX_, _CTYPE_, _PTR_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \ Matrix_memset(px1, 0, (R_xlen_t) len, sizeof(_CTYPE_)); \ if (di == 'N' || cl[1] != 't') { \ if (cl[2] != 'p') \ _PREFIX_ ## dcpy2(px1, px0, n, n, ul, di); \ else \ _PREFIX_ ## dcpy1(px1, px0, n, n, ul, ul, di); \ } \ } while (0) switch (cl[0]) { case 'n': case 'l': DAD_SUBCASES(i, int, LOGICAL); break; case 'i': DAD_SUBCASES(i, int, INTEGER); break; case 'd': DAD_SUBCASES(d, double, REAL); break; case 'z': DAD_SUBCASES(z, Rcomplex, COMPLEX); break; default: break; } #undef DAD_CASES #undef DAD_SUBCASES UNPROTECT(3); /* x1, x0, to */ return to; } /* as(, ".(ge|sy|sp|tr|tp)Matrix") */ SEXP R_diagonal_as_dense(SEXP from, SEXP kind, SEXP shape, SEXP packed, SEXP uplo) { static const char *valid[] = { VALID_DIAGONAL, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); char kind_; if (TYPEOF(kind) != STRSXP || LENGTH(kind) < 1 || (kind = STRING_ELT(kind, 0)) == NA_STRING || (kind_ = CHAR(kind)[0]) == '\0') error(_("invalid '%s' to '%s'"), "kind", __func__); char shape_; if (TYPEOF(shape) != STRSXP || LENGTH(shape) < 1 || (shape = STRING_ELT(shape, 0)) == NA_STRING || ((shape_ = CHAR(shape)[0]) != 'g' && shape_ != 's' && shape_ != 't')) error(_("invalid '%s' to '%s'"), "shape", __func__); int packed_ = 0; if (shape_ != 'g') { if (TYPEOF(packed) != LGLSXP || LENGTH(packed) < 1 || (packed_ = LOGICAL(packed)[0]) == NA_LOGICAL) error(_("'%s' must be %s or %s"), "packed", "TRUE", "FALSE"); } char ul = 'U'; if (shape_ != 'g') { if (TYPEOF(uplo) != STRSXP || LENGTH(uplo) < 1 || (uplo = STRING_ELT(uplo, 0)) == NA_STRING || ((ul = *CHAR(uplo)) != 'U' && ul != 'L')) error(_("'%s' must be \"%s\" or \"%s\""), "uplo", "U", "L"); } return diagonal_as_dense(from, valid[ivalid], kind_, shape_, packed_, ul); } SEXP index_as_dense(SEXP from, const char *class, char kind) { SEXP margin = PROTECT(GET_SLOT(from, Matrix_marginSym)); int mg = INTEGER(margin)[0] - 1; UNPROTECT(1); /* margin */ char cl[] = ".geMatrix"; cl[0] = (kind == '.') ? 'n' : ((kind == ',') ? 'd' : kind); SEXP to = PROTECT(newObject(cl)); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; Matrix_int_fast64_t len = (Matrix_int_fast64_t) m * n; if (len > R_XLEN_T_MAX) error(_("attempt to allocate vector of length exceeding %s"), "R_XLEN_T_MAX"); double bytes = (double) len * kindToSize(cl[0]); if (bytes > 0x1.0p+30 /* 1 GiB */) warning(_("sparse->dense coercion: allocating vector of size %0.1f GiB"), 0x1.0p-30 * bytes); if (m != n || n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); SET_SLOT(to, Matrix_DimNamesSym, dimnames); UNPROTECT(1); /* dimnames */ SEXP perm = PROTECT(GET_SLOT(from, Matrix_permSym)); int *pperm = INTEGER(perm); SEXP x = PROTECT(allocVector(kindToType(cl[0]), (R_xlen_t) len)); SET_SLOT(to, Matrix_xSym, x); #define IAD_SUBCASES(_CTYPE_, _PTR_, _ONE_) \ do { \ _CTYPE_ *px = _PTR_(x); \ Matrix_memset(px, 0, (R_xlen_t) len, sizeof(_CTYPE_)); \ if (mg == 0) { \ R_xlen_t m1 = (R_xlen_t) m; \ for (int i = 0; i < m; ++i) \ px[i + m1 * (*(pperm++) - 1)] = _ONE_; \ } else { \ for (int j = 0; j < n; ++j, px += m) \ px[ *(pperm++) - 1 ] = _ONE_; \ } \ } while (0) switch (cl[0]) { case 'n': case 'l': IAD_SUBCASES(int, LOGICAL, 1); break; case 'i': IAD_SUBCASES(int, INTEGER, 1); break; case 'd': IAD_SUBCASES(double, REAL, 1.0); break; case 'z': IAD_SUBCASES(Rcomplex, COMPLEX, Matrix_zone); break; default: break; } #undef IAD_SUBCASES UNPROTECT(3); /* x, perm, to */ return to; } /* as(, ".geMatrix") */ SEXP R_index_as_dense(SEXP from, SEXP kind) { static const char *valid[] = { "indMatrix", "pMatrix" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); char kind_; if (TYPEOF(kind) != STRSXP || LENGTH(kind) < 1 || (kind = STRING_ELT(kind, 0)) == NA_STRING || (kind_ = CHAR(kind)[0]) == '\0') error(_("invalid '%s' to '%s'"), "kind", __func__); return index_as_dense(from, valid[ivalid], kind_); } SEXP vector_as_sparse(SEXP from, const char *zzz, char ul, char di, int m, int n, int byrow, SEXP dimnames) { SEXP length0 = GET_SLOT(from, Matrix_lengthSym); Matrix_int_fast64_t r = (Matrix_int_fast64_t) ((TYPEOF(length0) == INTSXP) ? INTEGER(length0)[0] : REAL(length0)[0]); SEXP i0 = PROTECT(GET_SLOT(from, Matrix_iSym)), x0 = getAttrib(from, Matrix_xSym); SEXPTYPE tf = TYPEOF(x0); char cl[] = "...Matrix"; cl[0] = (zzz[0] == '.') ? ((x0 == R_NilValue) ? 'n' : typeToKind(tf)) : ((zzz[0] == ',') ? ((tf == CPLXSXP) ? 'z' : 'd') : zzz[0]); cl[1] = zzz[1]; cl[2] = (byrow) ? 'R' : 'C'; #ifndef MATRIX_ENABLE_IMATRIX if (cl[0] == 'i') cl[0] = 'd'; #endif SEXPTYPE tt = kindToType(cl[0]); if (x0 != R_NilValue) { PROTECT(x0); x0 = coerceVector(x0, tt); UNPROTECT(1); /* x0 */ } PROTECT(x0); if (cl[1] != 'g' && m != n) error(_("attempt to construct non-square %s"), (cl[1] == 's') ? "symmetricMatrix" : "triangularMatrix"); SEXP to = PROTECT(newObject(cl)); SEXP dim = GET_SLOT(to, Matrix_DimSym); int *pdim = INTEGER(dim); pdim[0] = m; pdim[1] = n; if (cl[1] != 's') SET_SLOT(to, Matrix_DimNamesSym, dimnames); else set_symmetrized_DimNames(to, dimnames, -1); if (cl[1] != 'g' && ul != 'U') { SEXP uplo = PROTECT(mkString("L")); SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ } if (cl[1] == 't' && di != 'N') { SEXP diag = PROTECT(mkString("U")); SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ } Matrix_int_fast64_t pos, mn = (Matrix_int_fast64_t) m * n, nnz1 = 0; R_xlen_t k = 0, nnz0 = XLENGTH(i0); #define VAS_SUBCASES(...) \ do { \ switch (TYPEOF(i0)) { \ case INTSXP: \ { \ int *pi0 = INTEGER(i0); \ VAS_SUBSUBCASES(__VA_ARGS__); \ break; \ } \ case REALSXP: \ { \ double *pi0 = REAL(i0); \ VAS_SUBSUBCASES(__VA_ARGS__); \ break; \ } \ default: \ break; \ } \ } while (0) #define VAS_SUBSUBCASES() \ do { \ if (nnz0 == 0) \ /* do nothing */ ; \ else if (cl[1] == 'g') { \ if (r == 0) \ nnz1 = mn; \ else if (r == mn) \ nnz1 = nnz0; \ else if (r > mn) \ while (k < nnz0 && (Matrix_int_fast64_t) pi0[k++] <= mn) \ nnz1++; \ else { \ Matrix_int_fast64_t mn_mod_r = mn % r; \ nnz1 = nnz0 * (mn / r); \ while (k < nnz0 && (Matrix_int_fast64_t) pi0[k++] <= mn_mod_r) \ nnz1++; \ } \ } \ else if (cl[1] == 's' || di == 'N') { \ if (r == 0) \ nnz1 = (mn + n) / 2; \ else if (r >= mn) { \ if ((ul == 'U') == !byrow) { \ while (k < nnz0 && (pos = (Matrix_int_fast64_t) pi0[k++] - 1) < mn) \ if (pos % n <= pos / n) \ ++nnz1; \ } else { \ while (k < nnz0 && (pos = (Matrix_int_fast64_t) pi0[k++] - 1) < mn) \ if (pos % n >= pos / n) \ ++nnz1; \ } \ } \ else { \ Matrix_int_fast64_t a = 0; \ if ((ul == 'U') == !byrow) { \ while (a < mn) { \ k = 0; \ while (k < nnz0 && (pos = a + pi0[k++] - 1) < mn) \ if (pos % n <= pos / n) \ ++nnz1; \ a += r; \ } \ } else { \ while (a < mn) { \ k = 0; \ while (k < nnz0 && (pos = a + pi0[k++] - 1) < mn) \ if (pos % n >= pos / n) \ ++nnz1; \ a += r; \ } \ } \ } \ } \ else { \ if (r == 0) \ nnz1 = (mn - n) / 2; \ else if (r >= mn) { \ if ((ul == 'U') == !byrow) { \ while (k < nnz0 && (pos = (Matrix_int_fast64_t) pi0[k++] - 1) < mn) \ if (pos % n < pos / n) \ ++nnz1; \ } else { \ while (k < nnz0 && (pos = (Matrix_int_fast64_t) pi0[k++] - 1) < mn) \ if (pos % n > pos / n) \ ++nnz1; \ } \ } \ else { \ Matrix_int_fast64_t a = 0; \ if ((ul == 'U') == !byrow) { \ while (a < mn) { \ k = 0; \ while (k < nnz0 && (pos = a + pi0[k++] - 1) < mn) \ if (pos % n < pos / n) \ ++nnz1; \ a += r; \ } \ } else { \ while (a < mn) { \ k = 0; \ while (k < nnz0 && (pos = a + pi0[k++] - 1) < mn) \ if (pos % n > pos / n) \ ++nnz1; \ a += r; \ } \ } \ } \ } \ } while (0) VAS_SUBCASES(); #undef VAS_SUBSUBCASES if (nnz1 > INT_MAX) error(_("attempt to construct %s with more than %s nonzero entries"), "sparseMatrix", "2^31-1"); int i_, j_, m_ = (byrow) ? n : m, n_ = (byrow) ? m : n; SEXP iSym = (byrow) ? Matrix_jSym : Matrix_iSym, p1 = PROTECT(allocVector(INTSXP, (R_xlen_t) n_ + 1)), i1 = PROTECT(allocVector(INTSXP, nnz1)); SET_SLOT(to, Matrix_pSym, p1); SET_SLOT(to, iSym, i1); int *pp1 = INTEGER(p1) + 1, *pi1 = INTEGER(i1); Matrix_memset(pp1 - 1, 0, (R_xlen_t) n + 1, sizeof(int)); k = 0; #define VAS_SUBSUBCASES(_MASK0_, _MASK1_, _REPLACE_, _CTYPE_, _PTR_, _ONE_, _NA_) \ do { \ _MASK0_(_CTYPE_ *px0 = _PTR_(x0)); \ _MASK1_(_CTYPE_ *px1 = _PTR_(x1)); \ if (nnz1 == 0) \ /* do nothing */ ; \ else if (cl[1] == 'g') { \ if (r == 0) { \ for (j_ = 0; j_ < n_; ++j_) { \ pp1[j_] = m; \ for (i_ = 0; i_ < m_; ++i_) { \ *(pi1++) = i_; \ _MASK1_(*(px1++) = _NA_); \ } \ } \ } \ else if (r >= mn) { \ while (k < nnz0 && (pos = (Matrix_int_fast64_t) pi0[k] - 1) < mn) { \ ++pp1[pos / m_]; \ *(pi1++) = pos % m_; \ _MASK1_(*(px1++) = _REPLACE_(px0[k], _ONE_)); \ ++k; \ } \ } \ else { \ Matrix_int_fast64_t a = 0; \ while (a < mn) { \ k = 0; \ while (k < nnz0 && (pos = a + pi0[k] - 1) < mn) { \ ++pp1[pos / m_]; \ *(pi1++) = pos % m_; \ _MASK1_(*(px1++) = _REPLACE_(px0[k], _ONE_)); \ ++k; \ } \ a += r; \ } \ } \ } \ else if (cl[1] == 's' || di == 'N') { \ if (r == 0) { \ if ((ul == 'U') == !byrow) { \ for (j_ = 0; j_ < n_; ++j_) { \ pp1[j_] = j_ + 1; \ for (i_ = 0; i_ <= j_; ++i_) { \ *(pi1++) = i_; \ _MASK1_(*(px1++) = _NA_); \ } \ } \ } else { \ for (j_ = 0; j_ < n_; ++j_) { \ pp1[j_] = n_ - j_; \ for (i_ = j_; i_ < n_; ++i_) { \ *(pi1++) = i_; \ _MASK1_(*(px1++) = _NA_); \ } \ } \ } \ } \ else if (r >= mn) { \ if ((ul == 'U') == !byrow) { \ while (k < nnz0 && (pos = (Matrix_int_fast64_t) pi0[k] - 1) < mn) { \ if ((i_ = pos % n_) <= (j_ = pos / n_)) { \ ++pp1[j_]; \ *(pi1++) = i_; \ _MASK1_(*(px1++) = _REPLACE_(px0[k], _ONE_)); \ } \ ++k; \ } \ } else { \ while (k < nnz0 && (pos = (Matrix_int_fast64_t) pi0[k] - 1) < mn) { \ if ((i_ = pos % n_) >= (j_ = pos / n_)) { \ ++pp1[j_]; \ *(pi1++) = i_; \ _MASK1_(*(px1++) = _REPLACE_(px0[k], _ONE_)); \ } \ ++k; \ } \ } \ } \ else { \ Matrix_int_fast64_t a = 0; \ if ((ul == 'U') == !byrow) { \ while (a < mn) { \ k = 0; \ while (k < nnz0 && (pos = a + pi0[k] - 1) < mn) { \ if ((i_ = pos % n) <= (j_ = pos / n)) { \ ++pp1[j_]; \ *(pi1++) = i_; \ _MASK1_(*(px1++) = _REPLACE_(px0[k], _ONE_)); \ } \ ++k; \ } \ a += r; \ } \ } else { \ while (a < mn) { \ k = 0; \ while (k < nnz0 && (pos = a + pi0[k] - 1) < mn) { \ if ((i_ = pos % n) >= (j_ = pos / n)) { \ ++pp1[j_]; \ *(pi1++) = i_; \ _MASK1_(*(px1++) = _REPLACE_(px0[k], _ONE_)); \ } \ ++k; \ } \ a += r; \ } \ } \ } \ } \ else { \ if (r == 0) { \ if ((ul == 'U') == !byrow) { \ for (j_ = 0; j_ < n_; ++j_) { \ pp1[j_] = j_; \ for (i_ = 0; i_ < j_; ++i_) { \ *(pi1++) = i_; \ _MASK1_(*(px1++) = _NA_); \ } \ } \ } else { \ for (j_ = 0; j_ < n_; ++j_) { \ pp1[j_] = n_ - j_ - 1; \ for (i_ = j_ + 1; i_ < n_; ++i_) { \ *(pi1++) = i_; \ _MASK1_(*(px1++) = _NA_); \ } \ } \ } \ } \ else if (r >= mn) { \ if ((ul == 'U') == !byrow) { \ while (k < nnz0 && (pos = (Matrix_int_fast64_t) pi0[k] - 1) < mn) { \ if ((i_ = pos % n_) < (j_ = pos / n_)) { \ ++pp1[j_]; \ *(pi1++) = i_; \ _MASK1_(*(px1++) = _REPLACE_(px0[k], _ONE_)); \ } \ ++k; \ } \ } else { \ while (k < nnz0 && (pos = (Matrix_int_fast64_t) pi0[k] - 1) < mn) { \ if ((i_ = pos % n_) > (j_ = pos / n_)) { \ ++pp1[j_]; \ *(pi1++) = i_; \ _MASK1_(*(px1++) = _REPLACE_(px0[k], _ONE_)); \ } \ ++k; \ } \ } \ } \ else { \ Matrix_int_fast64_t a = 0; \ if ((ul == 'U') == !byrow) { \ while (a < mn) { \ k = 0; \ while (k < nnz0 && (pos = a + pi0[k] - 1) < mn) { \ if ((i_ = pos % n) < (j_ = pos / n)) { \ ++pp1[j_]; \ *(pi1++) = i_; \ _MASK1_(*(px1++) = _REPLACE_(px0[k], _ONE_)); \ } \ ++k; \ } \ a += r; \ } \ } else { \ while (a < mn) { \ k = 0; \ while (k < nnz0 && (pos = a + pi0[k] - 1) < mn) { \ if ((i_ = pos % n) > (j_ = pos / n)) { \ ++pp1[j_]; \ *(pi1++) = i_; \ _MASK1_(*(px1++) = _REPLACE_(px0[k], _ONE_)); \ } \ ++k; \ } \ a += r; \ } \ } \ } \ } \ } while (0) if (cl[0] == 'n') VAS_SUBCASES(HIDE, HIDE, , , , , ); else { SEXP x1 = PROTECT(allocVector(kindToType(cl[0]), nnz1)); switch (cl[0]) { case 'l': if (x0 == R_NilValue) VAS_SUBCASES(HIDE, SHOW, SECONDOF, int, LOGICAL, 1, NA_LOGICAL); else VAS_SUBCASES(SHOW, SHOW, FIRSTOF, int, LOGICAL, 1, NA_LOGICAL); break; case 'i': if (x0 == R_NilValue) VAS_SUBCASES(HIDE, SHOW, SECONDOF, int, INTEGER, 1, NA_INTEGER); else VAS_SUBCASES(SHOW, SHOW, FIRSTOF, int, INTEGER, 1, NA_INTEGER); break; case 'd': if (x0 == R_NilValue) VAS_SUBCASES(HIDE, SHOW, SECONDOF, double, REAL, 1.0, NA_REAL); else VAS_SUBCASES(SHOW, SHOW, FIRSTOF, double, REAL, 1.0, NA_REAL); break; case 'z': if (x0 == R_NilValue) VAS_SUBCASES(HIDE, SHOW, SECONDOF, Rcomplex, COMPLEX, Matrix_zone, Matrix_zna); else VAS_SUBCASES(SHOW, SHOW, FIRSTOF, Rcomplex, COMPLEX, Matrix_zone, Matrix_zna); break; default: break; } SET_SLOT(to, Matrix_xSym, x1); UNPROTECT(1); /* x1 */ } #undef VAS_SUBCASES #undef VAS_SUBSUBCASES for (j_ = 0; j_ < n_; ++j_) pp1[j_] += pp1[j_ - 1]; switch (zzz[2]) { case 'C': to = sparse_as_Csparse(to, cl); break; case 'R': to = sparse_as_Rsparse(to, cl); break; case 'T': to = sparse_as_Tsparse(to, cl); break; default: break; } UNPROTECT(5); /* i1, p1, to, x0, i0 */ return to; } SEXP R_vector_as_sparse(SEXP from, SEXP zzz, SEXP uplo, SEXP diag, SEXP m, SEXP n, SEXP byrow, SEXP dimnames) { static const char *valid[] = { VALID_NONVIRTUAL_VECTOR, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); const char *zzz_; if (TYPEOF(zzz) != STRSXP || LENGTH(zzz) < 1 || (zzz = STRING_ELT(zzz, 0)) == NA_STRING || (zzz_ = CHAR(zzz))[0] == '\0' || (zzz_[1] != 'g' && zzz_[1] != 's' && zzz_[1] != 't') || (zzz_[2] != 'C' && zzz_[2] != 'R' && zzz_[2] != 'T')) error(_("second argument of '%s' does not specify a subclass of %s"), __func__, "[CRT]sparseMatrix"); char ul = 'U', di = 'N'; if (zzz_[1] != 'g') { if (TYPEOF(uplo) != STRSXP || LENGTH(uplo) < 1 || (uplo = STRING_ELT(uplo, 0)) == NA_STRING || ((ul = *CHAR(uplo)) != 'U' && ul != 'L')) error(_("'%s' must be \"%s\" or \"%s\""), "uplo", "U", "L"); } if (zzz_[1] == 't') { if (TYPEOF(diag) != STRSXP || LENGTH(diag) < 1 || (diag = STRING_ELT(diag, 0)) == NA_STRING || ((di = *CHAR(diag)) != 'N' && di != 'U')) error(_("'%s' must be \"%s\" or \"%s\""), "diag", "N", "U"); } int m_ = -1; if (m != R_NilValue) { if (TYPEOF(m) == INTSXP) { int tmp; if (LENGTH(m) >= 1 && (tmp = INTEGER(m)[0]) != NA_INTEGER && tmp >= 0) m_ = tmp; } else if (TYPEOF(m) == REALSXP) { double tmp; if (LENGTH(m) >= 1 && !ISNAN(tmp = REAL(m)[0]) && tmp >= 0.0) { if (trunc(tmp) > INT_MAX) error(_("dimensions cannot exceed %s"), "2^31-1"); m_ = (int) tmp; } } if (m_ < 0) error(_("invalid '%s' to '%s'"), "m", __func__); } int n_ = -1; if (n != R_NilValue) { if (TYPEOF(n) == INTSXP) { int tmp; if (LENGTH(n) >= 1 && (tmp = INTEGER(n)[0]) != NA_INTEGER && tmp >= 0) n_ = tmp; } else if (TYPEOF(n) == REALSXP) { double tmp; if (LENGTH(n) >= 1 && !ISNAN(tmp = REAL(n)[0]) && tmp >= 0.0) { if (trunc(tmp) > INT_MAX) error(_("dimensions cannot exceed %s"), "2^31-1"); n_ = (int) tmp; } } if (n_ < 0) error(_("invalid '%s' to '%s'"), "n", __func__); } int byrow_; if (TYPEOF(byrow) != LGLSXP || LENGTH(byrow) < 1 || (byrow_ = LOGICAL(byrow)[0]) == NA_LOGICAL) error(_("'%s' must be %s or %s"), "byrow", "TRUE", "FALSE"); if (dimnames != R_NilValue) if (TYPEOF(dimnames) != VECSXP || LENGTH(dimnames) != 2) error(_("invalid '%s' to '%s'"), "dimnames", __func__); SEXP tmp = GET_SLOT(from, Matrix_lengthSym); Matrix_int_fast64_t vlen_ = (Matrix_int_fast64_t) ((TYPEOF(tmp) == INTSXP) ? INTEGER(tmp)[0] : REAL(tmp)[0]); if (zzz_[1] != 'g' && (m_ < 0) != (n_ < 0)) { if (m_ < 0) m_ = n_; else n_ = m_; } else if (m_ < 0 && n_ < 0) { if (vlen_ > INT_MAX) error(_("dimensions cannot exceed %s"), "2^31-1"); m_ = (int) vlen_; n_ = 1; } else if (m_ < 0) { if (vlen_ > (Matrix_int_fast64_t) INT_MAX * n_) { if (n_ == 0) error(_("nonempty vector supplied for empty matrix")); else error(_("dimensions cannot exceed %s"), "2^31-1"); } m_ = (n_ == 0) ? 0 : vlen_ / n_ + (vlen_ % n_ != 0); } else if (n_ < 0) { if (vlen_ > (Matrix_int_fast64_t) m_ * INT_MAX) { if (m_ == 0) error(_("nonempty vector supplied for empty matrix")); else error(_("dimensions cannot exceed %s"), "2^31-1"); } n_ = (m_ == 0) ? 0 : vlen_ / m_ + (vlen_ % m_ != 0); } Matrix_int_fast64_t mlen_ = (Matrix_int_fast64_t) m_ * n_; if (vlen_ <= 1) /* do nothing */ ; else if (mlen_ == 0) warning(_("nonempty vector supplied for empty matrix")); else if (vlen_ > mlen_) warning(_("vector length (%lld) exceeds matrix length (%d * %d)"), (long long) vlen_, m_, n_); else if (mlen_ % vlen_ != 0) warning(_("matrix length (%d * %d) is not a multiple of vector length (%lld)"), m_, n_, (long long) vlen_); return vector_as_sparse(from, zzz_, ul, di, m_, n_, byrow_, dimnames); } SEXP matrix_as_sparse(SEXP from, const char *zzz, char ul, char di, int trans) { char cl[] = "...Matrix"; cl[0] = typeToKind(TYPEOF(from)); cl[1] = zzz[1]; cl[2] = (zzz[1] == 'g') ? 'e' : ((zzz[1] == 's') ? 'y' : 'r'); #ifndef MATRIX_ENABLE_IMATRIX if (cl[0] == 'i') cl[0] = 'd'; #endif PROTECT_INDEX pid; PROTECT_WITH_INDEX(from, &pid); REPROTECT(from = matrix_as_dense(from, cl, ul, di, trans, 0), pid); REPROTECT(from = dense_as_sparse(from, cl, zzz[2]), pid); cl[2] = zzz[2]; REPROTECT(from = sparse_as_kind(from, cl, zzz[0]), pid); UNPROTECT(1); return from; } /* as(, ".[gst][CRT]Matrix") */ SEXP R_matrix_as_sparse(SEXP from, SEXP zzz, SEXP uplo, SEXP diag, SEXP trans) { switch (TYPEOF(from)) { case LGLSXP: case INTSXP: case REALSXP: case CPLXSXP: break; default: ERROR_INVALID_TYPE(from, __func__); break; } const char *zzz_; if (TYPEOF(zzz) != STRSXP || LENGTH(zzz) < 1 || (zzz = STRING_ELT(zzz, 0)) == NA_STRING || (zzz_ = CHAR(zzz))[0] == '\0' || (zzz_[1] != 'g' && zzz_[1] != 's' && zzz_[1] != 't') || (zzz_[2] != 'C' && zzz_[2] != 'R' && zzz_[2] != 'T')) error(_("second argument of '%s' does not specify a subclass of %s"), __func__, "[CRT]sparseMatrix"); char ul = 'U', di = 'N'; if (zzz_[1] != 'g') { if (TYPEOF(uplo) != STRSXP || LENGTH(uplo) < 1 || (uplo = STRING_ELT(uplo, 0)) == NA_STRING || ((ul = *CHAR(uplo)) != 'U' && ul != 'L')) error(_("'%s' must be \"%s\" or \"%s\""), "uplo", "U", "L"); } if (zzz_[1] == 't') { if (TYPEOF(diag) != STRSXP || LENGTH(diag) < 1 || (diag = STRING_ELT(diag, 0)) == NA_STRING || ((di = *CHAR(diag)) != 'N' && di != 'U')) error(_("'%s' must be \"%s\" or \"%s\""), "diag", "N", "U"); } int trans_; if (TYPEOF(trans) != LGLSXP || LENGTH(trans) < 1 || (trans_ = LOGICAL(trans)[0]) == NA_LOGICAL) error(_("'%s' must be %s or %s"), "trans", "TRUE", "FALSE"); return matrix_as_sparse(from, zzz_, ul, di, trans_); } SEXP dense_as_sparse(SEXP from, const char *class, char repr) { char cl[] = "...Matrix"; cl[0] = class[0]; cl[1] = class[1]; cl[2] = repr; SEXP to = PROTECT(newObject(cl)); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; if (m != n || n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); SET_SLOT(to, Matrix_DimNamesSym, dimnames); UNPROTECT(1); /* dimnames */ char ul = 'U', di = 'N'; if (class[1] != 'g') { SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); ul = *CHAR(STRING_ELT(uplo, 0)); if (ul != 'U') SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ if (class[1] == 't') { SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); di = *CHAR(STRING_ELT(diag, 0)); if (di != 'N') SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ } } SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)), p1, i1, j1; int i, j, *pp, *pi, *pj; R_xlen_t nnz = 0; p1 = i1 = j1 = NULL; pp = pi = pj = NULL; #define DAS_CASES(_MASK_) \ do { \ switch (class[0]) { \ case 'l': \ DAS_SUBCASES(int, LOGICAL, _MASK_, ISNZ_LOGICAL); \ break; \ case 'i': \ DAS_SUBCASES(int, INTEGER, _MASK_, ISNZ_INTEGER); \ break; \ case 'd': \ DAS_SUBCASES(double, REAL, _MASK_, ISNZ_REAL); \ break; \ case 'z': \ DAS_SUBCASES(Rcomplex, COMPLEX, _MASK_, ISNZ_COMPLEX); \ break; \ default: \ break; \ } \ } while (0) #define DAS_SUBCASES(_CTYPE_, _PTR_, _MASK_, _ISNZ_) \ do { \ _CTYPE_ *px0 = _PTR_(x0) ; \ _MASK_(_CTYPE_ *px1 = _PTR_(x1)); \ if (class[1] == 'g') \ /* .geMatrix */ \ DAS_SUBSUBCASES(DAS_LOOP_GEN2C, DAS_LOOP_GEN2R, DAS_LOOP_GEN2C, \ _MASK_, _ISNZ_); \ else if (class[2] != 'p' && di == 'N') \ /* .syMatrix, non-unit diagonal .trMatrix */ \ DAS_SUBSUBCASES(DAS_LOOP_TRN2C, DAS_LOOP_TRN2R, DAS_LOOP_TRN2C, \ _MASK_, _ISNZ_); \ else if (class[2] != 'p') \ /* unit diagonal .trMatrix */ \ DAS_SUBSUBCASES(DAS_LOOP_TRU2C, DAS_LOOP_TRU2R, DAS_LOOP_TRU2C, \ _MASK_, _ISNZ_); \ else if (di == 'N') \ /* .spMatrix, non-unit diagonal .tpMatrix */ \ DAS_SUBSUBCASES(DAS_LOOP_TPN2C, DAS_LOOP_TPN2R, DAS_LOOP_TPN2C, \ _MASK_, _ISNZ_); \ else \ /* unit diagonal .tpMatrix */ \ DAS_SUBSUBCASES(DAS_LOOP_TPU2C, DAS_LOOP_TPU2R, DAS_LOOP_TPU2C, \ _MASK_, _ISNZ_); \ } while (0) #undef DAS_SUBSUBCASES #define DAS_SUBSUBCASES(_LOOP_C_, _LOOP_R_, _LOOP_T_, _MASK_, _ISNZ_) \ do { \ switch (cl[2]) { \ case 'C': \ _LOOP_C_(_ISNZ_, ++nnz, DAS_VALID2C); \ break; \ case 'R': \ _LOOP_R_(_ISNZ_, ++nnz, DAS_VALID2R); \ break; \ case 'T': \ _LOOP_T_(_ISNZ_, ++nnz, DAS_VALID2T); \ break; \ default: \ break; \ } \ } while (0) #define DAS_LOOP_GEN2C(_ISNZ_, _DO_INNER_, _DO_OUTER_) \ do { \ for (j = 0; j < n; ++j) { \ for (i = 0; i < m; ++i, ++px0) \ if (_ISNZ_(*px0)) _DO_INNER_; \ _DO_OUTER_; \ } \ } while (0) #define DAS_LOOP_GEN2R(_ISNZ_, _DO_INNER_, _DO_OUTER_) \ do { \ R_xlen_t mn1s = (R_xlen_t) m * n - 1; \ for (i = 0; i < m; ++i, px0 -= mn1s) { \ for (j = 0; j < n; ++j, px0 += m) \ if (_ISNZ_(*px0)) _DO_INNER_; \ _DO_OUTER_; \ } \ } while (0) #define DAS_LOOP_TRN2C(_ISNZ_, _DO_INNER_, _DO_OUTER_) \ do { \ if (ul == 'U') { \ for (j = 0; j < n; px0 += n - (++j)) { \ for (i = 0; i <= j; ++i, ++px0) \ if (_ISNZ_(*px0)) _DO_INNER_; \ _DO_OUTER_; \ } \ } else { \ for (j = 0; j < n; px0 += (++j)) { \ for (i = j; i < n; ++i, ++px0) \ if (_ISNZ_(*px0)) _DO_INNER_; \ _DO_OUTER_; \ } \ } \ } while (0) #define DAS_LOOP_TRN2R(_ISNZ_, _DO_INNER_, _DO_OUTER_) \ do { \ R_xlen_t d; \ if (ul == 'U') { \ d = (R_xlen_t) n * n - 1; \ for (i = 0; i < n; ++i, px0 -= (d -= n)) { \ for (j = i; j < n; ++j, px0 += n) \ if (_ISNZ_(*px0)) _DO_INNER_; \ _DO_OUTER_; \ } \ } else { \ d = -1; \ for (i = 0; i < n; ++i, px0 -= (d += n)) { \ for (j = 0; j <= i; ++j, px0 += n) \ if (_ISNZ_(*px0)) _DO_INNER_; \ _DO_OUTER_; \ } \ } \ } while (0) #define DAS_LOOP_TRU2C(_ISNZ_, _DO_INNER_, _DO_OUTER_) \ do { \ if (ul == 'U') { \ px0 += n; \ for (j = 1; j < n; ++j) { \ for (i = 0; i < j; ++i, ++px0) \ if (_ISNZ_(*px0)) _DO_INNER_; \ _DO_OUTER_; \ px0 += n - j; \ } \ } else { \ for (j = 0; j < n; ++j) { \ px0 += j + 1; \ for (i = j + 1; i < n; ++i, ++px0) \ if (_ISNZ_(*px0)) _DO_INNER_; \ _DO_OUTER_; \ } \ } \ } while (0) #define DAS_LOOP_TRU2R(_ISNZ_, _DO_INNER_, _DO_OUTER_) \ do { \ R_xlen_t d; \ if (ul == 'U') { \ d = (R_xlen_t) n * (n - 1) - 1; \ for (i = 0; i < n; ++i) { \ for (j = i + 1; j < n; ++j) { \ px0 += n; \ if (_ISNZ_(*px0)) _DO_INNER_; \ } \ _DO_OUTER_; \ px0 -= (d -= n); \ } \ } else { \ ++px0; \ d = -1; \ for (i = 1; i < n; ++i) { \ for (j = 0; j < i; ++j) { \ if (_ISNZ_(*px0)) _DO_INNER_; \ px0 += n; \ } \ _DO_OUTER_; \ px0 -= (d += n); \ } \ } \ } while (0) #define DAS_LOOP_TPN2C(_ISNZ_, _DO_INNER_, _DO_OUTER_) \ do { \ if (ul == 'U') { \ for (j = 0; j < n; ++j) { \ for (i = 0; i <= j; ++i, ++px0) \ if (_ISNZ_(*px0)) _DO_INNER_; \ _DO_OUTER_; \ } \ } else { \ for (j = 0; j < n; ++j) { \ for (i = j; i < n; ++i, ++px0) \ if (_ISNZ_(*px0)) _DO_INNER_; \ _DO_OUTER_; \ } \ } \ } while (0) #define DAS_LOOP_TPN2R(_ISNZ_, _DO_INNER_, _DO_OUTER_) \ do { \ R_xlen_t d; \ if (ul == 'U') { \ d = PACKED_LENGTH(n) - 1; \ for (i = 0; i < n; px0 -= (d -= (++i))) { \ for (j = i; j < n; px0 += (++j)) \ if (_ISNZ_(*px0)) _DO_INNER_; \ _DO_OUTER_; \ } \ } else { \ d = -1; \ for (i = 0; i < n; px0 -= (d += n - (++i))) { \ for (j = 0; j <= i; px0 += n - (++j)) \ if (_ISNZ_(*px0)) _DO_INNER_; \ _DO_OUTER_; \ } \ } \ } while (0) #define DAS_LOOP_TPU2C(_ISNZ_, _DO_INNER_, _DO_OUTER_) \ do { \ if (ul == 'U') { \ for (j = 1; j < n; ++j) { \ ++px0; \ for (i = 0; i < j; ++i, ++px0) \ if (_ISNZ_(*px0)) _DO_INNER_; \ _DO_OUTER_; \ } \ } else { \ for (j = 0; j < n; ++j) { \ ++px0; \ for (i = j + 1; i < n; ++i, ++px0) \ if (_ISNZ_(*px0)) _DO_INNER_; \ _DO_OUTER_; \ } \ } \ } while (0) #define DAS_LOOP_TPU2R(_ISNZ_, _DO_INNER_, _DO_OUTER_) \ do { \ R_xlen_t d; \ if (ul == 'U') { \ d = PACKED_LENGTH(n - 1) - 1; \ for (i = 0; i < n; ++i) { \ for (j = i + 1; j < n; ++j) { \ px0 += j; \ if (_ISNZ_(*px0)) _DO_INNER_; \ } \ _DO_OUTER_; \ px0 -= (d -= i + 1); \ } \ } else { \ ++px0; \ d = -1; \ for (i = 1; i < n; ++i) { \ for (j = 0; j < i; ++j) { \ if (_ISNZ_(*px0)) _DO_INNER_; \ px0 += n - j - 1; \ } \ _DO_OUTER_; \ px0 -= (d += n - i); \ } \ } \ } while (0) #define DAS_VALID2T \ if (nnz > INT_MAX) \ error(_("attempt to construct %s with more than %s nonzero entries"), \ "sparseMatrix", "2^31-1") #define DAS_VALID2C \ do { DAS_VALID2T; else *(pp++) = (int) nnz; } while (0) #define DAS_VALID2R DAS_VALID2C /* First we loop over the _nontrivial part_ of the denseMatrix 'from', by row ('R' case) or by column ('C' and 'T' cases), counting the nonzero entries and filling the 'p' slot of the result accordingly ('C' and 'R' cases) ... */ int nprotect = 2; if (cl[2] != 'T') { int r = (cl[2] == 'C') ? n : m; PROTECT(p1 = allocVector(INTSXP, (R_xlen_t) r + 1)); ++nprotect; SET_SLOT(to, Matrix_pSym, p1); pp = INTEGER(p1); *(pp++) = 0; if (r > 0 && di != 'N' && ul == ((cl[2] == 'C') ? 'U' : 'L')) *(pp++) = 0; /* first row or column skipped in these loops */ } if (class[0] == 'n') DAS_SUBCASES(int, LOGICAL, HIDE, ISNZ_LOGICAL); else DAS_CASES(HIDE); if (cl[2] != 'R') { PROTECT(i1 = allocVector(INTSXP, nnz)); ++nprotect; SET_SLOT(to, Matrix_iSym, i1); pi = INTEGER(i1); } if (cl[2] != 'C') { PROTECT(j1 = allocVector(INTSXP, nnz)); ++nprotect; SET_SLOT(to, Matrix_jSym, j1); pj = INTEGER(j1); } #undef DAS_SUBSUBCASES #define DAS_SUBSUBCASES(_LOOP_C_, _LOOP_R_, _LOOP_T_, _MASK_, _ISNZ_) \ do { \ switch (repr) { \ case 'C': \ _LOOP_C_(_ISNZ_, \ do { \ *(pi++) = i; \ _MASK_(*(px1++) = *px0); \ } while (0), ); \ break; \ case 'R': \ _LOOP_R_(_ISNZ_, \ do { \ *(pj++) = j; \ _MASK_(*(px1++) = *px0); \ } while (0), ); \ break; \ case 'T': \ _LOOP_T_(_ISNZ_, \ do { \ *(pi++) = i; \ *(pj++) = j; \ _MASK_(*(px1++) = *px0); \ } while (0), ); \ break; \ default: \ break; \ } \ } while (0) /* Then we loop back over the same entries in order to fill the 'i', 'j', and 'x' slots of the result (whichever exist) ... */ if (class[0] == 'n') DAS_SUBCASES(int, LOGICAL, HIDE, ISNZ_LOGICAL); else { SEXP x1 = PROTECT(allocVector(TYPEOF(x0), nnz)); SET_SLOT(to, Matrix_xSym, x1); DAS_CASES(SHOW); UNPROTECT(1); /* x1 */ } #undef DAS_CASES #undef DAS_SUBCASES #undef DAS_SUBSUBCASES #undef DAS_VALID2C #undef DAS_VALID2R #undef DAS_VALID2T #undef DAS_LOOP_GEN2C #undef DAS_LOOP_GEN2R #undef DAS_LOOP_TRN2C #undef DAS_LOOP_TRN2R #undef DAS_LOOP_TRU2C #undef DAS_LOOP_TRU2R #undef DAS_LOOP_TPN2C #undef DAS_LOOP_TPN2R #undef DAS_LOOP_TPU2C #undef DAS_LOOP_TPU2R UNPROTECT(nprotect); return to; } /* as(, "[CRT]sparseMatrix") */ SEXP R_dense_as_sparse(SEXP from, SEXP repr) { static const char *valid[] = { VALID_DENSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); char repr_; if (TYPEOF(repr) != STRSXP || LENGTH(repr) < 1 || (repr = STRING_ELT(repr, 0)) == NA_STRING || ((repr_ = CHAR(repr)[0]) != 'C' && repr_ != 'R' && repr_ != 'T')) error(_("invalid '%s' to '%s'"), "repr", __func__); return dense_as_sparse(from, valid[ivalid], repr_); } SEXP diagonal_as_sparse(SEXP from, const char *class, char kind, char shape, char repr, char ul) { char cl[] = "...Matrix"; cl[0] = (kind == '.') ? class[0] : ((kind == ',') ? ((class[0] == 'z') ? 'z' : 'd') : kind); cl[1] = shape; cl[2] = repr; SEXP to = PROTECT(newObject(cl)); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int n = INTEGER(dim)[0]; if (n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); if (cl[1] == 's') set_symmetrized_DimNames(to, dimnames, -1); else SET_SLOT(to, Matrix_DimNamesSym, dimnames); UNPROTECT(1); /* dimnames */ if (cl[1] != 'g' && ul != 'U') { SEXP uplo = PROTECT(mkString("L")); SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ } SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); char di = *CHAR(STRING_ELT(diag, 0)); if (cl[1] == 't' && di != 'N') SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ if (cl[1] == 't' && di != 'N') { if (cl[2] != 'T') { SEXP p = PROTECT(allocVector(INTSXP, (R_xlen_t) n + 1)); SET_SLOT(to, Matrix_pSym, p); Matrix_memset(INTEGER(p), 0, (R_xlen_t) n + 1, sizeof(int)); UNPROTECT(1); /* p */ } UNPROTECT(1); /* to */ return to; } #define DAS_CASES(_MASK_) \ do { \ switch (cl[0]) { \ case 'l': \ DAS_LOOP(int, LOGICAL, _MASK_, ISNZ_LOGICAL, 1); \ break; \ case 'i': \ DAS_LOOP(int, INTEGER, _MASK_, ISNZ_INTEGER, 1); \ break; \ case 'd': \ DAS_LOOP(double, REAL, _MASK_, ISNZ_REAL, 1.0); \ break; \ case 'z': \ DAS_LOOP(Rcomplex, COMPLEX, _MASK_, ISNZ_COMPLEX, Matrix_zone); \ break; \ default: \ break; \ } \ } while (0) SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)); if (class[0] != cl[0]) { if (class[0] == 'n' && cl[0] == 'l') x0 = duplicate(x0); else x0 = coerceVector(x0, kindToType(cl[0])); if (class[0] == 'n') naToOne(x0); UNPROTECT(1); /* x0 */ PROTECT(x0); } int d, nnz; if (cl[2] != 'T') { SEXP p = PROTECT(allocVector(INTSXP, (R_xlen_t) n + 1)); SET_SLOT(to, Matrix_pSym, p); int *pp = INTEGER(p); *(pp++) = 0; if (di == 'N') { nnz = 0; #undef DAS_LOOP #define DAS_LOOP(_CTYPE_, _PTR_, _MASK_, _ISNZ_, _ONE_) \ do { \ _CTYPE_ *px0 = _PTR_(x0); \ for (d = 0; d < n; ++d) { \ if (_ISNZ_(*px0)) \ ++nnz; \ *(pp++) = nnz; \ ++px0; \ } \ } while (0) if (cl[0] == 'n') DAS_LOOP(int, LOGICAL, HIDE, ISNZ_LOGICAL, 1); else DAS_CASES(SHOW); } else { nnz = n; for (d = 1; d <= n; ++d) *(pp++) = d; } UNPROTECT(1); /* p */ } else { if (di == 'N') { nnz = 0; #undef DAS_LOOP #define DAS_LOOP(_CTYPE_, _PTR_, _MASK_, _ISNZ_, _ONE_) \ do { \ _CTYPE_ *px0 = _PTR_(x0); \ for (d = 0; d < n; ++d) { \ if (_ISNZ_(*px0)) \ ++nnz; \ ++px0; \ } \ } while (0) if (cl[0] == 'n') DAS_LOOP(int, LOGICAL, HIDE, ISNZ_LOGICAL, 1); else DAS_CASES(SHOW); } else nnz = n; } SEXP i1 = PROTECT(allocVector(INTSXP, nnz)); if (cl[2] != 'T') SET_SLOT(to, (cl[2] == 'C') ? Matrix_iSym : Matrix_jSym, i1); else { SET_SLOT(to, Matrix_iSym, i1); SET_SLOT(to, Matrix_jSym, i1); } int *pi1 = INTEGER(i1); #undef DAS_LOOP #define DAS_LOOP(_CTYPE_, _PTR_, _MASK_, _ISNZ_, _ONE_) \ do { \ _MASK_(_CTYPE_ *px1 = _PTR_(x1)); \ if (di == 'N') { \ _CTYPE_ *px0 = _PTR_(x0); \ for (d = 0; d < n; ++d) { \ if (_ISNZ_(*px0)) { \ *(pi1++) = d; \ _MASK_(*(px1++) = *px0); \ } \ ++px0; \ } \ } else { \ for (d = 0; d < n; ++d) { \ *(pi1++) = d; \ _MASK_(*(px1++) = _ONE_); \ } \ } \ } while (0) if (cl[0] == 'n') DAS_LOOP(int, LOGICAL, HIDE, ISNZ_LOGICAL, 1); else if (di == 'N' && nnz == n) { SET_SLOT(to, Matrix_xSym, x0); DAS_CASES(HIDE); } else { SEXP x1 = PROTECT(allocVector(TYPEOF(x0), nnz)); SET_SLOT(to, Matrix_xSym, x1); DAS_CASES(SHOW); UNPROTECT(1); /* x1 */ } UNPROTECT(3); /* i1, x0, to */ return to; } /* as(, ".[gst][CRT]Matrix") */ SEXP R_diagonal_as_sparse(SEXP from, SEXP kind, SEXP shape, SEXP repr, SEXP uplo) { static const char *valid[] = { VALID_DIAGONAL, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); char kind_; if (TYPEOF(kind) != STRSXP || LENGTH(kind) < 1 || (kind = STRING_ELT(kind, 0)) == NA_STRING || (kind_ = CHAR(kind)[0]) == '\0') error(_("invalid '%s' to '%s'"), "kind", __func__); char shape_; if (TYPEOF(shape) != STRSXP || LENGTH(shape) < 1 || (shape = STRING_ELT(shape, 0)) == NA_STRING || ((shape_ = CHAR(shape)[0]) != 'g' && shape_ != 's' && shape_ != 't')) error(_("invalid '%s' to '%s'"), "shape", __func__); char repr_; if (TYPEOF(repr) != STRSXP || LENGTH(repr) < 1 || (repr = STRING_ELT(repr, 0)) == NA_STRING || ((repr_ = CHAR(repr)[0]) != 'C' && repr_ != 'R' && repr_ != 'T')) error(_("invalid '%s' to '%s'"), "repr", __func__); char ul = 'U'; if (shape_ != 'g') { if (TYPEOF(uplo) != STRSXP || LENGTH(uplo) < 1 || (uplo = STRING_ELT(uplo, 0)) == NA_STRING || ((ul = *CHAR(uplo)) != 'U' && ul != 'L')) error(_("'%s' must be \"%s\" or \"%s\""), "uplo", "U", "L"); } return diagonal_as_sparse(from, valid[ivalid], kind_, shape_, repr_, ul); } SEXP index_as_sparse(SEXP from, const char *class, char kind, char repr) { SEXP margin = PROTECT(GET_SLOT(from, Matrix_marginSym)); int mg = INTEGER(margin)[0] - 1; UNPROTECT(1); /* margin */ char cl[] = ".g.Matrix"; cl[0] = (kind == '.') ? 'n' : ((kind == ',') ? 'd' : kind); cl[2] = (repr == '.') ? ((mg == 0) ? 'R' : 'C') : repr; SEXP to = PROTECT(newObject(cl)); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1], r = (mg == 0) ? m : n, s = (mg == 0) ? n : m; if (m != n || n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); SET_SLOT(to, Matrix_DimNamesSym, dimnames); UNPROTECT(1); /* dimnames */ SEXP perm = PROTECT(GET_SLOT(from, Matrix_permSym)); int *pperm = INTEGER(perm); if (cl[2] == 'T') { SEXP i = PROTECT(allocVector(INTSXP, r)), j = PROTECT(allocVector(INTSXP, r)); int k, *pi = INTEGER(i), *pj = INTEGER(j); for (k = 0; k < r; ++k) { *(pi++) = k; *(pj++) = *(pperm++) - 1; } SET_SLOT(to, Matrix_iSym, (mg == 0) ? i : j); SET_SLOT(to, Matrix_jSym, (mg == 0) ? j : i); } else if ((cl[2] == 'C') == (mg != 0)) { SEXP p = PROTECT(allocVector(INTSXP, (R_xlen_t) r + 1)), i = PROTECT(allocVector(INTSXP, r)); int k, *pp = INTEGER(p), *pi = INTEGER(i); for (k = 0; k < r; ++k) { *(pp++) = k; *(pi++) = *(pperm++) - 1; } *pp = r; SET_SLOT(to, Matrix_pSym, p); SET_SLOT(to, (mg != 0) ? Matrix_iSym : Matrix_jSym, i); } else { SEXP p = PROTECT(allocVector(INTSXP, (R_xlen_t) s + 1)); int k, *pp = INTEGER(p); Matrix_memset(pp, 0, (R_xlen_t) s + 1, sizeof(int)); for (k = 0; k < r; ++k) ++pp[pperm[k]]; for (k = 0; k < s; ++k) pp[k + 1] += pp[k]; SEXP j = PROTECT(allocVector(INTSXP, r)); int *pj = INTEGER(j), *work; Matrix_Calloc(work, s, int); Matrix_memcpy(work, pp, s, sizeof(int)); --work; for (k = 0; k < r; ++k) pj[work[pperm[k]]++] = k; ++work; Matrix_Free(work, s); SET_SLOT(to, Matrix_pSym, p); SET_SLOT(to, (mg != 0) ? Matrix_jSym : Matrix_iSym, j); } UNPROTECT(2); if (cl[0] != 'n') { SEXP x = PROTECT(allocVector(kindToType(cl[0]), r)); SET_SLOT(to, Matrix_xSym, x); #define IAS_SUBCASES(_CTYPE_, _PTR_, _ONE_) \ do { \ _CTYPE_ *px = _PTR_(x); \ for (int k = 0; k < r; ++k) \ *(px++) = _ONE_; \ } while (0) switch (cl[0]) { case 'l': IAS_SUBCASES(int, LOGICAL, 1); break; case 'i': IAS_SUBCASES(int, INTEGER, 1); break; case 'd': IAS_SUBCASES(double, REAL, 1.0); break; case 'z': IAS_SUBCASES(Rcomplex, COMPLEX, Matrix_zone); break; default: break; } UNPROTECT(1); /* x */ } #undef IAS_SUBCASES UNPROTECT(2); /* perm, to */ return to; } /* as(, ".g[CRT]Matrix") */ SEXP R_index_as_sparse(SEXP from, SEXP kind, SEXP repr) { static const char *valid[] = { "indMatrix", "pMatrix" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); char kind_; if (TYPEOF(kind) != STRSXP || LENGTH(kind) < 1 || (kind = STRING_ELT(kind, 0)) == NA_STRING || (kind_ = CHAR(kind)[0]) == '\0') error(_("invalid '%s' to '%s'"), "kind", __func__); char repr_; if (TYPEOF(repr) != STRSXP || LENGTH(repr) < 1 || (repr = STRING_ELT(repr, 0)) == NA_STRING || ((repr_ = CHAR(repr)[0]) != '.' && repr_ != 'C' && repr_ != 'R' && repr_ != 'T')) error(_("invalid '%s' to '%s'"), "repr", __func__); return index_as_sparse(from, valid[ivalid], kind_, repr_); } SEXP dense_as_kind(SEXP from, const char *class, char kind, int new) { if (kind == '.') kind = class[0]; else if (kind == ',') kind = (class[0] == 'z') ? 'z' : 'd'; if (kind == class[0]) return from; SEXPTYPE tt = kindToType(kind); char cl[] = "...Matrix"; cl[0] = kind; cl[1] = class[1]; cl[2] = class[2]; SEXP to = PROTECT(newObject(cl)); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; if (m != n || n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); SET_SLOT(to, Matrix_DimNamesSym, dimnames); UNPROTECT(1); /* dimnames */ if (class[1] != 'g') { SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); char ul = *CHAR(STRING_ELT(uplo, 0)); if (ul != 'U') SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ if (class[1] == 't') { SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); char di = *CHAR(STRING_ELT(diag, 0)); if (di != 'N') SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ } } PROTECT_INDEX pid; SEXP x; PROTECT_WITH_INDEX(x = GET_SLOT(from, Matrix_xSym), &pid); if (TYPEOF(x) != tt) { REPROTECT(x = coerceVector(x, tt), pid); if (class[0] == 'n') /* n->[idz] */ naToOne(x); } else if (new) { REPROTECT(x = duplicate(x), pid); if (class[0] == 'n') /* n->l */ naToOne(x); } else { if (class[0] == 'n') { /* n->l */ R_xlen_t i, len = XLENGTH(x); int *px = LOGICAL(x); for (i = 0; i < len; ++i, ++px) { if (*px == NA_LOGICAL) { REPROTECT(x = duplicate(x), pid); naToOne(x); break; } } } } SET_SLOT(to, Matrix_xSym, x); UNPROTECT(2); /* x, to */ return to; } /* as(, "[nlidz]Matrix") */ SEXP R_dense_as_kind(SEXP from, SEXP kind) { static const char *valid[] = { VALID_DENSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); char kind_; if (TYPEOF(kind) != STRSXP || LENGTH(kind) < 1 || (kind = STRING_ELT(kind, 0)) == NA_STRING || (kind_ = CHAR(kind)[0]) == '\0') error(_("invalid '%s' to '%s'"), "kind", __func__); return dense_as_kind(from, valid[ivalid], kind_, 0); } SEXP sparse_as_kind(SEXP from, const char *class, char kind) { if (kind == '.') kind = class[0]; else if (kind == ',') kind = (class[0] == 'z') ? 'z' : 'd'; if (kind == class[0]) return from; SEXPTYPE tt = kindToType(kind); if (class[2] == 'T' && (class[0] == 'n' || class[0] == 'l') && kind != 'n' && kind != 'l') { /* defined in ./sparse.c : */ SEXP Tsparse_aggregate(SEXP); from = Tsparse_aggregate(from); } PROTECT(from); char cl[] = "...Matrix"; cl[0] = kind; cl[1] = class[1]; cl[2] = class[2]; SEXP to = PROTECT(newObject(cl)); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; if (m != n || n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); SET_SLOT(to, Matrix_DimNamesSym, dimnames); UNPROTECT(1); /* dimnames */ if (class[1] != 'g') { SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); char ul = *CHAR(STRING_ELT(uplo, 0)); if (ul != 'U') SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ if (class[1] == 't') { SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); char di = *CHAR(STRING_ELT(diag, 0)); if (di != 'N') SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ } } R_xlen_t nnz = -1; if (class[2] != 'T') { SEXP p = PROTECT(GET_SLOT(from, Matrix_pSym)); SET_SLOT(to, Matrix_pSym, p); nnz = INTEGER(p)[XLENGTH(p) - 1]; UNPROTECT(1); /* p */ } if (class[2] != 'R') { SEXP i = PROTECT(GET_SLOT(from, Matrix_iSym)); SET_SLOT(to, Matrix_iSym, i); if (nnz < 1) nnz = XLENGTH(i); UNPROTECT(1); /* i */ } if (class[2] != 'C') { SEXP j = PROTECT(GET_SLOT(from, Matrix_jSym)); SET_SLOT(to, Matrix_jSym, j); UNPROTECT(1); /* j */ } if (class[0] == 'n') { SEXP x = PROTECT(allocVector(tt, nnz)); switch (tt) { case LGLSXP: { int *px = LOGICAL(x); while (nnz--) *(px++) = 1; break; } case INTSXP: { int *px = INTEGER(x); while (nnz--) *(px++) = 1; break; } case REALSXP: { double *px = REAL(x); while (nnz--) *(px++) = 1.0; break; } case CPLXSXP: { Rcomplex *px = COMPLEX(x); while (nnz--) *(px++) = Matrix_zone; break; } default: break; } SET_SLOT(to, Matrix_xSym, x); UNPROTECT(1); /* x */ } else if (kind != 'n') { PROTECT_INDEX pid; SEXP x; PROTECT_WITH_INDEX(x = GET_SLOT(from, Matrix_xSym), &pid); REPROTECT(x = coerceVector(x, tt), pid); SET_SLOT(to, Matrix_xSym, x); UNPROTECT(1); /* x */ } UNPROTECT(2); /* to, from */ return to; } /* as(, "[nlidz]Matrix") */ SEXP R_sparse_as_kind(SEXP from, SEXP kind) { static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); char kind_; if (TYPEOF(kind) != STRSXP || LENGTH(kind) < 1 || (kind = STRING_ELT(kind, 0)) == NA_STRING || (kind_ = CHAR(kind)[0]) == '\0') error(_("invalid '%s' to '%s'"), "kind", __func__); return sparse_as_kind(from, valid[ivalid], kind_); } SEXP diagonal_as_kind(SEXP from, const char *class, char kind) { if (kind == '.') kind = class[0]; else if (kind == ',') kind = (class[0] == 'z') ? 'z' : 'd'; if (kind == class[0]) return from; SEXPTYPE tt = kindToType(kind); char cl[] = ".diMatrix"; cl[0] = kind; SEXP to = PROTECT(newObject(cl)); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int n = INTEGER(dim)[0]; if (n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); SET_SLOT(to, Matrix_DimNamesSym, dimnames); UNPROTECT(1); /* dimnames */ SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); char di = *CHAR(STRING_ELT(diag, 0)); if (di != 'N') SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ if (di == 'N') { PROTECT_INDEX pid; SEXP x; PROTECT_WITH_INDEX(x = GET_SLOT(from, Matrix_xSym), &pid); if (TYPEOF(x) == tt) { if (class[0] == 'n') { /* n->l */ R_xlen_t i, len = XLENGTH(x); int *px = LOGICAL(x); for (i = 0; i < len; ++i, ++px) { if (*px == NA_LOGICAL) { REPROTECT(x = duplicate(x), pid); naToOne(x); break; } } } } else { REPROTECT(x = coerceVector(x, tt), pid); if (class[0] == 'n') /* n->[idz] */ naToOne(x); } SET_SLOT(to, Matrix_xSym, x); UNPROTECT(1); /* x */ } UNPROTECT(1); /* to */ return to; } /* as(, "[nlidz]Matrix") */ SEXP R_diagonal_as_kind(SEXP from, SEXP kind) { static const char *valid[] = { VALID_DIAGONAL, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); char kind_; if (TYPEOF(kind) != STRSXP || LENGTH(kind) < 1 || (kind = STRING_ELT(kind, 0)) == NA_STRING || (kind_ = CHAR(kind)[0]) == '\0') error(_("invalid '%s' to '%s'"), "kind", __func__); return diagonal_as_kind(from, valid[ivalid], kind_); } SEXP index_as_kind(SEXP from, const char *class, char kind) { return index_as_sparse(from, class, kind, '.'); } /* as(, "[nlidz]Matrix") */ SEXP R_index_as_kind(SEXP from, SEXP kind) { static const char *valid[] = { "indMatrix", "pMatrix" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); char kind_; if (TYPEOF(kind) != STRSXP || LENGTH(kind) < 1 || (kind = STRING_ELT(kind, 0)) == NA_STRING || (kind_ = CHAR(kind)[0]) == '\0') error(_("invalid '%s' to '%s'"), "kind", __func__); return index_as_kind(from, valid[ivalid], kind_); } SEXP dense_as_general(SEXP from, const char *class, int new) { if (class[1] == 'g') return from; char cl[] = ".geMatrix"; cl[0] = class[0]; SEXP to = PROTECT(newObject(cl)); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int n = INTEGER(dim)[0]; if (n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); if (class[1] != 's') SET_SLOT(to, Matrix_DimNamesSym, dimnames); else set_symmetrized_DimNames(to, dimnames, -1); UNPROTECT(1); /* dimnames */ SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); char ul = *CHAR(STRING_ELT(uplo, 0)), di = 'N'; UNPROTECT(1); /* uplo */ if (class[1] == 's') { SEXP factors = PROTECT(GET_SLOT(from, Matrix_factorsSym)); if (LENGTH(factors) > 0) SET_SLOT(to, Matrix_factorsSym, factors); UNPROTECT(1); /* factors */ } else { SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); di = *CHAR(STRING_ELT(diag, 0)); UNPROTECT(1); /* diag */ } if ((Matrix_int_fast64_t) n * n > R_XLEN_T_MAX) error(_("attempt to allocate vector of length exceeding %s"), "R_XLEN_T_MAX"); SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)), x1 = x0; int nprotect = 2; if (class[2] == 'p' || new) { PROTECT(x1 = allocVector(TYPEOF(x0), (R_xlen_t) n * n)); ++nprotect; } SET_SLOT(to, Matrix_xSym, x1); #define DAG_SUBCASES(_PREFIX_, _CTYPE_, _PTR_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \ if (class[2] == 'p') \ _PREFIX_ ## unpack1(px1, px0, n, ul, di); \ else if (new) \ Matrix_memcpy(px1, px0, (R_xlen_t) n * n, sizeof(_CTYPE_)); \ if (class[1] == 's') \ _PREFIX_ ## syforce2(px1, n, ul); \ else \ _PREFIX_ ## trforce2(px1, n, n, ul, di); \ } while (0) switch (class[0]) { case 'n': case 'l': DAG_SUBCASES(i, int, LOGICAL); break; case 'i': DAG_SUBCASES(i, int, INTEGER); break; case 'd': DAG_SUBCASES(d, double, REAL); break; case 'z': DAG_SUBCASES(z, Rcomplex, COMPLEX); break; default: break; } #undef DAG_CASES #undef DAG_SUBCASES UNPROTECT(nprotect); return to; } /* as(, "generaMatrix") */ SEXP R_dense_as_general(SEXP from) { static const char *valid[] = { VALID_DENSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); return dense_as_general(from, valid[ivalid], 1); } SEXP sparse_as_general(SEXP from, const char *class) { if (class[1] == 'g') return from; char cl[] = ".g.Matrix"; cl[0] = class[0]; cl[2] = class[2]; SEXP to = PROTECT(newObject(cl)); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int n = INTEGER(dim)[0]; if (n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); if (class[1] == 's') set_symmetrized_DimNames(to, dimnames, -1); else SET_SLOT(to, Matrix_DimNamesSym, dimnames); UNPROTECT(1); /* dimnames */ if (class[1] == 's') { SEXP factors = PROTECT(GET_SLOT(from, Matrix_factorsSym)); if (LENGTH(factors) > 0) SET_SLOT(to, Matrix_factorsSym, factors); UNPROTECT(1); /* factors */ } else { SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); char di = *CHAR(STRING_ELT(diag, 0)); UNPROTECT(1); /* diag */ if (di == 'N') { if (class[2] != 'T') { SEXP p = PROTECT(GET_SLOT(from, Matrix_pSym)); SET_SLOT(to, Matrix_pSym, p); UNPROTECT(1); /* p */ } if (class[2] != 'R') { SEXP i = PROTECT(GET_SLOT(from, Matrix_iSym)); SET_SLOT(to, Matrix_iSym, i); UNPROTECT(1); /* i */ } if (class[2] != 'C') { SEXP j = PROTECT(GET_SLOT(from, Matrix_jSym)); SET_SLOT(to, Matrix_jSym, j); UNPROTECT(1); /* j */ } if (class[0] != 'n') { SEXP x = PROTECT(GET_SLOT(from, Matrix_xSym)); SET_SLOT(to, Matrix_xSym, x); UNPROTECT(1); /* x */ } UNPROTECT(1); /* to */ return to; } } SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); char ul = *CHAR(STRING_ELT(uplo, 0)); UNPROTECT(1); /* uplo */ #define ASSIGN_COMPLEX_JJ(_X_, _Y_) \ do { _X_.r = _Y_.r; _X_.i = 0.0; } while (0) #define ASSIGN_COMPLEX_JI(_X_, _Y_) \ do { _X_.r = _Y_.r; _X_.i = -_Y_.i; } while (0) #define SAG_CASES \ do { \ switch (class[0]) { \ case 'l': \ SAG_SUBCASES(int, LOGICAL, SHOW, 1, \ ASSIGN_REAL, ASSIGN_REAL); \ break; \ case 'i': \ SAG_SUBCASES(int, INTEGER, SHOW, 1, \ ASSIGN_REAL, ASSIGN_REAL); \ break; \ case 'd': \ SAG_SUBCASES(double, REAL, SHOW, 1.0, \ ASSIGN_REAL, ASSIGN_REAL); \ break; \ case 'z': \ SAG_SUBCASES(Rcomplex, COMPLEX, SHOW, Matrix_zone, \ ASSIGN_COMPLEX_JJ, ASSIGN_COMPLEX_JI); \ break; \ default: \ break; \ } \ } while (0) if (class[2] != 'T') { SEXP iSym = (class[2] == 'C') ? Matrix_iSym : Matrix_jSym, p0 = PROTECT(GET_SLOT(from, Matrix_pSym)), p1 = PROTECT(allocVector(INTSXP, (R_xlen_t) n + 1)), i0 = PROTECT(GET_SLOT(from, iSym)); int j, k, kend, *pp0 = INTEGER(p0), *pp1 = INTEGER(p1), *pi0 = INTEGER(i0); SET_SLOT(to, Matrix_pSym, p1); pp0++; *(pp1++) = 0; if (class[1] == 's') { Matrix_memset(pp1, 0, n, sizeof(int)); for (j = 0, k = 0; j < n; ++j) { kend = pp0[j]; while (k < kend) { if (pi0[k] != j) ++pp1[pi0[k]]; ++k; } } for (j = 1; j < n; ++j) pp1[j] += pp1[j - 1]; if (pp1[n - 1] > INT_MAX - pp0[n - 1]) error(_("attempt to construct %s with more than %s nonzero entries"), "sparseMatrix", "2^31-1"); for (j = 0; j < n; ++j) pp1[j] += pp0[j]; } else { if (n > INT_MAX - pp0[n - 1]) error(_("attempt to construct %s with more than %s nonzero entries"), "sparseMatrix", "2^31-1"); for (j = 0; j < n; ++j) pp1[j] = pp0[j] + j + 1; } SEXP i1 = PROTECT(allocVector(INTSXP, pp1[n - 1])); int *pi1 = INTEGER(i1); SET_SLOT(to, iSym, i1); #undef SAG_SUBCASES #define SAG_SUBCASES(_CTYPE_, _PTR_, _MASK_, _ONE_, _ASSIGN_JJ_, _ASSIGN_JI_) \ do { \ _MASK_(_CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1)); \ if (class[1] == 's') { \ int *pp1_; \ Matrix_Calloc(pp1_, n, int); \ Matrix_memcpy(pp1_, pp1 - 1, n, sizeof(int)); \ for (j = 0, k = 0; j < n; ++j) { \ kend = pp0[j]; \ while (k < kend) { \ if (pi0[k] == j) { \ pi1[pp1_[j]] = pi0[k]; \ _MASK_(_ASSIGN_JJ_(px1[pp1_[j]], px0[k])); \ ++pp1_[j]; \ } else { \ pi1[pp1_[j]] = pi0[k]; \ _MASK_(px1[pp1_[j]] = px0[k]); \ ++pp1_[j]; \ pi1[pp1_[pi0[k]]] = j; \ _MASK_(_ASSIGN_JI_(px1[pp1_[pi0[k]]], px0[k])); \ ++pp1_[pi0[k]]; \ } \ ++k; \ } \ } \ Matrix_Free(pp1_, n); \ } else if (ul == ((class[2] == 'C') ? 'U' : 'L')) { \ for (j = 0, k = 0; j < n; ++j) { \ kend = pp0[j]; \ while (k < kend) { \ *(pi1++) = *(pi0++); \ _MASK_(*(px1++) = *(px0++)); \ ++k; \ } \ *(pi1++) = j; \ _MASK_(*(px1++) = _ONE_); \ } \ } else { \ for (j = 0, k = 0; j < n; ++j) { \ kend = pp0[j]; \ *(pi1++) = j; \ _MASK_(*(px1++) = _ONE_); \ while (k < kend) { \ *(pi1++) = *(pi0++); \ _MASK_(*(px1++) = *(px0++)); \ ++k; \ } \ } \ } \ } while (0) if (class[0] == 'n') SAG_SUBCASES(int, LOGICAL, HIDE, 1, ASSIGN_REAL, ASSIGN_REAL); else { SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)), x1 = PROTECT(allocVector(TYPEOF(x0), pp1[n - 1])); SET_SLOT(to, Matrix_xSym, x1); SAG_CASES; UNPROTECT(2); /* x1, x0 */ } } else { SEXP i0 = PROTECT(GET_SLOT(from, Matrix_iSym)), j0 = PROTECT(GET_SLOT(from, Matrix_jSym)); int *pi0 = INTEGER(i0), *pj0 = INTEGER(j0); R_xlen_t nnz0 = XLENGTH(i0), nnz1; if (class[1] == 's') { nnz1 = nnz0; for (R_xlen_t k = 0; k < nnz0; ++k) if (pi0[k] == pj0[k]) --nnz1; } else nnz1 = n; if (nnz1 > R_XLEN_T_MAX - nnz0) error(_("attempt to allocate vector of length exceeding %s"), "R_XLEN_T_MAX"); nnz1 += nnz0; SEXP i1 = PROTECT(allocVector(INTSXP, nnz1)), j1 = PROTECT(allocVector(INTSXP, nnz1)); int *pi1 = INTEGER(i1), *pj1 = INTEGER(j1); SET_SLOT(to, Matrix_iSym, i1); SET_SLOT(to, Matrix_jSym, j1); #undef SAG_SUBCASES #define SAG_SUBCASES(_CTYPE_, _PTR_, _MASK_, _ONE_, _ASSIGN_JJ_, _ASSIGN_JI_) \ do { \ _MASK_(_CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1)); \ if (class[1] == 's') { \ for (R_xlen_t k = 0; k < nnz0; ++k) { \ if (*pi0 == *pj0) { \ *(pi1++) = *pi0; \ *(pj1++) = *pj0; \ _MASK_(_ASSIGN_JJ_((*px1), (*px0))); \ _MASK_(++px1); \ } else { \ *(pi1++) = *pi0; \ *(pj1++) = *pj0; \ _MASK_(*px1 = *px0); \ _MASK_(++px1); \ *(pi1++) = *pj0; \ *(pj1++) = *pi0; \ _MASK_(_ASSIGN_JI_((*px1), (*px0))); \ _MASK_(++px1); \ } \ ++pi0; ++pj0; _MASK_(++px0); \ } \ } else { \ Matrix_memcpy(pi1, pi0, nnz0, sizeof(int)); \ Matrix_memcpy(pj1, pj0, nnz0, sizeof(int)); \ _MASK_(Matrix_memcpy(px1, px0, nnz0, sizeof(_CTYPE_))); \ pi1 += nnz0; \ pj1 += nnz0; \ _MASK_(px1 += nnz0); \ for (int d = 0; d < n; ++d) { \ *(pi1++) = *(pj1++) = d; \ _MASK_(*(px1++) = _ONE_); \ } \ } \ } while (0) if (class[0] == 'n') SAG_SUBCASES(int, LOGICAL, HIDE, 1, ASSIGN_REAL, ASSIGN_REAL); else { SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)), x1 = PROTECT(allocVector(TYPEOF(x0), nnz1)); SET_SLOT(to, Matrix_xSym, x1); SAG_CASES; UNPROTECT(2); /* x1, x0 */ } } #undef SAG_CASES #undef SAG_SUBCASES UNPROTECT(5); return to; } /* as(<[CRT]sparseMatrix>, "generalMatrix") */ SEXP R_sparse_as_general(SEXP from) { static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); return sparse_as_general(from, valid[ivalid]); } SEXP dense_as_unpacked(SEXP from, const char *class) { if (class[0] != 'p' && class[2] != 'p') return from; char cl[] = "...Matrix"; if (class[0] == 'p') { cl[0] = 'c'; cl[1] = 'o'; cl[2] = 'r'; } else if (class[1] == 'p') { cl[0] = 'd'; cl[1] = 'p'; cl[2] = 'o'; } else { cl[0] = class[0]; cl[1] = class[1]; cl[2] = (class[1] == 's') ? 'y' : 'r'; } SEXP to = PROTECT(newObject(cl)); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int n = INTEGER(dim)[0]; if ((Matrix_int_fast64_t) n * n > R_XLEN_T_MAX) error(_("attempt to allocate vector of length exceeding %s"), "R_XLEN_T_MAX"); if (n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); SET_SLOT(to, Matrix_DimNamesSym, dimnames); UNPROTECT(1); /* dimnames */ SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); char ul = *CHAR(STRING_ELT(uplo, 0)); if (ul != 'U') SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ if (cl[1] != 't') { SEXP factors = PROTECT(GET_SLOT(from, Matrix_factorsSym)); if (LENGTH(factors) > 0) SET_SLOT(to, Matrix_factorsSym, factors); UNPROTECT(1); /* factors */ if (cl[0] == 'c') { SEXP sd = PROTECT(GET_SLOT(from, Matrix_sdSym)); if (LENGTH(sd) > 0) SET_SLOT(to, Matrix_sdSym, sd); UNPROTECT(1); /* sd */ } } else { SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); char di = *CHAR(STRING_ELT(diag, 0)); if (di != 'N') SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ } SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)), x1 = PROTECT(allocVector(TYPEOF(x0), (R_xlen_t) n * n)); SET_SLOT(to, Matrix_xSym, x1); #define UNPACK(_PREFIX_, _CTYPE_, _PTR_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \ Matrix_memset(px1, 0, (R_xlen_t) n * n, sizeof(_CTYPE_)); \ _PREFIX_ ## unpack1(px1, px0, n, ul, 'N'); \ } while (0) switch (cl[0]) { case 'n': case 'l': UNPACK(i, int, LOGICAL); break; case 'i': UNPACK(i, int, INTEGER); break; case 'c': case 'd': UNPACK(d, double, REAL); break; case 'z': UNPACK(z, Rcomplex, COMPLEX); break; default: break; } #undef UNPACK UNPROTECT(3); /* x1, x0, to */ return to; } /* as(, "unpackedMatrix") */ SEXP R_dense_as_unpacked(SEXP from) { static const char *valid[] = { "dpoMatrix", "dppMatrix", "corMatrix", "pcorMatrix", VALID_DENSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); return dense_as_unpacked(from, valid[ivalid]); } SEXP dense_as_packed(SEXP from, const char *class, char ul, char di) { if (class[0] == 'p' || class[2] == 'p') return from; char cl_[] = "p...Matrix", *cl = ((char *) &cl_) + 1; int ge = 0; if (class[0] == 'c') { cl[0] = 'c'; cl[1] = 'o'; cl[2] = 'r'; } else if (class[1] == 'p') { cl[0] = 'd'; cl[1] = 'p'; cl[2] = 'p'; } else { ge = class[1] == 'g'; cl[0] = class[0]; cl[1] = (!ge) ? class[1] : ((di == '\0') ? 's' : 't'); cl[2] = 'p'; } SEXP to = PROTECT(newObject((class[0] == 'c') ? cl - 1 : cl)); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), n = pdim[0]; if (pdim[1] != n) error(_("attempt to pack non-square matrix")); if (n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); SET_SLOT(to, Matrix_DimNamesSym, dimnames); UNPROTECT(1); /* dimnames */ if (ge) { if (ul != 'U') { SEXP uplo = PROTECT(mkString("L")); SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ } if (cl[1] == 't' && di != 'N') { SEXP diag = PROTECT(mkString("U")); SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ } } else { SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); ul = *CHAR(STRING_ELT(uplo, 0)); if (ul != 'U') SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ if (cl[1] == 't') { SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); di = *CHAR(STRING_ELT(diag, 0)); if (di != 'N') SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ } else { SEXP factors = PROTECT(GET_SLOT(from, Matrix_factorsSym)); if (LENGTH(factors) > 0) SET_SLOT(to, Matrix_factorsSym, factors); UNPROTECT(1); /* factors */ if (cl[0] == 'c') { SEXP sd = PROTECT(GET_SLOT(from, Matrix_sdSym)); if (LENGTH(sd) > 0) SET_SLOT(to, Matrix_sdSym, sd); UNPROTECT(1); /* sd */ } } } SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)), x1 = PROTECT(allocVector(TYPEOF(x0), PACKED_LENGTH(n))); SET_SLOT(to, Matrix_xSym, x1); #define PACK(_PREFIX_, _CTYPE_, _PTR_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \ _PREFIX_ ## pack2(px1, px0, n, ul, 'N'); \ } while (0) switch (cl[0]) { case 'n': case 'l': PACK(i, int, LOGICAL); break; case 'i': PACK(i, int, INTEGER); break; case 'c': case 'd': PACK(d, double, REAL); break; case 'z': PACK(z, Rcomplex, COMPLEX); break; default: break; } #undef PACK UNPROTECT(3); /* x1, x0, to */ return to; } /* as(, "packedMatrix") */ SEXP R_dense_as_packed(SEXP from, SEXP uplo, SEXP diag) { static const char *valid[] = { "dpoMatrix", "dppMatrix", "corMatrix", "pcorMatrix", VALID_DENSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); char ul = 'U', di = '\0'; if (valid[ivalid][1] == 'g') { if (TYPEOF(uplo) != STRSXP || LENGTH(uplo) < 1 || (uplo = STRING_ELT(uplo, 0)) == NA_STRING || ((ul = *CHAR(uplo)) != 'U' && ul != 'L')) error(_("'%s' must be \"%s\" or \"%s\""), "uplo", "U", "L"); if (diag != R_NilValue) { if (TYPEOF(diag) != STRSXP || LENGTH(diag) < 1 || (diag = STRING_ELT(diag, 0)) == NA_STRING || ((di = *CHAR(diag)) != 'N' && ul != 'U')) error(_("'%s' must be \"%s\" or \"%s\""), "diag", "N", "U"); } } return dense_as_packed(from, valid[ivalid], ul, di); } void trans(SEXP p0, SEXP i0, SEXP x0, SEXP p1, SEXP i1, SEXP x1, int m, int n) { int *pp0 = INTEGER(p0), *pp1 = INTEGER(p1), *pi0 = INTEGER(i0), *pi1 = INTEGER(i1), i, j, k, kend, nnz = pp0[n]; Matrix_memset(pp1, 0, (R_xlen_t) m + 1, sizeof(int)); ++pp0; ++pp1; for (k = 0; k < nnz; ++k) ++pp1[pi0[k]]; for (i = 0; i < m; ++i) pp1[i] += pp1[i - 1]; int *pp1_; Matrix_Calloc(pp1_, m, int); Matrix_memcpy(pp1_, pp1 - 1, m, sizeof(int)); #define TRANS_LOOP(_CTYPE_, _PTR_, _MASK_) \ do { \ _MASK_(_CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1)); \ for (j = 0, k = 0; j < n; ++j) { \ kend = pp0[j]; \ while (k < kend) { \ i = pi0[k]; \ pi1[pp1_[i]] = j; \ _MASK_(px1[pp1_[i]] = px0[k]); \ ++pp1_[i]; \ ++k; \ } \ } \ } while (0) if (!(x0 && x1) || TYPEOF(x0) != TYPEOF(x1)) TRANS_LOOP(int, LOGICAL, HIDE); else { switch (TYPEOF(x0)) { case LGLSXP: TRANS_LOOP(int, LOGICAL, SHOW); break; case INTSXP: TRANS_LOOP(int, INTEGER, SHOW); break; case REALSXP: TRANS_LOOP(double, REAL, SHOW); break; case CPLXSXP: TRANS_LOOP(Rcomplex, COMPLEX, SHOW); break; default: break; } } #undef TRANS_LOOP Matrix_Free(pp1_, m); return; } void tsort(SEXP i0, SEXP j0, SEXP x0, SEXP *p1, SEXP *i1, SEXP *x1, int m, int n) { R_xlen_t nnz0 = XLENGTH(i0), nnz1 = 0; if (nnz0 > INT_MAX) error(_("unable to aggregate %s with '%s' and '%s' slots of length exceeding %s"), "TsparseMatrix", "i", "j", "2^31-1"); /* FIXME: test for overflow and throw error only in that case */ PROTECT(*p1 = allocVector(INTSXP, (R_xlen_t) n + 1)); int *pi0 = INTEGER(i0), *pj0 = INTEGER(j0), *pp1 = INTEGER(*p1), *pi1, i, j, r = (m < n) ? n : m; R_xlen_t k, kstart, kend, kend_; *(pp1++) = 0; int *workA, *workB, *workC, *pj_; size_t lwork = (size_t) m + r + m + nnz0; Matrix_Calloc(workA, lwork, int); workB = workA + m; workC = workB + r; pj_ = workC + m; #define TSORT_LOOP(_CTYPE_, _PTR_, _MASK_, _INCREMENT_) \ do { \ _MASK_(_CTYPE_ *px0 = _PTR_(x0), *px1, *px_); \ _MASK_(Matrix_Calloc(px_, nnz0, _CTYPE_)); \ \ /* 1. Tabulate column indices in workA[i] */ \ \ for (k = 0; k < nnz0; ++k) \ ++workA[pi0[k]]; \ \ /* 2. Compute cumulative sum in workA[i], copying to workB[i] */ \ /* */ \ /* workA[i]: number of column indices listed for row i, */ \ /* incl. duplicates */ \ \ for (i = 1; i < m; ++i) \ workA[i] += (workB[i] = workA[i - 1]); \ \ /* 3. Group column indices and data by row in pj_[k], px_[k] */ \ /* */ \ /* workA[i]: number of column indices listed for row <= i, */ \ /* incl. duplicates */ \ /* workB[i]: number of column indices listed for row < i, */ \ /* incl. duplicates */ \ \ for (k = 0; k < nnz0; ++k) { \ pj_[workB[pi0[k]]] = pj0[k] ; \ _MASK_(px_[workB[pi0[k]]] = px0[k]); \ ++workB[pi0[k]]; \ } \ \ /* 4. Gather _unique_ column indices at the front of each group, */ \ /* aggregating data accordingly; record in workC[i] where */ \ /* the unique column indices stop and the duplicates begin */ \ /* */ \ /* workB[.]: unused */ \ /* pj_[k]: column indices grouped by row, */ \ /* incl. duplicates, unsorted */ \ /* px_[k]: corresponding data */ \ \ k = 0; \ for (j = 0; j < n; ++j) \ workB[j] = -1; \ for (i = 0; i < m; ++i) { \ kstart = kend_ = k; \ kend = workA[i]; \ while (k < kend) { \ if (workB[pj_[k]] < kstart) { \ /* Have not yet seen this column index */ \ workB[pj_[k]] = kend_; \ pj_[kend_] = pj_[k] ; \ _MASK_(px_[kend_] = px_[k]); \ ++kend_; \ } else { \ /* Have already seen this column index */ \ _MASK_(_INCREMENT_(px_[workB[pj_[k]]], px_[k])); \ } \ ++k; \ } \ workC[i] = kend_; \ nnz1 += kend_ - kstart; \ } \ \ /* 5. Tabulate _unique_ column indices in workB[j] */ \ /* */ \ /* workC[i]: pointer to first non-unique column index in row i */ \ /* pi_[k]: column indices grouped by row, */ \ /* with unique indices in front, */ \ /* i.e., in positions workA[i - 1] <= k < workC[i] */ \ /* px_[k]: corresponding data, "cumulated" appropriately */ \ \ k = 0; \ Matrix_memset(workB, 0, n, sizeof(int)); \ for (i = 0; i < m; ++i) { \ kend_ = workC[i]; \ while (k < kend_) { \ ++workB[pj_[k]]; \ ++k; \ } \ k = workA[i]; \ } \ \ /* 6. Compute cumulative sum in pp1[j], copying to workB[j] */ \ /* */ \ /* workB[j]: number of nonzero elements in column j */ \ \ for (j = 0; j < n; ++j) { \ pp1[j] = pp1[j - 1] + workB[j]; \ workB[j] = pp1[j - 1]; \ } \ \ PROTECT(*i1 = allocVector( INTSXP, nnz1)) ; \ _MASK_(PROTECT(*x1 = allocVector(TYPEOF(x0), nnz1))); \ pi1 = INTEGER(*i1) ; \ _MASK_(px1 = _PTR_(*x1)); \ \ /* 7. Pop unique (i,j) pairs from the unsorted stacks 0 <= i < m */ \ /* onto new stacks 0 <= j < n, which will be sorted */ \ /* */ \ /* workB[j]: number of nonzero elements in columns < j */ \ /* pp1[j]: number of nonzero elements in columns <= j */ \ \ k = 0; \ for (i = 0; i < m; ++i) { \ kend_ = workC[i]; \ while (k < kend_) { \ pi1[workB[pj_[k]]] = i; \ _MASK_(px1[workB[pj_[k]]] = px_[k]); \ ++workB[pj_[k]]; \ ++k; \ } \ k = workA[i]; \ } \ \ _MASK_(Matrix_Free(px_, nnz0)); \ _MASK_(UNPROTECT(1)); /* *px1 */ \ UNPROTECT(1) ; /* *pi1 */ \ } while (0) if (!x0) TSORT_LOOP(int, LOGICAL, HIDE, INCREMENT_PATTERN); else { switch (TYPEOF(x0)) { case LGLSXP: TSORT_LOOP(int, LOGICAL, SHOW, INCREMENT_LOGICAL); break; case INTSXP: TSORT_LOOP(int, INTEGER, SHOW, INCREMENT_INTEGER); break; case REALSXP: TSORT_LOOP(double, REAL, SHOW, INCREMENT_REAL); break; case CPLXSXP: TSORT_LOOP(Rcomplex, COMPLEX, SHOW, INCREMENT_COMPLEX); break; default: break; } } #undef TSORT_LOOP Matrix_Free(workA, lwork); UNPROTECT(1); /* *p1 */ return; } void taggr(SEXP i0, SEXP j0, SEXP x0, SEXP *i1, SEXP *j1, SEXP *x1, int m, int n) { R_xlen_t nnz0 = XLENGTH(i0), nnz1 = 0; if (nnz0 > INT_MAX) error(_("unable to aggregate %s with '%s' and '%s' slots of length exceeding %s"), "TsparseMatrix", "i", "j", "2^31-1"); /* FIXME: test for overflow and throw error only in that case */ int *pi0 = INTEGER(i0), *pj0 = INTEGER(j0), *pi1, *pj1, i, j, r = (m < n) ? n : m; R_xlen_t k, kstart, kend, kend_; int *workA, *workB, *workC, *pj_; size_t lwork = (size_t) m + r + m + nnz0; Matrix_Calloc(workA, lwork, int); workB = workA + m; workC = workB + r; pj_ = workC + m; #define TAGGR_LOOP(_CTYPE_, _PTR_, _MASK_, _INCREMENT_) \ do { \ _MASK_(_CTYPE_ *px0 = _PTR_(x0), *px1, *px_); \ _MASK_(Matrix_Calloc(px_, nnz0, _CTYPE_)); \ \ /* 1. Tabulate column indices in workA[i] */ \ \ for (k = 0; k < nnz0; ++k) \ ++workA[pi0[k]]; \ \ /* 2. Compute cumulative sum in workA[i], copying to workB[i] */ \ /* */ \ /* workA[i]: number of column indices listed for row i, */ \ /* incl. duplicates */ \ \ for (i = 1; i < m; ++i) \ workA[i] += (workB[i] = workA[i - 1]); \ \ /* 3. Group column indices and data by row in pj_[k], px_[k] */ \ /* */ \ /* workA[i]: number of column indices listed for row <= i, */ \ /* incl. duplicates */ \ /* workB[i]: number of column indices listed for row < i, */ \ /* incl. duplicates */ \ \ for (k = 0; k < nnz0; ++k) { \ pj_[workB[pi0[k]]] = pj0[k] ; \ _MASK_(px_[workB[pi0[k]]] = px0[k]); \ ++workB[pi0[k]]; \ } \ \ /* 4. Gather _unique_ column indices at the front of each group, */ \ /* aggregating data accordingly; record in workC[i] where */ \ /* the unique column indices stop and the duplicates begin */ \ /* */ \ /* workB[.]: unused */ \ /* pj_[k]: column indices grouped by row, */ \ /* incl. duplicates, unsorted */ \ /* px_[k]: corresponding data */ \ \ k = 0; \ for (j = 0; j < n; ++j) \ workB[j] = -1; \ for (i = 0; i < m; ++i) { \ kstart = kend_ = k; \ kend = workA[i]; \ while (k < kend) { \ if (workB[pj_[k]] < kstart) { \ /* Have not yet seen this column index */ \ workB[pj_[k]] = kend_; \ pj_[kend_] = pj_[k] ; \ _MASK_(px_[kend_] = px_[k]); \ ++kend_; \ } else { \ /* Have already seen this column index */ \ _MASK_(_INCREMENT_(px_[workB[pj_[k]]], px_[k])); \ } \ ++k; \ } \ workC[i] = kend_; \ nnz1 += kend_ - kstart; \ } \ if (nnz1 != nnz0) { \ PROTECT(*i1 = allocVector( INTSXP, nnz1)) ; \ PROTECT(*j1 = allocVector( INTSXP, nnz1)) ; \ _MASK_(PROTECT(*x1 = allocVector(TYPEOF(x0), nnz1))); \ pi1 = INTEGER(*i1) ; \ pj1 = INTEGER(*j1) ; \ _MASK_(px1 = _PTR_(*x1)); \ \ k = 0; \ for (i = 0; i < m; ++i) { \ kend_ = workC[i]; \ while (k < kend_) { \ *(pi1++) = i ; \ *(pj1++) = pj_[k] ; \ _MASK_(*(px1++) = px_[k]); \ ++k; \ } \ k = workA[i]; \ } \ \ _MASK_(UNPROTECT(1)); /* *px1 */ \ UNPROTECT(2) ; /* *pj1, *px1 */ \ } \ _MASK_(Matrix_Free(px_, nnz0)); \ } while (0) if (!x0) TAGGR_LOOP(int, LOGICAL, HIDE, ); else { switch (TYPEOF(x0)) { case LGLSXP: TAGGR_LOOP(int, LOGICAL, SHOW, INCREMENT_LOGICAL); break; case INTSXP: TAGGR_LOOP(int, INTEGER, SHOW, INCREMENT_INTEGER); break; case REALSXP: TAGGR_LOOP(double, REAL, SHOW, INCREMENT_REAL); break; case CPLXSXP: TAGGR_LOOP(Rcomplex, COMPLEX, SHOW, INCREMENT_COMPLEX); break; default: break; } } #undef TAGGR_LOOP Matrix_Free(workA, lwork); return; } SEXP sparse_as_Csparse(SEXP from, const char *class) { if (class[2] == 'C') return from; char cl[] = "..CMatrix"; cl[0] = class[0]; cl[1] = class[1]; SEXP to = PROTECT(newObject(cl)); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; if (m != n || n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); SET_SLOT(to, Matrix_DimNamesSym, dimnames); UNPROTECT(1); /* dimnames */ if (class[1] != 'g') { SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); char ul = *CHAR(STRING_ELT(uplo, 0)); if (ul != 'U') SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ } if (class[1] == 't') { SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); char di = *CHAR(STRING_ELT(diag, 0)); if (di != 'N') SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ } else { SEXP factors = PROTECT(GET_SLOT(from, Matrix_factorsSym)); if (LENGTH(factors) > 0) SET_SLOT(to, Matrix_factorsSym, factors); UNPROTECT(1); /* factors */ } if (class[2] == 'R') { SEXP p0 = PROTECT(GET_SLOT(from, Matrix_pSym)), j0 = PROTECT(GET_SLOT(from, Matrix_jSym)), p1 = PROTECT(allocVector(INTSXP, (R_xlen_t) n + 1)), i1 = PROTECT(allocVector(INTSXP, INTEGER(p0)[m])); SET_SLOT(to, Matrix_pSym, p1); SET_SLOT(to, Matrix_iSym, i1); if (class[0] == 'n') trans(p0, j0, NULL, p1, i1, NULL, n, m); else { SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)), x1 = PROTECT(allocVector(TYPEOF(x0), INTEGER(p0)[m])); SET_SLOT(to, Matrix_xSym, x1); trans(p0, j0, x0, p1, i1, x1, n, m); UNPROTECT(2); /* x1, x0 */ } UNPROTECT(4); /* i1, p1, j0, p0 */ } else { SEXP i0 = PROTECT(GET_SLOT(from, Matrix_iSym)), j0 = PROTECT(GET_SLOT(from, Matrix_jSym)), p1 = NULL, i1 = NULL; if (class[0] == 'n') { tsort(i0, j0, NULL, &p1, &i1, NULL, m, n); PROTECT(p1); PROTECT(i1); SET_SLOT(to, Matrix_pSym, p1); SET_SLOT(to, Matrix_iSym, i1); UNPROTECT(2); /* i1, p1 */ } else { SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)), x1 = NULL; tsort(i0, j0, x0, &p1, &i1, &x1, m, n); PROTECT(p1); PROTECT(i1); PROTECT(x1); SET_SLOT(to, Matrix_pSym, p1); SET_SLOT(to, Matrix_iSym, i1); SET_SLOT(to, Matrix_xSym, x1); UNPROTECT(4); /* x1, i1, p1, x0 */ } UNPROTECT(2); /* j0, i0 */ } UNPROTECT(1); /* to */ return to; } /* as(<[CRT]sparseMatrix>, "CsparseMatrix") */ SEXP R_sparse_as_Csparse(SEXP from) { static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); return sparse_as_Csparse(from, valid[ivalid]); } SEXP sparse_as_Rsparse(SEXP from, const char *class) { if (class[2] == 'R') return from; char cl[] = "..RMatrix"; cl[0] = class[0]; cl[1] = class[1]; SEXP to = PROTECT(newObject(cl)); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; if (m != n || n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); SET_SLOT(to, Matrix_DimNamesSym, dimnames); UNPROTECT(1); /* dimnames */ if (class[1] != 'g') { SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); char ul = *CHAR(STRING_ELT(uplo, 0)); if (ul != 'U') SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ } if (class[1] == 't') { SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); char di = *CHAR(STRING_ELT(diag, 0)); if (di != 'N') SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ } else { SEXP factors = PROTECT(GET_SLOT(from, Matrix_factorsSym)); if (LENGTH(factors) > 0) SET_SLOT(to, Matrix_factorsSym, factors); UNPROTECT(1); /* factors */ } if (class[2] == 'C') { SEXP p0 = PROTECT(GET_SLOT(from, Matrix_pSym)), i0 = PROTECT(GET_SLOT(from, Matrix_iSym)), p1 = PROTECT(allocVector(INTSXP, (R_xlen_t) m + 1)), j1 = PROTECT(allocVector(INTSXP, INTEGER(p0)[n])); SET_SLOT(to, Matrix_pSym, p1); SET_SLOT(to, Matrix_jSym, j1); if (class[0] == 'n') trans(p0, i0, NULL, p1, j1, NULL, m, n); else { SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)), x1 = PROTECT(allocVector(TYPEOF(x0), INTEGER(p0)[n])); SET_SLOT(to, Matrix_xSym, x1); trans(p0, i0, x0, p1, j1, x1, m, n); UNPROTECT(2); /* x1, x0 */ } UNPROTECT(4); /* j1, p1, i0, p0 */ } else { SEXP i0 = PROTECT(GET_SLOT(from, Matrix_iSym)), j0 = PROTECT(GET_SLOT(from, Matrix_jSym)), p1 = NULL, j1 = NULL; if (class[0] == 'n') { tsort(j0, i0, NULL, &p1, &j1, NULL, n, m); PROTECT(p1); PROTECT(j1); SET_SLOT(to, Matrix_pSym, p1); SET_SLOT(to, Matrix_jSym, j1); UNPROTECT(2); /* j1, p1 */ } else { SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)), x1 = NULL; tsort(j0, i0, x0, &p1, &j1, &x1, n, m); PROTECT(p1); PROTECT(j1); PROTECT(x1); SET_SLOT(to, Matrix_pSym, p1); SET_SLOT(to, Matrix_jSym, j1); SET_SLOT(to, Matrix_xSym, x1); UNPROTECT(4); /* x1, j1, p1, x0 */ } UNPROTECT(2); /* j0, i0 */ } UNPROTECT(1); /* to */ return to; } /* as(<[CRT]sparseMatrix>, "RsparseMatrix") */ SEXP R_sparse_as_Rsparse(SEXP from) { static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); return sparse_as_Rsparse(from, valid[ivalid]); } SEXP sparse_as_Tsparse(SEXP from, const char *class) { if (class[2] == 'T') return from; char cl[] = "..TMatrix"; cl[0] = class[0]; cl[1] = class[1]; SEXP to = PROTECT(newObject(cl)); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; if (m != n || n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); SET_SLOT(to, Matrix_DimNamesSym, dimnames); UNPROTECT(1); /* dimnames */ if (class[1] != 'g') { SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); char ul = *CHAR(STRING_ELT(uplo, 0)); if (ul != 'U') SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ } if (class[1] == 't') { SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); char di = *CHAR(STRING_ELT(diag, 0)); if (di != 'N') SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ } else { SEXP factors = PROTECT(GET_SLOT(from, Matrix_factorsSym)); if (LENGTH(factors) > 0) SET_SLOT(to, Matrix_factorsSym, factors); UNPROTECT(1); /* factors */ } SEXP iSym = (class[2] == 'C') ? Matrix_iSym : Matrix_jSym, jSym = (class[2] == 'C') ? Matrix_jSym : Matrix_iSym, p = PROTECT(GET_SLOT(from, Matrix_pSym)), i = PROTECT(GET_SLOT(from, iSym)); int *pp = INTEGER(p), *pi, r = (class[2] == 'C') ? n : m, nnz = pp[r]; if (XLENGTH(i) == nnz) { SET_SLOT(to, iSym, i); UNPROTECT(1); /* i */ } else { SEXP i_ = PROTECT(allocVector(INTSXP, nnz)); Matrix_memcpy(INTEGER(i_), INTEGER(i), nnz, sizeof(int)); SET_SLOT(to, iSym, i_); UNPROTECT(2); /* i_, i */ } PROTECT(i = allocVector(INTSXP, nnz)); SET_SLOT(to, jSym, i); pi = INTEGER(i); ++pp; int j, k, kend; for (j = 0, k = 0; j < r; ++j) { kend = pp[j]; while (k < kend) pi[k++] = j; } UNPROTECT(2); /* i, p */ if (class[0] != 'n') { SEXP x = PROTECT(GET_SLOT(from, Matrix_xSym)); if (XLENGTH(x) == nnz) SET_SLOT(to, Matrix_xSym, x); else { SEXP x_ = PROTECT(allocVector(TYPEOF(x), nnz)); SET_SLOT(to, Matrix_xSym, x_); switch (class[0]) { case 'l': Matrix_memcpy(LOGICAL(x_), LOGICAL(x), nnz, sizeof(int)); break; case 'i': Matrix_memcpy(INTEGER(x_), INTEGER(x), nnz, sizeof(int)); break; case 'd': Matrix_memcpy(REAL(x_), REAL(x), nnz, sizeof(double)); break; case 'z': Matrix_memcpy(COMPLEX(x_), COMPLEX(x), nnz, sizeof(Rcomplex)); break; default: break; } UNPROTECT(1); /* x_ */ } UNPROTECT(1); /* x */ } UNPROTECT(1); /* to */ return to; } /* as(<[CRT]sparseMatrix>, "TsparseMatrix") */ SEXP R_sparse_as_Tsparse(SEXP from) { static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); return sparse_as_Tsparse(from, valid[ivalid]); } /* as(, "vector") */ SEXP R_Matrix_as_vector(SEXP from) { static const char *valid[] = { VALID_NONVIRTUAL_MATRIX, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); const char *cl = valid[ivalid + VALID_NONVIRTUAL_SHIFT(ivalid, 1)]; SEXP to = NULL; PROTECT_INDEX pid; PROTECT_WITH_INDEX(from, &pid); switch (cl[2]) { case 'e': to = GET_SLOT(from, Matrix_xSym); if (cl[0] == 'n') { R_xlen_t len = XLENGTH(to); int *px = LOGICAL(to); while (len--) if (*(px++) == NA_LOGICAL) { PROTECT(to); to = duplicate(to); UNPROTECT(1); break; } } break; case 'y': case 'r': case 'p': REPROTECT(from = dense_as_general(from, cl, 1), pid); to = GET_SLOT(from, Matrix_xSym); break; case 'C': case 'R': case 'T': REPROTECT(from = sparse_as_dense(from, cl, 0), pid); REPROTECT(from = dense_as_general(from, cl, 0), pid); to = GET_SLOT(from, Matrix_xSym); break; case 'i': REPROTECT(from = diagonal_as_dense(from, cl, '.', 'g', 0, '\0'), pid); to = GET_SLOT(from, Matrix_xSym); break; case 'd': REPROTECT(from = index_as_dense(from, cl, 'n'), pid); to = GET_SLOT(from, Matrix_xSym); break; default: break; } switch (cl[2]) { case 'e': case 'y': case 'r': case 'p': case 'i': if (cl[0] == 'n') { PROTECT(to); naToOne(to); UNPROTECT(1); } break; default: break; } UNPROTECT(1); /* from */ return to; } /* as(, "matrix") */ SEXP R_Matrix_as_matrix(SEXP from) { static const char *valid[] = { VALID_NONVIRTUAL_MATRIX, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); const char *cl = valid[ivalid + VALID_NONVIRTUAL_SHIFT(ivalid, 1)]; SEXP to = NULL; PROTECT_INDEX pid; PROTECT_WITH_INDEX(from, &pid); switch (cl[2]) { case 'e': PROTECT(to = GET_SLOT(from, Matrix_xSym)); to = duplicate(to); UNPROTECT(1); break; case 'y': case 'r': case 'p': REPROTECT(from = dense_as_general(from, cl, 1), pid); to = GET_SLOT(from, Matrix_xSym); break; case 'C': case 'R': case 'T': REPROTECT(from = sparse_as_dense(from, cl, 0), pid); REPROTECT(from = dense_as_general(from, cl, 0), pid); to = GET_SLOT(from, Matrix_xSym); break; case 'i': REPROTECT(from = diagonal_as_dense(from, cl, '.', 'g', 0, '\0'), pid); to = GET_SLOT(from, Matrix_xSym); break; case 'd': REPROTECT(from = index_as_dense(from, cl, 'n'), pid); to = GET_SLOT(from, Matrix_xSym); break; default: break; } PROTECT(to); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); setAttrib(to, R_DimSymbol, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); if (!DimNames_is_trivial(dimnames)) setAttrib(to, R_DimNamesSymbol, dimnames); UNPROTECT(1); /* dimnames */ switch (cl[2]) { case 'e': case 'y': case 'r': case 'p': case 'i': if (cl[0] == 'n') naToOne(to); break; default: break; } UNPROTECT(2); /* to, from */ return to; } /* as(, "unpackedMatrix") */ SEXP R_Matrix_as_unpacked(SEXP from) { static const char *valid[] = { VALID_NONVIRTUAL_MATRIX, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); const char *cl = valid[ivalid + VALID_NONVIRTUAL_SHIFT(ivalid, 1)]; switch (cl[2]) { case 'e': case 'y': case 'r': return from; case 'p': return dense_as_unpacked(from, valid[ivalid]); case 'C': case 'R': case 'T': return sparse_as_dense(from, cl, 0); case 'i': return diagonal_as_dense(from, cl, '.', 't', 0, 'U'); case 'd': return index_as_dense(from, cl, 'n'); default: return R_NilValue; } } /* as(, "packedMatrix") */ SEXP R_Matrix_as_packed(SEXP from) { static const char *valid[] = { VALID_NONVIRTUAL_MATRIX, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); const char *cl = valid[ivalid + VALID_NONVIRTUAL_SHIFT(ivalid, 1)]; if (cl[1] == 'g' || cl[2] == 'd') error(_("attempt to pack a %s"), "generalMatrix"); switch (cl[2]) { case 'y': case 'r': return dense_as_packed(from, valid[ivalid], '\0', '\0'); case 'p': return from; case 'C': case 'R': case 'T': return sparse_as_dense(from, cl, 1); case 'i': return diagonal_as_dense(from, cl, '.', 't', 1, 'U'); default: return R_NilValue; } } /* as(, "CsparseMatrix") */ SEXP R_Matrix_as_Csparse(SEXP from) { static const char *valid[] = { VALID_NONVIRTUAL_MATRIX, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); const char *cl = valid[ivalid + VALID_NONVIRTUAL_SHIFT(ivalid, 1)]; switch (cl[2]) { case 'e': case 'y': case 'r': case 'p': return dense_as_sparse(from, cl, 'C'); case 'C': case 'R': case 'T': return sparse_as_Csparse(from, cl); case 'i': return diagonal_as_sparse(from, cl, '.', 't', 'C', 'U'); case 'd': return index_as_sparse(from, cl, 'n', 'C'); default: return R_NilValue; } } /* as(, "RsparseMatrix") */ SEXP R_Matrix_as_Rsparse(SEXP from) { static const char *valid[] = { VALID_NONVIRTUAL_MATRIX, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); const char *cl = valid[ivalid + VALID_NONVIRTUAL_SHIFT(ivalid, 1)]; switch (cl[2]) { case 'e': case 'y': case 'r': case 'p': return dense_as_sparse(from, cl, 'R'); case 'C': case 'R': case 'T': return sparse_as_Rsparse(from, cl); case 'i': return diagonal_as_sparse(from, cl, '.', 't', 'R', 'U'); case 'd': return index_as_sparse(from, cl, 'n', 'R'); default: return R_NilValue; } } /* as(, "TsparseMatrix") */ SEXP R_Matrix_as_Tsparse(SEXP from) { static const char *valid[] = { VALID_NONVIRTUAL_MATRIX, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); const char *cl = valid[ivalid + VALID_NONVIRTUAL_SHIFT(ivalid, 1)]; switch (cl[2]) { case 'e': case 'y': case 'r': case 'p': return dense_as_sparse(from, cl, 'T'); case 'C': case 'R': case 'T': return sparse_as_Tsparse(from, cl); case 'i': return diagonal_as_sparse(from, cl, '.', 't', 'T', 'U'); case 'd': return index_as_sparse(from, cl, 'n', 'T'); default: return R_NilValue; } } /* as(, "[nldiz]Matrix") */ SEXP R_Matrix_as_kind(SEXP from, SEXP kind, SEXP sparse) { static const char *valid[] = { VALID_NONVIRTUAL_MATRIX, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); const char *cl = valid[ivalid + VALID_NONVIRTUAL_SHIFT(ivalid, 1)]; char kind_; if (TYPEOF(kind) != STRSXP || LENGTH(kind) < 1 || (kind = STRING_ELT(kind, 0)) == NA_STRING || (kind_ = CHAR(kind)[0]) == '\0') error(_("invalid '%s' to '%s'"), "kind", __func__); if (TYPEOF(sparse) != LGLSXP || LENGTH(sparse) < 1) error(_("'%s' must be %s or %s or %s"), "sparse", "TRUE", "FALSE", "NA"); int sparse_ = LOGICAL(sparse)[0]; switch (cl[2]) { case 'e': case 'y': case 'r': case 'p': if (sparse_ == NA_LOGICAL || !sparse_) from = dense_as_kind(from, cl, kind_, 0); else { from = dense_as_sparse(from, cl, 'C'); PROTECT(from); char cl_[] = "..CMatrix"; cl_[0] = cl[0]; cl_[1] = cl[1]; from = sparse_as_kind(from, cl_, kind_); UNPROTECT(1); } return from; case 'C': case 'R': case 'T': from = sparse_as_kind(from, cl, kind_); if (sparse_ != NA_LOGICAL && !sparse_) { PROTECT(from); char cl_[] = "...Matrix"; cl_[0] = (kind_ == '.') ? cl[0] : ((kind_ == ',') ? ((cl[0] == 'z') ? 'z' : 'd') : kind_); cl_[1] = cl[1]; cl_[2] = cl[2]; from = sparse_as_dense(from, cl_, 0); UNPROTECT(1); } return from; case 'i': if (sparse_ == NA_LOGICAL) from = diagonal_as_kind(from, cl, kind_); else if (sparse_) from = diagonal_as_sparse(from, cl, kind_, 't', 'C', 'U'); else from = diagonal_as_dense(from, cl, kind_, 't', 0, 'U'); return from; case 'd': if (sparse_ == NA_LOGICAL || sparse_) from = index_as_sparse(from, cl, kind_, '.'); else from = index_as_dense(from, cl, kind_); return from; default: return R_NilValue; } } /* as(as(, "[nlidz]Matrix"), "generalMatrix") */ SEXP R_Matrix_as_general(SEXP from, SEXP kind) { static const char *valid[] = { VALID_NONVIRTUAL_MATRIX, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); const char *cl = valid[ivalid + VALID_NONVIRTUAL_SHIFT(ivalid, 1)]; char kind_; if (TYPEOF(kind) != STRSXP || LENGTH(kind) < 1 || (kind = STRING_ELT(kind, 0)) == NA_STRING || (kind_ = CHAR(kind)[0]) == '\0') error(_("invalid '%s' to '%s'"), "kind", __func__); switch (cl[2]) { case 'e': case 'y': case 'r': case 'p': { char cl_[] = "...Matrix"; cl_[0] = (kind_ == '.') ? cl[0] : ((kind_ == ',') ? ((cl[0] == 'z') ? 'z' : 'd') : kind_); cl_[1] = cl[1]; cl_[2] = cl[2]; from = dense_as_kind(from, cl, cl_[0], 1); PROTECT(from); from = dense_as_general(from, cl_, cl[0] == cl_[0]); UNPROTECT(1); return from; } case 'C': case 'R': case 'T': { char cl_[] = "...Matrix"; cl_[0] = (kind_ == '.') ? cl[0] : ((kind_ == ',') ? ((cl[0] == 'z') ? 'z' : 'd') : kind_); cl_[1] = cl[1]; cl_[2] = cl[2]; from = sparse_as_kind(from, cl, cl_[0]); PROTECT(from); from = sparse_as_general(from, cl_); UNPROTECT(1); return from; } case 'i': return diagonal_as_sparse(from, cl, kind_, 'g', 'C', '\0'); case 'd': /* indMatrix extends generalMatrix, but we typically do want this: */ return index_as_sparse(from, cl, kind_, '.'); default: return R_NilValue; } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/dense.c����������������������������������������������������������������������������������0000644�0001762�0000144�00000164762�14535466244�013604� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "Mdefines.h" #include "idz.h" #include "dense.h" SEXP dense_band(SEXP from, const char *class, int a, int b) { /* defined in ./coerce.c : */ SEXP dense_as_general(SEXP, const char *, int); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; UNPROTECT(1); /* dim */ /* Need tri[ul](<0-by-0>) and tri[ul](<1-by-1>) to be triangularMatrix */ if (a <= 1 - m && b >= n - 1 && (class[1] == 't' || m != n || m > 1 || n > 1)) return from; int ge = 0, sy = 0, tr = 0; ge = m != n || !((tr = a >= 0 || b <= 0 || class[1] == 't') || (sy = a == -b && class[1] == 's')); #define BAND_CASES(_DO_) \ do { \ switch (class[0]) { \ case 'n': \ case 'l': \ _DO_(i, int, LOGICAL); \ break; \ case 'i': \ _DO_(i, int, INTEGER); \ break; \ case 'd': \ _DO_(d, double, REAL); \ break; \ case 'z': \ _DO_(z, Rcomplex, COMPLEX); \ break; \ default: \ break; \ } \ } while (0) #define BAND2(_PREFIX_, _CTYPE_, _PTR_) \ _PREFIX_ ## band2(_PTR_(x1), m, n, a, b, di) #define BAND1(_PREFIX_, _CTYPE_, _PTR_) \ _PREFIX_ ## band1(_PTR_(x1), n, a, b, ul1, di) #define DCPY2(_PREFIX_, _CTYPE_, _PTR_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \ Matrix_memset(px1, 0, XLENGTH(x1), sizeof(_CTYPE_)); \ if (a <= 0 && b >= 0) \ _PREFIX_ ## dcpy2(px1, px0, n, XLENGTH(x1), 'U', di); \ } while (0) #define DCPY1(_PREFIX_, _CTYPE_, _PTR_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \ Matrix_memset(px1, 0, XLENGTH(x1), sizeof(_CTYPE_)); \ if (a <= 0 && b >= 0) \ _PREFIX_ ## dcpy1(px1, px0, n, XLENGTH(x1), ul1, ul0, di); \ } while (0) char ul0 = 'U', ul1 = 'U', di = 'N'; if (class[1] != 'g') { if (ge) { PROTECT(from = dense_as_general(from, class, 1)); SEXP x1 = PROTECT(GET_SLOT(from, Matrix_xSym)); BAND_CASES(BAND2); UNPROTECT(2); /* x1, from */ return from; } SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); ul0 = *CHAR(STRING_ELT(uplo, 0)); UNPROTECT(1); /* uplo */ if (class[1] == 't') { /* Be fast if band contains entire triangle */ if ((ul0 == 'U') ? (a <= 0 && b >= n - 1) : (b >= 0 && a <= 1 - m)) return from; else if (a <= 0 && b >= 0) { SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); di = *CHAR(STRING_ELT(diag, 0)); UNPROTECT(1); /* diag */ } } } char cl[] = "...Matrix"; cl[0] = class[0]; cl[1] = (ge) ? 'g' : ((sy) ? 's' : 't') ; cl[2] = (ge) ? 'e' : ((class[2] != 'p') ? ((sy) ? 'y' : 'r') : 'p'); SEXP to = PROTECT(newObject(cl)); dim = GET_SLOT(to, Matrix_DimSym); pdim = INTEGER(dim); pdim[0] = m; pdim[1] = n; SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); if (class[1] != 's' || sy) SET_SLOT(to, Matrix_DimNamesSym, dimnames); else set_symmetrized_DimNames(to, dimnames, -1); UNPROTECT(1); /* dimnames */ SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)), x1; if (ge) { PROTECT(x1 = duplicate(x0)); if (ATTRIB(x1) != R_NilValue) { SET_ATTRIB(x1, R_NilValue); if (OBJECT(x1)) SET_OBJECT(x1, 0); } SET_SLOT(to, Matrix_xSym, x1); BAND_CASES(BAND2); UNPROTECT(3); /* x1, x0, to */ return to; } /* Returning .(sy|sp|tr|tp)Matrix ... */ ul1 = (tr && class[1] != 't') ? ((a >= 0) ? 'U' : 'L') : ul0; if (ul1 != 'U') { SEXP uplo = PROTECT(mkString("L")); SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ } if (di != 'N') { SEXP diag = PROTECT(mkString("U")); SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ } if (tr && class[1] == 't') { if ((ul0 == 'U') ? (b <= 0) : (a >= 0)) { /* Result is either a diagonal matrix or a zero matrix : */ PROTECT(x1 = allocVector(TYPEOF(x0), XLENGTH(x0))); if (class[2] != 'p') BAND_CASES(DCPY2); else BAND_CASES(DCPY1); } else { PROTECT(x1 = duplicate(x0)); if (class[2] != 'p') BAND_CASES(BAND2); else BAND_CASES(BAND1); } } else { if (sy || (tr && (class[1] == 'g' || ul0 == ul1 || n <= 1))) { PROTECT(x1 = duplicate(x0)); if (ATTRIB(x1) != R_NilValue) { SET_ATTRIB(x1, R_NilValue); if (OBJECT(x1)) SET_OBJECT(x1, 0); } } else { /* Band is "opposite" the stored triangle : */ PROTECT(from = dense_transpose(from, class)); x1 = GET_SLOT(from, Matrix_xSym); UNPROTECT(1); PROTECT(x1); } if (class[2] != 'p') BAND_CASES(BAND2); else BAND_CASES(BAND1); } SET_SLOT(to, Matrix_xSym, x1); #undef BAND_CASES #undef BAND2 #undef BAND1 #undef DCPY2 #undef DCPY1 UNPROTECT(3); /* x1, x0, to */ return to; } /* band(, k1, k2), tri[ul](, k) */ /* NB: argument validation more or less copied by R_sparse_band() */ SEXP R_dense_band(SEXP from, SEXP k1, SEXP k2) { if (!IS_S4_OBJECT(from)) { /* defined in ./coerce.c : */ SEXP matrix_as_dense(SEXP, const char *, char, char, int, int); from = matrix_as_dense(from, ".ge", '\0', '\0', 0, 0); } PROTECT(from); static const char *valid[] = { VALID_DENSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; UNPROTECT(1); int a, b; if (k1 == R_NilValue) // tril() a = -m ; // was (m > 0) ? 1 - m : 0; else if ((a = asInteger(k1)) == NA_INTEGER || a < -m || a > n) error(_("'%s' (%d) must be an integer from %s (%d) to %s (%d)"), "k1", a, "-Dim[1]", -m, "Dim[2]", n); if (k2 == R_NilValue) // triu() b = n; // was (n > 0) ? n - 1 : 0; else if ((b = asInteger(k2)) == NA_INTEGER || b < -m || b > n) error(_("'%s' (%d) must be an integer from %s (%d) to %s (%d)"), "k2", b, "-Dim[1]", -m, "Dim[2]", n); else if (b < a) error(_("'%s' (%d) must be less than or equal to '%s' (%d)"), "k1", a, "k2", b); from = dense_band(from, valid[ivalid], a, b); UNPROTECT(1); return from; } SEXP dense_diag_get(SEXP obj, const char *class, int names) { SEXP dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1], r = (m < n) ? m : n, j; UNPROTECT(1); /* dim */ char ul = 'U', di = 'N'; if (class[1] != 'g') { if (class[2] == 'p') { SEXP uplo = PROTECT(GET_SLOT(obj, Matrix_uploSym)); ul = *CHAR(STRING_ELT(uplo, 0)); UNPROTECT(1); /* uplo */ } if (class[1] == 't') { SEXP diag = PROTECT(GET_SLOT(obj, Matrix_diagSym)); di = *CHAR(STRING_ELT(diag, 0)); UNPROTECT(1); /* diag */ } } SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)), res = PROTECT(allocVector(TYPEOF(x), r)); #define DG_LOOP(_CTYPE_, _PTR_, _ONE_) \ do { \ _CTYPE_ *pres = _PTR_(res), *px = _PTR_(x); \ if (di == 'U') \ for (j = 0; j < r; ++j) \ *(pres++) = _ONE_; \ else if (class[2] != 'p') { \ R_xlen_t m1a = (R_xlen_t) m + 1; \ for (j = 0; j < r; ++j, px += m1a) \ *(pres++) = *px; \ } \ else if (ul == 'U') \ for (j = 0; j < n; px += (++j) + 1) \ *(pres++) = *px; \ else \ for (j = 0; j < n; px += n - (j++)) \ *(pres++) = *px; \ } while (0) switch (class[0]) { case 'n': case 'l': DG_LOOP(int, LOGICAL, 1); break; case 'i': DG_LOOP(int, INTEGER, 1); break; case 'd': DG_LOOP(double, REAL, 1.0); break; case 'z': DG_LOOP(Rcomplex, COMPLEX, Matrix_zone); break; default: break; } if (names) { /* NB: The logic here must be adjusted once the validity method for 'symmetricMatrix' enforces symmetric 'Dimnames' */ SEXP dn = PROTECT(GET_SLOT(obj, Matrix_DimNamesSym)), rn = VECTOR_ELT(dn, 0), cn = VECTOR_ELT(dn, 1); if (cn == R_NilValue) { if (class[1] == 's' && rn != R_NilValue) setAttrib(res, R_NamesSymbol, rn); } else { if (class[1] == 's') setAttrib(res, R_NamesSymbol, cn); else if (rn != R_NilValue && (rn == cn || equal_character_vectors(rn, cn, r))) setAttrib(res, R_NamesSymbol, (r == m) ? rn : cn); } UNPROTECT(1); /* dn */ } #undef DG_LOOP UNPROTECT(2); /* x, res */ return res; } SEXP R_dense_diag_get(SEXP obj, SEXP names) { static const char *valid[] = { VALID_DENSE, "" }; int ivalid = R_check_class_etc(obj, valid); if (ivalid < 0) ERROR_INVALID_CLASS(obj, __func__); int names_; if (TYPEOF(names) != LGLSXP || LENGTH(names) < 1 || (names_ = LOGICAL(names)[0]) == NA_LOGICAL) error(_("'%s' must be %s or %s"), "names", "TRUE", "FALSE"); return dense_diag_get(obj, valid[ivalid], names_); } SEXP dense_diag_set(SEXP from, const char *class, SEXP value, int new) { SEXP to = PROTECT(newObject(class)); int v = LENGTH(value) != 1; SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1], r = (m < n) ? m : n, j; if (m != n || n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); SET_SLOT(to, Matrix_DimNamesSym, dimnames); UNPROTECT(1); /* dimnames */ char ul = 'U'; if (class[1] != 'g') { SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); ul = *CHAR(STRING_ELT(uplo, 0)); if (ul != 'U') SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ } SEXP x = PROTECT(GET_SLOT(from, Matrix_xSym)); if (new) { x = duplicate(x); UNPROTECT(1); /* x */ PROTECT(x); } SET_SLOT(to, Matrix_xSym, x); #define DS_LOOP(_CTYPE_, _PTR_) \ do { \ _CTYPE_ *px = _PTR_(x), *pvalue = _PTR_(value); \ if (class[2] != 'p') { \ R_xlen_t m1a = (R_xlen_t) m + 1; \ if (v) \ for (j = 0; j < r; ++j, px += m1a) \ *px = *(pvalue++); \ else \ for (j = 0; j < r; ++j, px += m1a) \ *px = *pvalue; \ } else if (ul == 'U') { \ if (v) \ for (j = 0; j < n; px += (++j) + 1) \ *px = *(pvalue++); \ else \ for (j = 0; j < n; px += (++j) + 1) \ *px = *pvalue; \ } else { \ if (v) \ for (j = 0; j < n; px += n - (j++)) \ *px = *(pvalue++); \ else \ for (j = 0; j < n; px += n - (j++)) \ *px = *pvalue; \ } \ } while (0) switch (class[0]) { case 'n': case 'l': DS_LOOP(int, LOGICAL); break; case 'i': DS_LOOP(int, INTEGER); break; case 'd': DS_LOOP(double, REAL); break; case 'z': DS_LOOP(Rcomplex, COMPLEX); break; default: break; } #undef DS_LOOP UNPROTECT(2); /* x, to */ return to; } SEXP R_dense_diag_set(SEXP from, SEXP value) { static const char *valid[] = { VALID_DENSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); const char *class = valid[ivalid]; SEXPTYPE tx = kindToType(class[0]), tv = TYPEOF(value); switch (tv) { case LGLSXP: case INTSXP: case REALSXP: case CPLXSXP: break; default: error(_("replacement diagonal has incompatible type \"%s\""), type2char(tv)); break; } SEXP dim = GET_SLOT(from, Matrix_DimSym); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1], r = (m < n) ? m : n; R_xlen_t len = XLENGTH(value); if (len != 1 && len != r) error(_("replacement diagonal has wrong length")); int new = 1; if (tv <= tx) { PROTECT(from); PROTECT(value = coerceVector(value, tx)); } else { /* defined in ./coerce.c : */ SEXP dense_as_kind(SEXP, const char *, char, int); #ifndef MATRIX_ENABLE_IMATRIX if (tv == INTSXP) { PROTECT(from = dense_as_kind(from, class, 'd', 0)); PROTECT(value = coerceVector(value, REALSXP)); } else { #endif PROTECT(from = dense_as_kind(from, class, typeToKind(tv), 0)); PROTECT(value); #ifndef MATRIX_ENABLE_IMATRIX } #endif class = valid[R_check_class_etc(from, valid)]; new = 0; } from = dense_diag_set(from, class, value, new); UNPROTECT(2); return from; } SEXP dense_transpose(SEXP from, const char *class) { SEXP to = PROTECT(newObject(class)); int isCor = class[0] == 'c' || (class[0] == 'p' && class[1] == 'c'); if (isCor) class = (class[0] != 'p') ? "dsyMatrix" : "dspMatrix"; else if (class[1] == 'p') class = (class[2] != 'p') ? "dsyMatrix" : "dspMatrix"; SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1], i, j; if (m != n) { UNPROTECT(1); /* dim */ PROTECT(dim = GET_SLOT(to, Matrix_DimSym)); pdim = INTEGER(dim); pdim[0] = n; pdim[1] = m; } else if (n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); if (class[1] == 's') SET_SLOT(to, Matrix_DimNamesSym, dimnames); else set_reversed_DimNames(to, dimnames); UNPROTECT(1); /* dimnames */ char ul = 'U'; if (class[1] != 'g') { SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); ul = *CHAR(STRING_ELT(uplo, 0)); UNPROTECT(1); /* uplo */ if (ul == 'U') { PROTECT(uplo = mkString("L")); SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ } if (class[1] == 't') { SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); char di = *CHAR(STRING_ELT(diag, 0)); if (di != 'N') SET_SLOT(to, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ } else { SEXP factors = PROTECT(GET_SLOT(from, Matrix_factorsSym)); if (LENGTH(factors) > 0) SET_SLOT(to, Matrix_factorsSym, factors); UNPROTECT(1); /* factors */ if (isCor && n > 0) { SEXP sd = PROTECT(GET_SLOT(from, Matrix_sdSym)); SET_SLOT(to, Matrix_sdSym, sd); UNPROTECT(1); /* sd */ } } } SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)), x1 = PROTECT(allocVector(TYPEOF(x0), XLENGTH(x0))); SET_SLOT(to, Matrix_xSym, x1); #define TRANS_LOOP(_CTYPE_, _PTR_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \ if (class[2] != 'p') { \ R_xlen_t mn1s = XLENGTH(x0) - 1; \ for (j = 0; j < m; ++j, px0 -= mn1s) \ for (i = 0; i < n; ++i, px0 += m) \ *(px1++) = *px0; \ } else if (ul == 'U') { \ for (j = 0; j < n; ++j) \ for (i = j; i < n; ++i) \ *(px1++) = *(px0 + PACKED_AR21_UP(j, i)); \ } else { \ R_xlen_t n2 = (R_xlen_t) n * 2; \ for (j = 0; j < n; ++j) \ for (i = 0; i <= j; ++i) \ *(px1++) = *(px0 + PACKED_AR21_LO(j, i, n2)); \ } \ } while (0) switch (class[0]) { case 'n': case 'l': TRANS_LOOP(int, LOGICAL); break; case 'i': TRANS_LOOP(int, INTEGER); break; case 'd': TRANS_LOOP(double, REAL); break; case 'z': TRANS_LOOP(Rcomplex, COMPLEX); break; default: break; } #undef TRANS_LOOP UNPROTECT(3); /* x1, x0, to */ return to; } SEXP R_dense_transpose(SEXP from) { static const char *valid[] = { "corMatrix", "pcorMatrix", "dpoMatrix", "dppMatrix", VALID_DENSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); return dense_transpose(from, valid[ivalid]); } SEXP dense_force_symmetric(SEXP from, const char *class, char ul) { char ul0 = 'U', ul1 = 'U', di = 'N'; if (class[1] != 'g') { SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); ul0 = ul1 = *CHAR(STRING_ELT(uplo, 0)); UNPROTECT(1); /* uplo */ if (class[1] == 't') { SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); di = *CHAR(STRING_ELT(diag, 0)); UNPROTECT(1); /* diag */ } } if (ul != '\0') ul1 = ul; if (class[1] == 's') { /* .s[yp]Matrix */ if (ul0 == ul1) return from; SEXP to = PROTECT(dense_transpose(from, class)); if (class[0] == 'z') { /* Need _conjugate_ transpose */ SEXP x1 = PROTECT(GET_SLOT(to, Matrix_xSym)); conjugate(x1); UNPROTECT(1); /* x1 */ } UNPROTECT(1) /* to */; return to; } /* Now handling just .(ge|tr|tp)Matrix ... */ char cl[] = ".s.Matrix"; cl[0] = class[0]; cl[2] = (class[2] != 'p') ? 'y' : 'p'; SEXP to = PROTECT(newObject(cl)); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), n = pdim[0]; if (pdim[1] != n) error(_("attempt to symmetrize a non-square matrix")); if (n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); set_symmetrized_DimNames(to, dimnames, -1); UNPROTECT(1); /* dimnames */ if (ul1 != 'U') { SEXP uplo = PROTECT(mkString("L")); SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ } SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)); if (class[1] == 'g' || ul0 == ul1) SET_SLOT(to, Matrix_xSym, x0); else { SEXP x1 = PROTECT(allocVector(TYPEOF(x0), XLENGTH(x0))); SET_SLOT(to, Matrix_xSym, x1); R_xlen_t len = XLENGTH(x1); #define DCPY(_PREFIX_, _CTYPE_, _PTR_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \ Matrix_memset(px1, 0, len, sizeof(_CTYPE_)); \ if (class[2] != 'p') \ _PREFIX_ ## dcpy2(px1, px0, n, len, '\0', di); \ else \ _PREFIX_ ## dcpy1(px1, px0, n, len, ul1, ul0, di); \ } while (0) switch (class[0]) { case 'n': case 'l': DCPY(i, int, LOGICAL); break; case 'i': DCPY(i, int, INTEGER); break; case 'd': DCPY(d, double, REAL); break; case 'z': DCPY(z, Rcomplex, COMPLEX); break; default: break; } #undef DCPY UNPROTECT(1); /* x1 */ } UNPROTECT(2); /* x0, to */ return to; } SEXP R_dense_force_symmetric(SEXP from, SEXP uplo) { static const char *valid[] = { VALID_DENSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); char ul = '\0'; if (uplo != R_NilValue) { if (TYPEOF(uplo) != STRSXP || LENGTH(uplo) < 1 || (uplo = STRING_ELT(uplo, 0)) == NA_STRING || ((ul = *CHAR(uplo)) != 'U' && ul != 'L')) error(_("invalid '%s' to '%s'"), "uplo", __func__); } return dense_force_symmetric(from, valid[ivalid], ul); } SEXP dense_symmpart(SEXP from, const char *class) { if (class[0] != 'z' && class[0] != 'd') { /* defined in ./coerce.c : */ SEXP dense_as_kind(SEXP, const char *, char, int); from = dense_as_kind(from, class, 'd', 0); } if (class[0] != 'z' && class[1] == 's') return from; PROTECT(from); char cl[] = ".s.Matrix"; cl[0] = (class[0] != 'z') ? 'd' : 'z'; cl[2] = (class[2] != 'p') ? 'y' : 'p'; SEXP to = PROTECT(newObject(cl)); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), n = pdim[0]; if (pdim[1] != n) error(_("attempt to get symmetric part of non-square matrix")); if (n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); if (class[1] == 's') SET_SLOT(to, Matrix_DimNamesSym, dimnames); else set_symmetrized_DimNames(to, dimnames, -1); UNPROTECT(1); /* dimnames */ char ul = 'U', di = 'N'; if (class[1] != 'g') { SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); ul = *CHAR(STRING_ELT(uplo, 0)); if (ul != 'U') SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ if (class[1] == 't') { SEXP diag = PROTECT(GET_SLOT(from, Matrix_diagSym)); di = *CHAR(STRING_ELT(diag, 0)); UNPROTECT(1); /* diag */ } } SEXP x = PROTECT(GET_SLOT(from, Matrix_xSym)); if (class[0] == 'z' || class[0] == 'd') { x = duplicate(x); UNPROTECT(1); /* x */ PROTECT(x); } SET_SLOT(to, Matrix_xSym, x); if (class[1] == 's') { /* Symmetric part of Hermitian matrix is real part */ zeroIm(x); UNPROTECT(3); /* x, to, from */ return to; } int i, j; #define SP_LOOP(_CTYPE_, _PTR_, _INCREMENT_, _SCALE1_, _ONE_) \ do { \ _CTYPE_ *px = _PTR_(x); \ if (class[1] == 'g') { \ _CTYPE_ *py = px; \ for (j = 0; j < n; ++j) { \ for (i = j + 1; i < n; ++i) { \ px += n; \ py += 1; \ _INCREMENT_((*px), (*py)); \ _SCALE1_((*px), 0.5); \ } \ px = (py += j + 2); \ } \ } else if (class[2] != 'p') { \ if (ul == 'U') { \ for (j = 0; j < n; ++j) { \ for (i = 0; i < j; ++i) { \ _SCALE1_((*px), 0.5); \ px += 1; \ } \ px += n - j; \ } \ } else { \ for (j = 0; j < n; ++j) { \ px += j + 1; \ for (i = j + 1; i < n; ++i) { \ _SCALE1_((*px), 0.5); \ px += 1; \ } \ } \ } \ if (di != 'N') { \ R_xlen_t n1a = (R_xlen_t) n + 1; \ px = _PTR_(x); \ for (j = 0; j < n; ++j, px += n1a) \ *px = _ONE_; \ } \ } else { \ if (ul == 'U') { \ for (j = 0; j < n; ++j) { \ for (i = 0; i < j; ++i) { \ _SCALE1_((*px), 0.5); \ px += 1; \ } \ px += 1; \ } \ if (di != 'N') { \ px = _PTR_(x); \ for (j = 0; j < n; px += (++j) + 1) \ *px = _ONE_; \ } \ } else { \ for (j = 0; j < n; ++j) { \ px += 1; \ for (i = j + 1; i < n; ++i) { \ _SCALE1_((*px), 0.5); \ px += 1; \ } \ } \ if (di != 'N') { \ px = _PTR_(x); \ for (j = 0; j < n; px += n - (j++)) \ *px = _ONE_; \ } \ } \ } \ } while (0) if (cl[0] == 'd') SP_LOOP(double, REAL, INCREMENT_REAL, SCALE1_REAL, 1.0); else SP_LOOP(Rcomplex, COMPLEX, INCREMENT_COMPLEX, SCALE1_COMPLEX, Matrix_zone); #undef SP_LOOP UNPROTECT(3); /* x, to, from */ return to; } SEXP R_dense_symmpart(SEXP from) { static const char *valid[] = { VALID_DENSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); return dense_symmpart(from, valid[ivalid]); } SEXP dense_skewpart(SEXP from, const char *class) { if (class[0] != 'z' && class[0] != 'd') { /* defined in ./coerce.c : */ SEXP dense_as_kind(SEXP, const char *, char, int); from = dense_as_kind(from, class, 'd', 0); } PROTECT(from); char cl[] = "...Matrix"; cl[0] = (class[0] != 'z') ? 'd' : 'z'; cl[1] = (class[1] != 's') ? 'g' : 's'; cl[2] = (class[1] != 's') ? 'e' : ((class[0] != 'z') ? 'C' : ((class[2] != 'p') ? 'y' : 'p')); SEXP to = PROTECT(newObject(cl)); SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)); int *pdim = INTEGER(dim), n = pdim[0]; if (pdim[1] != n) error(_("attempt to get skew-symmetric part of non-square matrix")); if (n > 0) SET_SLOT(to, Matrix_DimSym, dim); UNPROTECT(1); /* dim */ SEXP dimnames = PROTECT(GET_SLOT(from, Matrix_DimNamesSym)); if (class[1] == 's') SET_SLOT(to, Matrix_DimNamesSym, dimnames); else set_symmetrized_DimNames(to, dimnames, -1); UNPROTECT(1); /* dimnames */ char ul = 'U'; if (class[1] != 'g') { SEXP uplo = PROTECT(GET_SLOT(from, Matrix_uploSym)); ul = *CHAR(STRING_ELT(uplo, 0)); if (class[1] == 's' && ul != 'U') SET_SLOT(to, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ } if (class[1] == 's' && class[0] != 'z') { /* Skew-symmetric part of Hermitian matrix is imaginary part */ SEXP p = PROTECT(allocVector(INTSXP, (R_xlen_t) n + 1)); int *pp = INTEGER(p); Matrix_memset(pp, 0, (R_xlen_t) n + 1, sizeof(int)); SET_SLOT(to, Matrix_pSym, p); UNPROTECT(3); /* p, to, from */ return to; } SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)), x1 = x0; if (class[1] == 's') { /* Skew-symmetric part of Hermitian matrix is imaginary part */ x1 = duplicate(x1); UNPROTECT(1); /* x1 */ PROTECT(x1); SET_SLOT(to, Matrix_xSym, x1); zeroRe(x1); UNPROTECT(3); /* x1, to, from */ return to; } if (class[2] == 'p' || class[0] == 'z' || class[0] == 'd') { if ((Matrix_int_fast64_t) n * n > R_XLEN_T_MAX) error(_("attempt to allocate vector of length exceeding %s"), "R_XLEN_T_MAX"); x1 = allocVector(TYPEOF(x0), (R_xlen_t) n * n); } PROTECT(x1); SET_SLOT(to, Matrix_xSym, x1); int i, j; R_xlen_t upos = 0, lpos = 0; #define SP_LOOP(_CTYPE_, _PTR_, _INCREMENT_, _ASSIGN_, _ZERO_) \ do { \ _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \ if (class[1] == 'g') { \ for (j = 0; j < n; ++j) { \ lpos = j; \ for (i = 0; i < j; ++i) { \ _ASSIGN_(px1[upos], 0.5 * px0[upos]); \ _INCREMENT_(px1[upos], -0.5 * px0[lpos]); \ _ASSIGN_(px1[lpos], -px1[upos]); \ upos += 1; \ lpos += n; \ } \ px1[upos] = _ZERO_; \ upos += n - j; \ } \ } else if (class[2] != 'p') { \ if (ul == 'U') { \ for (j = 0; j < n; ++j) { \ lpos = j; \ for (i = 0; i < j; ++i) { \ _ASSIGN_(px1[upos], 0.5 * px0[upos]); \ _ASSIGN_(px1[lpos], -px1[upos]); \ upos += 1; \ lpos += n; \ } \ px1[upos] = _ZERO_; \ upos += n - j; \ } \ } else { \ for (j = 0; j < n; ++j) { \ upos = lpos; \ px1[lpos] = _ZERO_; \ for (i = j + 1; i < n; ++i) { \ upos += n; \ lpos += 1; \ _ASSIGN_(px1[lpos], 0.5 * px0[lpos]); \ _ASSIGN_(px1[upos], -px1[lpos]); \ } \ lpos += j + 2; \ } \ } \ } else { \ if (ul == 'U') { \ for (j = 0; j < n; ++j, ++px0) { \ lpos = j; \ for (i = 0; i < j; ++i, ++px0) { \ _ASSIGN_(px1[upos], 0.5 * (*px0)); \ _ASSIGN_(px1[lpos], -px1[upos]); \ upos += 1; \ lpos += n; \ } \ px1[upos] = _ZERO_; \ upos += n - j; \ } \ } else { \ for (j = 0; j < n; ++j, ++px0) { \ upos = lpos; \ px1[lpos] = _ZERO_; \ for (i = j + 1; i < n; ++i, ++px0) { \ upos += n; \ lpos += 1; \ _ASSIGN_(px1[lpos], 0.5 * (*px0)); \ _ASSIGN_(px1[upos], -px1[lpos]); \ } \ lpos += j + 2; \ } \ } \ } \ } while (0) if (cl[0] == 'd') SP_LOOP(double, REAL, INCREMENT_REAL, ASSIGN_REAL, 0.0); else SP_LOOP(Rcomplex, COMPLEX, INCREMENT_COMPLEX, ASSIGN_COMPLEX, Matrix_zzero); #undef SP_LOOP UNPROTECT(4); /* x1, x0, to, from */ return to; } SEXP R_dense_skewpart(SEXP from) { static const char *valid[] = { VALID_DENSE, "" }; int ivalid = R_check_class_etc(from, valid); if (ivalid < 0) ERROR_INVALID_CLASS(from, __func__); return dense_skewpart(from, valid[ivalid]); } int dense_is_symmetric(SEXP obj, const char *class, int checkDN) { if (class[1] == 's') return 1; if (checkDN) { SEXP dimnames = GET_SLOT(obj, Matrix_DimNamesSym); if (!DimNames_is_symmetric(dimnames)) return 0; } if (class[1] == 't') return dense_is_diagonal(obj, class); SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), n = pdim[0]; if (pdim[1] != n) return 0; if (n <= 1) return 1; SEXP x = GET_SLOT(obj, Matrix_xSym); int i, j; #define IS_LOOP(_CTYPE_, _PTR_, _NOTREAL_, _NOTCONJ_) \ do { \ _CTYPE_ *px = _PTR_(x), *py = px; \ for (j = 0; j < n; px = (py += (++j) + 1)) { \ if (_NOTREAL_((*px))) \ return 0; \ for (i = j + 1; i < n; ++i) { \ px += n; \ py += 1; \ if (_NOTCONJ_((*px), (*py))) \ return 0; \ } \ } \ return 1; \ } while (0) switch (class[0]) { case 'n': IS_LOOP(int, LOGICAL, NOTREAL_PATTERN, NOTCONJ_PATTERN); break; case 'l': IS_LOOP(int, LOGICAL, NOTREAL_LOGICAL, NOTCONJ_LOGICAL); break; case 'i': IS_LOOP(int, INTEGER, NOTREAL_INTEGER, NOTCONJ_INTEGER); break; case 'd': IS_LOOP(double, REAL, NOTREAL_REAL, NOTCONJ_REAL); break; case 'z': IS_LOOP(Rcomplex, COMPLEX, NOTREAL_COMPLEX, NOTCONJ_COMPLEX); break; default: break; } #undef IS_LOOP return 0; } SEXP R_dense_is_symmetric(SEXP obj, SEXP checkDN) { if (!IS_S4_OBJECT(obj)) { /* defined in ./coerce.c : */ SEXP matrix_as_dense(SEXP, const char *, char, char, int, int); obj = matrix_as_dense(obj, ".ge", '\0', '\0', 0, 0); } PROTECT(obj); static const char *valid[] = { VALID_DENSE, "" }; int ivalid = R_check_class_etc(obj, valid); if (ivalid < 0) ERROR_INVALID_CLASS(obj, __func__); int checkDN_; if (TYPEOF(checkDN) != LGLSXP || LENGTH(checkDN) < 1 || (checkDN_ = LOGICAL(checkDN)[0]) == NA_LOGICAL) error(_("'%s' must be %s or %s"), "checkDN", "TRUE", "FALSE"); SEXP ans = ScalarLogical(dense_is_symmetric(obj, valid[ivalid], checkDN_)); UNPROTECT(1); return ans; } int dense_is_triangular(SEXP obj, const char *class, int upper) { if (class[1] == 't') { SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = *CHAR(STRING_ELT(uplo, 0)); if (upper == NA_LOGICAL || (upper != 0) == (ul == 'U')) return (ul == 'U') ? 1 : -1; else if (dense_is_diagonal(obj, class)) return (ul == 'U') ? -1 : 1; else return 0; } if (class[1] == 's') { if (!dense_is_diagonal(obj, class)) return 0; SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = *CHAR(STRING_ELT(uplo, 0)); if (upper == NA_LOGICAL) return (ul == 'U') ? 1 : -1; else return (upper != 0) ? 1 : -1; } SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), n = pdim[0]; if (pdim[1] != n) return 0; if (n <= 1) return (upper != 0) ? 1 : -1; SEXP x = GET_SLOT(obj, Matrix_xSym); int i, j; #define IT_LOOP(_CTYPE_, _PTR_, _ISNZ_) \ do { \ _CTYPE_ *px; \ if (upper == NA_LOGICAL) { \ px = _PTR_(x); \ for (j = 0; j < n; px += (++j)) { \ px += 1; \ for (i = j + 1; i < n; ++i, px += 1) { \ if (_ISNZ_(*px)) { \ j = n; \ break; \ } \ } \ } \ if (j == n) \ return 1; \ px = _PTR_(x); \ for (j = 0; j < n; px += n - (++j)) { \ for (i = 0; i < j; ++i, px += 1) { \ if (_ISNZ_(*px)) { \ j = n; \ break; \ } \ } \ px += 1; \ } \ if (j == n) \ return -1; \ return 0; \ } else if (upper != 0) { \ px = _PTR_(x); \ for (j = 0; j < n; px += (++j)) { \ px += 1; \ for (i = j + 1; i < n; ++i, px += 1) \ if (_ISNZ_(*px)) \ return 0; \ } \ return 1; \ } else { \ px = _PTR_(x); \ for (j = 0; j < n; px += n - (++j)) { \ for (i = 0; i < j; ++i, px += 1) \ if (_ISNZ_(*px)) \ return 0; \ px += 1; \ } \ return -1; \ } \ } while (0) switch (class[0]) { case 'n': IT_LOOP(int, LOGICAL, ISNZ_PATTERN); break; case 'l': IT_LOOP(int, LOGICAL, ISNZ_LOGICAL); break; case 'i': IT_LOOP(int, INTEGER, ISNZ_INTEGER); break; case 'd': IT_LOOP(double, REAL, ISNZ_REAL); break; case 'z': IT_LOOP(Rcomplex, COMPLEX, ISNZ_COMPLEX); break; default: break; } #undef IT_LOOP return 0; } SEXP R_dense_is_triangular(SEXP obj, SEXP upper) { if (!IS_S4_OBJECT(obj)) { /* defined in ./coerce.c : */ SEXP matrix_as_dense(SEXP, const char *, char, char, int, int); obj = matrix_as_dense(obj, ".ge", '\0', '\0', 0, 0); } PROTECT(obj); static const char *valid[] = { VALID_DENSE, "" }; int ivalid = R_check_class_etc(obj, valid); if (ivalid < 0) ERROR_INVALID_CLASS(obj, __func__); if (TYPEOF(upper) != LGLSXP || LENGTH(upper) < 1) error(_("'%s' must be %s or %s or %s"), "upper", "TRUE", "FALSE", "NA"); int upper_ = LOGICAL(upper)[0]; int ans_ = dense_is_triangular(obj, valid[ivalid], upper_); SEXP ans = allocVector(LGLSXP, 1); LOGICAL(ans)[0] = ans_ != 0; if (upper_ == NA_LOGICAL && ans_ != 0) { PROTECT(ans); static SEXP kindSym = NULL; SEXP kindVal = PROTECT(mkString((ans_ > 0) ? "U" : "L")); if (!kindSym) kindSym = install("kind"); setAttrib(ans, kindSym, kindVal); UNPROTECT(2); } UNPROTECT(1); return ans; } int dense_is_diagonal(SEXP obj, const char *class) { SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), n = pdim[0]; if (pdim[1] != n) return 0; if (n <= 1) return 1; char ul = 'U'; if (class[1] != 'g') { SEXP uplo = GET_SLOT(obj, Matrix_uploSym); ul = *CHAR(STRING_ELT(uplo, 0)); } SEXP x = GET_SLOT(obj, Matrix_xSym); int i, j; #define ID_LOOP(_CTYPE_, _PTR_, _ISNZ_) \ do { \ _CTYPE_ *px = _PTR_(x); \ if (class[1] == 'g') { \ for (j = 0; j < n; ++j) { \ for (i = 0; i < j; ++i) { \ if (_ISNZ_(*px)) \ return 0; \ px += 1; \ } \ px += 1; \ for (i = j + 1; i < n; ++i) { \ if (_ISNZ_(*px)) \ return 0; \ px += 1; \ } \ } \ } else if (class[2] != 'p') { \ if (ul == 'U') { \ for (j = 0; j < n; ++j) { \ for (i = 0; i < j; ++i) { \ if (_ISNZ_(*px)) \ return 0; \ px += 1; \ } \ px += n - j; \ } \ } else { \ for (j = 0; j < n; ++j) { \ px += j + 1; \ for (i = j + 1; i < n; ++i) { \ if (_ISNZ_(*px)) \ return 0; \ px += 1; \ } \ } \ } \ } else { \ if (ul == 'U') { \ for (j = 0; j < n; ++j) { \ for (i = 0; i < j; ++i) { \ if (_ISNZ_(*px)) \ return 0; \ px += 1; \ } \ px += 1; \ } \ } else { \ for (j = 0; j < n; ++j) { \ px += 1; \ for (i = j + 1; i < n; ++i) { \ if (_ISNZ_(*px)) \ return 0; \ px += 1; \ } \ } \ } \ } \ return 1; \ } while (0) switch (class[0]) { case 'n': ID_LOOP(int, LOGICAL, ISNZ_PATTERN); break; case 'l': ID_LOOP(int, LOGICAL, ISNZ_LOGICAL); break; case 'i': ID_LOOP(int, INTEGER, ISNZ_INTEGER); break; case 'd': ID_LOOP(double, REAL, ISNZ_REAL); break; case 'z': ID_LOOP(Rcomplex, COMPLEX, ISNZ_COMPLEX); break; default: break; } #undef ID_LOOP return 0; } SEXP R_dense_is_diagonal(SEXP obj) { if (!IS_S4_OBJECT(obj)) { /* defined in ./coerce.c : */ SEXP matrix_as_dense(SEXP, const char *, char, char, int, int); obj = matrix_as_dense(obj, ".ge", '\0', '\0', 0, 0); } PROTECT(obj); static const char *valid[] = { VALID_DENSE, "" }; int ivalid = R_check_class_etc(obj, valid); if (ivalid < 0) ERROR_INVALID_CLASS(obj, __func__); SEXP ans = ScalarLogical(dense_is_diagonal(obj, valid[ivalid])); UNPROTECT(1); return ans; } #define CAST_PATTERN(_X_) (_X_ != 0) #define CAST_LOGICAL(_X_) (_X_ != 0) #define CAST_INTEGER(_X_) _X_ #define CAST_REAL(_X_) _X_ #define CAST_COMPLEX(_X_) _X_ #define SUM_CASES \ do { \ switch (class[0]) { \ case 'n': \ if (mean) \ SUM_LOOP(int, LOGICAL, double, REAL, \ 0.0, 1.0, NA_REAL, ISNA_PATTERN, \ CAST_PATTERN, INCREMENT_REAL, SCALE2_REAL); \ else \ SUM_LOOP(int, LOGICAL, int, INTEGER, \ 0, 1, NA_INTEGER, ISNA_PATTERN, \ CAST_PATTERN, INCREMENT_INTEGER, SCALE2_REAL); \ break; \ case 'l': \ if (mean) \ SUM_LOOP(int, LOGICAL, double, REAL, \ 0.0, 1.0, NA_REAL, ISNA_LOGICAL, \ CAST_LOGICAL, INCREMENT_REAL, SCALE2_REAL); \ else \ SUM_LOOP(int, LOGICAL, int, INTEGER, \ 0, 1, NA_INTEGER, ISNA_LOGICAL, \ CAST_LOGICAL, INCREMENT_INTEGER, SCALE2_REAL); \ break; \ case 'i': \ SUM_LOOP(int, INTEGER, double, REAL, \ 0.0, 1.0, NA_REAL, ISNA_INTEGER, \ CAST_INTEGER, INCREMENT_REAL, SCALE2_REAL); \ break; \ case 'd': \ SUM_LOOP(double, REAL, double, REAL, \ 0.0, 1.0, NA_REAL, ISNA_REAL, \ CAST_REAL, INCREMENT_REAL, SCALE2_REAL); \ break; \ case 'z': \ SUM_LOOP(Rcomplex, COMPLEX, Rcomplex, COMPLEX, \ Matrix_zzero, Matrix_zone, Matrix_zna, ISNA_COMPLEX, \ CAST_COMPLEX, INCREMENT_COMPLEX, SCALE2_COMPLEX); \ break; \ default: \ break; \ } \ } while (0) #define SUM_TYPEOF(c) (c == 'z') ? CPLXSXP : ((mean || c == 'd' || c == 'i') ? REALSXP : INTSXP) static void dense_colsum(SEXP x, const char *class, int m, int n, char ul, char di, int narm, int mean, SEXP res) { int i, j, count = -1, narm_ = narm && mean && class[0] != 'n', unpacked = class[2] != 'p'; #define SUM_LOOP(_CTYPE0_, _PTR0_, _CTYPE1_, _PTR1_, \ _ZERO_, _ONE_, _NA_, _ISNA_, \ _CAST_, _INCREMENT_, _SCALE2_) \ do { \ _CTYPE0_ *px0 = _PTR0_( x); \ _CTYPE1_ *px1 = _PTR1_(res), tmp; \ if (class[1] == 'g') { \ for (j = 0; j < n; ++j) { \ *px1 = _ZERO_; \ SUM_KERNEL(for (i = 0; i < m; ++i), _NA_, _ISNA_, \ _CAST_, _INCREMENT_, _SCALE2_); \ px1 += 1; \ } \ } else if (di == 'N') { \ if (ul == 'U') { \ for (j = 0; j < n; ++j) { \ *px1 = _ZERO_; \ SUM_KERNEL(for (i = 0; i <= j; ++i), _NA_, _ISNA_, \ _CAST_, _INCREMENT_, _SCALE2_); \ if (unpacked) \ px0 += n - j - 1; \ px1 += 1; \ } \ } else { \ for (j = 0; j < n; ++j) { \ if (unpacked) \ px0 += j; \ *px1 = _ZERO_; \ SUM_KERNEL(for (i = j; i < n; ++i), _NA_, _ISNA_, \ _CAST_, _INCREMENT_, _SCALE2_); \ px1 += 1; \ } \ } \ } else { \ if (ul == 'U') { \ for (j = 0; j < n; ++j) { \ *px1 = _ONE_; \ SUM_KERNEL(for (i = 0; i < j; ++i), _NA_, _ISNA_, \ _CAST_, _INCREMENT_, _SCALE2_); \ ++px0; \ if (unpacked) \ px0 += n - j - 1; \ px1 += 1; \ } \ } else { \ for (j = 0; j < n; ++j) { \ if (unpacked) \ px0 += j; \ ++px0; \ *px1 = _ONE_; \ SUM_KERNEL(for (i = j + 1; i < n; ++i), _NA_, _ISNA_, \ _CAST_, _INCREMENT_, _SCALE2_); \ px1 += 1; \ } \ } \ } \ } while (0) #define SUM_KERNEL(_FOR_, _NA_, _ISNA_, _CAST_, _INCREMENT_, _SCALE2_) \ do { \ if (mean) \ count = m; \ _FOR_ { \ if (_ISNA_(*px0)) { \ if (!narm) \ *px1 = _NA_; \ else if (narm_) \ --count; \ } else { \ tmp = _CAST_(*px0); \ _INCREMENT_((*px1), tmp); \ } \ ++px0; \ } \ if (mean) \ _SCALE2_((*px1), count); \ } while (0) SUM_CASES; #undef SUM_LOOP #undef SUM_KERNEL return; } static void dense_rowsum(SEXP x, const char *class, int m, int n, char ul, char di, int narm, int mean, SEXP res) { int i, j, *count = NULL, narm_ = narm && mean && class[0] != 'n', unpacked = class[2] != 'p', symmetric = class[1] == 's'; if (narm_) { Matrix_Calloc(count, m, int); for (i = 0; i < m; ++i) count[i] = n; } #define SUM_LOOP(_CTYPE0_, _PTR0_, _CTYPE1_, _PTR1_, \ _ZERO_, _ONE_, _NA_, _ISNA_, \ _CAST_, _INCREMENT_, _SCALE2_) \ do { \ _CTYPE0_ *px0 = _PTR0_( x); \ _CTYPE1_ *px1 = _PTR1_(res), tmp = (di == 'N') ? _ZERO_ : _ONE_; \ for (i = 0; i < m; ++i) \ px1[i] = tmp; \ if (class[1] == 'g') { \ for (j = 0; j < n; ++j) \ SUM_KERNEL(for (i = 0; i < m; ++i), _NA_, _ISNA_, \ _CAST_, _INCREMENT_); \ } else if (class[1] == 's' || di == 'N') { \ if (ul == 'U') { \ for (j = 0; j < n; ++j) { \ SUM_KERNEL(for (i = 0; i <= j; ++i), _NA_, _ISNA_, \ _CAST_, _INCREMENT_); \ if (unpacked) \ px0 += n - j - 1; \ } \ } else { \ for (j = 0; j < n; ++j) { \ if (unpacked) \ px0 += j; \ SUM_KERNEL(for (i = j; i < n; ++i), _NA_, _ISNA_, \ _CAST_, _INCREMENT_); \ } \ } \ } else { \ if (ul == 'U') { \ for (j = 0; j < n; ++j) { \ SUM_KERNEL(for (i = 0; i < j; ++i), _NA_, _ISNA_, \ _CAST_, _INCREMENT_); \ ++px0; \ if (unpacked) \ px0 += n - j - 1; \ } \ } else { \ for (j = 0; j < n; ++j) { \ if (unpacked) \ px0 += j; \ ++px0; \ SUM_KERNEL(for (i = j + 1; i < n; ++i), _NA_, _ISNA_, \ _CAST_, _INCREMENT_); \ } \ } \ } \ if (mean) { \ if (narm_) \ for (i = 0; i < m; ++i) \ _SCALE2_(px1[i], count[i]); \ else \ for (i = 0; i < m; ++i) \ _SCALE2_(px1[i], n); \ } \ } while (0) #define SUM_KERNEL(_FOR_, _NA_, _ISNA_, _CAST_, _INCREMENT_) \ do { \ _FOR_ { \ int again = symmetric && i != j; \ if (_ISNA_(*px0)) { \ if (!narm) { \ px1[i] = _NA_; \ if (again) \ px1[j] = _NA_; \ } else if (narm_) { \ --count[i]; \ if (again) \ --count[j]; \ } \ } else { \ tmp = _CAST_(*px0); \ _INCREMENT_(px1[i], tmp); \ if (again) \ _INCREMENT_(px1[j], tmp); \ } \ ++px0; \ } \ } while (0) SUM_CASES; #undef SUM_LOOP #undef SUM_KERNEL if (narm_) Matrix_Free(count, m); return; } SEXP dense_marginsum(SEXP obj, const char *class, int margin, int narm, int mean) { SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1], r = (margin == 0) ? m : n; SEXP res = PROTECT(allocVector(SUM_TYPEOF(class[0]), r)), x = PROTECT(GET_SLOT(obj, Matrix_xSym)); SEXP dimnames = (class[1] != 's') ? GET_SLOT(obj, Matrix_DimNamesSym) : get_symmetrized_DimNames(obj, -1), marnames = VECTOR_ELT(dimnames, margin); if (marnames != R_NilValue) { PROTECT(marnames); setAttrib(res, R_NamesSymbol, marnames); UNPROTECT(1); /* marnames */ } char ul = 'U', di = 'N'; if (class[1] != 'g') { SEXP uplo = GET_SLOT(obj, Matrix_uploSym); ul = *CHAR(STRING_ELT(uplo, 0)); if (class[1] == 't') { SEXP diag = GET_SLOT(obj, Matrix_diagSym); di = *CHAR(STRING_ELT(diag, 0)); } } if (margin == 0 || class[1] == 's') dense_rowsum(x, class, m, n, ul, di, narm, mean, res); else dense_colsum(x, class, m, n, ul, di, narm, mean, res); UNPROTECT(2); /* x, res */ return res; } /* (row|col)(Sums|Means)() */ SEXP R_dense_marginsum(SEXP obj, SEXP margin, SEXP narm, SEXP mean) { static const char *valid[] = { VALID_DENSE, "" }; int ivalid = R_check_class_etc(obj, valid); if (ivalid < 0) ERROR_INVALID_CLASS(obj, __func__); int margin_; if (TYPEOF(margin) != INTSXP || LENGTH(margin) < 1 || ((margin_ = INTEGER(margin)[0]) != 0 && margin_ != 1)) error(_("'%s' must be %d or %d"), "margin", 0, 1); int narm_; if (TYPEOF(narm) != LGLSXP || LENGTH(narm) < 1 || (narm_ = LOGICAL(narm)[0]) == NA_LOGICAL) error(_("'%s' must be %s or %s"), "narm", "TRUE", "FALSE"); int mean_; if (TYPEOF(mean) != LGLSXP || LENGTH(mean) < 1 || (mean_ = LOGICAL(mean)[0]) == NA_LOGICAL) error(_("'%s' must be %s or %s"), "mean", "TRUE", "FALSE"); return dense_marginsum(obj, valid[ivalid], margin_, narm_, mean_); } #undef SUM_CASES #undef SUM_TYPEOF #define TRY_INCREMENT(_LABEL_) \ do { \ if ((s >= 0) \ ? ( t <= MATRIX_INT_FAST64_MAX - s) \ : (-t <= s - MATRIX_INT_FAST64_MIN)) { \ s += t; \ t = 0; \ count = 0; \ } else { \ over = 1; \ goto _LABEL_; \ } \ } while (0) #define LONGDOUBLE_AS_DOUBLE(v) \ (v > DBL_MAX) ? R_PosInf : ((v < -DBL_MAX) ? R_NegInf : (double) v); SEXP dense_sum(SEXP obj, const char *class, int narm) { SEXP res; SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; char ul = 'U', di = 'N'; if (class[1] != 'g') { SEXP uplo = GET_SLOT(obj, Matrix_uploSym); ul = *CHAR(STRING_ELT(uplo, 0)); if (class[1] == 't') { SEXP diag = GET_SLOT(obj, Matrix_diagSym); di = *CHAR(STRING_ELT(diag, 0)); } } SEXP x = GET_SLOT(obj, Matrix_xSym); int i, j, unpacked = class[2] != 'p', symmetric = class[1] == 's'; #define SUM_LOOP \ do { \ if (class[1] == 'g') { \ for (j = 0; j < n; ++j) \ SUM_KERNEL(for (i = 0; i < m; ++i)); \ } else if (class[1] == 's' || di == 'N') { \ if (ul == 'U') { \ for (j = 0; j < n; ++j) { \ SUM_KERNEL(for (i = 0; i <= j; ++i)); \ if (unpacked) \ px += m - j - 1; \ } \ } else { \ for (j = 0; j < n; ++j) { \ if (unpacked) \ px += j; \ SUM_KERNEL(for (i = j; i < m; ++i)); \ } \ } \ } else { \ if (ul == 'U') { \ for (j = 0; j < n; ++j) { \ SUM_KERNEL(for (i = 0; i < j; ++i)); \ ++px; \ if (unpacked) \ px += m - j - 1; \ } \ } else { \ for (j = 0; j < n; ++j) { \ if (unpacked) \ px += j; \ ++px; \ SUM_KERNEL(for (i = j + 1; i < m; ++i)); \ } \ } \ } \ } while (0) if (class[0] == 'n') { int *px = LOGICAL(x); Matrix_int_fast64_t s = (di == 'N') ? 0LL : n; #define SUM_KERNEL(_FOR_) \ do { \ _FOR_ { \ if (*px != 0) \ s += (symmetric && i != j) ? 2 : 1; \ ++px; \ } \ } while (0) SUM_LOOP; #undef SUM_KERNEL if (s <= INT_MAX) { res = allocVector(INTSXP, 1); INTEGER(res)[0] = (int) s; } else { res = allocVector(REALSXP, 1); REAL(res)[0] = (double) s; } return res; } if (!narm && (class[0] == 'l' || class[0] == 'i')) { int *px = (class[0] == 'l') ? LOGICAL(x) : INTEGER(x); #define SUM_KERNEL(_FOR_) \ do { \ _FOR_ { \ if (*px == NA_INTEGER) { \ res = allocVector(INTSXP, 1); \ INTEGER(res)[0] = NA_INTEGER; \ return res; \ } \ ++px; \ } \ } while (0) SUM_LOOP; #undef SUM_KERNEL } if (class[0] == 'z') { Rcomplex *px = COMPLEX(x); long double zr = (di == 'N') ? 0.0L : n, zi = 0.0L; #define SUM_KERNEL(_FOR_) \ do { \ _FOR_ { \ if (!(narm && (ISNAN((*px).r) || ISNAN((*px).i)))) { \ zr += (symmetric && i != j) \ ? 2.0L * (*px).r : (*px).r; \ zi += (symmetric && i != j) \ ? 2.0L * (*px).i : (*px).i; \ } \ ++px; \ } \ } while (0) SUM_LOOP; #undef SUM_KERNEL res = allocVector(CPLXSXP, 1); COMPLEX(res)[0].r = LONGDOUBLE_AS_DOUBLE(zr); COMPLEX(res)[0].i = LONGDOUBLE_AS_DOUBLE(zi); } else if (class[0] == 'd') { double *px = REAL(x); long double zr = (di == 'N') ? 0.0L : n; #define SUM_KERNEL(_FOR_) \ do { \ _FOR_ { \ if (!(narm && ISNAN(*px))) \ zr += (symmetric && i != j) \ ? 2.0L * *px : *px; \ ++px; \ } \ } while (0) SUM_LOOP; #undef SUM_KERNEL res = allocVector(REALSXP, 1); REAL(res)[0] = LONGDOUBLE_AS_DOUBLE(zr); } else { int *px = (class[0] == 'i') ? INTEGER(x) : LOGICAL(x); Matrix_int_fast64_t s = (di == 'N') ? 0LL : n, t = 0LL; unsigned int count = 0; int over = 0; #define SUM_KERNEL(_FOR_) \ do { \ _FOR_ { \ if (!(narm && *px == NA_INTEGER)) { \ int d = (symmetric && i != j) ? 2 : 1; \ if (count > UINT_MAX - d) \ TRY_INCREMENT(ifover); \ t += (d == 2) ? 2LL * *px : *px; \ count += d; \ } \ ++px; \ } \ } while (0) SUM_LOOP; #undef SUM_KERNEL TRY_INCREMENT(ifover); ifover: if (over) { long double zr = (di == 'N') ? 0.0L : n; /* FIXME: wasteful */ px = (class[0] == 'i') ? INTEGER(x) : LOGICAL(x); #define SUM_KERNEL(_FOR_) \ do { \ _FOR_ { \ if (!(narm && *px == NA_INTEGER)) \ zr += (symmetric && i != j) \ ? 2.0L * *px : *px; \ ++px; \ } \ } while (0) SUM_LOOP; #undef SUM_KERNEL res = allocVector(REALSXP, 1); REAL(res)[0] = LONGDOUBLE_AS_DOUBLE(zr); } else if (s > INT_MIN && s <= INT_MAX) { res = allocVector(INTSXP, 1); INTEGER(res)[0] = (int) s; } else { res = allocVector(REALSXP, 1); REAL(res)[0] = (double) s; } } #undef SUM_LOOP return res; } /* sum() */ SEXP R_dense_sum(SEXP obj, SEXP narm) { static const char *valid[] = { VALID_DENSE, "" }; int ivalid = R_check_class_etc(obj, valid); if (ivalid < 0) ERROR_INVALID_CLASS(obj, __func__); int narm_; if (TYPEOF(narm) != LGLSXP || LENGTH(narm) < 1 || (narm_ = LOGICAL(narm)[0]) == NA_LOGICAL) error(_("'%s' must be %s or %s"), "narm", "TRUE", "FALSE"); return dense_sum(obj, valid[ivalid], narm_); } SEXP dense_prod(SEXP obj, const char *class, int narm) { SEXP res = PROTECT(allocVector((class[0] == 'z') ? CPLXSXP : REALSXP, 1)); SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; char ul = 'U', di = 'N'; if (class[1] != 'g') { SEXP uplo = GET_SLOT(obj, Matrix_uploSym); ul = *CHAR(STRING_ELT(uplo, 0)); if (class[1] == 't') { SEXP diag = GET_SLOT(obj, Matrix_diagSym); di = *CHAR(STRING_ELT(diag, 0)); } } SEXP x = GET_SLOT(obj, Matrix_xSym); int i, j, unpacked = class[2] != 'p', symmetric = class[1] == 's'; long double zr = 1.0L, zi = 0.0L; #define PROD_LOOP \ do { \ if (class[1] == 'g') { \ for (j = 0; j < n; ++j) \ PROD_KERNEL(for (i = 0; i < m; ++i)); \ } else if (class[1] == 's') { \ if (ul == 'U') { \ for (j = 0; j < n; ++j) { \ PROD_KERNEL(for (i = 0; i <= j; ++i)); \ if (unpacked) \ px += m - j - 1; \ } \ } else { \ for (j = 0; j < n; ++j) { \ if (unpacked) \ px += j; \ PROD_KERNEL(for (i = j; i < m; ++i)); \ } \ } \ } else if (di == 'N') { \ if (ul == 'U') { \ for (j = 0; j < n; ++j) { \ if (j == 1) { zr *= 0.0L; zi *= 0.0L; } \ PROD_KERNEL(for (i = 0; i <= j; ++i)); \ if (unpacked) \ px += m - j - 1; \ } \ } else { \ for (j = 0; j < n; ++j) { \ if (j == 1) { zr *= 0.0L; zi *= 0.0L; } \ if (unpacked) \ px += j; \ PROD_KERNEL(for (i = j; i < m; ++i)); \ } \ } \ } else { \ if (ul == 'U') { \ for (j = 0; j < n; ++j) { \ if (j == 1) { zr *= 0.0L; zi *= 0.0L; } \ PROD_KERNEL(for (i = 0; i < j; ++i)); \ ++px; \ if (unpacked) \ px += m - j - 1; \ } \ } else { \ for (j = 0; j < n; ++j) { \ if (j == 1) { zr *= 0.0L; zi *= 0.0L; } \ if (unpacked) \ px += j; \ ++px; \ PROD_KERNEL(for (i = j + 1; i < m; ++i)); \ } \ } \ } \ } while (0) if (class[0] == 'n') { int *px = LOGICAL(x); if (class[1] == 't') REAL(res)[0] = (n > 1 || (n == 1 && *px == 0)) ? 0.0 : 1.0; else { #define PROD_KERNEL(_FOR_) \ do { \ _FOR_ { \ if (*px == 0) { \ REAL(res)[0] = 0.0; \ UNPROTECT(1); /* res */ \ return res; \ } \ ++px; \ } \ } while (0) PROD_LOOP; #undef PROD_KERNEL REAL(res)[0] = 1.0; } UNPROTECT(1); /* res */ return res; } if (class[0] == 'z') { Rcomplex *px = COMPLEX(x); long double zr0, zi0; #define PROD_KERNEL(_FOR_) \ do { \ _FOR_ { \ if (!(narm && (ISNAN((*px).r) || ISNAN((*px).i)))) { \ zr0 = zr; zi0 = zi; \ zr = zr0 * (*px).r - zi0 * (*px).i; \ zi = zr0 * (*px).i + zi0 * (*px).r; \ if (symmetric && i != j) { \ zr0 = zr; zi0 = zi; \ zr = zr0 * (*px).r - zi0 * (*px).i; \ zi = zr0 * (*px).i + zi0 * (*px).r; \ } \ } \ ++px; \ } \ } while (0) PROD_LOOP; #undef PROD_KERNEL } else if (class[0] == 'd') { double *px = REAL(x); #define PROD_KERNEL(_FOR_) \ do { \ _FOR_ { \ if (!(narm && ISNAN(*px))) \ zr *= (symmetric && i != j) \ ? (long double) *px * *px : *px; \ ++px; \ } \ } while (0) PROD_LOOP; #undef PROD_KERNEL } else { int *px = (class[0] == 'l') ? LOGICAL(x) : INTEGER(x); #define PROD_KERNEL(_FOR_) \ do { \ _FOR_ { \ if (*px != NA_INTEGER) \ zr *= (symmetric && i != j) \ ? (long double) *px * *px : *px; \ else if (!narm) \ zr *= NA_REAL; \ ++px; \ } \ } while (0) PROD_LOOP; #undef PROD_KERNEL } #undef PROD_LOOP if (class[0] == 'z') { COMPLEX(res)[0].r = LONGDOUBLE_AS_DOUBLE(zr); COMPLEX(res)[0].i = LONGDOUBLE_AS_DOUBLE(zi); } else REAL(res)[0] = LONGDOUBLE_AS_DOUBLE(zr); UNPROTECT(1); /* res */ return res; } /* prod() */ SEXP R_dense_prod(SEXP obj, SEXP narm) { static const char *valid[] = { VALID_DENSE, "" }; int ivalid = R_check_class_etc(obj, valid); if (ivalid < 0) ERROR_INVALID_CLASS(obj, __func__); int narm_; if (TYPEOF(narm) != LGLSXP || LENGTH(narm) < 1 || (narm_ = LOGICAL(narm)[0]) == NA_LOGICAL) error(_("'%s' must be %s or %s"), "narm", "TRUE", "FALSE"); return dense_prod(obj, valid[ivalid], narm_); } #undef TRY_INCREMENT #undef LONGDOUBLE_AS_DOUBLE /* MJ: unused */ #if 0 /** * Perform a left cyclic shift of columns j to k in the upper triangular * matrix x, then restore it to upper triangular form with Givens rotations. * The algorithm is based on the Fortran routine DCHEX from Linpack. * * The lower triangle of x is not modified. * * @param x Matrix stored in column-major order * @param ldx leading dimension of x * @param j column number (0-based) that will be shifted to position k * @param k last column number (0-based) to be shifted * @param cosines cosines of the Givens rotations * @param sines sines of the Givens rotations * * @return 0 for success */ static int left_cyclic(double *x, int ldx, int j, int k, double *cosines, double *sines) { if (j < 0) error(_("incorrect left cyclic shift, j (%d) < 0"), j); if (j >= k) error(_("incorrect left cyclic shift, j (%d) >= k (%d)"), j, k); if (ldx < k) error(_("incorrect left cyclic shift, k (%d) > ldx (%d)"), k, ldx); double *lastcol = (double *) R_alloc((size_t) k + 1, sizeof(double)); int i; /* keep a copy of column j */ for (i = 0; i <= j; i++) lastcol[i] = x[i + j*ldx]; /* For safety, zero the rest */ for (i = j+1; i <= k; i++) lastcol[i] = 0.; for (int jj = j+1, ind = 0; jj <= k; jj++, ind++) { /* columns to be shifted */ int diagind = jj*(ldx+1); // ind == (jj-j) - 1 double tmp = x[diagind], cc, ss; /* Calculate the Givens rotation. */ /* This modified the super-diagonal element */ F77_CALL(drotg)(x+diagind-1, &tmp, cosines+ind, sines+ind); cc = cosines[ind]; ss = sines[ind]; /* Copy column jj+1 to column jj. */ for (i = 0; i < jj; i++) x[i + (jj-1)*ldx] = x[i+jj*ldx]; /* Apply rotation to columns up to k */ for (i = jj; i < k; i++) { tmp = cc*x[(jj-1)+i*ldx] + ss*x[jj+i*ldx]; x[jj+i*ldx] = cc*x[jj+i*ldx] - ss*x[(jj-1)+i*ldx]; x[(jj-1)+i*ldx] = tmp; } /* Apply rotation to lastcol */ lastcol[jj] = -ss*lastcol[jj-1]; lastcol[jj-1] *= cc; } /* Copy lastcol to column k */ for(i = 0; i <= k; i++) x[i+k*ldx] = lastcol[i]; return 0; } static SEXP getGivens(double *x, int ldx, int jmin, int rank) { int shiftlen = (rank - jmin) - 1; SEXP ans = PROTECT(allocVector(VECSXP, 4)), nms, cosines, sines; SET_VECTOR_ELT(ans, 0, ScalarInteger(jmin)); SET_VECTOR_ELT(ans, 1, ScalarInteger(rank)); SET_VECTOR_ELT(ans, 2, cosines = allocVector(REALSXP, shiftlen)); SET_VECTOR_ELT(ans, 3, sines = allocVector(REALSXP, shiftlen)); setAttrib(ans, R_NamesSymbol, nms = allocVector(STRSXP, 4)); SET_STRING_ELT(nms, 0, mkChar("jmin")); SET_STRING_ELT(nms, 1, mkChar("rank")); SET_STRING_ELT(nms, 2, mkChar("cosines")); SET_STRING_ELT(nms, 3, mkChar("sines")); if (left_cyclic(x, ldx, jmin, rank - 1, REAL(cosines), REAL(sines))) error(_("unknown error in getGivens")); UNPROTECT(1); return ans; } static SEXP checkGivens(SEXP X, SEXP jmin, SEXP rank) { if (!(isReal(X) && isMatrix(X))) error(_("X must be a numeric (double precision) matrix")); SEXP ans = PROTECT(allocVector(VECSXP, 2)), Xcp = PROTECT(duplicate(X)); int Xdims = INTEGER(getAttrib(X, R_DimSymbol)); SET_VECTOR_ELT(ans, 0, Xcp); SET_VECTOR_ELT(ans, 1, getGivens(REAL(Xcp), Xdims[0], asInteger(jmin), asInteger(rank))); UNPROTECT(2); return ans; } SEXP lsq_dense_chol(SEXP X, SEXP y) { if (!(isReal(X) && isMatrix(X))) error(_("X must be a numeric (double precision) matrix")); if (!(isReal(y) && isMatrix(y))) error(_("y must be a numeric (double precision) matrix")); int *Xdims = INTEGER(getAttrib(X, R_DimSymbol)), *ydims = INTEGER(getAttrib(y, R_DimSymbol)); if (Xdims[0] != ydim[0]) error(_("number of rows in y (%d) does not match " "number of rows in X (%d)"), ydims[0], Xdims[0]); int n = Xdims[0], p = Xdims[1], k = ydims[1]; if (p < 1 || k < 1) return allocMatrix(REALSXP, p, k); SEXP ans = PROTECT(allocMatrix(REALSXP, p, k)); double d_one = 1.0, d_zero = 0.0, *xpx = (double *) R_alloc((size_t) p * p, sizeof(double)); int info; F77_CALL(dgemm)("T", "N", &p, &k, &n, &d_one, REAL(X), &n, REAL(y), &n, &d_zero, REAL(ans), &p FCONE FCONE); F77_CALL(dsyrk)("U", "T", &p, &n, &d_one, REAL(X), &n, &d_zero, xpx, &p FCONE FCONE); F77_CALL(dposv)("U", &p, &k, xpx, &p, REAL(ans), &p, &info FCONE); if (info) error(_("LAPACK dposv returned error code %d"), info); UNPROTECT(1); return ans; } SEXP lsq_dense_qr(SEXP X, SEXP y) { if (!(isReal(X) && isMatrix(X))) error(_("X must be a numeric (double precision) matrix")); if (!(isReal(y) && isMatrix(y))) error(_("y must be a numeric (double precision) matrix")); int *Xdims = INTEGER(getAttrib(X, R_DimSymbol)), *ydims = INTEGER(getAttrib(y, R_DimSymbol)); if (Xdims[0] != ydim[0]) error(_("number of rows in y (%d) does not match " "number of rows in X (%d)"), ydims[0], Xdims[0]); int n = Xdims[0], p = Xdims[1], k = ydims[1]; if (p < 1 || k < 1) return allocMatrix(REALSXP, p, k); SEXP ans = PROTECT(duplicate(y)); double *xvals = (double *) R_alloc((size_t) n * p, sizeof(double)), *work, tmp; int lwork = -1, info; Memcpy(xvals, REAL(X), (size_t) n * p); F77_CALL(dgels)("N", &n, &p, &k, xvals, &n, REAL(ans), &n, &tmp, &lwork, &info FCONE); if (info) error(_("LAPACK dgels returned error code %d"), info); lwork = (int) tmp; work = (double *) R_alloc((size_t) lwork, sizeof(double)); F77_CALL(dgels)("N", &n, &p, &k, xvals, &n, REAL(ans), &n, work, &lwork, &info FCONE); if (info) error(_("LAPACK dgels returned error code %d"), info); UNPROTECT(1); return ans; } /* Rank-Correcting/Adapting LAPACK QR Decomposition * From Doug Bates' initial import; __unused__ * * Provides a qr() with 'rcond' and rank reduction while(rcond < tol), * possibly via Givens rotations but WITHOUT PIVOTING * * .Call(Matrix:::lapack_qr, A, 1e-17) * --> ~/R/MM/Pkg-ex/Matrix/qr-rank-deficient.R * * TODO: export as Matrix::qrNoPiv() or qr1() or similar */ SEXP lapack_qr(SEXP Xin, SEXP tl) { if (!(isReal(Xin) && isMatrix(Xin))) error(_("X must be a real (numeric) matrix")); double tol = asReal(tl); if (tol < 0.0) error(_("tol, given as %g, must be >= 0"), tol); if (tol > 1.0) error(_("tol, given as %g, must be <= 1"), tol); SEXP ans = PROTECT(allocVector(VECSXP, 5)), X, qraux, pivot; int *Xdims = INTEGER(getAttrib(Xin, R_DimSymbol)), n = Xdims[0], p = Xdims[1], /* size of triangular part of decomposition : */ trsz = (n < p) ? n : p, i; SET_VECTOR_ELT(ans, 0, X = duplicate(Xin)); SET_VECTOR_ELT(ans, 2, qraux = allocVector(REALSXP, trsz)); SET_VECTOR_ELT(ans, 3, pivot = allocVector(INTSXP, p)); for (i = 0; i < p; i++) INTEGER(pivot)[i] = i + 1; SEXP nms, Givens = PROTECT(allocVector(VECSXP, trsz - 1)); setAttrib(ans, R_NamesSymbol, nms = allocVector(STRSXP, 5)); SET_STRING_ELT(nms, 0, mkChar("qr")); SET_STRING_ELT(nms, 1, mkChar("rank")); SET_STRING_ELT(nms, 2, mkChar("qraux")); SET_STRING_ELT(nms, 3, mkChar("pivot")); SET_STRING_ELT(nms, 4, mkChar("Givens")); int rank = trsz, nGivens = 0; double rcond = 0.0; if (n > 0 && p > 0) { double *xpt = REAL(X), *work, tmp; int *iwork, lwork, info; lwork = -1; F77_CALL(dgeqrf)(&n, &p, xpt, &n, REAL(qraux), &tmp, &lwork, &info); if (info) error(_("LAPACK dgeqrf returned error code %d"), info); lwork = (int) tmp; work = (double *) R_alloc(((size_t) lwork < (size_t) 3 * trsz) ? (size_t) 3 * trsz : (size_t) lwork, sizeof(double)); F77_CALL(dgeqrf)(&n, &p, xpt, &n, REAL(qraux), work, &lwork, &info); if (info) error(_("LAPACK dgeqrf returned error code %d"), info); iwork = (int *) R_alloc((size_t) trsz, sizeof(int)); F77_CALL(dtrcon)("1", "U", "N", &rank, xpt, &n, &rcond, work, iwork, &info FCONE FCONE FCONE); if (info) error(_("LAPACK dtrcon returned error code %d"), info); while (rcond < tol) { /* check diagonal elements */ double el, minabs = (xpt[0] < 0.0) ? -xpt[0]: xpt[0]; int jmin = 0; for (i = 1; i < rank; i++) { el = xpt[i*n]; // had i*(n+1) which looks wrong to MM if (el < 0.0) el = -el; if (el < minabs) { jmin = i; minabs = el; } } if (jmin < (rank - 1)) { SET_VECTOR_ELT(Givens, nGivens, getGivens(xpt, n, jmin, rank)); nGivens++; } // otherwise jmin == (rank - 1), so just "drop that column" rank--; // new rcond := ... for reduced rank F77_CALL(dtrcon)("1", "U", "N", &rank, xpt, &n, &rcond, work, iwork, &info FCONE FCONE FCONE); if (info) error(_("LAPACK dtrcon returned error code %d"), info); } } SEXP Gcpy; SET_VECTOR_ELT(ans, 1, ScalarInteger(rank)); SET_VECTOR_ELT(ans, 4, Gcpy = allocVector(VECSXP, nGivens)); for (i = 0; i < nGivens; i++) SET_VECTOR_ELT(Gcpy, i, VECTOR_ELT(Givens, i)); setAttrib(ans, install("useLAPACK"), ScalarLogical(1)); setAttrib(ans, install("rcond"), ScalarReal(rcond)); UNPROTECT(2); return ans; } #endif /* MJ */ ��������������Matrix/src/utils.h����������������������������������������������������������������������������������0000644�0001762�0000144�00000000640�14504647603�013627� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_UTILS_H #define MATRIX_UTILS_H #include /* size_t */ #include void *Matrix_memset(void *, int, R_xlen_t, size_t); void *Matrix_memcpy(void *, const void *, R_xlen_t, size_t); char *Matrix_sprintf(const char *, ...); int equal_character_vectors(SEXP, SEXP, int); void conjugate(SEXP); void zeroRe(SEXP); void zeroIm(SEXP); void naToOne(SEXP); #endif /* MATRIX_UTILS_H */ ������������������������������������������������������������������������������������������������Matrix/src/version.h��������������������������������������������������������������������������������0000644�0001762�0000144�00000000751�14532153466�014157� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_VERSION_H #define MATRIX_VERSION_H /* (version)_{10} = (major minor patch)_{256} */ #define MATRIX_PACKAGE_VERSION 67077 #define MATRIX_PACKAGE_MAJOR 1 #define MATRIX_PACKAGE_MINOR 6 #define MATRIX_PACKAGE_PATCH 5 #define MATRIX_ABI_VERSION 1 /* (version)_{10} = (major minor patch)_{256} */ #define MATRIX_SUITESPARSE_VERSION 330241 #define MATRIX_SUITESPARSE_MAJOR 5 #define MATRIX_SUITESPARSE_MINOR 10 #define MATRIX_SUITESPARSE_PATCH 1 #endif /* MATRIX_VERSION_H */ �����������������������Matrix/src/cs-etc.c���������������������������������������������������������������������������������0000644�0001762�0000144�00000025207�14516234475�013650� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "Mdefines.h" #include "cs-etc.h" int Matrix_cs_xtype; /* flag indicating use of cs_di_* or cs_ci_* */ Matrix_cs *M2CXS(SEXP obj, int values) { Matrix_cs *A = (Matrix_cs *) R_alloc(1, sizeof(Matrix_cs)); memset(A, 0, sizeof(Matrix_cs)); SEXP dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)), p = PROTECT(GET_SLOT(obj, Matrix_pSym)), i = PROTECT(GET_SLOT(obj, Matrix_iSym)), x = PROTECT(getAttrib(obj, Matrix_xSym)); A->m = INTEGER(dim)[0]; A->n = INTEGER(dim)[1]; A->p = INTEGER(p); A->i = INTEGER(i); A->nzmax = LENGTH(i); A->nz = -1; A->xtype = MCS_PATTERN; if (values && x != R_NilValue) { switch (TYPEOF(x)) { case CPLXSXP: A->xtype = MCS_COMPLEX; A->x = COMPLEX(x); break; case REALSXP: A->xtype = MCS_REAL; A->x = REAL(x); break; default: ERROR_INVALID_TYPE(x, __func__); break; } } UNPROTECT(4); return A; } SEXP CXS2M(Matrix_cs *A, int values, char shape) { if (values && A->xtype != MCS_REAL && A->xtype != MCS_COMPLEX) error(_("wrong '%s'"), "xtype"); char cl[] = "..CMatrix"; cl[0] = (!values || A->xtype == MCS_PATTERN) ? 'n' : ((A->xtype == MCS_COMPLEX) ? 'z' : 'd'); cl[1] = shape; int nnz = A->p[A->n]; R_xlen_t np1 = (R_xlen_t) A->n + 1; SEXP obj = PROTECT(newObject(cl)), dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)), p = PROTECT(allocVector(INTSXP, np1)), i = PROTECT(allocVector(INTSXP, nnz)); INTEGER(dim)[0] = A->m; INTEGER(dim)[1] = A->n; Matrix_memcpy(INTEGER(p), A->p, np1, sizeof(int)); Matrix_memcpy(INTEGER(i), A->i, nnz, sizeof(int)); SET_SLOT(obj, Matrix_pSym, p); SET_SLOT(obj, Matrix_iSym, i); if (cl[0] != 'n') { SEXP x; if (cl[0] == 'z') { PROTECT(x = allocVector(CPLXSXP, nnz)); Matrix_memcpy(COMPLEX(x), A->x, nnz, sizeof(Rcomplex)); } else { PROTECT(x = allocVector(REALSXP, nnz)); Matrix_memcpy(REAL(x), A->x, nnz, sizeof(double)); } SET_SLOT(obj, Matrix_xSym, x); UNPROTECT(1); } UNPROTECT(4); return obj; } /* Wrappers for the functions that we use at least once : */ Matrix_csd *Matrix_cs_dfree(Matrix_csd *D) { #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) return (Matrix_csd *) cs_ci_dfree((cs_cid *) D); else return (Matrix_csd *) cs_di_dfree((cs_did *) D); #else return (Matrix_csd *) cs_dfree((csd *) D); #endif } Matrix_csd *Matrix_cs_dmperm(const Matrix_cs *A, int seed) { #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) return (Matrix_csd *) cs_ci_dmperm((cs_ci *) A, seed); else return (Matrix_csd *) cs_di_dmperm((cs_di *) A, seed); #else return (Matrix_csd *) cs_dmperm((cs *) A, seed); #endif } int Matrix_cs_dropzeros(Matrix_cs *A) { #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) return cs_ci_dropzeros((cs_ci *) A); else return cs_di_dropzeros((cs_di *) A); #else return cs_dropzeros((cs *) A); #endif } void *Matrix_cs_free(void *p) { #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) return cs_ci_free(p); else return cs_di_free(p); #else return cs_free(p); #endif } int Matrix_cs_happly(const Matrix_cs *V, int i, double beta, void *x) { #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) return cs_ci_happly((cs_ci *) V, i, beta, (double _Complex *) x); else return cs_di_happly((cs_di *) V, i, beta, (double *) x); #else return cs_happly((cs *) V, i, beta, (double *) x); #endif } int Matrix_cs_ipvec(const int *p, const void *b, void *x, int n) { #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) return cs_ci_ipvec(p, (double _Complex *) b, (double _Complex *) x, n); else return cs_di_ipvec(p, (double *) b, (double *) x, n); #else return cs_ipvec(p, (double *) b, (double *) x, n); #endif } int Matrix_cs_lsolve(const Matrix_cs *L, void *x) { #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) return cs_ci_lsolve((cs_ci *) L, (double _Complex *) x); else return cs_di_lsolve((cs_di *) L, (double *) x); #else return cs_lsolve((cs *) L, (double *) x); #endif } Matrix_csn *Matrix_cs_lu(const Matrix_cs *A, const Matrix_css *S, double tol) { #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) return (Matrix_csn *) cs_ci_lu((cs_ci *) A, (cs_cis *) S, tol); else return (Matrix_csn *) cs_di_lu((cs_di *) A, (cs_dis *) S, tol); #else return (Matrix_csn *) cs_lu((cs *) A, (css *) S, tol); #endif } int Matrix_cs_lusol(int order, const Matrix_cs *A, void *b, double tol) { #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) return cs_ci_lusol(order, (cs_ci *) A, (double _Complex *) b, tol); else return cs_di_lusol(order, (cs_di *) A, (double *) b, tol); #else return cs_lusol(order, (cs *) A, (double *) b, tol); #endif } Matrix_csn *Matrix_cs_nfree(Matrix_csn *N) { #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) return (Matrix_csn *) cs_ci_nfree((cs_cin *) N); else return (Matrix_csn *) cs_di_nfree((cs_din *) N); #else return (Matrix_csn *) cs_nfree((csn *) N); #endif } Matrix_cs *Matrix_cs_permute(const Matrix_cs *A, const int *pinv, const int *q, int values) { Matrix_cs *B = NULL; #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) { cs_ci *tmp = cs_ci_permute((cs_ci *) A, pinv, q, values); B = (Matrix_cs *) cs_ci_calloc(1, sizeof(Matrix_cs)); memcpy(B, tmp, sizeof(cs_ci)); tmp = cs_ci_free(tmp); } else { cs_di *tmp = cs_di_permute((cs_di *) A, pinv, q, values); B = (Matrix_cs *) cs_di_calloc(1, sizeof(Matrix_cs)); memcpy(B, tmp, sizeof(cs_di)); tmp = cs_di_free(tmp); } #else cs *tmp = cs_permute((cs *) A, pinv, q, values); B = (Matrix_cs *) cs_calloc(1, sizeof(Matrix_cs)); memcpy(B, tmp, sizeof(cs )); tmp = cs_free(tmp); #endif B->xtype = MCS_XTYPE_GET(); return B; } int *Matrix_cs_pinv(const int *p, int n) { #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) return cs_ci_pinv(p, n); else return cs_di_pinv(p, n); #else return cs_pinv(p, n); #endif } int Matrix_cs_pvec(const int *p, const void *b, void *x, int n) { #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) return cs_ci_pvec(p, (double _Complex *) b, (double _Complex *) x, n); else return cs_di_pvec(p, (double *) b, (double *) x, n); #else return cs_pvec(p, (double *) b, (double *) x, n); #endif } Matrix_csn *Matrix_cs_qr(const Matrix_cs *A, const Matrix_css *S) { #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) return (Matrix_csn *) cs_ci_qr((cs_ci *) A, (cs_cis *) S); else return (Matrix_csn *) cs_di_qr((cs_di *) A, (cs_dis *) S); #else return (Matrix_csn *) cs_qr((cs *) A, (css *) S); #endif } int Matrix_cs_qrsol(int order, const Matrix_cs *A, void *b) { #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) return cs_ci_qrsol(order, (cs_ci *) A, (double _Complex *) b); else return cs_di_qrsol(order, (cs_di *) A, (double *) b); #else return cs_qrsol(order, (cs *) A, (double *) b); #endif } Matrix_css *Matrix_cs_sfree(Matrix_css *S) { #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) return (Matrix_css *) cs_ci_sfree((cs_cis *) S); else return (Matrix_css *) cs_di_sfree((cs_dis *) S); #else return (Matrix_css *) cs_sfree((css *) S); #endif } Matrix_cs *Matrix_cs_spalloc(int m, int n, int nzmax, int values, int triplet) { Matrix_cs *B = NULL; #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) { cs_ci *tmp = cs_ci_spalloc(m, n, nzmax, values, triplet); B = (Matrix_cs *) cs_ci_calloc(1, sizeof(Matrix_cs)); memcpy(B, tmp, sizeof(cs_ci)); tmp = cs_ci_free(tmp); } else { cs_di *tmp = cs_di_spalloc(m, n, nzmax, values, triplet); B = (Matrix_cs *) cs_di_calloc(1, sizeof(Matrix_cs)); memcpy(B, tmp, sizeof(cs_di)); tmp = cs_di_free(tmp); } #else cs *tmp = cs_spalloc(m, n, nzmax, values, triplet); B = (Matrix_cs *) cs_calloc(1, sizeof(Matrix_cs)); memcpy(B, tmp, sizeof(cs )); tmp = cs_free(tmp); #endif B->xtype = MCS_XTYPE_GET(); return B; } Matrix_cs *Matrix_cs_speye(int m, int n, int values, int triplet) { int k, d = (m < n) ? m : n; Matrix_cs *B = Matrix_cs_spalloc(m, n, d, values, triplet); if (!B) return NULL; int *B__p = B->p, *B__i = B->i; for (k = 0; k < d; ++k) B__p[k] = B__i[k] = k; if (!triplet) for (k = d; k <= n; ++k) B__p[k] = d; if (values) { #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) { double _Complex *B__x = (double _Complex *) B->x; for (k = 0; k < d; ++k) B__x[k] = 1.0; } else { #endif double *B__x = (double *) B->x; for (k = 0; k < d; ++k) B__x[k] = 1.0; #ifdef CXSPARSE } #endif } return B; } Matrix_cs *Matrix_cs_spfree(Matrix_cs *A) { #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) return (Matrix_cs *) cs_ci_spfree((cs_ci *) A); else return (Matrix_cs *) cs_di_spfree((cs_di *) A); #else return (Matrix_cs *) cs_spfree((cs *) A); #endif } int Matrix_cs_sprealloc(Matrix_cs *A, int nzmax) { #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) return cs_ci_sprealloc((cs_ci *) A, nzmax); else return cs_di_sprealloc((cs_di *) A, nzmax); #else return cs_sprealloc((cs *) A, nzmax); #endif } int Matrix_cs_spsolve(Matrix_cs *L, const Matrix_cs *B, int k, int *xi, void *x, const int *pinv, int lo) { #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) return cs_ci_spsolve((cs_ci *) L, (cs_ci *) B, k, xi, (double _Complex *) x, pinv, lo); else return cs_di_spsolve((cs_di *) L, (cs_di *) B, k, xi, (double *) x, pinv, lo); #else return cs_spsolve((cs *) L, (cs *) B, k, xi, (double *) x, pinv, lo); #endif } Matrix_css *Matrix_cs_sqr(int order, const Matrix_cs *A, int qr) { #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) return (Matrix_css *) cs_ci_sqr(order, (cs_ci *) A, qr); else return (Matrix_css *) cs_di_sqr(order, (cs_di *) A, qr); #else return (Matrix_css *) cs_sqr(order, (cs *) A, qr); #endif } Matrix_cs *Matrix_cs_transpose(const Matrix_cs *A, int values) { Matrix_cs *B = NULL; #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) { cs_ci *tmp = cs_ci_transpose((cs_ci *) A, values); B = (Matrix_cs *) cs_ci_calloc(1, sizeof(Matrix_cs)); memcpy(B, tmp, sizeof(cs_ci)); tmp = cs_ci_free(tmp); } else { cs_di *tmp = cs_di_transpose((cs_di *) A, values); B = (Matrix_cs *) cs_di_calloc(1, sizeof(Matrix_cs)); memcpy(B, tmp, sizeof(cs_di)); tmp = cs_di_free(tmp); } #else cs *tmp = cs_transpose((cs *) A, values); B = (Matrix_cs *) cs_calloc(1, sizeof(Matrix_cs)); memcpy(B, tmp, sizeof(cs )); tmp = cs_free(tmp); #endif B->xtype = MCS_XTYPE_GET(); return B; } int Matrix_cs_usolve(const Matrix_cs *U, void *x) { #ifdef CXSPARSE if (MCS_XTYPE_GET() == MCS_COMPLEX) return cs_ci_usolve((cs_ci *) U, (double _Complex *) x); else return cs_di_usolve((cs_di *) U, (double *) x); #else return cs_usolve((cs *) U, (double *) x); #endif } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/sparse.h���������������������������������������������������������������������������������0000644�0001762�0000144�00000002707�14503212600�013752� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_SPARSE_H #define MATRIX_SPARSE_H #include SEXP sparse_drop0(SEXP, const char *, double); SEXP R_sparse_drop0(SEXP, SEXP); SEXP sparse_diag_U2N(SEXP, const char *); SEXP R_sparse_diag_U2N(SEXP); SEXP sparse_diag_N2U(SEXP, const char *); SEXP R_sparse_diag_N2U(SEXP); SEXP sparse_band(SEXP, const char *, int, int); SEXP R_sparse_band(SEXP, SEXP, SEXP); SEXP sparse_diag_get(SEXP, const char *, int); SEXP R_sparse_diag_get(SEXP, SEXP); SEXP sparse_diag_set(SEXP, const char *, SEXP); SEXP R_sparse_diag_set(SEXP, SEXP); SEXP sparse_transpose(SEXP, const char *, int); SEXP R_sparse_transpose(SEXP, SEXP); SEXP sparse_force_symmetric(SEXP, const char *, char); SEXP R_sparse_force_symmetric(SEXP, SEXP); SEXP sparse_symmpart(SEXP, const char *); SEXP R_sparse_symmpart(SEXP); SEXP sparse_skewpart(SEXP, const char *); SEXP R_sparse_skewpart(SEXP); int sparse_is_symmetric(SEXP, const char *, int); SEXP R_sparse_is_symmetric(SEXP, SEXP); int sparse_is_triangular(SEXP, const char *, int); SEXP R_sparse_is_triangular(SEXP, SEXP); int sparse_is_diagonal(SEXP, const char *); SEXP R_sparse_is_diagonal(SEXP); SEXP sparse_marginsum(SEXP, const char *, int, int, int, int); SEXP R_sparse_marginsum(SEXP, SEXP, SEXP, SEXP, SEXP); SEXP sparse_sum(SEXP, const char *, int); SEXP R_sparse_sum(SEXP, SEXP); SEXP sparse_prod(SEXP, const char *, int); SEXP R_sparse_prod(SEXP, SEXP); SEXP Tsparse_aggregate(SEXP); #endif /* MATRIX_SPARSE_H */ ���������������������������������������������������������Matrix/src/objects.h��������������������������������������������������������������������������������0000644�0001762�0000144�00000000342�14511521056�014106� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_OBJECTS_H #define MATRIX_OBJECTS_H #include SEXP R_Matrix_nonvirtual(SEXP, SEXP); SEXP R_Matrix_kind (SEXP); SEXP R_Matrix_shape(SEXP); SEXP R_Matrix_repr (SEXP); #endif /* MATRIX_OBJECTS_H */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/dgeMatrix.c������������������������������������������������������������������������������0000644�0001762�0000144�00000017714�14503225712�014410� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "Lapack-etc.h" #include "Mdefines.h" #include "dgeMatrix.h" /* MJ: unused */ #if 0 SEXP dgeMatrix_svd(SEXP x, SEXP nnu, SEXP nnv) { int /* nu = asInteger(nnu), nv = asInteger(nnv), */ *dims = INTEGER(GET_SLOT(x, Matrix_DimSym)); double *xx = REAL(GET_SLOT(x, Matrix_xSym)); SEXP val = PROTECT(allocVector(VECSXP, 3)); if (dims[0] && dims[1]) { int m = dims[0], n = dims[1], mm = (m < n)?m:n, lwork = -1, info; double tmp, *work; int *iwork, n_iw = 8 * mm; if(8 * (double)mm != n_iw) // integer overflow error(_("dgeMatrix_svd(x,*): dim(x)[j] = %d is too large"), mm); Matrix_Calloc(iwork, n_iw, int); SET_VECTOR_ELT(val, 0, allocVector(REALSXP, mm)); SET_VECTOR_ELT(val, 1, allocMatrix(REALSXP, m, mm)); SET_VECTOR_ELT(val, 2, allocMatrix(REALSXP, mm, n)); F77_CALL(dgesdd)("S", &m, &n, xx, &m, REAL(VECTOR_ELT(val, 0)), REAL(VECTOR_ELT(val, 1)), &m, REAL(VECTOR_ELT(val, 2)), &mm, &tmp, &lwork, iwork, &info FCONE); lwork = (int) tmp; Matrix_Calloc(work, lwork, double); F77_CALL(dgesdd)("S", &m, &n, xx, &m, REAL(VECTOR_ELT(val, 0)), REAL(VECTOR_ELT(val, 1)), &m, REAL(VECTOR_ELT(val, 2)), &mm, work, &lwork, iwork, &info FCONE); Matrix_Free(iwork, n_iw); Matrix_Free(work, lwork); } UNPROTECT(1); return val; } #endif /* MJ */ const static double padec [] = /* for matrix exponential calculation. */ { 5.0000000000000000e-1, 1.1666666666666667e-1, 1.6666666666666667e-2, 1.6025641025641026e-3, 1.0683760683760684e-4, 4.8562548562548563e-6, 1.3875013875013875e-7, 1.9270852604185938e-9, }; /** * Matrix exponential - based on the _corrected_ code for Octave's expm function. * * @param x real square matrix to exponentiate * * @return matrix exponential of x */ SEXP dgeMatrix_exp(SEXP x) { const double one = 1.0, zero = 0.0; const int i1 = 1; int *Dims = INTEGER(GET_SLOT(x, Matrix_DimSym)); const int n = Dims[1]; const R_xlen_t n_ = n, np1 = n + 1, nsqr = n_ * n_; // nsqr = n^2 SEXP val = PROTECT(duplicate(x)); int i, ilo, ilos, ihi, ihis, j, sqpow; int *pivot = R_Calloc(n, int); double *dpp = R_Calloc(nsqr, double), /* denominator power Pade' */ *npp = R_Calloc(nsqr, double), /* numerator power Pade' */ *perm = R_Calloc(n, double), *scale = R_Calloc(n, double), *v = REAL(GET_SLOT(val, Matrix_xSym)), *work = R_Calloc(nsqr, double), inf_norm, m1_j/*= (-1)^j */, trshift; R_CheckStack(); if (n < 1 || Dims[0] != n) error(_("Matrix exponential requires square, non-null matrix")); if(n == 1) { v[0] = exp(v[0]); UNPROTECT(1); return val; } /* Preconditioning 1. Shift diagonal by average diagonal if positive. */ trshift = 0; /* determine average diagonal element */ for (i = 0; i < n; i++) trshift += v[i * np1]; trshift /= n; if (trshift > 0.) { /* shift diagonal by -trshift */ for (i = 0; i < n; i++) v[i * np1] -= trshift; } /* Preconditioning 2. Balancing with dgebal. */ F77_CALL(dgebal)("P", &n, v, &n, &ilo, &ihi, perm, &j FCONE); if (j) error(_("dgeMatrix_exp: LAPACK routine dgebal returned %d"), j); F77_CALL(dgebal)("S", &n, v, &n, &ilos, &ihis, scale, &j FCONE); if (j) error(_("dgeMatrix_exp: LAPACK routine dgebal returned %d"), j); /* Preconditioning 3. Scaling according to infinity norm */ inf_norm = F77_CALL(dlange)("I", &n, &n, v, &n, work FCONE); sqpow = (inf_norm > 0) ? (int) (1 + log(inf_norm)/log(2.)) : 0; if (sqpow < 0) sqpow = 0; if (sqpow > 0) { double scale_factor = 1.0; for (i = 0; i < sqpow; i++) scale_factor *= 2.; for (R_xlen_t i = 0; i < nsqr; i++) v[i] /= scale_factor; } /* Pade' approximation. Powers v^8, v^7, ..., v^1 */ Matrix_memset(npp, 0, nsqr, sizeof(double)); Matrix_memset(dpp, 0, nsqr, sizeof(double)); m1_j = -1; for (j = 7; j >=0; j--) { double mult = padec[j]; /* npp = m * npp + padec[j] *m */ F77_CALL(dgemm)("N", "N", &n, &n, &n, &one, v, &n, npp, &n, &zero, work, &n FCONE FCONE); for (R_xlen_t i = 0; i < nsqr; i++) npp[i] = work[i] + mult * v[i]; /* dpp = m * dpp + (m1_j * padec[j]) * m */ mult *= m1_j; F77_CALL(dgemm)("N", "N", &n, &n, &n, &one, v, &n, dpp, &n, &zero, work, &n FCONE FCONE); for (R_xlen_t i = 0; i < nsqr; i++) dpp[i] = work[i] + mult * v[i]; m1_j *= -1; } /* Zero power */ for (R_xlen_t i = 0; i < nsqr; i++) dpp[i] *= -1.; for (j = 0; j < n; j++) { npp[j * np1] += 1.; dpp[j * np1] += 1.; } /* Pade' approximation is solve(dpp, npp) */ F77_CALL(dgetrf)(&n, &n, dpp, &n, pivot, &j); if (j) error(_("dgeMatrix_exp: dgetrf returned error code %d"), j); F77_CALL(dgetrs)("N", &n, &n, dpp, &n, pivot, npp, &n, &j FCONE); if (j) error(_("dgeMatrix_exp: dgetrs returned error code %d"), j); Memcpy(v, npp, nsqr); /* Now undo all of the preconditioning */ /* Preconditioning 3: square the result for every power of 2 */ while (sqpow--) { F77_CALL(dgemm)("N", "N", &n, &n, &n, &one, v, &n, v, &n, &zero, work, &n FCONE FCONE); Memcpy(v, work, nsqr); } /* Preconditioning 2: apply inverse scaling */ for (j = 0; j < n; j++) { R_xlen_t jn = j * n_; for (i = 0; i < n; i++) v[i + jn] *= scale[i]/scale[j]; } /* 2 b) Inverse permutation (if not the identity permutation) */ if (ilo != 1 || ihi != n) { /* Martin Maechler's code */ #define SWAP_ROW(I,J) F77_CALL(dswap)(&n, &v[(I)], &n, &v[(J)], &n) #define SWAP_COL(I,J) F77_CALL(dswap)(&n, &v[(I)*n_], &i1, &v[(J)*n_], &i1) #define RE_PERMUTE(I) \ int p_I = (int) (perm[I]) - 1; \ SWAP_COL(I, p_I); \ SWAP_ROW(I, p_I) /* reversion of "leading permutations" : in reverse order */ for (i = (ilo - 1) - 1; i >= 0; i--) { RE_PERMUTE(i); } /* reversion of "trailing permutations" : applied in forward order */ for (i = (ihi + 1) - 1; i < n; i++) { RE_PERMUTE(i); } } /* Preconditioning 1: Trace normalization */ if (trshift > 0.) { double mult = exp(trshift); for (R_xlen_t i = 0; i < nsqr; i++) v[i] *= mult; } /* Clean up */ R_Free(work); R_Free(scale); R_Free(perm); R_Free(npp); R_Free(dpp); R_Free(pivot); UNPROTECT(1); return val; } SEXP dgeMatrix_Schur(SEXP x, SEXP vectors, SEXP isDGE) { // 'x' is either a traditional matrix or a dgeMatrix, as indicated by isDGE. int *dims, n, vecs = asLogical(vectors), is_dge = asLogical(isDGE), info, izero = 0, lwork = -1, nprot = 1; if(is_dge) { dims = INTEGER(GET_SLOT(x, Matrix_DimSym)); } else { // traditional matrix dims = INTEGER(getAttrib(x, R_DimSymbol)); if(!isReal(x)) { // may not be "numeric" .. x = PROTECT(coerceVector(x, REALSXP)); // -> maybe error nprot++; } } double *work, tmp; const char *nms[] = {"WR", "WI", "T", "Z", ""}; SEXP val = PROTECT(Rf_mkNamed(VECSXP, nms)); n = dims[0]; if (n != dims[1] || n < 1) error(_("dgeMatrix_Schur: argument x must be a non-null square matrix")); const R_xlen_t n2 = ((R_xlen_t)n) * n; // = n^2 SET_VECTOR_ELT(val, 0, allocVector(REALSXP, n)); SET_VECTOR_ELT(val, 1, allocVector(REALSXP, n)); SET_VECTOR_ELT(val, 2, allocMatrix(REALSXP, n, n)); Memcpy(REAL(VECTOR_ELT(val, 2)), REAL(is_dge ? GET_SLOT(x, Matrix_xSym) : x), n2); SET_VECTOR_ELT(val, 3, allocMatrix(REALSXP, vecs ? n : 0, vecs ? n : 0)); F77_CALL(dgees)(vecs ? "V" : "N", "N", NULL, dims, (double *) NULL, dims, &izero, (double *) NULL, (double *) NULL, (double *) NULL, dims, &tmp, &lwork, (int *) NULL, &info FCONE FCONE); if (info) error(_("dgeMatrix_Schur: first call to dgees failed")); lwork = (int) tmp; Matrix_Calloc(work, lwork, double); F77_CALL(dgees)(vecs ? "V" : "N", "N", NULL, dims, REAL(VECTOR_ELT(val, 2)), dims, &izero, REAL(VECTOR_ELT(val, 0)), REAL(VECTOR_ELT(val, 1)), REAL(VECTOR_ELT(val, 3)), dims, work, &lwork, (int *) NULL, &info FCONE FCONE); Matrix_Free(work, lwork); if (info) error(_("dgeMatrix_Schur: dgees returned code %d"), info); UNPROTECT(nprot); return val; } // dgeMatrix_Schur ����������������������������������������������������Matrix/src/Lapack-etc.h�����������������������������������������������������������������������������0000644�0001762�0000144�00000003757�14510016544�014436� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_LAPACK_ETC_H #define MATRIX_LAPACK_ETC_H /* Copy and paste from WRE : */ // before any R headers, or define in PKG_CPPFLAGS #ifndef USE_FC_LEN_T # define USE_FC_LEN_T #endif #include #ifdef PR18534fixed # define usePR18534fix #endif #include #ifndef FCONE # define FCONE #endif #define ERROR_LAPACK_1(_ROUTINE_, _INFO_) \ do { \ if ((_INFO_) < 0) \ error(_("LAPACK routine '%s': argument %d had illegal value"), \ #_ROUTINE_, -(_INFO_)); \ } while (0) #define ERROR_LAPACK_2(_ROUTINE_, _INFO_, _WARN_, _LETTER_) \ do { \ ERROR_LAPACK_1(_ROUTINE_, _INFO_); \ if ((_INFO_) > 0 && (_WARN_) > 0) { \ if (_WARN_ > 1) \ error (_("LAPACK routine '%s': matrix is exactly singular, %s[i,i]=0, i=%d"), \ #_ROUTINE_, #_LETTER_, (_INFO_)); \ else \ warning(_("LAPACK routine '%s': matrix is exactly singular, %s[i,i]=0, i=%d"), \ #_ROUTINE_, #_LETTER_, (_INFO_)); \ } \ } while (0) #define ERROR_LAPACK_3(_ROUTINE_, _INFO_, _WARN_, _NPROTECT_) \ do { \ ERROR_LAPACK_1(_ROUTINE_, _INFO_); \ if ((_INFO_) > 0 && (_WARN_) > 0) { \ if (_WARN_ > 1) \ error (_("LAPACK routine '%s': leading principal minor of order %d is not positive"), \ #_ROUTINE_, (_INFO_)); \ else { \ warning(_("LAPACK routine '%s': leading principal minor of order %d is not positive"), \ #_ROUTINE_, (_INFO_)); \ UNPROTECT(_NPROTECT_); \ return ScalarInteger(_INFO_); \ } \ } \ } while (0) #define ERROR_LAPACK_4(_ROUTINE_, _INFO_, _RANK_, _WARN_) \ do { \ ERROR_LAPACK_1(_ROUTINE_, _INFO_); \ if ((_INFO_) > 0 && (_WARN_) > 0) { \ if (_WARN_ > 1) \ error (_("LAPACK routine '%s': matrix is rank deficient or not positive definite, the _computed_ rank is %d"), \ #_ROUTINE_, (_RANK_)); \ else \ warning(_("LAPACK routine '%s': matrix is rank deficient or not positive definite, the _computed_ rank is %d"), \ #_ROUTINE_, (_RANK_)); \ } \ } while (0) #endif /* MATRIX_LAPACK_ETC_H */ �����������������Matrix/src/Csparse.c��������������������������������������������������������������������������������0000644�0001762�0000144�00000017117�14515650276�014073� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "Mdefines.h" #include "cs-etc.h" #include "cholmod-etc.h" #include "Csparse.h" /* .validateCsparse(x, sort.if.needed = TRUE) */ SEXP CsparseMatrix_validate_maybe_sorting(SEXP x) { #define MKMS(_FORMAT_, ...) mkString(Matrix_sprintf(_FORMAT_, __VA_ARGS__)) /* defined in ./chm_common.c : */ SEXP checkpi(SEXP p, SEXP i, int m, int n); SEXP dim = GET_SLOT(x, Matrix_DimSym); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; SEXP p = PROTECT(GET_SLOT(x, Matrix_pSym)), i = PROTECT(GET_SLOT(x, Matrix_iSym)), cpi = PROTECT(checkpi(p, i, m, n)); if (TYPEOF(cpi) == LGLSXP && !LOGICAL(cpi)[0]) { cholmod_sparse *A = M2CHS(x, 1); A->sorted = 0; if (!cholmod_sort(A, &c)) error(_("'%s' failed"), "cholmod_sort"); int *pp = (int *) A->p, *pi = (int *) A->i, i0, ik, j, k, kend; for (j = 1, k = 0; j <= n; ++j) { kend = pp[j]; i0 = -1; while (k < kend) { ik = pi[k]; if (ik <= i0) { UNPROTECT(3); /* cpi, i, p */ return MKMS(_("'%s' slot is not increasing within columns after sorting"), "i"); } i0 = ik; ++k; } } LOGICAL(cpi)[0] = 1; } UNPROTECT(3); /* cpi, i, p */ return cpi; } static int strmatch(const char *x, const char **valid) { int i = 0; while (valid[i][0] != '\0') { if (strcmp(x, valid[i]) == 0) return i; ++i; } return -1; } /* (diag(obj)) where obj=dCHMsimpl (LDLt) or obj=dtCMatrix (nonunit) */ SEXP tCsparse_diag(SEXP obj, SEXP op) { static const char *valid[] = { /* 0 */ "trace", /* 1 */ "sumLog", /* 2 */ "prod", /* 3 */ "min", /* 4 */ "max", /* 5 */ "range", /* 6 */ "diag", /* 7 */ "diagBack", ""}; int ivalid = -1; if (TYPEOF(op) != STRSXP || LENGTH(op) < 1 || (op = STRING_ELT(op, 0)) == NA_STRING || (ivalid = strmatch(CHAR(op), valid)) < 0) error(_("invalid '%s' to '%s'"), "op", __func__); SEXP uplo = getAttrib(obj, Matrix_uploSym); char ul = (TYPEOF(uplo) == STRSXP && LENGTH(uplo) > 0) ? *CHAR(STRING_ELT(uplo, 0)) : 'L'; SEXP p = PROTECT(GET_SLOT(obj, Matrix_pSym)); int *pp = INTEGER(p) + 1, j, k = 0, kend, n = (int) (XLENGTH(p) - 1), len = (ivalid < 5) ? 1 : ((ivalid < 6) ? 2 : n); SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)); double *px = REAL(x), tmp; SEXP ans = PROTECT(allocVector(REALSXP, len)); double *pans = REAL(ans); switch (ivalid) { case 0: /* trace */ pans[0] = 0.0; for (j = 0; j < n; ++j) { kend = pp[j]; if (k < kend) pans[0] += px[(ul == 'U') ? kend - 1 : k]; k = kend; } break; case 1: /* sumLog */ pans[0] = 0.0; for (j = 0; j < n; ++j) { kend = pp[j]; if (k < kend) pans[0] += log(px[(ul == 'U') ? kend - 1 : k]); k = kend; } break; case 2: /* prod */ pans[0] = 1.0; for (j = 0; j < n; ++j) { kend = pp[j]; if (k < kend) pans[0] *= px[(ul == 'U') ? kend - 1 : k]; else pans[0] *= 0.0; k = kend; } break; case 3: /* min */ pans[0] = R_PosInf; for (j = 0; j < n; ++j) { kend = pp[j]; tmp = (k < kend) ? px[(ul == 'U') ? kend - 1 : k] : 0.0; if (ISNAN(tmp)) { pans[0] = tmp; break; } else if (tmp < pans[0]) pans[0] = tmp; k = kend; } break; case 4: /* max */ pans[0] = R_NegInf; for (j = 0; j < n; ++j) { kend = pp[j]; tmp = (k < kend) ? px[(ul == 'U') ? kend - 1 : k] : 0.0; if (ISNAN(tmp)) { pans[0] = tmp; break; } else if (tmp > pans[0]) pans[0] = tmp; k = kend; } break; case 5: /* range */ pans[0] = R_PosInf; pans[1] = R_NegInf; for (j = 0; j < n; ++j) { kend = pp[j]; tmp = (k < kend) ? px[(ul == 'U') ? kend - 1 : k] : 0.0; if (ISNAN(tmp)) { pans[0] = pans[1] = tmp; break; } else if (tmp < pans[0]) pans[0] = tmp; else if (tmp > pans[1]) pans[1] = tmp; k = kend; } break; case 6: /* diag */ case 7: /* diagBack */ { int *pperm = NULL; if (ivalid == 7) { SEXP perm = getAttrib(obj, Matrix_permSym); if (TYPEOF(perm) == INTSXP && LENGTH(perm) == n) pperm = INTEGER(perm); } for (j = 0; j < n; ++j) { kend = pp[j]; pans[(pperm) ? pperm[j] : j] = (k < kend) ? px[(ul == 'U') ? kend - 1 : k] : 0.0; k = kend; } break; } default: break; } UNPROTECT(3); return ans; } enum x_slot_kind { x_unknown = -2, /* NA */ x_pattern = -1, /* n */ x_double = 0, /* d */ x_logical = 1, /* l */ x_integer = 2, /* i */ x_complex = 3}; /* z */ /* x[i, j] <- value where x=<.[gt]CMatrix> and value=<.sparseVector> */ #define _n_Csp_ #include "t_Csparse_subassign.c" #define _l_Csp_ #include "t_Csparse_subassign.c" #define _i_Csp_ #include "t_Csparse_subassign.c" #define _d_Csp_ #include "t_Csparse_subassign.c" #define _z_Csp_ #include "t_Csparse_subassign.c" /* dmperm(x, nAns, seed) */ SEXP Csparse_dmperm(SEXP x, SEXP nans, SEXP seed) { Matrix_cs *A = M2CXS(x, 0); MCS_XTYPE_SET(A->xtype); Matrix_csd *D = Matrix_cs_dmperm(A, asInteger(seed)); if (!D) return R_NilValue; /* MJ: why not an error ... ? */ int len = asInteger(nans); if (len < 0) len = 0; else if (len > 6) len = 6; SEXP nms = PROTECT(allocVector(STRSXP, len)), ans = PROTECT(allocVector(VECSXP, len)), tmp; int k = len - 1; switch (len) { case 6: SET_STRING_ELT(nms, k, mkChar("cc5")); tmp = allocVector(INTSXP, 5); memcpy(INTEGER(tmp), D->cc, 5 * sizeof(int)); SET_VECTOR_ELT(ans, k, tmp); k--; case 5: SET_STRING_ELT(nms, k, mkChar("rr5")); tmp = allocVector(INTSXP, 5); memcpy(INTEGER(tmp), D->rr, 5 * sizeof(int)); SET_VECTOR_ELT(ans, k, tmp); k--; case 4: SET_STRING_ELT(nms, k, mkChar("s")); tmp = allocVector(INTSXP, D->nb + 1); memcpy(INTEGER(tmp), D->s, (D->nb + 1) * sizeof(int)); SET_VECTOR_ELT(ans, k, tmp); k--; case 3: SET_STRING_ELT(nms, k, mkChar("r")); tmp = allocVector(INTSXP, D->nb + 1); memcpy(INTEGER(tmp), D->r, (D->nb + 1) * sizeof(int)); SET_VECTOR_ELT(ans, k, tmp); k--; case 2: SET_STRING_ELT(nms, k, mkChar("q")); tmp = allocVector(INTSXP, A->n); for (int j = 0, *q0 = D->q, *q1 = INTEGER(tmp); j < A->n; ++j) q1[j] = q0[j] + 1; SET_VECTOR_ELT(ans, k, tmp); k--; case 1: SET_STRING_ELT(nms, k, mkChar("p")); tmp = allocVector(INTSXP, A->m); for (int i = 0, *p0 = D->p, *p1 = INTEGER(tmp); i < A->m; ++i) p1[i] = p0[i] + 1; SET_VECTOR_ELT(ans, k, tmp); k--; default: break; } D = Matrix_cs_dfree(D); setAttrib(ans, R_NamesSymbol, nms); UNPROTECT(2); return ans; } /* writeMM(obj, file) */ SEXP Csparse_MatrixMarket(SEXP obj, SEXP path) { static const char *valid[] = { VALID_CSPARSE, "" }; int ivalid = R_check_class_etc(obj, valid); if (ivalid < 0) ERROR_INVALID_CLASS(obj, __func__); const char *class = valid[ivalid]; PROTECT_INDEX pid; PROTECT_WITH_INDEX(obj, &pid); if (class[0] == 'l' || class[1] == 'i') { /* defined in ./coerce.c : */ SEXP sparse_as_kind(SEXP, const char *, char); REPROTECT(obj = sparse_as_kind(obj, class, 'd'), pid); class = valid[R_check_class_etc(obj, valid)]; } if (class[1] == 't') { /* defined in ./coerce.c : */ SEXP sparse_as_general(SEXP, const char *); REPROTECT(obj = sparse_as_general(obj, class), pid); class = valid[R_check_class_etc(obj, valid)]; } cholmod_sparse *A = M2CHS(obj, 1); if (class[1] == 's') { SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = *CHAR(STRING_ELT(uplo, 0)); A->stype = (ul == 'U') ? 1 : -1; } const char *path_ = CHAR(asChar(path)); FILE *f = fopen(path_, "w"); if (!f) error(_("failed to open file \"%s\" for writing"), path_); if (!cholmod_write_sparse(f, A, (cholmod_sparse *) NULL, (char *) NULL, &c)) error(_("'%s' failed"), "cholmod_write_sparse"); fclose(f); UNPROTECT(1); return R_NilValue; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/Makevars���������������������������������������������������������������������������������0000644�0001762�0000144�00000002112�14510017402�013767� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- Makefile -*- PKG_CPPFLAGS = -I./SuiteSparse_config -DNTIMER PKG_CFLAGS = $(C_VISIBILITY) PKG_LIBS = $(SUBLIBS) $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS) MkInclude = $(R_HOME)/etc${R_ARCH}/Makeconf include scripts/SOURCES_C.mkf OBJECTS = $(SOURCES_C:.c=.o) SUBDIRS = CHOLMOD COLAMD AMD SuiteSparse_config SUBLIBS = $(SUBDIRS:=.a) all: $(SHLIB) ## making src/*.o and in sublibs can be done simultaneously # for development: #$(SHLIB): $(OBJECTS) sublibraries # for real: $(SHLIB): $(OBJECTS) sublibs ## We have to clean here, to clean up between architectures: ## INSTALL only cleans src/*.o src/*$(SHLIB_EXT) for each arch sublibs: subclean sublibraries sublibraries: subclean @for d in $(SUBDIRS); do \ (cd $${d} && CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" MAKE="$(MAKE) -f \"$(MkInclude)\" -f Makefile" $(MAKE) -f "$(MkInclude)" -f Makefile library) || exit 1; \ done clean: subclean @-rm -rf .libs _libs @-rm -f *.o $(SHLIB) subclean: @-rm -f *.a @for d in $(SUBDIRS); do \ (cd $${d} && MkInclude="$(MkInclude)" $(MAKE) clean) || exit 1; \ done include scripts/DEPS.mkf ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/products.h�������������������������������������������������������������������������������0000644�0001762�0000144�00000000416�14503212600�014313� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_PRODUCTS_H #define MATRIX_PRODUCTS_H #include SEXP R_dense_matmult(SEXP, SEXP, SEXP, SEXP); SEXP R_sparse_matmult(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); SEXP R_diagonal_matmult(SEXP, SEXP, SEXP, SEXP, SEXP); #endif /* MATRIX_PRODUCTS_H */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/bind.h�����������������������������������������������������������������������������������0000644�0001762�0000144�00000000165�14503212600�013365� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_BIND_H #define MATRIX_BIND_H #include SEXP R_bind(SEXP); #endif /* MATRIX_BIND_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/abIndex.h��������������������������������������������������������������������������������0000644�0001762�0000144�00000000252�14503212600�014020� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_ABINDEX_H #define MATRIX_ABINDEX_H #include SEXP Matrix_rle_i(SEXP, SEXP); SEXP Matrix_rle_d(SEXP, SEXP); #endif /* MATRIX_ABINDEX_H */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/dgCMatrix.c������������������������������������������������������������������������������0000644�0001762�0000144�00000007664�14511304746�014355� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "Mdefines.h" #include "cs-etc.h" #include "cholmod-etc.h" #include "dgCMatrix.h" /* TODO: support NCOL(b) > 1 */ SEXP dgCMatrix_lusol(SEXP a, SEXP b) { Matrix_cs *A = M2CXS(a, 1); MCS_XTYPE_SET(MCS_REAL); PROTECT(b = (TYPEOF(b) == REALSXP) ? duplicate(b) : coerceVector(b, REALSXP)); if (A->m != A->n || A->m <= 0) error(_("'%s' is empty or not square"), "a"); if (LENGTH(b) != A->m) error(_("dimensions of '%s' and '%s' are inconsistent"), "a", "b"); if (!Matrix_cs_lusol(1, A, REAL(b), 1e-07)) error(_("'%s' failed"), "cs_lusol"); UNPROTECT(1); return b; } /* called from package MatrixModels's R code : */ /* TODO: support NCOL(b) > 1 */ /* TODO: give result list(L, coef, Xty, resid) */ SEXP dgCMatrix_qrsol(SEXP a, SEXP b, SEXP order) { /* FIXME? 'cs_qrsol' supports underdetermined systems. */ /* We should only require LENGTH(b) = max(m, n). */ int order_ = asInteger(order); if (order_ < 0 || order_ > 3) order_ = 0; Matrix_cs *A = M2CXS(a, 1); MCS_XTYPE_SET(MCS_REAL); PROTECT(b = (TYPEOF(b) == REALSXP) ? duplicate(b) : coerceVector(b, REALSXP)); if (LENGTH(b) != A->m) error(_("dimensions of '%s' and '%s' are inconsistent"), "a", "b"); if (A->n <= 0 || A->n > A->m) error(_("%s(%s, %s) requires m-by-n '%s' with m >= n > 0"), "dgCMatrix_qrsol", "a", "b", "a"); if (!Matrix_cs_qrsol(order_, A, REAL(b))) error(_("'%s' failed"), "cs_qrsol"); if (A->n < A->m) { SEXP tmp = allocVector(REALSXP, A->n); Matrix_memcpy(REAL(tmp), REAL(b), A->n, sizeof(double)); b = tmp; } UNPROTECT(1); return b; } /* called from package MatrixModels's R code : */ /* TODO: support NCOL(b) > 1 */ SEXP dgCMatrix_cholsol(SEXP at, SEXP b) { /* Find least squares solution of A * X = B, given A' and B : */ cholmod_sparse *At = M2CHS(at, 1); PROTECT(b = coerceVector(b, REALSXP)); if (LENGTH(b) != At->ncol) error(_("dimensions of '%s' and '%s' are inconsistent"), "at", "b"); if (At->ncol <= 0 || At->ncol < At->nrow) error(_("%s(%s, %s) requires m-by-n '%s' with n >= m > 0"), "dgCMatrix_cholsol", "at", "b", "at"); double zero[] = { 0.0, 0.0 }, one[] = {1.0, 0.0}, mone[] = { -1.0, 0.0 }; /* L * L' = A' * A */ cholmod_factor *L = cholmod_analyze(At, &c); if (!cholmod_factorize(At, L, &c)) error(_("'%s' failed"), "cholmod_factorize"); cholmod_dense *B = (cholmod_dense *) R_alloc(1, sizeof(cholmod_dense)); memset(B, 0, sizeof(cholmod_dense)); B->nrow = B->d = B->nzmax = LENGTH(b); B->ncol = 1; B->x = REAL(b); B->dtype = CHOLMOD_DOUBLE; B->xtype = CHOLMOD_REAL; /* A' * B = 1 * A' * B + 0 * */ cholmod_dense *AtB = cholmod_allocate_dense( At->nrow, 1, At->nrow, CHOLMOD_REAL, &c); if (!cholmod_sdmult(At, 0, one, zero, B, AtB, &c)) error(_("'%s' failed"), "cholmod_sdmult"); /* C := solve(A' * A, A' * B) = solve(L', solve(L, A' * B)) */ cholmod_dense *C = cholmod_solve(CHOLMOD_A, L, AtB, &c); if (!C) error(_("'%s' failed"), "cholmod_solve"); /* R := A * A' * C - B = 1 * (A')' * A' * X + (-1) * B */ cholmod_dense *R = cholmod_copy_dense(B, &c); if (!cholmod_sdmult(At, 1, mone, one, C, R, &c)) error(_("'%s' failed"), "cholmod_sdmult"); const char *nms[] = {"L", "coef", "Xty", "resid", ""}; SEXP ans = PROTECT(Rf_mkNamed(VECSXP, nms)), tmp; /* L : */ PROTECT(tmp = CHF2M(L, 1)); SET_VECTOR_ELT(ans, 0, tmp); /* coef : */ PROTECT(tmp = allocVector(REALSXP, At->nrow)); Matrix_memcpy(REAL(tmp), C->x, At->nrow, sizeof(double)); SET_VECTOR_ELT(ans, 1, tmp); /* Xty : */ PROTECT(tmp = allocVector(REALSXP, At->nrow)); Matrix_memcpy(REAL(tmp), AtB->x, At->nrow, sizeof(double)); SET_VECTOR_ELT(ans, 2, tmp); /* resid : */ PROTECT(tmp = allocVector(REALSXP, At->ncol)); Matrix_memcpy(REAL(tmp), R->x, At->ncol, sizeof(double)); SET_VECTOR_ELT(ans, 3, tmp); cholmod_free_factor(& L, &c); cholmod_free_dense (&AtB, &c); cholmod_free_dense (& C, &c); cholmod_free_dense (& R, &c); UNPROTECT(6); return ans; } ����������������������������������������������������������������������������Matrix/src/perm.c�����������������������������������������������������������������������������������0000644�0001762�0000144�00000010205�14503225712�013413� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "Mdefines.h" #include "perm.h" int isPerm(const int *p, int n, int off) { int res = 1; if (n <= 0) return res; int i, j; char *work; Matrix_Calloc(work, n, char); for (i = 0; i < n; ++i) { if (p[i] == NA_INTEGER || (j = p[i] - off) < 0 || j >= n || work[j]) { res = 0; break; } work[j] = 1; } Matrix_Free(work, n); return res; } int signPerm(const int *p, int n, int off) { if (!isPerm(p, n, off)) error(_("attempt to get sign of non-permutation")); int sign = 1; if (n <= 0) return sign; int i, pos = 0; char *work; Matrix_Calloc(work, n, char); while (pos < n) { work[pos] = 1; i = p[pos] - off; while (!work[i]) { /* transposition */ sign = -sign; work[i] = 1; i = p[i] - off; } while (pos < n && work[pos]) ++pos; } Matrix_Free(work, n); return sign; } void invertPerm(const int *p, int *ip, int n, int off, int ioff) { if (!isPerm(p, n, off)) error(_("attempt to invert non-permutation")); int j; for (j = 0; j < n; ++j) ip[p[j] - off] = j + ioff; return; } void asPerm(const int *p, int *ip, int m, int n, int off, int ioff) { int i, j, tmp; for (i = 0; i < n; ++i) ip[i] = i + ioff; for (i = 0; i < m; ++i) { j = p[i] - off; if (j < 0 || j >= n) error(_("invalid transposition vector")); if (j != i) { tmp = ip[j]; ip[j] = ip[i]; ip[i] = tmp; } } return; } SEXP R_isPerm(SEXP p, SEXP off) { if (TYPEOF(p) != INTSXP) error(_("'%s' is not of type \"%s\""), "p", "integer"); if (TYPEOF(off) != INTSXP) error(_("'%s' is not of type \"%s\""), "off", "integer"); if (XLENGTH(off) != 1) error(_("'%s' does not have length %d"), "off", 1); int off_ = INTEGER(off)[0]; if (off_ == NA_INTEGER) error(_("'%s' is NA"), "off"); R_xlen_t n_ = XLENGTH(p); if (n_ > INT_MAX) return ScalarLogical(0); return ScalarLogical(isPerm(INTEGER(p), (int) n_, off_)); } SEXP R_signPerm(SEXP p, SEXP off) { if (TYPEOF(p) != INTSXP) error(_("'%s' is not of type \"%s\""), "p", "integer"); if (TYPEOF(off) != INTSXP) error(_("'%s' is not of type \"%s\""), "off", "integer"); if (XLENGTH(off) != 1) error(_("'%s' does not have length %d"), "off", 1); int off_ = INTEGER(off)[0]; if (off_ == NA_INTEGER) error(_("'%s' is NA"), "off"); R_xlen_t n_ = XLENGTH(p); if (n_ > INT_MAX) error(_("attempt to get sign of non-permutation")); return ScalarInteger(signPerm(INTEGER(p), (int) n_, off_)); } SEXP R_invertPerm(SEXP p, SEXP off, SEXP ioff) { if (TYPEOF(p) != INTSXP) error(_("'%s' is not of type \"%s\""), "p", "integer"); if (TYPEOF(off) != INTSXP || TYPEOF(ioff) != INTSXP) error(_("'%s' or '%s' is not of type \"%s\""), "off", "ioff", "integer"); if (XLENGTH(off) != 1 || XLENGTH(ioff) != 1) error(_("'%s' or '%s' does not have length %d"), "off", "ioff", 1); int off_ = INTEGER(off)[0], ioff_ = INTEGER(ioff)[0]; if (off_ == NA_INTEGER || ioff_ == NA_INTEGER) error(_("'%s' or '%s' is NA"), "off", "ioff"); R_xlen_t n_ = XLENGTH(p); if (n_ > INT_MAX) error(_("attempt to invert non-permutation")); SEXP ip = PROTECT(allocVector(INTSXP, n_)); invertPerm(INTEGER(p), INTEGER(ip), (int) n_, off_, ioff_); UNPROTECT(1); return ip; } SEXP R_asPerm(SEXP p, SEXP off, SEXP ioff, SEXP n) { if (TYPEOF(p) != INTSXP) error(_("'%s' is not of type \"%s\""), "p", "integer"); R_xlen_t m_ = XLENGTH(p); if (m_ > INT_MAX) error(_("'%s' has length exceeding %s"), "p", "2^31-1"); if (TYPEOF(off) != INTSXP || TYPEOF(ioff) != INTSXP) error(_("'%s' or '%s' is not of type \"%s\""), "off", "ioff", "integer"); if (XLENGTH(off) != 1 || XLENGTH(ioff) != 1) error(_("'%s' or '%s' does not have length %d"), "off", "ioff", 1); int off_ = INTEGER(off)[0], ioff_ = INTEGER(ioff)[0]; if (off_ == NA_INTEGER || ioff_ == NA_INTEGER) error(_("'%s' or '%s' is NA"), "off", "ioff"); if (TYPEOF(n) != INTSXP) error(_("'%s' is not of type \"%s\""), "n", "integer"); if (XLENGTH(n) != 1) error(_("'%s' does not have length %d"), "n", 1); int n_ = INTEGER(n)[0]; if (n_ == NA_INTEGER || n_ < m_) error(_("'%s' is NA or less than %s"), "n", "length(p)"); SEXP ip = PROTECT(allocVector(INTSXP, n_)); asPerm(INTEGER(p), INTEGER(ip), (int) m_, n_, off_, ioff_); UNPROTECT(1); return ip; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/dgeMatrix.h������������������������������������������������������������������������������0000644�0001762�0000144�00000000263�14503212600�014374� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_DGEMATRIX_H #define MATRIX_DGEMATRIX_H #include SEXP dgeMatrix_Schur(SEXP, SEXP, SEXP); SEXP dgeMatrix_exp(SEXP); #endif /* MATRIX_DGEMATRIX_H */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/objects.c��������������������������������������������������������������������������������0000644�0001762�0000144�00000006271�14511521056�014110� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "Mdefines.h" #include "objects.h" SEXP newObject(const char *what) { SEXP class = PROTECT(R_do_MAKE_CLASS(what)), obj = R_do_new_object(class); UNPROTECT(1); return obj; } char typeToKind(SEXPTYPE type) { switch (type) { case LGLSXP: return 'l'; case INTSXP: return 'i'; case REALSXP: return 'd'; case CPLXSXP: return 'z'; default: error(_("unexpected type \"%s\" in '%s'"), type2char(type), __func__); return '\0'; } } SEXPTYPE kindToType(char kind) { switch (kind) { case 'n': case 'l': return LGLSXP; case 'i': return INTSXP; case 'd': return REALSXP; case 'z': return CPLXSXP; default: error(_("unexpected kind \"%c\" in '%s'"), kind, __func__); return NILSXP; } } size_t kindToSize(char kind) { switch (kind) { case 'n': case 'l': case 'i': return sizeof(int); case 'd': return sizeof(double); case 'z': return sizeof(Rcomplex); default: error(_("unexpected kind \"%c\" in '%s'"), kind, __func__); return 0; } } const char *Matrix_nonvirtual(SEXP obj, int strict) { if (!IS_S4_OBJECT(obj)) return ""; static const char *valid[] = { VALID_NONVIRTUAL, "" }; int ivalid = R_check_class_etc(obj, valid); if (ivalid < 0) return ""; if (!strict) ivalid += VALID_NONVIRTUAL_SHIFT(ivalid, 1); return valid[ivalid]; } char Matrix_kind(SEXP obj) { if (IS_S4_OBJECT(obj)) { static const char *valid[] = { VALID_NONVIRTUAL, "" }; int ivalid = R_check_class_etc(obj, valid); if (ivalid < 0) return '\0'; ivalid += VALID_NONVIRTUAL_SHIFT(ivalid, 1); const char *cl = valid[ivalid]; return (cl[2] == 'd') ? 'n' : cl[0]; } else { switch (TYPEOF(obj)) { case LGLSXP: return 'l'; case INTSXP: return 'i'; case REALSXP: return 'd'; case CPLXSXP: return 'z'; default: return '\0'; } } } char Matrix_shape(SEXP obj) { if (!IS_S4_OBJECT(obj)) return '\0'; static const char *valid[] = { VALID_NONVIRTUAL, "" }; int ivalid = R_check_class_etc(obj, valid); if (ivalid < 0) return '\0'; ivalid += VALID_NONVIRTUAL_SHIFT(ivalid, 1); const char *cl = valid[ivalid]; return (cl[2] == 'd' || cl[3] != 'M') ? 'g' : cl[1]; } char Matrix_repr(SEXP obj) { if (!IS_S4_OBJECT(obj)) return '\0'; static const char *valid[] = { VALID_NONVIRTUAL_MATRIX, "" }; int ivalid = R_check_class_etc(obj, valid); if (ivalid < 0) return '\0'; ivalid += VALID_NONVIRTUAL_SHIFT(ivalid, 1); const char *cl = valid[ivalid]; switch (cl[2]) { case 'e': case 'y': case 'r': return 'u'; /* unpackedMatrix */ case 'p': return 'p'; /* packedMatrix */ case 'C': case 'R': case 'T': return cl[2]; /* [CRT]sparseMatrix */ case 'i': return 'd'; /* diagonalMatrix */ case 'd': return 'i'; /* indMatrix */ default: return '\0'; } } SEXP R_Matrix_nonvirtual(SEXP obj, SEXP strict) { return mkString(Matrix_nonvirtual(obj, asLogical(strict))); } #define RETURN_AS_STRSXP(_C_) \ do { \ char c = _C_; \ if (!c) \ return mkString(""); \ else { \ char s[] = { c, '\0' }; \ return mkString(s); \ } \ } while (0) SEXP R_Matrix_kind(SEXP obj) { RETURN_AS_STRSXP(Matrix_kind (obj)); } SEXP R_Matrix_shape(SEXP obj) { RETURN_AS_STRSXP(Matrix_shape(obj)); } SEXP R_Matrix_repr(SEXP obj) { RETURN_AS_STRSXP(Matrix_repr (obj)); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/Csparse.h��������������������������������������������������������������������������������0000644�0001762�0000144�00000001003�14504647603�014061� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_CSPARSE_H #define MATRIX_CSPARSE_H #include SEXP CsparseMatrix_validate_maybe_sorting(SEXP); SEXP tCsparse_diag(SEXP, SEXP); SEXP nCsparse_subassign(SEXP, SEXP, SEXP, SEXP); SEXP lCsparse_subassign(SEXP, SEXP, SEXP, SEXP); SEXP iCsparse_subassign(SEXP, SEXP, SEXP, SEXP); SEXP dCsparse_subassign(SEXP, SEXP, SEXP, SEXP); SEXP zCsparse_subassign(SEXP, SEXP, SEXP, SEXP); SEXP Csparse_dmperm(SEXP, SEXP, SEXP); SEXP Csparse_MatrixMarket(SEXP, SEXP); #endif /* MATRIX_CSPARSE_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/AMD/�������������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14547723665�012731� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/AMD/Include/�����������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14547723665�014314� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/AMD/Include/amd.h������������������������������������������������������������������������0000644�0001762�0000144�00000042635�13652535054�015225� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================= */ /* === AMD: approximate minimum degree ordering =========================== */ /* ========================================================================= */ /* ------------------------------------------------------------------------- */ /* AMD Version 2.4, Copyright (c) 1996-2013 by Timothy A. Davis, */ /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ /* email: DrTimothyAldenDavis@gmail.com */ /* ------------------------------------------------------------------------- */ /* AMD finds a symmetric ordering P of a matrix A so that the Cholesky * factorization of P*A*P' has fewer nonzeros and takes less work than the * Cholesky factorization of A. If A is not symmetric, then it performs its * ordering on the matrix A+A'. Two sets of user-callable routines are * provided, one for int integers and the other for SuiteSparse_long integers. * * The method is based on the approximate minimum degree algorithm, discussed * in Amestoy, Davis, and Duff, "An approximate degree ordering algorithm", * SIAM Journal of Matrix Analysis and Applications, vol. 17, no. 4, pp. * 886-905, 1996. This package can perform both the AMD ordering (with * aggressive absorption), and the AMDBAR ordering (without aggressive * absorption) discussed in the above paper. This package differs from the * Fortran codes discussed in the paper: * * (1) it can ignore "dense" rows and columns, leading to faster run times * (2) it computes the ordering of A+A' if A is not symmetric * (3) it is followed by a depth-first post-ordering of the assembly tree * (or supernodal elimination tree) * * For historical reasons, the Fortran versions, amd.f and amdbar.f, have * been left (nearly) unchanged. They compute the identical ordering as * described in the above paper. */ #ifndef AMD_H #define AMD_H /* make it easy for C++ programs to include AMD */ #ifdef __cplusplus extern "C" { #endif /* get the definition of size_t: */ #include #include "SuiteSparse_config.h" int amd_order /* returns AMD_OK, AMD_OK_BUT_JUMBLED, * AMD_INVALID, or AMD_OUT_OF_MEMORY */ ( int n, /* A is n-by-n. n must be >= 0. */ const int Ap [ ], /* column pointers for A, of size n+1 */ const int Ai [ ], /* row indices of A, of size nz = Ap [n] */ int P [ ], /* output permutation, of size n */ double Control [ ], /* input Control settings, of size AMD_CONTROL */ double Info [ ] /* output Info statistics, of size AMD_INFO */ ) ; SuiteSparse_long amd_l_order /* see above for description of arguments */ ( SuiteSparse_long n, const SuiteSparse_long Ap [ ], const SuiteSparse_long Ai [ ], SuiteSparse_long P [ ], double Control [ ], double Info [ ] ) ; /* Input arguments (not modified): * * n: the matrix A is n-by-n. * Ap: an int/SuiteSparse_long array of size n+1, containing column * pointers of A. * Ai: an int/SuiteSparse_long array of size nz, containing the row * indices of A, where nz = Ap [n]. * Control: a double array of size AMD_CONTROL, containing control * parameters. Defaults are used if Control is NULL. * * Output arguments (not defined on input): * * P: an int/SuiteSparse_long array of size n, containing the output * permutation. If row i is the kth pivot row, then P [k] = i. In * MATLAB notation, the reordered matrix is A (P,P). * Info: a double array of size AMD_INFO, containing statistical * information. Ignored if Info is NULL. * * On input, the matrix A is stored in column-oriented form. The row indices * of nonzero entries in column j are stored in Ai [Ap [j] ... Ap [j+1]-1]. * * If the row indices appear in ascending order in each column, and there * are no duplicate entries, then amd_order is slightly more efficient in * terms of time and memory usage. If this condition does not hold, a copy * of the matrix is created (where these conditions do hold), and the copy is * ordered. This feature is new to v2.0 (v1.2 and earlier required this * condition to hold for the input matrix). * * Row indices must be in the range 0 to * n-1. Ap [0] must be zero, and thus nz = Ap [n] is the number of nonzeros * in A. The array Ap is of size n+1, and the array Ai is of size nz = Ap [n]. * The matrix does not need to be symmetric, and the diagonal does not need to * be present (if diagonal entries are present, they are ignored except for * the output statistic Info [AMD_NZDIAG]). The arrays Ai and Ap are not * modified. This form of the Ap and Ai arrays to represent the nonzero * pattern of the matrix A is the same as that used internally by MATLAB. * If you wish to use a more flexible input structure, please see the * umfpack_*_triplet_to_col routines in the UMFPACK package, at * http://www.suitesparse.com. * * Restrictions: n >= 0. Ap [0] = 0. Ap [j] <= Ap [j+1] for all j in the * range 0 to n-1. nz = Ap [n] >= 0. Ai [0..nz-1] must be in the range 0 * to n-1. Finally, Ai, Ap, and P must not be NULL. If any of these * restrictions are not met, AMD returns AMD_INVALID. * * AMD returns: * * AMD_OK if the matrix is valid and sufficient memory can be allocated to * perform the ordering. * * AMD_OUT_OF_MEMORY if not enough memory can be allocated. * * AMD_INVALID if the input arguments n, Ap, Ai are invalid, or if P is * NULL. * * AMD_OK_BUT_JUMBLED if the matrix had unsorted columns, and/or duplicate * entries, but was otherwise valid. * * The AMD routine first forms the pattern of the matrix A+A', and then * computes a fill-reducing ordering, P. If P [k] = i, then row/column i of * the original is the kth pivotal row. In MATLAB notation, the permuted * matrix is A (P,P), except that 0-based indexing is used instead of the * 1-based indexing in MATLAB. * * The Control array is used to set various parameters for AMD. If a NULL * pointer is passed, default values are used. The Control array is not * modified. * * Control [AMD_DENSE]: controls the threshold for "dense" rows/columns. * A dense row/column in A+A' can cause AMD to spend a lot of time in * ordering the matrix. If Control [AMD_DENSE] >= 0, rows/columns * with more than Control [AMD_DENSE] * sqrt (n) entries are ignored * during the ordering, and placed last in the output order. The * default value of Control [AMD_DENSE] is 10. If negative, no * rows/columns are treated as "dense". Rows/columns with 16 or * fewer off-diagonal entries are never considered "dense". * * Control [AMD_AGGRESSIVE]: controls whether or not to use aggressive * absorption, in which a prior element is absorbed into the current * element if is a subset of the current element, even if it is not * adjacent to the current pivot element (refer to Amestoy, Davis, * & Duff, 1996, for more details). The default value is nonzero, * which means to perform aggressive absorption. This nearly always * leads to a better ordering (because the approximate degrees are * more accurate) and a lower execution time. There are cases where * it can lead to a slightly worse ordering, however. To turn it off, * set Control [AMD_AGGRESSIVE] to 0. * * Control [2..4] are not used in the current version, but may be used in * future versions. * * The Info array provides statistics about the ordering on output. If it is * not present, the statistics are not returned. This is not an error * condition. * * Info [AMD_STATUS]: the return value of AMD, either AMD_OK, * AMD_OK_BUT_JUMBLED, AMD_OUT_OF_MEMORY, or AMD_INVALID. * * Info [AMD_N]: n, the size of the input matrix * * Info [AMD_NZ]: the number of nonzeros in A, nz = Ap [n] * * Info [AMD_SYMMETRY]: the symmetry of the matrix A. It is the number * of "matched" off-diagonal entries divided by the total number of * off-diagonal entries. An entry A(i,j) is matched if A(j,i) is also * an entry, for any pair (i,j) for which i != j. In MATLAB notation, * S = spones (A) ; * B = tril (S, -1) + triu (S, 1) ; * symmetry = nnz (B & B') / nnz (B) ; * * Info [AMD_NZDIAG]: the number of entries on the diagonal of A. * * Info [AMD_NZ_A_PLUS_AT]: the number of nonzeros in A+A', excluding the * diagonal. If A is perfectly symmetric (Info [AMD_SYMMETRY] = 1) * with a fully nonzero diagonal, then Info [AMD_NZ_A_PLUS_AT] = nz-n * (the smallest possible value). If A is perfectly unsymmetric * (Info [AMD_SYMMETRY] = 0, for an upper triangular matrix, for * example) with no diagonal, then Info [AMD_NZ_A_PLUS_AT] = 2*nz * (the largest possible value). * * Info [AMD_NDENSE]: the number of "dense" rows/columns of A+A' that were * removed from A prior to ordering. These are placed last in the * output order P. * * Info [AMD_MEMORY]: the amount of memory used by AMD, in bytes. In the * current version, this is 1.2 * Info [AMD_NZ_A_PLUS_AT] + 9*n * times the size of an integer. This is at most 2.4nz + 9n. This * excludes the size of the input arguments Ai, Ap, and P, which have * a total size of nz + 2*n + 1 integers. * * Info [AMD_NCMPA]: the number of garbage collections performed. * * Info [AMD_LNZ]: the number of nonzeros in L (excluding the diagonal). * This is a slight upper bound because mass elimination is combined * with the approximate degree update. It is a rough upper bound if * there are many "dense" rows/columns. The rest of the statistics, * below, are also slight or rough upper bounds, for the same reasons. * The post-ordering of the assembly tree might also not exactly * correspond to a true elimination tree postordering. * * Info [AMD_NDIV]: the number of divide operations for a subsequent LDL' * or LU factorization of the permuted matrix A (P,P). * * Info [AMD_NMULTSUBS_LDL]: the number of multiply-subtract pairs for a * subsequent LDL' factorization of A (P,P). * * Info [AMD_NMULTSUBS_LU]: the number of multiply-subtract pairs for a * subsequent LU factorization of A (P,P), assuming that no numerical * pivoting is required. * * Info [AMD_DMAX]: the maximum number of nonzeros in any column of L, * including the diagonal. * * Info [14..19] are not used in the current version, but may be used in * future versions. */ /* ------------------------------------------------------------------------- */ /* direct interface to AMD */ /* ------------------------------------------------------------------------- */ /* amd_2 is the primary AMD ordering routine. It is not meant to be * user-callable because of its restrictive inputs and because it destroys * the user's input matrix. It does not check its inputs for errors, either. * However, if you can work with these restrictions it can be faster than * amd_order and use less memory (assuming that you can create your own copy * of the matrix for AMD to destroy). Refer to AMD/Source/amd_2.c for a * description of each parameter. */ void amd_2 ( int n, int Pe [ ], int Iw [ ], int Len [ ], int iwlen, int pfree, int Nv [ ], int Next [ ], int Last [ ], int Head [ ], int Elen [ ], int Degree [ ], int W [ ], double Control [ ], double Info [ ] ) ; void amd_l2 ( SuiteSparse_long n, SuiteSparse_long Pe [ ], SuiteSparse_long Iw [ ], SuiteSparse_long Len [ ], SuiteSparse_long iwlen, SuiteSparse_long pfree, SuiteSparse_long Nv [ ], SuiteSparse_long Next [ ], SuiteSparse_long Last [ ], SuiteSparse_long Head [ ], SuiteSparse_long Elen [ ], SuiteSparse_long Degree [ ], SuiteSparse_long W [ ], double Control [ ], double Info [ ] ) ; /* ------------------------------------------------------------------------- */ /* amd_valid */ /* ------------------------------------------------------------------------- */ /* Returns AMD_OK or AMD_OK_BUT_JUMBLED if the matrix is valid as input to * amd_order; the latter is returned if the matrix has unsorted and/or * duplicate row indices in one or more columns. Returns AMD_INVALID if the * matrix cannot be passed to amd_order. For amd_order, the matrix must also * be square. The first two arguments are the number of rows and the number * of columns of the matrix. For its use in AMD, these must both equal n. * * NOTE: this routine returned TRUE/FALSE in v1.2 and earlier. */ int amd_valid ( int n_row, /* # of rows */ int n_col, /* # of columns */ const int Ap [ ], /* column pointers, of size n_col+1 */ const int Ai [ ] /* row indices, of size Ap [n_col] */ ) ; SuiteSparse_long amd_l_valid ( SuiteSparse_long n_row, SuiteSparse_long n_col, const SuiteSparse_long Ap [ ], const SuiteSparse_long Ai [ ] ) ; /* ------------------------------------------------------------------------- */ /* AMD memory manager and printf routines */ /* ------------------------------------------------------------------------- */ /* moved to SuiteSparse_config.c */ /* ------------------------------------------------------------------------- */ /* AMD Control and Info arrays */ /* ------------------------------------------------------------------------- */ /* amd_defaults: sets the default control settings */ void amd_defaults (double Control [ ]) ; void amd_l_defaults (double Control [ ]) ; /* amd_control: prints the control settings */ void amd_control (double Control [ ]) ; void amd_l_control (double Control [ ]) ; /* amd_info: prints the statistics */ void amd_info (double Info [ ]) ; void amd_l_info (double Info [ ]) ; #define AMD_CONTROL 5 /* size of Control array */ #define AMD_INFO 20 /* size of Info array */ /* contents of Control */ #define AMD_DENSE 0 /* "dense" if degree > Control [0] * sqrt (n) */ #define AMD_AGGRESSIVE 1 /* do aggressive absorption if Control [1] != 0 */ /* default Control settings */ #define AMD_DEFAULT_DENSE 10.0 /* default "dense" degree 10*sqrt(n) */ #define AMD_DEFAULT_AGGRESSIVE 1 /* do aggressive absorption by default */ /* contents of Info */ #define AMD_STATUS 0 /* return value of amd_order and amd_l_order */ #define AMD_N 1 /* A is n-by-n */ #define AMD_NZ 2 /* number of nonzeros in A */ #define AMD_SYMMETRY 3 /* symmetry of pattern (1 is sym., 0 is unsym.) */ #define AMD_NZDIAG 4 /* # of entries on diagonal */ #define AMD_NZ_A_PLUS_AT 5 /* nz in A+A' */ #define AMD_NDENSE 6 /* number of "dense" rows/columns in A */ #define AMD_MEMORY 7 /* amount of memory used by AMD */ #define AMD_NCMPA 8 /* number of garbage collections in AMD */ #define AMD_LNZ 9 /* approx. nz in L, excluding the diagonal */ #define AMD_NDIV 10 /* number of fl. point divides for LU and LDL' */ #define AMD_NMULTSUBS_LDL 11 /* number of fl. point (*,-) pairs for LDL' */ #define AMD_NMULTSUBS_LU 12 /* number of fl. point (*,-) pairs for LU */ #define AMD_DMAX 13 /* max nz. in any column of L, incl. diagonal */ /* ------------------------------------------------------------------------- */ /* return values of AMD */ /* ------------------------------------------------------------------------- */ #define AMD_OK 0 /* success */ #define AMD_OUT_OF_MEMORY -1 /* malloc failed, or problem too large */ #define AMD_INVALID -2 /* input arguments are not valid */ #define AMD_OK_BUT_JUMBLED 1 /* input matrix is OK for amd_order, but * columns were not sorted, and/or duplicate entries were present. AMD had * to do extra work before ordering the matrix. This is a warning, not an * error. */ /* ========================================================================== */ /* === AMD version ========================================================== */ /* ========================================================================== */ /* AMD Version 1.2 and later include the following definitions. * As an example, to test if the version you are using is 1.2 or later: * * #ifdef AMD_VERSION * if (AMD_VERSION >= AMD_VERSION_CODE (1,2)) ... * #endif * * This also works during compile-time: * * #if defined(AMD_VERSION) && (AMD_VERSION >= AMD_VERSION_CODE (1,2)) * printf ("This is version 1.2 or later\n") ; * #else * printf ("This is an early version\n") ; * #endif * * Versions 1.1 and earlier of AMD do not include a #define'd version number. */ #define AMD_DATE "May 4, 2016" #define AMD_VERSION_CODE(main,sub) ((main) * 1000 + (sub)) #define AMD_MAIN_VERSION 2 #define AMD_SUB_VERSION 4 #define AMD_SUBSUB_VERSION 6 #define AMD_VERSION AMD_VERSION_CODE(AMD_MAIN_VERSION,AMD_SUB_VERSION) #ifdef __cplusplus } #endif #endif ���������������������������������������������������������������������������������������������������Matrix/src/AMD/Include/amd_internal.h���������������������������������������������������������������0000644�0001762�0000144�00000020142�14211636445�017104� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================= */ /* === amd_internal.h ====================================================== */ /* ========================================================================= */ /* ------------------------------------------------------------------------- */ /* AMD, Copyright (c) Timothy A. Davis, */ /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ /* email: DrTimothyAldenDavis@gmail.com */ /* ------------------------------------------------------------------------- */ /* This file is for internal use in AMD itself, and does not normally need to * be included in user code (it is included in UMFPACK, however). All others * should use amd.h instead. */ // For use with R package 'Matrix': #define NPRINT /* ========================================================================= */ /* === NDEBUG ============================================================== */ /* ========================================================================= */ /* * Turning on debugging takes some work (see below). If you do not edit this * file, then debugging is always turned off, regardless of whether or not * -DNDEBUG is specified in your compiler options. * * If AMD is being compiled as a mexFunction, then MATLAB_MEX_FILE is defined, * and mxAssert is used instead of assert. If debugging is not enabled, no * MATLAB include files or functions are used. Thus, the AMD library libamd.a * can be safely used in either a stand-alone C program or in another * mexFunction, without any change. */ /* AMD will be exceedingly slow when running in debug mode. The next three lines ensure that debugging is turned off. */ #ifndef NDEBUG #define NDEBUG #endif /* To enable debugging, uncomment the following line: #undef NDEBUG */ /* ------------------------------------------------------------------------- */ /* ANSI include files */ /* ------------------------------------------------------------------------- */ /* from stdlib.h: size_t, malloc, free, realloc, and calloc */ #include #if !defined(NPRINT) || !defined(NDEBUG) /* from stdio.h: printf. Not included if NPRINT is defined at compile time. * fopen and fscanf are used when debugging. */ #include #endif /* from limits.h: INT_MAX and LONG_MAX */ #include /* from math.h: sqrt */ #include /* ------------------------------------------------------------------------- */ /* MATLAB include files (only if being used in or via MATLAB) */ /* ------------------------------------------------------------------------- */ #ifdef MATLAB_MEX_FILE #include "matrix.h" #include "mex.h" #endif /* ------------------------------------------------------------------------- */ /* basic definitions */ /* ------------------------------------------------------------------------- */ #ifdef FLIP #undef FLIP #endif #ifdef MAX #undef MAX #endif #ifdef MIN #undef MIN #endif #ifdef EMPTY #undef EMPTY #endif #ifdef GLOBAL #undef GLOBAL #endif #ifdef PRIVATE #undef PRIVATE #endif /* FLIP is a "negation about -1", and is used to mark an integer i that is * normally non-negative. FLIP (EMPTY) is EMPTY. FLIP of a number > EMPTY * is negative, and FLIP of a number < EMTPY is positive. FLIP (FLIP (i)) = i * for all integers i. UNFLIP (i) is >= EMPTY. */ #define EMPTY (-1) #define FLIP(i) (-(i)-2) #define UNFLIP(i) ((i < EMPTY) ? FLIP (i) : (i)) /* for integer MAX/MIN, or for doubles when we don't care how NaN's behave: */ #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define MIN(a,b) (((a) < (b)) ? (a) : (b)) /* logical expression of p implies q: */ #define IMPLIES(p,q) (!(p) || (q)) /* Note that the IBM RS 6000 xlc predefines TRUE and FALSE in . */ /* The Compaq Alpha also predefines TRUE and FALSE. */ #ifdef TRUE #undef TRUE #endif #ifdef FALSE #undef FALSE #endif #define TRUE (1) #define FALSE (0) #define PRIVATE static #define GLOBAL #define EMPTY (-1) /* Note that Linux's gcc 2.96 defines NULL as ((void *) 0), but other */ /* compilers (even gcc 2.95.2 on Solaris) define NULL as 0 or (0). We */ /* need to use the ANSI standard value of 0. */ #ifdef NULL #undef NULL #endif #define NULL 0 /* largest value of size_t */ #ifndef SIZE_T_MAX #ifdef SIZE_MAX /* C99 only */ #define SIZE_T_MAX SIZE_MAX #else #define SIZE_T_MAX ((size_t) (-1)) #endif #endif /* ------------------------------------------------------------------------- */ /* integer type for AMD: int or SuiteSparse_long */ /* ------------------------------------------------------------------------- */ #include "amd.h" #if defined (DLONG) || defined (ZLONG) #define Int SuiteSparse_long #define ID SuiteSparse_long_id #define Int_MAX SuiteSparse_long_max #define AMD_order amd_l_order #define AMD_defaults amd_l_defaults #define AMD_control amd_l_control #define AMD_info amd_l_info #define AMD_1 amd_l1 #define AMD_2 amd_l2 #define AMD_valid amd_l_valid #define AMD_aat amd_l_aat #define AMD_postorder amd_l_postorder #define AMD_post_tree amd_l_post_tree #define AMD_dump amd_l_dump #define AMD_debug amd_l_debug #define AMD_debug_init amd_l_debug_init #define AMD_preprocess amd_l_preprocess #else #define Int int #define ID "%d" #define Int_MAX INT_MAX #define AMD_order amd_order #define AMD_defaults amd_defaults #define AMD_control amd_control #define AMD_info amd_info #define AMD_1 amd_1 #define AMD_2 amd_2 #define AMD_valid amd_valid #define AMD_aat amd_aat #define AMD_postorder amd_postorder #define AMD_post_tree amd_post_tree #define AMD_dump amd_dump #define AMD_debug amd_debug #define AMD_debug_init amd_debug_init #define AMD_preprocess amd_preprocess #endif /* ------------------------------------------------------------------------- */ /* AMD routine definitions (not user-callable) */ /* ------------------------------------------------------------------------- */ GLOBAL size_t AMD_aat ( Int n, const Int Ap [ ], const Int Ai [ ], Int Len [ ], Int Tp [ ], double Info [ ] ) ; GLOBAL void AMD_1 ( Int n, const Int Ap [ ], const Int Ai [ ], Int P [ ], Int Pinv [ ], Int Len [ ], Int slen, Int S [ ], double Control [ ], double Info [ ] ) ; GLOBAL void AMD_postorder ( Int nn, Int Parent [ ], Int Npiv [ ], Int Fsize [ ], Int Order [ ], Int Child [ ], Int Sibling [ ], Int Stack [ ] ) ; GLOBAL Int AMD_post_tree ( Int root, Int k, Int Child [ ], const Int Sibling [ ], Int Order [ ], Int Stack [ ] #ifndef NDEBUG , Int nn #endif ) ; GLOBAL void AMD_preprocess ( Int n, const Int Ap [ ], const Int Ai [ ], Int Rp [ ], Int Ri [ ], Int W [ ], Int Flag [ ] ) ; /* ------------------------------------------------------------------------- */ /* debugging definitions */ /* ------------------------------------------------------------------------- */ #ifndef NDEBUG /* from assert.h: assert macro */ #include #ifndef EXTERN #define EXTERN extern #endif EXTERN Int AMD_debug ; GLOBAL void AMD_debug_init ( char *s ) ; GLOBAL void AMD_dump ( Int n, Int Pe [ ], Int Iw [ ], Int Len [ ], Int iwlen, Int pfree, Int Nv [ ], Int Next [ ], Int Last [ ], Int Head [ ], Int Elen [ ], Int Degree [ ], Int W [ ], Int nel ) ; #ifdef ASSERT #undef ASSERT #endif /* Use mxAssert if AMD is compiled into a mexFunction */ #ifdef MATLAB_MEX_FILE #define ASSERT(expression) (mxAssert ((expression), "")) #else #define ASSERT(expression) (assert (expression)) #endif #define AMD_DEBUG0(params) { SUITESPARSE_PRINTF (params) ; } #define AMD_DEBUG1(params) { if (AMD_debug >= 1) SUITESPARSE_PRINTF (params) ; } #define AMD_DEBUG2(params) { if (AMD_debug >= 2) SUITESPARSE_PRINTF (params) ; } #define AMD_DEBUG3(params) { if (AMD_debug >= 3) SUITESPARSE_PRINTF (params) ; } #define AMD_DEBUG4(params) { if (AMD_debug >= 4) SUITESPARSE_PRINTF (params) ; } #else /* no debugging */ #define ASSERT(expression) #define AMD_DEBUG0(params) #define AMD_DEBUG1(params) #define AMD_DEBUG2(params) #define AMD_DEBUG3(params) #define AMD_DEBUG4(params) #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/AMD/Makefile�����������������������������������������������������������������������������0000644�0001762�0000144�00000000276�14547724215�014366� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# compile just the C-callable library library: ( cd Source ; $(MAKE) lib ) # remove object files, but keep the compiled programs and library archives clean: ( cd Source ; $(MAKE) clean ) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/AMD/Source/������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14547724215�014161� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/AMD/Source/amd_postorder.c���������������������������������������������������������������0000644�0001762�0000144�00000012605�11770402705�017163� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================= */ /* === AMD_postorder ======================================================= */ /* ========================================================================= */ /* ------------------------------------------------------------------------- */ /* AMD, Copyright (c) Timothy A. Davis, */ /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ /* email: DrTimothyAldenDavis@gmail.com */ /* ------------------------------------------------------------------------- */ /* Perform a postordering (via depth-first search) of an assembly tree. */ #include "amd_internal.h" GLOBAL void AMD_postorder ( /* inputs, not modified on output: */ Int nn, /* nodes are in the range 0..nn-1 */ Int Parent [ ], /* Parent [j] is the parent of j, or EMPTY if root */ Int Nv [ ], /* Nv [j] > 0 number of pivots represented by node j, * or zero if j is not a node. */ Int Fsize [ ], /* Fsize [j]: size of node j */ /* output, not defined on input: */ Int Order [ ], /* output post-order */ /* workspaces of size nn: */ Int Child [ ], Int Sibling [ ], Int Stack [ ] ) { Int i, j, k, parent, frsize, f, fprev, maxfrsize, bigfprev, bigf, fnext ; for (j = 0 ; j < nn ; j++) { Child [j] = EMPTY ; Sibling [j] = EMPTY ; } /* --------------------------------------------------------------------- */ /* place the children in link lists - bigger elements tend to be last */ /* --------------------------------------------------------------------- */ for (j = nn-1 ; j >= 0 ; j--) { if (Nv [j] > 0) { /* this is an element */ parent = Parent [j] ; if (parent != EMPTY) { /* place the element in link list of the children its parent */ /* bigger elements will tend to be at the end of the list */ Sibling [j] = Child [parent] ; Child [parent] = j ; } } } #ifndef NDEBUG { Int nels, ff, nchild ; AMD_DEBUG1 (("\n\n================================ AMD_postorder:\n")); nels = 0 ; for (j = 0 ; j < nn ; j++) { if (Nv [j] > 0) { AMD_DEBUG1 (( ""ID" : nels "ID" npiv "ID" size "ID " parent "ID" maxfr "ID"\n", j, nels, Nv [j], Fsize [j], Parent [j], Fsize [j])) ; /* this is an element */ /* dump the link list of children */ nchild = 0 ; AMD_DEBUG1 ((" Children: ")) ; for (ff = Child [j] ; ff != EMPTY ; ff = Sibling [ff]) { AMD_DEBUG1 ((ID" ", ff)) ; ASSERT (Parent [ff] == j) ; nchild++ ; ASSERT (nchild < nn) ; } AMD_DEBUG1 (("\n")) ; parent = Parent [j] ; if (parent != EMPTY) { ASSERT (Nv [parent] > 0) ; } nels++ ; } } } AMD_DEBUG1 (("\n\nGo through the children of each node, and put\n" "the biggest child last in each list:\n")) ; #endif /* --------------------------------------------------------------------- */ /* place the largest child last in the list of children for each node */ /* --------------------------------------------------------------------- */ for (i = 0 ; i < nn ; i++) { if (Nv [i] > 0 && Child [i] != EMPTY) { #ifndef NDEBUG Int nchild ; AMD_DEBUG1 (("Before partial sort, element "ID"\n", i)) ; nchild = 0 ; for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) { ASSERT (f >= 0 && f < nn) ; AMD_DEBUG1 ((" f: "ID" size: "ID"\n", f, Fsize [f])) ; nchild++ ; ASSERT (nchild <= nn) ; } #endif /* find the biggest element in the child list */ fprev = EMPTY ; maxfrsize = EMPTY ; bigfprev = EMPTY ; bigf = EMPTY ; for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) { ASSERT (f >= 0 && f < nn) ; frsize = Fsize [f] ; if (frsize >= maxfrsize) { /* this is the biggest seen so far */ maxfrsize = frsize ; bigfprev = fprev ; bigf = f ; } fprev = f ; } ASSERT (bigf != EMPTY) ; fnext = Sibling [bigf] ; AMD_DEBUG1 (("bigf "ID" maxfrsize "ID" bigfprev "ID" fnext "ID " fprev " ID"\n", bigf, maxfrsize, bigfprev, fnext, fprev)) ; if (fnext != EMPTY) { /* if fnext is EMPTY then bigf is already at the end of list */ if (bigfprev == EMPTY) { /* delete bigf from the element of the list */ Child [i] = fnext ; } else { /* delete bigf from the middle of the list */ Sibling [bigfprev] = fnext ; } /* put bigf at the end of the list */ Sibling [bigf] = EMPTY ; ASSERT (Child [i] != EMPTY) ; ASSERT (fprev != bigf) ; ASSERT (fprev != EMPTY) ; Sibling [fprev] = bigf ; } #ifndef NDEBUG AMD_DEBUG1 (("After partial sort, element "ID"\n", i)) ; for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) { ASSERT (f >= 0 && f < nn) ; AMD_DEBUG1 ((" "ID" "ID"\n", f, Fsize [f])) ; ASSERT (Nv [f] > 0) ; nchild-- ; } ASSERT (nchild == 0) ; #endif } } /* --------------------------------------------------------------------- */ /* postorder the assembly tree */ /* --------------------------------------------------------------------- */ for (i = 0 ; i < nn ; i++) { Order [i] = EMPTY ; } k = 0 ; for (i = 0 ; i < nn ; i++) { if (Parent [i] == EMPTY && Nv [i] > 0) { AMD_DEBUG1 (("Root of assembly tree "ID"\n", i)) ; k = AMD_post_tree (i, k, Child, Sibling, Order, Stack #ifndef NDEBUG , nn #endif ) ; } } } ���������������������������������������������������������������������������������������������������������������������������Matrix/src/AMD/Source/amd_valid.c�������������������������������������������������������������������0000644�0001762�0000144�00000005644�11770402705�016246� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================= */ /* === AMD_valid =========================================================== */ /* ========================================================================= */ /* ------------------------------------------------------------------------- */ /* AMD, Copyright (c) Timothy A. Davis, */ /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ /* email: DrTimothyAldenDavis@gmail.com */ /* ------------------------------------------------------------------------- */ /* Check if a column-form matrix is valid or not. The matrix A is * n_row-by-n_col. The row indices of entries in column j are in * Ai [Ap [j] ... Ap [j+1]-1]. Required conditions are: * * n_row >= 0 * n_col >= 0 * nz = Ap [n_col] >= 0 number of entries in the matrix * Ap [0] == 0 * Ap [j] <= Ap [j+1] for all j in the range 0 to n_col. * Ai [0 ... nz-1] must be in the range 0 to n_row-1. * * If any of the above conditions hold, AMD_INVALID is returned. If the * following condition holds, AMD_OK_BUT_JUMBLED is returned (a warning, * not an error): * * row indices in Ai [Ap [j] ... Ap [j+1]-1] are not sorted in ascending * order, and/or duplicate entries exist. * * Otherwise, AMD_OK is returned. * * In v1.2 and earlier, this function returned TRUE if the matrix was valid * (now returns AMD_OK), or FALSE otherwise (now returns AMD_INVALID or * AMD_OK_BUT_JUMBLED). */ #include "amd_internal.h" GLOBAL Int AMD_valid ( /* inputs, not modified on output: */ Int n_row, /* A is n_row-by-n_col */ Int n_col, const Int Ap [ ], /* column pointers of A, of size n_col+1 */ const Int Ai [ ] /* row indices of A, of size nz = Ap [n_col] */ ) { Int nz, j, p1, p2, ilast, i, p, result = AMD_OK ; if (n_row < 0 || n_col < 0 || Ap == NULL || Ai == NULL) { return (AMD_INVALID) ; } nz = Ap [n_col] ; if (Ap [0] != 0 || nz < 0) { /* column pointers must start at Ap [0] = 0, and Ap [n] must be >= 0 */ AMD_DEBUG0 (("column 0 pointer bad or nz < 0\n")) ; return (AMD_INVALID) ; } for (j = 0 ; j < n_col ; j++) { p1 = Ap [j] ; p2 = Ap [j+1] ; AMD_DEBUG2 (("\nColumn: "ID" p1: "ID" p2: "ID"\n", j, p1, p2)) ; if (p1 > p2) { /* column pointers must be ascending */ AMD_DEBUG0 (("column "ID" pointer bad\n", j)) ; return (AMD_INVALID) ; } ilast = EMPTY ; for (p = p1 ; p < p2 ; p++) { i = Ai [p] ; AMD_DEBUG3 (("row: "ID"\n", i)) ; if (i < 0 || i >= n_row) { /* row index out of range */ AMD_DEBUG0 (("index out of range, col "ID" row "ID"\n", j, i)); return (AMD_INVALID) ; } if (i <= ilast) { /* row index unsorted, or duplicate entry present */ AMD_DEBUG1 (("index unsorted/dupl col "ID" row "ID"\n", j, i)); result = AMD_OK_BUT_JUMBLED ; } ilast = i ; } } return (result) ; } ��������������������������������������������������������������������������������������������Matrix/src/AMD/Source/amd_2.c�����������������������������������������������������������������������0000644�0001762�0000144�00000176471�13652535054�015324� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================= */ /* === AMD_2 =============================================================== */ /* ========================================================================= */ /* ------------------------------------------------------------------------- */ /* AMD, Copyright (c) Timothy A. Davis, */ /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ /* email: DrTimothyAldenDavis@gmail.com */ /* ------------------------------------------------------------------------- */ /* AMD_2: performs the AMD ordering on a symmetric sparse matrix A, followed * by a postordering (via depth-first search) of the assembly tree using the * AMD_postorder routine. */ #include "amd_internal.h" /* ========================================================================= */ /* === clear_flag ========================================================== */ /* ========================================================================= */ static Int clear_flag (Int wflg, Int wbig, Int W [ ], Int n) { Int x ; if (wflg < 2 || wflg >= wbig) { for (x = 0 ; x < n ; x++) { if (W [x] != 0) W [x] = 1 ; } wflg = 2 ; } /* at this point, W [0..n-1] < wflg holds */ return (wflg) ; } /* ========================================================================= */ /* === AMD_2 =============================================================== */ /* ========================================================================= */ GLOBAL void AMD_2 ( Int n, /* A is n-by-n, where n > 0 */ Int Pe [ ], /* Pe [0..n-1]: index in Iw of row i on input */ Int Iw [ ], /* workspace of size iwlen. Iw [0..pfree-1] * holds the matrix on input */ Int Len [ ], /* Len [0..n-1]: length for row/column i on input */ Int iwlen, /* length of Iw. iwlen >= pfree + n */ Int pfree, /* Iw [pfree ... iwlen-1] is empty on input */ /* 7 size-n workspaces, not defined on input: */ Int Nv [ ], /* the size of each supernode on output */ Int Next [ ], /* the output inverse permutation */ Int Last [ ], /* the output permutation */ Int Head [ ], Int Elen [ ], /* the size columns of L for each supernode */ Int Degree [ ], Int W [ ], /* control parameters and output statistics */ double Control [ ], /* array of size AMD_CONTROL */ double Info [ ] /* array of size AMD_INFO */ ) { /* * Given a representation of the nonzero pattern of a symmetric matrix, A, * (excluding the diagonal) perform an approximate minimum (UMFPACK/MA38-style) * degree ordering to compute a pivot order such that the introduction of * nonzeros (fill-in) in the Cholesky factors A = LL' is kept low. At each * step, the pivot selected is the one with the minimum UMFAPACK/MA38-style * upper-bound on the external degree. This routine can optionally perform * aggresive absorption (as done by MC47B in the Harwell Subroutine * Library). * * The approximate degree algorithm implemented here is the symmetric analog of * the degree update algorithm in MA38 and UMFPACK (the Unsymmetric-pattern * MultiFrontal PACKage, both by Davis and Duff). The routine is based on the * MA27 minimum degree ordering algorithm by Iain Duff and John Reid. * * This routine is a translation of the original AMDBAR and MC47B routines, * in Fortran, with the following modifications: * * (1) dense rows/columns are removed prior to ordering the matrix, and placed * last in the output order. The presence of a dense row/column can * increase the ordering time by up to O(n^2), unless they are removed * prior to ordering. * * (2) the minimum degree ordering is followed by a postordering (depth-first * search) of the assembly tree. Note that mass elimination (discussed * below) combined with the approximate degree update can lead to the mass * elimination of nodes with lower exact degree than the current pivot * element. No additional fill-in is caused in the representation of the * Schur complement. The mass-eliminated nodes merge with the current * pivot element. They are ordered prior to the current pivot element. * Because they can have lower exact degree than the current element, the * merger of two or more of these nodes in the current pivot element can * lead to a single element that is not a "fundamental supernode". The * diagonal block can have zeros in it. Thus, the assembly tree used here * is not guaranteed to be the precise supernodal elemination tree (with * "funadmental" supernodes), and the postordering performed by this * routine is not guaranteed to be a precise postordering of the * elimination tree. * * (3) input parameters are added, to control aggressive absorption and the * detection of "dense" rows/columns of A. * * (4) additional statistical information is returned, such as the number of * nonzeros in L, and the flop counts for subsequent LDL' and LU * factorizations. These are slight upper bounds, because of the mass * elimination issue discussed above. * * (5) additional routines are added to interface this routine to MATLAB * to provide a simple C-callable user-interface, to check inputs for * errors, compute the symmetry of the pattern of A and the number of * nonzeros in each row/column of A+A', to compute the pattern of A+A', * to perform the assembly tree postordering, and to provide debugging * ouput. Many of these functions are also provided by the Fortran * Harwell Subroutine Library routine MC47A. * * (6) both int and SuiteSparse_long versions are provided. In the * descriptions below and integer is and int or SuiteSparse_long depending * on which version is being used. ********************************************************************** ***** CAUTION: ARGUMENTS ARE NOT CHECKED FOR ERRORS ON INPUT. ****** ********************************************************************** ** If you want error checking, a more versatile input format, and a ** ** simpler user interface, use amd_order or amd_l_order instead. ** ** This routine is not meant to be user-callable. ** ********************************************************************** * ---------------------------------------------------------------------------- * References: * ---------------------------------------------------------------------------- * * [1] Timothy A. Davis and Iain Duff, "An unsymmetric-pattern multifrontal * method for sparse LU factorization", SIAM J. Matrix Analysis and * Applications, vol. 18, no. 1, pp. 140-158. Discusses UMFPACK / MA38, * which first introduced the approximate minimum degree used by this * routine. * * [2] Patrick Amestoy, Timothy A. Davis, and Iain S. Duff, "An approximate * minimum degree ordering algorithm," SIAM J. Matrix Analysis and * Applications, vol. 17, no. 4, pp. 886-905, 1996. Discusses AMDBAR and * MC47B, which are the Fortran versions of this routine. * * [3] Alan George and Joseph Liu, "The evolution of the minimum degree * ordering algorithm," SIAM Review, vol. 31, no. 1, pp. 1-19, 1989. * We list below the features mentioned in that paper that this code * includes: * * mass elimination: * Yes. MA27 relied on supervariable detection for mass elimination. * * indistinguishable nodes: * Yes (we call these "supervariables"). This was also in the MA27 * code - although we modified the method of detecting them (the * previous hash was the true degree, which we no longer keep track * of). A supervariable is a set of rows with identical nonzero * pattern. All variables in a supervariable are eliminated together. * Each supervariable has as its numerical name that of one of its * variables (its principal variable). * * quotient graph representation: * Yes. We use the term "element" for the cliques formed during * elimination. This was also in the MA27 code. The algorithm can * operate in place, but it will work more efficiently if given some * "elbow room." * * element absorption: * Yes. This was also in the MA27 code. * * external degree: * Yes. The MA27 code was based on the true degree. * * incomplete degree update and multiple elimination: * No. This was not in MA27, either. Our method of degree update * within MC47B is element-based, not variable-based. It is thus * not well-suited for use with incomplete degree update or multiple * elimination. * * Authors, and Copyright (C) 2004 by: * Timothy A. Davis, Patrick Amestoy, Iain S. Duff, John K. Reid. * * Acknowledgements: This work (and the UMFPACK package) was supported by the * National Science Foundation (ASC-9111263, DMS-9223088, and CCR-0203270). * The UMFPACK/MA38 approximate degree update algorithm, the unsymmetric analog * which forms the basis of AMD, was developed while Tim Davis was supported by * CERFACS (Toulouse, France) in a post-doctoral position. This C version, and * the etree postorder, were written while Tim Davis was on sabbatical at * Stanford University and Lawrence Berkeley National Laboratory. * ---------------------------------------------------------------------------- * INPUT ARGUMENTS (unaltered): * ---------------------------------------------------------------------------- * n: The matrix order. Restriction: n >= 1. * * iwlen: The size of the Iw array. On input, the matrix is stored in * Iw [0..pfree-1]. However, Iw [0..iwlen-1] should be slightly larger * than what is required to hold the matrix, at least iwlen >= pfree + n. * Otherwise, excessive compressions will take place. The recommended * value of iwlen is 1.2 * pfree + n, which is the value used in the * user-callable interface to this routine (amd_order.c). The algorithm * will not run at all if iwlen < pfree. Restriction: iwlen >= pfree + n. * Note that this is slightly more restrictive than the actual minimum * (iwlen >= pfree), but AMD_2 will be very slow with no elbow room. * Thus, this routine enforces a bare minimum elbow room of size n. * * pfree: On input the tail end of the array, Iw [pfree..iwlen-1], is empty, * and the matrix is stored in Iw [0..pfree-1]. During execution, * additional data is placed in Iw, and pfree is modified so that * Iw [pfree..iwlen-1] is always the unused part of Iw. * * Control: A double array of size AMD_CONTROL containing input parameters * that affect how the ordering is computed. If NULL, then default * settings are used. * * Control [AMD_DENSE] is used to determine whether or not a given input * row is "dense". A row is "dense" if the number of entries in the row * exceeds Control [AMD_DENSE] times sqrt (n), except that rows with 16 or * fewer entries are never considered "dense". To turn off the detection * of dense rows, set Control [AMD_DENSE] to a negative number, or to a * number larger than sqrt (n). The default value of Control [AMD_DENSE] * is AMD_DEFAULT_DENSE, which is defined in amd.h as 10. * * Control [AMD_AGGRESSIVE] is used to determine whether or not aggressive * absorption is to be performed. If nonzero, then aggressive absorption * is performed (this is the default). * ---------------------------------------------------------------------------- * INPUT/OUPUT ARGUMENTS: * ---------------------------------------------------------------------------- * * Pe: An integer array of size n. On input, Pe [i] is the index in Iw of * the start of row i. Pe [i] is ignored if row i has no off-diagonal * entries. Thus Pe [i] must be in the range 0 to pfree-1 for non-empty * rows. * * During execution, it is used for both supervariables and elements: * * Principal supervariable i: index into Iw of the description of * supervariable i. A supervariable represents one or more rows of * the matrix with identical nonzero pattern. In this case, * Pe [i] >= 0. * * Non-principal supervariable i: if i has been absorbed into another * supervariable j, then Pe [i] = FLIP (j), where FLIP (j) is defined * as (-(j)-2). Row j has the same pattern as row i. Note that j * might later be absorbed into another supervariable j2, in which * case Pe [i] is still FLIP (j), and Pe [j] = FLIP (j2) which is * < EMPTY, where EMPTY is defined as (-1) in amd_internal.h. * * Unabsorbed element e: the index into Iw of the description of element * e, if e has not yet been absorbed by a subsequent element. Element * e is created when the supervariable of the same name is selected as * the pivot. In this case, Pe [i] >= 0. * * Absorbed element e: if element e is absorbed into element e2, then * Pe [e] = FLIP (e2). This occurs when the pattern of e (which we * refer to as Le) is found to be a subset of the pattern of e2 (that * is, Le2). In this case, Pe [i] < EMPTY. If element e is "null" * (it has no nonzeros outside its pivot block), then Pe [e] = EMPTY, * and e is the root of an assembly subtree (or the whole tree if * there is just one such root). * * Dense variable i: if i is "dense", then Pe [i] = EMPTY. * * On output, Pe holds the assembly tree/forest, which implicitly * represents a pivot order with identical fill-in as the actual order * (via a depth-first search of the tree), as follows. If Nv [i] > 0, * then i represents a node in the assembly tree, and the parent of i is * Pe [i], or EMPTY if i is a root. If Nv [i] = 0, then (i, Pe [i]) * represents an edge in a subtree, the root of which is a node in the * assembly tree. Note that i refers to a row/column in the original * matrix, not the permuted matrix. * * Info: A double array of size AMD_INFO. If present, (that is, not NULL), * then statistics about the ordering are returned in the Info array. * See amd.h for a description. * ---------------------------------------------------------------------------- * INPUT/MODIFIED (undefined on output): * ---------------------------------------------------------------------------- * * Len: An integer array of size n. On input, Len [i] holds the number of * entries in row i of the matrix, excluding the diagonal. The contents * of Len are undefined on output. * * Iw: An integer array of size iwlen. On input, Iw [0..pfree-1] holds the * description of each row i in the matrix. The matrix must be symmetric, * and both upper and lower triangular parts must be present. The * diagonal must not be present. Row i is held as follows: * * Len [i]: the length of the row i data structure in the Iw array. * Iw [Pe [i] ... Pe [i] + Len [i] - 1]: * the list of column indices for nonzeros in row i (simple * supervariables), excluding the diagonal. All supervariables * start with one row/column each (supervariable i is just row i). * If Len [i] is zero on input, then Pe [i] is ignored on input. * * Note that the rows need not be in any particular order, and there * may be empty space between the rows. * * During execution, the supervariable i experiences fill-in. This is * represented by placing in i a list of the elements that cause fill-in * in supervariable i: * * Len [i]: the length of supervariable i in the Iw array. * Iw [Pe [i] ... Pe [i] + Elen [i] - 1]: * the list of elements that contain i. This list is kept short * by removing absorbed elements. * Iw [Pe [i] + Elen [i] ... Pe [i] + Len [i] - 1]: * the list of supervariables in i. This list is kept short by * removing nonprincipal variables, and any entry j that is also * contained in at least one of the elements (j in Le) in the list * for i (e in row i). * * When supervariable i is selected as pivot, we create an element e of * the same name (e=i): * * Len [e]: the length of element e in the Iw array. * Iw [Pe [e] ... Pe [e] + Len [e] - 1]: * the list of supervariables in element e. * * An element represents the fill-in that occurs when supervariable i is * selected as pivot (which represents the selection of row i and all * non-principal variables whose principal variable is i). We use the * term Le to denote the set of all supervariables in element e. Absorbed * supervariables and elements are pruned from these lists when * computationally convenient. * * CAUTION: THE INPUT MATRIX IS OVERWRITTEN DURING COMPUTATION. * The contents of Iw are undefined on output. * ---------------------------------------------------------------------------- * OUTPUT (need not be set on input): * ---------------------------------------------------------------------------- * * Nv: An integer array of size n. During execution, ABS (Nv [i]) is equal to * the number of rows that are represented by the principal supervariable * i. If i is a nonprincipal or dense variable, then Nv [i] = 0. * Initially, Nv [i] = 1 for all i. Nv [i] < 0 signifies that i is a * principal variable in the pattern Lme of the current pivot element me. * After element me is constructed, Nv [i] is set back to a positive * value. * * On output, Nv [i] holds the number of pivots represented by super * row/column i of the original matrix, or Nv [i] = 0 for non-principal * rows/columns. Note that i refers to a row/column in the original * matrix, not the permuted matrix. * * Elen: An integer array of size n. See the description of Iw above. At the * start of execution, Elen [i] is set to zero for all rows i. During * execution, Elen [i] is the number of elements in the list for * supervariable i. When e becomes an element, Elen [e] = FLIP (esize) is * set, where esize is the size of the element (the number of pivots, plus * the number of nonpivotal entries). Thus Elen [e] < EMPTY. * Elen (i) = EMPTY set when variable i becomes nonprincipal. * * For variables, Elen (i) >= EMPTY holds until just before the * postordering and permutation vectors are computed. For elements, * Elen [e] < EMPTY holds. * * On output, Elen [i] is the degree of the row/column in the Cholesky * factorization of the permuted matrix, corresponding to the original row * i, if i is a super row/column. It is equal to EMPTY if i is * non-principal. Note that i refers to a row/column in the original * matrix, not the permuted matrix. * * Note that the contents of Elen on output differ from the Fortran * version (Elen holds the inverse permutation in the Fortran version, * which is instead returned in the Next array in this C version, * described below). * * Last: In a degree list, Last [i] is the supervariable preceding i, or EMPTY * if i is the head of the list. In a hash bucket, Last [i] is the hash * key for i. * * Last [Head [hash]] is also used as the head of a hash bucket if * Head [hash] contains a degree list (see the description of Head, * below). * * On output, Last [0..n-1] holds the permutation. That is, if * i = Last [k], then row i is the kth pivot row (where k ranges from 0 to * n-1). Row Last [k] of A is the kth row in the permuted matrix, PAP'. * * Next: Next [i] is the supervariable following i in a link list, or EMPTY if * i is the last in the list. Used for two kinds of lists: degree lists * and hash buckets (a supervariable can be in only one kind of list at a * time). * * On output Next [0..n-1] holds the inverse permutation. That is, if * k = Next [i], then row i is the kth pivot row. Row i of A appears as * the (Next[i])-th row in the permuted matrix, PAP'. * * Note that the contents of Next on output differ from the Fortran * version (Next is undefined on output in the Fortran version). * ---------------------------------------------------------------------------- * LOCAL WORKSPACE (not input or output - used only during execution): * ---------------------------------------------------------------------------- * * Degree: An integer array of size n. If i is a supervariable, then * Degree [i] holds the current approximation of the external degree of * row i (an upper bound). The external degree is the number of nonzeros * in row i, minus ABS (Nv [i]), the diagonal part. The bound is equal to * the exact external degree if Elen [i] is less than or equal to two. * * We also use the term "external degree" for elements e to refer to * |Le \ Lme|. If e is an element, then Degree [e] is |Le|, which is the * degree of the off-diagonal part of the element e (not including the * diagonal part). * * Head: An integer array of size n. Head is used for degree lists. * Head [deg] is the first supervariable in a degree list. All * supervariables i in a degree list Head [deg] have the same approximate * degree, namely, deg = Degree [i]. If the list Head [deg] is empty then * Head [deg] = EMPTY. * * During supervariable detection Head [hash] also serves as a pointer to * a hash bucket. If Head [hash] >= 0, there is a degree list of degree * hash. The hash bucket head pointer is Last [Head [hash]]. If * Head [hash] = EMPTY, then the degree list and hash bucket are both * empty. If Head [hash] < EMPTY, then the degree list is empty, and * FLIP (Head [hash]) is the head of the hash bucket. After supervariable * detection is complete, all hash buckets are empty, and the * (Last [Head [hash]] = EMPTY) condition is restored for the non-empty * degree lists. * * W: An integer array of size n. The flag array W determines the status of * elements and variables, and the external degree of elements. * * for elements: * if W [e] = 0, then the element e is absorbed. * if W [e] >= wflg, then W [e] - wflg is the size of the set * |Le \ Lme|, in terms of nonzeros (the sum of ABS (Nv [i]) for * each principal variable i that is both in the pattern of * element e and NOT in the pattern of the current pivot element, * me). * if wflg > W [e] > 0, then e is not absorbed and has not yet been * seen in the scan of the element lists in the computation of * |Le\Lme| in Scan 1 below. * * for variables: * during supervariable detection, if W [j] != wflg then j is * not in the pattern of variable i. * * The W array is initialized by setting W [i] = 1 for all i, and by * setting wflg = 2. It is reinitialized if wflg becomes too large (to * ensure that wflg+n does not cause integer overflow). * ---------------------------------------------------------------------------- * LOCAL INTEGERS: * ---------------------------------------------------------------------------- */ Int deg, degme, dext, lemax, e, elenme, eln, i, ilast, inext, j, jlast, jnext, k, knt1, knt2, knt3, lenj, ln, me, mindeg, nel, nleft, nvi, nvj, nvpiv, slenme, wbig, we, wflg, wnvi, ok, ndense, ncmpa, dense, aggressive ; unsigned Int hash ; /* unsigned, so that hash % n is well defined.*/ /* * deg: the degree of a variable or element * degme: size, |Lme|, of the current element, me (= Degree [me]) * dext: external degree, |Le \ Lme|, of some element e * lemax: largest |Le| seen so far (called dmax in Fortran version) * e: an element * elenme: the length, Elen [me], of element list of pivotal variable * eln: the length, Elen [...], of an element list * hash: the computed value of the hash function * i: a supervariable * ilast: the entry in a link list preceding i * inext: the entry in a link list following i * j: a supervariable * jlast: the entry in a link list preceding j * jnext: the entry in a link list, or path, following j * k: the pivot order of an element or variable * knt1: loop counter used during element construction * knt2: loop counter used during element construction * knt3: loop counter used during compression * lenj: Len [j] * ln: length of a supervariable list * me: current supervariable being eliminated, and the current * element created by eliminating that supervariable * mindeg: current minimum degree * nel: number of pivots selected so far * nleft: n - nel, the number of nonpivotal rows/columns remaining * nvi: the number of variables in a supervariable i (= Nv [i]) * nvj: the number of variables in a supervariable j (= Nv [j]) * nvpiv: number of pivots in current element * slenme: number of variables in variable list of pivotal variable * wbig: = (INT_MAX - n) for the int version, (SuiteSparse_long_max - n) * for the SuiteSparse_long version. wflg is not allowed to * be >= wbig. * we: W [e] * wflg: used for flagging the W array. See description of Iw. * wnvi: wflg - Nv [i] * x: either a supervariable or an element * * ok: true if supervariable j can be absorbed into i * ndense: number of "dense" rows/columns * dense: rows/columns with initial degree > dense are considered "dense" * aggressive: true if aggressive absorption is being performed * ncmpa: number of garbage collections * ---------------------------------------------------------------------------- * LOCAL DOUBLES, used for statistical output only (except for alpha): * ---------------------------------------------------------------------------- */ double f, r, ndiv, s, nms_lu, nms_ldl, dmax, alpha, lnz, lnzme ; /* * f: nvpiv * r: degme + nvpiv * ndiv: number of divisions for LU or LDL' factorizations * s: number of multiply-subtract pairs for LU factorization, for the * current element me * nms_lu number of multiply-subtract pairs for LU factorization * nms_ldl number of multiply-subtract pairs for LDL' factorization * dmax: the largest number of entries in any column of L, including the * diagonal * alpha: "dense" degree ratio * lnz: the number of nonzeros in L (excluding the diagonal) * lnzme: the number of nonzeros in L (excl. the diagonal) for the * current element me * ---------------------------------------------------------------------------- * LOCAL "POINTERS" (indices into the Iw array) * ---------------------------------------------------------------------------- */ Int p, p1, p2, p3, p4, pdst, pend, pj, pme, pme1, pme2, pn, psrc ; /* * Any parameter (Pe [...] or pfree) or local variable starting with "p" (for * Pointer) is an index into Iw, and all indices into Iw use variables starting * with "p." The only exception to this rule is the iwlen input argument. * * p: pointer into lots of things * p1: Pe [i] for some variable i (start of element list) * p2: Pe [i] + Elen [i] - 1 for some variable i * p3: index of first supervariable in clean list * p4: * pdst: destination pointer, for compression * pend: end of memory to compress * pj: pointer into an element or variable * pme: pointer into the current element (pme1...pme2) * pme1: the current element, me, is stored in Iw [pme1...pme2] * pme2: the end of the current element * pn: pointer into a "clean" variable, also used to compress * psrc: source pointer, for compression */ /* ========================================================================= */ /* INITIALIZATIONS */ /* ========================================================================= */ /* Note that this restriction on iwlen is slightly more restrictive than * what is actually required in AMD_2. AMD_2 can operate with no elbow * room at all, but it will be slow. For better performance, at least * size-n elbow room is enforced. */ ASSERT (iwlen >= pfree + n) ; ASSERT (n > 0) ; /* initialize output statistics */ lnz = 0 ; ndiv = 0 ; nms_lu = 0 ; nms_ldl = 0 ; dmax = 1 ; me = EMPTY ; mindeg = 0 ; ncmpa = 0 ; nel = 0 ; lemax = 0 ; /* get control parameters */ if (Control != (double *) NULL) { alpha = Control [AMD_DENSE] ; aggressive = (Control [AMD_AGGRESSIVE] != 0) ; } else { alpha = AMD_DEFAULT_DENSE ; aggressive = AMD_DEFAULT_AGGRESSIVE ; } /* Note: if alpha is NaN, this is undefined: */ if (alpha < 0) { /* only remove completely dense rows/columns */ dense = n-2 ; } else { dense = alpha * sqrt ((double) n) ; } dense = MAX (16, dense) ; dense = MIN (n, dense) ; AMD_DEBUG1 (("\n\nAMD (debug), alpha %g, aggr. "ID"\n", alpha, aggressive)) ; for (i = 0 ; i < n ; i++) { Last [i] = EMPTY ; Head [i] = EMPTY ; Next [i] = EMPTY ; /* if separate Hhead array is used for hash buckets: * Hhead [i] = EMPTY ; */ Nv [i] = 1 ; W [i] = 1 ; Elen [i] = 0 ; Degree [i] = Len [i] ; } #ifndef NDEBUG AMD_DEBUG1 (("\n======Nel "ID" initial\n", nel)) ; AMD_dump (n, Pe, Iw, Len, iwlen, pfree, Nv, Next, Last, Head, Elen, Degree, W, -1) ; #endif /* initialize wflg */ wbig = Int_MAX - n ; wflg = clear_flag (0, wbig, W, n) ; /* --------------------------------------------------------------------- */ /* initialize degree lists and eliminate dense and empty rows */ /* --------------------------------------------------------------------- */ ndense = 0 ; for (i = 0 ; i < n ; i++) { deg = Degree [i] ; ASSERT (deg >= 0 && deg < n) ; if (deg == 0) { /* ------------------------------------------------------------- * we have a variable that can be eliminated at once because * there is no off-diagonal non-zero in its row. Note that * Nv [i] = 1 for an empty variable i. It is treated just * the same as an eliminated element i. * ------------------------------------------------------------- */ Elen [i] = FLIP (1) ; nel++ ; Pe [i] = EMPTY ; W [i] = 0 ; } else if (deg > dense) { /* ------------------------------------------------------------- * Dense variables are not treated as elements, but as unordered, * non-principal variables that have no parent. They do not take * part in the postorder, since Nv [i] = 0. Note that the Fortran * version does not have this option. * ------------------------------------------------------------- */ AMD_DEBUG1 (("Dense node "ID" degree "ID"\n", i, deg)) ; ndense++ ; Nv [i] = 0 ; /* do not postorder this node */ Elen [i] = EMPTY ; nel++ ; Pe [i] = EMPTY ; } else { /* ------------------------------------------------------------- * place i in the degree list corresponding to its degree * ------------------------------------------------------------- */ inext = Head [deg] ; ASSERT (inext >= EMPTY && inext < n) ; if (inext != EMPTY) Last [inext] = i ; Next [i] = inext ; Head [deg] = i ; } } /* ========================================================================= */ /* WHILE (selecting pivots) DO */ /* ========================================================================= */ while (nel < n) { #ifndef NDEBUG AMD_DEBUG1 (("\n======Nel "ID"\n", nel)) ; if (AMD_debug >= 2) { AMD_dump (n, Pe, Iw, Len, iwlen, pfree, Nv, Next, Last, Head, Elen, Degree, W, nel) ; } #endif /* ========================================================================= */ /* GET PIVOT OF MINIMUM DEGREE */ /* ========================================================================= */ /* ----------------------------------------------------------------- */ /* find next supervariable for elimination */ /* ----------------------------------------------------------------- */ ASSERT (mindeg >= 0 && mindeg < n) ; for (deg = mindeg ; deg < n ; deg++) { me = Head [deg] ; if (me != EMPTY) break ; } mindeg = deg ; ASSERT (me >= 0 && me < n) ; AMD_DEBUG1 (("=================me: "ID"\n", me)) ; /* ----------------------------------------------------------------- */ /* remove chosen variable from link list */ /* ----------------------------------------------------------------- */ inext = Next [me] ; ASSERT (inext >= EMPTY && inext < n) ; if (inext != EMPTY) Last [inext] = EMPTY ; Head [deg] = inext ; /* ----------------------------------------------------------------- */ /* me represents the elimination of pivots nel to nel+Nv[me]-1. */ /* place me itself as the first in this set. */ /* ----------------------------------------------------------------- */ elenme = Elen [me] ; nvpiv = Nv [me] ; ASSERT (nvpiv > 0) ; nel += nvpiv ; /* ========================================================================= */ /* CONSTRUCT NEW ELEMENT */ /* ========================================================================= */ /* ----------------------------------------------------------------- * At this point, me is the pivotal supervariable. It will be * converted into the current element. Scan list of the pivotal * supervariable, me, setting tree pointers and constructing new list * of supervariables for the new element, me. p is a pointer to the * current position in the old list. * ----------------------------------------------------------------- */ /* flag the variable "me" as being in Lme by negating Nv [me] */ Nv [me] = -nvpiv ; degme = 0 ; ASSERT (Pe [me] >= 0 && Pe [me] < iwlen) ; if (elenme == 0) { /* ------------------------------------------------------------- */ /* construct the new element in place */ /* ------------------------------------------------------------- */ pme1 = Pe [me] ; pme2 = pme1 - 1 ; for (p = pme1 ; p <= pme1 + Len [me] - 1 ; p++) { i = Iw [p] ; ASSERT (i >= 0 && i < n && Nv [i] >= 0) ; nvi = Nv [i] ; if (nvi > 0) { /* ----------------------------------------------------- */ /* i is a principal variable not yet placed in Lme. */ /* store i in new list */ /* ----------------------------------------------------- */ /* flag i as being in Lme by negating Nv [i] */ degme += nvi ; Nv [i] = -nvi ; Iw [++pme2] = i ; /* ----------------------------------------------------- */ /* remove variable i from degree list. */ /* ----------------------------------------------------- */ ilast = Last [i] ; inext = Next [i] ; ASSERT (ilast >= EMPTY && ilast < n) ; ASSERT (inext >= EMPTY && inext < n) ; if (inext != EMPTY) Last [inext] = ilast ; if (ilast != EMPTY) { Next [ilast] = inext ; } else { /* i is at the head of the degree list */ ASSERT (Degree [i] >= 0 && Degree [i] < n) ; Head [Degree [i]] = inext ; } } } } else { /* ------------------------------------------------------------- */ /* construct the new element in empty space, Iw [pfree ...] */ /* ------------------------------------------------------------- */ p = Pe [me] ; pme1 = pfree ; slenme = Len [me] - elenme ; for (knt1 = 1 ; knt1 <= elenme + 1 ; knt1++) { if (knt1 > elenme) { /* search the supervariables in me. */ e = me ; pj = p ; ln = slenme ; AMD_DEBUG2 (("Search sv: "ID" "ID" "ID"\n", me,pj,ln)) ; } else { /* search the elements in me. */ e = Iw [p++] ; ASSERT (e >= 0 && e < n) ; pj = Pe [e] ; ln = Len [e] ; AMD_DEBUG2 (("Search element e "ID" in me "ID"\n", e,me)) ; ASSERT (Elen [e] < EMPTY && W [e] > 0 && pj >= 0) ; } ASSERT (ln >= 0 && (ln == 0 || (pj >= 0 && pj < iwlen))) ; /* --------------------------------------------------------- * search for different supervariables and add them to the * new list, compressing when necessary. this loop is * executed once for each element in the list and once for * all the supervariables in the list. * --------------------------------------------------------- */ for (knt2 = 1 ; knt2 <= ln ; knt2++) { i = Iw [pj++] ; ASSERT (i >= 0 && i < n && (i == me || Elen [i] >= EMPTY)); nvi = Nv [i] ; AMD_DEBUG2 ((": "ID" "ID" "ID" "ID"\n", i, Elen [i], Nv [i], wflg)) ; if (nvi > 0) { /* ------------------------------------------------- */ /* compress Iw, if necessary */ /* ------------------------------------------------- */ if (pfree >= iwlen) { AMD_DEBUG1 (("GARBAGE COLLECTION\n")) ; /* prepare for compressing Iw by adjusting pointers * and lengths so that the lists being searched in * the inner and outer loops contain only the * remaining entries. */ Pe [me] = p ; Len [me] -= knt1 ; /* check if nothing left of supervariable me */ if (Len [me] == 0) Pe [me] = EMPTY ; Pe [e] = pj ; Len [e] = ln - knt2 ; /* nothing left of element e */ if (Len [e] == 0) Pe [e] = EMPTY ; ncmpa++ ; /* one more garbage collection */ /* store first entry of each object in Pe */ /* FLIP the first entry in each object */ for (j = 0 ; j < n ; j++) { pn = Pe [j] ; if (pn >= 0) { ASSERT (pn >= 0 && pn < iwlen) ; Pe [j] = Iw [pn] ; Iw [pn] = FLIP (j) ; } } /* psrc/pdst point to source/destination */ psrc = 0 ; pdst = 0 ; pend = pme1 - 1 ; while (psrc <= pend) { /* search for next FLIP'd entry */ j = FLIP (Iw [psrc++]) ; if (j >= 0) { AMD_DEBUG2 (("Got object j: "ID"\n", j)) ; Iw [pdst] = Pe [j] ; Pe [j] = pdst++ ; lenj = Len [j] ; /* copy from source to destination */ for (knt3 = 0 ; knt3 <= lenj - 2 ; knt3++) { Iw [pdst++] = Iw [psrc++] ; } } } /* move the new partially-constructed element */ p1 = pdst ; for (psrc = pme1 ; psrc <= pfree-1 ; psrc++) { Iw [pdst++] = Iw [psrc] ; } pme1 = p1 ; pfree = pdst ; pj = Pe [e] ; p = Pe [me] ; } /* ------------------------------------------------- */ /* i is a principal variable not yet placed in Lme */ /* store i in new list */ /* ------------------------------------------------- */ /* flag i as being in Lme by negating Nv [i] */ degme += nvi ; Nv [i] = -nvi ; Iw [pfree++] = i ; AMD_DEBUG2 ((" s: "ID" nv "ID"\n", i, Nv [i])); /* ------------------------------------------------- */ /* remove variable i from degree link list */ /* ------------------------------------------------- */ ilast = Last [i] ; inext = Next [i] ; ASSERT (ilast >= EMPTY && ilast < n) ; ASSERT (inext >= EMPTY && inext < n) ; if (inext != EMPTY) Last [inext] = ilast ; if (ilast != EMPTY) { Next [ilast] = inext ; } else { /* i is at the head of the degree list */ ASSERT (Degree [i] >= 0 && Degree [i] < n) ; Head [Degree [i]] = inext ; } } } if (e != me) { /* set tree pointer and flag to indicate element e is * absorbed into new element me (the parent of e is me) */ AMD_DEBUG1 ((" Element "ID" => "ID"\n", e, me)) ; Pe [e] = FLIP (me) ; W [e] = 0 ; } } pme2 = pfree - 1 ; } /* ----------------------------------------------------------------- */ /* me has now been converted into an element in Iw [pme1..pme2] */ /* ----------------------------------------------------------------- */ /* degme holds the external degree of new element */ Degree [me] = degme ; Pe [me] = pme1 ; Len [me] = pme2 - pme1 + 1 ; ASSERT (Pe [me] >= 0 && Pe [me] < iwlen) ; Elen [me] = FLIP (nvpiv + degme) ; /* FLIP (Elen (me)) is now the degree of pivot (including * diagonal part). */ #ifndef NDEBUG AMD_DEBUG2 (("New element structure: length= "ID"\n", pme2-pme1+1)) ; for (pme = pme1 ; pme <= pme2 ; pme++) AMD_DEBUG3 ((" "ID"", Iw[pme])); AMD_DEBUG3 (("\n")) ; #endif /* ----------------------------------------------------------------- */ /* make sure that wflg is not too large. */ /* ----------------------------------------------------------------- */ /* With the current value of wflg, wflg+n must not cause integer * overflow */ wflg = clear_flag (wflg, wbig, W, n) ; /* ========================================================================= */ /* COMPUTE (W [e] - wflg) = |Le\Lme| FOR ALL ELEMENTS */ /* ========================================================================= */ /* ----------------------------------------------------------------- * Scan 1: compute the external degrees of previous elements with * respect to the current element. That is: * (W [e] - wflg) = |Le \ Lme| * for each element e that appears in any supervariable in Lme. The * notation Le refers to the pattern (list of supervariables) of a * previous element e, where e is not yet absorbed, stored in * Iw [Pe [e] + 1 ... Pe [e] + Len [e]]. The notation Lme * refers to the pattern of the current element (stored in * Iw [pme1..pme2]). If aggressive absorption is enabled, and * (W [e] - wflg) becomes zero, then the element e will be absorbed * in Scan 2. * ----------------------------------------------------------------- */ AMD_DEBUG2 (("me: ")) ; for (pme = pme1 ; pme <= pme2 ; pme++) { i = Iw [pme] ; ASSERT (i >= 0 && i < n) ; eln = Elen [i] ; AMD_DEBUG3 ((""ID" Elen "ID": \n", i, eln)) ; if (eln > 0) { /* note that Nv [i] has been negated to denote i in Lme: */ nvi = -Nv [i] ; ASSERT (nvi > 0 && Pe [i] >= 0 && Pe [i] < iwlen) ; wnvi = wflg - nvi ; for (p = Pe [i] ; p <= Pe [i] + eln - 1 ; p++) { e = Iw [p] ; ASSERT (e >= 0 && e < n) ; we = W [e] ; AMD_DEBUG4 ((" e "ID" we "ID" ", e, we)) ; if (we >= wflg) { /* unabsorbed element e has been seen in this loop */ AMD_DEBUG4 ((" unabsorbed, first time seen")) ; we -= nvi ; } else if (we != 0) { /* e is an unabsorbed element */ /* this is the first we have seen e in all of Scan 1 */ AMD_DEBUG4 ((" unabsorbed")) ; we = Degree [e] + wnvi ; } AMD_DEBUG4 (("\n")) ; W [e] = we ; } } } AMD_DEBUG2 (("\n")) ; /* ========================================================================= */ /* DEGREE UPDATE AND ELEMENT ABSORPTION */ /* ========================================================================= */ /* ----------------------------------------------------------------- * Scan 2: for each i in Lme, sum up the degree of Lme (which is * degme), plus the sum of the external degrees of each Le for the * elements e appearing within i, plus the supervariables in i. * Place i in hash list. * ----------------------------------------------------------------- */ for (pme = pme1 ; pme <= pme2 ; pme++) { i = Iw [pme] ; ASSERT (i >= 0 && i < n && Nv [i] < 0 && Elen [i] >= 0) ; AMD_DEBUG2 (("Updating: i "ID" "ID" "ID"\n", i, Elen[i], Len [i])); p1 = Pe [i] ; p2 = p1 + Elen [i] - 1 ; pn = p1 ; hash = 0 ; deg = 0 ; ASSERT (p1 >= 0 && p1 < iwlen && p2 >= -1 && p2 < iwlen) ; /* ------------------------------------------------------------- */ /* scan the element list associated with supervariable i */ /* ------------------------------------------------------------- */ /* UMFPACK/MA38-style approximate degree: */ if (aggressive) { for (p = p1 ; p <= p2 ; p++) { e = Iw [p] ; ASSERT (e >= 0 && e < n) ; we = W [e] ; if (we != 0) { /* e is an unabsorbed element */ /* dext = | Le \ Lme | */ dext = we - wflg ; if (dext > 0) { deg += dext ; Iw [pn++] = e ; hash += e ; AMD_DEBUG4 ((" e: "ID" hash = "ID"\n",e,hash)) ; } else { /* external degree of e is zero, absorb e into me*/ AMD_DEBUG1 ((" Element "ID" =>"ID" (aggressive)\n", e, me)) ; ASSERT (dext == 0) ; Pe [e] = FLIP (me) ; W [e] = 0 ; } } } } else { for (p = p1 ; p <= p2 ; p++) { e = Iw [p] ; ASSERT (e >= 0 && e < n) ; we = W [e] ; if (we != 0) { /* e is an unabsorbed element */ dext = we - wflg ; ASSERT (dext >= 0) ; deg += dext ; Iw [pn++] = e ; hash += e ; AMD_DEBUG4 ((" e: "ID" hash = "ID"\n",e,hash)) ; } } } /* count the number of elements in i (including me): */ Elen [i] = pn - p1 + 1 ; /* ------------------------------------------------------------- */ /* scan the supervariables in the list associated with i */ /* ------------------------------------------------------------- */ /* The bulk of the AMD run time is typically spent in this loop, * particularly if the matrix has many dense rows that are not * removed prior to ordering. */ p3 = pn ; p4 = p1 + Len [i] ; for (p = p2 + 1 ; p < p4 ; p++) { j = Iw [p] ; ASSERT (j >= 0 && j < n) ; nvj = Nv [j] ; if (nvj > 0) { /* j is unabsorbed, and not in Lme. */ /* add to degree and add to new list */ deg += nvj ; Iw [pn++] = j ; hash += j ; AMD_DEBUG4 ((" s: "ID" hash "ID" Nv[j]= "ID"\n", j, hash, nvj)) ; } } /* ------------------------------------------------------------- */ /* update the degree and check for mass elimination */ /* ------------------------------------------------------------- */ /* with aggressive absorption, deg==0 is identical to the * Elen [i] == 1 && p3 == pn test, below. */ ASSERT (IMPLIES (aggressive, (deg==0) == (Elen[i]==1 && p3==pn))) ; if (Elen [i] == 1 && p3 == pn) { /* --------------------------------------------------------- */ /* mass elimination */ /* --------------------------------------------------------- */ /* There is nothing left of this node except for an edge to * the current pivot element. Elen [i] is 1, and there are * no variables adjacent to node i. Absorb i into the * current pivot element, me. Note that if there are two or * more mass eliminations, fillin due to mass elimination is * possible within the nvpiv-by-nvpiv pivot block. It is this * step that causes AMD's analysis to be an upper bound. * * The reason is that the selected pivot has a lower * approximate degree than the true degree of the two mass * eliminated nodes. There is no edge between the two mass * eliminated nodes. They are merged with the current pivot * anyway. * * No fillin occurs in the Schur complement, in any case, * and this effect does not decrease the quality of the * ordering itself, just the quality of the nonzero and * flop count analysis. It also means that the post-ordering * is not an exact elimination tree post-ordering. */ AMD_DEBUG1 ((" MASS i "ID" => parent e "ID"\n", i, me)) ; Pe [i] = FLIP (me) ; nvi = -Nv [i] ; degme -= nvi ; nvpiv += nvi ; nel += nvi ; Nv [i] = 0 ; Elen [i] = EMPTY ; } else { /* --------------------------------------------------------- */ /* update the upper-bound degree of i */ /* --------------------------------------------------------- */ /* the following degree does not yet include the size * of the current element, which is added later: */ Degree [i] = MIN (Degree [i], deg) ; /* --------------------------------------------------------- */ /* add me to the list for i */ /* --------------------------------------------------------- */ /* move first supervariable to end of list */ Iw [pn] = Iw [p3] ; /* move first element to end of element part of list */ Iw [p3] = Iw [p1] ; /* add new element, me, to front of list. */ Iw [p1] = me ; /* store the new length of the list in Len [i] */ Len [i] = pn - p1 + 1 ; /* --------------------------------------------------------- */ /* place in hash bucket. Save hash key of i in Last [i]. */ /* --------------------------------------------------------- */ /* NOTE: this can fail if hash is negative, because the ANSI C * standard does not define a % b when a and/or b are negative. * That's why hash is defined as an unsigned Int, to avoid this * problem. */ hash = hash % n ; ASSERT (((Int) hash) >= 0 && ((Int) hash) < n) ; /* if the Hhead array is not used: */ j = Head [hash] ; if (j <= EMPTY) { /* degree list is empty, hash head is FLIP (j) */ Next [i] = FLIP (j) ; Head [hash] = FLIP (i) ; } else { /* degree list is not empty, use Last [Head [hash]] as * hash head. */ Next [i] = Last [j] ; Last [j] = i ; } /* if a separate Hhead array is used: * Next [i] = Hhead [hash] ; Hhead [hash] = i ; */ Last [i] = hash ; } } Degree [me] = degme ; /* ----------------------------------------------------------------- */ /* Clear the counter array, W [...], by incrementing wflg. */ /* ----------------------------------------------------------------- */ /* make sure that wflg+n does not cause integer overflow */ lemax = MAX (lemax, degme) ; wflg += lemax ; wflg = clear_flag (wflg, wbig, W, n) ; /* at this point, W [0..n-1] < wflg holds */ /* ========================================================================= */ /* SUPERVARIABLE DETECTION */ /* ========================================================================= */ AMD_DEBUG1 (("Detecting supervariables:\n")) ; for (pme = pme1 ; pme <= pme2 ; pme++) { i = Iw [pme] ; ASSERT (i >= 0 && i < n) ; AMD_DEBUG2 (("Consider i "ID" nv "ID"\n", i, Nv [i])) ; if (Nv [i] < 0) { /* i is a principal variable in Lme */ /* --------------------------------------------------------- * examine all hash buckets with 2 or more variables. We do * this by examing all unique hash keys for supervariables in * the pattern Lme of the current element, me * --------------------------------------------------------- */ /* let i = head of hash bucket, and empty the hash bucket */ ASSERT (Last [i] >= 0 && Last [i] < n) ; hash = Last [i] ; /* if Hhead array is not used: */ j = Head [hash] ; if (j == EMPTY) { /* hash bucket and degree list are both empty */ i = EMPTY ; } else if (j < EMPTY) { /* degree list is empty */ i = FLIP (j) ; Head [hash] = EMPTY ; } else { /* degree list is not empty, restore Last [j] of head j */ i = Last [j] ; Last [j] = EMPTY ; } /* if separate Hhead array is used: * i = Hhead [hash] ; Hhead [hash] = EMPTY ; */ ASSERT (i >= EMPTY && i < n) ; AMD_DEBUG2 (("----i "ID" hash "ID"\n", i, hash)) ; while (i != EMPTY && Next [i] != EMPTY) { /* ----------------------------------------------------- * this bucket has one or more variables following i. * scan all of them to see if i can absorb any entries * that follow i in hash bucket. Scatter i into w. * ----------------------------------------------------- */ ln = Len [i] ; eln = Elen [i] ; ASSERT (ln >= 0 && eln >= 0) ; ASSERT (Pe [i] >= 0 && Pe [i] < iwlen) ; /* do not flag the first element in the list (me) */ for (p = Pe [i] + 1 ; p <= Pe [i] + ln - 1 ; p++) { ASSERT (Iw [p] >= 0 && Iw [p] < n) ; W [Iw [p]] = wflg ; } /* ----------------------------------------------------- */ /* scan every other entry j following i in bucket */ /* ----------------------------------------------------- */ jlast = i ; j = Next [i] ; ASSERT (j >= EMPTY && j < n) ; while (j != EMPTY) { /* ------------------------------------------------- */ /* check if j and i have identical nonzero pattern */ /* ------------------------------------------------- */ AMD_DEBUG3 (("compare i "ID" and j "ID"\n", i,j)) ; /* check if i and j have the same Len and Elen */ ASSERT (Len [j] >= 0 && Elen [j] >= 0) ; ASSERT (Pe [j] >= 0 && Pe [j] < iwlen) ; ok = (Len [j] == ln) && (Elen [j] == eln) ; /* skip the first element in the list (me) */ for (p = Pe [j] + 1 ; ok && p <= Pe [j] + ln - 1 ; p++) { ASSERT (Iw [p] >= 0 && Iw [p] < n) ; if (W [Iw [p]] != wflg) ok = 0 ; } if (ok) { /* --------------------------------------------- */ /* found it! j can be absorbed into i */ /* --------------------------------------------- */ AMD_DEBUG1 (("found it! j "ID" => i "ID"\n", j,i)); Pe [j] = FLIP (i) ; /* both Nv [i] and Nv [j] are negated since they */ /* are in Lme, and the absolute values of each */ /* are the number of variables in i and j: */ Nv [i] += Nv [j] ; Nv [j] = 0 ; Elen [j] = EMPTY ; /* delete j from hash bucket */ ASSERT (j != Next [j]) ; j = Next [j] ; Next [jlast] = j ; } else { /* j cannot be absorbed into i */ jlast = j ; ASSERT (j != Next [j]) ; j = Next [j] ; } ASSERT (j >= EMPTY && j < n) ; } /* ----------------------------------------------------- * no more variables can be absorbed into i * go to next i in bucket and clear flag array * ----------------------------------------------------- */ wflg++ ; i = Next [i] ; ASSERT (i >= EMPTY && i < n) ; } } } AMD_DEBUG2 (("detect done\n")) ; /* ========================================================================= */ /* RESTORE DEGREE LISTS AND REMOVE NONPRINCIPAL SUPERVARIABLES FROM ELEMENT */ /* ========================================================================= */ p = pme1 ; nleft = n - nel ; for (pme = pme1 ; pme <= pme2 ; pme++) { i = Iw [pme] ; ASSERT (i >= 0 && i < n) ; nvi = -Nv [i] ; AMD_DEBUG3 (("Restore i "ID" "ID"\n", i, nvi)) ; if (nvi > 0) { /* i is a principal variable in Lme */ /* restore Nv [i] to signify that i is principal */ Nv [i] = nvi ; /* --------------------------------------------------------- */ /* compute the external degree (add size of current element) */ /* --------------------------------------------------------- */ deg = Degree [i] + degme - nvi ; deg = MIN (deg, nleft - nvi) ; ASSERT (IMPLIES (aggressive, deg > 0) && deg >= 0 && deg < n) ; /* --------------------------------------------------------- */ /* place the supervariable at the head of the degree list */ /* --------------------------------------------------------- */ inext = Head [deg] ; ASSERT (inext >= EMPTY && inext < n) ; if (inext != EMPTY) Last [inext] = i ; Next [i] = inext ; Last [i] = EMPTY ; Head [deg] = i ; /* --------------------------------------------------------- */ /* save the new degree, and find the minimum degree */ /* --------------------------------------------------------- */ mindeg = MIN (mindeg, deg) ; Degree [i] = deg ; /* --------------------------------------------------------- */ /* place the supervariable in the element pattern */ /* --------------------------------------------------------- */ Iw [p++] = i ; } } AMD_DEBUG2 (("restore done\n")) ; /* ========================================================================= */ /* FINALIZE THE NEW ELEMENT */ /* ========================================================================= */ AMD_DEBUG2 (("ME = "ID" DONE\n", me)) ; Nv [me] = nvpiv ; /* save the length of the list for the new element me */ Len [me] = p - pme1 ; if (Len [me] == 0) { /* there is nothing left of the current pivot element */ /* it is a root of the assembly tree */ Pe [me] = EMPTY ; W [me] = 0 ; } if (elenme != 0) { /* element was not constructed in place: deallocate part of */ /* it since newly nonprincipal variables may have been removed */ pfree = p ; } /* The new element has nvpiv pivots and the size of the contribution * block for a multifrontal method is degme-by-degme, not including * the "dense" rows/columns. If the "dense" rows/columns are included, * the frontal matrix is no larger than * (degme+ndense)-by-(degme+ndense). */ if (Info != (double *) NULL) { f = nvpiv ; r = degme + ndense ; dmax = MAX (dmax, f + r) ; /* number of nonzeros in L (excluding the diagonal) */ lnzme = f*r + (f-1)*f/2 ; lnz += lnzme ; /* number of divide operations for LDL' and for LU */ ndiv += lnzme ; /* number of multiply-subtract pairs for LU */ s = f*r*r + r*(f-1)*f + (f-1)*f*(2*f-1)/6 ; nms_lu += s ; /* number of multiply-subtract pairs for LDL' */ nms_ldl += (s + lnzme)/2 ; } #ifndef NDEBUG AMD_DEBUG2 (("finalize done nel "ID" n "ID"\n ::::\n", nel, n)) ; for (pme = Pe [me] ; pme <= Pe [me] + Len [me] - 1 ; pme++) { AMD_DEBUG3 ((" "ID"", Iw [pme])) ; } AMD_DEBUG3 (("\n")) ; #endif } /* ========================================================================= */ /* DONE SELECTING PIVOTS */ /* ========================================================================= */ if (Info != (double *) NULL) { /* count the work to factorize the ndense-by-ndense submatrix */ f = ndense ; dmax = MAX (dmax, (double) ndense) ; /* number of nonzeros in L (excluding the diagonal) */ lnzme = (f-1)*f/2 ; lnz += lnzme ; /* number of divide operations for LDL' and for LU */ ndiv += lnzme ; /* number of multiply-subtract pairs for LU */ s = (f-1)*f*(2*f-1)/6 ; nms_lu += s ; /* number of multiply-subtract pairs for LDL' */ nms_ldl += (s + lnzme)/2 ; /* number of nz's in L (excl. diagonal) */ Info [AMD_LNZ] = lnz ; /* number of divide ops for LU and LDL' */ Info [AMD_NDIV] = ndiv ; /* number of multiply-subtract pairs for LDL' */ Info [AMD_NMULTSUBS_LDL] = nms_ldl ; /* number of multiply-subtract pairs for LU */ Info [AMD_NMULTSUBS_LU] = nms_lu ; /* number of "dense" rows/columns */ Info [AMD_NDENSE] = ndense ; /* largest front is dmax-by-dmax */ Info [AMD_DMAX] = dmax ; /* number of garbage collections in AMD */ Info [AMD_NCMPA] = ncmpa ; /* successful ordering */ Info [AMD_STATUS] = AMD_OK ; } /* ========================================================================= */ /* POST-ORDERING */ /* ========================================================================= */ /* ------------------------------------------------------------------------- * Variables at this point: * * Pe: holds the elimination tree. The parent of j is FLIP (Pe [j]), * or EMPTY if j is a root. The tree holds both elements and * non-principal (unordered) variables absorbed into them. * Dense variables are non-principal and unordered. * * Elen: holds the size of each element, including the diagonal part. * FLIP (Elen [e]) > 0 if e is an element. For unordered * variables i, Elen [i] is EMPTY. * * Nv: Nv [e] > 0 is the number of pivots represented by the element e. * For unordered variables i, Nv [i] is zero. * * Contents no longer needed: * W, Iw, Len, Degree, Head, Next, Last. * * The matrix itself has been destroyed. * * n: the size of the matrix. * No other scalars needed (pfree, iwlen, etc.) * ------------------------------------------------------------------------- */ /* restore Pe */ for (i = 0 ; i < n ; i++) { Pe [i] = FLIP (Pe [i]) ; } /* restore Elen, for output information, and for postordering */ for (i = 0 ; i < n ; i++) { Elen [i] = FLIP (Elen [i]) ; } /* Now the parent of j is Pe [j], or EMPTY if j is a root. Elen [e] > 0 * is the size of element e. Elen [i] is EMPTY for unordered variable i. */ #ifndef NDEBUG AMD_DEBUG2 (("\nTree:\n")) ; for (i = 0 ; i < n ; i++) { AMD_DEBUG2 ((" "ID" parent: "ID" ", i, Pe [i])) ; ASSERT (Pe [i] >= EMPTY && Pe [i] < n) ; if (Nv [i] > 0) { /* this is an element */ e = i ; AMD_DEBUG2 ((" element, size is "ID"\n", Elen [i])) ; ASSERT (Elen [e] > 0) ; } AMD_DEBUG2 (("\n")) ; } AMD_DEBUG2 (("\nelements:\n")) ; for (e = 0 ; e < n ; e++) { if (Nv [e] > 0) { AMD_DEBUG3 (("Element e= "ID" size "ID" nv "ID" \n", e, Elen [e], Nv [e])) ; } } AMD_DEBUG2 (("\nvariables:\n")) ; for (i = 0 ; i < n ; i++) { Int cnt ; if (Nv [i] == 0) { AMD_DEBUG3 (("i unordered: "ID"\n", i)) ; j = Pe [i] ; cnt = 0 ; AMD_DEBUG3 ((" j: "ID"\n", j)) ; if (j == EMPTY) { AMD_DEBUG3 ((" i is a dense variable\n")) ; } else { ASSERT (j >= 0 && j < n) ; while (Nv [j] == 0) { AMD_DEBUG3 ((" j : "ID"\n", j)) ; j = Pe [j] ; AMD_DEBUG3 ((" j:: "ID"\n", j)) ; cnt++ ; if (cnt > n) break ; } e = j ; AMD_DEBUG3 ((" got to e: "ID"\n", e)) ; } } } #endif /* ========================================================================= */ /* compress the paths of the variables */ /* ========================================================================= */ for (i = 0 ; i < n ; i++) { if (Nv [i] == 0) { /* ------------------------------------------------------------- * i is an un-ordered row. Traverse the tree from i until * reaching an element, e. The element, e, was the principal * supervariable of i and all nodes in the path from i to when e * was selected as pivot. * ------------------------------------------------------------- */ AMD_DEBUG1 (("Path compression, i unordered: "ID"\n", i)) ; j = Pe [i] ; ASSERT (j >= EMPTY && j < n) ; AMD_DEBUG3 ((" j: "ID"\n", j)) ; if (j == EMPTY) { /* Skip a dense variable. It has no parent. */ AMD_DEBUG3 ((" i is a dense variable\n")) ; continue ; } /* while (j is a variable) */ while (Nv [j] == 0) { AMD_DEBUG3 ((" j : "ID"\n", j)) ; j = Pe [j] ; AMD_DEBUG3 ((" j:: "ID"\n", j)) ; ASSERT (j >= 0 && j < n) ; } /* got to an element e */ e = j ; AMD_DEBUG3 (("got to e: "ID"\n", e)) ; /* ------------------------------------------------------------- * traverse the path again from i to e, and compress the path * (all nodes point to e). Path compression allows this code to * compute in O(n) time. * ------------------------------------------------------------- */ j = i ; /* while (j is a variable) */ while (Nv [j] == 0) { jnext = Pe [j] ; AMD_DEBUG3 (("j "ID" jnext "ID"\n", j, jnext)) ; Pe [j] = e ; j = jnext ; ASSERT (j >= 0 && j < n) ; } } } /* ========================================================================= */ /* postorder the assembly tree */ /* ========================================================================= */ AMD_postorder (n, Pe, Nv, Elen, W, /* output order */ Head, Next, Last) ; /* workspace */ /* ========================================================================= */ /* compute output permutation and inverse permutation */ /* ========================================================================= */ /* W [e] = k means that element e is the kth element in the new * order. e is in the range 0 to n-1, and k is in the range 0 to * the number of elements. Use Head for inverse order. */ for (k = 0 ; k < n ; k++) { Head [k] = EMPTY ; Next [k] = EMPTY ; } for (e = 0 ; e < n ; e++) { k = W [e] ; ASSERT ((k == EMPTY) == (Nv [e] == 0)) ; if (k != EMPTY) { ASSERT (k >= 0 && k < n) ; Head [k] = e ; } } /* construct output inverse permutation in Next, * and permutation in Last */ nel = 0 ; for (k = 0 ; k < n ; k++) { e = Head [k] ; if (e == EMPTY) break ; ASSERT (e >= 0 && e < n && Nv [e] > 0) ; Next [e] = nel ; nel += Nv [e] ; } ASSERT (nel == n - ndense) ; /* order non-principal variables (dense, & those merged into supervar's) */ for (i = 0 ; i < n ; i++) { if (Nv [i] == 0) { e = Pe [i] ; ASSERT (e >= EMPTY && e < n) ; if (e != EMPTY) { /* This is an unordered variable that was merged * into element e via supernode detection or mass * elimination of i when e became the pivot element. * Place i in order just before e. */ ASSERT (Next [i] == EMPTY && Nv [e] > 0) ; Next [i] = Next [e] ; Next [e]++ ; } else { /* This is a dense unordered variable, with no parent. * Place it last in the output order. */ Next [i] = nel++ ; } } } ASSERT (nel == n) ; AMD_DEBUG2 (("\n\nPerm:\n")) ; for (i = 0 ; i < n ; i++) { k = Next [i] ; ASSERT (k >= 0 && k < n) ; Last [k] = i ; AMD_DEBUG2 ((" perm ["ID"] = "ID"\n", k, i)) ; } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/AMD/Source/amd_info.c��������������������������������������������������������������������0000644�0001762�0000144�00000010305�13652535054�016075� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================= */ /* === AMD_info ============================================================ */ /* ========================================================================= */ /* ------------------------------------------------------------------------- */ /* AMD, Copyright (c) Timothy A. Davis, */ /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ /* email: DrTimothyAldenDavis@gmail.com */ /* ------------------------------------------------------------------------- */ /* User-callable. Prints the output statistics for AMD. See amd.h * for details. If the Info array is not present, nothing is printed. */ #include "amd_internal.h" #define PRI(format,x) { if (x >= 0) { SUITESPARSE_PRINTF ((format, x)) ; }} GLOBAL void AMD_info ( double Info [ ] ) { double n, ndiv, nmultsubs_ldl, nmultsubs_lu, lnz, lnzd ; SUITESPARSE_PRINTF (("\nAMD version %d.%d.%d, %s, results:\n", AMD_MAIN_VERSION, AMD_SUB_VERSION, AMD_SUBSUB_VERSION, AMD_DATE)) ; if (!Info) { return ; } n = Info [AMD_N] ; ndiv = Info [AMD_NDIV] ; nmultsubs_ldl = Info [AMD_NMULTSUBS_LDL] ; nmultsubs_lu = Info [AMD_NMULTSUBS_LU] ; lnz = Info [AMD_LNZ] ; lnzd = (n >= 0 && lnz >= 0) ? (n + lnz) : (-1) ; /* AMD return status */ SUITESPARSE_PRINTF ((" status: ")) ; if (Info [AMD_STATUS] == AMD_OK) { SUITESPARSE_PRINTF (("OK\n")) ; } else if (Info [AMD_STATUS] == AMD_OUT_OF_MEMORY) { SUITESPARSE_PRINTF (("out of memory\n")) ; } else if (Info [AMD_STATUS] == AMD_INVALID) { SUITESPARSE_PRINTF (("invalid matrix\n")) ; } else if (Info [AMD_STATUS] == AMD_OK_BUT_JUMBLED) { SUITESPARSE_PRINTF (("OK, but jumbled\n")) ; } else { SUITESPARSE_PRINTF (("unknown\n")) ; } /* statistics about the input matrix */ PRI (" n, dimension of A: %.20g\n", n); PRI (" nz, number of nonzeros in A: %.20g\n", Info [AMD_NZ]) ; PRI (" symmetry of A: %.4f\n", Info [AMD_SYMMETRY]) ; PRI (" number of nonzeros on diagonal: %.20g\n", Info [AMD_NZDIAG]) ; PRI (" nonzeros in pattern of A+A' (excl. diagonal): %.20g\n", Info [AMD_NZ_A_PLUS_AT]) ; PRI (" # dense rows/columns of A+A': %.20g\n", Info [AMD_NDENSE]) ; /* statistics about AMD's behavior */ PRI (" memory used, in bytes: %.20g\n", Info [AMD_MEMORY]) ; PRI (" # of memory compactions: %.20g\n", Info [AMD_NCMPA]) ; /* statistics about the ordering quality */ SUITESPARSE_PRINTF (("\n" " The following approximate statistics are for a subsequent\n" " factorization of A(P,P) + A(P,P)'. They are slight upper\n" " bounds if there are no dense rows/columns in A+A', and become\n" " looser if dense rows/columns exist.\n\n")) ; PRI (" nonzeros in L (excluding diagonal): %.20g\n", lnz) ; PRI (" nonzeros in L (including diagonal): %.20g\n", lnzd) ; PRI (" # divide operations for LDL' or LU: %.20g\n", ndiv) ; PRI (" # multiply-subtract operations for LDL': %.20g\n", nmultsubs_ldl) ; PRI (" # multiply-subtract operations for LU: %.20g\n", nmultsubs_lu) ; PRI (" max nz. in any column of L (incl. diagonal): %.20g\n", Info [AMD_DMAX]) ; /* total flop counts for various factorizations */ if (n >= 0 && ndiv >= 0 && nmultsubs_ldl >= 0 && nmultsubs_lu >= 0) { SUITESPARSE_PRINTF (("\n" " chol flop count for real A, sqrt counted as 1 flop: %.20g\n" " LDL' flop count for real A: %.20g\n" " LDL' flop count for complex A: %.20g\n" " LU flop count for real A (with no pivoting): %.20g\n" " LU flop count for complex A (with no pivoting): %.20g\n\n", n + ndiv + 2*nmultsubs_ldl, ndiv + 2*nmultsubs_ldl, 9*ndiv + 8*nmultsubs_ldl, ndiv + 2*nmultsubs_lu, 9*ndiv + 8*nmultsubs_lu)) ; } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/AMD/Source/amd_aat.c���������������������������������������������������������������������0000644�0001762�0000144�00000011357�11770402705�015712� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================= */ /* === AMD_aat ============================================================= */ /* ========================================================================= */ /* ------------------------------------------------------------------------- */ /* AMD, Copyright (c) Timothy A. Davis, */ /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ /* email: DrTimothyAldenDavis@gmail.com */ /* ------------------------------------------------------------------------- */ /* AMD_aat: compute the symmetry of the pattern of A, and count the number of * nonzeros each column of A+A' (excluding the diagonal). Assumes the input * matrix has no errors, with sorted columns and no duplicates * (AMD_valid (n, n, Ap, Ai) must be AMD_OK, but this condition is not * checked). */ #include "amd_internal.h" GLOBAL size_t AMD_aat /* returns nz in A+A' */ ( Int n, const Int Ap [ ], const Int Ai [ ], Int Len [ ], /* Len [j]: length of column j of A+A', excl diagonal*/ Int Tp [ ], /* workspace of size n */ double Info [ ] ) { Int p1, p2, p, i, j, pj, pj2, k, nzdiag, nzboth, nz ; double sym ; size_t nzaat ; #ifndef NDEBUG AMD_debug_init ("AMD AAT") ; for (k = 0 ; k < n ; k++) Tp [k] = EMPTY ; ASSERT (AMD_valid (n, n, Ap, Ai) == AMD_OK) ; #endif if (Info != (double *) NULL) { /* clear the Info array, if it exists */ for (i = 0 ; i < AMD_INFO ; i++) { Info [i] = EMPTY ; } Info [AMD_STATUS] = AMD_OK ; } for (k = 0 ; k < n ; k++) { Len [k] = 0 ; } nzdiag = 0 ; nzboth = 0 ; nz = Ap [n] ; for (k = 0 ; k < n ; k++) { p1 = Ap [k] ; p2 = Ap [k+1] ; AMD_DEBUG2 (("\nAAT Column: "ID" p1: "ID" p2: "ID"\n", k, p1, p2)) ; /* construct A+A' */ for (p = p1 ; p < p2 ; ) { /* scan the upper triangular part of A */ j = Ai [p] ; if (j < k) { /* entry A (j,k) is in the strictly upper triangular part, * add both A (j,k) and A (k,j) to the matrix A+A' */ Len [j]++ ; Len [k]++ ; AMD_DEBUG3 ((" upper ("ID","ID") ("ID","ID")\n", j,k, k,j)); p++ ; } else if (j == k) { /* skip the diagonal */ p++ ; nzdiag++ ; break ; } else /* j > k */ { /* first entry below the diagonal */ break ; } /* scan lower triangular part of A, in column j until reaching * row k. Start where last scan left off. */ ASSERT (Tp [j] != EMPTY) ; ASSERT (Ap [j] <= Tp [j] && Tp [j] <= Ap [j+1]) ; pj2 = Ap [j+1] ; for (pj = Tp [j] ; pj < pj2 ; ) { i = Ai [pj] ; if (i < k) { /* A (i,j) is only in the lower part, not in upper. * add both A (i,j) and A (j,i) to the matrix A+A' */ Len [i]++ ; Len [j]++ ; AMD_DEBUG3 ((" lower ("ID","ID") ("ID","ID")\n", i,j, j,i)) ; pj++ ; } else if (i == k) { /* entry A (k,j) in lower part and A (j,k) in upper */ pj++ ; nzboth++ ; break ; } else /* i > k */ { /* consider this entry later, when k advances to i */ break ; } } Tp [j] = pj ; } /* Tp [k] points to the entry just below the diagonal in column k */ Tp [k] = p ; } /* clean up, for remaining mismatched entries */ for (j = 0 ; j < n ; j++) { for (pj = Tp [j] ; pj < Ap [j+1] ; pj++) { i = Ai [pj] ; /* A (i,j) is only in the lower part, not in upper. * add both A (i,j) and A (j,i) to the matrix A+A' */ Len [i]++ ; Len [j]++ ; AMD_DEBUG3 ((" lower cleanup ("ID","ID") ("ID","ID")\n", i,j, j,i)) ; } } /* --------------------------------------------------------------------- */ /* compute the symmetry of the nonzero pattern of A */ /* --------------------------------------------------------------------- */ /* Given a matrix A, the symmetry of A is: * B = tril (spones (A), -1) + triu (spones (A), 1) ; * sym = nnz (B & B') / nnz (B) ; * or 1 if nnz (B) is zero. */ if (nz == nzdiag) { sym = 1 ; } else { sym = (2 * (double) nzboth) / ((double) (nz - nzdiag)) ; } nzaat = 0 ; for (k = 0 ; k < n ; k++) { nzaat += Len [k] ; } AMD_DEBUG1 (("AMD nz in A+A', excluding diagonal (nzaat) = %g\n", (double) nzaat)) ; AMD_DEBUG1 ((" nzboth: "ID" nz: "ID" nzdiag: "ID" symmetry: %g\n", nzboth, nz, nzdiag, sym)) ; if (Info != (double *) NULL) { Info [AMD_STATUS] = AMD_OK ; Info [AMD_N] = n ; Info [AMD_NZ] = nz ; Info [AMD_SYMMETRY] = sym ; /* symmetry of pattern of A */ Info [AMD_NZDIAG] = nzdiag ; /* nonzeros on diagonal of A */ Info [AMD_NZ_A_PLUS_AT] = nzaat ; /* nonzeros in A+A' */ } return (nzaat) ; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/AMD/Source/amd_control.c�����������������������������������������������������������������0000644�0001762�0000144�00000003513�13652535054�016625� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================= */ /* === AMD_control ========================================================= */ /* ========================================================================= */ /* ------------------------------------------------------------------------- */ /* AMD, Copyright (c) Timothy A. Davis, */ /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ /* email: DrTimothyAldenDavis@gmail.com */ /* ------------------------------------------------------------------------- */ /* User-callable. Prints the control parameters for AMD. See amd.h * for details. If the Control array is not present, the defaults are * printed instead. */ #include "amd_internal.h" GLOBAL void AMD_control ( double Control [ ] ) { double alpha ; Int aggressive ; if (Control != (double *) NULL) { alpha = Control [AMD_DENSE] ; aggressive = Control [AMD_AGGRESSIVE] != 0 ; } else { alpha = AMD_DEFAULT_DENSE ; aggressive = AMD_DEFAULT_AGGRESSIVE ; } SUITESPARSE_PRINTF (( "\nAMD version %d.%d.%d, %s: approximate minimum degree ordering\n" " dense row parameter: %g\n", AMD_MAIN_VERSION, AMD_SUB_VERSION, AMD_SUBSUB_VERSION, AMD_DATE, alpha)) ; if (alpha < 0) { SUITESPARSE_PRINTF ((" no rows treated as dense\n")) ; } else { SUITESPARSE_PRINTF (( " (rows with more than max (%g * sqrt (n), 16) entries are\n" " considered \"dense\", and placed last in output permutation)\n", alpha)) ; } if (aggressive) { SUITESPARSE_PRINTF ((" aggressive absorption: yes\n")) ; } else { SUITESPARSE_PRINTF ((" aggressive absorption: no\n")) ; } SUITESPARSE_PRINTF ((" size of AMD integer: %d\n\n", sizeof (Int))) ; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/AMD/Source/amd_order.c�������������������������������������������������������������������0000644�0001762�0000144�00000013617�13652535054�016266� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================= */ /* === AMD_order =========================================================== */ /* ========================================================================= */ /* ------------------------------------------------------------------------- */ /* AMD, Copyright (c) Timothy A. Davis, */ /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ /* email: DrTimothyAldenDavis@gmail.com */ /* ------------------------------------------------------------------------- */ /* User-callable AMD minimum degree ordering routine. See amd.h for * documentation. */ #include "amd_internal.h" /* ========================================================================= */ /* === AMD_order =========================================================== */ /* ========================================================================= */ GLOBAL Int AMD_order ( Int n, const Int Ap [ ], const Int Ai [ ], Int P [ ], double Control [ ], double Info [ ] ) { Int *Len, *S, nz, i, *Pinv, info, status, *Rp, *Ri, *Cp, *Ci, ok ; size_t nzaat, slen ; double mem = 0 ; #ifndef NDEBUG AMD_debug_init ("amd") ; #endif /* clear the Info array, if it exists */ info = Info != (double *) NULL ; if (info) { for (i = 0 ; i < AMD_INFO ; i++) { Info [i] = EMPTY ; } Info [AMD_N] = n ; Info [AMD_STATUS] = AMD_OK ; } /* make sure inputs exist and n is >= 0 */ if (Ai == (Int *) NULL || Ap == (Int *) NULL || P == (Int *) NULL || n < 0) { if (info) Info [AMD_STATUS] = AMD_INVALID ; return (AMD_INVALID) ; /* arguments are invalid */ } if (n == 0) { return (AMD_OK) ; /* n is 0 so there's nothing to do */ } nz = Ap [n] ; if (info) { Info [AMD_NZ] = nz ; } if (nz < 0) { if (info) Info [AMD_STATUS] = AMD_INVALID ; return (AMD_INVALID) ; } /* check if n or nz will cause size_t overflow */ if (((size_t) n) >= SIZE_T_MAX / sizeof (Int) || ((size_t) nz) >= SIZE_T_MAX / sizeof (Int)) { if (info) Info [AMD_STATUS] = AMD_OUT_OF_MEMORY ; return (AMD_OUT_OF_MEMORY) ; /* problem too large */ } /* check the input matrix: AMD_OK, AMD_INVALID, or AMD_OK_BUT_JUMBLED */ status = AMD_valid (n, n, Ap, Ai) ; if (status == AMD_INVALID) { if (info) Info [AMD_STATUS] = AMD_INVALID ; return (AMD_INVALID) ; /* matrix is invalid */ } /* allocate two size-n integer workspaces */ Len = SuiteSparse_malloc (n, sizeof (Int)) ; Pinv = SuiteSparse_malloc (n, sizeof (Int)) ; mem += n ; mem += n ; if (!Len || !Pinv) { /* :: out of memory :: */ SuiteSparse_free (Len) ; SuiteSparse_free (Pinv) ; if (info) Info [AMD_STATUS] = AMD_OUT_OF_MEMORY ; return (AMD_OUT_OF_MEMORY) ; } if (status == AMD_OK_BUT_JUMBLED) { /* sort the input matrix and remove duplicate entries */ AMD_DEBUG1 (("Matrix is jumbled\n")) ; Rp = SuiteSparse_malloc (n+1, sizeof (Int)) ; Ri = SuiteSparse_malloc (nz, sizeof (Int)) ; mem += (n+1) ; mem += MAX (nz,1) ; if (!Rp || !Ri) { /* :: out of memory :: */ SuiteSparse_free (Rp) ; SuiteSparse_free (Ri) ; SuiteSparse_free (Len) ; SuiteSparse_free (Pinv) ; if (info) Info [AMD_STATUS] = AMD_OUT_OF_MEMORY ; return (AMD_OUT_OF_MEMORY) ; } /* use Len and Pinv as workspace to create R = A' */ AMD_preprocess (n, Ap, Ai, Rp, Ri, Len, Pinv) ; Cp = Rp ; Ci = Ri ; } else { /* order the input matrix as-is. No need to compute R = A' first */ Rp = NULL ; Ri = NULL ; Cp = (Int *) Ap ; Ci = (Int *) Ai ; } /* --------------------------------------------------------------------- */ /* determine the symmetry and count off-diagonal nonzeros in A+A' */ /* --------------------------------------------------------------------- */ nzaat = AMD_aat (n, Cp, Ci, Len, P, Info) ; AMD_DEBUG1 (("nzaat: %g\n", (double) nzaat)) ; ASSERT ((MAX (nz-n, 0) <= nzaat) && (nzaat <= 2 * (size_t) nz)) ; /* --------------------------------------------------------------------- */ /* allocate workspace for matrix, elbow room, and 6 size-n vectors */ /* --------------------------------------------------------------------- */ S = NULL ; slen = nzaat ; /* space for matrix */ ok = ((slen + nzaat/5) >= slen) ; /* check for size_t overflow */ slen += nzaat/5 ; /* add elbow room */ for (i = 0 ; ok && i < 7 ; i++) { ok = ((slen + n) > slen) ; /* check for size_t overflow */ slen += n ; /* size-n elbow room, 6 size-n work */ } mem += slen ; ok = ok && (slen < SIZE_T_MAX / sizeof (Int)) ; /* check for overflow */ ok = ok && (slen < Int_MAX) ; /* S[i] for Int i must be OK */ if (ok) { S = SuiteSparse_malloc (slen, sizeof (Int)) ; } AMD_DEBUG1 (("slen %g\n", (double) slen)) ; if (!S) { /* :: out of memory :: (or problem too large) */ SuiteSparse_free (Rp) ; SuiteSparse_free (Ri) ; SuiteSparse_free (Len) ; SuiteSparse_free (Pinv) ; if (info) Info [AMD_STATUS] = AMD_OUT_OF_MEMORY ; return (AMD_OUT_OF_MEMORY) ; } if (info) { /* memory usage, in bytes. */ Info [AMD_MEMORY] = mem * sizeof (Int) ; } /* --------------------------------------------------------------------- */ /* order the matrix */ /* --------------------------------------------------------------------- */ AMD_1 (n, Cp, Ci, P, Pinv, Len, slen, S, Control, Info) ; /* --------------------------------------------------------------------- */ /* free the workspace */ /* --------------------------------------------------------------------- */ SuiteSparse_free (Rp) ; SuiteSparse_free (Ri) ; SuiteSparse_free (Len) ; SuiteSparse_free (Pinv) ; SuiteSparse_free (S) ; if (info) Info [AMD_STATUS] = status ; return (status) ; /* successful ordering */ } �����������������������������������������������������������������������������������������������������������������Matrix/src/AMD/Source/make-Make.R�������������������������������������������������������������������0000644�0001762�0000144�00000001421�13763176012�016065� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## From: Prof Brian Ripley ## To: Martin Maechler ## cc: Doug and Martin ## Subject: Re: [Rd] Package Matrix does not compile in R-devel_2009-01-10 (fwd) ## Date: Thu, 15 Jan 2009 14:22:17 +0000 (GMT) AMD <- c("aat", "1", "2", "postorder", "post_tree", "defaults", "order", "control", "info", "valid", "preprocess", "dump") cat("OBJS = ") for (i in AMD) cat(sprintf("amd_i_%s.o amd_l_%s.o ", i, i)) cat("\n\n") CC1 <- "\t$(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include" for (i in AMD) cat(sprintf("amd_i_%s.o: amd_%s.c $(INC)", i, i), sprintf(paste(CC1, "-DDINT -c amd_%s.c -o $@"), i), sep="\n") cat("\n") for (i in AMD) cat(sprintf("amd_l_%s.o: amd_%s.c $(INC)", i,i), sprintf(paste(CC1, "-DDLONG -c amd_%s.c -o $@"), i), sep="\n") �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/AMD/Source/amd_1.c�����������������������������������������������������������������������0000644�0001762�0000144�00000013116�11770402705�015300� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================= */ /* === AMD_1 =============================================================== */ /* ========================================================================= */ /* ------------------------------------------------------------------------- */ /* AMD, Copyright (c) Timothy A. Davis, */ /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ /* email: DrTimothyAldenDavis@gmail.com */ /* ------------------------------------------------------------------------- */ /* AMD_1: Construct A+A' for a sparse matrix A and perform the AMD ordering. * * The n-by-n sparse matrix A can be unsymmetric. It is stored in MATLAB-style * compressed-column form, with sorted row indices in each column, and no * duplicate entries. Diagonal entries may be present, but they are ignored. * Row indices of column j of A are stored in Ai [Ap [j] ... Ap [j+1]-1]. * Ap [0] must be zero, and nz = Ap [n] is the number of entries in A. The * size of the matrix, n, must be greater than or equal to zero. * * This routine must be preceded by a call to AMD_aat, which computes the * number of entries in each row/column in A+A', excluding the diagonal. * Len [j], on input, is the number of entries in row/column j of A+A'. This * routine constructs the matrix A+A' and then calls AMD_2. No error checking * is performed (this was done in AMD_valid). */ #include "amd_internal.h" GLOBAL void AMD_1 ( Int n, /* n > 0 */ const Int Ap [ ], /* input of size n+1, not modified */ const Int Ai [ ], /* input of size nz = Ap [n], not modified */ Int P [ ], /* size n output permutation */ Int Pinv [ ], /* size n output inverse permutation */ Int Len [ ], /* size n input, undefined on output */ Int slen, /* slen >= sum (Len [0..n-1]) + 7n, * ideally slen = 1.2 * sum (Len) + 8n */ Int S [ ], /* size slen workspace */ double Control [ ], /* input array of size AMD_CONTROL */ double Info [ ] /* output array of size AMD_INFO */ ) { Int i, j, k, p, pfree, iwlen, pj, p1, p2, pj2, *Iw, *Pe, *Nv, *Head, *Elen, *Degree, *s, *W, *Sp, *Tp ; /* --------------------------------------------------------------------- */ /* construct the matrix for AMD_2 */ /* --------------------------------------------------------------------- */ ASSERT (n > 0) ; iwlen = slen - 6*n ; s = S ; Pe = s ; s += n ; Nv = s ; s += n ; Head = s ; s += n ; Elen = s ; s += n ; Degree = s ; s += n ; W = s ; s += n ; Iw = s ; s += iwlen ; ASSERT (AMD_valid (n, n, Ap, Ai) == AMD_OK) ; /* construct the pointers for A+A' */ Sp = Nv ; /* use Nv and W as workspace for Sp and Tp [ */ Tp = W ; pfree = 0 ; for (j = 0 ; j < n ; j++) { Pe [j] = pfree ; Sp [j] = pfree ; pfree += Len [j] ; } /* Note that this restriction on iwlen is slightly more restrictive than * what is strictly required in AMD_2. AMD_2 can operate with no elbow * room at all, but it will be very slow. For better performance, at * least size-n elbow room is enforced. */ ASSERT (iwlen >= pfree + n) ; #ifndef NDEBUG for (p = 0 ; p < iwlen ; p++) Iw [p] = EMPTY ; #endif for (k = 0 ; k < n ; k++) { AMD_DEBUG1 (("Construct row/column k= "ID" of A+A'\n", k)) ; p1 = Ap [k] ; p2 = Ap [k+1] ; /* construct A+A' */ for (p = p1 ; p < p2 ; ) { /* scan the upper triangular part of A */ j = Ai [p] ; ASSERT (j >= 0 && j < n) ; if (j < k) { /* entry A (j,k) in the strictly upper triangular part */ ASSERT (Sp [j] < (j == n-1 ? pfree : Pe [j+1])) ; ASSERT (Sp [k] < (k == n-1 ? pfree : Pe [k+1])) ; Iw [Sp [j]++] = k ; Iw [Sp [k]++] = j ; p++ ; } else if (j == k) { /* skip the diagonal */ p++ ; break ; } else /* j > k */ { /* first entry below the diagonal */ break ; } /* scan lower triangular part of A, in column j until reaching * row k. Start where last scan left off. */ ASSERT (Ap [j] <= Tp [j] && Tp [j] <= Ap [j+1]) ; pj2 = Ap [j+1] ; for (pj = Tp [j] ; pj < pj2 ; ) { i = Ai [pj] ; ASSERT (i >= 0 && i < n) ; if (i < k) { /* A (i,j) is only in the lower part, not in upper */ ASSERT (Sp [i] < (i == n-1 ? pfree : Pe [i+1])) ; ASSERT (Sp [j] < (j == n-1 ? pfree : Pe [j+1])) ; Iw [Sp [i]++] = j ; Iw [Sp [j]++] = i ; pj++ ; } else if (i == k) { /* entry A (k,j) in lower part and A (j,k) in upper */ pj++ ; break ; } else /* i > k */ { /* consider this entry later, when k advances to i */ break ; } } Tp [j] = pj ; } Tp [k] = p ; } /* clean up, for remaining mismatched entries */ for (j = 0 ; j < n ; j++) { for (pj = Tp [j] ; pj < Ap [j+1] ; pj++) { i = Ai [pj] ; ASSERT (i >= 0 && i < n) ; /* A (i,j) is only in the lower part, not in upper */ ASSERT (Sp [i] < (i == n-1 ? pfree : Pe [i+1])) ; ASSERT (Sp [j] < (j == n-1 ? pfree : Pe [j+1])) ; Iw [Sp [i]++] = j ; Iw [Sp [j]++] = i ; } } #ifndef NDEBUG for (j = 0 ; j < n-1 ; j++) ASSERT (Sp [j] == Pe [j+1]) ; ASSERT (Sp [n-1] == pfree) ; #endif /* Tp and Sp no longer needed ] */ /* --------------------------------------------------------------------- */ /* order the matrix */ /* --------------------------------------------------------------------- */ AMD_2 (n, Pe, Iw, Len, iwlen, pfree, Nv, Pinv, P, Head, Elen, Degree, W, Control, Info) ; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/AMD/Source/Makefile����������������������������������������������������������������������0000644�0001762�0000144�00000000335�14547724215�015622� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PKG_CPPFLAGS = -I../Include -I../../SuiteSparse_config LIB = ../../AMD.a lib: $(LIB) include make_o.mk $(LIB): $(OBJS) $(AR) -rucs $(LIB) $(OBJS) mostlyclean: clean clean: @-rm -rf .libs _libs $(LIB) @-rm -f *.o ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/AMD/Source/make_o.mk���������������������������������������������������������������������0000644�0001762�0000144�00000006025�13763176012�015743� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OBJS = amd_i_aat.o amd_l_aat.o amd_i_1.o amd_l_1.o amd_i_2.o amd_l_2.o amd_i_postorder.o amd_l_postorder.o amd_i_post_tree.o amd_l_post_tree.o amd_i_defaults.o amd_l_defaults.o amd_i_order.o amd_l_order.o amd_i_control.o amd_l_control.o amd_i_info.o amd_l_info.o amd_i_valid.o amd_l_valid.o amd_i_preprocess.o amd_l_preprocess.o amd_i_dump.o amd_l_dump.o amd_i_aat.o: amd_aat.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDINT -c amd_aat.c -o $@ amd_i_1.o: amd_1.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDINT -c amd_1.c -o $@ amd_i_2.o: amd_2.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDINT -c amd_2.c -o $@ amd_i_postorder.o: amd_postorder.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDINT -c amd_postorder.c -o $@ amd_i_post_tree.o: amd_post_tree.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDINT -c amd_post_tree.c -o $@ amd_i_defaults.o: amd_defaults.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDINT -c amd_defaults.c -o $@ amd_i_order.o: amd_order.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDINT -c amd_order.c -o $@ amd_i_control.o: amd_control.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDINT -c amd_control.c -o $@ amd_i_info.o: amd_info.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDINT -c amd_info.c -o $@ amd_i_valid.o: amd_valid.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDINT -c amd_valid.c -o $@ amd_i_preprocess.o: amd_preprocess.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDINT -c amd_preprocess.c -o $@ amd_i_dump.o: amd_dump.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDINT -c amd_dump.c -o $@ amd_l_aat.o: amd_aat.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDLONG -c amd_aat.c -o $@ amd_l_1.o: amd_1.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDLONG -c amd_1.c -o $@ amd_l_2.o: amd_2.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDLONG -c amd_2.c -o $@ amd_l_postorder.o: amd_postorder.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDLONG -c amd_postorder.c -o $@ amd_l_post_tree.o: amd_post_tree.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDLONG -c amd_post_tree.c -o $@ amd_l_defaults.o: amd_defaults.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDLONG -c amd_defaults.c -o $@ amd_l_order.o: amd_order.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDLONG -c amd_order.c -o $@ amd_l_control.o: amd_control.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDLONG -c amd_control.c -o $@ amd_l_info.o: amd_info.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDLONG -c amd_info.c -o $@ amd_l_valid.o: amd_valid.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDLONG -c amd_valid.c -o $@ amd_l_preprocess.o: amd_preprocess.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDLONG -c amd_preprocess.c -o $@ amd_l_dump.o: amd_dump.c $(INC) $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDLONG -c amd_dump.c -o $@ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/AMD/Source/amd_dump.c��������������������������������������������������������������������0000644�0001762�0000144�00000011624�11770402705�016107� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================= */ /* === AMD_dump ============================================================ */ /* ========================================================================= */ /* ------------------------------------------------------------------------- */ /* AMD, Copyright (c) Timothy A. Davis, */ /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ /* email: DrTimothyAldenDavis@gmail.com */ /* ------------------------------------------------------------------------- */ /* Debugging routines for AMD. Not used if NDEBUG is not defined at compile- * time (the default). See comments in amd_internal.h on how to enable * debugging. Not user-callable. */ #include "amd_internal.h" #ifndef NDEBUG /* This global variable is present only when debugging */ GLOBAL Int AMD_debug = -999 ; /* default is no debug printing */ /* ========================================================================= */ /* === AMD_debug_init ====================================================== */ /* ========================================================================= */ /* Sets the debug print level, by reading the file debug.amd (if it exists) */ GLOBAL void AMD_debug_init ( char *s ) { FILE *f ; f = fopen ("debug.amd", "r") ; if (f == (FILE *) NULL) { AMD_debug = -999 ; } else { fscanf (f, ID, &AMD_debug) ; fclose (f) ; } if (AMD_debug >= 0) { printf ("%s: AMD_debug_init, D= "ID"\n", s, AMD_debug) ; } } /* ========================================================================= */ /* === AMD_dump ============================================================ */ /* ========================================================================= */ /* Dump AMD's data structure, except for the hash buckets. This routine * cannot be called when the hash buckets are non-empty. */ GLOBAL void AMD_dump ( Int n, /* A is n-by-n */ Int Pe [ ], /* pe [0..n-1]: index in iw of start of row i */ Int Iw [ ], /* workspace of size iwlen, iwlen [0..pfree-1] * holds the matrix on input */ Int Len [ ], /* len [0..n-1]: length for row i */ Int iwlen, /* length of iw */ Int pfree, /* iw [pfree ... iwlen-1] is empty on input */ Int Nv [ ], /* nv [0..n-1] */ Int Next [ ], /* next [0..n-1] */ Int Last [ ], /* last [0..n-1] */ Int Head [ ], /* head [0..n-1] */ Int Elen [ ], /* size n */ Int Degree [ ], /* size n */ Int W [ ], /* size n */ Int nel ) { Int i, pe, elen, nv, len, e, p, k, j, deg, w, cnt, ilast ; if (AMD_debug < 0) return ; ASSERT (pfree <= iwlen) ; AMD_DEBUG3 (("\nAMD dump, pfree: "ID"\n", pfree)) ; for (i = 0 ; i < n ; i++) { pe = Pe [i] ; elen = Elen [i] ; nv = Nv [i] ; len = Len [i] ; w = W [i] ; if (elen >= EMPTY) { if (nv == 0) { AMD_DEBUG3 (("\nI "ID": nonprincipal: ", i)) ; ASSERT (elen == EMPTY) ; if (pe == EMPTY) { AMD_DEBUG3 ((" dense node\n")) ; ASSERT (w == 1) ; } else { ASSERT (pe < EMPTY) ; AMD_DEBUG3 ((" i "ID" -> parent "ID"\n", i, FLIP (Pe[i]))); } } else { AMD_DEBUG3 (("\nI "ID": active principal supervariable:\n",i)); AMD_DEBUG3 ((" nv(i): "ID" Flag: %d\n", nv, (nv < 0))) ; ASSERT (elen >= 0) ; ASSERT (nv > 0 && pe >= 0) ; p = pe ; AMD_DEBUG3 ((" e/s: ")) ; if (elen == 0) AMD_DEBUG3 ((" : ")) ; ASSERT (pe + len <= pfree) ; for (k = 0 ; k < len ; k++) { j = Iw [p] ; AMD_DEBUG3 ((" "ID"", j)) ; ASSERT (j >= 0 && j < n) ; if (k == elen-1) AMD_DEBUG3 ((" : ")) ; p++ ; } AMD_DEBUG3 (("\n")) ; } } else { e = i ; if (w == 0) { AMD_DEBUG3 (("\nE "ID": absorbed element: w "ID"\n", e, w)) ; ASSERT (nv > 0 && pe < 0) ; AMD_DEBUG3 ((" e "ID" -> parent "ID"\n", e, FLIP (Pe [e]))) ; } else { AMD_DEBUG3 (("\nE "ID": unabsorbed element: w "ID"\n", e, w)) ; ASSERT (nv > 0 && pe >= 0) ; p = pe ; AMD_DEBUG3 ((" : ")) ; ASSERT (pe + len <= pfree) ; for (k = 0 ; k < len ; k++) { j = Iw [p] ; AMD_DEBUG3 ((" "ID"", j)) ; ASSERT (j >= 0 && j < n) ; p++ ; } AMD_DEBUG3 (("\n")) ; } } } /* this routine cannot be called when the hash buckets are non-empty */ AMD_DEBUG3 (("\nDegree lists:\n")) ; if (nel >= 0) { cnt = 0 ; for (deg = 0 ; deg < n ; deg++) { if (Head [deg] == EMPTY) continue ; ilast = EMPTY ; AMD_DEBUG3 ((ID": \n", deg)) ; for (i = Head [deg] ; i != EMPTY ; i = Next [i]) { AMD_DEBUG3 ((" "ID" : next "ID" last "ID" deg "ID"\n", i, Next [i], Last [i], Degree [i])) ; ASSERT (i >= 0 && i < n && ilast == Last [i] && deg == Degree [i]) ; cnt += Nv [i] ; ilast = i ; } AMD_DEBUG3 (("\n")) ; } ASSERT (cnt == n - nel) ; } } #endif ������������������������������������������������������������������������������������������������������������Matrix/src/AMD/Source/amd_defaults.c����������������������������������������������������������������0000644�0001762�0000144�00000002345�11770402705�016751� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================= */ /* === AMD_defaults ======================================================== */ /* ========================================================================= */ /* ------------------------------------------------------------------------- */ /* AMD, Copyright (c) Timothy A. Davis, */ /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ /* email: DrTimothyAldenDavis@gmail.com */ /* ------------------------------------------------------------------------- */ /* User-callable. Sets default control parameters for AMD. See amd.h * for details. */ #include "amd_internal.h" /* ========================================================================= */ /* === AMD defaults ======================================================== */ /* ========================================================================= */ GLOBAL void AMD_defaults ( double Control [ ] ) { Int i ; if (Control != (double *) NULL) { for (i = 0 ; i < AMD_CONTROL ; i++) { Control [i] = 0 ; } Control [AMD_DENSE] = AMD_DEFAULT_DENSE ; Control [AMD_AGGRESSIVE] = AMD_DEFAULT_AGGRESSIVE ; } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/AMD/Source/amd_post_tree.c���������������������������������������������������������������0000644�0001762�0000144�00000007167�11770402705�017155� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================= */ /* === AMD_post_tree ======================================================= */ /* ========================================================================= */ /* ------------------------------------------------------------------------- */ /* AMD, Copyright (c) Timothy A. Davis, */ /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ /* email: DrTimothyAldenDavis@gmail.com */ /* ------------------------------------------------------------------------- */ /* Post-ordering of a supernodal elimination tree. */ #include "amd_internal.h" GLOBAL Int AMD_post_tree ( Int root, /* root of the tree */ Int k, /* start numbering at k */ Int Child [ ], /* input argument of size nn, undefined on * output. Child [i] is the head of a link * list of all nodes that are children of node * i in the tree. */ const Int Sibling [ ], /* input argument of size nn, not modified. * If f is a node in the link list of the * children of node i, then Sibling [f] is the * next child of node i. */ Int Order [ ], /* output order, of size nn. Order [i] = k * if node i is the kth node of the reordered * tree. */ Int Stack [ ] /* workspace of size nn */ #ifndef NDEBUG , Int nn /* nodes are in the range 0..nn-1. */ #endif ) { Int f, head, h, i ; #if 0 /* --------------------------------------------------------------------- */ /* recursive version (Stack [ ] is not used): */ /* --------------------------------------------------------------------- */ /* this is simple, but can caouse stack overflow if nn is large */ i = root ; for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) { k = AMD_post_tree (f, k, Child, Sibling, Order, Stack, nn) ; } Order [i] = k++ ; return (k) ; #endif /* --------------------------------------------------------------------- */ /* non-recursive version, using an explicit stack */ /* --------------------------------------------------------------------- */ /* push root on the stack */ head = 0 ; Stack [0] = root ; while (head >= 0) { /* get head of stack */ ASSERT (head < nn) ; i = Stack [head] ; AMD_DEBUG1 (("head of stack "ID" \n", i)) ; ASSERT (i >= 0 && i < nn) ; if (Child [i] != EMPTY) { /* the children of i are not yet ordered */ /* push each child onto the stack in reverse order */ /* so that small ones at the head of the list get popped first */ /* and the biggest one at the end of the list gets popped last */ for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) { head++ ; ASSERT (head < nn) ; ASSERT (f >= 0 && f < nn) ; } h = head ; ASSERT (head < nn) ; for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) { ASSERT (h > 0) ; Stack [h--] = f ; AMD_DEBUG1 (("push "ID" on stack\n", f)) ; ASSERT (f >= 0 && f < nn) ; } ASSERT (Stack [h] == i) ; /* delete child list so that i gets ordered next time we see it */ Child [i] = EMPTY ; } else { /* the children of i (if there were any) are already ordered */ /* remove i from the stack and order it. Front i is kth front */ head-- ; AMD_DEBUG1 (("pop "ID" order "ID"\n", i, k)) ; Order [i] = k++ ; ASSERT (k <= nn) ; } #ifndef NDEBUG AMD_DEBUG1 (("\nStack:")) ; for (h = head ; h >= 0 ; h--) { Int j = Stack [h] ; AMD_DEBUG1 ((" "ID, j)) ; ASSERT (j >= 0 && j < nn) ; } AMD_DEBUG1 (("\n\n")) ; ASSERT (head < nn) ; #endif } return (k) ; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/AMD/Source/amd_preprocess.c��������������������������������������������������������������0000644�0001762�0000144�00000007340�11770402705�017327� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================= */ /* === AMD_preprocess ====================================================== */ /* ========================================================================= */ /* ------------------------------------------------------------------------- */ /* AMD, Copyright (c) Timothy A. Davis, */ /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ /* email: DrTimothyAldenDavis@gmail.com */ /* ------------------------------------------------------------------------- */ /* Sorts, removes duplicate entries, and transposes from the nonzero pattern of * a column-form matrix A, to obtain the matrix R. The input matrix can have * duplicate entries and/or unsorted columns (AMD_valid (n,Ap,Ai) must not be * AMD_INVALID). * * This input condition is NOT checked. This routine is not user-callable. */ #include "amd_internal.h" /* ========================================================================= */ /* === AMD_preprocess ====================================================== */ /* ========================================================================= */ /* AMD_preprocess does not check its input for errors or allocate workspace. * On input, the condition (AMD_valid (n,n,Ap,Ai) != AMD_INVALID) must hold. */ GLOBAL void AMD_preprocess ( Int n, /* input matrix: A is n-by-n */ const Int Ap [ ], /* size n+1 */ const Int Ai [ ], /* size nz = Ap [n] */ /* output matrix R: */ Int Rp [ ], /* size n+1 */ Int Ri [ ], /* size nz (or less, if duplicates present) */ Int W [ ], /* workspace of size n */ Int Flag [ ] /* workspace of size n */ ) { /* --------------------------------------------------------------------- */ /* local variables */ /* --------------------------------------------------------------------- */ Int i, j, p, p2 ; ASSERT (AMD_valid (n, n, Ap, Ai) != AMD_INVALID) ; /* --------------------------------------------------------------------- */ /* count the entries in each row of A (excluding duplicates) */ /* --------------------------------------------------------------------- */ for (i = 0 ; i < n ; i++) { W [i] = 0 ; /* # of nonzeros in row i (excl duplicates) */ Flag [i] = EMPTY ; /* Flag [i] = j if i appears in column j */ } for (j = 0 ; j < n ; j++) { p2 = Ap [j+1] ; for (p = Ap [j] ; p < p2 ; p++) { i = Ai [p] ; if (Flag [i] != j) { /* row index i has not yet appeared in column j */ W [i]++ ; /* one more entry in row i */ Flag [i] = j ; /* flag row index i as appearing in col j*/ } } } /* --------------------------------------------------------------------- */ /* compute the row pointers for R */ /* --------------------------------------------------------------------- */ Rp [0] = 0 ; for (i = 0 ; i < n ; i++) { Rp [i+1] = Rp [i] + W [i] ; } for (i = 0 ; i < n ; i++) { W [i] = Rp [i] ; Flag [i] = EMPTY ; } /* --------------------------------------------------------------------- */ /* construct the row form matrix R */ /* --------------------------------------------------------------------- */ /* R = row form of pattern of A */ for (j = 0 ; j < n ; j++) { p2 = Ap [j+1] ; for (p = Ap [j] ; p < p2 ; p++) { i = Ai [p] ; if (Flag [i] != j) { /* row index i has not yet appeared in column j */ Ri [W [i]++] = j ; /* put col j in row i */ Flag [i] = j ; /* flag row index i as appearing in col j*/ } } } #ifndef NDEBUG ASSERT (AMD_valid (n, n, Rp, Ri) == AMD_OK) ; for (j = 0 ; j < n ; j++) { ASSERT (W [j] == Rp [j+1]) ; } #endif } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/t_Csparse_subassign.c��������������������������������������������������������������������0000644�0001762�0000144�00000032250�14531352033�016453� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*------ Definition of a template for [diln]Csparse_subassign(...) : * * -------- ~~~~~~~~~~~~~~~~~~~~~~ * i.e., included several times from ./Csparse.c * ~~~~~~~~~~~ * _slot_kind : use the integer codes matching x_slot_kind in ./Csparse.c */ #ifdef _d_Csp_ # define Csparse_subassign dCsparse_subassign # define x_CLASSES "dgCMatrix",/* 0 */ "dtCMatrix" /* 1 */ # define sparseVECTOR "dsparseVector" # define slot_kind_x 0 # define _DOUBLE_x # define _has_x_slot_ # undef _d_Csp_ #elif defined (_l_Csp_) # define Csparse_subassign lCsparse_subassign # define x_CLASSES "lgCMatrix",/* 0 */ "ltCMatrix" /* 1 */ # define sparseVECTOR "lsparseVector" # define slot_kind_x 1 # define _LGL_x # define _has_x_slot_ # undef _l_Csp_ #elif defined (_i_Csp_) # define Csparse_subassign iCsparse_subassign # define x_CLASSES "igCMatrix",/* 0 */ "itCMatrix" /* 1 */ # define sparseVECTOR "isparseVector" # define slot_kind_x 2 # define _INT_x # define _has_x_slot_ # undef _i_Csp_ #elif defined (_n_Csp_) # define Csparse_subassign nCsparse_subassign # define x_CLASSES "ngCMatrix",/* 0 */ "ntCMatrix" /* 1 */ # define sparseVECTOR "nsparseVector" # define slot_kind_x -1 # define _INT_x /* withOUT 'x' slot -- CARE! we assume that this is the *ONLY* case w/o x slot */ # undef _n_Csp_ #elif defined (_z_Csp_) // # error "zgC* not yet implemented" # define Csparse_subassign zCsparse_subassign # define x_CLASSES "zgCMatrix",/* 0 */ "ztCMatrix" /* 1 */ # define sparseVECTOR "zsparseVector" # define slot_kind_x 3 # define _CPLX_x # define _has_x_slot_ # undef _z_Csp_ #else # error "no valid _[dilnz]gC_ option" #endif // ------------------------------------------------- #ifdef _DOUBLE_x # define Type_x double # define Type_x_0_init(_VAR_) double _VAR_ = 0. # define Type_x_1_init(_VAR_) double _VAR_ = 1. # define STYP_x REAL # define SXP_x REALSXP #undef _DOUBLE_x #elif defined (_LGL_x) # define Type_x int # define Type_x_0_init(_VAR_) int _VAR_ = 0 # define Type_x_1_init(_VAR_) int _VAR_ = 1 # define STYP_x LOGICAL # define SXP_x LGLSXP #undef _LGL_x #elif defined (_INT_x) # define Type_x int # define Type_x_0_init(_VAR_) int _VAR_ = 0 # define Type_x_1_init(_VAR_) int _VAR_ = 1 # define STYP_x INTEGER # define SXP_x INTSXP #undef _INT_x #elif defined (_CPLX_x) # define Type_x Rcomplex # define Type_x_0_init(_VAR_) Rcomplex _VAR_; _VAR_.r = _VAR_.i = 0. # define Type_x_1_init(_VAR_) Rcomplex _VAR_; _VAR_.r = 1.; _VAR_.i = 0. # define STYP_x COMPLEX # define SXP_x CPLXSXP #else # error "invalid macro logic" #endif /** * Subassignment: x[i,j] <- value * * @param x * @param i_ integer row index 0-origin vector (as returned from R .ind.prep2()) * @param j_ integer column index 0-origin vector * @param value must be a [dln]sparseVector {which is recycled if needed} * * @return a Csparse matrix like x, but with the values replaced */ SEXP Csparse_subassign(SEXP x, SEXP i_, SEXP j_, SEXP value) { // TODO: for other classes consider using a trick as RallocedReal() in ./chm_common.c static const char *valid_cM [] = { // the only ones, for "the moment". FIXME: extend (!) x_CLASSES, ""}, // value: assume a "dsparseVector" for now -- slots: (i, length, x) *valid_spv[] = { sparseVECTOR, // = "the one with the same slot-class" // all others: ctype_v slot_kind "nsparseVector",// 1 -1 "lsparseVector",// 2 1 "isparseVector",// 3 2 "dsparseVector",// 4 0 "zsparseVector",// 5 3 ""}; int ctype_x = R_check_class_etc(x, valid_cM), ctype_v = R_check_class_etc(value, valid_spv); if (ctype_x < 0) error(_("invalid class of 'x' in Csparse_subassign()")); if (ctype_v < 0) error(_("invalid class of 'value' in Csparse_subassign()")); Rboolean value_is_nsp = ctype_v == 1; #ifndef _has_x_slot_ // i.e. "n.CMatrix" : sparseVECTOR == "nsparseVector" if(!value_is_nsp) value_is_nsp = (ctype_v == 0); #endif SEXP islot = GET_SLOT(x, Matrix_iSym), dimslot = GET_SLOT(x, Matrix_DimSym), i_cp = PROTECT(coerceVector(i_, INTSXP)), j_cp = PROTECT(coerceVector(j_, INTSXP)); // for d.CMatrix and l.CMatrix but not n.CMatrix: int *dims = INTEGER(dimslot), ncol = dims[1], /* nrow = dims[0], */ *i = INTEGER(i_cp), len_i = LENGTH(i_cp), *j = INTEGER(j_cp), len_j = LENGTH(j_cp), k, nnz_x = LENGTH(islot); int nnz = nnz_x; #define MATRIX_SUBASSIGN_VERBOSE // Temporary hack for debugging --- remove eventually -- FIXME #ifdef MATRIX_SUBASSIGN_VERBOSE Rboolean verbose = i[0] < 0; if(verbose) { i[0] = -i[0]; REprintf("Csparse_subassign() x[i,j] <- val; x is \"%s\"; value \"%s\" is_nsp=%d\n", valid_cM[ctype_x], valid_spv[ctype_v], (int)value_is_nsp); } #endif SEXP val_i_slot, val_x_slot; val_i_slot = PROTECT(coerceVector(GET_SLOT(value, Matrix_iSym), REALSXP)); double *val_i = REAL(val_i_slot); int nnz_val = LENGTH(GET_SLOT(value, Matrix_iSym)), n_prot = 4; Type_x *val_x = NULL; if(!value_is_nsp) { if(ctype_v) { // matrix 'x' and 'value' are of different kinds switch((enum x_slot_kind) slot_kind_x) { case x_pattern:// "n" case x_logical:// "l" if(ctype_v >= 3) warning(_("x[] <- val: val is coerced to logical for \"%s\" x"), valid_cM[ctype_x]); break; case x_integer: if(ctype_v >= 4) error(_("x[] <- val: val should be integer or logical, is coerced to integer, for \"%s\" x"), valid_cM[ctype_x]); break; case x_double: case x_complex: // coercion should be tried (and fail for complex -> double) below break; default: error(_("programming error in Csparse_subassign() should never happen")); } // otherwise: "coerce" : as(., ) : val_x_slot = PROTECT(coerceVector(GET_SLOT(value, Matrix_xSym), SXP_x)); n_prot++; val_x = STYP_x(val_x_slot); } else { val_x = STYP_x( GET_SLOT(value, Matrix_xSym)); } } int64_t len_val = (int64_t) asReal(GET_SLOT(value, Matrix_lengthSym)); /* llen_i = (int64_t) len_i; */ SEXP ans; /* Instead of simple "duplicate": PROTECT(ans = duplicate(x)) , build up: */ // Assuming that ans will have the same basic Matrix type as x : ans = PROTECT(newObject(valid_cM[ctype_x])); SET_SLOT(ans, Matrix_DimSym, duplicate(dimslot)); SET_SLOT(ans, Matrix_DimNamesSym, duplicate(GET_SLOT(x, Matrix_DimNamesSym))); SET_SLOT(ans, Matrix_pSym, duplicate(GET_SLOT(x, Matrix_pSym))); SEXP r_pslot = GET_SLOT(ans, Matrix_pSym); // and assign the i- and x- slots at the end, as they are potentially modified // not just in content, but also in their *length* int *rp = INTEGER(r_pslot), *ri = R_Calloc(nnz_x, int); // to contain the final i - slot Memcpy(ri, INTEGER(islot), nnz_x); Type_x_0_init(z_ans); Type_x_1_init(one_ans); #ifdef _has_x_slot_ Type_x *rx = R_Calloc(nnz_x, Type_x); // to contain the final x - slot Memcpy(rx, STYP_x(GET_SLOT(x, Matrix_xSym)), nnz_x); #endif // NB: nnz_x : will always be the "current allocated length" of (i, x) slots // -- nnz : the current *used* length; always nnz <= nnz_x int jj, j_val = 0; // in "running" conceptionally through all value[i+ jj*len_i] // values, we are "below"/"before" the (j_val)-th non-zero one. // e.g. if value = (0,0,...,0), have nnz_val == 0, j_val must remain == 0 int64_t ii_val;// == "running" index (i + jj*len_i) % len_val for value[] for(jj = 0, ii_val=0; jj < len_j; jj++) { int j__ = j[jj]; /* int64_t j_l = jj * llen_i; */ R_CheckUserInterrupt(); for(int ii = 0; ii < len_i; ii++, ii_val++) { int i__ = i[ii], p1, p2; if(nnz_val && ii_val >= len_val) { // "recycle" indexing into value[] ii_val -= len_val; // = (ii + jj*len_i) % len_val j_val = 0; } int64_t ii_v1;//= ii_val + 1; Type_x v, /* := value[(ii + j_l) % len_val] = .sparseVector_sub((ii + j_l) % len_val, nnz_val, val_i, val_x, len_val) */ M_ij; int ind; Rboolean have_entry = FALSE; // note that rp[]'s may have *changed* even when 'j' remained! // "FIXME": do this only *when* rp[] has changed p1 = rp[j__], p2 = rp[j__ + 1]; // v := value[(ii + j_l) % len_val] = value[ii_val] v = z_ans; if(j_val < nnz_val) { // maybe find v := non-zero value[ii_val] ii_v1 = ii_val + 1; if(ii_v1 < val_i[j_val]) { // typical case: are still in zero-stretch // v = z_ans (== 0) } else if(ii_v1 == val_i[j_val]) { // have a match v = (value_is_nsp) ? one_ans : val_x[j_val]; j_val++;// from now on, look at the next non-zero entry } else { // ii_v1 > val_i[j_val] REprintf("programming thinko in Csparse_subassign(*, i=%d,j=%d): ii_v=%lld, v@i[j_val=%d]=%g\n", i__,j__, (long long)ii_v1, j_val, val_i[j_val]); j_val++;// from now on, look at the next non-zero entry } } // --------------- M_ij := getM(i., j.) -------------------------------- M_ij = z_ans; // as in ./t_sparseVector.c for(ind = p1; ind < p2; ind++) { if(ri[ind] >= i__) { if(ri[ind] == i__) { #ifdef _has_x_slot_ M_ij = rx[ind]; #else M_ij = 1; #endif #ifdef MATRIX_SUBASSIGN_VERBOSE if(verbose) REprintf("have entry x[%d, %d] = %g\n", i__, j__, # ifdef _CPLX_x (double)M_ij.r); # else (double)M_ij); # endif #endif have_entry = TRUE; } else { // ri[ind] > i__ #ifdef MATRIX_SUBASSIGN_VERBOSE if(verbose) REprintf("@i > i__ = %d --> ind-- = %d\n", i__, ind); #endif } break; } } //-- R: if(getM(i., j.) != (v <- getV(ii, jj))) // if(contents differ) ==> value needs to be changed : #ifdef _CPLX_x if(M_ij.r != v.r || M_ij.i != v.i) { #else if(M_ij != v) { #endif #ifdef MATRIX_SUBASSIGN_VERBOSE if(verbose) REprintf("setting x[%d, %d] <- %g", i__,j__, # ifdef _CPLX_x (double) v.r); # else (double) v); # endif #endif // (otherwise: nothing to do): // setM(i__, j__, v) // ---------------------------------------------------------- #ifndef _has_x_slot_ if(v == z_ans) { // Case I ----- remove x[i, j] = M_ij which we know is *non*-zero // BUT it is more efficient (memory-management!) *NOT* to remove, /// but --- in the case of x slot put a 0 zero there, and only at the very end drop them, // currently using drop0() in R code // we know : have_entry = TRUE ; // ri[ind] == i__; M_ij = rx[ind]; #ifdef MATRIX_SUBASSIGN_VERBOSE if(verbose) REprintf(" rm ind=%d\n", ind); #endif // remove the 'ind'-th element from x@i and x@x : nnz-- ; for(k=ind; k < nnz; k++) { ri[k] = ri[k+1]; #ifdef _has_x_slot_ rx[k] = rx[k+1]; #endif } for(k=j__ + 1; k <= ncol; k++) { rp[k] = rp[k] - 1; } } else #endif if(have_entry) { // Case II ----- replace (non-empty) x[i,j] by v ------- #ifdef MATRIX_SUBASSIGN_VERBOSE if(verbose) REprintf(" repl. ind=%d\n", ind); #endif #ifdef _has_x_slot_ rx[ind] = v; #endif } else { // Case III ----- v != 0 : insert v into "empty" x[i,j] ---- // extend the i and x slot by one entry : --------------------- if(nnz+1 > nnz_x) { // need to reallocate: #ifdef MATRIX_SUBASSIGN_VERBOSE if(verbose) REprintf(" R_Realloc()ing: nnz_x=%d", nnz_x); #endif // do it "only" 1x,..4x at the very most increasing by the // nnz-length of "value": nnz_x += (1 + nnz_val / 4); #ifdef MATRIX_SUBASSIGN_VERBOSE if(verbose) REprintf("(nnz_v=%d) --> %d ", nnz_val, nnz_x); #endif // C doc on realloc() says that the old content is *preserve*d ri = R_Realloc(ri, nnz_x, int); #ifdef _has_x_slot_ rx = R_Realloc(rx, nnz_x, Type_x); #endif } // 3) fill them ... int i1 = ind; #ifdef MATRIX_SUBASSIGN_VERBOSE if(verbose) REprintf(" INSERT p12=(%d,%d) -> ind=%d -> i1 = %d\n", p1,p2, ind, i1); #endif // shift the "upper values" *before* the insertion: for(int l = nnz-1; l >= i1; l--) { ri[l+1] = ri[l]; #ifdef _has_x_slot_ rx[l+1] = rx[l]; #endif } ri[i1] = i__; #ifdef _has_x_slot_ rx[i1] = v; #endif nnz++; // the columns j "right" of the current one : for(k=j__ + 1; k <= ncol; k++) rp[k]++; } } #ifdef MATRIX_SUBASSIGN_VERBOSE else if(verbose) REprintf("M_ij == v = %g\n", # ifdef _CPLX_x (double) v.r); # else (double) v); # endif #endif }// for( ii ) }// for( jj ) if(ctype_x == 1) { // triangularMatrix: copy the 'diag' and 'uplo' slots SET_SLOT(ans, Matrix_uploSym, duplicate(GET_SLOT(x, Matrix_uploSym))); SET_SLOT(ans, Matrix_diagSym, duplicate(GET_SLOT(x, Matrix_diagSym))); } // now assign the i- and x- slots, free memory and return : PROTECT(islot = allocVector(INTSXP, nnz)); Memcpy(INTEGER(islot), ri, nnz); SET_SLOT(ans, Matrix_iSym, islot); UNPROTECT(1); #ifdef _has_x_slot_ PROTECT(islot = allocVector(SXP_x, nnz)); Memcpy(STYP_x(islot), rx, nnz); SET_SLOT(ans, Matrix_xSym, islot); UNPROTECT(1); R_Free(rx); #endif R_Free(ri); UNPROTECT(n_prot); return ans; } #undef Csparse_subassign #undef x_CLASSES #undef sparseVECTOR #undef Type_x #undef STYP_x #undef SXP_x #undef Type_x_0_init #undef Type_x_1_init #undef _has_x_slot_ #undef slot_kind_x #ifdef _CPLX_x # undef _CPLX_x #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/validity.h�������������������������������������������������������������������������������0000644�0001762�0000144�00000004025�14503212600�014275� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_VALIDITY_H #define MATRIX_VALIDITY_H #include char* Dim_validate(SEXP); SEXP R_Dim_validate(SEXP); char* DimNames_validate(SEXP, int[]); SEXP R_DimNames_validate(SEXP, SEXP); SEXP R_DimNames_fixup(SEXP); SEXP Matrix_validate(SEXP); SEXP MatrixFactorization_validate(SEXP); SEXP nMatrix_validate(SEXP); SEXP lMatrix_validate(SEXP); SEXP iMatrix_validate(SEXP); SEXP dMatrix_validate(SEXP); SEXP zMatrix_validate(SEXP); SEXP compMatrix_validate(SEXP); SEXP symmetricMatrix_validate(SEXP); SEXP triangularMatrix_validate(SEXP); SEXP diagonalMatrix_validate(SEXP); SEXP indMatrix_validate(SEXP); SEXP pMatrix_validate(SEXP); SEXP CsparseMatrix_validate(SEXP); SEXP RsparseMatrix_validate(SEXP); SEXP TsparseMatrix_validate(SEXP); SEXP sCMatrix_validate(SEXP); SEXP tCMatrix_validate(SEXP); SEXP sRMatrix_validate(SEXP); SEXP tRMatrix_validate(SEXP); SEXP sTMatrix_validate(SEXP); SEXP tTMatrix_validate(SEXP); SEXP xgCMatrix_validate(SEXP); SEXP xsCMatrix_validate(SEXP); SEXP xtCMatrix_validate(SEXP); SEXP xgRMatrix_validate(SEXP); SEXP xsRMatrix_validate(SEXP); SEXP xtRMatrix_validate(SEXP); SEXP xgTMatrix_validate(SEXP); SEXP xsTMatrix_validate(SEXP); SEXP xtTMatrix_validate(SEXP); SEXP unpackedMatrix_validate(SEXP); SEXP packedMatrix_validate(SEXP); SEXP dpoMatrix_validate(SEXP); SEXP dppMatrix_validate(SEXP); SEXP corMatrix_validate(SEXP); SEXP pcorMatrix_validate(SEXP); SEXP sparseVector_validate(SEXP); SEXP lsparseVector_validate(SEXP); SEXP isparseVector_validate(SEXP); SEXP dsparseVector_validate(SEXP); SEXP zsparseVector_validate(SEXP); SEXP denseLU_validate(SEXP); SEXP sparseLU_validate(SEXP); SEXP sparseQR_validate(SEXP); SEXP BunchKaufman_validate(SEXP); SEXP pBunchKaufman_validate(SEXP); SEXP Cholesky_validate(SEXP); SEXP pCholesky_validate(SEXP); SEXP CHMfactor_validate(SEXP); SEXP CHMsimpl_validate(SEXP); SEXP CHMsuper_validate(SEXP); SEXP dCHMsimpl_validate(SEXP); SEXP dCHMsuper_validate(SEXP); SEXP Schur_validate(SEXP); void validObject(SEXP, const char *); #endif /* MATRIX_VALIDITY_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/subscript.h������������������������������������������������������������������������������0000644�0001762�0000144�00000000354�14503212600�014467� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_SUBSCRIPT_H #define MATRIX_SUBSCRIPT_H #include SEXP R_subscript_1ary (SEXP, SEXP); SEXP R_subscript_1ary_mat(SEXP, SEXP); SEXP R_subscript_2ary (SEXP, SEXP, SEXP); #endif /* MATRIX_SUBSCRIPT_H */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/coerce.h���������������������������������������������������������������������������������0000644�0001762�0000144�00000004605�14512156155�013730� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_COERCE_H #define MATRIX_COERCE_H #include SEXP vector_as_dense(SEXP, const char *, char, char, int, int, int, SEXP); SEXP R_vector_as_dense(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); SEXP matrix_as_dense(SEXP, const char *, char, char, int, int); SEXP R_matrix_as_dense(SEXP, SEXP, SEXP, SEXP, SEXP); SEXP sparse_as_dense(SEXP, const char *, int); SEXP R_sparse_as_dense(SEXP, SEXP); SEXP diagonal_as_dense(SEXP, const char *, char, char, int, char); SEXP R_diagonal_as_dense(SEXP, SEXP, SEXP, SEXP, SEXP); SEXP index_as_dense(SEXP, const char *, char); SEXP R_index_as_dense(SEXP, SEXP); SEXP vector_as_sparse(SEXP, const char *, char, char, int, int, int, SEXP); SEXP R_vector_as_sparse(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); SEXP matrix_as_sparse(SEXP, const char *, char, char, int); SEXP R_matrix_as_sparse(SEXP, SEXP, SEXP, SEXP, SEXP); SEXP dense_as_sparse(SEXP, const char *, char); SEXP R_dense_as_sparse(SEXP, SEXP); SEXP diagonal_as_sparse(SEXP, const char *, char, char, char, char); SEXP R_diagonal_as_sparse(SEXP, SEXP, SEXP, SEXP, SEXP); SEXP index_as_sparse(SEXP, const char *, char, char); SEXP R_index_as_sparse(SEXP, SEXP, SEXP); SEXP dense_as_kind(SEXP, const char *, char, int); SEXP R_dense_as_kind(SEXP, SEXP); SEXP sparse_as_kind(SEXP, const char *, char); SEXP R_sparse_as_kind(SEXP, SEXP); SEXP diagonal_as_kind(SEXP, const char *, char); SEXP R_diagonal_as_kind(SEXP, SEXP); SEXP index_as_kind(SEXP, const char *, char); SEXP R_index_as_kind(SEXP, SEXP); SEXP dense_as_general(SEXP, const char *, int); SEXP R_dense_as_general(SEXP); SEXP sparse_as_general(SEXP, const char *); SEXP R_sparse_as_general(SEXP); SEXP dense_as_unpacked(SEXP, const char *); SEXP R_dense_as_unpacked(SEXP); SEXP dense_as_packed(SEXP, const char *, char, char); SEXP R_dense_as_packed(SEXP, SEXP, SEXP); SEXP sparse_as_Csparse(SEXP, const char *); SEXP R_sparse_as_Csparse(SEXP); SEXP sparse_as_Rsparse(SEXP, const char *); SEXP R_sparse_as_Rsparse(SEXP); SEXP sparse_as_Tsparse(SEXP, const char *); SEXP R_sparse_as_Tsparse(SEXP); SEXP R_Matrix_as_vector(SEXP); SEXP R_Matrix_as_matrix(SEXP); SEXP R_Matrix_as_unpacked(SEXP); SEXP R_Matrix_as_packed(SEXP); SEXP R_Matrix_as_Csparse(SEXP); SEXP R_Matrix_as_Rsparse(SEXP); SEXP R_Matrix_as_Tsparse(SEXP); SEXP R_Matrix_as_kind(SEXP, SEXP, SEXP); SEXP R_Matrix_as_general(SEXP, SEXP); #endif /* MATRIX_COERCE_H */ ���������������������������������������������������������������������������������������������������������������������������Matrix/src/idz.c������������������������������������������������������������������������������������0000644�0001762�0000144�00000030133�14503225712�013240� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "Mdefines.h" #include "idz.h" #define IDZ \ TEMPLATE(i, int, 0 , 1 ) \ TEMPLATE(d, double, 0.0, 1.0) \ TEMPLATE(z, Rcomplex, Matrix_zzero, Matrix_zone) #define TEMPLATE(_PREFIX_, _CTYPE_, _ZERO_, _ONE_) \ static void _PREFIX_ ## \ swap(int n, _CTYPE_ *x, int incx, _CTYPE_ *y, int incy) \ { \ _CTYPE_ tmp; \ while (n--) { \ tmp = *x; \ *x = *y; \ *y = tmp; \ x += incx; \ y += incy; \ } \ return; \ } IDZ #undef TEMPLATE #define TEMPLATE(_PREFIX_, _CTYPE_, _ZERO_, _ONE_) \ static void _PREFIX_ ## \ syswapr(char uplo, int n, _CTYPE_ *x, int k0, int k1) \ { \ _CTYPE_ *x0 = x + (R_xlen_t) k0 * n, *x1 = x + (R_xlen_t) k1 * n, \ tmp; \ if (uplo == 'U') { \ _PREFIX_ ## swap(k0, x0, 1, x1, 1); \ tmp = x0[k0]; \ x0[k0] = x1[k1]; \ x1[k1] = tmp; \ _PREFIX_ ## swap(k1 - k0 - 1, x0 + k0 + n, n, x1 + k0 + 1, 1); \ _PREFIX_ ## swap(n - k1 - 1, x1 + k0 + n, n, x1 + k1 + n, n); \ } else { \ _PREFIX_ ## swap(k0, x + k0, n, x + k1, n); \ tmp = x0[k0]; \ x0[k0] = x1[k1]; \ x1[k1] = tmp; \ _PREFIX_ ## swap(k1 - k0 - 1, x0 + k0 + 1, 1, x0 + k1 + n, n); \ _PREFIX_ ## swap(n - k1 - 1, x0 + k1 + 1, 1, x1 + k1 + 1, 1); \ } \ return; \ } IDZ #undef TEMPLATE #define TEMPLATE(_PREFIX_, _CTYPE_, _ZERO_, _ONE_) \ void _PREFIX_ ## \ rowperm2(_CTYPE_ *x, int m, int n, int *p, int off, int invert) \ { \ int i, k0, k1; \ for (i = 0; i < m; ++i) \ p[i] = -(p[i] - off + 1); \ if (!invert) { \ for (i = 0; i < m; ++i) { \ if (p[i] > 0) \ continue; \ k0 = i; \ p[k0] = -p[k0]; \ k1 = p[k0] - 1; \ while (p[k1] < 0) { \ _PREFIX_ ## swap(n, x + k0, m, x + k1, m); \ k0 = k1; \ p[k0] = -p[k0]; \ k1 = p[k0] - 1; \ } \ } \ } else { \ for (i = 0; i < m; ++i) { \ if (p[i] > 0) \ continue; \ k0 = i; \ p[k0] = -p[k0]; \ k1 = p[k0] - 1; \ while (k1 != k0) { \ _PREFIX_ ## swap(n, x + k0, m, x + k1, m); \ p[k1] = -p[k1]; \ k1 = p[k1] - 1; \ } \ } \ } \ for (i = 0; i < m; ++i) \ p[i] = p[i] + off - 1; \ return; \ } IDZ #undef TEMPLATE #define TEMPLATE(_PREFIX_, _CTYPE_, _ZERO_, _ONE_) \ void _PREFIX_ ## \ symperm2(_CTYPE_ *x, int n, char uplo, int *p, int off, int invert) \ { \ int i, k0, k1; \ for (i = 0; i < n; ++i) \ p[i] = -(p[i] - off + 1); \ if (!invert) { \ for (i = 0; i < n; ++i) { \ if (p[i] > 0) \ continue; \ k0 = i; \ p[k0] = -p[k0]; \ k1 = p[k0] - 1; \ while (p[k1] < 0) { \ if (k0 < k1) \ _PREFIX_ ## syswapr(uplo, n, x, k0, k1); \ else \ _PREFIX_ ## syswapr(uplo, n, x, k1, k0); \ k0 = k1; \ p[k0] = -p[k0]; \ k1 = p[k0] - 1; \ } \ } \ } else { \ for (i = 0; i < n; ++i) { \ if (p[i] > 0) \ continue; \ k0 = i; \ p[k0] = -p[k0]; \ k1 = p[k0] - 1; \ while (k1 != k0) { \ if (k0 < k1) \ _PREFIX_ ## syswapr(uplo, n, x, k0, k1); \ else \ _PREFIX_ ## syswapr(uplo, n, x, k1, k0); \ p[k1] = -p[k1]; \ k1 = p[k1] - 1; \ } \ } \ } \ for (i = 0; i < n; ++i) \ p[i] = p[i] + off - 1; \ return; \ } IDZ #undef TEMPLATE #define TEMPLATE(_PREFIX_, _CTYPE_, _ZERO_, _ONE_) \ void _PREFIX_ ## \ pack2(_CTYPE_ *dest, const _CTYPE_ *src, int n, char uplo, char diag) \ { \ int i, j; \ R_xlen_t dpos = 0, spos = 0; \ if (uplo == 'U') { \ for (j = 0; j < n; spos += n-(++j)) \ for (i = 0; i <= j; ++i) \ dest[dpos++] = src[spos++]; \ if (diag != 'N') { \ dpos = 0; \ for (j = 0; j < n; dpos += (++j)+1) \ dest[dpos] = _ONE_; \ } \ } else { \ for (j = 0; j < n; spos += (++j)) \ for (i = j; i < n; ++i) \ dest[dpos++] = src[spos++]; \ if (diag != 'N') { \ dpos = 0; \ for (j = 0; j < n; dpos += n-(j++)) \ dest[dpos] = _ONE_; \ } \ } \ return; \ } IDZ #undef TEMPLATE #define TEMPLATE(_PREFIX_, _CTYPE_, _ZERO_, _ONE_) \ void _PREFIX_ ## \ unpack1(_CTYPE_ *dest, const _CTYPE_ *src, int n, char uplo, char diag) \ { \ int i, j; \ R_xlen_t dpos = 0, spos = 0; \ if (uplo == 'U') { \ for (j = 0; j < n; dpos += n-(++j)) \ for (i = 0; i <= j; ++i) \ dest[dpos++] = src[spos++]; \ } else { \ for (j = 0; j < n; dpos += (++j)) \ for (i = j; i < n; ++i) \ dest[dpos++] = src[spos++]; \ } \ if (diag != 'N') { \ dpos = 0; \ R_xlen_t n1a = (R_xlen_t) n + 1; \ for (j = 0; j < n; ++j, dpos += n1a) \ dest[dpos] = _ONE_; \ } \ return; \ } IDZ #undef TEMPLATE #define TEMPLATE(_PREFIX_, _CTYPE_, _ZERO_, _ONE_) \ void _PREFIX_ ## \ transpose2(_CTYPE_ *dest, const _CTYPE_ *src, int m, int n) \ { \ R_xlen_t mn1s = (R_xlen_t) m * n - 1; \ int i, j; \ for (j = 0; j < m; ++j, src -= mn1s) \ for (i = 0; i < n; ++i, src += m) \ *(dest++) = *src; \ return; \ } IDZ #undef TEMPLATE #define TEMPLATE(_PREFIX_, _CTYPE_, _ZERO_, _ONE_) \ void _PREFIX_ ## \ transpose1(_CTYPE_ *dest, const _CTYPE_ *src, int n, char uplo) \ { \ int i, j; \ if (uplo == 'U') { \ for (j = 0; j < n; ++j) \ for (i = j; i < n; ++i) \ *(dest++) = *(src + PACKED_AR21_UP(j, i)); \ } else { \ R_xlen_t n2 = (R_xlen_t) n * 2; \ for (j = 0; j < n; ++j) \ for (i = 0; i <= j; ++i) \ *(dest++) = *(src + PACKED_AR21_LO(j, i, n2)); \ } \ return; \ } IDZ #undef TEMPLATE #define ASSIGN_JJ_i(_X_) #define ASSIGN_JJ_d(_X_) #define ASSIGN_JJ_z(_X_) \ _X_.i = 0.0 #define ASSIGN_JI_i(_X_, _Y_) \ _X_ = _Y_ #define ASSIGN_JI_d(_X_, _Y_) \ _X_ = _Y_ #define ASSIGN_JI_z(_X_, _Y_) \ do { \ _X_.r = _Y_.r; \ _X_.i = -_Y_.i; \ } while (0) #define TEMPLATE(_PREFIX_, _CTYPE_, _ZERO_, _ONE_) \ void _PREFIX_ ## \ syforce2(_CTYPE_ *x, int n, char uplo) \ { \ _CTYPE_ *y = x; \ int i, j; \ if (uplo == 'U') { \ for (j = 0; j < n; ++j) { \ ASSIGN_JJ_ ## _PREFIX_((*x)); \ x += 1; \ y += n; \ for (i = j + 1; i < n; ++i) { \ ASSIGN_JI_ ## _PREFIX_((*x), (*y)); \ x += 1; \ y += n; \ } \ x = y = x + j + 1; \ } \ } else { \ for (j = 0; j < n; ++j) { \ ASSIGN_JJ_ ## _PREFIX_((*y)); \ x += 1; \ y += n; \ for (i = j + 1; i < n; ++i) { \ ASSIGN_JI_ ## _PREFIX_((*y), (*x)); \ x += 1; \ y += n; \ } \ x = y = x + j + 1; \ } \ } \ return; \ } IDZ #undef TEMPLATE #undef ASSIGN_JJ_i #undef ASSIGN_JJ_d #undef ASSIGN_JJ_z #undef ASSIGN_JI_i #undef ASSIGN_JI_d #undef ASSIGN_JI_z #define TEMPLATE(_PREFIX_, _CTYPE_, _ZERO_, _ONE_) \ void _PREFIX_ ## \ trforce2(_CTYPE_ *x, int m, int n, char uplo, char diag) \ { \ _CTYPE_ *y = x; \ int i, j, r = (m < n) ? m : n; \ if (uplo == 'U') { \ for (j = 0; j < r; ++j) { \ for (i = j + 1; i < m; ++i) \ *(++x) = _ZERO_; \ x += j + 2; \ } \ } else { \ for (j = 0; j < r; ++j) { \ for (i = 0; i < j; ++i) \ *(x++) = _ZERO_; \ x += m - j; \ } \ for (j = r; j < n; ++j) \ for (i = 0; i < m; ++i) \ *(x++) = _ZERO_; \ } \ if (diag != 'N') { \ R_xlen_t m1a = (R_xlen_t) m + 1; \ for (j = 0; j < r; ++j) { \ *y = _ONE_; \ y += m1a; \ } \ } \ return; \ } IDZ #undef TEMPLATE #define TEMPLATE(_PREFIX_, _CTYPE_, _ZERO_, _ONE_) \ void _PREFIX_ ## \ band2(_CTYPE_ *x, int m, int n, int a, int b, char diag) \ { \ if (m == 0 || n == 0) \ return; \ if (a > b || a >= n || b <= -m) { \ Matrix_memset(x, 0, (R_xlen_t) m * n, sizeof(_CTYPE_)); \ return; \ } \ if (a <= -m) a = 1-m; \ if (b >= n) b = n-1; \ \ int i, j, i0, i1, \ j0 = (a < 0) ? 0 : a, \ j1 = (b < n-m) ? m+b : n; \ \ if (j0 > 0) { \ R_xlen_t dx = (R_xlen_t) m * j0; \ Matrix_memset(x, 0, dx, sizeof(_CTYPE_)); \ x += dx; \ } \ for (j = j0; j < j1; ++j, x += m) { \ i0 = j - b; \ i1 = j - a + 1; \ for (i = 0; i < i0; ++i) \ *(x + i) = _ZERO_; \ for (i = i1; i < m; ++i) \ *(x + i) = _ZERO_; \ } \ if (j1 < n) \ Matrix_memset(x, 0, (R_xlen_t) m * (n - j1), sizeof(_CTYPE_)); \ if (diag != 'N' && a <= 0 && b >= 0) { \ x -= m * (R_xlen_t) j; \ R_xlen_t m1a = (R_xlen_t) m + 1; \ for (j = 0; j < n; ++j, x += m1a) \ *x = _ONE_; \ } \ return; \ } IDZ #undef TEMPLATE #define TEMPLATE(_PREFIX_, _CTYPE_, _ZERO_, _ONE_) \ void _PREFIX_ ## \ band1(_CTYPE_ *x, int n, int a, int b, char uplo, char diag) \ { \ if (n == 0) \ return; \ if (a > b || a >= n || b <= -n) { \ Matrix_memset(x, 0, PACKED_LENGTH(n), sizeof(_CTYPE_)); \ return; \ } \ if (uplo == 'U') { \ if (a < 0) a = 0; \ if (b >= n) b = n-1; \ } else { \ if (b > 0) b = 0; \ if (a <= -n) a = 1-n; \ } \ \ int i, j, i0, i1, \ j0 = (a < 0) ? 0 : a, \ j1 = (b < 0) ? n+b : n; \ \ if (uplo == 'U') { \ if (j0 > 0) { \ R_xlen_t dx; \ Matrix_memset(x, 0, dx = PACKED_LENGTH(j0), \ sizeof(_CTYPE_)); \ x += dx; \ } \ for (j = j0; j < j1; x += (++j)) { \ i0 = j - b; \ i1 = j - a + 1; \ for (i = 0; i < i0; ++i) \ *(x + i) = _ZERO_; \ for (i = i1; i <= j; ++i) \ *(x + i) = _ZERO_; \ } \ if (j1 < n) \ Matrix_memset(x, 0, PACKED_LENGTH(n) - PACKED_LENGTH(j1), \ sizeof(_CTYPE_)); \ if (diag != 'N' && a == 0) { \ x -= PACKED_LENGTH(j); \ for (j = 0; j < n; x += (++j)+1) \ *x = _ONE_; \ } \ } else { \ if (j0 > 0) { \ R_xlen_t dx = PACKED_LENGTH(n) - PACKED_LENGTH(j0); \ Matrix_memset(x, 0, dx, sizeof(_CTYPE_)); \ x += dx; \ } \ for (j = j0; j < j1; x += n-(j++)) { \ i0 = j - b; \ i1 = j - a + 1; \ for (i = j; i < i0; ++i) \ *(x + i - j) = _ZERO_; \ for (i = i1; i < n; ++i) \ *(x + i - j) = _ZERO_; \ } \ if (j1 < n) \ Matrix_memset(x, 0, PACKED_LENGTH(n - j1), \ sizeof(_CTYPE_)); \ if (diag != 'N' && b == 0) { \ x -= PACKED_LENGTH(n) - PACKED_LENGTH(j); \ for (j = 0; j < n; x += n-(j++)) \ *x = _ONE_; \ } \ } \ return; \ } IDZ #undef TEMPLATE #define TEMPLATE(_PREFIX_, _CTYPE_, _ZERO_, _ONE_) \ void _PREFIX_ ## \ dcpy2(_CTYPE_ *dest, const _CTYPE_ *src, int n, R_xlen_t length, \ char uplo, char diag) \ { \ int j; \ R_xlen_t n1a = (R_xlen_t) n + 1; \ if (diag != 'N') { \ for (j = 0; j < n; ++j, dest += n1a) \ *dest = _ONE_; \ } else if (length == n) { \ /* copying from diagonalMatrix */ \ for (j = 0; j < n; ++j, dest += n1a, ++src) \ *dest = *src; \ } else if (length == (n * n1a) / 2) { \ /* copying from packedMatrix */ \ if (uplo == 'U') { \ for (j = 0; j < n; dest += n1a, src += (++j)+1) \ *dest = *src; \ } else { \ for (j = 0; j < n; dest += n1a, src += n-(j++)) \ *dest = *src; \ } \ } else if (length == (R_xlen_t) n * n) { \ /* copying from square unpackedMatrix */ \ for (j = 0; j < n; ++j, dest += n1a, src += n1a) \ *dest = *src; \ } else { \ error(_("incompatible '%s' and '%s' in '%s'"), \ "n", "length", __func__); \ } \ return; \ } IDZ #undef TEMPLATE #define TEMPLATE(_PREFIX_, _CTYPE_, _ZERO_, _ONE_) \ void _PREFIX_ ## \ dcpy1(_CTYPE_ *dest, const _CTYPE_ *src, int n, R_xlen_t length, \ char uplo_dest, char uplo_src, char diag) \ { \ int j; \ if (diag != 'N') { \ if (uplo_dest == 'U') { \ for (j = 0; j < n; dest += (++j)+1) \ *dest = _ONE_; \ } else { \ for (j = 0; j < n; dest += n-(j++)) \ *dest = _ONE_; \ } \ } else if (length == n) { \ /* copying from diagonalMatrix */ \ if (uplo_dest == 'U') { \ for (j = 0; j < n; dest += (++j)+1, ++src) \ *dest = *src; \ } else { \ for (j = 0; j < n; dest += n-(j++), ++src) \ *dest = *src; \ } \ } else if (length == PACKED_LENGTH(n)) { \ /* copying from packedMatrix */ \ if (uplo_dest == 'U') { \ if (uplo_src == 'U') { \ for (j = 0; j < n; src += (++j)+1, dest += j+1) \ *dest = *src; \ } else { \ for (j = 0; j < n; src += n-j, dest += (++j)+1) \ *dest = *src; \ } \ } else { \ if (uplo_src == 'U') { \ for (j = 0; j < n; dest += n-(j++), src += j+1) \ *dest = *src; \ } else { \ for (j = 0; j < n; dest += n-j, src += n-(j++)) \ *dest = *src; \ } \ } \ } else if (length == (R_xlen_t) n * n) { \ /* copying from square unpackedMatrix */ \ R_xlen_t n1a = (R_xlen_t) n + 1; \ if (uplo_dest == 'U') { \ for (j = 0; j < n; dest += (++j)+1, src += n1a) \ *dest = *src; \ } else { \ for (j = 0; j < n; dest += n-(j++), src += n1a) \ *dest = *src; \ } \ } else { \ error(_("incompatible '%s' and '%s' in '%s'"), \ "n", "length", __func__); \ } \ return; \ } IDZ #undef TEMPLATE #undef IDZ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/determinant.c����������������������������������������������������������������������������0000644�0001762�0000144�00000023257�14511304746�015001� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include /* math.h, logspace_add, logspace_sub */ #include "Mdefines.h" #include "cholmod-etc.h" #include "determinant.h" static SEXP mkDet(double modulus, int logarithm, int sign) { SEXP nms = PROTECT(allocVector(STRSXP, 2)), cl = PROTECT(mkString("det")), det = PROTECT(allocVector(VECSXP, 2)), det0 = PROTECT(ScalarReal((logarithm) ? modulus : exp(modulus))), det1 = PROTECT(ScalarInteger(sign)), det0a = PROTECT(ScalarLogical(logarithm)); SET_STRING_ELT(nms, 0, mkChar("modulus")); SET_STRING_ELT(nms, 1, mkChar("sign")); setAttrib(det, R_NamesSymbol, nms); setAttrib(det, R_ClassSymbol, cl); setAttrib(det0, install("logarithm"), det0a); SET_VECTOR_ELT(det, 0, det0); SET_VECTOR_ELT(det, 1, det1); UNPROTECT(6); return det; } SEXP denseLU_determinant(SEXP obj, SEXP logarithm) { #define DETERMINANT_START \ SEXP dim = GET_SLOT(obj, Matrix_DimSym); \ int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; \ if (m != n) \ error(_("determinant of non-square matrix is undefined")); \ int givelog = asLogical(logarithm) != 0; \ double modulus = 0.0; /* result for n == 0 */ DETERMINANT_START; SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)); int sign = (TYPEOF(x) == CPLXSXP) ? NA_INTEGER : 1; if (n > 0) { int j; R_xlen_t n1a = (R_xlen_t) n + 1; if (TYPEOF(x) == CPLXSXP) { Rcomplex *px = COMPLEX(x); for (j = 0; j < n; ++j) { modulus += log(hypot((*px).r, (*px).i)); px += n1a; } } else { SEXP pivot = GET_SLOT(obj, Matrix_permSym); int *ppivot = INTEGER(pivot); double *px = REAL(x); for (j = 0; j < n; ++j) { if (ISNAN(*px) || *px >= 0.0) { modulus += log(*px); if (*ppivot != j + 1) sign = -sign; } else { modulus += log(-(*px)); if (*ppivot == j + 1) sign = -sign; } px += n1a; ppivot += 1; } } } UNPROTECT(1); /* x */ return mkDet(modulus, givelog, sign); } SEXP BunchKaufman_determinant(SEXP obj, SEXP logarithm) { DETERMINANT_START; SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)); int sign = (TYPEOF(x) == CPLXSXP) ? NA_INTEGER : 1; if (n > 0) { SEXP pivot = GET_SLOT(obj, Matrix_permSym); int *ppivot = INTEGER(pivot); SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = *CHAR(STRING_ELT(uplo, 0)); int j = 0, unpacked = (Matrix_int_fast64_t) n * n <= R_XLEN_T_MAX && XLENGTH(x) == (R_xlen_t) m * m; R_xlen_t n1a = (R_xlen_t) n + 1; if (TYPEOF(x) == CPLXSXP) { Rcomplex *px = COMPLEX(x), a, b, c; while (j < n) { if (ppivot[j] > 0) { modulus += log(hypot((*px).r, (*px).i)); px += (unpacked) ? n1a : ((ul == 'U') ? j + 2 : n - j); j += 1; } else { a = *px; if (ul == 'U') { px += (unpacked) ? n1a : j + 2; b = *px; c = *(px - 1); px += (unpacked) ? n1a : j + 3; } else { c = *(px + 1); px += (unpacked) ? n1a : n - j; b = *px; px += (unpacked) ? n1a : n - j - 1; } modulus += log(hypot(a.r * b.r - a.i * b.i - c.r * c.r + c.i * c.i, a.r * b.i + a.i * b.r - 2.0 * c.r * c.i)); j += 2; } } } else { double *px = REAL(x), a, b, c, logab, logcc; while (j < n) { if (ppivot[j] > 0) { if (*px >= 0.0) modulus += log(*px); else { modulus += log(-(*px)); sign = -sign; } px += (unpacked) ? n1a : ((ul == 'U') ? j + 2 : n - j); j += 1; } else { a = *px; if (ul == 'U') { px += (unpacked) ? n1a : j + 2; b = *px; c = *(px - 1); px += (unpacked) ? n1a : j + 3; } else { c = *(px + 1); px += (unpacked) ? n1a : n - j; b = *px; px += (unpacked) ? n1a : n - j - 1; } logab = log(fabs(a)) + log(fabs(b)); logcc = 2.0 * log(fabs(c)); if ((a < 0.0) != (b < 0.0)) { /* det = ab - cc = -(abs(ab) + cc) < 0 */ modulus += logspace_add(logab, logcc); sign = -sign; } else if (logab < logcc) { /* det = ab - cc = -(cc - ab) < 0 */ modulus += logspace_sub(logcc, logab); sign = -sign; } else { /* det = ab - cc > 0 */ modulus += logspace_sub(logab, logcc); } j += 2; } } } } UNPROTECT(1); /* x */ return mkDet(modulus, givelog, sign); } SEXP Cholesky_determinant(SEXP obj, SEXP logarithm) { DETERMINANT_START; SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)); int sign = (TYPEOF(x) == CPLXSXP) ? NA_INTEGER : 1; if (n > 0) { SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = *CHAR(STRING_ELT(uplo, 0)); int j, unpacked = (Matrix_int_fast64_t) n * n <= R_XLEN_T_MAX && XLENGTH(x) == (R_xlen_t) m * m; R_xlen_t n1a = (R_xlen_t) n + 1; if (TYPEOF(x) == CPLXSXP) { Rcomplex *px = COMPLEX(x); for (j = 0; j < n; ++j) { modulus += log(hypot((*px).r, (*px).i)); px += (unpacked) ? n1a : ((ul == 'U') ? j + 2 : n - j); } } else { double *px = REAL(x); for (j = 0; j < n; ++j) { if (ISNAN(*px) || *px >= 0.0) modulus += log(*px); else { modulus += log(-(*px)); sign = -sign; } px += (unpacked) ? n1a : ((ul == 'U') ? j + 2 : n - j); } } modulus *= 2.0; } UNPROTECT(1); /* x */ return mkDet(modulus, givelog, sign); } SEXP sparseLU_determinant(SEXP obj, SEXP logarithm) { DETERMINANT_START; SEXP U = PROTECT(GET_SLOT(obj, Matrix_USym)), x = PROTECT(GET_SLOT(U, Matrix_xSym)); int sign = (TYPEOF(x) == CPLXSXP) ? NA_INTEGER : 1; if (n > 0) { SEXP p = PROTECT(GET_SLOT(U, Matrix_pSym)), i = PROTECT(GET_SLOT(U, Matrix_iSym)); int *pp = INTEGER(p) + 1, *pi = INTEGER(i), j, k = 0, kend; if (TYPEOF(x) == CPLXSXP) { Rcomplex *px = COMPLEX(x); for (j = 0; j < n; ++j) { kend = pp[j]; if (k < kend && pi[kend - 1] == j) modulus += log(hypot(px[kend - 1].r, px[kend - 1].i)); else { UNPROTECT(4); /* i, p, x, U */ return mkDet(R_NegInf, givelog, 1); } k = kend; } } else { double *px = REAL(x); for (j = 0; j < n; ++j) { kend = pp[j]; if (k < kend && pi[kend - 1] == j) { if (ISNAN(px[kend - 1]) || px[kend - 1] >= 0.0) modulus += log(px[kend - 1]); else { modulus += log(-px[kend - 1]); sign = -sign; } } else { UNPROTECT(4); /* i, p, x, U */ return mkDet(R_NegInf, givelog, 1); } k = kend; } /* defined in ./perm.c : */ int signPerm(const int *, int, int); p = GET_SLOT(obj, Matrix_pSym); if (signPerm(INTEGER(p), LENGTH(p), 0) < 0) sign = -sign; p = GET_SLOT(obj, Matrix_qSym); if (signPerm(INTEGER(p), LENGTH(p), 0) < 0) sign = -sign; } UNPROTECT(2); /* i, p */ } UNPROTECT(2); /* x, U */ return mkDet(modulus, givelog, sign); } SEXP sparseQR_determinant(SEXP obj, SEXP logarithm) { DETERMINANT_START; SEXP R = PROTECT(GET_SLOT(obj, Matrix_RSym)), x = PROTECT(GET_SLOT(R, Matrix_xSym)); int sign = (TYPEOF(x) == CPLXSXP) ? NA_INTEGER : 1; dim = GET_SLOT(R, Matrix_DimSym); if (INTEGER(dim)[0] > n) error(_("%s(<%s>) does not support structurally rank deficient case"), "determinant", "sparseQR"); if (n > 0) { SEXP p = PROTECT(GET_SLOT(R, Matrix_pSym)), i = PROTECT(GET_SLOT(R, Matrix_iSym)); int *pp = INTEGER(p) + 1, *pi = INTEGER(i), j, k = 0, kend; if (TYPEOF(x) == CPLXSXP) { Rcomplex *px = COMPLEX(x); for (j = 0; j < n; ++j) { kend = pp[j]; if (k < kend && pi[kend - 1] == j) modulus += log(hypot(px[kend - 1].r, px[kend - 1].i)); else { UNPROTECT(4); /* i, p, x, U */ return mkDet(R_NegInf, givelog, 1); } k = kend; } } else { double *px = REAL(x); for (j = 0; j < n; ++j) { kend = pp[j]; if (k < kend && pi[kend - 1] == j) { if (ISNAN(px[kend - 1]) || px[kend - 1] >= 0.0) modulus += log(px[kend - 1]); else { modulus += log(-px[kend - 1]); sign = -sign; } } else { UNPROTECT(4); /* i, p, x, R */ return mkDet(R_NegInf, givelog, 1); } k = kend; } /* defined in ./perm.c : */ int signPerm(const int *, int, int); p = GET_SLOT(obj, Matrix_pSym); if (signPerm(INTEGER(p), LENGTH(p), 0) < 0) sign = -sign; p = GET_SLOT(obj, Matrix_qSym); if (signPerm(INTEGER(p), LENGTH(p), 0) < 0) sign = -sign; if (n % 2) sign = -sign; } UNPROTECT(2); /* i, p */ } UNPROTECT(2); /* x, R */ return mkDet(modulus, givelog, sign); } SEXP CHMfactor_determinant(SEXP obj, SEXP logarithm, SEXP sqrt) { DETERMINANT_START; cholmod_factor *L = M2CHF(obj, 1); int sign = (L->xtype == CHOLMOD_COMPLEX) ? NA_INTEGER : 1; if (n > 0) { int j, sqrt_ = asLogical(sqrt); if (L->is_super) { int k, nc, nsuper = (int) L->nsuper, *psuper = (int *) L->super, *ppi = (int *) L->pi, *ppx = (int *) L->px; R_xlen_t nr1a; if (L->xtype == CHOLMOD_COMPLEX) { Rcomplex *px = (Rcomplex *) L->x, *px_; for (k = 0; k < nsuper; ++k) { nc = psuper[k + 1] - psuper[k]; nr1a = (R_xlen_t) (ppi[k + 1] - ppi[k]) + 1; px_ = px + ppx[k]; for (j = 0; j < nc; ++j) { modulus += log(hypot((*px_).r, (*px_).i)); px_ += nr1a; } } } else { double *px = (double *) L->x, *px_; for (k = 0; k < nsuper; ++k) { nc = psuper[k + 1] - psuper[k]; nr1a = (R_xlen_t) (ppi[k + 1] - ppi[k]) + 1; px_ = px + ppx[k]; for (j = 0; j < nc; ++j) { modulus += log(*px_); px_ += nr1a; } } } modulus *= 2.0; } else { int *pp = (int *) L->p; if (L->xtype == CHOLMOD_COMPLEX) { Rcomplex *px = (Rcomplex *) L->x; for (j = 0; j < n; ++j) modulus += log(hypot(px[pp[j]].r, px[pp[j]].i)); if (L->is_ll) modulus *= 2.0; } else { double *px = (double *) L->x; if (L->is_ll) { for (j = 0; j < n; ++j) modulus += log(px[pp[j]]); modulus *= 2.0; } else { for (j = 0; j < n; ++j) { if (ISNAN(px[pp[j]]) || px[pp[j]] >= 0.0) modulus += log(px[pp[j]]); else { if (sqrt_) return mkDet(R_NaN, givelog, 1); modulus += log(-px[pp[j]]); sign = -sign; } } } } } if (sqrt_) modulus *= 0.5; } return mkDet(modulus, givelog, sign); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/COLAMD/����������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14547723665�013267� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/COLAMD/Include/��������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14547723665�014652� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/COLAMD/Include/colamd.h������������������������������������������������������������������0000644�0001762�0000144�00000020251�13652535054�016247� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === colamd/symamd prototypes and definitions ============================= */ /* ========================================================================== */ /* COLAMD / SYMAMD include file You must include this file (colamd.h) in any routine that uses colamd, symamd, or the related macros and definitions. Authors: The authors of the code itself are Stefan I. Larimore and Timothy A. Davis (DrTimothyAldenDavis@gmail.com). The algorithm was developed in collaboration with John Gilbert, Xerox PARC, and Esmond Ng, Oak Ridge National Laboratory. Acknowledgements: This work was supported by the National Science Foundation, under grants DMS-9504974 and DMS-9803599. Notice: Copyright (c) 1998-2007, Timothy A. Davis, All Rights Reserved. See COLAMD/Doc/License.txt for the license. Availability: The colamd/symamd library is available at http://www.suitesparse.com This file is required by the colamd.c, colamdmex.c, and symamdmex.c files, and by any C code that calls the routines whose prototypes are listed below, or that uses the colamd/symamd definitions listed below. */ #ifndef COLAMD_H #define COLAMD_H /* make it easy for C++ programs to include COLAMD */ #ifdef __cplusplus extern "C" { #endif /* ========================================================================== */ /* === Include files ======================================================== */ /* ========================================================================== */ #include /* ========================================================================== */ /* === COLAMD version ======================================================= */ /* ========================================================================== */ /* COLAMD Version 2.4 and later will include the following definitions. * As an example, to test if the version you are using is 2.4 or later: * * #ifdef COLAMD_VERSION * if (COLAMD_VERSION >= COLAMD_VERSION_CODE (2,4)) ... * #endif * * This also works during compile-time: * * #if defined(COLAMD_VERSION) && (COLAMD_VERSION >= COLAMD_VERSION_CODE (2,4)) * printf ("This is version 2.4 or later\n") ; * #else * printf ("This is an early version\n") ; * #endif * * Versions 2.3 and earlier of COLAMD do not include a #define'd version number. */ #define COLAMD_DATE "May 4, 2016" #define COLAMD_VERSION_CODE(main,sub) ((main) * 1000 + (sub)) #define COLAMD_MAIN_VERSION 2 #define COLAMD_SUB_VERSION 9 #define COLAMD_SUBSUB_VERSION 6 #define COLAMD_VERSION \ COLAMD_VERSION_CODE(COLAMD_MAIN_VERSION,COLAMD_SUB_VERSION) /* ========================================================================== */ /* === Knob and statistics definitions ====================================== */ /* ========================================================================== */ /* size of the knobs [ ] array. Only knobs [0..1] are currently used. */ #define COLAMD_KNOBS 20 /* number of output statistics. Only stats [0..6] are currently used. */ #define COLAMD_STATS 20 /* knobs [0] and stats [0]: dense row knob and output statistic. */ #define COLAMD_DENSE_ROW 0 /* knobs [1] and stats [1]: dense column knob and output statistic. */ #define COLAMD_DENSE_COL 1 /* knobs [2]: aggressive absorption */ #define COLAMD_AGGRESSIVE 2 /* stats [2]: memory defragmentation count output statistic */ #define COLAMD_DEFRAG_COUNT 2 /* stats [3]: colamd status: zero OK, > 0 warning or notice, < 0 error */ #define COLAMD_STATUS 3 /* stats [4..6]: error info, or info on jumbled columns */ #define COLAMD_INFO1 4 #define COLAMD_INFO2 5 #define COLAMD_INFO3 6 /* error codes returned in stats [3]: */ #define COLAMD_OK (0) #define COLAMD_OK_BUT_JUMBLED (1) #define COLAMD_ERROR_A_not_present (-1) #define COLAMD_ERROR_p_not_present (-2) #define COLAMD_ERROR_nrow_negative (-3) #define COLAMD_ERROR_ncol_negative (-4) #define COLAMD_ERROR_nnz_negative (-5) #define COLAMD_ERROR_p0_nonzero (-6) #define COLAMD_ERROR_A_too_small (-7) #define COLAMD_ERROR_col_length_negative (-8) #define COLAMD_ERROR_row_index_out_of_bounds (-9) #define COLAMD_ERROR_out_of_memory (-10) #define COLAMD_ERROR_internal_error (-999) /* ========================================================================== */ /* === Prototypes of user-callable routines ================================= */ /* ========================================================================== */ #include "SuiteSparse_config.h" size_t colamd_recommended /* returns recommended value of Alen, */ /* or 0 if input arguments are erroneous */ ( int nnz, /* nonzeros in A */ int n_row, /* number of rows in A */ int n_col /* number of columns in A */ ) ; size_t colamd_l_recommended /* returns recommended value of Alen, */ /* or 0 if input arguments are erroneous */ ( SuiteSparse_long nnz, /* nonzeros in A */ SuiteSparse_long n_row, /* number of rows in A */ SuiteSparse_long n_col /* number of columns in A */ ) ; void colamd_set_defaults /* sets default parameters */ ( /* knobs argument is modified on output */ double knobs [COLAMD_KNOBS] /* parameter settings for colamd */ ) ; void colamd_l_set_defaults /* sets default parameters */ ( /* knobs argument is modified on output */ double knobs [COLAMD_KNOBS] /* parameter settings for colamd */ ) ; int colamd /* returns (1) if successful, (0) otherwise*/ ( /* A and p arguments are modified on output */ int n_row, /* number of rows in A */ int n_col, /* number of columns in A */ int Alen, /* size of the array A */ int A [], /* row indices of A, of size Alen */ int p [], /* column pointers of A, of size n_col+1 */ double knobs [COLAMD_KNOBS],/* parameter settings for colamd */ int stats [COLAMD_STATS] /* colamd output statistics and error codes */ ) ; SuiteSparse_long colamd_l /* returns (1) if successful, (0) otherwise*/ ( /* A and p arguments are modified on output */ SuiteSparse_long n_row, /* number of rows in A */ SuiteSparse_long n_col, /* number of columns in A */ SuiteSparse_long Alen, /* size of the array A */ SuiteSparse_long A [], /* row indices of A, of size Alen */ SuiteSparse_long p [], /* column pointers of A, of size n_col+1 */ double knobs [COLAMD_KNOBS],/* parameter settings for colamd */ SuiteSparse_long stats [COLAMD_STATS] /* colamd output statistics * and error codes */ ) ; int symamd /* return (1) if OK, (0) otherwise */ ( int n, /* number of rows and columns of A */ int A [], /* row indices of A */ int p [], /* column pointers of A */ int perm [], /* output permutation, size n_col+1 */ double knobs [COLAMD_KNOBS], /* parameters (uses defaults if NULL) */ int stats [COLAMD_STATS], /* output statistics and error codes */ void * (*allocate) (size_t, size_t), /* pointer to calloc (ANSI C) or */ /* mxCalloc (for MATLAB mexFunction) */ void (*release) (void *) /* pointer to free (ANSI C) or */ /* mxFree (for MATLAB mexFunction) */ ) ; SuiteSparse_long symamd_l /* return (1) if OK, (0) otherwise */ ( SuiteSparse_long n, /* number of rows and columns of A */ SuiteSparse_long A [], /* row indices of A */ SuiteSparse_long p [], /* column pointers of A */ SuiteSparse_long perm [], /* output permutation, size n_col+1 */ double knobs [COLAMD_KNOBS], /* parameters (uses defaults if NULL) */ SuiteSparse_long stats [COLAMD_STATS], /* output stats and error codes */ void * (*allocate) (size_t, size_t), /* pointer to calloc (ANSI C) or */ /* mxCalloc (for MATLAB mexFunction) */ void (*release) (void *) /* pointer to free (ANSI C) or */ /* mxFree (for MATLAB mexFunction) */ ) ; void colamd_report ( int stats [COLAMD_STATS] ) ; void colamd_l_report ( SuiteSparse_long stats [COLAMD_STATS] ) ; void symamd_report ( int stats [COLAMD_STATS] ) ; void symamd_l_report ( SuiteSparse_long stats [COLAMD_STATS] ) ; #ifdef __cplusplus } #endif #endif /* COLAMD_H */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/COLAMD/Makefile��������������������������������������������������������������������������0000644�0001762�0000144�00000000276�14547724215�014724� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# compile just the C-callable library library: ( cd Source ; $(MAKE) lib ) # remove object files, but keep the compiled programs and library archives clean: ( cd Source ; $(MAKE) clean ) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/COLAMD/Source/���������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14547724215�014517� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/COLAMD/Source/Makefile�������������������������������������������������������������������0000644�0001762�0000144�00000000507�14547724215�016161� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PKG_CPPFLAGS = -I../Include -I../../SuiteSparse_config LIB = ../../COLAMD.a lib: $(LIB) colamd_l.o: colamd.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -I../Include -DDLONG -c colamd.c -o $@ $(LIB): colamd.o colamd_l.o $(AR) -rucs $(LIB) colamd.o colamd_l.o mostlyclean: clean clean: @-rm -rf .libs _libs $(LIB) @-rm -f *.o �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/COLAMD/Source/colamd.c�������������������������������������������������������������������0000644�0001762�0000144�00000322005�13652535054�016121� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === colamd/symamd - a sparse matrix column ordering algorithm ============ */ /* ========================================================================== */ /* COLAMD / SYMAMD colamd: an approximate minimum degree column ordering algorithm, for LU factorization of symmetric or unsymmetric matrices, QR factorization, least squares, interior point methods for linear programming problems, and other related problems. symamd: an approximate minimum degree ordering algorithm for Cholesky factorization of symmetric matrices. Purpose: Colamd computes a permutation Q such that the Cholesky factorization of (AQ)'(AQ) has less fill-in and requires fewer floating point operations than A'A. This also provides a good ordering for sparse partial pivoting methods, P(AQ) = LU, where Q is computed prior to numerical factorization, and P is computed during numerical factorization via conventional partial pivoting with row interchanges. Colamd is the column ordering method used in SuperLU, part of the ScaLAPACK library. It is also available as built-in function in MATLAB Version 6, available from MathWorks, Inc. (http://www.mathworks.com). This routine can be used in place of colmmd in MATLAB. Symamd computes a permutation P of a symmetric matrix A such that the Cholesky factorization of PAP' has less fill-in and requires fewer floating point operations than A. Symamd constructs a matrix M such that M'M has the same nonzero pattern of A, and then orders the columns of M using colmmd. The column ordering of M is then returned as the row and column ordering P of A. Authors: The authors of the code itself are Stefan I. Larimore and Timothy A. Davis (DrTimothyAldenDavis@gmail.com). The algorithm was developed in collaboration with John Gilbert, Xerox PARC, and Esmond Ng, Oak Ridge National Laboratory. Acknowledgements: This work was supported by the National Science Foundation, under grants DMS-9504974 and DMS-9803599. Copyright and License: Copyright (c) 1998-2007, Timothy A. Davis, All Rights Reserved. COLAMD is also available under alternate licenses, contact T. Davis for details. See COLAMD/Doc/License.txt for the license. Availability: The colamd/symamd library is available at http://www.suitesparse.com Appears as ACM Algorithm 836. See the ChangeLog file for changes since Version 1.0. References: T. A. Davis, J. R. Gilbert, S. Larimore, E. Ng, An approximate column minimum degree ordering algorithm, ACM Transactions on Mathematical Software, vol. 30, no. 3., pp. 353-376, 2004. T. A. Davis, J. R. Gilbert, S. Larimore, E. Ng, Algorithm 836: COLAMD, an approximate column minimum degree ordering algorithm, ACM Transactions on Mathematical Software, vol. 30, no. 3., pp. 377-380, 2004. */ /* ========================================================================== */ /* === Description of user-callable routines ================================ */ /* ========================================================================== */ /* COLAMD includes both int and SuiteSparse_long versions of all its routines. The description below is for the int version. For SuiteSparse_long, all int arguments become SuiteSparse_long. SuiteSparse_long is normally defined as long, except for WIN64. ---------------------------------------------------------------------------- colamd_recommended: ---------------------------------------------------------------------------- C syntax: #include "colamd.h" size_t colamd_recommended (int nnz, int n_row, int n_col) ; size_t colamd_l_recommended (SuiteSparse_long nnz, SuiteSparse_long n_row, SuiteSparse_long n_col) ; Purpose: Returns recommended value of Alen for use by colamd. Returns 0 if any input argument is negative. The use of this routine is optional. Not needed for symamd, which dynamically allocates its own memory. Note that in v2.4 and earlier, these routines returned int or long. They now return a value of type size_t. Arguments (all input arguments): int nnz ; Number of nonzeros in the matrix A. This must be the same value as p [n_col] in the call to colamd - otherwise you will get a wrong value of the recommended memory to use. int n_row ; Number of rows in the matrix A. int n_col ; Number of columns in the matrix A. ---------------------------------------------------------------------------- colamd_set_defaults: ---------------------------------------------------------------------------- C syntax: #include "colamd.h" colamd_set_defaults (double knobs [COLAMD_KNOBS]) ; colamd_l_set_defaults (double knobs [COLAMD_KNOBS]) ; Purpose: Sets the default parameters. The use of this routine is optional. Arguments: double knobs [COLAMD_KNOBS] ; Output only. NOTE: the meaning of the dense row/col knobs has changed in v2.4 knobs [0] and knobs [1] control dense row and col detection: Colamd: rows with more than max (16, knobs [COLAMD_DENSE_ROW] * sqrt (n_col)) entries are removed prior to ordering. Columns with more than max (16, knobs [COLAMD_DENSE_COL] * sqrt (MIN (n_row,n_col))) entries are removed prior to ordering, and placed last in the output column ordering. Symamd: uses only knobs [COLAMD_DENSE_ROW], which is knobs [0]. Rows and columns with more than max (16, knobs [COLAMD_DENSE_ROW] * sqrt (n)) entries are removed prior to ordering, and placed last in the output ordering. COLAMD_DENSE_ROW and COLAMD_DENSE_COL are defined as 0 and 1, respectively, in colamd.h. Default values of these two knobs are both 10. Currently, only knobs [0] and knobs [1] are used, but future versions may use more knobs. If so, they will be properly set to their defaults by the future version of colamd_set_defaults, so that the code that calls colamd will not need to change, assuming that you either use colamd_set_defaults, or pass a (double *) NULL pointer as the knobs array to colamd or symamd. knobs [2]: aggressive absorption knobs [COLAMD_AGGRESSIVE] controls whether or not to do aggressive absorption during the ordering. Default is TRUE. ---------------------------------------------------------------------------- colamd: ---------------------------------------------------------------------------- C syntax: #include "colamd.h" int colamd (int n_row, int n_col, int Alen, int *A, int *p, double knobs [COLAMD_KNOBS], int stats [COLAMD_STATS]) ; SuiteSparse_long colamd_l (SuiteSparse_long n_row, SuiteSparse_long n_col, SuiteSparse_long Alen, SuiteSparse_long *A, SuiteSparse_long *p, double knobs [COLAMD_KNOBS], SuiteSparse_long stats [COLAMD_STATS]) ; Purpose: Computes a column ordering (Q) of A such that P(AQ)=LU or (AQ)'AQ=LL' have less fill-in and require fewer floating point operations than factorizing the unpermuted matrix A or A'A, respectively. Returns: TRUE (1) if successful, FALSE (0) otherwise. Arguments: int n_row ; Input argument. Number of rows in the matrix A. Restriction: n_row >= 0. Colamd returns FALSE if n_row is negative. int n_col ; Input argument. Number of columns in the matrix A. Restriction: n_col >= 0. Colamd returns FALSE if n_col is negative. int Alen ; Input argument. Restriction (see note): Alen >= 2*nnz + 6*(n_col+1) + 4*(n_row+1) + n_col Colamd returns FALSE if these conditions are not met. Note: this restriction makes an modest assumption regarding the size of the two typedef's structures in colamd.h. We do, however, guarantee that Alen >= colamd_recommended (nnz, n_row, n_col) will be sufficient. Note: the macro version does not check for integer overflow, and thus is not recommended. Use the colamd_recommended routine instead. int A [Alen] ; Input argument, undefined on output. A is an integer array of size Alen. Alen must be at least as large as the bare minimum value given above, but this is very low, and can result in excessive run time. For best performance, we recommend that Alen be greater than or equal to colamd_recommended (nnz, n_row, n_col), which adds nnz/5 to the bare minimum value given above. On input, the row indices of the entries in column c of the matrix are held in A [(p [c]) ... (p [c+1]-1)]. The row indices in a given column c need not be in ascending order, and duplicate row indices may be be present. However, colamd will work a little faster if both of these conditions are met (Colamd puts the matrix into this format, if it finds that the the conditions are not met). The matrix is 0-based. That is, rows are in the range 0 to n_row-1, and columns are in the range 0 to n_col-1. Colamd returns FALSE if any row index is out of range. The contents of A are modified during ordering, and are undefined on output. int p [n_col+1] ; Both input and output argument. p is an integer array of size n_col+1. On input, it holds the "pointers" for the column form of the matrix A. Column c of the matrix A is held in A [(p [c]) ... (p [c+1]-1)]. The first entry, p [0], must be zero, and p [c] <= p [c+1] must hold for all c in the range 0 to n_col-1. The value p [n_col] is thus the total number of entries in the pattern of the matrix A. Colamd returns FALSE if these conditions are not met. On output, if colamd returns TRUE, the array p holds the column permutation (Q, for P(AQ)=LU or (AQ)'(AQ)=LL'), where p [0] is the first column index in the new ordering, and p [n_col-1] is the last. That is, p [k] = j means that column j of A is the kth pivot column, in AQ, where k is in the range 0 to n_col-1 (p [0] = j means that column j of A is the first column in AQ). If colamd returns FALSE, then no permutation is returned, and p is undefined on output. double knobs [COLAMD_KNOBS] ; Input argument. See colamd_set_defaults for a description. int stats [COLAMD_STATS] ; Output argument. Statistics on the ordering, and error status. See colamd.h for related definitions. Colamd returns FALSE if stats is not present. stats [0]: number of dense or empty rows ignored. stats [1]: number of dense or empty columns ignored (and ordered last in the output permutation p) Note that a row can become "empty" if it contains only "dense" and/or "empty" columns, and similarly a column can become "empty" if it only contains "dense" and/or "empty" rows. stats [2]: number of garbage collections performed. This can be excessively high if Alen is close to the minimum required value. stats [3]: status code. < 0 is an error code. > 1 is a warning or notice. 0 OK. Each column of the input matrix contained row indices in increasing order, with no duplicates. 1 OK, but columns of input matrix were jumbled (unsorted columns or duplicate entries). Colamd had to do some extra work to sort the matrix first and remove duplicate entries, but it still was able to return a valid permutation (return value of colamd was TRUE). stats [4]: highest numbered column that is unsorted or has duplicate entries. stats [5]: last seen duplicate or unsorted row index. stats [6]: number of duplicate or unsorted row indices. -1 A is a null pointer -2 p is a null pointer -3 n_row is negative stats [4]: n_row -4 n_col is negative stats [4]: n_col -5 number of nonzeros in matrix is negative stats [4]: number of nonzeros, p [n_col] -6 p [0] is nonzero stats [4]: p [0] -7 A is too small stats [4]: required size stats [5]: actual size (Alen) -8 a column has a negative number of entries stats [4]: column with < 0 entries stats [5]: number of entries in col -9 a row index is out of bounds stats [4]: column with bad row index stats [5]: bad row index stats [6]: n_row, # of rows of matrx -10 (unused; see symamd.c) -999 (unused; see symamd.c) Future versions may return more statistics in the stats array. Example: See colamd_example.c for a complete example. To order the columns of a 5-by-4 matrix with 11 nonzero entries in the following nonzero pattern x 0 x 0 x 0 x x 0 x x 0 0 0 x x x x 0 0 with default knobs and no output statistics, do the following: #include "colamd.h" #define ALEN 100 int A [ALEN] = {0, 1, 4, 2, 4, 0, 1, 2, 3, 1, 3} ; int p [ ] = {0, 3, 5, 9, 11} ; int stats [COLAMD_STATS] ; colamd (5, 4, ALEN, A, p, (double *) NULL, stats) ; The permutation is returned in the array p, and A is destroyed. ---------------------------------------------------------------------------- symamd: ---------------------------------------------------------------------------- C syntax: #include "colamd.h" int symamd (int n, int *A, int *p, int *perm, double knobs [COLAMD_KNOBS], int stats [COLAMD_STATS], void (*allocate) (size_t, size_t), void (*release) (void *)) ; SuiteSparse_long symamd_l (SuiteSparse_long n, SuiteSparse_long *A, SuiteSparse_long *p, SuiteSparse_long *perm, double knobs [COLAMD_KNOBS], SuiteSparse_long stats [COLAMD_STATS], void (*allocate) (size_t, size_t), void (*release) (void *)) ; Purpose: The symamd routine computes an ordering P of a symmetric sparse matrix A such that the Cholesky factorization PAP' = LL' remains sparse. It is based on a column ordering of a matrix M constructed so that the nonzero pattern of M'M is the same as A. The matrix A is assumed to be symmetric; only the strictly lower triangular part is accessed. You must pass your selected memory allocator (usually calloc/free or mxCalloc/mxFree) to symamd, for it to allocate memory for the temporary matrix M. Returns: TRUE (1) if successful, FALSE (0) otherwise. Arguments: int n ; Input argument. Number of rows and columns in the symmetrix matrix A. Restriction: n >= 0. Symamd returns FALSE if n is negative. int A [nnz] ; Input argument. A is an integer array of size nnz, where nnz = p [n]. The row indices of the entries in column c of the matrix are held in A [(p [c]) ... (p [c+1]-1)]. The row indices in a given column c need not be in ascending order, and duplicate row indices may be present. However, symamd will run faster if the columns are in sorted order with no duplicate entries. The matrix is 0-based. That is, rows are in the range 0 to n-1, and columns are in the range 0 to n-1. Symamd returns FALSE if any row index is out of range. The contents of A are not modified. int p [n+1] ; Input argument. p is an integer array of size n+1. On input, it holds the "pointers" for the column form of the matrix A. Column c of the matrix A is held in A [(p [c]) ... (p [c+1]-1)]. The first entry, p [0], must be zero, and p [c] <= p [c+1] must hold for all c in the range 0 to n-1. The value p [n] is thus the total number of entries in the pattern of the matrix A. Symamd returns FALSE if these conditions are not met. The contents of p are not modified. int perm [n+1] ; Output argument. On output, if symamd returns TRUE, the array perm holds the permutation P, where perm [0] is the first index in the new ordering, and perm [n-1] is the last. That is, perm [k] = j means that row and column j of A is the kth column in PAP', where k is in the range 0 to n-1 (perm [0] = j means that row and column j of A are the first row and column in PAP'). The array is used as a workspace during the ordering, which is why it must be of length n+1, not just n. double knobs [COLAMD_KNOBS] ; Input argument. See colamd_set_defaults for a description. int stats [COLAMD_STATS] ; Output argument. Statistics on the ordering, and error status. See colamd.h for related definitions. Symamd returns FALSE if stats is not present. stats [0]: number of dense or empty row and columns ignored (and ordered last in the output permutation perm). Note that a row/column can become "empty" if it contains only "dense" and/or "empty" columns/rows. stats [1]: (same as stats [0]) stats [2]: number of garbage collections performed. stats [3]: status code. < 0 is an error code. > 1 is a warning or notice. 0 OK. Each column of the input matrix contained row indices in increasing order, with no duplicates. 1 OK, but columns of input matrix were jumbled (unsorted columns or duplicate entries). Symamd had to do some extra work to sort the matrix first and remove duplicate entries, but it still was able to return a valid permutation (return value of symamd was TRUE). stats [4]: highest numbered column that is unsorted or has duplicate entries. stats [5]: last seen duplicate or unsorted row index. stats [6]: number of duplicate or unsorted row indices. -1 A is a null pointer -2 p is a null pointer -3 (unused, see colamd.c) -4 n is negative stats [4]: n -5 number of nonzeros in matrix is negative stats [4]: # of nonzeros (p [n]). -6 p [0] is nonzero stats [4]: p [0] -7 (unused) -8 a column has a negative number of entries stats [4]: column with < 0 entries stats [5]: number of entries in col -9 a row index is out of bounds stats [4]: column with bad row index stats [5]: bad row index stats [6]: n_row, # of rows of matrx -10 out of memory (unable to allocate temporary workspace for M or count arrays using the "allocate" routine passed into symamd). Future versions may return more statistics in the stats array. void * (*allocate) (size_t, size_t) A pointer to a function providing memory allocation. The allocated memory must be returned initialized to zero. For a C application, this argument should normally be a pointer to calloc. For a MATLAB mexFunction, the routine mxCalloc is passed instead. void (*release) (size_t, size_t) A pointer to a function that frees memory allocated by the memory allocation routine above. For a C application, this argument should normally be a pointer to free. For a MATLAB mexFunction, the routine mxFree is passed instead. ---------------------------------------------------------------------------- colamd_report: ---------------------------------------------------------------------------- C syntax: #include "colamd.h" colamd_report (int stats [COLAMD_STATS]) ; colamd_l_report (SuiteSparse_long stats [COLAMD_STATS]) ; Purpose: Prints the error status and statistics recorded in the stats array on the standard error output (for a standard C routine) or on the MATLAB output (for a mexFunction). Arguments: int stats [COLAMD_STATS] ; Input only. Statistics from colamd. ---------------------------------------------------------------------------- symamd_report: ---------------------------------------------------------------------------- C syntax: #include "colamd.h" symamd_report (int stats [COLAMD_STATS]) ; symamd_l_report (SuiteSparse_long stats [COLAMD_STATS]) ; Purpose: Prints the error status and statistics recorded in the stats array on the standard error output (for a standard C routine) or on the MATLAB output (for a mexFunction). Arguments: int stats [COLAMD_STATS] ; Input only. Statistics from symamd. */ /* ========================================================================== */ /* === Scaffolding code definitions ======================================== */ /* ========================================================================== */ /* Ensure that debugging is turned off: */ #ifndef NDEBUG #define NDEBUG #endif /* turn on debugging by uncommenting the following line #undef NDEBUG */ /* Our "scaffolding code" philosophy: In our opinion, well-written library code should keep its "debugging" code, and just normally have it turned off by the compiler so as not to interfere with performance. This serves several purposes: (1) assertions act as comments to the reader, telling you what the code expects at that point. All assertions will always be true (unless there really is a bug, of course). (2) leaving in the scaffolding code assists anyone who would like to modify the code, or understand the algorithm (by reading the debugging output, one can get a glimpse into what the code is doing). (3) (gasp!) for actually finding bugs. This code has been heavily tested and "should" be fully functional and bug-free ... but you never know... The code will become outrageously slow when debugging is enabled. To control the level of debugging output, set an environment variable D to 0 (little), 1 (some), 2, 3, or 4 (lots). When debugging, you should see the following message on the standard output: colamd: debug version, D = 1 (THIS WILL BE SLOW!) or a similar message for symamd. If you don't, then debugging has not been enabled. */ /* ========================================================================== */ /* === Include files ======================================================== */ /* ========================================================================== */ #include "colamd.h" #include #include #ifdef MATLAB_MEX_FILE #include "mex.h" #include "matrix.h" #endif /* MATLAB_MEX_FILE */ #if !defined (NPRINT) || !defined (NDEBUG) #include #endif #ifndef NULL #define NULL ((void *) 0) #endif /* ========================================================================== */ /* === int or SuiteSparse_long ============================================== */ /* ========================================================================== */ #ifdef DLONG #define Int SuiteSparse_long #define ID SuiteSparse_long_id #define Int_MAX SuiteSparse_long_max #define COLAMD_recommended colamd_l_recommended #define COLAMD_set_defaults colamd_l_set_defaults #define COLAMD_MAIN colamd_l #define SYMAMD_MAIN symamd_l #define COLAMD_report colamd_l_report #define SYMAMD_report symamd_l_report #else #define Int int #define ID "%d" #define Int_MAX INT_MAX #define COLAMD_recommended colamd_recommended #define COLAMD_set_defaults colamd_set_defaults #define COLAMD_MAIN colamd #define SYMAMD_MAIN symamd #define COLAMD_report colamd_report #define SYMAMD_report symamd_report #endif /* ========================================================================== */ /* === Row and Column structures ============================================ */ /* ========================================================================== */ /* User code that makes use of the colamd/symamd routines need not directly */ /* reference these structures. They are used only for colamd_recommended. */ typedef struct Colamd_Col_struct { Int start ; /* index for A of first row in this column, or DEAD */ /* if column is dead */ Int length ; /* number of rows in this column */ union { Int thickness ; /* number of original columns represented by this */ /* col, if the column is alive */ Int parent ; /* parent in parent tree super-column structure, if */ /* the column is dead */ } shared1 ; union { Int score ; /* the score used to maintain heap, if col is alive */ Int order ; /* pivot ordering of this column, if col is dead */ } shared2 ; union { Int headhash ; /* head of a hash bucket, if col is at the head of */ /* a degree list */ Int hash ; /* hash value, if col is not in a degree list */ Int prev ; /* previous column in degree list, if col is in a */ /* degree list (but not at the head of a degree list) */ } shared3 ; union { Int degree_next ; /* next column, if col is in a degree list */ Int hash_next ; /* next column, if col is in a hash list */ } shared4 ; } Colamd_Col ; typedef struct Colamd_Row_struct { Int start ; /* index for A of first col in this row */ Int length ; /* number of principal columns in this row */ union { Int degree ; /* number of principal & non-principal columns in row */ Int p ; /* used as a row pointer in init_rows_cols () */ } shared1 ; union { Int mark ; /* for computing set differences and marking dead rows*/ Int first_column ;/* first column in row (used in garbage collection) */ } shared2 ; } Colamd_Row ; /* ========================================================================== */ /* === Definitions ========================================================== */ /* ========================================================================== */ /* Routines are either PUBLIC (user-callable) or PRIVATE (not user-callable) */ #define PUBLIC #define PRIVATE static #define DENSE_DEGREE(alpha,n) \ ((Int) MAX (16.0, (alpha) * sqrt ((double) (n)))) #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #define ONES_COMPLEMENT(r) (-(r)-1) /* -------------------------------------------------------------------------- */ /* Change for version 2.1: define TRUE and FALSE only if not yet defined */ /* -------------------------------------------------------------------------- */ #ifndef TRUE #define TRUE (1) #endif #ifndef FALSE #define FALSE (0) #endif /* -------------------------------------------------------------------------- */ #define EMPTY (-1) /* Row and column status */ #define ALIVE (0) #define DEAD (-1) /* Column status */ #define DEAD_PRINCIPAL (-1) #define DEAD_NON_PRINCIPAL (-2) /* Macros for row and column status update and checking. */ #define ROW_IS_DEAD(r) ROW_IS_MARKED_DEAD (Row[r].shared2.mark) #define ROW_IS_MARKED_DEAD(row_mark) (row_mark < ALIVE) #define ROW_IS_ALIVE(r) (Row [r].shared2.mark >= ALIVE) #define COL_IS_DEAD(c) (Col [c].start < ALIVE) #define COL_IS_ALIVE(c) (Col [c].start >= ALIVE) #define COL_IS_DEAD_PRINCIPAL(c) (Col [c].start == DEAD_PRINCIPAL) #define KILL_ROW(r) { Row [r].shared2.mark = DEAD ; } #define KILL_PRINCIPAL_COL(c) { Col [c].start = DEAD_PRINCIPAL ; } #define KILL_NON_PRINCIPAL_COL(c) { Col [c].start = DEAD_NON_PRINCIPAL ; } /* ========================================================================== */ /* === Colamd reporting mechanism =========================================== */ /* ========================================================================== */ #if defined (MATLAB_MEX_FILE) || defined (MATHWORKS) /* In MATLAB, matrices are 1-based to the user, but 0-based internally */ #define INDEX(i) ((i)+1) #else /* In C, matrices are 0-based and indices are reported as such in *_report */ #define INDEX(i) (i) #endif /* ========================================================================== */ /* === Prototypes of PRIVATE routines ======================================= */ /* ========================================================================== */ PRIVATE Int init_rows_cols ( Int n_row, Int n_col, Colamd_Row Row [], Colamd_Col Col [], Int A [], Int p [], Int stats [COLAMD_STATS] ) ; PRIVATE void init_scoring ( Int n_row, Int n_col, Colamd_Row Row [], Colamd_Col Col [], Int A [], Int head [], double knobs [COLAMD_KNOBS], Int *p_n_row2, Int *p_n_col2, Int *p_max_deg ) ; PRIVATE Int find_ordering ( Int n_row, Int n_col, Int Alen, Colamd_Row Row [], Colamd_Col Col [], Int A [], Int head [], Int n_col2, Int max_deg, Int pfree, Int aggressive ) ; PRIVATE void order_children ( Int n_col, Colamd_Col Col [], Int p [] ) ; PRIVATE void detect_super_cols ( #ifndef NDEBUG Int n_col, Colamd_Row Row [], #endif /* NDEBUG */ Colamd_Col Col [], Int A [], Int head [], Int row_start, Int row_length ) ; PRIVATE Int garbage_collection ( Int n_row, Int n_col, Colamd_Row Row [], Colamd_Col Col [], Int A [], Int *pfree ) ; PRIVATE Int clear_mark ( Int tag_mark, Int max_mark, Int n_row, Colamd_Row Row [] ) ; PRIVATE void print_report ( char *method, Int stats [COLAMD_STATS] ) ; /* ========================================================================== */ /* === Debugging prototypes and definitions ================================= */ /* ========================================================================== */ #ifndef NDEBUG #include /* colamd_debug is the *ONLY* global variable, and is only */ /* present when debugging */ PRIVATE Int colamd_debug = 0 ; /* debug print level */ #define DEBUG0(params) { SUITESPARSE_PRINTF (params) ; } #define DEBUG1(params) { if (colamd_debug >= 1) SUITESPARSE_PRINTF (params) ; } #define DEBUG2(params) { if (colamd_debug >= 2) SUITESPARSE_PRINTF (params) ; } #define DEBUG3(params) { if (colamd_debug >= 3) SUITESPARSE_PRINTF (params) ; } #define DEBUG4(params) { if (colamd_debug >= 4) SUITESPARSE_PRINTF (params) ; } #ifdef MATLAB_MEX_FILE #define ASSERT(expression) (mxAssert ((expression), "")) #else #define ASSERT(expression) (assert (expression)) #endif /* MATLAB_MEX_FILE */ PRIVATE void colamd_get_debug /* gets the debug print level from getenv */ ( char *method ) ; PRIVATE void debug_deg_lists ( Int n_row, Int n_col, Colamd_Row Row [], Colamd_Col Col [], Int head [], Int min_score, Int should, Int max_deg ) ; PRIVATE void debug_mark ( Int n_row, Colamd_Row Row [], Int tag_mark, Int max_mark ) ; PRIVATE void debug_matrix ( Int n_row, Int n_col, Colamd_Row Row [], Colamd_Col Col [], Int A [] ) ; PRIVATE void debug_structures ( Int n_row, Int n_col, Colamd_Row Row [], Colamd_Col Col [], Int A [], Int n_col2 ) ; #else /* NDEBUG */ /* === No debugging ========================================================= */ #define DEBUG0(params) ; #define DEBUG1(params) ; #define DEBUG2(params) ; #define DEBUG3(params) ; #define DEBUG4(params) ; #define ASSERT(expression) #endif /* NDEBUG */ /* ========================================================================== */ /* === USER-CALLABLE ROUTINES: ============================================== */ /* ========================================================================== */ /* ========================================================================== */ /* === colamd_recommended =================================================== */ /* ========================================================================== */ /* The colamd_recommended routine returns the suggested size for Alen. This value has been determined to provide good balance between the number of garbage collections and the memory requirements for colamd. If any argument is negative, or if integer overflow occurs, a 0 is returned as an error condition. 2*nnz space is required for the row and column indices of the matrix. COLAMD_C (n_col) + COLAMD_R (n_row) space is required for the Col and Row arrays, respectively, which are internal to colamd (roughly 6*n_col + 4*n_row). An additional n_col space is the minimal amount of "elbow room", and nnz/5 more space is recommended for run time efficiency. Alen is approximately 2.2*nnz + 7*n_col + 4*n_row + 10. This function is not needed when using symamd. */ /* add two values of type size_t, and check for integer overflow */ static size_t t_add (size_t a, size_t b, int *ok) { (*ok) = (*ok) && ((a + b) >= MAX (a,b)) ; return ((*ok) ? (a + b) : 0) ; } /* compute a*k where k is a small integer, and check for integer overflow */ static size_t t_mult (size_t a, size_t k, int *ok) { size_t i, s = 0 ; for (i = 0 ; i < k ; i++) { s = t_add (s, a, ok) ; } return (s) ; } /* size of the Col and Row structures */ #define COLAMD_C(n_col,ok) \ ((t_mult (t_add (n_col, 1, ok), sizeof (Colamd_Col), ok) / sizeof (Int))) #define COLAMD_R(n_row,ok) \ ((t_mult (t_add (n_row, 1, ok), sizeof (Colamd_Row), ok) / sizeof (Int))) PUBLIC size_t COLAMD_recommended /* returns recommended value of Alen. */ ( /* === Parameters ======================================================= */ Int nnz, /* number of nonzeros in A */ Int n_row, /* number of rows in A */ Int n_col /* number of columns in A */ ) { size_t s, c, r ; int ok = TRUE ; if (nnz < 0 || n_row < 0 || n_col < 0) { return (0) ; } s = t_mult (nnz, 2, &ok) ; /* 2*nnz */ c = COLAMD_C (n_col, &ok) ; /* size of column structures */ r = COLAMD_R (n_row, &ok) ; /* size of row structures */ s = t_add (s, c, &ok) ; s = t_add (s, r, &ok) ; s = t_add (s, n_col, &ok) ; /* elbow room */ s = t_add (s, nnz/5, &ok) ; /* elbow room */ ok = ok && (s < Int_MAX) ; return (ok ? s : 0) ; } /* ========================================================================== */ /* === colamd_set_defaults ================================================== */ /* ========================================================================== */ /* The colamd_set_defaults routine sets the default values of the user- controllable parameters for colamd and symamd: Colamd: rows with more than max (16, knobs [0] * sqrt (n_col)) entries are removed prior to ordering. Columns with more than max (16, knobs [1] * sqrt (MIN (n_row,n_col))) entries are removed prior to ordering, and placed last in the output column ordering. Symamd: Rows and columns with more than max (16, knobs [0] * sqrt (n)) entries are removed prior to ordering, and placed last in the output ordering. knobs [0] dense row control knobs [1] dense column control knobs [2] if nonzero, do aggresive absorption knobs [3..19] unused, but future versions might use this */ PUBLIC void COLAMD_set_defaults ( /* === Parameters ======================================================= */ double knobs [COLAMD_KNOBS] /* knob array */ ) { /* === Local variables ================================================== */ Int i ; if (!knobs) { return ; /* no knobs to initialize */ } for (i = 0 ; i < COLAMD_KNOBS ; i++) { knobs [i] = 0 ; } knobs [COLAMD_DENSE_ROW] = 10 ; knobs [COLAMD_DENSE_COL] = 10 ; knobs [COLAMD_AGGRESSIVE] = TRUE ; /* default: do aggressive absorption*/ } /* ========================================================================== */ /* === symamd =============================================================== */ /* ========================================================================== */ PUBLIC Int SYMAMD_MAIN /* return TRUE if OK, FALSE otherwise */ ( /* === Parameters ======================================================= */ Int n, /* number of rows and columns of A */ Int A [], /* row indices of A */ Int p [], /* column pointers of A */ Int perm [], /* output permutation, size n+1 */ double knobs [COLAMD_KNOBS], /* parameters (uses defaults if NULL) */ Int stats [COLAMD_STATS], /* output statistics and error codes */ void * (*allocate) (size_t, size_t), /* pointer to calloc (ANSI C) or */ /* mxCalloc (for MATLAB mexFunction) */ void (*release) (void *) /* pointer to free (ANSI C) or */ /* mxFree (for MATLAB mexFunction) */ ) { /* === Local variables ================================================== */ Int *count ; /* length of each column of M, and col pointer*/ Int *mark ; /* mark array for finding duplicate entries */ Int *M ; /* row indices of matrix M */ size_t Mlen ; /* length of M */ Int n_row ; /* number of rows in M */ Int nnz ; /* number of entries in A */ Int i ; /* row index of A */ Int j ; /* column index of A */ Int k ; /* row index of M */ Int mnz ; /* number of nonzeros in M */ Int pp ; /* index into a column of A */ Int last_row ; /* last row seen in the current column */ Int length ; /* number of nonzeros in a column */ double cknobs [COLAMD_KNOBS] ; /* knobs for colamd */ double default_knobs [COLAMD_KNOBS] ; /* default knobs for colamd */ #ifndef NDEBUG colamd_get_debug ("symamd") ; #endif /* NDEBUG */ /* === Check the input arguments ======================================== */ if (!stats) { DEBUG0 (("symamd: stats not present\n")) ; return (FALSE) ; } for (i = 0 ; i < COLAMD_STATS ; i++) { stats [i] = 0 ; } stats [COLAMD_STATUS] = COLAMD_OK ; stats [COLAMD_INFO1] = -1 ; stats [COLAMD_INFO2] = -1 ; if (!A) { stats [COLAMD_STATUS] = COLAMD_ERROR_A_not_present ; DEBUG0 (("symamd: A not present\n")) ; return (FALSE) ; } if (!p) /* p is not present */ { stats [COLAMD_STATUS] = COLAMD_ERROR_p_not_present ; DEBUG0 (("symamd: p not present\n")) ; return (FALSE) ; } if (n < 0) /* n must be >= 0 */ { stats [COLAMD_STATUS] = COLAMD_ERROR_ncol_negative ; stats [COLAMD_INFO1] = n ; DEBUG0 (("symamd: n negative %d\n", n)) ; return (FALSE) ; } nnz = p [n] ; if (nnz < 0) /* nnz must be >= 0 */ { stats [COLAMD_STATUS] = COLAMD_ERROR_nnz_negative ; stats [COLAMD_INFO1] = nnz ; DEBUG0 (("symamd: number of entries negative %d\n", nnz)) ; return (FALSE) ; } if (p [0] != 0) { stats [COLAMD_STATUS] = COLAMD_ERROR_p0_nonzero ; stats [COLAMD_INFO1] = p [0] ; DEBUG0 (("symamd: p[0] not zero %d\n", p [0])) ; return (FALSE) ; } /* === If no knobs, set default knobs =================================== */ if (!knobs) { COLAMD_set_defaults (default_knobs) ; knobs = default_knobs ; } /* === Allocate count and mark ========================================== */ count = (Int *) ((*allocate) (n+1, sizeof (Int))) ; if (!count) { stats [COLAMD_STATUS] = COLAMD_ERROR_out_of_memory ; DEBUG0 (("symamd: allocate count (size %d) failed\n", n+1)) ; return (FALSE) ; } mark = (Int *) ((*allocate) (n+1, sizeof (Int))) ; if (!mark) { stats [COLAMD_STATUS] = COLAMD_ERROR_out_of_memory ; (*release) ((void *) count) ; DEBUG0 (("symamd: allocate mark (size %d) failed\n", n+1)) ; return (FALSE) ; } /* === Compute column counts of M, check if A is valid ================== */ stats [COLAMD_INFO3] = 0 ; /* number of duplicate or unsorted row indices*/ for (i = 0 ; i < n ; i++) { mark [i] = -1 ; } for (j = 0 ; j < n ; j++) { last_row = -1 ; length = p [j+1] - p [j] ; if (length < 0) { /* column pointers must be non-decreasing */ stats [COLAMD_STATUS] = COLAMD_ERROR_col_length_negative ; stats [COLAMD_INFO1] = j ; stats [COLAMD_INFO2] = length ; (*release) ((void *) count) ; (*release) ((void *) mark) ; DEBUG0 (("symamd: col %d negative length %d\n", j, length)) ; return (FALSE) ; } for (pp = p [j] ; pp < p [j+1] ; pp++) { i = A [pp] ; if (i < 0 || i >= n) { /* row index i, in column j, is out of bounds */ stats [COLAMD_STATUS] = COLAMD_ERROR_row_index_out_of_bounds ; stats [COLAMD_INFO1] = j ; stats [COLAMD_INFO2] = i ; stats [COLAMD_INFO3] = n ; (*release) ((void *) count) ; (*release) ((void *) mark) ; DEBUG0 (("symamd: row %d col %d out of bounds\n", i, j)) ; return (FALSE) ; } if (i <= last_row || mark [i] == j) { /* row index is unsorted or repeated (or both), thus col */ /* is jumbled. This is a notice, not an error condition. */ stats [COLAMD_STATUS] = COLAMD_OK_BUT_JUMBLED ; stats [COLAMD_INFO1] = j ; stats [COLAMD_INFO2] = i ; (stats [COLAMD_INFO3]) ++ ; DEBUG1 (("symamd: row %d col %d unsorted/duplicate\n", i, j)) ; } if (i > j && mark [i] != j) { /* row k of M will contain column indices i and j */ count [i]++ ; count [j]++ ; } /* mark the row as having been seen in this column */ mark [i] = j ; last_row = i ; } } /* v2.4: removed free(mark) */ /* === Compute column pointers of M ===================================== */ /* use output permutation, perm, for column pointers of M */ perm [0] = 0 ; for (j = 1 ; j <= n ; j++) { perm [j] = perm [j-1] + count [j-1] ; } for (j = 0 ; j < n ; j++) { count [j] = perm [j] ; } /* === Construct M ====================================================== */ mnz = perm [n] ; n_row = mnz / 2 ; Mlen = COLAMD_recommended (mnz, n_row, n) ; M = (Int *) ((*allocate) (Mlen, sizeof (Int))) ; DEBUG0 (("symamd: M is %d-by-%d with %d entries, Mlen = %g\n", n_row, n, mnz, (double) Mlen)) ; if (!M) { stats [COLAMD_STATUS] = COLAMD_ERROR_out_of_memory ; (*release) ((void *) count) ; (*release) ((void *) mark) ; DEBUG0 (("symamd: allocate M (size %g) failed\n", (double) Mlen)) ; return (FALSE) ; } k = 0 ; if (stats [COLAMD_STATUS] == COLAMD_OK) { /* Matrix is OK */ for (j = 0 ; j < n ; j++) { ASSERT (p [j+1] - p [j] >= 0) ; for (pp = p [j] ; pp < p [j+1] ; pp++) { i = A [pp] ; ASSERT (i >= 0 && i < n) ; if (i > j) { /* row k of M contains column indices i and j */ M [count [i]++] = k ; M [count [j]++] = k ; k++ ; } } } } else { /* Matrix is jumbled. Do not add duplicates to M. Unsorted cols OK. */ DEBUG0 (("symamd: Duplicates in A.\n")) ; for (i = 0 ; i < n ; i++) { mark [i] = -1 ; } for (j = 0 ; j < n ; j++) { ASSERT (p [j+1] - p [j] >= 0) ; for (pp = p [j] ; pp < p [j+1] ; pp++) { i = A [pp] ; ASSERT (i >= 0 && i < n) ; if (i > j && mark [i] != j) { /* row k of M contains column indices i and j */ M [count [i]++] = k ; M [count [j]++] = k ; k++ ; mark [i] = j ; } } } /* v2.4: free(mark) moved below */ } /* count and mark no longer needed */ (*release) ((void *) count) ; (*release) ((void *) mark) ; /* v2.4: free (mark) moved here */ ASSERT (k == n_row) ; /* === Adjust the knobs for M =========================================== */ for (i = 0 ; i < COLAMD_KNOBS ; i++) { cknobs [i] = knobs [i] ; } /* there are no dense rows in M */ cknobs [COLAMD_DENSE_ROW] = -1 ; cknobs [COLAMD_DENSE_COL] = knobs [COLAMD_DENSE_ROW] ; /* === Order the columns of M =========================================== */ /* v2.4: colamd cannot fail here, so the error check is removed */ (void) COLAMD_MAIN (n_row, n, (Int) Mlen, M, perm, cknobs, stats) ; /* Note that the output permutation is now in perm */ /* === get the statistics for symamd from colamd ======================== */ /* a dense column in colamd means a dense row and col in symamd */ stats [COLAMD_DENSE_ROW] = stats [COLAMD_DENSE_COL] ; /* === Free M =========================================================== */ (*release) ((void *) M) ; DEBUG0 (("symamd: done.\n")) ; return (TRUE) ; } /* ========================================================================== */ /* === colamd =============================================================== */ /* ========================================================================== */ /* The colamd routine computes a column ordering Q of a sparse matrix A such that the LU factorization P(AQ) = LU remains sparse, where P is selected via partial pivoting. The routine can also be viewed as providing a permutation Q such that the Cholesky factorization (AQ)'(AQ) = LL' remains sparse. */ PUBLIC Int COLAMD_MAIN /* returns TRUE if successful, FALSE otherwise*/ ( /* === Parameters ======================================================= */ Int n_row, /* number of rows in A */ Int n_col, /* number of columns in A */ Int Alen, /* length of A */ Int A [], /* row indices of A */ Int p [], /* pointers to columns in A */ double knobs [COLAMD_KNOBS],/* parameters (uses defaults if NULL) */ Int stats [COLAMD_STATS] /* output statistics and error codes */ ) { /* === Local variables ================================================== */ Int i ; /* loop index */ Int nnz ; /* nonzeros in A */ size_t Row_size ; /* size of Row [], in integers */ size_t Col_size ; /* size of Col [], in integers */ size_t need ; /* minimum required length of A */ Colamd_Row *Row ; /* pointer into A of Row [0..n_row] array */ Colamd_Col *Col ; /* pointer into A of Col [0..n_col] array */ Int n_col2 ; /* number of non-dense, non-empty columns */ Int n_row2 ; /* number of non-dense, non-empty rows */ Int ngarbage ; /* number of garbage collections performed */ Int max_deg ; /* maximum row degree */ double default_knobs [COLAMD_KNOBS] ; /* default knobs array */ Int aggressive ; /* do aggressive absorption */ int ok ; #ifndef NDEBUG colamd_get_debug ("colamd") ; #endif /* NDEBUG */ /* === Check the input arguments ======================================== */ if (!stats) { DEBUG0 (("colamd: stats not present\n")) ; return (FALSE) ; } for (i = 0 ; i < COLAMD_STATS ; i++) { stats [i] = 0 ; } stats [COLAMD_STATUS] = COLAMD_OK ; stats [COLAMD_INFO1] = -1 ; stats [COLAMD_INFO2] = -1 ; if (!A) /* A is not present */ { stats [COLAMD_STATUS] = COLAMD_ERROR_A_not_present ; DEBUG0 (("colamd: A not present\n")) ; return (FALSE) ; } if (!p) /* p is not present */ { stats [COLAMD_STATUS] = COLAMD_ERROR_p_not_present ; DEBUG0 (("colamd: p not present\n")) ; return (FALSE) ; } if (n_row < 0) /* n_row must be >= 0 */ { stats [COLAMD_STATUS] = COLAMD_ERROR_nrow_negative ; stats [COLAMD_INFO1] = n_row ; DEBUG0 (("colamd: nrow negative %d\n", n_row)) ; return (FALSE) ; } if (n_col < 0) /* n_col must be >= 0 */ { stats [COLAMD_STATUS] = COLAMD_ERROR_ncol_negative ; stats [COLAMD_INFO1] = n_col ; DEBUG0 (("colamd: ncol negative %d\n", n_col)) ; return (FALSE) ; } nnz = p [n_col] ; if (nnz < 0) /* nnz must be >= 0 */ { stats [COLAMD_STATUS] = COLAMD_ERROR_nnz_negative ; stats [COLAMD_INFO1] = nnz ; DEBUG0 (("colamd: number of entries negative %d\n", nnz)) ; return (FALSE) ; } if (p [0] != 0) { stats [COLAMD_STATUS] = COLAMD_ERROR_p0_nonzero ; stats [COLAMD_INFO1] = p [0] ; DEBUG0 (("colamd: p[0] not zero %d\n", p [0])) ; return (FALSE) ; } /* === If no knobs, set default knobs =================================== */ if (!knobs) { COLAMD_set_defaults (default_knobs) ; knobs = default_knobs ; } aggressive = (knobs [COLAMD_AGGRESSIVE] != FALSE) ; /* === Allocate the Row and Col arrays from array A ===================== */ ok = TRUE ; Col_size = COLAMD_C (n_col, &ok) ; /* size of Col array of structs */ Row_size = COLAMD_R (n_row, &ok) ; /* size of Row array of structs */ /* need = 2*nnz + n_col + Col_size + Row_size ; */ need = t_mult (nnz, 2, &ok) ; need = t_add (need, n_col, &ok) ; need = t_add (need, Col_size, &ok) ; need = t_add (need, Row_size, &ok) ; if (!ok || need > (size_t) Alen || need > Int_MAX) { /* not enough space in array A to perform the ordering */ stats [COLAMD_STATUS] = COLAMD_ERROR_A_too_small ; stats [COLAMD_INFO1] = need ; stats [COLAMD_INFO2] = Alen ; DEBUG0 (("colamd: Need Alen >= %d, given only Alen = %d\n", need,Alen)); return (FALSE) ; } Alen -= Col_size + Row_size ; Col = (Colamd_Col *) &A [Alen] ; Row = (Colamd_Row *) &A [Alen + Col_size] ; /* === Construct the row and column data structures ===================== */ if (!init_rows_cols (n_row, n_col, Row, Col, A, p, stats)) { /* input matrix is invalid */ DEBUG0 (("colamd: Matrix invalid\n")) ; return (FALSE) ; } /* === Initialize scores, kill dense rows/columns ======================= */ init_scoring (n_row, n_col, Row, Col, A, p, knobs, &n_row2, &n_col2, &max_deg) ; /* === Order the supercolumns =========================================== */ ngarbage = find_ordering (n_row, n_col, Alen, Row, Col, A, p, n_col2, max_deg, 2*nnz, aggressive) ; /* === Order the non-principal columns ================================== */ order_children (n_col, Col, p) ; /* === Return statistics in stats ======================================= */ stats [COLAMD_DENSE_ROW] = n_row - n_row2 ; stats [COLAMD_DENSE_COL] = n_col - n_col2 ; stats [COLAMD_DEFRAG_COUNT] = ngarbage ; DEBUG0 (("colamd: done.\n")) ; return (TRUE) ; } /* ========================================================================== */ /* === colamd_report ======================================================== */ /* ========================================================================== */ PUBLIC void COLAMD_report ( Int stats [COLAMD_STATS] ) { print_report ("colamd", stats) ; } /* ========================================================================== */ /* === symamd_report ======================================================== */ /* ========================================================================== */ PUBLIC void SYMAMD_report ( Int stats [COLAMD_STATS] ) { print_report ("symamd", stats) ; } /* ========================================================================== */ /* === NON-USER-CALLABLE ROUTINES: ========================================== */ /* ========================================================================== */ /* There are no user-callable routines beyond this point in the file */ /* ========================================================================== */ /* === init_rows_cols ======================================================= */ /* ========================================================================== */ /* Takes the column form of the matrix in A and creates the row form of the matrix. Also, row and column attributes are stored in the Col and Row structs. If the columns are un-sorted or contain duplicate row indices, this routine will also sort and remove duplicate row indices from the column form of the matrix. Returns FALSE if the matrix is invalid, TRUE otherwise. Not user-callable. */ PRIVATE Int init_rows_cols /* returns TRUE if OK, or FALSE otherwise */ ( /* === Parameters ======================================================= */ Int n_row, /* number of rows of A */ Int n_col, /* number of columns of A */ Colamd_Row Row [], /* of size n_row+1 */ Colamd_Col Col [], /* of size n_col+1 */ Int A [], /* row indices of A, of size Alen */ Int p [], /* pointers to columns in A, of size n_col+1 */ Int stats [COLAMD_STATS] /* colamd statistics */ ) { /* === Local variables ================================================== */ Int col ; /* a column index */ Int row ; /* a row index */ Int *cp ; /* a column pointer */ Int *cp_end ; /* a pointer to the end of a column */ Int *rp ; /* a row pointer */ Int *rp_end ; /* a pointer to the end of a row */ Int last_row ; /* previous row */ /* === Initialize columns, and check column pointers ==================== */ for (col = 0 ; col < n_col ; col++) { Col [col].start = p [col] ; Col [col].length = p [col+1] - p [col] ; if (Col [col].length < 0) { /* column pointers must be non-decreasing */ stats [COLAMD_STATUS] = COLAMD_ERROR_col_length_negative ; stats [COLAMD_INFO1] = col ; stats [COLAMD_INFO2] = Col [col].length ; DEBUG0 (("colamd: col %d length %d < 0\n", col, Col [col].length)) ; return (FALSE) ; } Col [col].shared1.thickness = 1 ; Col [col].shared2.score = 0 ; Col [col].shared3.prev = EMPTY ; Col [col].shared4.degree_next = EMPTY ; } /* p [0..n_col] no longer needed, used as "head" in subsequent routines */ /* === Scan columns, compute row degrees, and check row indices ========= */ stats [COLAMD_INFO3] = 0 ; /* number of duplicate or unsorted row indices*/ for (row = 0 ; row < n_row ; row++) { Row [row].length = 0 ; Row [row].shared2.mark = -1 ; } for (col = 0 ; col < n_col ; col++) { last_row = -1 ; cp = &A [p [col]] ; cp_end = &A [p [col+1]] ; while (cp < cp_end) { row = *cp++ ; /* make sure row indices within range */ if (row < 0 || row >= n_row) { stats [COLAMD_STATUS] = COLAMD_ERROR_row_index_out_of_bounds ; stats [COLAMD_INFO1] = col ; stats [COLAMD_INFO2] = row ; stats [COLAMD_INFO3] = n_row ; DEBUG0 (("colamd: row %d col %d out of bounds\n", row, col)) ; return (FALSE) ; } if (row <= last_row || Row [row].shared2.mark == col) { /* row index are unsorted or repeated (or both), thus col */ /* is jumbled. This is a notice, not an error condition. */ stats [COLAMD_STATUS] = COLAMD_OK_BUT_JUMBLED ; stats [COLAMD_INFO1] = col ; stats [COLAMD_INFO2] = row ; (stats [COLAMD_INFO3]) ++ ; DEBUG1 (("colamd: row %d col %d unsorted/duplicate\n",row,col)); } if (Row [row].shared2.mark != col) { Row [row].length++ ; } else { /* this is a repeated entry in the column, */ /* it will be removed */ Col [col].length-- ; } /* mark the row as having been seen in this column */ Row [row].shared2.mark = col ; last_row = row ; } } /* === Compute row pointers ============================================= */ /* row form of the matrix starts directly after the column */ /* form of matrix in A */ Row [0].start = p [n_col] ; Row [0].shared1.p = Row [0].start ; Row [0].shared2.mark = -1 ; for (row = 1 ; row < n_row ; row++) { Row [row].start = Row [row-1].start + Row [row-1].length ; Row [row].shared1.p = Row [row].start ; Row [row].shared2.mark = -1 ; } /* === Create row form ================================================== */ if (stats [COLAMD_STATUS] == COLAMD_OK_BUT_JUMBLED) { /* if cols jumbled, watch for repeated row indices */ for (col = 0 ; col < n_col ; col++) { cp = &A [p [col]] ; cp_end = &A [p [col+1]] ; while (cp < cp_end) { row = *cp++ ; if (Row [row].shared2.mark != col) { A [(Row [row].shared1.p)++] = col ; Row [row].shared2.mark = col ; } } } } else { /* if cols not jumbled, we don't need the mark (this is faster) */ for (col = 0 ; col < n_col ; col++) { cp = &A [p [col]] ; cp_end = &A [p [col+1]] ; while (cp < cp_end) { A [(Row [*cp++].shared1.p)++] = col ; } } } /* === Clear the row marks and set row degrees ========================== */ for (row = 0 ; row < n_row ; row++) { Row [row].shared2.mark = 0 ; Row [row].shared1.degree = Row [row].length ; } /* === See if we need to re-create columns ============================== */ if (stats [COLAMD_STATUS] == COLAMD_OK_BUT_JUMBLED) { DEBUG0 (("colamd: reconstructing column form, matrix jumbled\n")) ; #ifndef NDEBUG /* make sure column lengths are correct */ for (col = 0 ; col < n_col ; col++) { p [col] = Col [col].length ; } for (row = 0 ; row < n_row ; row++) { rp = &A [Row [row].start] ; rp_end = rp + Row [row].length ; while (rp < rp_end) { p [*rp++]-- ; } } for (col = 0 ; col < n_col ; col++) { ASSERT (p [col] == 0) ; } /* now p is all zero (different than when debugging is turned off) */ #endif /* NDEBUG */ /* === Compute col pointers ========================================= */ /* col form of the matrix starts at A [0]. */ /* Note, we may have a gap between the col form and the row */ /* form if there were duplicate entries, if so, it will be */ /* removed upon the first garbage collection */ Col [0].start = 0 ; p [0] = Col [0].start ; for (col = 1 ; col < n_col ; col++) { /* note that the lengths here are for pruned columns, i.e. */ /* no duplicate row indices will exist for these columns */ Col [col].start = Col [col-1].start + Col [col-1].length ; p [col] = Col [col].start ; } /* === Re-create col form =========================================== */ for (row = 0 ; row < n_row ; row++) { rp = &A [Row [row].start] ; rp_end = rp + Row [row].length ; while (rp < rp_end) { A [(p [*rp++])++] = row ; } } } /* === Done. Matrix is not (or no longer) jumbled ====================== */ return (TRUE) ; } /* ========================================================================== */ /* === init_scoring ========================================================= */ /* ========================================================================== */ /* Kills dense or empty columns and rows, calculates an initial score for each column, and places all columns in the degree lists. Not user-callable. */ PRIVATE void init_scoring ( /* === Parameters ======================================================= */ Int n_row, /* number of rows of A */ Int n_col, /* number of columns of A */ Colamd_Row Row [], /* of size n_row+1 */ Colamd_Col Col [], /* of size n_col+1 */ Int A [], /* column form and row form of A */ Int head [], /* of size n_col+1 */ double knobs [COLAMD_KNOBS],/* parameters */ Int *p_n_row2, /* number of non-dense, non-empty rows */ Int *p_n_col2, /* number of non-dense, non-empty columns */ Int *p_max_deg /* maximum row degree */ ) { /* === Local variables ================================================== */ Int c ; /* a column index */ Int r, row ; /* a row index */ Int *cp ; /* a column pointer */ Int deg ; /* degree of a row or column */ Int *cp_end ; /* a pointer to the end of a column */ Int *new_cp ; /* new column pointer */ Int col_length ; /* length of pruned column */ Int score ; /* current column score */ Int n_col2 ; /* number of non-dense, non-empty columns */ Int n_row2 ; /* number of non-dense, non-empty rows */ Int dense_row_count ; /* remove rows with more entries than this */ Int dense_col_count ; /* remove cols with more entries than this */ Int min_score ; /* smallest column score */ Int max_deg ; /* maximum row degree */ Int next_col ; /* Used to add to degree list.*/ #ifndef NDEBUG Int debug_count ; /* debug only. */ #endif /* NDEBUG */ /* === Extract knobs ==================================================== */ /* Note: if knobs contains a NaN, this is undefined: */ if (knobs [COLAMD_DENSE_ROW] < 0) { /* only remove completely dense rows */ dense_row_count = n_col-1 ; } else { dense_row_count = DENSE_DEGREE (knobs [COLAMD_DENSE_ROW], n_col) ; } if (knobs [COLAMD_DENSE_COL] < 0) { /* only remove completely dense columns */ dense_col_count = n_row-1 ; } else { dense_col_count = DENSE_DEGREE (knobs [COLAMD_DENSE_COL], MIN (n_row, n_col)) ; } DEBUG1 (("colamd: densecount: %d %d\n", dense_row_count, dense_col_count)) ; max_deg = 0 ; n_col2 = n_col ; n_row2 = n_row ; /* === Kill empty columns =============================================== */ /* Put the empty columns at the end in their natural order, so that LU */ /* factorization can proceed as far as possible. */ for (c = n_col-1 ; c >= 0 ; c--) { deg = Col [c].length ; if (deg == 0) { /* this is a empty column, kill and order it last */ Col [c].shared2.order = --n_col2 ; KILL_PRINCIPAL_COL (c) ; } } DEBUG1 (("colamd: null columns killed: %d\n", n_col - n_col2)) ; /* === Kill dense columns =============================================== */ /* Put the dense columns at the end, in their natural order */ for (c = n_col-1 ; c >= 0 ; c--) { /* skip any dead columns */ if (COL_IS_DEAD (c)) { continue ; } deg = Col [c].length ; if (deg > dense_col_count) { /* this is a dense column, kill and order it last */ Col [c].shared2.order = --n_col2 ; /* decrement the row degrees */ cp = &A [Col [c].start] ; cp_end = cp + Col [c].length ; while (cp < cp_end) { Row [*cp++].shared1.degree-- ; } KILL_PRINCIPAL_COL (c) ; } } DEBUG1 (("colamd: Dense and null columns killed: %d\n", n_col - n_col2)) ; /* === Kill dense and empty rows ======================================== */ for (r = 0 ; r < n_row ; r++) { deg = Row [r].shared1.degree ; ASSERT (deg >= 0 && deg <= n_col) ; if (deg > dense_row_count || deg == 0) { /* kill a dense or empty row */ KILL_ROW (r) ; --n_row2 ; } else { /* keep track of max degree of remaining rows */ max_deg = MAX (max_deg, deg) ; } } DEBUG1 (("colamd: Dense and null rows killed: %d\n", n_row - n_row2)) ; /* === Compute initial column scores ==================================== */ /* At this point the row degrees are accurate. They reflect the number */ /* of "live" (non-dense) columns in each row. No empty rows exist. */ /* Some "live" columns may contain only dead rows, however. These are */ /* pruned in the code below. */ /* now find the initial matlab score for each column */ for (c = n_col-1 ; c >= 0 ; c--) { /* skip dead column */ if (COL_IS_DEAD (c)) { continue ; } score = 0 ; cp = &A [Col [c].start] ; new_cp = cp ; cp_end = cp + Col [c].length ; while (cp < cp_end) { /* get a row */ row = *cp++ ; /* skip if dead */ if (ROW_IS_DEAD (row)) { continue ; } /* compact the column */ *new_cp++ = row ; /* add row's external degree */ score += Row [row].shared1.degree - 1 ; /* guard against integer overflow */ score = MIN (score, n_col) ; } /* determine pruned column length */ col_length = (Int) (new_cp - &A [Col [c].start]) ; if (col_length == 0) { /* a newly-made null column (all rows in this col are "dense" */ /* and have already been killed) */ DEBUG2 (("Newly null killed: %d\n", c)) ; Col [c].shared2.order = --n_col2 ; KILL_PRINCIPAL_COL (c) ; } else { /* set column length and set score */ ASSERT (score >= 0) ; ASSERT (score <= n_col) ; Col [c].length = col_length ; Col [c].shared2.score = score ; } } DEBUG1 (("colamd: Dense, null, and newly-null columns killed: %d\n", n_col-n_col2)) ; /* At this point, all empty rows and columns are dead. All live columns */ /* are "clean" (containing no dead rows) and simplicial (no supercolumns */ /* yet). Rows may contain dead columns, but all live rows contain at */ /* least one live column. */ #ifndef NDEBUG debug_structures (n_row, n_col, Row, Col, A, n_col2) ; #endif /* NDEBUG */ /* === Initialize degree lists ========================================== */ #ifndef NDEBUG debug_count = 0 ; #endif /* NDEBUG */ /* clear the hash buckets */ for (c = 0 ; c <= n_col ; c++) { head [c] = EMPTY ; } min_score = n_col ; /* place in reverse order, so low column indices are at the front */ /* of the lists. This is to encourage natural tie-breaking */ for (c = n_col-1 ; c >= 0 ; c--) { /* only add principal columns to degree lists */ if (COL_IS_ALIVE (c)) { DEBUG4 (("place %d score %d minscore %d ncol %d\n", c, Col [c].shared2.score, min_score, n_col)) ; /* === Add columns score to DList =============================== */ score = Col [c].shared2.score ; ASSERT (min_score >= 0) ; ASSERT (min_score <= n_col) ; ASSERT (score >= 0) ; ASSERT (score <= n_col) ; ASSERT (head [score] >= EMPTY) ; /* now add this column to dList at proper score location */ next_col = head [score] ; Col [c].shared3.prev = EMPTY ; Col [c].shared4.degree_next = next_col ; /* if there already was a column with the same score, set its */ /* previous pointer to this new column */ if (next_col != EMPTY) { Col [next_col].shared3.prev = c ; } head [score] = c ; /* see if this score is less than current min */ min_score = MIN (min_score, score) ; #ifndef NDEBUG debug_count++ ; #endif /* NDEBUG */ } } #ifndef NDEBUG DEBUG1 (("colamd: Live cols %d out of %d, non-princ: %d\n", debug_count, n_col, n_col-debug_count)) ; ASSERT (debug_count == n_col2) ; debug_deg_lists (n_row, n_col, Row, Col, head, min_score, n_col2, max_deg) ; #endif /* NDEBUG */ /* === Return number of remaining columns, and max row degree =========== */ *p_n_col2 = n_col2 ; *p_n_row2 = n_row2 ; *p_max_deg = max_deg ; } /* ========================================================================== */ /* === find_ordering ======================================================== */ /* ========================================================================== */ /* Order the principal columns of the supercolumn form of the matrix (no supercolumns on input). Uses a minimum approximate column minimum degree ordering method. Not user-callable. */ PRIVATE Int find_ordering /* return the number of garbage collections */ ( /* === Parameters ======================================================= */ Int n_row, /* number of rows of A */ Int n_col, /* number of columns of A */ Int Alen, /* size of A, 2*nnz + n_col or larger */ Colamd_Row Row [], /* of size n_row+1 */ Colamd_Col Col [], /* of size n_col+1 */ Int A [], /* column form and row form of A */ Int head [], /* of size n_col+1 */ Int n_col2, /* Remaining columns to order */ Int max_deg, /* Maximum row degree */ Int pfree, /* index of first free slot (2*nnz on entry) */ Int aggressive ) { /* === Local variables ================================================== */ Int k ; /* current pivot ordering step */ Int pivot_col ; /* current pivot column */ Int *cp ; /* a column pointer */ Int *rp ; /* a row pointer */ Int pivot_row ; /* current pivot row */ Int *new_cp ; /* modified column pointer */ Int *new_rp ; /* modified row pointer */ Int pivot_row_start ; /* pointer to start of pivot row */ Int pivot_row_degree ; /* number of columns in pivot row */ Int pivot_row_length ; /* number of supercolumns in pivot row */ Int pivot_col_score ; /* score of pivot column */ Int needed_memory ; /* free space needed for pivot row */ Int *cp_end ; /* pointer to the end of a column */ Int *rp_end ; /* pointer to the end of a row */ Int row ; /* a row index */ Int col ; /* a column index */ Int max_score ; /* maximum possible score */ Int cur_score ; /* score of current column */ unsigned Int hash ; /* hash value for supernode detection */ Int head_column ; /* head of hash bucket */ Int first_col ; /* first column in hash bucket */ Int tag_mark ; /* marker value for mark array */ Int row_mark ; /* Row [row].shared2.mark */ Int set_difference ; /* set difference size of row with pivot row */ Int min_score ; /* smallest column score */ Int col_thickness ; /* "thickness" (no. of columns in a supercol) */ Int max_mark ; /* maximum value of tag_mark */ Int pivot_col_thickness ; /* number of columns represented by pivot col */ Int prev_col ; /* Used by Dlist operations. */ Int next_col ; /* Used by Dlist operations. */ Int ngarbage ; /* number of garbage collections performed */ #ifndef NDEBUG Int debug_d ; /* debug loop counter */ Int debug_step = 0 ; /* debug loop counter */ #endif /* NDEBUG */ /* === Initialization and clear mark ==================================== */ max_mark = INT_MAX - n_col ; /* INT_MAX defined in */ tag_mark = clear_mark (0, max_mark, n_row, Row) ; min_score = 0 ; ngarbage = 0 ; DEBUG1 (("colamd: Ordering, n_col2=%d\n", n_col2)) ; /* === Order the columns ================================================ */ for (k = 0 ; k < n_col2 ; /* 'k' is incremented below */) { #ifndef NDEBUG if (debug_step % 100 == 0) { DEBUG2 (("\n... Step k: %d out of n_col2: %d\n", k, n_col2)) ; } else { DEBUG3 (("\n----------Step k: %d out of n_col2: %d\n", k, n_col2)) ; } debug_step++ ; debug_deg_lists (n_row, n_col, Row, Col, head, min_score, n_col2-k, max_deg) ; debug_matrix (n_row, n_col, Row, Col, A) ; #endif /* NDEBUG */ /* === Select pivot column, and order it ============================ */ /* make sure degree list isn't empty */ ASSERT (min_score >= 0) ; ASSERT (min_score <= n_col) ; ASSERT (head [min_score] >= EMPTY) ; #ifndef NDEBUG for (debug_d = 0 ; debug_d < min_score ; debug_d++) { ASSERT (head [debug_d] == EMPTY) ; } #endif /* NDEBUG */ /* get pivot column from head of minimum degree list */ while (head [min_score] == EMPTY && min_score < n_col) { min_score++ ; } pivot_col = head [min_score] ; ASSERT (pivot_col >= 0 && pivot_col <= n_col) ; next_col = Col [pivot_col].shared4.degree_next ; head [min_score] = next_col ; if (next_col != EMPTY) { Col [next_col].shared3.prev = EMPTY ; } ASSERT (COL_IS_ALIVE (pivot_col)) ; /* remember score for defrag check */ pivot_col_score = Col [pivot_col].shared2.score ; /* the pivot column is the kth column in the pivot order */ Col [pivot_col].shared2.order = k ; /* increment order count by column thickness */ pivot_col_thickness = Col [pivot_col].shared1.thickness ; k += pivot_col_thickness ; ASSERT (pivot_col_thickness > 0) ; DEBUG3 (("Pivot col: %d thick %d\n", pivot_col, pivot_col_thickness)) ; /* === Garbage_collection, if necessary ============================= */ needed_memory = MIN (pivot_col_score, n_col - k) ; if (pfree + needed_memory >= Alen) { pfree = garbage_collection (n_row, n_col, Row, Col, A, &A [pfree]) ; ngarbage++ ; /* after garbage collection we will have enough */ ASSERT (pfree + needed_memory < Alen) ; /* garbage collection has wiped out the Row[].shared2.mark array */ tag_mark = clear_mark (0, max_mark, n_row, Row) ; #ifndef NDEBUG debug_matrix (n_row, n_col, Row, Col, A) ; #endif /* NDEBUG */ } /* === Compute pivot row pattern ==================================== */ /* get starting location for this new merged row */ pivot_row_start = pfree ; /* initialize new row counts to zero */ pivot_row_degree = 0 ; /* tag pivot column as having been visited so it isn't included */ /* in merged pivot row */ Col [pivot_col].shared1.thickness = -pivot_col_thickness ; /* pivot row is the union of all rows in the pivot column pattern */ cp = &A [Col [pivot_col].start] ; cp_end = cp + Col [pivot_col].length ; while (cp < cp_end) { /* get a row */ row = *cp++ ; DEBUG4 (("Pivot col pattern %d %d\n", ROW_IS_ALIVE (row), row)) ; /* skip if row is dead */ if (ROW_IS_ALIVE (row)) { rp = &A [Row [row].start] ; rp_end = rp + Row [row].length ; while (rp < rp_end) { /* get a column */ col = *rp++ ; /* add the column, if alive and untagged */ col_thickness = Col [col].shared1.thickness ; if (col_thickness > 0 && COL_IS_ALIVE (col)) { /* tag column in pivot row */ Col [col].shared1.thickness = -col_thickness ; ASSERT (pfree < Alen) ; /* place column in pivot row */ A [pfree++] = col ; pivot_row_degree += col_thickness ; } } } } /* clear tag on pivot column */ Col [pivot_col].shared1.thickness = pivot_col_thickness ; max_deg = MAX (max_deg, pivot_row_degree) ; #ifndef NDEBUG DEBUG3 (("check2\n")) ; debug_mark (n_row, Row, tag_mark, max_mark) ; #endif /* NDEBUG */ /* === Kill all rows used to construct pivot row ==================== */ /* also kill pivot row, temporarily */ cp = &A [Col [pivot_col].start] ; cp_end = cp + Col [pivot_col].length ; while (cp < cp_end) { /* may be killing an already dead row */ row = *cp++ ; DEBUG3 (("Kill row in pivot col: %d\n", row)) ; KILL_ROW (row) ; } /* === Select a row index to use as the new pivot row =============== */ pivot_row_length = pfree - pivot_row_start ; if (pivot_row_length > 0) { /* pick the "pivot" row arbitrarily (first row in col) */ pivot_row = A [Col [pivot_col].start] ; DEBUG3 (("Pivotal row is %d\n", pivot_row)) ; } else { /* there is no pivot row, since it is of zero length */ pivot_row = EMPTY ; ASSERT (pivot_row_length == 0) ; } ASSERT (Col [pivot_col].length > 0 || pivot_row_length == 0) ; /* === Approximate degree computation =============================== */ /* Here begins the computation of the approximate degree. The column */ /* score is the sum of the pivot row "length", plus the size of the */ /* set differences of each row in the column minus the pattern of the */ /* pivot row itself. The column ("thickness") itself is also */ /* excluded from the column score (we thus use an approximate */ /* external degree). */ /* The time taken by the following code (compute set differences, and */ /* add them up) is proportional to the size of the data structure */ /* being scanned - that is, the sum of the sizes of each column in */ /* the pivot row. Thus, the amortized time to compute a column score */ /* is proportional to the size of that column (where size, in this */ /* context, is the column "length", or the number of row indices */ /* in that column). The number of row indices in a column is */ /* monotonically non-decreasing, from the length of the original */ /* column on input to colamd. */ /* === Compute set differences ====================================== */ DEBUG3 (("** Computing set differences phase. **\n")) ; /* pivot row is currently dead - it will be revived later. */ DEBUG3 (("Pivot row: ")) ; /* for each column in pivot row */ rp = &A [pivot_row_start] ; rp_end = rp + pivot_row_length ; while (rp < rp_end) { col = *rp++ ; ASSERT (COL_IS_ALIVE (col) && col != pivot_col) ; DEBUG3 (("Col: %d\n", col)) ; /* clear tags used to construct pivot row pattern */ col_thickness = -Col [col].shared1.thickness ; ASSERT (col_thickness > 0) ; Col [col].shared1.thickness = col_thickness ; /* === Remove column from degree list =========================== */ cur_score = Col [col].shared2.score ; prev_col = Col [col].shared3.prev ; next_col = Col [col].shared4.degree_next ; ASSERT (cur_score >= 0) ; ASSERT (cur_score <= n_col) ; ASSERT (cur_score >= EMPTY) ; if (prev_col == EMPTY) { head [cur_score] = next_col ; } else { Col [prev_col].shared4.degree_next = next_col ; } if (next_col != EMPTY) { Col [next_col].shared3.prev = prev_col ; } /* === Scan the column ========================================== */ cp = &A [Col [col].start] ; cp_end = cp + Col [col].length ; while (cp < cp_end) { /* get a row */ row = *cp++ ; row_mark = Row [row].shared2.mark ; /* skip if dead */ if (ROW_IS_MARKED_DEAD (row_mark)) { continue ; } ASSERT (row != pivot_row) ; set_difference = row_mark - tag_mark ; /* check if the row has been seen yet */ if (set_difference < 0) { ASSERT (Row [row].shared1.degree <= max_deg) ; set_difference = Row [row].shared1.degree ; } /* subtract column thickness from this row's set difference */ set_difference -= col_thickness ; ASSERT (set_difference >= 0) ; /* absorb this row if the set difference becomes zero */ if (set_difference == 0 && aggressive) { DEBUG3 (("aggressive absorption. Row: %d\n", row)) ; KILL_ROW (row) ; } else { /* save the new mark */ Row [row].shared2.mark = set_difference + tag_mark ; } } } #ifndef NDEBUG debug_deg_lists (n_row, n_col, Row, Col, head, min_score, n_col2-k-pivot_row_degree, max_deg) ; #endif /* NDEBUG */ /* === Add up set differences for each column ======================= */ DEBUG3 (("** Adding set differences phase. **\n")) ; /* for each column in pivot row */ rp = &A [pivot_row_start] ; rp_end = rp + pivot_row_length ; while (rp < rp_end) { /* get a column */ col = *rp++ ; ASSERT (COL_IS_ALIVE (col) && col != pivot_col) ; hash = 0 ; cur_score = 0 ; cp = &A [Col [col].start] ; /* compact the column */ new_cp = cp ; cp_end = cp + Col [col].length ; DEBUG4 (("Adding set diffs for Col: %d.\n", col)) ; while (cp < cp_end) { /* get a row */ row = *cp++ ; ASSERT(row >= 0 && row < n_row) ; row_mark = Row [row].shared2.mark ; /* skip if dead */ if (ROW_IS_MARKED_DEAD (row_mark)) { DEBUG4 ((" Row %d, dead\n", row)) ; continue ; } DEBUG4 ((" Row %d, set diff %d\n", row, row_mark-tag_mark)); ASSERT (row_mark >= tag_mark) ; /* compact the column */ *new_cp++ = row ; /* compute hash function */ hash += row ; /* add set difference */ cur_score += row_mark - tag_mark ; /* integer overflow... */ cur_score = MIN (cur_score, n_col) ; } /* recompute the column's length */ Col [col].length = (Int) (new_cp - &A [Col [col].start]) ; /* === Further mass elimination ================================= */ if (Col [col].length == 0) { DEBUG4 (("further mass elimination. Col: %d\n", col)) ; /* nothing left but the pivot row in this column */ KILL_PRINCIPAL_COL (col) ; pivot_row_degree -= Col [col].shared1.thickness ; ASSERT (pivot_row_degree >= 0) ; /* order it */ Col [col].shared2.order = k ; /* increment order count by column thickness */ k += Col [col].shared1.thickness ; } else { /* === Prepare for supercolumn detection ==================== */ DEBUG4 (("Preparing supercol detection for Col: %d.\n", col)) ; /* save score so far */ Col [col].shared2.score = cur_score ; /* add column to hash table, for supercolumn detection */ hash %= n_col + 1 ; DEBUG4 ((" Hash = %d, n_col = %d.\n", hash, n_col)) ; ASSERT (((Int) hash) <= n_col) ; head_column = head [hash] ; if (head_column > EMPTY) { /* degree list "hash" is non-empty, use prev (shared3) of */ /* first column in degree list as head of hash bucket */ first_col = Col [head_column].shared3.headhash ; Col [head_column].shared3.headhash = col ; } else { /* degree list "hash" is empty, use head as hash bucket */ first_col = - (head_column + 2) ; head [hash] = - (col + 2) ; } Col [col].shared4.hash_next = first_col ; /* save hash function in Col [col].shared3.hash */ Col [col].shared3.hash = (Int) hash ; ASSERT (COL_IS_ALIVE (col)) ; } } /* The approximate external column degree is now computed. */ /* === Supercolumn detection ======================================== */ DEBUG3 (("** Supercolumn detection phase. **\n")) ; detect_super_cols ( #ifndef NDEBUG n_col, Row, #endif /* NDEBUG */ Col, A, head, pivot_row_start, pivot_row_length) ; /* === Kill the pivotal column ====================================== */ KILL_PRINCIPAL_COL (pivot_col) ; /* === Clear mark =================================================== */ tag_mark = clear_mark (tag_mark+max_deg+1, max_mark, n_row, Row) ; #ifndef NDEBUG DEBUG3 (("check3\n")) ; debug_mark (n_row, Row, tag_mark, max_mark) ; #endif /* NDEBUG */ /* === Finalize the new pivot row, and column scores ================ */ DEBUG3 (("** Finalize scores phase. **\n")) ; /* for each column in pivot row */ rp = &A [pivot_row_start] ; /* compact the pivot row */ new_rp = rp ; rp_end = rp + pivot_row_length ; while (rp < rp_end) { col = *rp++ ; /* skip dead columns */ if (COL_IS_DEAD (col)) { continue ; } *new_rp++ = col ; /* add new pivot row to column */ A [Col [col].start + (Col [col].length++)] = pivot_row ; /* retrieve score so far and add on pivot row's degree. */ /* (we wait until here for this in case the pivot */ /* row's degree was reduced due to mass elimination). */ cur_score = Col [col].shared2.score + pivot_row_degree ; /* calculate the max possible score as the number of */ /* external columns minus the 'k' value minus the */ /* columns thickness */ max_score = n_col - k - Col [col].shared1.thickness ; /* make the score the external degree of the union-of-rows */ cur_score -= Col [col].shared1.thickness ; /* make sure score is less or equal than the max score */ cur_score = MIN (cur_score, max_score) ; ASSERT (cur_score >= 0) ; /* store updated score */ Col [col].shared2.score = cur_score ; /* === Place column back in degree list ========================= */ ASSERT (min_score >= 0) ; ASSERT (min_score <= n_col) ; ASSERT (cur_score >= 0) ; ASSERT (cur_score <= n_col) ; ASSERT (head [cur_score] >= EMPTY) ; next_col = head [cur_score] ; Col [col].shared4.degree_next = next_col ; Col [col].shared3.prev = EMPTY ; if (next_col != EMPTY) { Col [next_col].shared3.prev = col ; } head [cur_score] = col ; /* see if this score is less than current min */ min_score = MIN (min_score, cur_score) ; } #ifndef NDEBUG debug_deg_lists (n_row, n_col, Row, Col, head, min_score, n_col2-k, max_deg) ; #endif /* NDEBUG */ /* === Resurrect the new pivot row ================================== */ if (pivot_row_degree > 0) { /* update pivot row length to reflect any cols that were killed */ /* during super-col detection and mass elimination */ Row [pivot_row].start = pivot_row_start ; Row [pivot_row].length = (Int) (new_rp - &A[pivot_row_start]) ; ASSERT (Row [pivot_row].length > 0) ; Row [pivot_row].shared1.degree = pivot_row_degree ; Row [pivot_row].shared2.mark = 0 ; /* pivot row is no longer dead */ DEBUG1 (("Resurrect Pivot_row %d deg: %d\n", pivot_row, pivot_row_degree)) ; } } /* === All principal columns have now been ordered ====================== */ return (ngarbage) ; } /* ========================================================================== */ /* === order_children ======================================================= */ /* ========================================================================== */ /* The find_ordering routine has ordered all of the principal columns (the representatives of the supercolumns). The non-principal columns have not yet been ordered. This routine orders those columns by walking up the parent tree (a column is a child of the column which absorbed it). The final permutation vector is then placed in p [0 ... n_col-1], with p [0] being the first column, and p [n_col-1] being the last. It doesn't look like it at first glance, but be assured that this routine takes time linear in the number of columns. Although not immediately obvious, the time taken by this routine is O (n_col), that is, linear in the number of columns. Not user-callable. */ PRIVATE void order_children ( /* === Parameters ======================================================= */ Int n_col, /* number of columns of A */ Colamd_Col Col [], /* of size n_col+1 */ Int p [] /* p [0 ... n_col-1] is the column permutation*/ ) { /* === Local variables ================================================== */ Int i ; /* loop counter for all columns */ Int c ; /* column index */ Int parent ; /* index of column's parent */ Int order ; /* column's order */ /* === Order each non-principal column ================================== */ for (i = 0 ; i < n_col ; i++) { /* find an un-ordered non-principal column */ ASSERT (COL_IS_DEAD (i)) ; if (!COL_IS_DEAD_PRINCIPAL (i) && Col [i].shared2.order == EMPTY) { parent = i ; /* once found, find its principal parent */ do { parent = Col [parent].shared1.parent ; } while (!COL_IS_DEAD_PRINCIPAL (parent)) ; /* now, order all un-ordered non-principal columns along path */ /* to this parent. collapse tree at the same time */ c = i ; /* get order of parent */ order = Col [parent].shared2.order ; do { ASSERT (Col [c].shared2.order == EMPTY) ; /* order this column */ Col [c].shared2.order = order++ ; /* collaps tree */ Col [c].shared1.parent = parent ; /* get immediate parent of this column */ c = Col [c].shared1.parent ; /* continue until we hit an ordered column. There are */ /* guarranteed not to be anymore unordered columns */ /* above an ordered column */ } while (Col [c].shared2.order == EMPTY) ; /* re-order the super_col parent to largest order for this group */ Col [parent].shared2.order = order ; } } /* === Generate the permutation ========================================= */ for (c = 0 ; c < n_col ; c++) { p [Col [c].shared2.order] = c ; } } /* ========================================================================== */ /* === detect_super_cols ==================================================== */ /* ========================================================================== */ /* Detects supercolumns by finding matches between columns in the hash buckets. Check amongst columns in the set A [row_start ... row_start + row_length-1]. The columns under consideration are currently *not* in the degree lists, and have already been placed in the hash buckets. The hash bucket for columns whose hash function is equal to h is stored as follows: if head [h] is >= 0, then head [h] contains a degree list, so: head [h] is the first column in degree bucket h. Col [head [h]].headhash gives the first column in hash bucket h. otherwise, the degree list is empty, and: -(head [h] + 2) is the first column in hash bucket h. For a column c in a hash bucket, Col [c].shared3.prev is NOT a "previous column" pointer. Col [c].shared3.hash is used instead as the hash number for that column. The value of Col [c].shared4.hash_next is the next column in the same hash bucket. Assuming no, or "few" hash collisions, the time taken by this routine is linear in the sum of the sizes (lengths) of each column whose score has just been computed in the approximate degree computation. Not user-callable. */ PRIVATE void detect_super_cols ( /* === Parameters ======================================================= */ #ifndef NDEBUG /* these two parameters are only needed when debugging is enabled: */ Int n_col, /* number of columns of A */ Colamd_Row Row [], /* of size n_row+1 */ #endif /* NDEBUG */ Colamd_Col Col [], /* of size n_col+1 */ Int A [], /* row indices of A */ Int head [], /* head of degree lists and hash buckets */ Int row_start, /* pointer to set of columns to check */ Int row_length /* number of columns to check */ ) { /* === Local variables ================================================== */ Int hash ; /* hash value for a column */ Int *rp ; /* pointer to a row */ Int c ; /* a column index */ Int super_c ; /* column index of the column to absorb into */ Int *cp1 ; /* column pointer for column super_c */ Int *cp2 ; /* column pointer for column c */ Int length ; /* length of column super_c */ Int prev_c ; /* column preceding c in hash bucket */ Int i ; /* loop counter */ Int *rp_end ; /* pointer to the end of the row */ Int col ; /* a column index in the row to check */ Int head_column ; /* first column in hash bucket or degree list */ Int first_col ; /* first column in hash bucket */ /* === Consider each column in the row ================================== */ rp = &A [row_start] ; rp_end = rp + row_length ; while (rp < rp_end) { col = *rp++ ; if (COL_IS_DEAD (col)) { continue ; } /* get hash number for this column */ hash = Col [col].shared3.hash ; ASSERT (hash <= n_col) ; /* === Get the first column in this hash bucket ===================== */ head_column = head [hash] ; if (head_column > EMPTY) { first_col = Col [head_column].shared3.headhash ; } else { first_col = - (head_column + 2) ; } /* === Consider each column in the hash bucket ====================== */ for (super_c = first_col ; super_c != EMPTY ; super_c = Col [super_c].shared4.hash_next) { ASSERT (COL_IS_ALIVE (super_c)) ; ASSERT (Col [super_c].shared3.hash == hash) ; length = Col [super_c].length ; /* prev_c is the column preceding column c in the hash bucket */ prev_c = super_c ; /* === Compare super_c with all columns after it ================ */ for (c = Col [super_c].shared4.hash_next ; c != EMPTY ; c = Col [c].shared4.hash_next) { ASSERT (c != super_c) ; ASSERT (COL_IS_ALIVE (c)) ; ASSERT (Col [c].shared3.hash == hash) ; /* not identical if lengths or scores are different */ if (Col [c].length != length || Col [c].shared2.score != Col [super_c].shared2.score) { prev_c = c ; continue ; } /* compare the two columns */ cp1 = &A [Col [super_c].start] ; cp2 = &A [Col [c].start] ; for (i = 0 ; i < length ; i++) { /* the columns are "clean" (no dead rows) */ ASSERT (ROW_IS_ALIVE (*cp1)) ; ASSERT (ROW_IS_ALIVE (*cp2)) ; /* row indices will same order for both supercols, */ /* no gather scatter nessasary */ if (*cp1++ != *cp2++) { break ; } } /* the two columns are different if the for-loop "broke" */ if (i != length) { prev_c = c ; continue ; } /* === Got it! two columns are identical =================== */ ASSERT (Col [c].shared2.score == Col [super_c].shared2.score) ; Col [super_c].shared1.thickness += Col [c].shared1.thickness ; Col [c].shared1.parent = super_c ; KILL_NON_PRINCIPAL_COL (c) ; /* order c later, in order_children() */ Col [c].shared2.order = EMPTY ; /* remove c from hash bucket */ Col [prev_c].shared4.hash_next = Col [c].shared4.hash_next ; } } /* === Empty this hash bucket ======================================= */ if (head_column > EMPTY) { /* corresponding degree list "hash" is not empty */ Col [head_column].shared3.headhash = EMPTY ; } else { /* corresponding degree list "hash" is empty */ head [hash] = EMPTY ; } } } /* ========================================================================== */ /* === garbage_collection =================================================== */ /* ========================================================================== */ /* Defragments and compacts columns and rows in the workspace A. Used when all avaliable memory has been used while performing row merging. Returns the index of the first free position in A, after garbage collection. The time taken by this routine is linear is the size of the array A, which is itself linear in the number of nonzeros in the input matrix. Not user-callable. */ PRIVATE Int garbage_collection /* returns the new value of pfree */ ( /* === Parameters ======================================================= */ Int n_row, /* number of rows */ Int n_col, /* number of columns */ Colamd_Row Row [], /* row info */ Colamd_Col Col [], /* column info */ Int A [], /* A [0 ... Alen-1] holds the matrix */ Int *pfree /* &A [0] ... pfree is in use */ ) { /* === Local variables ================================================== */ Int *psrc ; /* source pointer */ Int *pdest ; /* destination pointer */ Int j ; /* counter */ Int r ; /* a row index */ Int c ; /* a column index */ Int length ; /* length of a row or column */ #ifndef NDEBUG Int debug_rows ; DEBUG2 (("Defrag..\n")) ; for (psrc = &A[0] ; psrc < pfree ; psrc++) ASSERT (*psrc >= 0) ; debug_rows = 0 ; #endif /* NDEBUG */ /* === Defragment the columns =========================================== */ pdest = &A[0] ; for (c = 0 ; c < n_col ; c++) { if (COL_IS_ALIVE (c)) { psrc = &A [Col [c].start] ; /* move and compact the column */ ASSERT (pdest <= psrc) ; Col [c].start = (Int) (pdest - &A [0]) ; length = Col [c].length ; for (j = 0 ; j < length ; j++) { r = *psrc++ ; if (ROW_IS_ALIVE (r)) { *pdest++ = r ; } } Col [c].length = (Int) (pdest - &A [Col [c].start]) ; } } /* === Prepare to defragment the rows =================================== */ for (r = 0 ; r < n_row ; r++) { if (ROW_IS_DEAD (r) || (Row [r].length == 0)) { /* This row is already dead, or is of zero length. Cannot compact * a row of zero length, so kill it. NOTE: in the current version, * there are no zero-length live rows. Kill the row (for the first * time, or again) just to be safe. */ KILL_ROW (r) ; } else { /* save first column index in Row [r].shared2.first_column */ psrc = &A [Row [r].start] ; Row [r].shared2.first_column = *psrc ; ASSERT (ROW_IS_ALIVE (r)) ; /* flag the start of the row with the one's complement of row */ *psrc = ONES_COMPLEMENT (r) ; #ifndef NDEBUG debug_rows++ ; #endif /* NDEBUG */ } } /* === Defragment the rows ============================================== */ psrc = pdest ; while (psrc < pfree) { /* find a negative number ... the start of a row */ if (*psrc++ < 0) { psrc-- ; /* get the row index */ r = ONES_COMPLEMENT (*psrc) ; ASSERT (r >= 0 && r < n_row) ; /* restore first column index */ *psrc = Row [r].shared2.first_column ; ASSERT (ROW_IS_ALIVE (r)) ; ASSERT (Row [r].length > 0) ; /* move and compact the row */ ASSERT (pdest <= psrc) ; Row [r].start = (Int) (pdest - &A [0]) ; length = Row [r].length ; for (j = 0 ; j < length ; j++) { c = *psrc++ ; if (COL_IS_ALIVE (c)) { *pdest++ = c ; } } Row [r].length = (Int) (pdest - &A [Row [r].start]) ; ASSERT (Row [r].length > 0) ; #ifndef NDEBUG debug_rows-- ; #endif /* NDEBUG */ } } /* ensure we found all the rows */ ASSERT (debug_rows == 0) ; /* === Return the new value of pfree ==================================== */ return ((Int) (pdest - &A [0])) ; } /* ========================================================================== */ /* === clear_mark =========================================================== */ /* ========================================================================== */ /* Clears the Row [].shared2.mark array, and returns the new tag_mark. Return value is the new tag_mark. Not user-callable. */ PRIVATE Int clear_mark /* return the new value for tag_mark */ ( /* === Parameters ======================================================= */ Int tag_mark, /* new value of tag_mark */ Int max_mark, /* max allowed value of tag_mark */ Int n_row, /* number of rows in A */ Colamd_Row Row [] /* Row [0 ... n_row-1].shared2.mark is set to zero */ ) { /* === Local variables ================================================== */ Int r ; if (tag_mark <= 0 || tag_mark >= max_mark) { for (r = 0 ; r < n_row ; r++) { if (ROW_IS_ALIVE (r)) { Row [r].shared2.mark = 0 ; } } tag_mark = 1 ; } return (tag_mark) ; } /* ========================================================================== */ /* === print_report ========================================================= */ /* ========================================================================== */ PRIVATE void print_report ( char *method, Int stats [COLAMD_STATS] ) { Int i1, i2, i3 ; SUITESPARSE_PRINTF (("\n%s version %d.%d, %s: ", method, COLAMD_MAIN_VERSION, COLAMD_SUB_VERSION, COLAMD_DATE)) ; if (!stats) { SUITESPARSE_PRINTF (("No statistics available.\n")) ; return ; } i1 = stats [COLAMD_INFO1] ; i2 = stats [COLAMD_INFO2] ; i3 = stats [COLAMD_INFO3] ; if (stats [COLAMD_STATUS] >= 0) { SUITESPARSE_PRINTF (("OK. ")) ; } else { SUITESPARSE_PRINTF (("ERROR. ")) ; } switch (stats [COLAMD_STATUS]) { case COLAMD_OK_BUT_JUMBLED: SUITESPARSE_PRINTF(( "Matrix has unsorted or duplicate row indices.\n")) ; SUITESPARSE_PRINTF(( "%s: number of duplicate or out-of-order row indices: %d\n", method, i3)) ; SUITESPARSE_PRINTF(( "%s: last seen duplicate or out-of-order row index: %d\n", method, INDEX (i2))) ; SUITESPARSE_PRINTF(( "%s: last seen in column: %d", method, INDEX (i1))) ; /* no break - fall through to next case instead */ case COLAMD_OK: SUITESPARSE_PRINTF(("\n")) ; SUITESPARSE_PRINTF(( "%s: number of dense or empty rows ignored: %d\n", method, stats [COLAMD_DENSE_ROW])) ; SUITESPARSE_PRINTF(( "%s: number of dense or empty columns ignored: %d\n", method, stats [COLAMD_DENSE_COL])) ; SUITESPARSE_PRINTF(( "%s: number of garbage collections performed: %d\n", method, stats [COLAMD_DEFRAG_COUNT])) ; break ; case COLAMD_ERROR_A_not_present: SUITESPARSE_PRINTF(( "Array A (row indices of matrix) not present.\n")) ; break ; case COLAMD_ERROR_p_not_present: SUITESPARSE_PRINTF(( "Array p (column pointers for matrix) not present.\n")) ; break ; case COLAMD_ERROR_nrow_negative: SUITESPARSE_PRINTF(("Invalid number of rows (%d).\n", i1)) ; break ; case COLAMD_ERROR_ncol_negative: SUITESPARSE_PRINTF(("Invalid number of columns (%d).\n", i1)) ; break ; case COLAMD_ERROR_nnz_negative: SUITESPARSE_PRINTF(( "Invalid number of nonzero entries (%d).\n", i1)) ; break ; case COLAMD_ERROR_p0_nonzero: SUITESPARSE_PRINTF(( "Invalid column pointer, p [0] = %d, must be zero.\n", i1)); break ; case COLAMD_ERROR_A_too_small: SUITESPARSE_PRINTF(("Array A too small.\n")) ; SUITESPARSE_PRINTF(( " Need Alen >= %d, but given only Alen = %d.\n", i1, i2)) ; break ; case COLAMD_ERROR_col_length_negative: SUITESPARSE_PRINTF (("Column %d has a negative number of nonzero entries (%d).\n", INDEX (i1), i2)) ; break ; case COLAMD_ERROR_row_index_out_of_bounds: SUITESPARSE_PRINTF (("Row index (row %d) out of bounds (%d to %d) in column %d.\n", INDEX (i2), INDEX (0), INDEX (i3-1), INDEX (i1))) ; break ; case COLAMD_ERROR_out_of_memory: SUITESPARSE_PRINTF(("Out of memory.\n")) ; break ; /* v2.4: internal-error case deleted */ } } /* ========================================================================== */ /* === colamd debugging routines ============================================ */ /* ========================================================================== */ /* When debugging is disabled, the remainder of this file is ignored. */ #ifndef NDEBUG /* ========================================================================== */ /* === debug_structures ===================================================== */ /* ========================================================================== */ /* At this point, all empty rows and columns are dead. All live columns are "clean" (containing no dead rows) and simplicial (no supercolumns yet). Rows may contain dead columns, but all live rows contain at least one live column. */ PRIVATE void debug_structures ( /* === Parameters ======================================================= */ Int n_row, Int n_col, Colamd_Row Row [], Colamd_Col Col [], Int A [], Int n_col2 ) { /* === Local variables ================================================== */ Int i ; Int c ; Int *cp ; Int *cp_end ; Int len ; Int score ; Int r ; Int *rp ; Int *rp_end ; Int deg ; /* === Check A, Row, and Col ============================================ */ for (c = 0 ; c < n_col ; c++) { if (COL_IS_ALIVE (c)) { len = Col [c].length ; score = Col [c].shared2.score ; DEBUG4 (("initial live col %5d %5d %5d\n", c, len, score)) ; ASSERT (len > 0) ; ASSERT (score >= 0) ; ASSERT (Col [c].shared1.thickness == 1) ; cp = &A [Col [c].start] ; cp_end = cp + len ; while (cp < cp_end) { r = *cp++ ; ASSERT (ROW_IS_ALIVE (r)) ; } } else { i = Col [c].shared2.order ; ASSERT (i >= n_col2 && i < n_col) ; } } for (r = 0 ; r < n_row ; r++) { if (ROW_IS_ALIVE (r)) { i = 0 ; len = Row [r].length ; deg = Row [r].shared1.degree ; ASSERT (len > 0) ; ASSERT (deg > 0) ; rp = &A [Row [r].start] ; rp_end = rp + len ; while (rp < rp_end) { c = *rp++ ; if (COL_IS_ALIVE (c)) { i++ ; } } ASSERT (i > 0) ; } } } /* ========================================================================== */ /* === debug_deg_lists ====================================================== */ /* ========================================================================== */ /* Prints the contents of the degree lists. Counts the number of columns in the degree list and compares it to the total it should have. Also checks the row degrees. */ PRIVATE void debug_deg_lists ( /* === Parameters ======================================================= */ Int n_row, Int n_col, Colamd_Row Row [], Colamd_Col Col [], Int head [], Int min_score, Int should, Int max_deg ) { /* === Local variables ================================================== */ Int deg ; Int col ; Int have ; Int row ; /* === Check the degree lists =========================================== */ if (n_col > 10000 && colamd_debug <= 0) { return ; } have = 0 ; DEBUG4 (("Degree lists: %d\n", min_score)) ; for (deg = 0 ; deg <= n_col ; deg++) { col = head [deg] ; if (col == EMPTY) { continue ; } DEBUG4 (("%d:", deg)) ; while (col != EMPTY) { DEBUG4 ((" %d", col)) ; have += Col [col].shared1.thickness ; ASSERT (COL_IS_ALIVE (col)) ; col = Col [col].shared4.degree_next ; } DEBUG4 (("\n")) ; } DEBUG4 (("should %d have %d\n", should, have)) ; ASSERT (should == have) ; /* === Check the row degrees ============================================ */ if (n_row > 10000 && colamd_debug <= 0) { return ; } for (row = 0 ; row < n_row ; row++) { if (ROW_IS_ALIVE (row)) { ASSERT (Row [row].shared1.degree <= max_deg) ; } } } /* ========================================================================== */ /* === debug_mark =========================================================== */ /* ========================================================================== */ /* Ensures that the tag_mark is less that the maximum and also ensures that each entry in the mark array is less than the tag mark. */ PRIVATE void debug_mark ( /* === Parameters ======================================================= */ Int n_row, Colamd_Row Row [], Int tag_mark, Int max_mark ) { /* === Local variables ================================================== */ Int r ; /* === Check the Row marks ============================================== */ ASSERT (tag_mark > 0 && tag_mark <= max_mark) ; if (n_row > 10000 && colamd_debug <= 0) { return ; } for (r = 0 ; r < n_row ; r++) { ASSERT (Row [r].shared2.mark < tag_mark) ; } } /* ========================================================================== */ /* === debug_matrix ========================================================= */ /* ========================================================================== */ /* Prints out the contents of the columns and the rows. */ PRIVATE void debug_matrix ( /* === Parameters ======================================================= */ Int n_row, Int n_col, Colamd_Row Row [], Colamd_Col Col [], Int A [] ) { /* === Local variables ================================================== */ Int r ; Int c ; Int *rp ; Int *rp_end ; Int *cp ; Int *cp_end ; /* === Dump the rows and columns of the matrix ========================== */ if (colamd_debug < 3) { return ; } DEBUG3 (("DUMP MATRIX:\n")) ; for (r = 0 ; r < n_row ; r++) { DEBUG3 (("Row %d alive? %d\n", r, ROW_IS_ALIVE (r))) ; if (ROW_IS_DEAD (r)) { continue ; } DEBUG3 (("start %d length %d degree %d\n", Row [r].start, Row [r].length, Row [r].shared1.degree)) ; rp = &A [Row [r].start] ; rp_end = rp + Row [r].length ; while (rp < rp_end) { c = *rp++ ; DEBUG4 ((" %d col %d\n", COL_IS_ALIVE (c), c)) ; } } for (c = 0 ; c < n_col ; c++) { DEBUG3 (("Col %d alive? %d\n", c, COL_IS_ALIVE (c))) ; if (COL_IS_DEAD (c)) { continue ; } DEBUG3 (("start %d length %d shared1 %d shared2 %d\n", Col [c].start, Col [c].length, Col [c].shared1.thickness, Col [c].shared2.score)) ; cp = &A [Col [c].start] ; cp_end = cp + Col [c].length ; while (cp < cp_end) { r = *cp++ ; DEBUG4 ((" %d row %d\n", ROW_IS_ALIVE (r), r)) ; } } } PRIVATE void colamd_get_debug ( char *method ) { FILE *f ; colamd_debug = 0 ; /* no debug printing */ f = fopen ("debug", "r") ; if (f == (FILE *) NULL) { colamd_debug = 0 ; } else { fscanf (f, "%d", &colamd_debug) ; fclose (f) ; } DEBUG0 (("%s: debug version, D = %d (THIS WILL BE SLOW!)\n", method, colamd_debug)) ; } #endif /* NDEBUG */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/t_Matrix_rle.c���������������������������������������������������������������������������0000644�0001762�0000144�00000004713�14170031121�015075� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*------ Definition of a template for Matrix_rle_[di](...) : * * -------- ~~~~~~~~~~~~~~~~~~~~~~ * i.e., included several times from ./abIndex.c * ~~~~~~~~~~~ */ /* for all cases with an 'x' slot -- i.e. almost all cases ; * just redefine this in the other cases: */ #ifdef _rle_d_ # define Matrix_RLE_ Matrix_rle_d # define Type_x_ double # define STYP_x_ REAL # define SXP_ans REALSXP #elif defined _rle_i_ # define Matrix_RLE_ Matrix_rle_i # define Type_x_ int # define STYP_x_ INTEGER # define SXP_ans INTSXP #else # error "invalid _rle_ macro logic" #endif /** * RLE (Run Length Encoding) -- only when it's worth * * @param x_ R vector which can be coerced to "double" / "integer" * @param force_ R logical indicating if the result must be "RLE" even when inefficient * * @return NULL or a valid R object of class "rle" */ SEXP Matrix_RLE_(SEXP x_, SEXP force_) { int n = LENGTH(PROTECT(x_ = coerceVector(x_, SXP_ans))); Rboolean no_force = !asLogical(force_); if (no_force && n < 3) { UNPROTECT(1); return R_NilValue; } else { register Type_x_ lv; register int ln, i, c = 0; int n2 = (no_force) ? n / 3 : n; /* upper bound: ==> max RAM requirement 2 x n2, (= 2/3 n); * using 2 instead of 3 would need 50% more time, have max * RAM requirement 2.5x for savings of any size */ Type_x_ *x = STYP_x_(x_), *val; int *len; const char *res_nms[] = {"lengths", "values", ""}; SEXP ans; if(n > 0) { /* needed for force=TRUE */ len = R_Calloc(n2, int); val = R_Calloc(n2, Type_x_); lv = x[0]; ln = 1; for(i = 1; i < n; i++) { if (x[i] == lv) { ln++; } else { val[c] = lv; len[c] = ln; c++; if (no_force && c == n2) { /* reached the "efficiency bound" */ R_Free(len); R_Free(val); UNPROTECT(1); return R_NilValue; } lv = x[i]; ln = 1; } } val[c] = lv; len[c] = ln; c++; } ans = PROTECT(Rf_mkNamed(VECSXP, res_nms)); SET_VECTOR_ELT(ans, 0, allocVector(INTSXP, c)); /* lengths */ SET_VECTOR_ELT(ans, 1, allocVector(SXP_ans, c)); /* values */ if(n > 0) { Memcpy(INTEGER(VECTOR_ELT(ans, 0)), len, c); Memcpy(STYP_x_(VECTOR_ELT(ans, 1)), val, c); } setAttrib(ans, R_ClassSymbol, mkString("rle")); if(n > 0) { R_Free(len); R_Free(val); } UNPROTECT(2); return ans; } } /* Matrix_RLE_() template */ #undef Matrix_RLE_ #undef Type_x_ #undef STYP_x_ #undef SXP_ans �����������������������������������������������������Matrix/src/abIndex.c��������������������������������������������������������������������������������0000644�0001762�0000144�00000000237�14503225712�014026� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "Mdefines.h" #include "abIndex.h" #define _rle_d_ #include "t_Matrix_rle.c" #undef _rle_d_ #define _rle_i_ #include "t_Matrix_rle.c" #undef _rle_i_ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/utils-R.h��������������������������������������������������������������������������������0000644�0001762�0000144�00000000744�14514041632�014022� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_UTILS_R_H #define MATRIX_UTILS_R_H #include SEXP R_Matrix_version(void); SEXP R_index_triangle(SEXP, SEXP, SEXP, SEXP); SEXP R_index_diagonal(SEXP, SEXP, SEXP); SEXP R_nnz(SEXP, SEXP, SEXP); SEXP R_all0(SEXP); SEXP R_any0(SEXP); SEXP Mmatrix(SEXP); SEXP compressed_non_0_ij(SEXP, SEXP); SEXP Matrix_expand_pointers(SEXP); SEXP m_encodeInd (SEXP, SEXP, SEXP, SEXP); SEXP m_encodeInd2(SEXP, SEXP, SEXP, SEXP, SEXP); #endif /* MATRIX_UTILS_R_H */ ����������������������������Matrix/src/Minlines.h�������������������������������������������������������������������������������0000644�0001762�0000144�00000000156�14505625474�014252� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATRIX_MINLINES_H #define MATRIX_MINLINES_H /* Currently none ... */ #endif /* MATRIX_MINLINES_H */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/scripts/���������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14547724215�014007� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/scripts/DEPS.mkf�������������������������������������������������������������������������0000644�0001762�0000144�00000014353�14516024403�015233� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#-*- Makefile -*- #------------- produced by ./DEPS.mkf_make.sh (plus minimal emacs cleanup) # Csparse.o: Csparse.c Mdefines.h version.h Syms.h utils.h cs-etc.h cs.h \ cholmod-etc.h SuiteSparse_config/SuiteSparse_config.h \ CHOLMOD/Include/cholmod.h CHOLMOD/Include/cholmod_io64.h \ CHOLMOD/Include/cholmod_config.h CHOLMOD/Include/cholmod_core.h \ CHOLMOD/Include/cholmod_check.h CHOLMOD/Include/cholmod_cholesky.h \ CHOLMOD/Include/cholmod_partition.h CHOLMOD/Include/cholmod_camd.h \ CHOLMOD/Include/cholmod_supernodal.h \ CHOLMOD/Include/cholmod_matrixops.h CHOLMOD/Include/cholmod_modify.h \ Csparse.h t_Csparse_subassign.c abIndex.o: abIndex.c Mdefines.h version.h Syms.h utils.h abIndex.h \ t_Matrix_rle.c attrib.o: attrib.c Mdefines.h version.h Syms.h utils.h attrib.h bind.o: bind.c Mdefines.h version.h Syms.h utils.h coerce.h bind.h chm_common.o: chm_common.c Mdefines.h version.h \ Syms.h utils.h chm_common.h \ cholmod-etc.h SuiteSparse_config/SuiteSparse_config.h \ CHOLMOD/Include/cholmod.h CHOLMOD/Include/cholmod_io64.h \ CHOLMOD/Include/cholmod_config.h CHOLMOD/Include/cholmod_core.h \ CHOLMOD/Include/cholmod_check.h CHOLMOD/Include/cholmod_cholesky.h \ CHOLMOD/Include/cholmod_partition.h CHOLMOD/Include/cholmod_camd.h \ CHOLMOD/Include/cholmod_supernodal.h \ CHOLMOD/Include/cholmod_matrixops.h CHOLMOD/Include/cholmod_modify.h cholmod-etc.o: cholmod-etc.c Mdefines.h version.h \ Syms.h utils.h idz.h cholmod-etc.h \ SuiteSparse_config/SuiteSparse_config.h CHOLMOD/Include/cholmod.h \ CHOLMOD/Include/cholmod_io64.h CHOLMOD/Include/cholmod_config.h \ CHOLMOD/Include/cholmod_core.h CHOLMOD/Include/cholmod_check.h \ CHOLMOD/Include/cholmod_cholesky.h CHOLMOD/Include/cholmod_partition.h \ CHOLMOD/Include/cholmod_camd.h CHOLMOD/Include/cholmod_supernodal.h \ CHOLMOD/Include/cholmod_matrixops.h CHOLMOD/Include/cholmod_modify.h coerce.o: coerce.c Mdefines.h version.h Syms.h utils.h idz.h coerce.h cs-etc.o: cs-etc.c Mdefines.h version.h Syms.h utils.h cs-etc.h cs.h cs.o: cs.c cs.h cs_utils.o: cs_utils.c dense.o: dense.c Mdefines.h version.h Syms.h utils.h idz.h dense.h determinant.o: determinant.c Mdefines.h version.h \ Syms.h utils.h cholmod-etc.h \ SuiteSparse_config/SuiteSparse_config.h CHOLMOD/Include/cholmod.h \ CHOLMOD/Include/cholmod_io64.h CHOLMOD/Include/cholmod_config.h \ CHOLMOD/Include/cholmod_core.h CHOLMOD/Include/cholmod_check.h \ CHOLMOD/Include/cholmod_cholesky.h CHOLMOD/Include/cholmod_partition.h \ CHOLMOD/Include/cholmod_camd.h CHOLMOD/Include/cholmod_supernodal.h \ CHOLMOD/Include/cholmod_matrixops.h CHOLMOD/Include/cholmod_modify.h \ determinant.h dgCMatrix.o: dgCMatrix.c Mdefines.h version.h \ Syms.h utils.h cs-etc.h cs.h \ cholmod-etc.h SuiteSparse_config/SuiteSparse_config.h \ CHOLMOD/Include/cholmod.h CHOLMOD/Include/cholmod_io64.h \ CHOLMOD/Include/cholmod_config.h CHOLMOD/Include/cholmod_core.h \ CHOLMOD/Include/cholmod_check.h CHOLMOD/Include/cholmod_cholesky.h \ CHOLMOD/Include/cholmod_partition.h CHOLMOD/Include/cholmod_camd.h \ CHOLMOD/Include/cholmod_supernodal.h \ CHOLMOD/Include/cholmod_matrixops.h CHOLMOD/Include/cholmod_modify.h \ dgCMatrix.h dgeMatrix.o: dgeMatrix.c Lapack-etc.h Mdefines.h version.h \ Syms.h utils.h dgeMatrix.h factorizations.o: factorizations.c Lapack-etc.h \ cs-etc.h \ cs.h \ cholmod-etc.h \ SuiteSparse_config/SuiteSparse_config.h CHOLMOD/Include/cholmod.h \ CHOLMOD/Include/cholmod_io64.h CHOLMOD/Include/cholmod_config.h \ CHOLMOD/Include/cholmod_core.h CHOLMOD/Include/cholmod_check.h \ CHOLMOD/Include/cholmod_cholesky.h CHOLMOD/Include/cholmod_partition.h \ CHOLMOD/Include/cholmod_camd.h CHOLMOD/Include/cholmod_supernodal.h \ CHOLMOD/Include/cholmod_matrixops.h CHOLMOD/Include/cholmod_modify.h \ Mdefines.h version.h Syms.h utils.h factorizations.h idz.o: idz.c Mdefines.h version.h Syms.h utils.h idz.h init.o: init.c Mdefines.h version.h Syms.h utils.h Csparse.h abIndex.h \ attrib.h bind.h chm_common.h cholmod-etc.h \ SuiteSparse_config/SuiteSparse_config.h CHOLMOD/Include/cholmod.h \ CHOLMOD/Include/cholmod_io64.h CHOLMOD/Include/cholmod_config.h \ CHOLMOD/Include/cholmod_core.h CHOLMOD/Include/cholmod_check.h \ CHOLMOD/Include/cholmod_cholesky.h CHOLMOD/Include/cholmod_partition.h \ CHOLMOD/Include/cholmod_camd.h CHOLMOD/Include/cholmod_supernodal.h \ CHOLMOD/Include/cholmod_matrixops.h CHOLMOD/Include/cholmod_modify.h \ coerce.h dense.h determinant.h dgCMatrix.h dgeMatrix.h \ factorizations.h kappa.h objects.h perm.h products.h solve.h sparse.h \ sparseVector.h subscript.h utils-R.h validity.h kappa.o: kappa.c Lapack-etc.h Mdefines.h version.h \ Syms.h utils.h kappa.h objects.o: objects.c Mdefines.h version.h Syms.h utils.h objects.h perm.o: perm.c Mdefines.h version.h Syms.h utils.h perm.h products.o: products.c Lapack-etc.h cholmod-etc.h \ SuiteSparse_config/SuiteSparse_config.h CHOLMOD/Include/cholmod.h \ CHOLMOD/Include/cholmod_io64.h CHOLMOD/Include/cholmod_config.h \ CHOLMOD/Include/cholmod_core.h CHOLMOD/Include/cholmod_check.h \ CHOLMOD/Include/cholmod_cholesky.h CHOLMOD/Include/cholmod_partition.h \ CHOLMOD/Include/cholmod_camd.h CHOLMOD/Include/cholmod_supernodal.h \ CHOLMOD/Include/cholmod_matrixops.h CHOLMOD/Include/cholmod_modify.h \ Mdefines.h version.h Syms.h utils.h idz.h coerce.h \ dense.h sparse.h products.h solve.o: solve.c Lapack-etc.h cs-etc.h \ cs.h \ cholmod-etc.h \ SuiteSparse_config/SuiteSparse_config.h CHOLMOD/Include/cholmod.h \ CHOLMOD/Include/cholmod_io64.h CHOLMOD/Include/cholmod_config.h \ CHOLMOD/Include/cholmod_core.h CHOLMOD/Include/cholmod_check.h \ CHOLMOD/Include/cholmod_cholesky.h CHOLMOD/Include/cholmod_partition.h \ CHOLMOD/Include/cholmod_camd.h CHOLMOD/Include/cholmod_supernodal.h \ CHOLMOD/Include/cholmod_matrixops.h CHOLMOD/Include/cholmod_modify.h \ Mdefines.h version.h Syms.h utils.h idz.h solve.h sparse.o: sparse.c Mdefines.h version.h Syms.h utils.h sparse.h sparseVector.o: sparseVector.c Mdefines.h version.h \ Syms.h utils.h sparseVector.h subscript.o: subscript.c Mdefines.h version.h \ Syms.h utils.h subscript.h utils-R.o: utils-R.c Mdefines.h version.h Syms.h utils.h utils-R.h utils.o: utils.c Mdefines.h version.h Syms.h utils.h validity.o: validity.c Mdefines.h version.h Syms.h utils.h validity.h �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/scripts/SOURCES_C.mkf��������������������������������������������������������������������0000644�0001762�0000144�00000000554�14504476335�016077� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������SOURCES_C = \ Csparse.c \ abIndex.c \ attrib.c \ bind.c \ chm_common.c \ cholmod-etc.c \ coerce.c \ cs.c \ cs-etc.c \ dense.c \ determinant.c \ dgCMatrix.c \ dgeMatrix.c \ factorizations.c \ idz.c \ init.c \ kappa.c \ objects.c \ perm.c \ products.c \ solve.c \ sparse.c \ sparseVector.c \ subscript.c \ utils-R.c \ utils.c \ validity.c ����������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/���������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14547723665�013415� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Core/����������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14547723665�014305� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Core/cholmod_common.c������������������������������������������������������������0000644�0001762�0000144�00000057144�13652535054�017446� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Core/cholmod_common ================================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Core Module. Copyright (C) 2005-2006, * Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* Core utility routines for the cholmod_common object: * * Primary routines: * ----------------- * cholmod_start the first call to CHOLMOD * cholmod_finish the last call to CHOLMOD * * Secondary routines: * ------------------- * cholmod_defaults restore (most) default control parameters * cholmod_allocate_work allocate (or reallocate) workspace in Common * cholmod_free_work free workspace in Common * cholmod_clear_flag clear Common->Flag in workspace * cholmod_maxrank column dimension of Common->Xwork workspace * * The Common object is unique. It cannot be allocated or deallocated by * CHOLMOD, since it contains the definition of the memory management routines * used (pointers to malloc, free, realloc, and calloc, or their equivalent). * The Common object contains workspace that is used between calls to * CHOLMOD routines. This workspace allocated by CHOLMOD as needed, by * cholmod_allocate_work and cholmod_free_work. */ #include "cholmod_internal.h" #include "cholmod_core.h" #ifdef GPU_BLAS #include "cholmod_gpu.h" #endif /* ========================================================================== */ /* === cholmod_start ======================================================== */ /* ========================================================================== */ /* Initialize Common default parameters and statistics. Sets workspace * pointers to NULL. * * This routine must be called just once, prior to calling any other CHOLMOD * routine. Do not call this routine after any other CHOLMOD routine (except * cholmod_finish, to start a new CHOLMOD session), or a memory leak will * occur. * * workspace: none */ int CHOLMOD(start) ( cholmod_common *Common ) { int k ; if (Common == NULL) { return (FALSE) ; } /* ---------------------------------------------------------------------- */ /* user error handling routine */ /* ---------------------------------------------------------------------- */ Common->error_handler = NULL ; /* ---------------------------------------------------------------------- */ /* integer and numerical types */ /* ---------------------------------------------------------------------- */ Common->itype = ITYPE ; Common->dtype = DTYPE ; /* ---------------------------------------------------------------------- */ /* default control parameters */ /* ---------------------------------------------------------------------- */ CHOLMOD(defaults) (Common) ; Common->try_catch = FALSE ; /* ---------------------------------------------------------------------- */ /* memory management routines */ /* ---------------------------------------------------------------------- */ /* moved to SuiteSparse_config */ /* ---------------------------------------------------------------------- */ /* complex arithmetic routines */ /* ---------------------------------------------------------------------- */ /* moved to SuiteSparse_config */ /* ---------------------------------------------------------------------- */ /* print routine */ /* ---------------------------------------------------------------------- */ /* moved to SuiteSparse_config */ /* ---------------------------------------------------------------------- */ /* workspace */ /* ---------------------------------------------------------------------- */ /* This code assumes the workspace held in Common is not initialized. If * it is, then a memory leak will occur because the pointers are * overwritten with NULL. */ Common->nrow = 0 ; Common->mark = EMPTY ; Common->xworksize = 0 ; Common->iworksize = 0 ; Common->Flag = NULL ; Common->Head = NULL ; Common->Iwork = NULL ; Common->Xwork = NULL ; Common->no_workspace_reallocate = FALSE ; /* ---------------------------------------------------------------------- */ /* statistics */ /* ---------------------------------------------------------------------- */ /* fl and lnz are computed in cholmod_analyze and cholmod_rowcolcounts */ Common->fl = EMPTY ; Common->lnz = EMPTY ; /* modfl is computed in cholmod_updown, cholmod_rowadd, and cholmod_rowdel*/ Common->modfl = EMPTY ; /* all routines use status as their error-report code */ Common->status = CHOLMOD_OK ; Common->malloc_count = 0 ; /* # calls to malloc minus # calls to free */ Common->memory_usage = 0 ; /* peak memory usage (in bytes) */ Common->memory_inuse = 0 ; /* current memory in use (in bytes) */ Common->nrealloc_col = 0 ; Common->nrealloc_factor = 0 ; Common->ndbounds_hit = 0 ; Common->rowfacfl = 0 ; Common->aatfl = EMPTY ; /* Common->called_nd is TRUE if cholmod_analyze called or NESDIS */ Common->called_nd = FALSE ; Common->blas_ok = TRUE ; /* false if BLAS int overflow occurs */ /* ---------------------------------------------------------------------- */ /* default SuiteSparseQR knobs and statististics */ /* ---------------------------------------------------------------------- */ for (k = 0 ; k < 10 ; k++) Common->SPQR_istat [k] = 0 ; Common->SPQR_flopcount_bound = 0 ; /* upper bound on flop count */ Common->SPQR_tol_used = 0 ; /* tolerance used */ Common->SPQR_norm_E_fro = 0 ; /* Frobenius norm of dropped entries */ Common->SPQR_grain = 1 ; /* no Intel TBB multitasking, by default */ Common->SPQR_small = 1e6 ; /* target min task size for TBB */ Common->SPQR_shrink = 1 ; /* controls SPQR shrink realloc */ Common->SPQR_nthreads = 0 ; /* 0: let TBB decide how many threads to use */ Common->SPQR_flopcount = 0 ; /* flop count for SPQR */ Common->SPQR_analyze_time = 0 ; /* analysis time for SPQR */ Common->SPQR_factorize_time = 0 ; /* factorize time for SPQR */ Common->SPQR_solve_time = 0 ; /* backsolve time for SPQR */ /* ---------------------------------------------------------------------- */ /* GPU initializations */ /* ---------------------------------------------------------------------- */ /* these are destroyed by cholmod_gpu_deallocate and cholmod_gpu_end */ Common->cublasHandle = NULL ; Common->cublasEventPotrf [0] = NULL ; Common->cublasEventPotrf [1] = NULL ; Common->cublasEventPotrf [2] = NULL ; for (k = 0 ; k < CHOLMOD_HOST_SUPERNODE_BUFFERS ; k++) { Common->gpuStream [k] = NULL ; Common->updateCBuffersFree [k] = NULL ; } Common->updateCKernelsComplete = NULL; /* these are destroyed by cholmod_gpu_deallocate */ Common->dev_mempool = NULL; Common->dev_mempool_size = 0; Common->host_pinned_mempool = NULL; Common->host_pinned_mempool_size = 0; Common->syrkStart = 0 ; Common->cholmod_cpu_gemm_time = 0 ; Common->cholmod_cpu_syrk_time = 0 ; Common->cholmod_cpu_trsm_time = 0 ; Common->cholmod_cpu_potrf_time = 0 ; Common->cholmod_gpu_gemm_time = 0 ; Common->cholmod_gpu_syrk_time = 0 ; Common->cholmod_gpu_trsm_time = 0 ; Common->cholmod_gpu_potrf_time = 0 ; Common->cholmod_assemble_time = 0 ; Common->cholmod_assemble_time2 = 0 ; Common->cholmod_cpu_gemm_calls = 0 ; Common->cholmod_cpu_syrk_calls = 0 ; Common->cholmod_cpu_trsm_calls = 0 ; Common->cholmod_cpu_potrf_calls = 0 ; Common->cholmod_gpu_gemm_calls = 0 ; Common->cholmod_gpu_syrk_calls = 0 ; Common->cholmod_gpu_trsm_calls = 0 ; Common->cholmod_gpu_potrf_calls = 0 ; Common->maxGpuMemBytes = 0; Common->maxGpuMemFraction = 0.0; /* SPQR statistics and settings */ Common->gpuMemorySize = 1 ; /* default: no GPU memory available */ Common->gpuKernelTime = 0.0 ; Common->gpuFlops = 0 ; Common->gpuNumKernelLaunches = 0 ; DEBUG_INIT ("cholmod start", Common) ; return (TRUE) ; } /* ========================================================================== */ /* === cholmod_defaults ===================================================== */ /* ========================================================================== */ /* Set Common default parameters, except for the function pointers. * * workspace: none */ int CHOLMOD(defaults) ( cholmod_common *Common ) { Int i ; RETURN_IF_NULL_COMMON (FALSE) ; /* ---------------------------------------------------------------------- */ /* default control parameters */ /* ---------------------------------------------------------------------- */ Common->dbound = 0.0 ; Common->grow0 = 1.2 ; Common->grow1 = 1.2 ; Common->grow2 = 5 ; Common->maxrank = 8 ; Common->final_asis = TRUE ; Common->final_super = TRUE ; Common->final_ll = FALSE ; Common->final_pack = TRUE ; Common->final_monotonic = TRUE ; Common->final_resymbol = FALSE ; /* use simplicial factorization if flop/nnz(L) < 40, supernodal otherwise */ Common->supernodal = CHOLMOD_AUTO ; Common->supernodal_switch = 40 ; Common->nrelax [0] = 4 ; Common->nrelax [1] = 16 ; Common->nrelax [2] = 48 ; Common->zrelax [0] = 0.8 ; Common->zrelax [1] = 0.1 ; Common->zrelax [2] = 0.05 ; Common->prefer_zomplex = FALSE ; Common->prefer_upper = TRUE ; Common->prefer_binary = FALSE ; Common->quick_return_if_not_posdef = FALSE ; /* METIS workarounds */ Common->metis_memory = 0.0 ; /* > 0 for memory guard (2 is reasonable) */ Common->metis_nswitch = 3000 ; Common->metis_dswitch = 0.66 ; Common->print = 3 ; Common->precise = FALSE ; /* ---------------------------------------------------------------------- */ /* default ordering methods */ /* ---------------------------------------------------------------------- */ /* Note that if the Partition module is not installed, the CHOLMOD_METIS * and CHOLMOD_NESDIS methods will not be available. cholmod_analyze will * report the CHOLMOD_NOT_INSTALLED error, and safely skip over them. */ #if (CHOLMOD_MAXMETHODS < 9) #error "CHOLMOD_MAXMETHODS must be 9 or more (defined in cholmod_core.h)." #endif /* default strategy: try given, AMD, and then METIS if AMD reports high * fill-in. NESDIS can be used instead, if Common->default_nesdis is TRUE. */ Common->nmethods = 0 ; /* use default strategy */ Common->default_nesdis = FALSE ; /* use METIS in default strategy */ Common->current = 0 ; /* current method being tried */ Common->selected = 0 ; /* the best method selected */ /* first, fill each method with default parameters */ for (i = 0 ; i <= CHOLMOD_MAXMETHODS ; i++) { /* CHOLMOD's default method is AMD for A or AA' */ Common->method [i].ordering = CHOLMOD_AMD ; /* CHOLMOD nested dissection and minimum degree parameter */ Common->method [i].prune_dense = 10.0 ; /* dense row/col control */ /* min degree parameters (AMD, COLAMD, SYMAMD, CAMD, CCOLAMD, CSYMAMD)*/ Common->method [i].prune_dense2 = -1 ; /* COLAMD dense row control */ Common->method [i].aggressive = TRUE ; /* aggressive absorption */ Common->method [i].order_for_lu = FALSE ;/* order for Cholesky not LU */ /* CHOLMOD's nested dissection (METIS + constrained AMD) */ Common->method [i].nd_small = 200 ; /* small graphs aren't cut */ Common->method [i].nd_compress = TRUE ; /* compress graph & subgraphs */ Common->method [i].nd_camd = 1 ; /* use CAMD */ Common->method [i].nd_components = FALSE ; /* lump connected comp. */ Common->method [i].nd_oksep = 1.0 ; /* sep ok if < oksep*n */ /* statistics for each method are not yet computed */ Common->method [i].fl = EMPTY ; Common->method [i].lnz = EMPTY ; } Common->postorder = TRUE ; /* follow ordering with weighted postorder */ /* Next, define some methods. The first five use default parameters. */ Common->method [0].ordering = CHOLMOD_GIVEN ; /* skip if UserPerm NULL */ Common->method [1].ordering = CHOLMOD_AMD ; Common->method [2].ordering = CHOLMOD_METIS ; Common->method [3].ordering = CHOLMOD_NESDIS ; Common->method [4].ordering = CHOLMOD_NATURAL ; /* CHOLMOD's nested dissection with large leaves of separator tree */ Common->method [5].ordering = CHOLMOD_NESDIS ; Common->method [5].nd_small = 20000 ; /* CHOLMOD's nested dissection with tiny leaves, and no AMD ordering */ Common->method [6].ordering = CHOLMOD_NESDIS ; Common->method [6].nd_small = 4 ; Common->method [6].nd_camd = 0 ; /* no CSYMAMD or CAMD */ /* CHOLMOD's nested dissection with no dense node removal */ Common->method [7].ordering = CHOLMOD_NESDIS ; Common->method [7].prune_dense = -1. ; /* COLAMD for A*A', AMD for A */ Common->method [8].ordering = CHOLMOD_COLAMD ; /* ---------------------------------------------------------------------- */ /* GPU configuration and statistics */ /* ---------------------------------------------------------------------- */ #ifdef DLONG Common->useGPU = EMPTY ; #else /* GPU acceleration is not supported for int version of CHOLMOD */ Common->useGPU = 0 ; #endif return (TRUE) ; } /* ========================================================================== */ /* === cholmod_finish ======================================================= */ /* ========================================================================== */ /* The last call to CHOLMOD must be cholmod_finish. You may call this routine * more than once, and can safely call any other CHOLMOD routine after calling * it (including cholmod_start). * * The statistics and parameter settings in Common are preserved. The * workspace in Common is freed. This routine is just another name for * cholmod_free_work. */ int CHOLMOD(finish) ( cholmod_common *Common ) { return (CHOLMOD(free_work) (Common)) ; } /* ========================================================================== */ /* === cholmod_allocate_work ================================================ */ /* ========================================================================== */ /* Allocate and initialize workspace for CHOLMOD routines, or increase the size * of already-allocated workspace. If enough workspace is already allocated, * then nothing happens. * * workspace: Flag (nrow), Head (nrow+1), Iwork (iworksize), Xwork (xworksize) */ int CHOLMOD(allocate_work) ( /* ---- input ---- */ size_t nrow, /* # of rows in the matrix A */ size_t iworksize, /* size of Iwork */ size_t xworksize, /* size of Xwork */ /* --------------- */ cholmod_common *Common ) { double *W ; Int *Head ; Int i ; size_t nrow1 ; int ok = TRUE ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* Allocate Flag (nrow) and Head (nrow+1) */ /* ---------------------------------------------------------------------- */ nrow = MAX (1, nrow) ; /* nrow1 = nrow + 1 */ nrow1 = CHOLMOD(add_size_t) (nrow, 1, &ok) ; if (!ok) { /* nrow+1 causes size_t overflow ; problem is too large */ Common->status = CHOLMOD_TOO_LARGE ; CHOLMOD(free_work) (Common) ; return (FALSE) ; } if (nrow > Common->nrow) { if (Common->no_workspace_reallocate) { /* CHOLMOD is not allowed to change the workspace here */ Common->status = CHOLMOD_INVALID ; return (FALSE) ; } /* free the old workspace (if any) and allocate new space */ Common->Flag = CHOLMOD(free) (Common->nrow, sizeof (Int), Common->Flag, Common) ; Common->Head = CHOLMOD(free) (Common->nrow+1,sizeof (Int), Common->Head, Common) ; Common->Flag = CHOLMOD(malloc) (nrow, sizeof (Int), Common) ; Common->Head = CHOLMOD(malloc) (nrow1, sizeof (Int), Common) ; /* record the new size of Flag and Head */ Common->nrow = nrow ; if (Common->status < CHOLMOD_OK) { CHOLMOD(free_work) (Common) ; return (FALSE) ; } /* initialize Flag and Head */ Common->mark = EMPTY ; CHOLMOD(clear_flag) (Common) ; Head = Common->Head ; for (i = 0 ; i <= (Int) (nrow) ; i++) { Head [i] = EMPTY ; } } /* ---------------------------------------------------------------------- */ /* Allocate Iwork (iworksize) */ /* ---------------------------------------------------------------------- */ iworksize = MAX (1, iworksize) ; if (iworksize > Common->iworksize) { if (Common->no_workspace_reallocate) { /* CHOLMOD is not allowed to change the workspace here */ Common->status = CHOLMOD_INVALID ; return (FALSE) ; } /* free the old workspace (if any) and allocate new space. * integer overflow safely detected in cholmod_malloc */ CHOLMOD(free) (Common->iworksize, sizeof (Int), Common->Iwork, Common) ; Common->Iwork = CHOLMOD(malloc) (iworksize, sizeof (Int), Common) ; /* record the new size of Iwork */ Common->iworksize = iworksize ; if (Common->status < CHOLMOD_OK) { CHOLMOD(free_work) (Common) ; return (FALSE) ; } /* note that Iwork does not need to be initialized */ } /* ---------------------------------------------------------------------- */ /* Allocate Xwork (xworksize) and set it to ((double) 0.) */ /* ---------------------------------------------------------------------- */ /* make sure xworksize is >= 1 */ xworksize = MAX (1, xworksize) ; if (xworksize > Common->xworksize) { if (Common->no_workspace_reallocate) { /* CHOLMOD is not allowed to change the workspace here */ Common->status = CHOLMOD_INVALID ; return (FALSE) ; } /* free the old workspace (if any) and allocate new space */ CHOLMOD(free) (Common->xworksize, sizeof (double), Common->Xwork, Common) ; Common->Xwork = CHOLMOD(malloc) (xworksize, sizeof (double), Common) ; /* record the new size of Xwork */ Common->xworksize = xworksize ; if (Common->status < CHOLMOD_OK) { CHOLMOD(free_work) (Common) ; return (FALSE) ; } /* initialize Xwork */ W = Common->Xwork ; for (i = 0 ; i < (Int) xworksize ; i++) { W [i] = 0. ; } } return (TRUE) ; } /* ========================================================================== */ /* === cholmod_free_work ==================================================== */ /* ========================================================================== */ /* Deallocate the CHOLMOD workspace. * * workspace: deallocates all workspace in Common */ int CHOLMOD(free_work) ( cholmod_common *Common ) { RETURN_IF_NULL_COMMON (FALSE) ; Common->Flag = CHOLMOD(free) (Common->nrow, sizeof (Int), Common->Flag, Common) ; Common->Head = CHOLMOD(free) (Common->nrow+1, sizeof (Int), Common->Head, Common) ; Common->Iwork = CHOLMOD(free) (Common->iworksize, sizeof (Int), Common->Iwork, Common) ; Common->Xwork = CHOLMOD(free) (Common->xworksize, sizeof (double), Common->Xwork, Common) ; Common->nrow = 0 ; Common->iworksize = 0 ; Common->xworksize = 0 ; #ifdef GPU_BLAS CHOLMOD(gpu_deallocate) (Common) ; #endif return (TRUE) ; } /* ========================================================================== */ /* === cholmod_clear_flag =================================================== */ /* ========================================================================== */ /* Increment mark to ensure Flag [0..nrow-1] < mark. If integer overflow * occurs, or mark was initially negative, reset the entire array. This is * not an error condition, but an intended function of the Flag workspace. * * workspace: Flag (nrow). Does not modify Flag if nrow is zero. */ SuiteSparse_long CHOLMOD(clear_flag) ( cholmod_common *Common ) { Int i, nrow, *Flag ; RETURN_IF_NULL_COMMON (-1) ; Common->mark++ ; if (Common->mark <= 0) { nrow = Common->nrow ; Flag = Common->Flag ; PRINT2 (("reset Flag: nrow "ID"\n", nrow)) ; PRINT2 (("reset Flag: mark %ld\n", Common->mark)) ; for (i = 0 ; i < nrow ; i++) { Flag [i] = EMPTY ; } Common->mark = 0 ; } return (Common->mark) ; } /* ========================================================================== */ /* ==== cholmod_maxrank ===================================================== */ /* ========================================================================== */ /* Find a valid value of Common->maxrank. Returns 0 if error, or 2, 4, or 8 * if successful. */ size_t CHOLMOD(maxrank) /* returns validated value of Common->maxrank */ ( /* ---- input ---- */ size_t n, /* A and L will have n rows */ /* --------------- */ cholmod_common *Common ) { size_t maxrank ; RETURN_IF_NULL_COMMON (0) ; maxrank = Common->maxrank ; if (n > 0) { /* Ensure maxrank*n*sizeof(double) does not result in integer overflow. * If n is so large that 2*n*sizeof(double) results in integer overflow * (n = 268,435,455 if an Int is 32 bits), then maxrank will be 0 or 1, * but maxrank will be set to 2 below. 2*n will not result in integer * overflow, and CHOLMOD will run out of memory or safely detect integer * overflow elsewhere. */ maxrank = MIN (maxrank, Size_max / (n * sizeof (double))) ; } if (maxrank <= 2) { maxrank = 2 ; } else if (maxrank <= 4) { maxrank = 4 ; } else { maxrank = 8 ; } return (maxrank) ; } /* ========================================================================== */ /* === cholmod_dbound ======================================================= */ /* ========================================================================== */ /* Ensure the absolute value of a diagonal entry, D (j,j), is greater than * Common->dbound. This routine is not meant for the user to call. It is used * by the various LDL' factorization and update/downdate routines. The * default value of Common->dbound is zero, and in that case this routine is not * called at all. No change is made if D (j,j) is NaN. CHOLMOD does not call * this routine if Common->dbound is NaN. */ double CHOLMOD(dbound) /* returns modified diagonal entry of D */ ( /* ---- input ---- */ double dj, /* diagonal entry of D, for LDL' factorization */ /* --------------- */ cholmod_common *Common ) { double dbound ; RETURN_IF_NULL_COMMON (0) ; if (!IS_NAN (dj)) { dbound = Common->dbound ; if (dj < 0) { if (dj > -dbound) { dj = -dbound ; Common->ndbounds_hit++ ; if (Common->status == CHOLMOD_OK) { ERROR (CHOLMOD_DSMALL, "diagonal below threshold") ; } } } else { if (dj < dbound) { dj = dbound ; Common->ndbounds_hit++ ; if (Common->status == CHOLMOD_OK) { ERROR (CHOLMOD_DSMALL, "diagonal below threshold") ; } } } } return (dj) ; } /* ========================================================================== */ /* === scorecomp ============================================================ */ /* ========================================================================== */ /* For sorting descendant supernodes with qsort */ int CHOLMOD(score_comp) (struct cholmod_descendant_score_t *i, struct cholmod_descendant_score_t *j) { if ((*i).score < (*j).score) { return (1) ; } else { return (-1) ; } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Core/cholmod_aat.c���������������������������������������������������������������0000644�0001762�0000144�00000020354�13652535054�016714� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Core/cholmod_aat ===================================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Core Module. Copyright (C) 2005-2006, * Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* C = A*A' or C = A(:,f)*A(:,f)' * * A can be packed or unpacked, sorted or unsorted, but must be stored with * both upper and lower parts (A->stype of zero). C is returned as packed, * C->stype of zero (both upper and lower parts present), and unsorted. See * cholmod_ssmult in the MatrixOps Module for a more general matrix-matrix * multiply. * * You can trivially convert C into a symmetric upper/lower matrix by * changing C->stype = 1 or -1 after calling this routine. * * workspace: * Flag (A->nrow), * Iwork (max (A->nrow, A->ncol)) if fset present, * Iwork (A->nrow) if no fset, * W (A->nrow) if mode > 0, * allocates temporary copy for A'. * * A can be pattern or real. Complex or zomplex cases are supported only * if the mode is <= 0 (in which case the numerical values are ignored). */ #include "cholmod_internal.h" #include "cholmod_core.h" cholmod_sparse *CHOLMOD(aat) ( /* ---- input ---- */ cholmod_sparse *A, /* input matrix; C=A*A' is constructed */ Int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) * -2: pattern only, no diagonal, add 50% + n extra * space to C */ /* --------------- */ cholmod_common *Common ) { double fjt ; double *Ax, *Fx, *Cx, *W ; Int *Ap, *Anz, *Ai, *Fp, *Fi, *Cp, *Ci, *Flag ; cholmod_sparse *C, *F ; Int packed, j, i, pa, paend, pf, pfend, n, mark, cnz, t, p, values, diag, extra ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (A, NULL) ; values = (mode > 0) && (A->xtype != CHOLMOD_PATTERN) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, values ? CHOLMOD_REAL : CHOLMOD_ZOMPLEX, NULL) ; if (A->stype) { ERROR (CHOLMOD_INVALID, "matrix cannot be symmetric") ; return (NULL) ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ diag = (mode >= 0) ; n = A->nrow ; CHOLMOD(allocate_work) (n, MAX (A->ncol, A->nrow), values ? n : 0, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory */ } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n : 0, Common)) ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ ASSERT (CHOLMOD(dump_sparse) (A, "A", Common) >= 0) ; /* get the A matrix */ Ap = A->p ; Anz = A->nz ; Ai = A->i ; Ax = A->x ; packed = A->packed ; /* get workspace */ W = Common->Xwork ; /* size n, unused if values is FALSE */ Flag = Common->Flag ; /* size n, Flag [0..n-1] < mark on input*/ /* ---------------------------------------------------------------------- */ /* F = A' or A(:,f)' */ /* ---------------------------------------------------------------------- */ /* workspace: Iwork (nrow if no fset; MAX (nrow,ncol) if fset)*/ F = CHOLMOD(ptranspose) (A, values, NULL, fset, fsize, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory */ } Fp = F->p ; Fi = F->i ; Fx = F->x ; /* ---------------------------------------------------------------------- */ /* count the number of entries in the result C */ /* ---------------------------------------------------------------------- */ cnz = 0 ; for (j = 0 ; j < n ; j++) { /* clear the Flag array */ /* mark = CHOLMOD(clear_flag) (Common) ; */ CHOLMOD_CLEAR_FLAG (Common) ; mark = Common->mark ; /* exclude the diagonal, if requested */ if (!diag) { Flag [j] = mark ; } /* for each nonzero F(t,j) in column j, do: */ pfend = Fp [j+1] ; for (pf = Fp [j] ; pf < pfend ; pf++) { /* F(t,j) is nonzero */ t = Fi [pf] ; /* add the nonzero pattern of A(:,t) to the pattern of C(:,j) */ pa = Ap [t] ; paend = (packed) ? (Ap [t+1]) : (pa + Anz [t]) ; for ( ; pa < paend ; pa++) { i = Ai [pa] ; if (Flag [i] != mark) { Flag [i] = mark ; cnz++ ; } } } if (cnz < 0) { break ; /* integer overflow case */ } } extra = (mode == -2) ? (cnz/2 + n) : 0 ; mark = CHOLMOD(clear_flag) (Common) ; /* ---------------------------------------------------------------------- */ /* check for integer overflow */ /* ---------------------------------------------------------------------- */ if (cnz < 0 || (cnz + extra) < 0) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; CHOLMOD(clear_flag) (Common) ; CHOLMOD(free_sparse) (&F, Common) ; return (NULL) ; /* problem too large */ } /* ---------------------------------------------------------------------- */ /* allocate C */ /* ---------------------------------------------------------------------- */ C = CHOLMOD(allocate_sparse) (n, n, cnz + extra, FALSE, TRUE, 0, values ? A->xtype : CHOLMOD_PATTERN, Common) ; if (Common->status < CHOLMOD_OK) { CHOLMOD(free_sparse) (&F, Common) ; return (NULL) ; /* out of memory */ } Cp = C->p ; Ci = C->i ; Cx = C->x ; /* ---------------------------------------------------------------------- */ /* C = A*A' */ /* ---------------------------------------------------------------------- */ cnz = 0 ; if (values) { /* pattern and values */ for (j = 0 ; j < n ; j++) { /* clear the Flag array */ mark = CHOLMOD(clear_flag) (Common) ; /* start column j of C */ Cp [j] = cnz ; /* for each nonzero F(t,j) in column j, do: */ pfend = Fp [j+1] ; for (pf = Fp [j] ; pf < pfend ; pf++) { /* F(t,j) is nonzero */ t = Fi [pf] ; fjt = Fx [pf] ; /* add the nonzero pattern of A(:,t) to the pattern of C(:,j) * and scatter the values into W */ pa = Ap [t] ; paend = (packed) ? (Ap [t+1]) : (pa + Anz [t]) ; for ( ; pa < paend ; pa++) { i = Ai [pa] ; if (Flag [i] != mark) { Flag [i] = mark ; Ci [cnz++] = i ; } W [i] += Ax [pa] * fjt ; } } /* gather the values into C(:,j) */ for (p = Cp [j] ; p < cnz ; p++) { i = Ci [p] ; Cx [p] = W [i] ; W [i] = 0 ; } } } else { /* pattern only */ for (j = 0 ; j < n ; j++) { /* clear the Flag array */ mark = CHOLMOD(clear_flag) (Common) ; /* exclude the diagonal, if requested */ if (!diag) { Flag [j] = mark ; } /* start column j of C */ Cp [j] = cnz ; /* for each nonzero F(t,j) in column j, do: */ pfend = Fp [j+1] ; for (pf = Fp [j] ; pf < pfend ; pf++) { /* F(t,j) is nonzero */ t = Fi [pf] ; /* add the nonzero pattern of A(:,t) to the pattern of C(:,j) */ pa = Ap [t] ; paend = (packed) ? (Ap [t+1]) : (pa + Anz [t]) ; for ( ; pa < paend ; pa++) { i = Ai [pa] ; if (Flag [i] != mark) { Flag [i] = mark ; Ci [cnz++] = i ; } } } } } Cp [n] = cnz ; ASSERT (IMPLIES (mode != -2, MAX (1,cnz) == C->nzmax)) ; /* ---------------------------------------------------------------------- */ /* clear workspace and free temporary matrices and return result */ /* ---------------------------------------------------------------------- */ CHOLMOD(free_sparse) (&F, Common) ; CHOLMOD(clear_flag) (Common) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n : 0, Common)) ; DEBUG (i = CHOLMOD(dump_sparse) (C, "aat", Common)) ; ASSERT (IMPLIES (mode < 0, i == 0)) ; return (C) ; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Core/cholmod_complex.c�����������������������������������������������������������0000644�0001762�0000144�00000035251�13652535054�017620� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Core/cholmod_complex ================================================= */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Core Module. Copyright (C) 2005-2006, * Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* If you convert a matrix that contains uninitialized data, valgrind will * complain. This can occur in a factor L which has gaps (a partial * factorization, or after updates that change the nonzero pattern), an * unpacked sparse matrix, a dense matrix with leading dimension d > # of rows, * or any matrix (dense, sparse, triplet, or factor) with more space allocated * than is used. You can safely ignore any of these complaints by valgrind. */ #include "cholmod_internal.h" #include "cholmod_core.h" /* ========================================================================== */ /* === cholmod_hypot ======================================================== */ /* ========================================================================== */ double CHOLMOD(hypot) (double x, double y) { return (SuiteSparse_config.hypot_func (x, y)) ; } /* ========================================================================== */ /* === cholmod_divcomplex =================================================== */ /* ========================================================================== */ /* c = a/b where c, a, and b are complex. The real and imaginary parts are * passed as separate arguments to this routine. The NaN case is ignored * for the double relop br >= bi. Returns 1 if the denominator is zero, * 0 otherwise. Note that this return value is the single exception to the * rule that all CHOLMOD routines that return int return TRUE if successful * or FALSE otherise. * * This uses ACM Algo 116, by R. L. Smith, 1962, which tries to avoid * underflow and overflow. * * c can be the same variable as a or b. * * Default value of the SuiteSparse_config.divcomplex_func pointer is * SuiteSparse_divcomplex, located in SuiteSparse_config.c. */ int CHOLMOD(divcomplex) ( double ar, double ai, /* real and imaginary parts of a */ double br, double bi, /* real and imaginary parts of b */ double *cr, double *ci /* real and imaginary parts of c */ ) { return (SuiteSparse_config.divcomplex_func (ar, ai, br, bi, cr, ci)) ; } /* ========================================================================== */ /* === change_complexity ==================================================== */ /* ========================================================================== */ /* X and Z represent an array of size nz, with numeric xtype given by xtype_in. * * If xtype_in is: * CHOLMOD_PATTERN: X and Z must be NULL. * CHOLMOD_REAL: X is of size nz, Z must be NULL. * CHOLMOD_COMPLEX: X is of size 2*nz, Z must be NULL. * CHOLMOD_ZOMPLEX: X is of size nz, Z is of size nz. * * The array is changed into the numeric xtype given by xtype_out, with the * same definitions of X and Z above. Note that the input conditions, above, * are not checked. These are checked in the caller routine. * * Returns TRUE if successful, FALSE otherwise. X and Z are not modified if * not successful. */ static int change_complexity ( /* ---- input ---- */ Int nz, /* size of X and/or Z */ int xtype_in, /* xtype of X and Z on input */ int xtype_out, /* requested xtype of X and Z on output */ int xtype1, /* xtype_out must be in the range [xtype1 .. xtype2] */ int xtype2, /* ---- in/out --- */ void **XX, /* old X on input, new X on output */ void **ZZ, /* old Z on input, new Z on output */ /* --------------- */ cholmod_common *Common ) { double *Xold, *Zold, *Xnew, *Znew ; Int k ; size_t nz2 ; if (xtype_out < xtype1 || xtype_out > xtype2) { ERROR (CHOLMOD_INVALID, "invalid xtype") ; return (FALSE) ; } Common->status = CHOLMOD_OK ; Xold = *XX ; Zold = *ZZ ; switch (xtype_in) { /* ------------------------------------------------------------------ */ /* converting from pattern */ /* ------------------------------------------------------------------ */ case CHOLMOD_PATTERN: switch (xtype_out) { /* ---------------------------------------------------------- */ /* pattern -> real */ /* ---------------------------------------------------------- */ case CHOLMOD_REAL: /* allocate X and set to all ones */ Xnew = CHOLMOD(malloc) (nz, sizeof (double), Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; } for (k = 0 ; k < nz ; k++) { Xnew [k] = 1 ; } *XX = Xnew ; break ; /* ---------------------------------------------------------- */ /* pattern -> complex */ /* ---------------------------------------------------------- */ case CHOLMOD_COMPLEX: /* allocate X and set to all ones */ Xnew = CHOLMOD(malloc) (nz, 2*sizeof (double), Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; } for (k = 0 ; k < nz ; k++) { Xnew [2*k ] = 1 ; Xnew [2*k+1] = 0 ; } *XX = Xnew ; break ; /* ---------------------------------------------------------- */ /* pattern -> zomplex */ /* ---------------------------------------------------------- */ case CHOLMOD_ZOMPLEX: /* allocate X and Z and set to all ones */ Xnew = CHOLMOD(malloc) (nz, sizeof (double), Common) ; Znew = CHOLMOD(malloc) (nz, sizeof (double), Common) ; if (Common->status < CHOLMOD_OK) { CHOLMOD(free) (nz, sizeof (double), Xnew, Common) ; CHOLMOD(free) (nz, sizeof (double), Znew, Common) ; return (FALSE) ; } for (k = 0 ; k < nz ; k++) { Xnew [k] = 1 ; Znew [k] = 0 ; } *XX = Xnew ; *ZZ = Znew ; break ; } break ; /* ------------------------------------------------------------------ */ /* converting from real */ /* ------------------------------------------------------------------ */ case CHOLMOD_REAL: switch (xtype_out) { /* ---------------------------------------------------------- */ /* real -> pattern */ /* ---------------------------------------------------------- */ case CHOLMOD_PATTERN: /* free X */ *XX = CHOLMOD(free) (nz, sizeof (double), *XX, Common) ; break ; /* ---------------------------------------------------------- */ /* real -> complex */ /* ---------------------------------------------------------- */ case CHOLMOD_COMPLEX: /* allocate a new X and copy the old X */ Xnew = CHOLMOD(malloc) (nz, 2*sizeof (double), Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; } for (k = 0 ; k < nz ; k++) { Xnew [2*k ] = Xold [k] ; Xnew [2*k+1] = 0 ; } CHOLMOD(free) (nz, sizeof (double), *XX, Common) ; *XX = Xnew ; break ; /* ---------------------------------------------------------- */ /* real -> zomplex */ /* ---------------------------------------------------------- */ case CHOLMOD_ZOMPLEX: /* allocate a new Z and set it to zero */ Znew = CHOLMOD(malloc) (nz, sizeof (double), Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; } for (k = 0 ; k < nz ; k++) { Znew [k] = 0 ; } *ZZ = Znew ; break ; } break ; /* ------------------------------------------------------------------ */ /* converting from complex */ /* ------------------------------------------------------------------ */ case CHOLMOD_COMPLEX: switch (xtype_out) { /* ---------------------------------------------------------- */ /* complex -> pattern */ /* ---------------------------------------------------------- */ case CHOLMOD_PATTERN: /* free X */ *XX = CHOLMOD(free) (nz, 2*sizeof (double), *XX, Common) ; break ; /* ---------------------------------------------------------- */ /* complex -> real */ /* ---------------------------------------------------------- */ case CHOLMOD_REAL: /* pack the real part of X, discarding the imaginary part */ for (k = 0 ; k < nz ; k++) { Xold [k] = Xold [2*k] ; } /* shrink X in half (this cannot fail) */ nz2 = 2*nz ; *XX = CHOLMOD(realloc) (nz, sizeof (double), *XX, &nz2, Common) ; break ; /* ---------------------------------------------------------- */ /* complex -> zomplex */ /* ---------------------------------------------------------- */ case CHOLMOD_ZOMPLEX: /* allocate X and Z and copy the old X into them */ Xnew = CHOLMOD(malloc) (nz, sizeof (double), Common) ; Znew = CHOLMOD(malloc) (nz, sizeof (double), Common) ; if (Common->status < CHOLMOD_OK) { CHOLMOD(free) (nz, sizeof (double), Xnew, Common) ; CHOLMOD(free) (nz, sizeof (double), Znew, Common) ; return (FALSE) ; } for (k = 0 ; k < nz ; k++) { Xnew [k] = Xold [2*k ] ; Znew [k] = Xold [2*k+1] ; } CHOLMOD(free) (nz, 2*sizeof (double), *XX, Common) ; *XX = Xnew ; *ZZ = Znew ; break ; } break ; /* ------------------------------------------------------------------ */ /* converting from zomplex */ /* ------------------------------------------------------------------ */ case CHOLMOD_ZOMPLEX: switch (xtype_out) { /* ---------------------------------------------------------- */ /* zomplex -> pattern */ /* ---------------------------------------------------------- */ case CHOLMOD_PATTERN: /* free X and Z */ *XX = CHOLMOD(free) (nz, sizeof (double), *XX, Common) ; *ZZ = CHOLMOD(free) (nz, sizeof (double), *ZZ, Common) ; break ; /* ---------------------------------------------------------- */ /* zomplex -> real */ /* ---------------------------------------------------------- */ case CHOLMOD_REAL: /* free the imaginary part */ *ZZ = CHOLMOD(free) (nz, sizeof (double), *ZZ, Common) ; break ; /* ---------------------------------------------------------- */ /* zomplex -> complex */ /* ---------------------------------------------------------- */ case CHOLMOD_COMPLEX: Xnew = CHOLMOD(malloc) (nz, 2*sizeof (double), Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; } for (k = 0 ; k < nz ; k++) { Xnew [2*k ] = Xold [k] ; Xnew [2*k+1] = Zold [k] ; } CHOLMOD(free) (nz, sizeof (double), *XX, Common) ; CHOLMOD(free) (nz, sizeof (double), *ZZ, Common) ; *XX = Xnew ; *ZZ = NULL ; break ; } break ; } return (TRUE) ; } /* ========================================================================== */ /* === cholmod_sparse_xtype ================================================= */ /* ========================================================================== */ /* Change the numeric xtype of a sparse matrix. Supports any type on input * and output (pattern, real, complex, or zomplex). */ int CHOLMOD(sparse_xtype) ( /* ---- input ---- */ int to_xtype, /* requested xtype */ /* ---- in/out --- */ cholmod_sparse *A, /* sparse matrix to change */ /* --------------- */ cholmod_common *Common ) { Int ok ; RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; ok = change_complexity (A->nzmax, A->xtype, to_xtype, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, &(A->x), &(A->z), Common) ; if (ok) { A->xtype = to_xtype ; } return (ok) ; } /* ========================================================================== */ /* === cholmod_triplet_xtype ================================================ */ /* ========================================================================== */ /* Change the numeric xtype of a triplet matrix. Supports any type on input * and output (pattern, real, complex, or zomplex). */ int CHOLMOD(triplet_xtype) ( /* ---- input ---- */ int to_xtype, /* requested xtype */ /* ---- in/out --- */ cholmod_triplet *T, /* triplet matrix to change */ /* --------------- */ cholmod_common *Common ) { Int ok ; RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (T, FALSE) ; RETURN_IF_XTYPE_INVALID (T, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; ok = change_complexity (T->nzmax, T->xtype, to_xtype, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, &(T->x), &(T->z), Common) ; if (ok) { T->xtype = to_xtype ; } return (ok) ; } /* ========================================================================== */ /* === cholmod_dense_xtype ================================================= */ /* ========================================================================== */ /* Change the numeric xtype of a dense matrix. Supports real, complex or * zomplex on input and output */ int CHOLMOD(dense_xtype) ( /* ---- input ---- */ int to_xtype, /* requested xtype */ /* ---- in/out --- */ cholmod_dense *X, /* dense matrix to change */ /* --------------- */ cholmod_common *Common ) { Int ok ; RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (X, FALSE) ; RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; ok = change_complexity (X->nzmax, X->xtype, to_xtype, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, &(X->x), &(X->z), Common) ; if (ok) { X->xtype = to_xtype ; } return (ok) ; } /* ========================================================================== */ /* === cholmod_factor_xtype ================================================= */ /* ========================================================================== */ /* Change the numeric xtype of a factor. Supports real, complex or zomplex on * input and output. Supernodal zomplex factors are not supported. */ int CHOLMOD(factor_xtype) ( /* ---- input ---- */ int to_xtype, /* requested xtype */ /* ---- in/out --- */ cholmod_factor *L, /* factor to change */ /* --------------- */ cholmod_common *Common ) { Int ok ; RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (L, FALSE) ; RETURN_IF_XTYPE_INVALID (L, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; if (L->is_super && (L->xtype == CHOLMOD_ZOMPLEX || to_xtype == CHOLMOD_ZOMPLEX)) { ERROR (CHOLMOD_INVALID, "invalid xtype for supernodal L") ; return (FALSE) ; } ok = change_complexity ((L->is_super ? L->xsize : L->nzmax), L->xtype, to_xtype, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, &(L->x), &(L->z), Common) ; if (ok) { L->xtype = to_xtype ; } return (ok) ; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Core/t_cholmod_transpose.c�������������������������������������������������������0000644�0001762�0000144�00000020703�13652535054�020506� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Core/t_cholmod_transpose ============================================= */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Core Module. Copyright (C) 2005-2006, * Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* Template routine for cholmod_transpose. All xtypes are supported. For * complex matrices, either the array tranpose or complex conjugate transpose * can be computed. */ #include "cholmod_template.h" /* ========================================================================== */ /* === t_cholmod_transpose_unsym ============================================ */ /* ========================================================================== */ /* Compute F = A', A (:,f)', or A (p,f)', where A is unsymmetric and F is * already allocated. The complex case performs either the array transpose * or complex conjugate transpose. * * workspace: * Iwork (MAX (nrow,ncol)) if fset is present * Iwork (nrow) if fset is NULL */ static int TEMPLATE (cholmod_transpose_unsym) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to transpose */ Int *Perm, /* size nrow, if present (can be NULL) */ Int *fset, /* subset of 0:(A->ncol)-1 */ Int nf, /* size of fset */ /* ---- output --- */ cholmod_sparse *F, /* F = A', A(:,f)', or A(p,f)' */ /* --------------- */ cholmod_common *Common ) { double *Ax, *Az, *Fx, *Fz ; Int *Ap, *Anz, *Ai, *Fp, *Fnz, *Fj, *Wi, *Iwork ; Int j, p, pend, nrow, ncol, Apacked, use_fset, fp, Fpacked, jj, permute ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ /* ensure the xtype of A and F match (ignored if this is pattern version) */ if (!XTYPE_OK (A->xtype)) { ERROR (CHOLMOD_INVALID, "real/complex mismatch") ; return (FALSE) ; } /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ use_fset = (fset != NULL) ; nrow = A->nrow ; ncol = A->ncol ; Ap = A->p ; /* size A->ncol+1, column pointers of A */ Ai = A->i ; /* size nz = Ap [A->ncol], row indices of A */ Ax = A->x ; /* size nz, real values of A */ Az = A->z ; /* size nz, imag values of A */ Anz = A->nz ; Apacked = A->packed ; ASSERT (IMPLIES (!Apacked, Anz != NULL)) ; permute = (Perm != NULL) ; Fp = F->p ; /* size A->nrow+1, row pointers of F */ Fj = F->i ; /* size nz, column indices of F */ Fx = F->x ; /* size nz, real values of F */ Fz = F->z ; /* size nz, imag values of F */ Fnz = F->nz ; Fpacked = F->packed ; ASSERT (IMPLIES (!Fpacked, Fnz != NULL)) ; nf = (use_fset) ? nf : ncol ; /* ---------------------------------------------------------------------- */ /* get workspace */ /* ---------------------------------------------------------------------- */ Iwork = Common->Iwork ; Wi = Iwork ; /* size nrow (i/l/l) */ /* ---------------------------------------------------------------------- */ /* construct the transpose */ /* ---------------------------------------------------------------------- */ for (jj = 0 ; jj < nf ; jj++) { j = (use_fset) ? (fset [jj]) : jj ; p = Ap [j] ; pend = (Apacked) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { fp = Wi [Ai [p]]++ ; Fj [fp] = j ; #ifdef NCONJUGATE ASSIGN (Fx, Fz, fp, Ax, Az, p) ; #else ASSIGN_CONJ (Fx, Fz, fp, Ax, Az, p) ; #endif } } return (TRUE) ; } /* ========================================================================== */ /* === t_cholmod_transpose_sym ============================================== */ /* ========================================================================== */ /* Compute F = A' or A (p,p)', where A is symmetric and F is already allocated. * The complex case performs either the array transpose or complex conjugate * transpose. * * workspace: Iwork (nrow) if Perm NULL, Iwork (2*nrow) if Perm non-NULL. */ static int TEMPLATE (cholmod_transpose_sym) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to transpose */ Int *Perm, /* size n, if present (can be NULL) */ /* ---- output --- */ cholmod_sparse *F, /* F = A' or A(p,p)' */ /* --------------- */ cholmod_common *Common ) { double *Ax, *Az, *Fx, *Fz ; Int *Ap, *Anz, *Ai, *Fp, *Fj, *Wi, *Pinv, *Iwork ; Int p, pend, packed, fp, upper, permute, jold, n, i, j, iold ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ /* ensure the xtype of A and F match (ignored if this is pattern version) */ if (!XTYPE_OK (A->xtype)) { ERROR (CHOLMOD_INVALID, "real/complex mismatch") ; return (FALSE) ; } /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ permute = (Perm != NULL) ; n = A->nrow ; Ap = A->p ; /* size A->ncol+1, column pointers of A */ Ai = A->i ; /* size nz = Ap [A->ncol], row indices of A */ Ax = A->x ; /* size nz, real values of A */ Az = A->z ; /* size nz, imag values of A */ Anz = A->nz ; packed = A->packed ; ASSERT (IMPLIES (!packed, Anz != NULL)) ; upper = (A->stype > 0) ; Fp = F->p ; /* size A->nrow+1, row pointers of F */ Fj = F->i ; /* size nz, column indices of F */ Fx = F->x ; /* size nz, real values of F */ Fz = F->z ; /* size nz, imag values of F */ /* ---------------------------------------------------------------------- */ /* get workspace */ /* ---------------------------------------------------------------------- */ Iwork = Common->Iwork ; Wi = Iwork ; /* size n (i/l/l) */ Pinv = Iwork + n ; /* size n (i/i/l) , unused if Perm NULL */ /* ---------------------------------------------------------------------- */ /* construct the transpose */ /* ---------------------------------------------------------------------- */ if (permute) { if (upper) { /* permuted, upper */ for (j = 0 ; j < n ; j++) { jold = Perm [j] ; p = Ap [jold] ; pend = (packed) ? Ap [jold+1] : p + Anz [jold] ; for ( ; p < pend ; p++) { iold = Ai [p] ; if (iold <= jold) { i = Pinv [iold] ; if (i < j) { fp = Wi [i]++ ; Fj [fp] = j ; #ifdef NCONJUGATE ASSIGN (Fx, Fz, fp, Ax, Az, p) ; #else ASSIGN_CONJ (Fx, Fz, fp, Ax, Az, p) ; #endif } else { fp = Wi [j]++ ; Fj [fp] = i ; ASSIGN (Fx, Fz, fp, Ax, Az, p) ; } } } } } else { /* permuted, lower */ for (j = 0 ; j < n ; j++) { jold = Perm [j] ; p = Ap [jold] ; pend = (packed) ? Ap [jold+1] : p + Anz [jold] ; for ( ; p < pend ; p++) { iold = Ai [p] ; if (iold >= jold) { i = Pinv [iold] ; if (i > j) { fp = Wi [i]++ ; Fj [fp] = j ; #ifdef NCONJUGATE ASSIGN (Fx, Fz, fp, Ax, Az, p) ; #else ASSIGN_CONJ (Fx, Fz, fp, Ax, Az, p) ; #endif } else { fp = Wi [j]++ ; Fj [fp] = i ; ASSIGN (Fx, Fz, fp, Ax, Az, p) ; } } } } } } else { if (upper) { /* unpermuted, upper */ for (j = 0 ; j < n ; j++) { p = Ap [j] ; pend = (packed) ? Ap [j+1] : p + Anz [j] ; for ( ; p < pend ; p++) { i = Ai [p] ; if (i <= j) { fp = Wi [i]++ ; Fj [fp] = j ; #ifdef NCONJUGATE ASSIGN (Fx, Fz, fp, Ax, Az, p) ; #else ASSIGN_CONJ (Fx, Fz, fp, Ax, Az, p) ; #endif } } } } else { /* unpermuted, lower */ for (j = 0 ; j < n ; j++) { p = Ap [j] ; pend = (packed) ? Ap [j+1] : p + Anz [j] ; for ( ; p < pend ; p++) { i = Ai [p] ; if (i >= j) { fp = Wi [i]++ ; Fj [fp] = j ; #ifdef NCONJUGATE ASSIGN (Fx, Fz, fp, Ax, Az, p) ; #else ASSIGN_CONJ (Fx, Fz, fp, Ax, Az, p) ; #endif } } } } } return (TRUE) ; } #undef PATTERN #undef REAL #undef COMPLEX #undef ZOMPLEX #undef NCONJUGATE �������������������������������������������������������������Matrix/src/CHOLMOD/Core/cholmod_version.c�����������������������������������������������������������0000644�0001762�0000144�00000002260�13652535054�017630� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Core/cholmod_version ================================================= */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Core Module. Copyright (C) 2005-2013, * Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* Return the current version of CHOLMOD. Unlike all other functions in CHOLMOD, this function does not require the CHOLMOD Common. */ #include "cholmod_internal.h" #include "cholmod_core.h" int CHOLMOD(version) /* returns CHOLMOD_VERSION */ ( /* output, contents not defined on input. Not used if NULL. version [0] = CHOLMOD_MAIN_VERSION ; version [1] = CHOLMOD_SUB_VERSION ; version [2] = CHOLMOD_SUBSUB_VERSION ; */ int version [3] ) { if (version != NULL) { version [0] = CHOLMOD_MAIN_VERSION ; version [1] = CHOLMOD_SUB_VERSION ; version [2] = CHOLMOD_SUBSUB_VERSION ; } return (CHOLMOD_VERSION) ; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Core/t_cholmod_triplet.c���������������������������������������������������������0000644�0001762�0000144�00000010542�13652535054�020153� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Core/t_cholmod_triplet =============================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Core Module. Copyright (C) 2005-2006, * Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* Template routine for cholmod_triplet. All xtypes supported */ #include "cholmod_template.h" /* ========================================================================== */ /* === t_cholmod_triplet_to_sparse ========================================== */ /* ========================================================================== */ static size_t TEMPLATE (cholmod_triplet_to_sparse) ( /* ---- input ---- */ cholmod_triplet *T, /* matrix to copy */ /* ---- in/out --- */ cholmod_sparse *R, /* output matrix */ /* --------------- */ cholmod_common *Common ) { double *Rx, *Rz, *Tx, *Tz ; Int *Wj, *Rp, *Ri, *Rnz, *Ti, *Tj ; Int i, j, p, p1, p2, pdest, pj, k, stype, nrow, ncol, nz ; size_t anz ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ /* Wj contains a copy of Rp on input [ */ Wj = Common->Iwork ; /* size MAX (nrow,ncol). (i/l/l) */ Rp = R->p ; Ri = R->i ; Rnz = R->nz ; Rx = R->x ; Rz = R->z ; Ti = T->i ; Tj = T->j ; Tx = T->x ; Tz = T->z ; nz = T->nnz ; nrow = T->nrow ; ncol = T->ncol ; stype = SIGN (T->stype) ; /* ---------------------------------------------------------------------- */ /* construct the row form */ /* ---------------------------------------------------------------------- */ /* if Ti is jumbled, this part dominates the run time */ if (stype > 0) { for (k = 0 ; k < nz ; k++) { i = Ti [k] ; j = Tj [k] ; if (i < j) { /* place triplet (j,i,x) in column i of R */ p = Wj [i]++ ; Ri [p] = j ; } else { /* place triplet (i,j,x) in column j of R */ p = Wj [j]++ ; Ri [p] = i ; } ASSIGN (Rx, Rz, p, Tx, Tz, k) ; } } else if (stype < 0) { for (k = 0 ; k < nz ; k++) { i = Ti [k] ; j = Tj [k] ; if (i > j) { /* place triplet (j,i,x) in column i of R */ p = Wj [i]++ ; Ri [p] = j ; } else { /* place triplet (i,j,x) in column j of R */ p = Wj [j]++ ; Ri [p] = i ; } ASSIGN (Rx, Rz, p, Tx, Tz, k) ; } } else { for (k = 0 ; k < nz ; k++) { /* place triplet (i,j,x) in column i of R */ p = Wj [Ti [k]]++ ; Ri [p] = Tj [k] ; ASSIGN (Rx, Rz, p, Tx, Tz, k) ; } } /* done using Wj (i/l/l) as temporary row pointers ] */ /* ---------------------------------------------------------------------- */ /* sum up duplicates */ /* ---------------------------------------------------------------------- */ /* use Wj (i/l/l) of size ncol to keep track of duplicates in each row [ */ for (j = 0 ; j < ncol ; j++) { Wj [j] = EMPTY ; } anz = 0 ; for (i = 0 ; i < nrow ; i++) { p1 = Rp [i] ; p2 = Rp [i+1] ; pdest = p1 ; /* at this point Wj [j] < p1 holds true for all columns j, because * Ri/Rx is stored in row oriented manner */ for (p = p1 ; p < p2 ; p++) { j = Ri [p] ; pj = Wj [j] ; if (pj >= p1) { /* this column index j is already in row i at position pj; * sum up the duplicate entry */ /* Rx [pj] += Rx [p] ; */ ASSEMBLE (Rx, Rz, pj, Rx, Rz, p) ; } else { /* keep the entry and keep track in Wj [j] for case above */ Wj [j] = pdest ; if (pdest != p) { Ri [pdest] = j ; ASSIGN (Rx, Rz, pdest, Rx, Rz, p) ; } pdest++ ; } } Rnz [i] = pdest - p1 ; anz += (pdest - p1) ; } /* done using Wj to keep track of duplicate entries in each row ] */ /* ---------------------------------------------------------------------- */ /* return number of entries after summing up duplicates */ /* ---------------------------------------------------------------------- */ return (anz) ; } #undef PATTERN #undef REAL #undef COMPLEX #undef ZOMPLEX ��������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Core/cholmod_sparse.c������������������������������������������������������������0000644�0001762�0000144�00000042431�13652535054�017444� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Core/cholmod_sparse ================================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Core Module. Copyright (C) 2005-2006, * Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* Core utility routines for the cholmod_sparse object: * * A sparse matrix is held in compressed column form. In the basic type * ("packed", which corresponds to a MATLAB sparse matrix), an n-by-n matrix * with nz entries is held in three arrays: p of size n+1, i of size nz, and x * of size nz. Row indices of column j are held in i [p [j] ... p [j+1]-1] and * in the same locations in x. There may be no duplicate entries in a column. * Row indices in each column may be sorted or unsorted (CHOLMOD keeps track). * * Primary routines: * ----------------- * cholmod_allocate_sparse allocate a sparse matrix * cholmod_free_sparse free a sparse matrix * * Secondary routines: * ------------------- * cholmod_reallocate_sparse change the size (# entries) of sparse matrix * cholmod_nnz number of nonzeros in a sparse matrix * cholmod_speye sparse identity matrix * cholmod_spzeros sparse zero matrix * cholmod_copy_sparse create a copy of a sparse matrix * * All xtypes are supported (pattern, real, complex, and zomplex) */ #include "cholmod_internal.h" #include "cholmod_core.h" /* ========================================================================== */ /* === cholmod_allocate_sparse ============================================== */ /* ========================================================================== */ /* Allocate space for a matrix. A->i and A->x are not initialized. A->p * (and A->nz if A is not packed) are set to zero, so a matrix containing no * entries (all zero) is returned. See also cholmod_spzeros. * * workspace: none */ cholmod_sparse *CHOLMOD(allocate_sparse) ( /* ---- input ---- */ size_t nrow, /* # of rows of A */ size_t ncol, /* # of columns of A */ size_t nzmax, /* max # of nonzeros of A */ int sorted, /* TRUE if columns of A sorted, FALSE otherwise */ int packed, /* TRUE if A will be packed, FALSE otherwise */ int stype, /* stype of A */ int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ /* --------------- */ cholmod_common *Common ) { cholmod_sparse *A ; Int *Ap, *Anz ; size_t nzmax0 ; Int j ; int ok = TRUE ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; if (stype != 0 && nrow != ncol) { ERROR (CHOLMOD_INVALID, "rectangular matrix with stype != 0 invalid") ; return (NULL) ; } if (xtype < CHOLMOD_PATTERN || xtype > CHOLMOD_ZOMPLEX) { ERROR (CHOLMOD_INVALID, "xtype invalid") ; return (NULL) ; } /* ensure the dimensions do not cause integer overflow */ (void) CHOLMOD(add_size_t) (ncol, 2, &ok) ; if (!ok || nrow > Int_max || ncol > Int_max || nzmax > Int_max) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (NULL) ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate header */ /* ---------------------------------------------------------------------- */ A = CHOLMOD(malloc) (sizeof (cholmod_sparse), 1, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory */ } PRINT1 (("cholmod_allocate_sparse %d-by-%d nzmax %d sorted %d packed %d" " xtype %d\n", nrow, ncol, nzmax, sorted, packed, xtype)) ; nzmax = MAX (1, nzmax) ; A->nrow = nrow ; A->ncol = ncol ; A->nzmax = nzmax ; A->packed = packed ; /* default is packed (A->nz not present) */ A->stype = stype ; A->itype = ITYPE ; A->xtype = xtype ; A->dtype = DTYPE ; A->nz = NULL ; A->p = NULL ; A->i = NULL ; A->x = NULL ; A->z = NULL ; /* A 1-by-m matrix always has sorted columns */ A->sorted = (nrow <= 1) ? TRUE : sorted ; /* ---------------------------------------------------------------------- */ /* allocate the matrix itself */ /* ---------------------------------------------------------------------- */ /* allocate O(ncol) space */ A->p = CHOLMOD(malloc) (((size_t) ncol)+1, sizeof (Int), Common) ; if (!packed) { A->nz = CHOLMOD(malloc) (ncol, sizeof (Int), Common) ; } /* allocate O(nz) space */ nzmax0 = 0 ; CHOLMOD(realloc_multiple) (nzmax, 1, xtype, &(A->i), NULL, &(A->x), &(A->z), &nzmax0, Common) ; if (Common->status < CHOLMOD_OK) { CHOLMOD(free_sparse) (&A, Common) ; return (NULL) ; /* out of memory */ } /* ---------------------------------------------------------------------- */ /* initialize A->p and A->nz so that A is an empty matrix */ /* ---------------------------------------------------------------------- */ Ap = A->p ; for (j = 0 ; j <= (Int) ncol ; j++) { Ap [j] = 0 ; } if (!packed) { Anz = A->nz ; for (j = 0 ; j < (Int) ncol ; j++) { Anz [j] = 0 ; } } return (A) ; } /* ========================================================================== */ /* === cholmod_free_sparse ================================================== */ /* ========================================================================== */ /* free a sparse matrix * * workspace: none */ int CHOLMOD(free_sparse) ( /* ---- in/out --- */ cholmod_sparse **AHandle, /* matrix to deallocate, NULL on output */ /* --------------- */ cholmod_common *Common ) { Int n, nz ; cholmod_sparse *A ; RETURN_IF_NULL_COMMON (FALSE) ; if (AHandle == NULL) { /* nothing to do */ return (TRUE) ; } A = *AHandle ; if (A == NULL) { /* nothing to do */ return (TRUE) ; } n = A->ncol ; nz = A->nzmax ; A->p = CHOLMOD(free) (n+1, sizeof (Int), A->p, Common) ; A->i = CHOLMOD(free) (nz, sizeof (Int), A->i, Common) ; A->nz = CHOLMOD(free) (n, sizeof (Int), A->nz, Common) ; switch (A->xtype) { case CHOLMOD_REAL: A->x = CHOLMOD(free) (nz, sizeof (double), A->x, Common) ; break ; case CHOLMOD_COMPLEX: A->x = CHOLMOD(free) (nz, 2*sizeof (double), A->x, Common) ; break ; case CHOLMOD_ZOMPLEX: A->x = CHOLMOD(free) (nz, sizeof (double), A->x, Common) ; A->z = CHOLMOD(free) (nz, sizeof (double), A->z, Common) ; break ; } *AHandle = CHOLMOD(free) (1, sizeof (cholmod_sparse), (*AHandle), Common) ; return (TRUE) ; } /* ========================================================================== */ /* === cholmod_reallocate_sparse ============================================ */ /* ========================================================================== */ /* Change the size of A->i, A->x, and A->z, or allocate them if their current * size is zero. A->x and A->z are not modified if A->xtype is CHOLMOD_PATTERN. * A->z is not modified unless A->xtype is CHOLMOD_ZOMPLEX. * * workspace: none */ int CHOLMOD(reallocate_sparse) ( /* ---- input ---- */ size_t nznew, /* new # of entries in A */ /* ---- in/out --- */ cholmod_sparse *A, /* matrix to reallocate */ /* --------------- */ cholmod_common *Common ) { /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; Common->status = CHOLMOD_OK ; PRINT1 (("realloc matrix %d to %d, xtype: %d\n", A->nzmax, nznew, A->xtype)) ; /* ---------------------------------------------------------------------- */ /* resize the matrix */ /* ---------------------------------------------------------------------- */ CHOLMOD(realloc_multiple) (MAX (1,nznew), 1, A->xtype, &(A->i), NULL, &(A->x), &(A->z), &(A->nzmax), Common) ; return (Common->status == CHOLMOD_OK) ; } /* ========================================================================== */ /* === cholmod_speye ======================================================== */ /* ========================================================================== */ /* Return a sparse identity matrix. */ cholmod_sparse *CHOLMOD(speye) ( /* ---- input ---- */ size_t nrow, /* # of rows of A */ size_t ncol, /* # of columns of A */ int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ /* --------------- */ cholmod_common *Common ) { double *Ax, *Az ; cholmod_sparse *A ; Int *Ap, *Ai ; Int j, n ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate the matrix */ /* ---------------------------------------------------------------------- */ n = MIN (nrow, ncol) ; A = CHOLMOD(allocate_sparse) (nrow, ncol, n, TRUE, TRUE, 0, xtype, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory or inputs invalid */ } /* ---------------------------------------------------------------------- */ /* create the identity matrix */ /* ---------------------------------------------------------------------- */ Ap = A->p ; Ai = A->i ; Ax = A->x ; Az = A->z ; for (j = 0 ; j < n ; j++) { Ap [j] = j ; } for (j = n ; j <= ((Int) ncol) ; j++) { Ap [j] = n ; } for (j = 0 ; j < n ; j++) { Ai [j] = j ; } switch (xtype) { case CHOLMOD_REAL: for (j = 0 ; j < n ; j++) { Ax [j] = 1 ; } break ; case CHOLMOD_COMPLEX: for (j = 0 ; j < n ; j++) { Ax [2*j ] = 1 ; Ax [2*j+1] = 0 ; } break ; case CHOLMOD_ZOMPLEX: for (j = 0 ; j < n ; j++) { Ax [j] = 1 ; } for (j = 0 ; j < n ; j++) { Az [j] = 0 ; } break ; } return (A) ; } /* ========================================================================== */ /* === cholmod_spzeros ====================================================== */ /* ========================================================================== */ /* Return a sparse zero matrix. */ cholmod_sparse *CHOLMOD(spzeros) ( /* ---- input ---- */ size_t nrow, /* # of rows of A */ size_t ncol, /* # of columns of A */ size_t nzmax, /* max # of nonzeros of A */ int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ /* --------------- */ cholmod_common *Common ) { /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate the matrix */ /* ---------------------------------------------------------------------- */ return (CHOLMOD(allocate_sparse) (nrow, ncol, nzmax, TRUE, TRUE, 0, xtype, Common)) ; } /* ========================================================================== */ /* === cholmod_nnz ========================================================== */ /* ========================================================================== */ /* Return the number of entries in a sparse matrix. * * workspace: none * integer overflow cannot occur, since the matrix is already allocated. */ SuiteSparse_long CHOLMOD(nnz) ( /* ---- input ---- */ cholmod_sparse *A, /* --------------- */ cholmod_common *Common ) { Int *Ap, *Anz ; size_t nz ; Int j, ncol ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (EMPTY) ; RETURN_IF_NULL (A, EMPTY) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, EMPTY) ; Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* return nnz (A) */ /* ---------------------------------------------------------------------- */ ncol = A->ncol ; if (A->packed) { Ap = A->p ; RETURN_IF_NULL (Ap, EMPTY) ; nz = Ap [ncol] ; } else { Anz = A->nz ; RETURN_IF_NULL (Anz, EMPTY) ; nz = 0 ; for (j = 0 ; j < ncol ; j++) { nz += MAX (0, Anz [j]) ; } } return (nz) ; } /* ========================================================================== */ /* === cholmod_copy_sparse ================================================== */ /* ========================================================================== */ /* C = A. Create an exact copy of a sparse matrix, with one exception. * Entries in unused space are not copied (they might not be initialized, * and copying them would cause program checkers such as purify and * valgrind to complain). The xtype of the resulting matrix C is the same as * the xtype of the input matrix A. * * See also Core/cholmod_copy, which copies a matrix with possible changes * in stype, presence of diagonal entries, pattern vs. numerical values, * real and/or imaginary parts, and so on. */ cholmod_sparse *CHOLMOD(copy_sparse) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to copy */ /* --------------- */ cholmod_common *Common ) { double *Ax, *Cx, *Az, *Cz ; Int *Ap, *Ai, *Anz, *Cp, *Ci, *Cnz ; cholmod_sparse *C ; Int p, pend, j, ncol, packed, nzmax, nz, xtype ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (A, NULL) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, NULL) ; if (A->stype != 0 && A->nrow != A->ncol) { ERROR (CHOLMOD_INVALID, "rectangular matrix with stype != 0 invalid") ; return (NULL) ; } Common->status = CHOLMOD_OK ; ASSERT (CHOLMOD(dump_sparse) (A, "A original", Common) >= 0) ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ ncol = A->ncol ; nzmax = A->nzmax ; packed = A->packed ; Ap = A->p ; Ai = A->i ; Ax = A->x ; Az = A->z ; Anz = A->nz ; xtype = A->xtype ; /* ---------------------------------------------------------------------- */ /* allocate the copy */ /* ---------------------------------------------------------------------- */ C = CHOLMOD(allocate_sparse) (A->nrow, A->ncol, A->nzmax, A->sorted, A->packed, A->stype, A->xtype, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory */ } Cp = C->p ; Ci = C->i ; Cx = C->x ; Cz = C->z ; Cnz = C->nz ; /* ---------------------------------------------------------------------- */ /* copy the matrix */ /* ---------------------------------------------------------------------- */ for (j = 0 ; j <= ncol ; j++) { Cp [j] = Ap [j] ; } if (packed) { nz = Ap [ncol] ; for (p = 0 ; p < nz ; p++) { Ci [p] = Ai [p] ; } switch (xtype) { case CHOLMOD_REAL: for (p = 0 ; p < nz ; p++) { Cx [p] = Ax [p] ; } break ; case CHOLMOD_COMPLEX: for (p = 0 ; p < 2*nz ; p++) { Cx [p] = Ax [p] ; } break ; case CHOLMOD_ZOMPLEX: for (p = 0 ; p < nz ; p++) { Cx [p] = Ax [p] ; Cz [p] = Az [p] ; } break ; } } else { for (j = 0 ; j < ncol ; j++) { Cnz [j] = Anz [j] ; } switch (xtype) { case CHOLMOD_PATTERN: for (j = 0 ; j < ncol ; j++) { p = Ap [j] ; pend = p + Anz [j] ; for ( ; p < pend ; p++) { Ci [p] = Ai [p] ; } } break ; case CHOLMOD_REAL: for (j = 0 ; j < ncol ; j++) { p = Ap [j] ; pend = p + Anz [j] ; for ( ; p < pend ; p++) { Ci [p] = Ai [p] ; Cx [p] = Ax [p] ; } } break ; case CHOLMOD_COMPLEX: for (j = 0 ; j < ncol ; j++) { p = Ap [j] ; pend = p + Anz [j] ; for ( ; p < pend ; p++) { Ci [p] = Ai [p] ; Cx [2*p ] = Ax [2*p ] ; Cx [2*p+1] = Ax [2*p+1] ; } } break ; case CHOLMOD_ZOMPLEX: for (j = 0 ; j < ncol ; j++) { p = Ap [j] ; pend = p + Anz [j] ; for ( ; p < pend ; p++) { Ci [p] = Ai [p] ; Cx [p] = Ax [p] ; Cz [p] = Az [p] ; } } break ; } } /* ---------------------------------------------------------------------- */ /* return the result */ /* ---------------------------------------------------------------------- */ ASSERT (CHOLMOD(dump_sparse) (C, "C copy", Common) >= 0) ; return (C) ; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Core/cholmod_factor.c������������������������������������������������������������0000644�0001762�0000144�00000065203�13652535054�017427� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Core/cholmod_factor ================================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Core Module. Copyright (C) 2005-2013, * Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* Core utility routines for the cholmod_factor object: * * The data structure for an LL' or LDL' factorization is too complex to * describe in one sentence. This object can hold the symbolic analysis alone, * or in combination with a "simplicial" (similar to a sparse matrix) or * "supernodal" form of the numerical factorization. Only the routine to free * a factor is primary, since a factor object is created by the factorization * routine (cholmod_factorize). It must be freed with cholmod_free_factor. * * Primary routine: * ---------------- * cholmod_free_factor free a factor * * Secondary routines: * ------------------- * cholmod_allocate_factor allocate a symbolic factor (LL' or LDL') * cholmod_reallocate_factor change the # entries in a factor * cholmod_change_factor change the type of factor (e.g., LDL' to LL') * cholmod_pack_factor pack the columns of a factor * cholmod_reallocate_column resize a single column of a factor * cholmod_factor_to_sparse create a sparse matrix copy of a factor * cholmod_copy_factor create a copy of a factor * * Note that there is no cholmod_sparse_to_factor routine to create a factor * as a copy of a sparse matrix. It could be done, after a fashion, but a * lower triangular sparse matrix would not necessarily have a chordal graph, * which would break the many CHOLMOD routines that rely on this property. * * The cholmod_factor_to_sparse routine is provided so that matrix operations * in the MatrixOps module may be applied to L. Those operations operate on * cholmod_sparse objects, and they are not guaranteed to maintain the chordal * property of L. Such a modified L cannot be safely converted back to a * cholmod_factor object. */ #include "cholmod_internal.h" #include "cholmod_core.h" /* ========================================================================== */ /* === cholmod_allocate_factor ============================================== */ /* ========================================================================== */ /* Allocate a simplicial symbolic factor, with L->Perm and L->ColCount allocated * and initialized to "empty" values (Perm [k] = k, and ColCount[k] = 1). * The integer and numerical parts of L are not allocated. L->xtype is returned * as CHOLMOD_PATTERN and L->is_super are returned as FALSE. L->is_ll is also * returned FALSE, but this may be modified when the matrix is factorized. * * This is sufficient (but far from ideal) for input to cholmod_factorize, * since the simplicial LL' or LDL' factorization (cholmod_rowfac) can * reallocate the columns of L as needed. The primary purpose of this routine * is to allocate space for a symbolic factorization, for the "expert" user to * do his or her own symbolic analysis. The typical user should use * cholmod_analyze instead of this routine. * * workspace: none */ cholmod_factor *CHOLMOD(allocate_factor) ( /* ---- input ---- */ size_t n, /* L is n-by-n */ /* --------------- */ cholmod_common *Common ) { Int j ; Int *Perm, *ColCount ; cholmod_factor *L ; int ok = TRUE ; RETURN_IF_NULL_COMMON (FALSE) ; Common->status = CHOLMOD_OK ; /* ensure the dimension does not cause integer overflow */ (void) CHOLMOD(add_size_t) (n, 2, &ok) ; if (!ok || n > Int_max) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (NULL) ; } L = CHOLMOD(malloc) (sizeof (cholmod_factor), 1, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory */ } L->n = n ; L->is_ll = FALSE ; L->is_super = FALSE ; L->is_monotonic = TRUE ; L->itype = ITYPE ; L->xtype = CHOLMOD_PATTERN ; L->dtype = DTYPE ; /* allocate the purely symbolic part of L */ L->ordering = CHOLMOD_NATURAL ; L->Perm = CHOLMOD(malloc) (n, sizeof (Int), Common) ; L->IPerm = NULL ; /* only created by cholmod_solve2 when needed */ L->ColCount = CHOLMOD(malloc) (n, sizeof (Int), Common) ; /* simplicial part of L is empty */ L->nzmax = 0 ; L->p = NULL ; L->i = NULL ; L->x = NULL ; L->z = NULL ; L->nz = NULL ; L->next = NULL ; L->prev = NULL ; /* supernodal part of L is also empty */ L->nsuper = 0 ; L->ssize = 0 ; L->xsize = 0 ; L->maxesize = 0 ; L->maxcsize = 0 ; L->super = NULL ; L->pi = NULL ; L->px = NULL ; L->s = NULL ; L->useGPU = 0; /* L has not been factorized */ L->minor = n ; if (Common->status < CHOLMOD_OK) { CHOLMOD(free_factor) (&L, Common) ; return (NULL) ; /* out of memory */ } /* initialize Perm and ColCount */ Perm = L->Perm ; for (j = 0 ; j < ((Int) n) ; j++) { Perm [j] = j ; } ColCount = L->ColCount ; for (j = 0 ; j < ((Int) n) ; j++) { ColCount [j] = 1 ; } return (L) ; } /* ========================================================================== */ /* === cholmod_free_factor ================================================== */ /* ========================================================================== */ /* Free a factor object. * * workspace: none */ int CHOLMOD(free_factor) ( /* ---- in/out --- */ cholmod_factor **LHandle, /* factor to free, NULL on output */ /* --------------- */ cholmod_common *Common ) { Int n, lnz, xs, ss, s ; cholmod_factor *L ; RETURN_IF_NULL_COMMON (FALSE) ; if (LHandle == NULL) { /* nothing to do */ return (TRUE) ; } L = *LHandle ; if (L == NULL) { /* nothing to do */ return (TRUE) ; } n = L->n ; lnz = L->nzmax ; s = L->nsuper + 1 ; xs = (L->is_super) ? ((Int) (L->xsize)) : (lnz) ; ss = L->ssize ; /* symbolic part of L */ CHOLMOD(free) (n, sizeof (Int), L->Perm, Common) ; CHOLMOD(free) (n, sizeof (Int), L->IPerm, Common) ; CHOLMOD(free) (n, sizeof (Int), L->ColCount, Common) ; /* simplicial form of L */ CHOLMOD(free) (n+1, sizeof (Int), L->p, Common) ; CHOLMOD(free) (lnz, sizeof (Int), L->i, Common) ; CHOLMOD(free) (n, sizeof (Int), L->nz, Common) ; CHOLMOD(free) (n+2, sizeof (Int), L->next, Common) ; CHOLMOD(free) (n+2, sizeof (Int), L->prev, Common) ; /* supernodal form of L */ CHOLMOD(free) (s, sizeof (Int), L->pi, Common) ; CHOLMOD(free) (s, sizeof (Int), L->px, Common) ; CHOLMOD(free) (s, sizeof (Int), L->super, Common) ; CHOLMOD(free) (ss, sizeof (Int), L->s, Common) ; /* numerical values for both simplicial and supernodal L */ if (L->xtype == CHOLMOD_REAL) { CHOLMOD(free) (xs, sizeof (double), L->x, Common) ; } else if (L->xtype == CHOLMOD_COMPLEX) { CHOLMOD(free) (xs, 2*sizeof (double), L->x, Common) ; } else if (L->xtype == CHOLMOD_ZOMPLEX) { CHOLMOD(free) (xs, sizeof (double), L->x, Common) ; CHOLMOD(free) (xs, sizeof (double), L->z, Common) ; } *LHandle = CHOLMOD(free) (1, sizeof (cholmod_factor), (*LHandle), Common) ; return (TRUE) ; } /* ========================================================================== */ /* === cholmod_reallocate_factor ============================================ */ /* ========================================================================== */ /* Change the size of L->i and L->x, or allocate them if their current size * is zero. L must be simplicial. * * workspace: none */ int CHOLMOD(reallocate_factor) ( /* ---- input ---- */ size_t nznew, /* new # of entries in L */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ /* --------------- */ cholmod_common *Common ) { /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (L, FALSE) ; RETURN_IF_XTYPE_INVALID (L, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; PRINT1 (("realloc factor: xtype %d\n", L->xtype)) ; if (L->is_super) { /* L must be simplicial, and not symbolic */ ERROR (CHOLMOD_INVALID, "L invalid") ; return (FALSE) ; } Common->status = CHOLMOD_OK ; PRINT1 (("realloc factor %g to %g\n", (double) L->nzmax, (double) nznew)) ; /* ---------------------------------------------------------------------- */ /* resize (or allocate) the L->i and L->x components of the factor */ /* ---------------------------------------------------------------------- */ CHOLMOD(realloc_multiple) (nznew, 1, L->xtype, &(L->i), NULL, &(L->x), &(L->z), &(L->nzmax), Common) ; return (Common->status == CHOLMOD_OK) ; } /* ========================================================================== */ /* === cholmod_reallocate_column =========================================== */ /* ========================================================================== */ /* Column j needs more space, reallocate it at the end of L->i and L->x. * If the reallocation fails, the factor is converted to a simplicial * symbolic factor (no pattern, just L->Perm and L->ColCount). * * workspace: none */ int CHOLMOD(reallocate_column) ( /* ---- input ---- */ size_t j, /* the column to reallocate */ size_t need, /* required size of column j */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ /* --------------- */ cholmod_common *Common ) { double xneed ; double *Lx, *Lz ; Int *Lp, *Lprev, *Lnext, *Li, *Lnz ; Int n, pold, pnew, len, k, tail ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (L, FALSE) ; RETURN_IF_XTYPE_INVALID (L, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; if (L->is_super) { ERROR (CHOLMOD_INVALID, "L must be simplicial") ; return (FALSE) ; } n = L->n ; if (j >= L->n || need == 0) { ERROR (CHOLMOD_INVALID, "j invalid") ; return (FALSE) ; /* j out of range */ } Common->status = CHOLMOD_OK ; DEBUG (CHOLMOD(dump_factor) (L, "start colrealloc", Common)) ; /* ---------------------------------------------------------------------- */ /* increase the size of L if needed */ /* ---------------------------------------------------------------------- */ /* head = n+1 ; */ tail = n ; Lp = L->p ; Lnz = L->nz ; Lprev = L->prev ; Lnext = L->next ; ASSERT (Lnz != NULL) ; ASSERT (Lnext != NULL && Lprev != NULL) ; PRINT1 (("col %g need %g\n", (double) j, (double) need)) ; /* column j cannot have more than n-j entries if all entries are present */ need = MIN (need, n-j) ; /* compute need in double to avoid integer overflow */ if (Common->grow1 >= 1.0) { xneed = (double) need ; xneed = Common->grow1 * xneed + Common->grow2 ; xneed = MIN (xneed, n-j) ; need = (Int) xneed ; } PRINT1 (("really new need %g current %g\n", (double) need, (double) (Lp [Lnext [j]] - Lp [j]))) ; ASSERT (need >= 1 && need <= n-j) ; if (Lp [Lnext [j]] - Lp [j] >= (Int) need) { /* no need to reallocate the column, it's already big enough */ PRINT1 (("colrealloc: quick return %g %g\n", (double) (Lp [Lnext [j]] - Lp [j]), (double) need)) ; return (TRUE) ; } if (Lp [tail] + need > L->nzmax) { /* use double to avoid integer overflow */ xneed = (double) need ; if (Common->grow0 < 1.2) /* fl. pt. compare, false if NaN */ { /* if grow0 is less than 1.2 or NaN, don't use it */ xneed = 1.2 * (((double) L->nzmax) + xneed + 1) ; } else { xneed = Common->grow0 * (((double) L->nzmax) + xneed + 1) ; } if (xneed > Size_max || !CHOLMOD(reallocate_factor) ((Int) xneed, L, Common)) { /* out of memory, convert to simplicial symbolic */ CHOLMOD(change_factor) (CHOLMOD_PATTERN, L->is_ll, FALSE, TRUE, TRUE, L, Common) ; ERROR (CHOLMOD_OUT_OF_MEMORY, "out of memory; L now symbolic") ; return (FALSE) ; /* out of memory */ } PRINT1 (("\n=== GROW L from %g to %g\n", (double) L->nzmax, (double) xneed)) ; /* pack all columns so that each column has at most grow2 free space */ CHOLMOD(pack_factor) (L, Common) ; ASSERT (Common->status == CHOLMOD_OK) ; Common->nrealloc_factor++ ; } /* ---------------------------------------------------------------------- */ /* reallocate the column */ /* ---------------------------------------------------------------------- */ Common->nrealloc_col++ ; Li = L->i ; Lx = L->x ; Lz = L->z ; /* remove j from its current position in the list */ Lnext [Lprev [j]] = Lnext [j] ; Lprev [Lnext [j]] = Lprev [j] ; /* place j at the end of the list */ Lnext [Lprev [tail]] = j ; Lprev [j] = Lprev [tail] ; Lnext [j] = n ; Lprev [tail] = j ; /* L is no longer monotonic; columns are out-of-order */ L->is_monotonic = FALSE ; /* allocate space for column j */ pold = Lp [j] ; pnew = Lp [tail] ; Lp [j] = pnew ; Lp [tail] += need ; /* copy column j to the new space */ len = Lnz [j] ; for (k = 0 ; k < len ; k++) { Li [pnew + k] = Li [pold + k] ; } if (L->xtype == CHOLMOD_REAL) { for (k = 0 ; k < len ; k++) { Lx [pnew + k] = Lx [pold + k] ; } } else if (L->xtype == CHOLMOD_COMPLEX) { for (k = 0 ; k < len ; k++) { Lx [2*(pnew + k) ] = Lx [2*(pold + k) ] ; Lx [2*(pnew + k)+1] = Lx [2*(pold + k)+1] ; } } else if (L->xtype == CHOLMOD_ZOMPLEX) { for (k = 0 ; k < len ; k++) { Lx [pnew + k] = Lx [pold + k] ; Lz [pnew + k] = Lz [pold + k] ; } } DEBUG (CHOLMOD(dump_factor) (L, "colrealloc done", Common)) ; /* successful reallocation of column j of L */ return (TRUE) ; } /* ========================================================================== */ /* === cholmod_pack_factor ================================================== */ /* ========================================================================== */ /* Pack the columns of a simplicial LDL' or LL' factor. This can be followed * by a call to cholmod_reallocate_factor to reduce the size of L to the exact * size required by the factor, if desired. Alternatively, you can leave the * size of L->i and L->x the same, to allow space for future updates/rowadds. * * Each column is reduced in size so that it has at most Common->grow2 free * space at the end of the column. * * Does nothing and returns silently if given any other type of factor. * * Does NOT force the columns of L to be monotonic. It thus differs from * cholmod_change_factor (xtype, -, FALSE, TRUE, TRUE, L, Common), which * packs the columns and ensures that they appear in monotonic order. */ int CHOLMOD(pack_factor) ( /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ /* --------------- */ cholmod_common *Common ) { double *Lx, *Lz ; Int *Lp, *Li, *Lnz, *Lnext ; Int pnew, j, k, pold, len, n, head, tail, grow2 ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (L, FALSE) ; RETURN_IF_XTYPE_INVALID (L, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; Common->status = CHOLMOD_OK ; DEBUG (CHOLMOD(dump_factor) (L, "start pack", Common)) ; PRINT1 (("PACK factor %d\n", L->is_super)) ; if (L->xtype == CHOLMOD_PATTERN || L->is_super) { /* nothing to do unless L is simplicial numeric */ return (TRUE) ; } /* ---------------------------------------------------------------------- */ /* pack */ /* ---------------------------------------------------------------------- */ grow2 = Common->grow2 ; PRINT1 (("\nPACK grow2 "ID"\n", grow2)) ; pnew = 0 ; n = L->n ; Lp = L->p ; Li = L->i ; Lx = L->x ; Lz = L->z ; Lnz = L->nz ; Lnext = L->next ; head = n+1 ; tail = n ; for (j = Lnext [head] ; j != tail ; j = Lnext [j]) { /* pack column j */ pold = Lp [j] ; len = Lnz [j] ; ASSERT (len > 0) ; PRINT2 (("col "ID" pnew "ID" pold "ID"\n", j, pnew, pold)) ; if (pnew < pold) { PRINT2 ((" pack this column\n")) ; for (k = 0 ; k < len ; k++) { Li [pnew + k] = Li [pold + k] ; } if (L->xtype == CHOLMOD_REAL) { for (k = 0 ; k < len ; k++) { Lx [pnew + k] = Lx [pold + k] ; } } else if (L->xtype == CHOLMOD_COMPLEX) { for (k = 0 ; k < len ; k++) { Lx [2*(pnew + k) ] = Lx [2*(pold + k) ] ; Lx [2*(pnew + k)+1] = Lx [2*(pold + k)+1] ; } } else if (L->xtype == CHOLMOD_ZOMPLEX) { for (k = 0 ; k < len ; k++) { Lx [pnew + k] = Lx [pold + k] ; Lz [pnew + k] = Lz [pold + k] ; } } Lp [j] = pnew ; } len = MIN (len + grow2, n - j) ; pnew = MIN (Lp [j] + len, Lp [Lnext [j]]) ; } PRINT2 (("final pnew = "ID"\n", pnew)) ; return (TRUE) ; } /* ========================================================================== */ /* === cholmod_factor_to_sparse ============================================= */ /* ========================================================================== */ /* Constructs a column-oriented sparse matrix containing the pattern and values * of a simplicial or supernodal numerical factor, and then converts the factor * into a simplicial symbolic factor. If L is already packed, monotonic, * and simplicial (which is the case when cholmod_factorize uses the simplicial * Cholesky factorization algorithm) then this routine requires only O(1) * memory and takes O(1) time. * * Only operates on numeric factors (real, complex, or zomplex). Does not * change the numeric L->xtype (the resulting sparse matrix has the same xtype * as L). If this routine fails, L is left unmodified. */ cholmod_sparse *CHOLMOD(factor_to_sparse) ( /* ---- in/out --- */ cholmod_factor *L, /* factor to copy, converted to symbolic on output */ /* --------------- */ cholmod_common *Common ) { cholmod_sparse *Lsparse ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (L, NULL) ; RETURN_IF_XTYPE_INVALID (L, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, NULL) ; Common->status = CHOLMOD_OK ; DEBUG (CHOLMOD(dump_factor) (L, "start convert to matrix", Common)) ; /* ---------------------------------------------------------------------- */ /* convert to packed, monotonic, simplicial, numeric */ /* ---------------------------------------------------------------------- */ /* leave as LL or LDL' */ if (!CHOLMOD(change_factor) (L->xtype, L->is_ll, FALSE, TRUE, TRUE, L, Common)) { ERROR (CHOLMOD_INVALID, "cannot convert L") ; return (NULL) ; } /* ---------------------------------------------------------------------- */ /* create Lsparse */ /* ---------------------------------------------------------------------- */ /* allocate the header for Lsparse, the sparse matrix version of L */ Lsparse = CHOLMOD(malloc) (sizeof (cholmod_sparse), 1, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory */ } /* transfer the contents from L to Lsparse */ Lsparse->nrow = L->n ; Lsparse->ncol = L->n ; Lsparse->p = L->p ; Lsparse->i = L->i ; Lsparse->x = L->x ; Lsparse->z = L->z ; Lsparse->nz = NULL ; Lsparse->stype = 0 ; Lsparse->itype = L->itype ; Lsparse->xtype = L->xtype ; Lsparse->dtype = L->dtype ; Lsparse->sorted = TRUE ; Lsparse->packed = TRUE ; Lsparse->nzmax = L->nzmax ; ASSERT (CHOLMOD(dump_sparse) (Lsparse, "Lsparse", Common) >= 0) ; /* ---------------------------------------------------------------------- */ /* convert L to symbolic, but do not free contents transfered to Lsparse */ /* ---------------------------------------------------------------------- */ L->p = NULL ; L->i = NULL ; L->x = NULL ; L->z = NULL ; L->xtype = CHOLMOD_PATTERN ; CHOLMOD(change_factor) (CHOLMOD_PATTERN, FALSE, FALSE, TRUE, TRUE, L, Common) ; return (Lsparse) ; } /* ========================================================================== */ /* === cholmod_copy_factor ================================================== */ /* ========================================================================== */ /* Create an exact copy of a factor, with one exception: * * Entries in unused space are not copied (they might not be initialized, * and copying them would cause program checkers such as purify and * valgrind to complain). * * Note that a supernodal L cannot be zomplex. */ cholmod_factor *CHOLMOD(copy_factor) ( /* ---- input ---- */ cholmod_factor *L, /* factor to copy */ /* --------------- */ cholmod_common *Common ) { cholmod_factor *L2 ; double *Lx, *L2x, *Lz, *L2z ; Int *Perm, *ColCount, *Lp, *Li, *Lnz, *Lnext, *Lprev, *Lsuper, *Lpi, *Lpx, *Ls, *Perm2, *ColCount2, *L2p, *L2i, *L2nz, *L2next, *L2prev, *L2super, *L2pi, *L2px, *L2s ; Int n, j, p, pend, s, xsize, ssize, nsuper ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (L, NULL) ; RETURN_IF_XTYPE_INVALID (L, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, NULL) ; Common->status = CHOLMOD_OK ; DEBUG (CHOLMOD(dump_factor) (L, "start copy", Common)) ; n = L->n ; /* ---------------------------------------------------------------------- */ /* allocate a simplicial symbolic factor */ /* ---------------------------------------------------------------------- */ /* allocates L2->Perm and L2->ColCount */ L2 = CHOLMOD(allocate_factor) (n, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory */ } ASSERT (L2->xtype == CHOLMOD_PATTERN && !(L2->is_super)) ; Perm = L->Perm ; ColCount = L->ColCount ; Perm2 = L2->Perm ; ColCount2 = L2->ColCount ; L2->ordering = L->ordering ; for (j = 0 ; j < n ; j++) { Perm2 [j] = Perm [j] ; } for (j = 0 ; j < n ; j++) { ColCount2 [j] = ColCount [j] ; } L2->is_ll = L->is_ll ; /* ---------------------------------------------------------------------- */ /* copy the rest of the factor */ /* ---------------------------------------------------------------------- */ if (L->xtype != CHOLMOD_PATTERN && !(L->super)) { /* ------------------------------------------------------------------ */ /* allocate a simplicial numeric factor */ /* ------------------------------------------------------------------ */ /* allocate L2->p, L2->nz, L2->prev, L2->next, L2->i, and L2->x. * packed = -1 so that cholmod_change_factor allocates space of * size L2->nzmax */ L2->nzmax = L->nzmax ; if (!CHOLMOD(change_factor) (L->xtype, L->is_ll, FALSE, -1, TRUE, L2, Common)) { CHOLMOD(free_factor) (&L2, Common) ; return (NULL) ; /* out of memory */ } ASSERT (MAX (1, L->nzmax) == L2->nzmax) ; /* ------------------------------------------------------------------ */ /* copy the contents of a simplicial numeric factor */ /* ------------------------------------------------------------------ */ Lp = L->p ; Li = L->i ; Lx = L->x ; Lz = L->z ; Lnz = L->nz ; Lnext = L->next ; Lprev = L->prev ; L2p = L2->p ; L2i = L2->i ; L2x = L2->x ; L2z = L2->z ; L2nz = L2->nz ; L2next = L2->next ; L2prev = L2->prev ; L2->xtype = L->xtype ; L2->dtype = L->dtype ; for (j = 0 ; j <= n ; j++) { L2p [j] = Lp [j] ; } for (j = 0 ; j < n+2 ; j++) { L2prev [j] = Lprev [j] ; } for (j = 0 ; j < n+2 ; j++) { L2next [j] = Lnext [j] ; } for (j = 0 ; j < n ; j++) { L2nz [j] = Lnz [j] ; } for (j = 0 ; j < n ; j++) { p = Lp [j] ; pend = p + Lnz [j] ; for ( ; p < pend ; p++) { L2i [p] = Li [p] ; } p = Lp [j] ; if (L->xtype == CHOLMOD_REAL) { for ( ; p < pend ; p++) { L2x [p] = Lx [p] ; } } else if (L->xtype == CHOLMOD_COMPLEX) { for ( ; p < pend ; p++) { L2x [2*p ] = Lx [2*p ] ; L2x [2*p+1] = Lx [2*p+1] ; } } else if (L->xtype == CHOLMOD_ZOMPLEX) { for ( ; p < pend ; p++) { L2x [p] = Lx [p] ; L2z [p] = Lz [p] ; } } } } else if (L->is_super) { /* ------------------------------------------------------------------ */ /* copy a supernodal factor */ /* ------------------------------------------------------------------ */ xsize = L->xsize ; ssize = L->ssize ; nsuper = L->nsuper ; L2->xsize = xsize ; L2->ssize = ssize ; L2->nsuper = nsuper ; /* allocate L2->super, L2->pi, L2->px, and L2->s. Allocate L2->x if * L is numeric */ if (!CHOLMOD(change_factor) (L->xtype, TRUE, TRUE, TRUE, TRUE, L2, Common)) { CHOLMOD(free_factor) (&L2, Common) ; return (NULL) ; /* out of memory */ } ASSERT (L2->s != NULL) ; /* ------------------------------------------------------------------ */ /* copy the contents of a supernodal factor */ /* ------------------------------------------------------------------ */ Lsuper = L->super ; Lpi = L->pi ; Lpx = L->px ; Ls = L->s ; Lx = L->x ; L2super = L2->super ; L2pi = L2->pi ; L2px = L2->px ; L2s = L2->s ; L2x = L2->x ; L2->maxcsize = L->maxcsize ; L2->maxesize = L->maxesize ; for (s = 0 ; s <= nsuper ; s++) { L2super [s] = Lsuper [s] ; } for (s = 0 ; s <= nsuper ; s++) { L2pi [s] = Lpi [s] ; } for (s = 0 ; s <= nsuper ; s++) { L2px [s] = Lpx [s] ; } L2s [0] = 0 ; for (p = 0 ; p < ssize ; p++) { L2s [p] = Ls [p] ; } if (L->xtype == CHOLMOD_REAL) { for (p = 0 ; p < xsize ; p++) { L2x [p] = Lx [p] ; } } else if (L->xtype == CHOLMOD_COMPLEX) { for (p = 0 ; p < 2*xsize ; p++) { L2x [p] = Lx [p] ; } } } L2->minor = L->minor ; L2->is_monotonic = L->is_monotonic ; DEBUG (CHOLMOD(dump_factor) (L2, "L2 got copied", Common)) ; ASSERT (L2->xtype == L->xtype && L2->is_super == L->is_super) ; return (L2) ; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Core/t_cholmod_dense.c�����������������������������������������������������������0000644�0001762�0000144�00000015650�13652535054�017573� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Core/t_cholmod_dense ================================================= */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Core Module. Copyright (C) 2005-2006, * Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* Template routine for cholmod_dense. All xtypes supported, except that there * are no dense matrices with an xtype of pattern. */ #include "cholmod_template.h" /* ========================================================================== */ /* === t_cholmod_sparse_to_dense ============================================ */ /* ========================================================================== */ static cholmod_dense *TEMPLATE (cholmod_sparse_to_dense) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to copy */ /* --------------- */ cholmod_common *Common ) { double *Ax, *Xx, *Az, *Xz ; Int *Ap, *Ai, *Anz ; cholmod_dense *X ; Int i, j, p, pend, nrow, ncol, packed ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ nrow = A->nrow ; ncol = A->ncol ; packed = A->packed ; Ap = A->p ; Ai = A->i ; Ax = A->x ; Az = A->z ; Anz = A->nz ; /* ---------------------------------------------------------------------- */ /* allocate result */ /* ---------------------------------------------------------------------- */ X = CHOLMOD(zeros) (nrow, ncol, XTYPE2, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory */ } Xx = X->x ; Xz = X->z ; /* ---------------------------------------------------------------------- */ /* copy into dense matrix */ /* ---------------------------------------------------------------------- */ if (A->stype < 0) { /* A is symmetric with lower stored, but both parts of X are present */ for (j = 0 ; j < ncol ; j++) { p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; if (i >= j) { ASSIGN2 (Xx, Xz, i+j*nrow, Ax, Az, p) ; ASSIGN2_CONJ (Xx, Xz, j+i*nrow, Ax, Az, p) ; } } } } else if (A->stype > 0) { /* A is symmetric with upper stored, but both parts of X are present */ for (j = 0 ; j < ncol ; j++) { p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; if (i <= j) { ASSIGN2 (Xx, Xz, i+j*nrow, Ax, Az, p) ; ASSIGN2_CONJ (Xx, Xz, j+i*nrow, Ax, Az, p) ; } } } } else { /* both parts of A and X are present */ for (j = 0 ; j < ncol ; j++) { p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; ASSIGN2 (Xx, Xz, i+j*nrow, Ax, Az, p) ; } } } return (X) ; } #ifndef PATTERN /* There are no dense matrices of xtype CHOLMOD_PATTERN */ /* ========================================================================== */ /* === t_cholmod_dense_to_sparse ============================================ */ /* ========================================================================== */ static cholmod_sparse *TEMPLATE (cholmod_dense_to_sparse) ( /* ---- input ---- */ cholmod_dense *X, /* matrix to copy */ int values, /* TRUE if values to be copied, FALSE otherwise */ /* --------------- */ cholmod_common *Common ) { double *Xx, *Cx, *Xz, *Cz ; Int *Ci, *Cp ; cholmod_sparse *C ; Int i, j, p, d, nrow, ncol, nz ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ nrow = X->nrow ; ncol = X->ncol ; d = X->d ; Xx = X->x ; Xz = X->z ; /* ---------------------------------------------------------------------- */ /* count the number of nonzeros in the result */ /* ---------------------------------------------------------------------- */ nz = 0 ; for (j = 0 ; j < ncol ; j++) { for (i = 0 ; i < nrow ; i++) { if (ENTRY_IS_NONZERO (Xx, Xz, i+j*d)) { nz++ ; } } } /* ---------------------------------------------------------------------- */ /* allocate the result C */ /* ---------------------------------------------------------------------- */ C = CHOLMOD(allocate_sparse) (nrow, ncol, nz, TRUE, TRUE, 0, values ? XTYPE : CHOLMOD_PATTERN, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory */ } Cp = C->p ; Ci = C->i ; Cx = C->x ; Cz = C->z ; /* ---------------------------------------------------------------------- */ /* copy the dense matrix X into the sparse matrix C */ /* ---------------------------------------------------------------------- */ p = 0 ; for (j = 0 ; j < ncol ; j++) { Cp [j] = p ; for (i = 0 ; i < nrow ; i++) { if (ENTRY_IS_NONZERO (Xx, Xz, i+j*d)) { Ci [p] = i ; if (values) { ASSIGN (Cx, Cz, p, Xx, Xz, i+j*d) ; } p++ ; } } } ASSERT (p == nz) ; Cp [ncol] = nz ; /* ---------------------------------------------------------------------- */ /* return result */ /* ---------------------------------------------------------------------- */ ASSERT (CHOLMOD(dump_sparse) (C, "C", Common) >= 0) ; return (C) ; } /* ========================================================================== */ /* === t_cholmod_copy_dense2 ================================================ */ /* ========================================================================== */ /* Y = X, where X and Y are both already allocated. */ static int TEMPLATE (cholmod_copy_dense2) ( /* ---- input ---- */ cholmod_dense *X, /* matrix to copy */ /* ---- output --- */ cholmod_dense *Y /* copy of matrix X */ ) { double *Xx, *Xz, *Yx, *Yz ; Int i, j, nrow, ncol, dy, dx ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ Xx = X->x ; Xz = X->z ; Yx = Y->x ; Yz = Y->z ; dx = X->d ; dy = Y->d ; nrow = X->nrow ; ncol = X->ncol ; /* ---------------------------------------------------------------------- */ /* copy */ /* ---------------------------------------------------------------------- */ CLEAR (Yx, Yz, 0) ; for (j = 0 ; j < ncol ; j++) { for (i = 0 ; i < nrow ; i++) { ASSIGN (Yx, Yz, i+j*dy, Xx, Xz, i+j*dx) ; } } return (TRUE) ; } #endif #undef PATTERN #undef REAL #undef COMPLEX #undef ZOMPLEX ����������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Core/License.txt�����������������������������������������������������������������0000644�0001762�0000144�00000002072�11770402705�016411� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CHOLMOD/Core Module. Copyright (C) 2005-2006, Univ. of Florida. Author: Timothy A. Davis CHOLMOD is also available under other licenses; contact authors for details. http://www.suitesparse.com Note that this license is for the CHOLMOD/Core module only. All CHOLMOD modules are licensed separately. -------------------------------------------------------------------------------- This Module is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This Module 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this Module; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Core/cholmod_memory.c������������������������������������������������������������0000644�0001762�0000144�00000040644�13652535054�017463� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Core/cholmod_memory ================================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Core Module. Copyright (C) 2005-2013, * Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* Core memory management routines: * * Primary routines: * ----------------- * cholmod_malloc malloc wrapper * cholmod_free free wrapper * * Secondary routines: * ------------------- * cholmod_calloc calloc wrapper * cholmod_realloc realloc wrapper * cholmod_realloc_multiple realloc wrapper for multiple objects * * The user may make use of these, just like malloc and free. You can even * malloc an object and safely free it with cholmod_free, and visa versa * (except that the memory usage statistics will be corrupted). These routines * do differ from malloc and free. If cholmod_free is given a NULL pointer, * for example, it does nothing (unlike the ANSI free). cholmod_realloc does * not return NULL if given a non-NULL pointer and a nonzero size, even if it * fails (it sets an error code in Common->status instead). * * CHOLMOD keeps track of the amount of memory it has allocated, and so the * cholmod_free routine includes as a parameter the size of the object being * freed. This is only used for memory usage statistics, which are very useful * in finding memory leaks in your program. If you, the user of CHOLMOD, pass * the wrong size, the only consequence is that the memory usage statistics * will be invalid. This will causes assertions to fail if CHOLMOD is * compiled with debugging enabled, but otherwise it will cause no errors. * * The cholmod_free_* routines for each CHOLMOD object keep track of the size * of the blocks they free, so they do not require you to pass their sizes * as a parameter. * * If a block of size zero is requested, these routines allocate a block of * size one instead. */ #include "cholmod_internal.h" #include "cholmod_core.h" /* ========================================================================== */ /* === cholmod_add_size_t =================================================== */ /* ========================================================================== */ /* Safely compute a+b, and check for integer overflow. If overflow occurs, * return 0 and set OK to FALSE. Also return 0 if OK is FALSE on input. */ size_t CHOLMOD(add_size_t) (size_t a, size_t b, int *ok) { size_t s = a + b ; (*ok) = (*ok) && (s >= a) ; return ((*ok) ? s : 0) ; } /* ========================================================================== */ /* === cholmod_mult_size_t ================================================== */ /* ========================================================================== */ /* Safely compute a*k, where k should be small, and check for integer overflow. * If overflow occurs, return 0 and set OK to FALSE. Also return 0 if OK is * FALSE on input. */ size_t CHOLMOD(mult_size_t) (size_t a, size_t k, int *ok) { size_t p = 0, s ; while (*ok) { if (k % 2) { p = p + a ; (*ok) = (*ok) && (p >= a) ; } k = k / 2 ; if (!k) return (p) ; s = a + a ; (*ok) = (*ok) && (s >= a) ; a = s ; } return (0) ; } /* ========================================================================== */ /* === cholmod_malloc ======================================================= */ /* ========================================================================== */ /* Wrapper around malloc routine. Allocates space of size MAX(1,n)*size, where * size is normally a sizeof (...). * * This routine, cholmod_calloc, and cholmod_realloc do not set Common->status * to CHOLMOD_OK on success, so that a sequence of cholmod_malloc's, _calloc's, * or _realloc's can be used. If any of them fails, the Common->status will * hold the most recent error status. * * Usage, for a pointer to int: * * p = cholmod_malloc (n, sizeof (int), Common) * * Uses a pointer to the malloc routine (or its equivalent) defined in Common. */ void *CHOLMOD(malloc) /* returns pointer to the newly malloc'd block */ ( /* ---- input ---- */ size_t n, /* number of items */ size_t size, /* size of each item */ /* --------------- */ cholmod_common *Common ) { void *p ; size_t s ; /* int ok = TRUE ; */ RETURN_IF_NULL_COMMON (NULL) ; if (size == 0) { ERROR (CHOLMOD_INVALID, "sizeof(item) must be > 0") ; p = NULL ; } else if (n >= (Size_max / size) || n >= Int_max) { /* object is too big to allocate without causing integer overflow */ ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; p = NULL ; } else { /* call malloc, or its equivalent */ p = SuiteSparse_malloc (n, size) ; if (p == NULL) { /* failure: out of memory */ ERROR (CHOLMOD_OUT_OF_MEMORY, "out of memory") ; } else { /* success: increment the count of objects allocated */ Common->malloc_count++ ; Common->memory_inuse += (n * size) ; Common->memory_usage = MAX (Common->memory_usage, Common->memory_inuse) ; PRINTM (("cholmod_malloc %p %g cnt: %g inuse %g\n", p, (double) n*size, (double) Common->malloc_count, (double) Common->memory_inuse)) ; } } return (p) ; } /* ========================================================================== */ /* === cholmod_free ========================================================= */ /* ========================================================================== */ /* Wrapper around free routine. Returns NULL, which can be assigned to the * pointer being freed, as in: * * p = cholmod_free (n, sizeof (int), p, Common) ; * * In CHOLMOD, the syntax: * * cholmod_free (n, sizeof (int), p, Common) ; * * is used if p is a local pointer and the routine is returning shortly. * Uses a pointer to the free routine (or its equivalent) defined in Common. * Nothing is freed if the pointer is NULL. */ void *CHOLMOD(free) /* always returns NULL */ ( /* ---- input ---- */ size_t n, /* number of items */ size_t size, /* size of each item */ /* ---- in/out --- */ void *p, /* block of memory to free */ /* --------------- */ cholmod_common *Common ) { RETURN_IF_NULL_COMMON (NULL) ; if (p != NULL) { /* only free the object if the pointer is not NULL */ /* call free, or its equivalent */ SuiteSparse_free (p) ; Common->malloc_count-- ; Common->memory_inuse -= (n * size) ; PRINTM (("cholmod_free %p %g cnt: %g inuse %g\n", p, (double) n*size, (double) Common->malloc_count, (double) Common->memory_inuse)) ; /* This assertion will fail if the user calls cholmod_malloc and * cholmod_free with mismatched memory sizes. It shouldn't fail * otherwise. */ ASSERT (IMPLIES (Common->malloc_count == 0, Common->memory_inuse == 0)); } /* return NULL, and the caller should assign this to p. This avoids * freeing the same pointer twice. */ return (NULL) ; } /* ========================================================================== */ /* === cholmod_calloc ======================================================= */ /* ========================================================================== */ /* Wrapper around calloc routine. * * Uses a pointer to the calloc routine (or its equivalent) defined in Common. * This routine is identical to malloc, except that it zeros the newly allocated * block to zero. */ void *CHOLMOD(calloc) /* returns pointer to the newly calloc'd block */ ( /* ---- input ---- */ size_t n, /* number of items */ size_t size, /* size of each item */ /* --------------- */ cholmod_common *Common ) { void *p ; RETURN_IF_NULL_COMMON (NULL) ; if (size == 0) { ERROR (CHOLMOD_INVALID, "sizeof(item) must be > 0") ; p = NULL ; } else if (n >= (Size_max / size) || n >= Int_max) { /* object is too big to allocate without causing integer overflow */ ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; p = NULL ; } else { /* call calloc, or its equivalent */ p = SuiteSparse_calloc (n, size) ; if (p == NULL) { /* failure: out of memory */ ERROR (CHOLMOD_OUT_OF_MEMORY, "out of memory") ; } else { /* success: increment the count of objects allocated */ Common->malloc_count++ ; Common->memory_inuse += (n * size) ; Common->memory_usage = MAX (Common->memory_usage, Common->memory_inuse) ; PRINTM (("cholmod_malloc %p %g cnt: %g inuse %g\n", p, (double) n*size, (double) Common->malloc_count, (double) Common->memory_inuse)) ; } } return (p) ; } /* ========================================================================== */ /* === cholmod_realloc ====================================================== */ /* ========================================================================== */ /* Wrapper around realloc routine. Given a pointer p to a block of size * (*n)*size memory, it changes the size of the block pointed to by p to be * MAX(1,nnew)*size in size. It may return a pointer different than p. This * should be used as (for a pointer to int): * * p = cholmod_realloc (nnew, sizeof (int), p, *n, Common) ; * * If p is NULL, this is the same as p = cholmod_malloc (...). * A size of nnew=0 is treated as nnew=1. * * If the realloc fails, p is returned unchanged and Common->status is set * to CHOLMOD_OUT_OF_MEMORY. If successful, Common->status is not modified, * and p is returned (possibly changed) and pointing to a large block of memory. * * Uses a pointer to the realloc routine (or its equivalent) defined in Common. */ void *CHOLMOD(realloc) /* returns pointer to reallocated block */ ( /* ---- input ---- */ size_t nnew, /* requested # of items in reallocated block */ size_t size, /* size of each item */ /* ---- in/out --- */ void *p, /* block of memory to realloc */ size_t *n, /* current size on input, nnew on output if successful*/ /* --------------- */ cholmod_common *Common ) { size_t nold = (*n) ; void *pnew ; size_t s ; int ok = TRUE ; RETURN_IF_NULL_COMMON (NULL) ; if (size == 0) { ERROR (CHOLMOD_INVALID, "sizeof(item) must be > 0") ; p = NULL ; } else if (p == NULL) { /* A fresh object is being allocated. */ PRINT1 (("realloc fresh: %d %d\n", nnew, size)) ; p = CHOLMOD(malloc) (nnew, size, Common) ; *n = (p == NULL) ? 0 : nnew ; } else if (nold == nnew) { /* Nothing to do. Do not change p or n. */ PRINT1 (("realloc nothing: %d %d\n", nnew, size)) ; } else if (nnew >= (Size_max / size) || nnew >= Int_max) { /* failure: nnew is too big. Do not change p or n. */ ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; } else { /* The object exists, and is changing to some other nonzero size. */ /* call realloc, or its equivalent */ PRINT1 (("realloc : %d to %d, %d\n", nold, nnew, size)) ; pnew = SuiteSparse_realloc (nnew, nold, size, p, &ok) ; if (ok) { /* success: return revised p and change the size of the block */ PRINTM (("cholmod_free %p %g cnt: %g inuse %g\n" "cholmod_malloc %p %g cnt: %g inuse %g\n", p, (double) nold*size, (double) Common->malloc_count-1, (double) (Common->memory_inuse - nold*size), pnew, (double) nnew*size, (double) Common->malloc_count, (double) (Common->memory_inuse + (nnew-nold)*size))) ; p = pnew ; *n = nnew ; Common->memory_inuse += ((nnew-nold) * size) ; } else { /* Increasing the size of the block has failed. * Do not change n. */ ERROR (CHOLMOD_OUT_OF_MEMORY, "out of memory") ; } Common->memory_usage = MAX (Common->memory_usage, Common->memory_inuse); } return (p) ; } /* ========================================================================== */ /* === cholmod_realloc_multiple ============================================= */ /* ========================================================================== */ /* reallocate multiple blocks of memory, all of the same size (up to two integer * and two real blocks). Either reallocations all succeed, or all are returned * in the original size (they are freed if the original size is zero). The nnew * blocks are of size 1 or more. */ int CHOLMOD(realloc_multiple) ( /* ---- input ---- */ size_t nnew, /* requested # of items in reallocated blocks */ int nint, /* number of int/SuiteSparse_long blocks */ int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ /* ---- in/out --- */ void **Iblock, /* int or SuiteSparse_long block */ void **Jblock, /* int or SuiteSparse_long block */ void **Xblock, /* complex or double block */ void **Zblock, /* zomplex case only: double block */ size_t *nold_p, /* current size of the I,J,X,Z blocks on input, * nnew on output if successful */ /* --------------- */ cholmod_common *Common ) { double *xx, *zz ; size_t i, j, x, z, nold ; RETURN_IF_NULL_COMMON (FALSE) ; if (xtype < CHOLMOD_PATTERN || xtype > CHOLMOD_ZOMPLEX) { ERROR (CHOLMOD_INVALID, "invalid xtype") ; return (FALSE) ; } nold = *nold_p ; if (nint < 1 && xtype == CHOLMOD_PATTERN) { /* nothing to do */ return (TRUE) ; } i = nold ; j = nold ; x = nold ; z = nold ; if (nint > 0) { *Iblock = CHOLMOD(realloc) (nnew, sizeof (Int), *Iblock, &i, Common) ; } if (nint > 1) { *Jblock = CHOLMOD(realloc) (nnew, sizeof (Int), *Jblock, &j, Common) ; } switch (xtype) { case CHOLMOD_REAL: *Xblock = CHOLMOD(realloc) (nnew, sizeof (double), *Xblock, &x, Common) ; break ; case CHOLMOD_COMPLEX: *Xblock = CHOLMOD(realloc) (nnew, 2*sizeof (double), *Xblock, &x, Common) ; break ; case CHOLMOD_ZOMPLEX: *Xblock = CHOLMOD(realloc) (nnew, sizeof (double), *Xblock, &x, Common) ; *Zblock = CHOLMOD(realloc) (nnew, sizeof (double), *Zblock, &z, Common) ; break ; } if (Common->status < CHOLMOD_OK) { /* one or more realloc's failed. Resize all back down to nold. */ if (nold == 0) { if (nint > 0) { *Iblock = CHOLMOD(free) (i, sizeof (Int), *Iblock, Common) ; } if (nint > 1) { *Jblock = CHOLMOD(free) (j, sizeof (Int), *Jblock, Common) ; } switch (xtype) { case CHOLMOD_REAL: *Xblock = CHOLMOD(free) (x, sizeof (double), *Xblock, Common) ; break ; case CHOLMOD_COMPLEX: *Xblock = CHOLMOD(free) (x, 2*sizeof (double), *Xblock, Common) ; break ; case CHOLMOD_ZOMPLEX: *Xblock = CHOLMOD(free) (x, sizeof (double), *Xblock, Common) ; *Zblock = CHOLMOD(free) (x, sizeof (double), *Zblock, Common) ; break ; } } else { if (nint > 0) { *Iblock = CHOLMOD(realloc) (nold, sizeof (Int), *Iblock, &i, Common) ; } if (nint > 1) { *Jblock = CHOLMOD(realloc) (nold, sizeof (Int), *Jblock, &j, Common) ; } switch (xtype) { case CHOLMOD_REAL: *Xblock = CHOLMOD(realloc) (nold, sizeof (double), *Xblock, &x, Common) ; break ; case CHOLMOD_COMPLEX: *Xblock = CHOLMOD(realloc) (nold, 2*sizeof (double), *Xblock, &x, Common) ; break ; case CHOLMOD_ZOMPLEX: *Xblock = CHOLMOD(realloc) (nold, sizeof (double), *Xblock, &x, Common) ; *Zblock = CHOLMOD(realloc) (nold, sizeof (double), *Zblock, &z, Common) ; break ; } } return (FALSE) ; } if (nold == 0) { /* New space was allocated. Clear the first entry so that valgrind * doesn't complain about its access in change_complexity * (Core/cholmod_complex.c). */ xx = *Xblock ; zz = *Zblock ; switch (xtype) { case CHOLMOD_REAL: xx [0] = 0 ; break ; case CHOLMOD_COMPLEX: xx [0] = 0 ; xx [1] = 0 ; break ; case CHOLMOD_ZOMPLEX: xx [0] = 0 ; zz [0] = 0 ; break ; } } /* all realloc's succeeded, change size to reflect realloc'ed size. */ *nold_p = nnew ; return (TRUE) ; } ��������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Core/cholmod_add.c���������������������������������������������������������������0000644�0001762�0000144�00000017677�13652535054�016715� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Core/cholmod_add ===================================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Core Module. Copyright (C) 2005-2006, * Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* C = alpha*A + beta*B, or spones(A+B). Result is packed, with sorted or * unsorted columns. This routine is much faster and takes less memory if C * is allowed to have unsorted columns. * * If A and B are both symmetric (in upper form) then C is the same. Likewise, * if A and B are both symmetric (in lower form) then C is the same. * Otherwise, C is unsymmetric. A and B must have the same dimension. * * workspace: Flag (nrow), W (nrow) if values, Iwork (max (nrow,ncol)). * allocates temporary copies for A and B if they are symmetric. * allocates temporary copy of C if it is to be returned sorted. * * A and B can have an xtype of pattern or real. Complex or zomplex cases * are supported only if the "values" input parameter is FALSE. */ #include "cholmod_internal.h" #include "cholmod_core.h" cholmod_sparse *CHOLMOD(add) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to add */ cholmod_sparse *B, /* matrix to add */ double alpha [2], /* scale factor for A */ double beta [2], /* scale factor for B */ int values, /* if TRUE compute the numerical values of C */ int sorted, /* if TRUE, sort columns of C */ /* --------------- */ cholmod_common *Common ) { double *Ax, *Bx, *Cx, *W ; Int apacked, up, lo, nrow, ncol, bpacked, nzmax, pa, paend, pb, pbend, i, j, p, mark, nz ; Int *Ap, *Ai, *Anz, *Bp, *Bi, *Bnz, *Flag, *Cp, *Ci ; cholmod_sparse *A2, *B2, *C ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (A, NULL) ; RETURN_IF_NULL (B, NULL) ; values = values && (A->xtype != CHOLMOD_PATTERN) && (B->xtype != CHOLMOD_PATTERN) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, values ? CHOLMOD_REAL : CHOLMOD_ZOMPLEX, NULL) ; RETURN_IF_XTYPE_INVALID (B, CHOLMOD_PATTERN, values ? CHOLMOD_REAL : CHOLMOD_ZOMPLEX, NULL) ; if (A->nrow != B->nrow || A->ncol != B->ncol) { /* A and B must have the same dimensions */ ERROR (CHOLMOD_INVALID, "A and B dimesions do not match") ; return (NULL) ; } /* A and B must have the same numerical type if values is TRUE (both must * be CHOLMOD_REAL, this is implicitly checked above) */ Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ nrow = A->nrow ; ncol = A->ncol ; CHOLMOD(allocate_work) (nrow, MAX (nrow,ncol), values ? nrow : 0, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory */ } /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ if (nrow <= 1) { /* C will be implicitly sorted, so no need to sort it here */ sorted = FALSE ; } /* convert A or B to unsymmetric, if necessary */ A2 = NULL ; B2 = NULL ; if (A->stype != B->stype) { if (A->stype) { /* workspace: Iwork (max (nrow,ncol)) */ A2 = CHOLMOD(copy) (A, 0, values, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory */ } A = A2 ; } if (B->stype) { /* workspace: Iwork (max (nrow,ncol)) */ B2 = CHOLMOD(copy) (B, 0, values, Common) ; if (Common->status < CHOLMOD_OK) { CHOLMOD(free_sparse) (&A2, Common) ; return (NULL) ; /* out of memory */ } B = B2 ; } } /* get the A matrix */ ASSERT (A->stype == B->stype) ; up = (A->stype > 0) ; lo = (A->stype < 0) ; Ap = A->p ; Anz = A->nz ; Ai = A->i ; Ax = A->x ; apacked = A->packed ; /* get the B matrix */ Bp = B->p ; Bnz = B->nz ; Bi = B->i ; Bx = B->x ; bpacked = B->packed ; /* get workspace */ W = Common->Xwork ; /* size nrow, used if values is TRUE */ Flag = Common->Flag ; /* size nrow, Flag [0..nrow-1] < mark on input */ /* ---------------------------------------------------------------------- */ /* allocate the result C */ /* ---------------------------------------------------------------------- */ /* If integer overflow occurs, nzmax < 0 and the allocate fails properly * (likewise in most other matrix manipulation routines). */ nzmax = CHOLMOD(nnz) (A, Common) + CHOLMOD(nnz) (B, Common) ; C = CHOLMOD(allocate_sparse) (nrow, ncol, nzmax, FALSE, TRUE, SIGN (A->stype), values ? A->xtype : CHOLMOD_PATTERN, Common) ; if (Common->status < CHOLMOD_OK) { CHOLMOD(free_sparse) (&A2, Common) ; CHOLMOD(free_sparse) (&B2, Common) ; return (NULL) ; /* out of memory */ } Cp = C->p ; Ci = C->i ; Cx = C->x ; /* ---------------------------------------------------------------------- */ /* compute C = alpha*A + beta*B */ /* ---------------------------------------------------------------------- */ nz = 0 ; for (j = 0 ; j < ncol ; j++) { Cp [j] = nz ; /* clear the Flag array */ /* mark = CHOLMOD(clear_flag) (Common) ; */ CHOLMOD_CLEAR_FLAG (Common) ; mark = Common->mark ; /* scatter B into W */ pb = Bp [j] ; pbend = (bpacked) ? (Bp [j+1]) : (pb + Bnz [j]) ; for (p = pb ; p < pbend ; p++) { i = Bi [p] ; if ((up && i > j) || (lo && i < j)) { continue ; } Flag [i] = mark ; if (values) { W [i] = beta [0] * Bx [p] ; } } /* add A and gather from W into C(:,j) */ pa = Ap [j] ; paend = (apacked) ? (Ap [j+1]) : (pa + Anz [j]) ; for (p = pa ; p < paend ; p++) { i = Ai [p] ; if ((up && i > j) || (lo && i < j)) { continue ; } Flag [i] = EMPTY ; Ci [nz] = i ; if (values) { Cx [nz] = W [i] + alpha [0] * Ax [p] ; W [i] = 0 ; } nz++ ; } /* gather remaining entries into C(:,j), using pattern of B */ for (p = pb ; p < pbend ; p++) { i = Bi [p] ; if ((up && i > j) || (lo && i < j)) { continue ; } if (Flag [i] == mark) { Ci [nz] = i ; if (values) { Cx [nz] = W [i] ; W [i] = 0 ; } nz++ ; } } } Cp [ncol] = nz ; /* ---------------------------------------------------------------------- */ /* reduce C in size and free temporary matrices */ /* ---------------------------------------------------------------------- */ ASSERT (MAX (1,nz) <= C->nzmax) ; CHOLMOD(reallocate_sparse) (nz, C, Common) ; ASSERT (Common->status >= CHOLMOD_OK) ; /* clear the Flag array */ mark = CHOLMOD(clear_flag) (Common) ; CHOLMOD(free_sparse) (&A2, Common) ; CHOLMOD(free_sparse) (&B2, Common) ; /* ---------------------------------------------------------------------- */ /* sort C, if requested */ /* ---------------------------------------------------------------------- */ if (sorted) { /* workspace: Iwork (max (nrow,ncol)) */ if (!CHOLMOD(sort) (C, Common)) { CHOLMOD(free_sparse) (&C, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory */ } } } /* ---------------------------------------------------------------------- */ /* return result */ /* ---------------------------------------------------------------------- */ ASSERT (CHOLMOD(dump_sparse) (C, "add", Common) >= 0) ; return (C) ; } �����������������������������������������������������������������Matrix/src/CHOLMOD/Core/cholmod_transpose.c���������������������������������������������������������0000644�0001762�0000144�00000074776�13652535054�020206� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Core/cholmod_transpose =============================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Core Module. Copyright (C) 2005-2006, * Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* Core utility routines for the cholmod_sparse object to * compute the transpose or permuted transpose of a matrix: * * Primary routines: * ----------------- * cholmod_transpose transpose sparse matrix * cholmod_ptranspose transpose and permute sparse matrix * cholmod_sort sort row indices in each column of sparse matrix * * Secondary routines: * ------------------- * cholmod_transpose_unsym transpose unsymmetric sparse matrix * cholmod_transpose_sym transpose symmetric sparse matrix * * All xtypes (pattern, real, complex, and zomplex) are supported. * * --------------------------------------- * Unsymmetric case: A->stype is zero. * --------------------------------------- * * Computes F = A', F = A (:,f)' or F = A (p,f)', except that the indexing by * f does not work the same as the MATLAB notation (see below). A->stype * is zero, which denotes that both the upper and lower triangular parts of * A are present (and used). A may in fact be symmetric in pattern and/or * value; A->stype just denotes which part of A are stored. A may be * rectangular. * * p is a permutation of 0:m-1, and f is a subset of 0:n-1, where A is m-by-n. * There can be no duplicate entries in p or f. * * The set f is held in fset and fsize. * fset = NULL means ":" in MATLAB. fsize is ignored. * fset != NULL means f = fset [0..fsize-1]. * fset != NULL and fsize = 0 means f is the empty set. * * Columns not in the set f are considered to be zero. That is, * if A is 5-by-10 then F = A (:,[3 4])' is not 2-by-5, but 10-by-5, and rows * 3 and 4 of F are equal to columns 3 and 4 of A (the other rows of F are * zero). More precisely, in MATLAB notation: * * [m n] = size (A) ; * F = A ; * notf = ones (1,n) ; * notf (f) = 0 ; * F (:, find (notf)) = 0 * F = F' * * If you want the MATLAB equivalent F=A(p,f) operation, use cholmod_submatrix * instead (which does not compute the transpose). * * F->nzmax must be large enough to hold the matrix F. It is not modified. * If F->nz is present then F->nz [j] = # of entries in column j of F. * * A can be sorted or unsorted, with packed or unpacked columns. * * If f is present and not sorted in ascending order, then F is unsorted * (that is, it may contain columns whose row indices do not appear in * ascending order). Otherwise, F is sorted (the row indices in each * column of F appear in strictly ascending order). * * F is returned in packed or unpacked form, depending on F->packed on input. * If F->packed is false, then F is returned in unpacked form (F->nz must be * present). Each row i of F is large enough to hold all the entries in row i * of A, even if f is provided. That is, F->i and * F->x [F->p [i] .. F->p [i] + F->nz [i] - 1] contain all entries in A (i,f), * but F->p [i+1] - F->p [i] is equal to the number of nonzeros in A (i,:), * not just A (i,f). * * The cholmod_transpose_unsym routine is the only operation in CHOLMOD that * can produce an unpacked matrix. * * --------------------------------------- * Symmetric case: A->stype is nonzero. * --------------------------------------- * * Computes F = A' or F = A(p,p)', the transpose or permuted transpose, where * A->stype is nonzero. * * If A->stype > 0, then A is a symmetric matrix where just the upper part * of the matrix is stored. Entries in the lower triangular part may be * present, but are ignored. A must be square. If F=A', then F is returned * sorted; otherwise F is unsorted for the F=A(p,p)' case. * * There can be no duplicate entries in p. * The fset and fsize parameters are not used. * * Three kinds of transposes are available, depending on the "values" parameter: * 0: do not transpose the numerical values; create a CHOLMOD_PATTERN matrix * 1: array transpose * 2: complex conjugate transpose (same as 2 if input is real or pattern) * * ----------------------------------------------------------------------------- * * For cholmod_transpose_unsym and cholmod_transpose_sym, the output matrix * F must already be pre-allocated by the caller, with the correct dimensions. * If F is not valid or has the wrong dimensions, it is not modified. * Otherwise, if F is too small, the transpose is not computed; the contents * of F->p contain the column pointers of the resulting matrix, where * F->p [F->ncol] > F->nzmax. In this case, the remaining contents of F are * not modified. F can still be properly free'd with cholmod_free_sparse. */ #include "cholmod_internal.h" #include "cholmod_core.h" /* ========================================================================== */ /* === TEMPLATE ============================================================= */ /* ========================================================================== */ #define PATTERN #include "t_cholmod_transpose.c" #define REAL #include "t_cholmod_transpose.c" #define COMPLEX #include "t_cholmod_transpose.c" #define COMPLEX #define NCONJUGATE #include "t_cholmod_transpose.c" #define ZOMPLEX #include "t_cholmod_transpose.c" #define ZOMPLEX #define NCONJUGATE #include "t_cholmod_transpose.c" /* ========================================================================== */ /* === cholmod_transpose_unsym ============================================== */ /* ========================================================================== */ /* Compute F = A', A (:,f)', or A (p,f)', where A is unsymmetric and F is * already allocated. See cholmod_transpose for a simpler routine. * * workspace: * Iwork (MAX (nrow,ncol)) if fset is present * Iwork (nrow) if fset is NULL * * The xtype of A and F must match, unless values is zero or F->xtype is * CHOLMOD_PATTERN (in which case only the pattern of A is transpose into F). */ int CHOLMOD(transpose_unsym) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to transpose */ int values, /* 2: complex conj. transpose, 1: array transpose, 0: do not transpose the numerical values */ Int *Perm, /* size nrow, if present (can be NULL) */ Int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ /* ---- output --- */ cholmod_sparse *F, /* F = A', A(:,f)', or A(p,f)' */ /* --------------- */ cholmod_common *Common ) { Int *Fp, *Fnz, *Ap, *Ai, *Anz, *Wi ; Int nrow, ncol, permute, use_fset, Apacked, Fpacked, p, pend, i, j, k, Fsorted, nf, jj, jlast ; size_t s ; int ok = TRUE ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_NULL (F, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; RETURN_IF_XTYPE_INVALID (F, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; if (A->nrow != F->ncol || A->ncol != F->nrow) { ERROR (CHOLMOD_INVALID, "F has the wrong dimensions") ; return (FALSE) ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ nf = fsize ; use_fset = (fset != NULL) ; nrow = A->nrow ; ncol = A->ncol ; Ap = A->p ; /* size A->ncol+1, column pointers of A */ Ai = A->i ; /* size nz = Ap [A->ncol], row indices of A */ Anz = A->nz ; Apacked = A->packed ; ASSERT (IMPLIES (!Apacked, Anz != NULL)) ; permute = (Perm != NULL) ; Fp = F->p ; /* size A->nrow+1, row pointers of F */ Fnz = F->nz ; Fpacked = F->packed ; ASSERT (IMPLIES (!Fpacked, Fnz != NULL)) ; nf = (use_fset) ? nf : ncol ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ /* s = nrow + ((fset != NULL) ? ncol : 0) */ s = CHOLMOD(add_size_t) (nrow, ((fset != NULL) ? ncol : 0), &ok) ; if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (FALSE) ; } CHOLMOD(allocate_work) (0, s, 0, Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; /* out of memory */ } Wi = Common->Iwork ; /* size nrow (i/l/l) */ /* ---------------------------------------------------------------------- */ /* check Perm and fset */ /* ---------------------------------------------------------------------- */ if (permute) { for (i = 0 ; i < nrow ; i++) { Wi [i] = 1 ; } for (k = 0 ; k < nrow ; k++) { i = Perm [k] ; if (i < 0 || i > nrow || Wi [i] == 0) { ERROR (CHOLMOD_INVALID, "invalid permutation") ; return (FALSE) ; } Wi [i] = 0 ; } } if (use_fset) { for (j = 0 ; j < ncol ; j++) { Wi [j] = 1 ; } for (k = 0 ; k < nf ; k++) { j = fset [k] ; if (j < 0 || j > ncol || Wi [j] == 0) { ERROR (CHOLMOD_INVALID, "invalid fset") ; return (FALSE) ; } Wi [j] = 0 ; } } /* Perm and fset are now valid */ ASSERT (CHOLMOD(dump_perm) (Perm, nrow, nrow, "Perm", Common)) ; ASSERT (CHOLMOD(dump_perm) (fset, nf, ncol, "fset", Common)) ; /* ---------------------------------------------------------------------- */ /* count the entries in each row of A or A(:,f) */ /* ---------------------------------------------------------------------- */ for (i = 0 ; i < nrow ; i++) { Wi [i] = 0 ; } jlast = EMPTY ; Fsorted = TRUE ; if (use_fset) { /* count entries in each row of A(:,f) */ for (jj = 0 ; jj < nf ; jj++) { j = fset [jj] ; if (j <= jlast) { Fsorted = FALSE ; } p = Ap [j] ; pend = (Apacked) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { Wi [Ai [p]]++ ; } jlast = j ; } /* save the nz counts if F is unpacked, and recount all of A */ if (!Fpacked) { if (permute) { for (i = 0 ; i < nrow ; i++) { Fnz [i] = Wi [Perm [i]] ; } } else { for (i = 0 ; i < nrow ; i++) { Fnz [i] = Wi [i] ; } } for (i = 0 ; i < nrow ; i++) { Wi [i] = 0 ; } /* count entries in each row of A */ for (j = 0 ; j < ncol ; j++) { p = Ap [j] ; pend = (Apacked) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { Wi [Ai [p]]++ ; } } } } else { /* count entries in each row of A */ for (j = 0 ; j < ncol ; j++) { p = Ap [j] ; pend = (Apacked) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { Wi [Ai [p]]++ ; } } /* save the nz counts if F is unpacked */ if (!Fpacked) { if (permute) { for (i = 0 ; i < nrow ; i++) { Fnz [i] = Wi [Perm [i]] ; } } else { for (i = 0 ; i < nrow ; i++) { Fnz [i] = Wi [i] ; } } } } /* ---------------------------------------------------------------------- */ /* compute the row pointers */ /* ---------------------------------------------------------------------- */ p = 0 ; if (permute) { for (i = 0 ; i < nrow ; i++) { Fp [i] = p ; p += Wi [Perm [i]] ; } for (i = 0 ; i < nrow ; i++) { Wi [Perm [i]] = Fp [i] ; } } else { for (i = 0 ; i < nrow ; i++) { Fp [i] = p ; p += Wi [i] ; } for (i = 0 ; i < nrow ; i++) { Wi [i] = Fp [i] ; } } Fp [nrow] = p ; if (p > (Int) (F->nzmax)) { ERROR (CHOLMOD_INVALID, "F is too small") ; return (FALSE) ; } /* ---------------------------------------------------------------------- */ /* transpose matrix, using template routine */ /* ---------------------------------------------------------------------- */ ok = FALSE ; if (values == 0 || F->xtype == CHOLMOD_PATTERN) { ok = p_cholmod_transpose_unsym (A, Perm, fset, nf, F, Common) ; } else if (F->xtype == CHOLMOD_REAL) { ok = r_cholmod_transpose_unsym (A, Perm, fset, nf, F, Common) ; } else if (F->xtype == CHOLMOD_COMPLEX) { if (values == 1) { /* array transpose */ ok = ct_cholmod_transpose_unsym (A, Perm, fset, nf, F, Common) ; } else { /* complex conjugate transpose */ ok = c_cholmod_transpose_unsym (A, Perm, fset, nf, F, Common) ; } } else if (F->xtype == CHOLMOD_ZOMPLEX) { if (values == 1) { /* array transpose */ ok = zt_cholmod_transpose_unsym (A, Perm, fset, nf, F, Common) ; } else { /* complex conjugate transpose */ ok = z_cholmod_transpose_unsym (A, Perm, fset, nf, F, Common) ; } } /* ---------------------------------------------------------------------- */ /* finalize result F */ /* ---------------------------------------------------------------------- */ if (ok) { F->sorted = Fsorted ; } ASSERT (CHOLMOD(dump_sparse) (F, "output F unsym", Common) >= 0) ; return (ok) ; } /* ========================================================================== */ /* === cholmod_transpose_sym ================================================ */ /* ========================================================================== */ /* Compute F = A' or A (p,p)', where A is symmetric and F is already allocated. * See cholmod_transpose for a simpler routine. * * workspace: Iwork (nrow) if Perm NULL, Iwork (2*nrow) if Perm non-NULL. */ int CHOLMOD(transpose_sym) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to transpose */ int values, /* 2: complex conj. transpose, 1: array transpose, 0: do not transpose the numerical values */ Int *Perm, /* size nrow, if present (can be NULL) */ /* ---- output --- */ cholmod_sparse *F, /* F = A' or A(p,p)' */ /* --------------- */ cholmod_common *Common ) { Int *Ap, *Anz, *Ai, *Fp, *Wi, *Pinv, *Iwork ; Int p, pend, packed, upper, permute, jold, n, i, j, k, iold ; size_t s ; int ok = TRUE ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_NULL (F, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; RETURN_IF_XTYPE_INVALID (F, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; if (A->nrow != A->ncol || A->stype == 0) { /* this routine handles square symmetric matrices only */ ERROR (CHOLMOD_INVALID, "matrix must be symmetric") ; return (FALSE) ; } if (A->nrow != F->ncol || A->ncol != F->nrow) { ERROR (CHOLMOD_INVALID, "F has the wrong dimensions") ; return (FALSE) ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ permute = (Perm != NULL) ; n = A->nrow ; Ap = A->p ; /* size A->ncol+1, column pointers of A */ Ai = A->i ; /* size nz = Ap [A->ncol], row indices of A */ Anz = A->nz ; packed = A->packed ; ASSERT (IMPLIES (!packed, Anz != NULL)) ; upper = (A->stype > 0) ; Fp = F->p ; /* size A->nrow+1, row pointers of F */ /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ /* s = (Perm != NULL) ? 2*n : n */ s = CHOLMOD(add_size_t) (n, ((Perm != NULL) ? n : 0), &ok) ; if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (FALSE) ; } CHOLMOD(allocate_work) (0, s, 0, Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; /* out of memory */ } /* ---------------------------------------------------------------------- */ /* get workspace */ /* ---------------------------------------------------------------------- */ Iwork = Common->Iwork ; Wi = Iwork ; /* size n (i/l/l) */ Pinv = Iwork + n ; /* size n (i/i/l) , unused if Perm NULL */ /* ---------------------------------------------------------------------- */ /* check Perm and construct inverse permutation */ /* ---------------------------------------------------------------------- */ if (permute) { for (i = 0 ; i < n ; i++) { Pinv [i] = EMPTY ; } for (k = 0 ; k < n ; k++) { i = Perm [k] ; if (i < 0 || i > n || Pinv [i] != EMPTY) { ERROR (CHOLMOD_INVALID, "invalid permutation") ; return (FALSE) ; } Pinv [i] = k ; } } /* Perm is now valid */ ASSERT (CHOLMOD(dump_perm) (Perm, n, n, "Perm", Common)) ; /* ---------------------------------------------------------------------- */ /* count the entries in each row of F */ /* ---------------------------------------------------------------------- */ for (i = 0 ; i < n ; i++) { Wi [i] = 0 ; } if (packed) { if (permute) { if (upper) { /* packed, permuted, upper */ for (j = 0 ; j < n ; j++) { jold = Perm [j] ; pend = Ap [jold+1] ; for (p = Ap [jold] ; p < pend ; p++) { iold = Ai [p] ; if (iold <= jold) { i = Pinv [iold] ; Wi [MIN (i, j)]++ ; } } } } else { /* packed, permuted, lower */ for (j = 0 ; j < n ; j++) { jold = Perm [j] ; pend = Ap [jold+1] ; for (p = Ap [jold] ; p < pend ; p++) { iold = Ai [p] ; if (iold >= jold) { i = Pinv [iold] ; Wi [MAX (i, j)]++ ; } } } } } else { if (upper) { /* packed, unpermuted, upper */ for (j = 0 ; j < n ; j++) { pend = Ap [j+1] ; for (p = Ap [j] ; p < pend ; p++) { i = Ai [p] ; if (i <= j) { Wi [i]++ ; } } } } else { /* packed, unpermuted, lower */ for (j = 0 ; j < n ; j++) { pend = Ap [j+1] ; for (p = Ap [j] ; p < pend ; p++) { i = Ai [p] ; if (i >= j) { Wi [i]++ ; } } } } } } else { if (permute) { if (upper) { /* unpacked, permuted, upper */ for (j = 0 ; j < n ; j++) { jold = Perm [j] ; p = Ap [jold] ; pend = p + Anz [jold] ; for ( ; p < pend ; p++) { iold = Ai [p] ; if (iold <= jold) { i = Pinv [iold] ; Wi [MIN (i, j)]++ ; } } } } else { /* unpacked, permuted, lower */ for (j = 0 ; j < n ; j++) { jold = Perm [j] ; p = Ap [jold] ; pend = p + Anz [jold] ; for ( ; p < pend ; p++) { iold = Ai [p] ; if (iold >= jold) { i = Pinv [iold] ; Wi [MAX (i, j)]++ ; } } } } } else { if (upper) { /* unpacked, unpermuted, upper */ for (j = 0 ; j < n ; j++) { p = Ap [j] ; pend = p + Anz [j] ; for ( ; p < pend ; p++) { i = Ai [p] ; if (i <= j) { Wi [i]++ ; } } } } else { /* unpacked, unpermuted, lower */ for (j = 0 ; j < n ; j++) { p = Ap [j] ; pend = p + Anz [j] ; for ( ; p < pend ; p++) { i = Ai [p] ; if (i >= j) { Wi [i]++ ; } } } } } } /* ---------------------------------------------------------------------- */ /* compute the row pointers */ /* ---------------------------------------------------------------------- */ p = 0 ; for (i = 0 ; i < n ; i++) { Fp [i] = p ; p += Wi [i] ; } Fp [n] = p ; for (i = 0 ; i < n ; i++) { Wi [i] = Fp [i] ; } if (p > (Int) (F->nzmax)) { ERROR (CHOLMOD_INVALID, "F is too small") ; return (FALSE) ; } /* ---------------------------------------------------------------------- */ /* transpose matrix, using template routine */ /* ---------------------------------------------------------------------- */ ok = FALSE ; if (values == 0 || F->xtype == CHOLMOD_PATTERN) { PRINT2 (("\n:::: p_transpose_sym Perm %p\n", Perm)) ; ok = p_cholmod_transpose_sym (A, Perm, F, Common) ; } else if (F->xtype == CHOLMOD_REAL) { PRINT2 (("\n:::: r_transpose_sym Perm %p\n", Perm)) ; ok = r_cholmod_transpose_sym (A, Perm, F, Common) ; } else if (F->xtype == CHOLMOD_COMPLEX) { if (values == 1) { /* array transpose */ PRINT2 (("\n:::: ct_transpose_sym Perm %p\n", Perm)) ; ok = ct_cholmod_transpose_sym (A, Perm, F, Common) ; } else { /* complex conjugate transpose */ PRINT2 (("\n:::: c_transpose_sym Perm %p\n", Perm)) ; ok = c_cholmod_transpose_sym (A, Perm, F, Common) ; } } else if (F->xtype == CHOLMOD_ZOMPLEX) { if (values == 1) { /* array transpose */ PRINT2 (("\n:::: zt_transpose_sym Perm %p\n", Perm)) ; ok = zt_cholmod_transpose_sym (A, Perm, F, Common) ; } else { /* complex conjugate transpose */ PRINT2 (("\n:::: z_transpose_sym Perm %p\n", Perm)) ; ok = z_cholmod_transpose_sym (A, Perm, F, Common) ; } } /* ---------------------------------------------------------------------- */ /* finalize result F */ /* ---------------------------------------------------------------------- */ /* F is sorted if there is no permutation vector */ if (ok) { F->sorted = !permute ; F->packed = TRUE ; F->stype = - SIGN (A->stype) ; /* flip the stype */ ASSERT (CHOLMOD(dump_sparse) (F, "output F sym", Common) >= 0) ; } return (ok) ; } /* ========================================================================== */ /* === cholmod_transpose ==================================================== */ /* ========================================================================== */ /* Returns A'. See also cholmod_ptranspose below. */ cholmod_sparse *CHOLMOD(transpose) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to transpose */ int values, /* 2: complex conj. transpose, 1: array transpose, 0: do not transpose the numerical values (returns its result as CHOLMOD_PATTERN) */ /* --------------- */ cholmod_common *Common ) { return (CHOLMOD(ptranspose) (A, values, NULL, NULL, 0, Common)) ; } /* ========================================================================== */ /* === cholmod_ptranspose =================================================== */ /* ========================================================================== */ /* Return A' or A(p,p)' if A is symmetric. Return A', A(:,f)', or A(p,f)' if * A is unsymmetric. * * workspace: * Iwork (MAX (nrow,ncol)) if unsymmetric and fset is non-NULL * Iwork (nrow) if unsymmetric and fset is NULL * Iwork (2*nrow) if symmetric and Perm is non-NULL. * Iwork (nrow) if symmetric and Perm is NULL. * * A simple worst-case upper bound on the workspace is nrow+ncol. */ cholmod_sparse *CHOLMOD(ptranspose) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to transpose */ int values, /* 2: complex conj. transpose, 1: array transpose, 0: do not transpose the numerical values */ Int *Perm, /* if non-NULL, F = A(p,f) or A(p,p) */ Int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ /* --------------- */ cholmod_common *Common ) { Int *Ap, *Anz ; cholmod_sparse *F ; Int nrow, ncol, use_fset, j, jj, fnz, packed, stype, nf, xtype ; size_t ineed ; int ok = TRUE ; nf = fsize ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, NULL) ; stype = A->stype ; Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ nrow = A->nrow ; ncol = A->ncol ; if (stype != 0) { use_fset = FALSE ; if (Perm != NULL) { ineed = CHOLMOD(mult_size_t) (A->nrow, 2, &ok) ; } else { ineed = A->nrow ; } } else { use_fset = (fset != NULL) ; if (use_fset) { ineed = MAX (A->nrow, A->ncol) ; } else { ineed = A->nrow ; } } if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (NULL) ; } CHOLMOD(allocate_work) (0, ineed, 0, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory */ } /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ Ap = A->p ; Anz = A->nz ; packed = A->packed ; ASSERT (IMPLIES (!packed, Anz != NULL)) ; xtype = values ? A->xtype : CHOLMOD_PATTERN ; /* ---------------------------------------------------------------------- */ /* allocate F */ /* ---------------------------------------------------------------------- */ /* determine # of nonzeros in F */ if (stype != 0) { /* F=A' or F=A(p,p)', fset is ignored */ fnz = CHOLMOD(nnz) (A, Common) ; } else { nf = (use_fset) ? nf : ncol ; if (use_fset) { fnz = 0 ; /* F=A(:,f)' or F=A(p,f)' */ for (jj = 0 ; jj < nf ; jj++) { /* The fset is not yet checked; it will be thoroughly checked * in cholmod_transpose_unsym. For now, just make sure we don't * access Ap and Anz out of bounds. */ j = fset [jj] ; if (j >= 0 && j < ncol) { fnz += packed ? (Ap [j+1] - Ap [j]) : MAX (0, Anz [j]) ; } } } else { /* F=A' or F=A(p,:)' */ fnz = CHOLMOD(nnz) (A, Common) ; } } /* F is ncol-by-nrow, fnz nonzeros, sorted unless f is present and unsorted, * packed, of opposite stype as A, and with/without numerical values */ F = CHOLMOD(allocate_sparse) (ncol, nrow, fnz, TRUE, TRUE, -SIGN(stype), xtype, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory */ } /* ---------------------------------------------------------------------- */ /* transpose and optionally permute the matrix A */ /* ---------------------------------------------------------------------- */ if (stype != 0) { /* F = A (p,p)', using upper or lower triangular part of A only */ ok = CHOLMOD(transpose_sym) (A, values, Perm, F, Common) ; } else { /* F = A (p,f)' */ ok = CHOLMOD(transpose_unsym) (A, values, Perm, fset, nf, F, Common) ; } /* ---------------------------------------------------------------------- */ /* return the matrix F, or NULL if an error occured */ /* ---------------------------------------------------------------------- */ if (!ok) { CHOLMOD(free_sparse) (&F, Common) ; } return (F) ; } /* ========================================================================== */ /* === cholmod_sort ========================================================= */ /* ========================================================================== */ /* Sort the columns of A, in place. Returns A in packed form, even if it * starts as unpacked. Removes entries in the ignored part of a symmetric * matrix. * * workspace: Iwork (max (nrow,ncol)). Allocates additional workspace for a * temporary copy of A'. */ int CHOLMOD(sort) ( /* ---- in/out --- */ cholmod_sparse *A, /* matrix to sort */ /* --------------- */ cholmod_common *Common ) { Int *Ap ; cholmod_sparse *F ; Int anz, ncol, nrow, stype ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; Common->status = CHOLMOD_OK ; nrow = A->nrow ; if (nrow <= 1) { /* a 1-by-n sparse matrix must be sorted */ A->sorted = TRUE ; return (TRUE) ; } /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ ncol = A->ncol ; CHOLMOD(allocate_work) (0, MAX (nrow, ncol), 0, Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; /* out of memory */ } /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ anz = CHOLMOD(nnz) (A, Common) ; stype = A->stype ; /* ---------------------------------------------------------------------- */ /* sort the columns of the matrix */ /* ---------------------------------------------------------------------- */ /* allocate workspace for transpose: ncol-by-nrow, same # of nonzeros as A, * sorted, packed, same stype as A, and of the same numeric type as A. */ F = CHOLMOD(allocate_sparse) (ncol, nrow, anz, TRUE, TRUE, stype, A->xtype, Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; /* out of memory */ } if (stype != 0) { /* F = A', upper or lower triangular part only */ CHOLMOD(transpose_sym) (A, 1, NULL, F, Common) ; A->packed = TRUE ; /* A = F' */ CHOLMOD(transpose_sym) (F, 1, NULL, A, Common) ; } else { /* F = A' */ CHOLMOD(transpose_unsym) (A, 1, NULL, NULL, 0, F, Common) ; A->packed = TRUE ; /* A = F' */ CHOLMOD(transpose_unsym) (F, 1, NULL, NULL, 0, A, Common) ; } ASSERT (A->sorted && A->packed) ; ASSERT (CHOLMOD(dump_sparse) (A, "Asorted", Common) >= 0) ; /* ---------------------------------------------------------------------- */ /* reduce A in size, if needed. This must succeed. */ /* ---------------------------------------------------------------------- */ Ap = A->p ; anz = Ap [ncol] ; ASSERT ((size_t) anz <= A->nzmax) ; CHOLMOD(reallocate_sparse) (anz, A, Common) ; ASSERT (Common->status >= CHOLMOD_OK) ; /* ---------------------------------------------------------------------- */ /* free workspace */ /* ---------------------------------------------------------------------- */ CHOLMOD(free_sparse) (&F, Common) ; return (TRUE) ; } ��Matrix/src/CHOLMOD/Core/cholmod_triplet.c�����������������������������������������������������������0000644�0001762�0000144�00000055510�13652535054�017634� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Core/cholmod_triplet ================================================= */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Core Module. Copyright (C) 2005-2006, * Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* Core utility routines for the cholmod_triplet object: * * A sparse matrix held in triplet form is the simplest one for a user to * create. It consists of a list of nz entries in arbitrary order, held in * three arrays: i, j, and x, each of length nk. The kth entry is in row i[k], * column j[k], with value x[k]. There may be duplicate values; if A(i,j) * appears more than once, its value is the sum of the entries with those row * and column indices. * * Primary routines: * ----------------- * cholmod_allocate_triplet allocate a triplet matrix * cholmod_free_triplet free a triplet matrix * * Secondary routines: * ------------------- * cholmod_reallocate_triplet reallocate a triplet matrix * cholmod_sparse_to_triplet create a triplet matrix copy of a sparse matrix * cholmod_triplet_to_sparse create a sparse matrix copy of a triplet matrix * cholmod_copy_triplet create a copy of a triplet matrix * * The relationship between an m-by-n cholmod_sparse matrix A and a * cholmod_triplet matrix (i, j, and x) is identical to how they are used in * the MATLAB "sparse" and "find" functions: * * [i j x] = find (A) * [m n] = size (A) * A = sparse (i,j,x,m,n) * * with the exception that the cholmod_sparse matrix may be "unpacked", may * have either sorted or unsorted columns (depending on the option selected), * and may be symmetric with just the upper or lower triangular part stored. * Likewise, the cholmod_triplet matrix may contain just the entries in the * upper or lower triangular part of a symmetric matrix. * * MATLAB sparse matrices are always "packed", always have sorted columns, * and always store both parts of a symmetric matrix. In some cases, MATLAB * behaves like CHOLMOD by ignoring entries in the upper or lower triangular * part of a matrix that is otherwise assumed to be symmetric (such as the * input to chol). In CHOLMOD, that option is a characteristic of the object. * In MATLAB, that option is based on how a matrix is used as the input to * a function. * * The triplet matrix is provided to give the user a simple way of constructing * a sparse matrix. There are very few operations supported for triplet * matrices. The assumption is that they will be converted to cholmod_sparse * matrix form first. * * Adding two triplet matrices simply involves concatenating the contents of * the three arrays (i, j, and x). To permute a triplet matrix, just replace * the row and column indices with their permuted values. For example, if * P is a permutation vector, then P [k] = j means row/column j is the kth * row/column in C=P*A*P'. In MATLAB notation, C=A(p,p). If Pinv is an array * of size n and T is the triplet form of A, then: * * Ti = T->i ; * Tj = T->j ; * for (k = 0 ; k < n ; k++) Pinv [P [k]] = k ; * for (k = 0 ; k < nz ; k++) Ti [k] = Pinv [Ti [k]] ; * for (k = 0 ; k < nz ; k++) Tj [k] = Pinv [Tj [k]] ; * * overwrites T with the triplet form of C=P*A*P'. The conversion * * C = cholmod_triplet_to_sparse (T, 0, &Common) ; * * will then return the matrix C = P*A*P'. * * Note that T->stype > 0 means that entries in the lower triangular part of * T are transposed into the upper triangular part when T is converted to * sparse matrix (cholmod_sparse) form with cholmod_triplet_to_sparse. The * opposite is true for T->stype < 0. * * Since the triplet matrix T is so simple to generate, it's quite easy * to remove entries that you do not want, prior to converting T to the * cholmod_sparse form. So if you include these entries in T, CHOLMOD * assumes that there must be a reason (such as the one above). Thus, * no entry in a triplet matrix is ever ignored. * * Other operations, such as extacting a submatrix, horizontal and vertical * concatenation, multiply a triplet matrix times a dense matrix, are also * simple. Multiplying two triplet matrices is not trivial; the simplest * method is to convert them to cholmod_sparse matrices first. * * Supports all xtypes (pattern, real, complex, and zomplex). */ #include "cholmod_internal.h" #include "cholmod_core.h" /* ========================================================================== */ /* === TEMPLATE ============================================================= */ /* ========================================================================== */ #define PATTERN #include "t_cholmod_triplet.c" #define REAL #include "t_cholmod_triplet.c" #define COMPLEX #include "t_cholmod_triplet.c" #define ZOMPLEX #include "t_cholmod_triplet.c" /* ========================================================================== */ /* === cholmod_allocate_triplet ============================================= */ /* ========================================================================== */ /* allocate space for a triplet matrix * * workspace: none */ cholmod_triplet *CHOLMOD(allocate_triplet) ( /* ---- input ---- */ size_t nrow, /* # of rows of T */ size_t ncol, /* # of columns of T */ size_t nzmax, /* max # of nonzeros of T */ int stype, /* stype of T */ int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ /* --------------- */ cholmod_common *Common ) { cholmod_triplet *T ; size_t nzmax0 ; int ok = TRUE ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; if (xtype < CHOLMOD_PATTERN || xtype > CHOLMOD_ZOMPLEX) { ERROR (CHOLMOD_INVALID, "xtype invalid") ; return (NULL) ; } /* ensure the dimensions do not cause integer overflow */ (void) CHOLMOD(add_size_t) (ncol, 2, &ok) ; if (!ok || nrow > Int_max || ncol > Int_max || nzmax > Int_max) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (NULL) ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate header */ /* ---------------------------------------------------------------------- */ T = CHOLMOD(malloc) (sizeof (cholmod_triplet), 1, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory */ } PRINT1 (("cholmod_allocate_triplet %d-by-%d nzmax %d xtype %d\n", nrow, ncol, nzmax, xtype)) ; nzmax = MAX (1, nzmax) ; T->nrow = nrow ; T->ncol = ncol ; T->nzmax = nzmax ; T->nnz = 0 ; T->stype = stype ; T->itype = ITYPE ; T->xtype = xtype ; T->dtype = DTYPE ; T->j = NULL ; T->i = NULL ; T->x = NULL ; T->z = NULL ; /* ---------------------------------------------------------------------- */ /* allocate the matrix itself */ /* ---------------------------------------------------------------------- */ nzmax0 = 0 ; CHOLMOD(realloc_multiple) (nzmax, 2, xtype, &(T->i), &(T->j), &(T->x), &(T->z), &nzmax0, Common) ; if (Common->status < CHOLMOD_OK) { CHOLMOD(free_triplet) (&T, Common) ; return (NULL) ; /* out of memory */ } return (T) ; } /* ========================================================================== */ /* === cholmod_free_triplet ================================================= */ /* ========================================================================== */ /* free a triplet matrix * * workspace: none */ int CHOLMOD(free_triplet) ( /* ---- in/out --- */ cholmod_triplet **THandle, /* matrix to deallocate, NULL on output */ /* --------------- */ cholmod_common *Common ) { Int nz ; cholmod_triplet *T ; RETURN_IF_NULL_COMMON (FALSE) ; if (THandle == NULL) { /* nothing to do */ return (TRUE) ; } T = *THandle ; if (T == NULL) { /* nothing to do */ return (TRUE) ; } nz = T->nzmax ; T->j = CHOLMOD(free) (nz, sizeof (Int), T->j, Common) ; T->i = CHOLMOD(free) (nz, sizeof (Int), T->i, Common) ; if (T->xtype == CHOLMOD_REAL) { T->x = CHOLMOD(free) (nz, sizeof (double), T->x, Common) ; } else if (T->xtype == CHOLMOD_COMPLEX) { T->x = CHOLMOD(free) (nz, 2*sizeof (double), T->x, Common) ; } else if (T->xtype == CHOLMOD_ZOMPLEX) { T->x = CHOLMOD(free) (nz, sizeof (double), T->x, Common) ; T->z = CHOLMOD(free) (nz, sizeof (double), T->z, Common) ; } *THandle = CHOLMOD(free) (1, sizeof (cholmod_triplet), (*THandle), Common) ; return (TRUE) ; } /* ========================================================================== */ /* === cholmod_reallocate_triplet =========================================== */ /* ========================================================================== */ /* Change the size of T->i, T->j, and T->x, or allocate them if their current * size is zero. T->x is not modified if T->xtype is CHOLMOD_PATTERN. * * workspace: none */ int CHOLMOD(reallocate_triplet) ( /* ---- input ---- */ size_t nznew, /* new # of entries in T */ /* ---- in/out --- */ cholmod_triplet *T, /* triplet matrix to modify */ /* --------------- */ cholmod_common *Common ) { /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (T, FALSE) ; RETURN_IF_XTYPE_INVALID (T, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; Common->status = CHOLMOD_OK ; PRINT1 (("realloc triplet %d to %d, xtype: %d\n", T->nzmax, nznew, T->xtype)) ; /* ---------------------------------------------------------------------- */ /* resize the matrix */ /* ---------------------------------------------------------------------- */ CHOLMOD(realloc_multiple) (MAX (1,nznew), 2, T->xtype, &(T->i), &(T->j), &(T->x), &(T->z), &(T->nzmax), Common) ; return (Common->status == CHOLMOD_OK) ; } /* ========================================================================== */ /* === cholmod_triplet_to_sparse ============================================ */ /* ========================================================================== */ /* Convert a set of triplets into a cholmod_sparse matrix. In MATLAB notation, * for unsymmetric matrices: * * A = sparse (Ti, Tj, Tx, nrow, ncol, nzmax) ; * * For the symmetric upper case: * * A = sparse (min(Ti,Tj), max(Ti,Tj), Tx, nrow, ncol, nzmax) ; * * For the symmetric lower case: * * A = sparse (max(Ti,Tj), min(Ti,Tj), Tx, nrow, ncol, nzmax) ; * * If Tx is NULL, then A->x is not allocated, and only the pattern of A is * computed. A is returned in packed form, and can be of any stype * (upper/lower/unsymmetric). It has enough space to hold the values in T, * or nzmax, whichever is larger. * * workspace: Iwork (max (nrow,ncol)) * allocates a temporary copy of its output matrix. * * The resulting sparse matrix has the same xtype as the input triplet matrix. */ cholmod_sparse *CHOLMOD(triplet_to_sparse) ( /* ---- input ---- */ cholmod_triplet *T, /* matrix to copy */ size_t nzmax, /* allocate at least this much space in output matrix */ /* --------------- */ cholmod_common *Common ) { cholmod_sparse *R, *A = NULL ; Int *Wj, *Rp, *Ri, *Rnz, *Ti, *Tj ; Int i, j, p, k, stype, nrow, ncol, nz, ok ; size_t anz = 0 ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (T, NULL) ; Ti = T->i ; Tj = T->j ; RETURN_IF_NULL (Ti, NULL) ; RETURN_IF_NULL (Tj, NULL) ; RETURN_IF_XTYPE_INVALID (T, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, NULL) ; stype = SIGN (T->stype) ; if (stype && T->nrow != T->ncol) { /* inputs invalid */ ERROR (CHOLMOD_INVALID, "matrix invalid") ; return (NULL) ; } Common->status = CHOLMOD_OK ; DEBUG (CHOLMOD(dump_triplet) (T, "T", Common)) ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ nrow = T->nrow ; ncol = T->ncol ; nz = T->nnz ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ CHOLMOD(allocate_work) (0, MAX (nrow, ncol), 0, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory */ } /* ---------------------------------------------------------------------- */ /* allocate temporary matrix R */ /* ---------------------------------------------------------------------- */ R = CHOLMOD(allocate_sparse) (ncol, nrow, nz, FALSE, FALSE, -stype, T->xtype, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory */ } Rp = R->p ; Ri = R->i ; Rnz = R->nz ; /* ---------------------------------------------------------------------- */ /* count the entries in each row of A (also counting duplicates) */ /* ---------------------------------------------------------------------- */ for (i = 0 ; i < nrow ; i++) { Rnz [i] = 0 ; } if (stype > 0) { for (k = 0 ; k < nz ; k++) { i = Ti [k] ; j = Tj [k] ; if (i < 0 || i >= nrow || j < 0 || j >= ncol) { ERROR (CHOLMOD_INVALID, "index out of range") ; break ; } /* A will be symmetric with just the upper triangular part stored. * Create a matrix R that is lower triangular. Entries in the * upper part of R are transposed to the lower part. */ Rnz [MIN (i,j)]++ ; } } else if (stype < 0) { for (k = 0 ; k < nz ; k++) { i = Ti [k] ; j = Tj [k] ; if (i < 0 || i >= nrow || j < 0 || j >= ncol) { ERROR (CHOLMOD_INVALID, "index out of range") ; break ; } /* A will be symmetric with just the lower triangular part stored. * Create a matrix R that is upper triangular. Entries in the * lower part of R are transposed to the upper part. */ Rnz [MAX (i,j)]++ ; } } else { for (k = 0 ; k < nz ; k++) { i = Ti [k] ; j = Tj [k] ; if (i < 0 || i >= nrow || j < 0 || j >= ncol) { ERROR (CHOLMOD_INVALID, "index out of range") ; break ; } /* constructing an unsymmetric matrix */ Rnz [i]++ ; } } if (Common->status < CHOLMOD_OK) { /* triplet matrix is invalid */ CHOLMOD(free_sparse) (&R, Common) ; return (NULL) ; } /* ---------------------------------------------------------------------- */ /* construct the row pointers */ /* ---------------------------------------------------------------------- */ p = 0 ; for (i = 0 ; i < nrow ; i++) { Rp [i] = p ; p += Rnz [i] ; } Rp [nrow] = p ; /* use Wj (i/l/l) as temporary row pointers */ Wj = Common->Iwork ; /* size MAX (nrow,ncol) FUTURE WORK: (i/l/l) */ for (i = 0 ; i < nrow ; i++) { Wj [i] = Rp [i] ; } /* ---------------------------------------------------------------------- */ /* construct triplet matrix, using template routine */ /* ---------------------------------------------------------------------- */ switch (T->xtype) { case CHOLMOD_PATTERN: anz = p_cholmod_triplet_to_sparse (T, R, Common) ; break ; case CHOLMOD_REAL: anz = r_cholmod_triplet_to_sparse (T, R, Common) ; break ; case CHOLMOD_COMPLEX: anz = c_cholmod_triplet_to_sparse (T, R, Common) ; break ; case CHOLMOD_ZOMPLEX: anz = z_cholmod_triplet_to_sparse (T, R, Common) ; break ; } /* ---------------------------------------------------------------------- */ /* A = R' (array transpose, not complex conjugate transpose) */ /* ---------------------------------------------------------------------- */ /* workspace: Iwork (R->nrow), which is A->ncol */ ASSERT (CHOLMOD(dump_sparse) (R, "R", Common) >= 0) ; A = CHOLMOD(allocate_sparse) (nrow, ncol, MAX (anz, nzmax), TRUE, TRUE, stype, T->xtype, Common) ; if (stype) { ok = CHOLMOD(transpose_sym) (R, 1, NULL, A, Common) ; } else { ok = CHOLMOD(transpose_unsym) (R, 1, NULL, NULL, 0, A, Common) ; } CHOLMOD(free_sparse) (&R, Common) ; if (Common->status < CHOLMOD_OK) { CHOLMOD(free_sparse) (&A, Common) ; } /* ---------------------------------------------------------------------- */ /* return result */ /* ---------------------------------------------------------------------- */ ASSERT (CHOLMOD(dump_sparse) (A, "A = triplet(T) result", Common) >= 0) ; return (A) ; } /* ========================================================================== */ /* === cholmod_sparse_to_triplet ============================================ */ /* ========================================================================== */ /* Converts a sparse column-oriented matrix to triplet form. * The resulting triplet matrix has the same xtype as the sparse matrix. * * workspace: none */ cholmod_triplet *CHOLMOD(sparse_to_triplet) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to copy */ /* --------------- */ cholmod_common *Common ) { double *Ax, *Az, *Tx, *Tz ; Int *Ap, *Ai, *Ti, *Tj, *Anz ; cholmod_triplet *T ; Int i, xtype, p, pend, k, j, nrow, ncol, nz, stype, packed, up, lo, both ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (A, NULL) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, NULL) ; stype = SIGN (A->stype) ; nrow = A->nrow ; ncol = A->ncol ; if (stype && nrow != ncol) { /* inputs invalid */ ERROR (CHOLMOD_INVALID, "matrix invalid") ; return (NULL) ; } Ax = A->x ; Az = A->z ; xtype = A->xtype ; Common->status = CHOLMOD_OK ; ASSERT (CHOLMOD(dump_sparse) (A, "A", Common) >= 0) ; /* ---------------------------------------------------------------------- */ /* allocate triplet matrix */ /* ---------------------------------------------------------------------- */ nz = CHOLMOD(nnz) (A, Common) ; T = CHOLMOD(allocate_triplet) (nrow, ncol, nz, A->stype, A->xtype, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory */ } /* ---------------------------------------------------------------------- */ /* convert to a sparse matrix */ /* ---------------------------------------------------------------------- */ Ap = A->p ; Ai = A->i ; Anz = A->nz ; packed = A->packed ; Ti = T->i ; Tj = T->j ; Tx = T->x ; Tz = T->z ; T->stype = A->stype ; both = (A->stype == 0) ; up = (A->stype > 0) ; lo = (A->stype < 0) ; k = 0 ; for (j = 0 ; j < ncol ; j++) { p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; if (both || (up && i <= j) || (lo && i >= j)) { Ti [k] = Ai [p] ; Tj [k] = j ; if (xtype == CHOLMOD_REAL) { Tx [k] = Ax [p] ; } else if (xtype == CHOLMOD_COMPLEX) { Tx [2*k ] = Ax [2*p ] ; Tx [2*k+1] = Ax [2*p+1] ; } else if (xtype == CHOLMOD_ZOMPLEX) { Tx [k] = Ax [p] ; Tz [k] = Az [p] ; } k++ ; ASSERT (k <= nz) ; } } } T->nnz = k ; /* ---------------------------------------------------------------------- */ /* return result */ /* ---------------------------------------------------------------------- */ ASSERT (CHOLMOD(dump_triplet) (T, "T", Common)) ; return (T) ; } /* ========================================================================== */ /* === cholmod_copy_triplet ================================================= */ /* ========================================================================== */ /* Create an exact copy of a triplet matrix, except that entries in unused * space are not copied (they might not be initialized, and copying them would * cause program checkers such as purify and valgrind to complain). * The output triplet matrix has the same xtype as the input triplet matrix. */ cholmod_triplet *CHOLMOD(copy_triplet) ( /* ---- input ---- */ cholmod_triplet *T, /* matrix to copy */ /* --------------- */ cholmod_common *Common ) { double *Tx, *Tz, *Cx, *Cz ; Int *Ci, *Cj, *Ti, *Tj ; cholmod_triplet *C ; Int xtype, k, nz ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (T, NULL) ; RETURN_IF_XTYPE_INVALID (T, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, NULL) ; nz = T->nnz ; Ti = T->i ; Tj = T->j ; Tx = T->x ; Tz = T->z ; xtype = T->xtype ; RETURN_IF_NULL (Ti, NULL) ; RETURN_IF_NULL (Tj, NULL) ; Common->status = CHOLMOD_OK ; DEBUG (CHOLMOD(dump_triplet) (T, "T input", Common)) ; /* ---------------------------------------------------------------------- */ /* allocate copy */ /* ---------------------------------------------------------------------- */ C = CHOLMOD(allocate_triplet) (T->nrow, T->ncol, T->nzmax, T->stype, xtype, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory */ } /* ---------------------------------------------------------------------- */ /* copy the triplet matrix */ /* ---------------------------------------------------------------------- */ Ci = C->i ; Cj = C->j ; Cx = C->x ; Cz = C->z ; C->nnz = nz ; for (k = 0 ; k < nz ; k++) { Ci [k] = Ti [k] ; } for (k = 0 ; k < nz ; k++) { Cj [k] = Tj [k] ; } if (xtype == CHOLMOD_REAL) { for (k = 0 ; k < nz ; k++) { Cx [k] = Tx [k] ; } } else if (xtype == CHOLMOD_COMPLEX) { for (k = 0 ; k < nz ; k++) { Cx [2*k ] = Tx [2*k ] ; Cx [2*k+1] = Tx [2*k+1] ; } } else if (xtype == CHOLMOD_ZOMPLEX) { for (k = 0 ; k < nz ; k++) { Cx [k] = Tx [k] ; Cz [k] = Tz [k] ; } } /* ---------------------------------------------------------------------- */ /* return the result */ /* ---------------------------------------------------------------------- */ ASSERT (CHOLMOD(dump_triplet) (C, "C triplet copy", Common)) ; return (C) ; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Core/t_cholmod_change_factor.c���������������������������������������������������0000644�0001762�0000144�00000037152�13652535054�021261� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Core/t_cholmod_change_factor ========================================= */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Core Module. Copyright (C) 2005-2006, * Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* Template routine for cholmod_change_factor. All xtypes supported. */ #include "cholmod_template.h" /* ========================================================================== */ /* === t_change_simplicial_numeric ========================================== */ /* ========================================================================== */ static void TEMPLATE (change_simplicial_numeric) ( cholmod_factor *L, Int to_ll, Int to_packed, Int *newLi, double *newLx, double *newLz, Int lnz, Int grow, double grow1, Int grow2, Int make_ll, Int make_monotonic, Int make_ldl, cholmod_common *Common ) { double xlen, dj [1], ljj [1], lj2 [1] ; double *Lx, *Lz ; Int *Lp, *Li, *Lnz ; Int n, j, len, pnew, pold, k, p, pend ; n = L->n ; Lp = L->p ; Li = L->i ; Lx = L->x ; Lz = L->z ; Lnz = L->nz ; if (make_ll) { L->minor = n ; } if (make_monotonic) { /* ------------------------------------------------------------------ */ /* reorder the columns to make them monotonic */ /* ------------------------------------------------------------------ */ pnew = 0 ; for (j = 0 ; j < n ; j++) { /* copy and pack column j */ len = Lnz [j] ; PRINT2 (("j: "ID" Lnz[j] "ID" len "ID" p "ID"\n", j, Lnz [j], len, pnew)) ; pold = Lp [j] ; ASSERT (Li [pold] == j) ; if (make_ll) { /* ---------------------------------------------------------- */ /* copy and convert LDL' to LL' */ /* ---------------------------------------------------------- */ /* dj = Lx [pold] ; */ ASSIGN_REAL (dj,0, Lx,pold) ; if (IS_LE_ZERO (dj [0])) { /* Conversion has failed; matrix is not positive definite. * Do not modify the column so that the LDL' factorization * can be restored if desired, by converting back to LDL'. * Continue the conversion, but flag the error. */ if (L->minor == (size_t) n) { ERROR (CHOLMOD_NOT_POSDEF, "L not positive definite") ; L->minor = j ; } for (k = 0 ; k < len ; k++) { newLi [pnew + k] = Li [pold + k] ; /* newLx [pnew + k] = Lx [pold + k] ; */ ASSIGN (newLx, newLz, pnew+k, Lx, Lz, pold+k) ; } } else { ljj [0] = sqrt (dj [0]) ; newLi [pnew] = j ; /* newLx [pnew] = ljj ; */ ASSIGN_REAL (newLx, pnew, ljj, 0) ; CLEAR_IMAG (newLx, newLz, pnew) ; for (k = 1 ; k < len ; k++) { newLi [pnew + k] = Li [pold + k] ; /* newLx [pnew + k] = Lx [pold + k] * ljj ; */ MULT_REAL (newLx, newLz, pnew+k, Lx, Lz, pold+k, ljj,0); } } } else if (make_ldl) { /* ---------------------------------------------------------- */ /* copy and convert LL' to LDL' */ /* ---------------------------------------------------------- */ /* ljj = Lx [pold] ; */ ASSIGN_REAL (ljj, 0, Lx, pold) ; if (ljj [0] <= 0) { /* matrix is not positive-definite; copy column as-is */ for (k = 0 ; k < len ; k++) { newLi [pnew + k] = Li [pold + k] ; /* newLx [pnew + k] = Lx [pold + k] ; */ ASSIGN (newLx, newLz, pnew+k, Lx, Lz, pold+k) ; } } else { newLi [pnew] = j ; /* newLx [pnew] = ljj*ljj ; */ lj2 [0] = ljj [0] * ljj [0] ; ASSIGN_REAL (newLx, pnew, lj2, 0) ; CLEAR_IMAG (newLx, newLz, pnew) ; for (k = 1 ; k < len ; k++) { newLi [pnew + k] = Li [pold + k] ; /* newLx [pnew + k] = Lx [pold + k] / ljj ; */ DIV_REAL (newLx, newLz, pnew+k, Lx, Lz, pold+k, ljj,0) ; } } } else { /* ---------------------------------------------------------- */ /* copy and leave LL' or LDL' as-is */ /* ---------------------------------------------------------- */ for (k = 0 ; k < len ; k++) { newLi [pnew + k] = Li [pold + k] ; /* newLx [pnew + k] = Lx [pold + k] ; */ ASSIGN (newLx, newLz, pnew+k, Lx, Lz, pold+k) ; } } Lp [j] = pnew ; /* compute len in double to avoid integer overflow */ if (grow) { xlen = (double) len ; xlen = grow1 * xlen + grow2 ; xlen = MIN (xlen, n-j) ; len = (Int) xlen ; } ASSERT (len >= Lnz [j] && len <= n-j) ; pnew += len ; ASSERT (pnew > 0) ; /* integer overflow case already covered */ } Lp [n] = pnew ; PRINT1 (("final pnew = "ID", lnz "ID" lnzmax %g\n", pnew, lnz, (double) L->nzmax)) ; ASSERT (pnew <= lnz) ; /* free the old L->i and L->x and replace with the new ones */ CHOLMOD(free) (L->nzmax, sizeof (Int), L->i, Common) ; #ifdef REAL CHOLMOD(free) (L->nzmax, sizeof (double), L->x, Common) ; #elif defined (COMPLEX) CHOLMOD(free) (L->nzmax, 2*sizeof (double), L->x, Common) ; #else CHOLMOD(free) (L->nzmax, sizeof (double), L->x, Common) ; CHOLMOD(free) (L->nzmax, sizeof (double), L->z, Common) ; #endif L->i = newLi ; L->x = newLx ; L->z = newLz ; L->nzmax = lnz ; /* reconstruct the link list */ natural_list (L) ; } else if (to_packed) { /* ------------------------------------------------------------------ */ /* already monotonic, just pack the columns of L */ /* ------------------------------------------------------------------ */ pnew = 0 ; if (make_ll) { /* -------------------------------------------------------------- */ /* pack and convert LDL' to LL' */ /* -------------------------------------------------------------- */ for (j = 0 ; j < n ; j++) { /* pack column j */ pold = Lp [j] ; len = Lnz [j] ; ASSERT (len > 0) ; ASSERT (Li [pold] == j) ; PRINT2 (("col "ID" pnew "ID" pold "ID"\n", j, pnew, pold)) ; /* dj = Lx [pold] ; */ ASSIGN_REAL (dj,0, Lx,pold) ; if (IS_LE_ZERO (dj [0])) { /* Conversion has failed; matrix is not positive definite. * Do not modify the column so that the LDL' factorization * can be restored if desired, by converting back to LDL'. * Continue the conversion, but flag the error. */ if (L->minor == (size_t) n) { ERROR (CHOLMOD_NOT_POSDEF, "L not positive definite") ; L->minor = j ; } for (k = 0 ; k < len ; k++) { Li [pnew + k] = Li [pold + k] ; /* Lx [pnew + k] = Lx [pold + k] ; */ ASSIGN (Lx, Lz, pnew+k, Lx, Lz, pold+k) ; } } else { ljj [0] = sqrt (dj [0]) ; Li [pnew] = j ; /* Lx [pnew] = ljj ; */ ASSIGN_REAL (Lx, pnew, ljj, 0) ; CLEAR_IMAG (Lx, Lz, pnew) ; for (k = 1 ; k < len ; k++) { Li [pnew + k] = Li [pold + k] ; /* Lx [pnew + k] = Lx [pold + k] * ljj ; */ MULT_REAL (Lx, Lz, pnew+k, Lx, Lz, pold+k, ljj,0) ; } } Lp [j] = pnew ; pnew += len ; } } else if (make_ldl) { /* -------------------------------------------------------------- */ /* pack and convert LL' to LDL' */ /* -------------------------------------------------------------- */ for (j = 0 ; j < n ; j++) { /* pack column j */ pold = Lp [j] ; len = Lnz [j] ; /* ljj = Lx [pold] ; */ ASSIGN_REAL (ljj, 0, Lx, pold) ; ASSERT (len > 0) ; PRINT2 (("col "ID" pnew "ID" pold "ID"\n", j, pnew, pold)) ; if (ljj [0] <= 0) { /* matrix is not positive-definite; pack column as-is */ for (k = 0 ; k < len ; k++) { Li [pnew + k] = Li [pold + k] ; /* Lx [pnew + k] = Lx [pold + k] ; */ ASSIGN (Lx, Lz, pnew+k, Lx, Lz, pold+k) ; } } else { Li [pnew] = Li [pold] ; /* Lx [pnew] = ljj*ljj ; */ lj2 [0] = ljj [0] * ljj [0] ; ASSIGN_REAL (Lx, pnew, lj2, 0) ; CLEAR_IMAG (Lx, Lz, pnew) ; for (k = 1 ; k < len ; k++) { Li [pnew + k] = Li [pold + k] ; /* Lx [pnew + k] = Lx [pold + k] / ljj ; */ DIV_REAL (Lx, Lz, pnew+k, Lx, Lz, pold+k, ljj,0) ; } } Lp [j] = pnew ; pnew += len ; } } else { /* ---------------------------------------------------------- */ /* pack and leave LL' or LDL' as-is */ /* ---------------------------------------------------------- */ for (j = 0 ; j < n ; j++) { /* pack column j */ pold = Lp [j] ; len = Lnz [j] ; ASSERT (len > 0) ; PRINT2 (("col "ID" pnew "ID" pold "ID"\n", j, pnew, pold)) ; if (pnew < pold) { PRINT2 ((" pack this column\n")) ; for (k = 0 ; k < len ; k++) { Li [pnew + k] = Li [pold + k] ; /* Lx [pnew + k] = Lx [pold + k] ; */ ASSIGN (Lx, Lz, pnew+k, Lx, Lz, pold+k) ; } Lp [j] = pnew ; } pnew += len ; } } Lp [n] = pnew ; PRINT2 (("Lp [n] = "ID"\n", pnew)) ; } else if (make_ll) { /* ------------------------------------------------------------------ */ /* convert LDL' to LL', but do so in-place */ /* ------------------------------------------------------------------ */ for (j = 0 ; j < n ; j++) { p = Lp [j] ; pend = p + Lnz [j] ; /* dj = Lx [p] ; */ ASSIGN_REAL (dj,0, Lx,p) ; if (IS_LE_ZERO (dj [0])) { /* Conversion has failed; matrix is not positive definite. * Do not modify the column so that the LDL' factorization * can be restored if desired, by converting back to LDL'. * Continue the conversion, but flag the error. */ if (L->minor == (size_t) n) { ERROR (CHOLMOD_NOT_POSDEF, "L not positive definite") ; L->minor = j ; } } else { ljj [0] = sqrt (dj [0]) ; /* Lx [p] = ljj ; */ ASSIGN_REAL (Lx,p, ljj,0) ; CLEAR_IMAG (Lx, Lz, p) ; for (p++ ; p < pend ; p++) { /* Lx [p] *= ljj ; */ MULT_REAL (Lx,Lz,p, Lx,Lz,p, ljj,0) ; } } } } else if (make_ldl) { /* ------------------------------------------------------------------ */ /* convert LL' to LDL', but do so in-place */ /* ------------------------------------------------------------------ */ for (j = 0 ; j < n ; j++) { p = Lp [j] ; pend = p + Lnz [j] ; /* ljj = Lx [p] ; */ ASSIGN_REAL (ljj, 0, Lx, p) ; if (ljj [0] > 0) { /* Lx [p] = ljj*ljj ; */ lj2 [0] = ljj [0] * ljj [0] ; ASSIGN_REAL (Lx, p, lj2, 0) ; CLEAR_IMAG (Lx, Lz, p) ; for (p++ ; p < pend ; p++) { /* Lx [p] /= ljj ; */ DIV_REAL (Lx,Lz,p, Lx,Lz,p, ljj,0) ; } } } } L->is_ll = to_ll ; DEBUG (CHOLMOD(dump_factor) (L, "done change simplicial numeric", Common)) ; } /* ========================================================================== */ /* === t_ll_super_to_simplicial_numeric ===================================== */ /* ========================================================================== */ /* A supernodal L can only be real or complex, not zomplex */ #ifndef ZOMPLEX static void TEMPLATE (ll_super_to_simplicial_numeric) ( cholmod_factor *L, Int to_packed, Int to_ll, cholmod_common *Common ) { double ljj [1], lj2 [1] ; double *Lx ; Int *Ls, *Lpi, *Lpx, *Super, *Lp, *Li, *Lnz ; Int n, lnz, s, nsuper, p, psi, psx, psend, nsrow, nscol, ii, jj, j, k1, k2, q ; L->is_ll = to_ll ; Lp = L->p ; Li = L->i ; Lx = L->x ; Lnz = L->nz ; lnz = L->nzmax ; n = L->n ; nsuper = L->nsuper ; Lpi = L->pi ; Lpx = L->px ; Ls = L->s ; Super = L->super ; p = 0 ; for (s = 0 ; s < nsuper ; s++) { k1 = Super [s] ; k2 = Super [s+1] ; psi = Lpi [s] ; psend = Lpi [s+1] ; psx = Lpx [s] ; nsrow = psend - psi ; nscol = k2 - k1 ; for (jj = 0 ; jj < nscol ; jj++) { /* column j of L starts here */ j = jj + k1 ; if (to_ll) { if (to_packed) { /* ------------------------------------------------------ */ /* convert to LL' packed */ /* ------------------------------------------------------ */ Lp [j] = p ; PRINT2 (("Col j "ID" p "ID"\n", j, p)) ; for (ii = jj ; ii < nsrow ; ii++) { /* get L(i,j) from supernode and store in column j */ ASSERT (p < (Int) (L->xsize) && p <= psx+ii+jj*nsrow) ; Li [p] = Ls [psi + ii] ; /* Lx [p] = Lx [psx + ii + jj*nsrow] ; */ q = psx + ii + jj*nsrow ; ASSIGN (Lx,-,p, Lx,-,q) ; PRINT2 ((" i "ID" ", Li [p])) ; XPRINT2 (Lx,-,q) ; PRINT2 (("\n")) ; p++ ; } Lnz [j] = p - Lp [j] ; } else { /* ------------------------------------------------------ */ /* convert to LL' unpacked */ /* ------------------------------------------------------ */ p = psx + jj + jj*nsrow ; Lp [j] = p ; Li [p] = j ; Lnz [j] = nsrow - jj ; p++ ; for (ii = jj + 1 ; ii < nsrow ; ii++) { /* get L(i,j) from supernode and store in column j */ Li [psx + ii + jj*nsrow] = Ls [psi + ii] ; } } } else { if (to_packed) { /* ------------------------------------------------------ */ /* convert to LDL' packed */ /* ------------------------------------------------------ */ Lp [j] = p ; PRINT2 (("Col j "ID" p "ID"\n", Lp [j], p)) ; /* ljj = Lx [psx + jj + jj*nsrow] ; */ ASSIGN_REAL (ljj, 0, Lx, psx + jj + jj*nsrow) ; if (ljj [0] <= 0) { /* the matrix is not positive definite; do not divide */ /* Lx [p] = ljj ; */ ASSIGN_REAL (Lx, p, ljj, 0) ; CLEAR_IMAG (Lx, Lz, p) ; ljj [0] = 1 ; } else { lj2 [0] = ljj [0] * ljj [0] ; /* Lx [p] = ljj*ljj ; */ ASSIGN_REAL (Lx, p, lj2, 0) ; CLEAR_IMAG (Lx, Lz, p) ; } Li [p] = j ; p++ ; for (ii = jj + 1 ; ii < nsrow ; ii++) { /* get L(i,j) from supernode and store in column j */ ASSERT (p < (Int) (L->xsize) && p <= psx+ii+jj*nsrow) ; Li [p] = Ls [psi + ii] ; /* Lx [p] = Lx [psx + ii + jj*nsrow] / ljj ; */ q = psx + ii + jj*nsrow ; DIV_REAL (Lx, Lz, p, Lx, Lz, q, ljj,0) ; PRINT2 ((" i "ID" %g\n", Li [p], Lx [p])) ; p++ ; } Lnz [j] = p - Lp [j] ; } else { /* ------------------------------------------------------ */ /* convert to LDL' unpacked */ /* ------------------------------------------------------ */ p = psx + jj + jj*nsrow ; Lp [j] = p ; /* ljj = Lx [p] ; */ ASSIGN_REAL (ljj,0, Lx,p) ; if (ljj [0] <= 0) { /* the matrix is not positive definite; do not divide */ /* Lx [p] = ljj ; */ ASSIGN_REAL (Lx, p, ljj, 0) ; CLEAR_IMAG (Lx, Lz, p) ; ljj [0] = 1 ; } else { lj2 [0] = ljj [0] * ljj [0] ; /* Lx [p] = ljj*ljj ; */ ASSIGN_REAL (Lx, p, lj2, 0) ; CLEAR_IMAG (Lx, Lz, p) ; } Li [p] = j ; Lnz [j] = nsrow - jj ; p++ ; for (ii = jj + 1 ; ii < nsrow ; ii++) { /* get L(i,j) from supernode and store in column j */ Li [psx + ii + jj*nsrow] = Ls [psi + ii] ; /* Lx [psx + ii + jj*nsrow] /= ljj ; */ q = psx + ii + jj*nsrow ; DIV_REAL (Lx, Lz, q, Lx, Lz, q, ljj,0) ; } } } } } if (to_packed) { Lp [n] = p ; PRINT1 (("Final Lp "ID" n "ID" lnz "ID"\n", p, n, lnz)) ; ASSERT (Lp [n] == lnz) ; ASSERT (lnz <= (Int) (L->xsize)) ; /* reduce size of L->x to match L->i. This cannot fail. */ L->x = CHOLMOD(realloc) (lnz, #ifdef COMPLEX 2 * #endif sizeof (double), L->x, &(L->xsize), Common) ; ASSERT (lnz == (Int) (L->xsize)) ; Common->status = CHOLMOD_OK ; } else { Lp [n] = Lpx [nsuper] ; ASSERT (MAX (1,Lp [n]) == (Int) (L->xsize)) ; ASSERT (MAX (1,Lp [n]) == (Int) (L->nzmax)) ; } } #endif #undef PATTERN #undef REAL #undef COMPLEX #undef ZOMPLEX ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Core/cholmod_error.c�������������������������������������������������������������0000644�0001762�0000144�00000006477�13652535054�017312� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Core/cholmod_error =================================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Core Module. Copyright (C) 2005-2006, * Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* CHOLMOD error-handling routine. */ #include "cholmod_internal.h" #include "cholmod_core.h" /* ========================================================================== */ /* ==== cholmod_error ======================================================= */ /* ========================================================================== */ /* An error has occurred. Set the status, optionally print an error message, * and call the user error-handling routine (if it exists). If * Common->try_catch is TRUE, then CHOLMOD is inside a try/catch block. * The status is set, but no message is printed and the user error handler * is not called. This is not (yet) an error, since CHOLMOD may recover. * * In the current version, this try/catch mechanism is used internally only in * cholmod_analyze, which tries multiple ordering methods and picks the best * one. If one or more ordering method fails, it keeps going. Only one * ordering needs to succeed for cholmod_analyze to succeed. */ int CHOLMOD(error) ( /* ---- input ---- */ int status, /* error status */ const char *file, /* name of source code file where error occured */ int line, /* line number in source code file where error occured*/ const char *message, /* error message */ /* --------------- */ cholmod_common *Common ) { RETURN_IF_NULL_COMMON (FALSE) ; Common->status = status ; if (!(Common->try_catch)) { #ifndef NPRINT /* print a warning or error message */ if (SuiteSparse_config.printf_func != NULL) { if (status > 0 && Common->print > 1) { SuiteSparse_config.printf_func ("CHOLMOD warning:") ; if (message != NULL) { SuiteSparse_config.printf_func (" %s.", message) ; } if (file != NULL) { SuiteSparse_config.printf_func (" file: %s", file) ; SuiteSparse_config.printf_func (" line: %d", line) ; } SuiteSparse_config.printf_func ("\n") ; fflush (stdout) ; fflush (stderr) ; } else if (Common->print > 0) { SuiteSparse_config.printf_func ("CHOLMOD error:") ; if (message != NULL) { SuiteSparse_config.printf_func (" %s.", message) ; } if (file != NULL) { SuiteSparse_config.printf_func (" file: %s", file) ; SuiteSparse_config.printf_func (" line: %d", line) ; } SuiteSparse_config.printf_func ("\n") ; fflush (stdout) ; fflush (stderr) ; } } #endif /* call the user error handler, if it exists */ if (Common->error_handler != NULL) { Common->error_handler (status, file, line, message) ; } } return (TRUE) ; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Core/cholmod_change_factor.c�����������������������������������������������������0000644�0001762�0000144�00000113014�13652535054�020726� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Core/cholmod_change_factor =========================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Core Module. Copyright (C) 2005-2006, * Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* Change the numeric/symbolic, LL/LDL, simplicial/super, packed/unpacked, * monotonic/non-monotonic status of a cholmod_factor object. * * There are four basic classes of factor types: * * (1) simplicial symbolic: Consists of two size-n arrays: the fill-reducing * permutation (L->Perm) and the nonzero count for each column of L * (L->ColCount). All other factor types also include this information. * L->ColCount may be exact (obtained from the analysis routines), or * it may be a guess. During factorization, and certainly after update/ * downdate, the columns of L can have a different number of nonzeros. * L->ColCount is used to allocate space. L->ColCount is exact for the * supernodal factorizations. The nonzero pattern of L is not kept. * * (2) simplicial numeric: These represent L in a compressed column form. The * variants of this type are: * * LDL': L is unit diagonal. Row indices in column j are located in * L->i [L->p [j] ... L->p [j] + L->nz [j]], and corresponding numeric * values are in the same locations in L->x. The total number of * entries is the sum of L->nz [j]. The unit diagonal is not stored; * D is stored on the diagonal of L instead. L->p may or may not be * monotonic. The order of storage of the columns in L->i and L->x is * given by a doubly-linked list (L->prev and L->next). L->p is of * size n+1, but only the first n entries are used (it is used if L * is converted to a sparse matrix via cholmod_factor_to_sparse). * * For the complex case, L->x is stored interleaved with real/imag * parts, and is of size 2*lnz*sizeof(double). For the zomplex case, * L->x is of size lnz*sizeof(double) and holds the real part; L->z * is the same size and holds the imaginary part. * * LL': This is identical to the LDL' form, except that the non-unit * diagonal of L is stored as the first entry in each column of L. * * (3) supernodal symbolic: A representation of the nonzero pattern of the * supernodes for a supernodal factorization. There are L->nsuper * supernodes. Columns L->super [k] to L->super [k+1]-1 are in the kth * supernode. The row indices for the kth supernode are in * L->s [L->pi [k] ... L->pi [k+1]-1]. The numerical values are not * allocated (L->x), but when they are they will be located in * L->x [L->px [k] ... L->px [k+1]-1], and the L->px array is defined * in this factor type. * * For the complex case, L->x is stored interleaved with real/imag parts, * and is of size 2*L->xsize*sizeof(double). The zomplex supernodal case * is not supported, since it is not compatible with LAPACK and the BLAS. * * (4) supernodal numeric: Always an LL' factorization. L is non-unit * diagonal. L->x contains the numerical values of the supernodes, as * described above for the supernodal symbolic factor. * For the complex case, L->x is stored interleaved, and is of size * 2*L->xsize*sizeof(double). The zomplex supernodal case is not * supported, since it is not compatible with LAPACK and the BLAS. * * FUTURE WORK: support a supernodal LDL' factor. * * * In all cases, the row indices in each column (L->i for simplicial L and * L->s for supernodal L) are kept sorted from low indices to high indices. * This means the diagonal of L (or D for LDL' factors) is always kept as the * first entry in each column. * * The cholmod_change_factor routine can do almost all possible conversions. * It cannot do the following conversions: * * (1) Simplicial numeric types cannot be converted to a supernodal * symbolic type. This would simultaneously deallocate the * simplicial pattern and numeric values and reallocate uninitialized * space for the supernodal pattern. This isn't useful for the user, * and not needed by CHOLMOD's own routines either. * * (2) Only a symbolic factor (simplicial to supernodal) can be converted * to a supernodal numeric factor. * * Some conversions are meant only to be used internally by other CHOLMOD * routines, and should not be performed by the end user. They allocate space * whose contents are undefined: * * (1) converting from simplicial symbolic to supernodal symbolic. * (2) converting any factor to supernodal numeric. * * workspace: no conversion routine uses workspace in Common. No temporary * workspace is allocated. * * Supports all xtypes, except that there is no supernodal zomplex L. * * The to_xtype parameter is used only when converting from symbolic to numeric * or numeric to symbolic. It cannot be used to convert a numeric xtype (real, * complex, or zomplex) to a different numeric xtype. For that conversion, * use cholmod_factor_xtype instead. */ #include "cholmod_internal.h" #include "cholmod_core.h" static void natural_list (cholmod_factor *L) ; /* ========================================================================== */ /* === TEMPLATE ============================================================= */ /* ========================================================================== */ #define REAL #include "t_cholmod_change_factor.c" #define COMPLEX #include "t_cholmod_change_factor.c" #define ZOMPLEX #include "t_cholmod_change_factor.c" /* ========================================================================== */ /* === L_is_packed ========================================================== */ /* ========================================================================== */ /* Return TRUE if the columns of L are packed, FALSE otherwise. For debugging * only. */ #ifndef NDEBUG static int L_is_packed (cholmod_factor *L, cholmod_common *Common) { Int j ; Int *Lnz = L->nz ; Int *Lp = L->p ; Int n = L->n ; if (L->xtype == CHOLMOD_PATTERN || L->is_super) { return (TRUE) ; } if (Lnz == NULL || Lp == NULL) { return (TRUE) ; } for (j = 0 ; j < n ; j++) { PRINT3 (("j: "ID" Lnz "ID" Lp[j+1] "ID" Lp[j] "ID"\n", j, Lnz [j], Lp [j+1], Lp [j])) ; if (Lnz [j] != (Lp [j+1] - Lp [j])) { PRINT2 (("L is not packed\n")) ; return (FALSE) ; } } return (TRUE) ; } #endif /* ========================================================================== */ /* === natural_list ========================================================= */ /* ========================================================================== */ /* Create a naturally-ordered doubly-linked list of columns. */ static void natural_list (cholmod_factor *L) { Int head, tail, n, j ; Int *Lnext, *Lprev ; Lnext = L->next ; Lprev = L->prev ; ASSERT (Lprev != NULL && Lnext != NULL) ; n = L->n ; head = n+1 ; tail = n ; Lnext [head] = 0 ; Lprev [head] = EMPTY ; Lnext [tail] = EMPTY ; Lprev [tail] = n-1 ; for (j = 0 ; j < n ; j++) { Lnext [j] = j+1 ; Lprev [j] = j-1 ; } Lprev [0] = head ; L->is_monotonic = TRUE ; } /* ========================================================================== */ /* === allocate_simplicial_numeric ========================================== */ /* ========================================================================== */ /* Allocate O(n) arrays for simplicial numeric factorization. Initializes * the link lists only. Does not allocate the L->i, L->x, or L->z arrays. */ static int allocate_simplicial_numeric ( cholmod_factor *L, cholmod_common *Common ) { Int n ; Int *Lp, *Lnz, *Lprev, *Lnext ; size_t n1, n2 ; PRINT1 (("Allocate simplicial\n")) ; ASSERT (L->xtype == CHOLMOD_PATTERN || L->is_super) ; ASSERT (L->p == NULL) ; ASSERT (L->nz == NULL) ; ASSERT (L->prev == NULL) ; ASSERT (L->next == NULL) ; n = L->n ; /* this cannot cause size_t overflow */ n1 = ((size_t) n) + 1 ; n2 = ((size_t) n) + 2 ; Lp = CHOLMOD(malloc) (n1, sizeof (Int), Common) ; Lnz = CHOLMOD(malloc) (n, sizeof (Int), Common) ; Lprev = CHOLMOD(malloc) (n2, sizeof (Int), Common) ; Lnext = CHOLMOD(malloc) (n2, sizeof (Int), Common) ; if (Common->status < CHOLMOD_OK) { CHOLMOD(free) (n1, sizeof (Int), Lp, Common) ; CHOLMOD(free) (n, sizeof (Int), Lnz, Common) ; CHOLMOD(free) (n2, sizeof (Int), Lprev, Common) ; CHOLMOD(free) (n2, sizeof (Int), Lnext, Common) ; PRINT1 (("Allocate simplicial failed\n")) ; return (FALSE) ; /* out of memory */ } /* ============================================== commit the changes to L */ L->p = Lp ; L->nz = Lnz ; L->prev = Lprev ; L->next = Lnext ; /* initialize a doubly linked list for columns in natural order */ natural_list (L) ; PRINT1 (("Allocate simplicial done\n")) ; return (TRUE) ; } /* ========================================================================== */ /* === simplicial_symbolic_to_super_symbolic ================================ */ /* ========================================================================== */ /* Convert a simplicial symbolic factor supernodal symbolic factor. Does not * initialize the new space. */ static int simplicial_symbolic_to_super_symbolic ( cholmod_factor *L, cholmod_common *Common ) { Int nsuper, xsize, ssize ; Int *Lsuper, *Lpi, *Lpx, *Ls ; size_t nsuper1 ; ASSERT (L->xtype == CHOLMOD_PATTERN && !(L->is_super)) ; xsize = L->xsize ; ssize = L->ssize ; nsuper = L->nsuper ; nsuper1 = ((size_t) nsuper) + 1 ; PRINT1 (("simple sym to super sym: ssize "ID" xsize "ID" nsuper "ID"" " status %d\n", ssize, xsize, nsuper, Common->status)) ; /* O(nsuper) arrays, where nsuper <= n */ Lsuper = CHOLMOD(malloc) (nsuper1, sizeof (Int), Common) ; Lpi = CHOLMOD(malloc) (nsuper1, sizeof (Int), Common) ; Lpx = CHOLMOD(malloc) (nsuper1, sizeof (Int), Common) ; /* O(ssize) array, where ssize <= nnz(L), and usually much smaller */ Ls = CHOLMOD(malloc) (ssize, sizeof (Int), Common) ; if (Common->status < CHOLMOD_OK) { CHOLMOD(free) (nsuper1, sizeof (Int), Lsuper, Common) ; CHOLMOD(free) (nsuper1, sizeof (Int), Lpi, Common) ; CHOLMOD(free) (nsuper1, sizeof (Int), Lpx, Common) ; CHOLMOD(free) (ssize, sizeof (Int), Ls, Common) ; return (FALSE) ; /* out of memory */ } /* ============================================== commit the changes to L */ ASSERT (Lsuper != NULL && Lpi != NULL && Lpx != NULL && Ls != NULL) ; L->maxcsize = 0 ; L->maxesize = 0 ; L->super = Lsuper ; L->pi = Lpi ; L->px = Lpx ; L->s = Ls ; Ls [0] = EMPTY ; /* supernodal pattern undefined */ L->is_super = TRUE ; L->is_ll = TRUE ; /* supernodal LDL' not supported */ L->xtype = CHOLMOD_PATTERN ; L->dtype = DTYPE ; L->minor = L->n ; return (TRUE) ; } /* ========================================================================== */ /* === any_to_simplicial_symbolic =========================================== */ /* ========================================================================== */ /* Convert any factor L to a simplicial symbolic factor, leaving only L->Perm * and L->ColCount. Cannot fail. Any of the components of L (except Perm and * ColCount) may already be free'd. */ static void any_to_simplicial_symbolic ( cholmod_factor *L, int to_ll, cholmod_common *Common ) { Int n, lnz, xs, ss, s, e ; size_t n1, n2 ; /* ============================================== commit the changes to L */ n = L->n ; lnz = L->nzmax ; s = L->nsuper + 1 ; xs = (L->is_super) ? ((Int) (L->xsize)) : (lnz) ; e = (L->xtype == CHOLMOD_COMPLEX ? 2 : 1) ; ss = L->ssize ; /* this cannot cause size_t overflow */ n1 = ((size_t) n) + 1 ; n2 = ((size_t) n) + 2 ; /* free all but the symbolic analysis (Perm and ColCount) */ L->p = CHOLMOD(free) (n1, sizeof (Int), L->p, Common) ; L->i = CHOLMOD(free) (lnz, sizeof (Int), L->i, Common) ; L->x = CHOLMOD(free) (xs, e*sizeof (double), L->x, Common) ; L->z = CHOLMOD(free) (lnz, sizeof (double), L->z, Common) ; L->nz = CHOLMOD(free) (n, sizeof (Int), L->nz, Common) ; L->next = CHOLMOD(free) (n2, sizeof (Int), L->next, Common) ; L->prev = CHOLMOD(free) (n2, sizeof (Int), L->prev, Common) ; L->super = CHOLMOD(free) (s, sizeof (Int), L->super, Common) ; L->pi = CHOLMOD(free) (s, sizeof (Int), L->pi, Common) ; L->px = CHOLMOD(free) (s, sizeof (Int), L->px, Common) ; L->s = CHOLMOD(free) (ss, sizeof (Int), L->s, Common) ; L->nzmax = 0 ; L->is_super = FALSE ; L->xtype = CHOLMOD_PATTERN ; L->dtype = DTYPE ; L->minor = n ; L->is_ll = to_ll ; } /* ========================================================================== */ /* === ll_super_to_super_symbolic =========================================== */ /* ========================================================================== */ /* Convert a numerical supernodal L to symbolic supernodal. Cannot fail. */ static void ll_super_to_super_symbolic ( cholmod_factor *L, cholmod_common *Common ) { /* ============================================== commit the changes to L */ /* free all but the supernodal numerical factor */ ASSERT (L->xtype != CHOLMOD_PATTERN && L->is_super && L->is_ll) ; DEBUG (CHOLMOD(dump_factor) (L, "start to super symbolic", Common)) ; L->x = CHOLMOD(free) (L->xsize, (L->xtype == CHOLMOD_COMPLEX ? 2 : 1) * sizeof (double), L->x, Common) ; L->xtype = CHOLMOD_PATTERN ; L->dtype = DTYPE ; L->minor = L->n ; L->is_ll = TRUE ; /* supernodal LDL' not supported */ DEBUG (CHOLMOD(dump_factor) (L, "done to super symbolic", Common)) ; } /* ========================================================================== */ /* === simplicial_symbolic_to_simplicial_numeric ============================ */ /* ========================================================================== */ /* Convert a simplicial symbolic L to a simplicial numeric L; allocate space * for L using L->ColCount from symbolic analysis, and set L to identity. * * If packed < 0, then this routine is creating a copy of another factor * (via cholmod_copy_factor). In this case, the space is not initialized. */ static void simplicial_symbolic_to_simplicial_numeric ( cholmod_factor *L, int to_ll, int packed, int to_xtype, cholmod_common *Common ) { double grow0, grow1, xlen, xlnz ; double *Lx, *Lz ; Int *Li, *Lp, *Lnz, *ColCount ; Int n, grow, grow2, p, j, lnz, len, ok, e ; ASSERT (L->xtype == CHOLMOD_PATTERN && !(L->is_super)) ; if (!allocate_simplicial_numeric (L, Common)) { PRINT1 (("out of memory, allocate simplicial numeric\n")) ; return ; /* out of memory */ } ASSERT (L->ColCount != NULL && L->nz != NULL && L->p != NULL) ; ASSERT (L->x == NULL && L->z == NULL && L->i == NULL) ; ColCount = L->ColCount ; Lnz = L->nz ; Lp = L->p ; ok = TRUE ; n = L->n ; if (packed < 0) { /* ------------------------------------------------------------------ */ /* used by cholmod_copy_factor to allocate a copy of a factor object */ /* ------------------------------------------------------------------ */ lnz = L->nzmax ; L->nzmax = 0 ; } else if (packed) { /* ------------------------------------------------------------------ */ /* LDL' or LL' packed */ /* ------------------------------------------------------------------ */ PRINT1 (("convert to packed LL' or LDL'\n")) ; lnz = 0 ; for (j = 0 ; ok && j < n ; j++) { /* ensure len is in the range 1 to n-j */ len = ColCount [j] ; len = MAX (1, len) ; len = MIN (len, n-j) ; lnz += len ; ok = (lnz >= 0) ; } for (j = 0 ; j <= n ; j++) { Lp [j] = j ; } for (j = 0 ; j < n ; j++) { Lnz [j] = 1 ; } } else { /* ------------------------------------------------------------------ */ /* LDL' unpacked */ /* ------------------------------------------------------------------ */ PRINT1 (("convert to unpacked\n")) ; /* compute new lnzmax */ /* if any parameter is NaN, grow is false */ grow0 = Common->grow0 ; grow1 = Common->grow1 ; grow2 = Common->grow2 ; grow0 = IS_NAN (grow0) ? 1 : grow0 ; grow1 = IS_NAN (grow1) ? 1 : grow1 ; /* fl.pt. compare, but no NaN's: */ grow = (grow0 >= 1.0) && (grow1 >= 1.0) && (grow2 > 0) ; PRINT1 (("init, grow1 %g grow2 "ID"\n", grow1, grow2)) ; /* initialize Lp and Lnz for each column */ lnz = 0 ; for (j = 0 ; ok && j < n ; j++) { Lp [j] = lnz ; Lnz [j] = 1 ; /* ensure len is in the range 1 to n-j */ len = ColCount [j] ; len = MAX (1, len) ; len = MIN (len, n-j) ; /* compute len in double to avoid integer overflow */ PRINT1 (("ColCount ["ID"] = "ID"\n", j, len)) ; if (grow) { xlen = (double) len ; xlen = grow1 * xlen + grow2 ; xlen = MIN (xlen, n-j) ; len = (Int) xlen ; } ASSERT (len >= 1 && len <= n-j) ; lnz += len ; ok = (lnz >= 0) ; } if (ok) { Lp [n] = lnz ; if (grow) { /* add extra space */ xlnz = (double) lnz ; xlnz *= grow0 ; xlnz = MIN (xlnz, Size_max) ; xlnz = MIN (xlnz, ((double) n * (double) n + (double) n) / 2) ; lnz = (Int) xlnz ; } } } lnz = MAX (1, lnz) ; if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; } /* allocate L->i, L->x, and L->z */ PRINT1 (("resizing from zero size to lnz "ID"\n", lnz)) ; ASSERT (L->nzmax == 0) ; e = (to_xtype == CHOLMOD_COMPLEX ? 2 : 1) ; if (!ok || !CHOLMOD(realloc_multiple) (lnz, 1, to_xtype, &(L->i), NULL, &(L->x), &(L->z), &(L->nzmax), Common)) { L->p = CHOLMOD(free) (n+1, sizeof (Int), L->p, Common) ; L->nz = CHOLMOD(free) (n, sizeof (Int), L->nz, Common) ; L->prev = CHOLMOD(free) (n+2, sizeof (Int), L->prev, Common) ; L->next = CHOLMOD(free) (n+2, sizeof (Int), L->next, Common) ; L->i = CHOLMOD(free) (lnz, sizeof (Int), L->i, Common) ; L->x = CHOLMOD(free) (lnz, e*sizeof (double), L->x, Common) ; L->z = CHOLMOD(free) (lnz, sizeof (double), L->z, Common) ; PRINT1 (("cannot realloc simplicial numeric\n")) ; return ; /* out of memory */ } /* ============================================== commit the changes to L */ /* initialize L to be the identity matrix */ L->xtype = to_xtype ; L->dtype = DTYPE ; L->minor = n ; Li = L->i ; Lx = L->x ; Lz = L->z ; #if 0 if (lnz == 1) { /* the user won't expect to access this entry, but some CHOLMOD * routines may. Set it to zero so that valgrind doesn't complain. */ switch (to_xtype) { case CHOLMOD_REAL: Lx [0] = 0 ; break ; case CHOLMOD_COMPLEX: Lx [0] = 0 ; Lx [1] = 0 ; break ; case CHOLMOD_ZOMPLEX: Lx [0] = 0 ; Lz [0] = 0 ; break ; } } #endif if (packed >= 0) { /* create the unit diagonal for either the LL' or LDL' case */ switch (L->xtype) { case CHOLMOD_REAL: for (j = 0 ; j < n ; j++) { ASSERT (Lp [j] < Lp [j+1]) ; p = Lp [j] ; Li [p] = j ; Lx [p] = 1 ; } break ; case CHOLMOD_COMPLEX: for (j = 0 ; j < n ; j++) { ASSERT (Lp [j] < Lp [j+1]) ; p = Lp [j] ; Li [p] = j ; Lx [2*p ] = 1 ; Lx [2*p+1] = 0 ; } break ; case CHOLMOD_ZOMPLEX: for (j = 0 ; j < n ; j++) { ASSERT (Lp [j] < Lp [j+1]) ; p = Lp [j] ; Li [p] = j ; Lx [p] = 1 ; Lz [p] = 0 ; } break ; } } L->is_ll = to_ll ; PRINT1 (("done convert simplicial symbolic to numeric\n")) ; } /* ========================================================================== */ /* === change_simplicial_numeric ============================================ */ /* ========================================================================== */ /* Change LL' to LDL', LDL' to LL', or leave as-is. * * If to_packed is TRUE, then the columns of L are packed and made monotonic * (to_monotonic is ignored; it is implicitly TRUE). * * If to_monotonic is TRUE but to_packed is FALSE, the columns of L are made * monotonic but not packed. * * If both to_packed and to_monotonic are FALSE, then the columns of L are * left as-is, and the conversion is done in place. * * If L is already monotonic, or if it is to be left non-monotonic, then this * conversion always succeeds. * * When converting an LDL' to LL' factorization, any column with a negative * or zero diagonal entry is not modified so that conversion back to LDL' will * succeed. This can result in a matrix L with a negative entry on the diagonal * If the kth entry on the diagonal of D is negative, it and the kth column of * L are left unchanged. A subsequent conversion back to an LDL' form will also * leave the column unchanged, so the correct LDL' factorization will be * restored. L->minor is set to the smallest k for which D (k,k) is negative. */ static void change_simplicial_numeric ( cholmod_factor *L, int to_ll, int to_packed, int to_monotonic, cholmod_common *Common ) { double grow0, grow1, xlen, xlnz ; void *newLi, *newLx, *newLz ; double *Lx, *Lz ; Int *Lp, *Li, *Lnz ; Int make_monotonic, grow2, n, j, lnz, len, grow, ok, make_ll, make_ldl ; size_t nzmax0 ; PRINT1 (("\n===Change simplicial numeric: %d %d %d\n", to_ll, to_packed, to_monotonic)) ; DEBUG (CHOLMOD(dump_factor) (L, "change simplicial numeric", Common)) ; ASSERT (L->xtype != CHOLMOD_PATTERN && !(L->is_super)) ; make_monotonic = ((to_packed || to_monotonic) && !(L->is_monotonic)) ; make_ll = (to_ll && !(L->is_ll)) ; make_ldl = (!to_ll && L->is_ll) ; n = L->n ; Lp = L->p ; Li = L->i ; Lx = L->x ; Lz = L->z ; Lnz = L->nz ; grow = FALSE ; grow0 = Common->grow0 ; grow1 = Common->grow1 ; grow2 = Common->grow2 ; grow0 = IS_NAN (grow0) ? 1 : grow0 ; grow1 = IS_NAN (grow1) ? 1 : grow1 ; ok = TRUE ; newLi = NULL ; newLx = NULL ; newLz = NULL ; lnz = 0 ; if (make_monotonic) { /* ------------------------------------------------------------------ */ /* Columns out of order, but will be reordered and optionally packed. */ /* ------------------------------------------------------------------ */ PRINT1 (("L is non-monotonic\n")) ; /* compute new L->nzmax */ if (!to_packed) { /* if any parameter is NaN, grow is false */ /* fl.pt. comparisons below are false if any parameter is NaN */ grow = (grow0 >= 1.0) && (grow1 >= 1.0) && (grow2 > 0) ; } for (j = 0 ; ok && j < n ; j++) { len = Lnz [j] ; ASSERT (len >= 1 && len <= n-j) ; /* compute len in double to avoid integer overflow */ if (grow) { xlen = (double) len ; xlen = grow1 * xlen + grow2 ; xlen = MIN (xlen, n-j) ; len = (Int) xlen ; } ASSERT (len >= Lnz [j] && len <= n-j) ; PRINT2 (("j: "ID" Lnz[j] "ID" len "ID" p "ID"\n", j, Lnz [j], len, lnz)) ; lnz += len ; ok = (lnz >= 0) ; } if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return ; } if (grow) { xlnz = (double) lnz ; xlnz *= grow0 ; xlnz = MIN (xlnz, Size_max) ; xlnz = MIN (xlnz, ((double) n * (double) n + (double) n) / 2) ; lnz = (Int) xlnz ; } lnz = MAX (1, lnz) ; PRINT1 (("final lnz "ID"\n", lnz)) ; nzmax0 = 0 ; CHOLMOD(realloc_multiple) (lnz, 1, L->xtype, &newLi, NULL, &newLx, &newLz, &nzmax0, Common) ; if (Common->status < CHOLMOD_OK) { return ; /* out of memory */ } } /* ============================================== commit the changes to L */ /* ---------------------------------------------------------------------- */ /* convert the simplicial L, using template routine */ /* ---------------------------------------------------------------------- */ switch (L->xtype) { case CHOLMOD_REAL: r_change_simplicial_numeric (L, to_ll, to_packed, newLi, newLx, newLz, lnz, grow, grow1, grow2, make_ll, make_monotonic, make_ldl, Common) ; break ; case CHOLMOD_COMPLEX: c_change_simplicial_numeric (L, to_ll, to_packed, newLi, newLx, newLz, lnz, grow, grow1, grow2, make_ll, make_monotonic, make_ldl, Common) ; break ; case CHOLMOD_ZOMPLEX: z_change_simplicial_numeric (L, to_ll, to_packed, newLi, newLx, newLz, lnz, grow, grow1, grow2, make_ll, make_monotonic, make_ldl, Common) ; break ; } DEBUG (CHOLMOD(dump_factor) (L, "L simplicial changed", Common)) ; } /* ========================================================================== */ /* === ll_super_to_simplicial_numeric ======================================= */ /* ========================================================================== */ /* Convert a supernodal numeric factorization to any simplicial numeric one. * Leaves L->xtype unchanged (real or complex, not zomplex since there is * no supernodal zomplex L). */ static void ll_super_to_simplicial_numeric ( cholmod_factor *L, int to_packed, int to_ll, cholmod_common *Common ) { Int *Ls, *Lpi, *Lpx, *Super, *Li ; Int n, lnz, s, nsuper, psi, psend, nsrow, nscol, k1, k2, erows ; DEBUG (CHOLMOD(dump_factor) (L, "start LL super to simplicial", Common)) ; PRINT1 (("super -> simplicial (%d %d)\n", to_packed, to_ll)) ; ASSERT (L->xtype != CHOLMOD_PATTERN && L->is_ll && L->is_super) ; ASSERT (L->x != NULL && L->i == NULL) ; n = L->n ; nsuper = L->nsuper ; Lpi = L->pi ; Lpx = L->px ; Ls = L->s ; Super = L->super ; /* Int overflow cannot occur since supernodal L already exists */ if (to_packed) { /* count the number of nonzeros in L. Each supernode is of the form * * l . . . For this example, nscol = 4 (# columns). nsrow = 9. * l l . . The "." entries are allocated in the supernodal * l l l . factor, but not used. They are not copied to the * l l l l simplicial factor. Some "l" and "e" entries may be * e e e e numerically zero and even symbolically zero if a * e e e e tight simplicial factorization or resymbol were * e e e e done, because of numerical cancellation and relaxed * e e e e supernode amalgamation, respectively. * e e e e */ lnz = 0 ; for (s = 0 ; s < nsuper ; s++) { k1 = Super [s] ; k2 = Super [s+1] ; psi = Lpi [s] ; psend = Lpi [s+1] ; nsrow = psend - psi ; nscol = k2 - k1 ; ASSERT (nsrow >= nscol) ; erows = nsrow - nscol ; /* lower triangular part, including the diagonal, * counting the "l" terms in the figure above. */ lnz += nscol * (nscol+1) / 2 ; /* rectangular part, below the diagonal block (the "e" terms) */ lnz += nscol * erows ; } ASSERT (lnz <= (Int) (L->xsize)) ; } else { /* Li will be the same size as Lx */ lnz = L->xsize ; } ASSERT (lnz >= 0) ; PRINT1 (("simplicial lnz = "ID" to_packed: %d to_ll: %d L->xsize %g\n", lnz, to_ll, to_packed, (double) L->xsize)) ; Li = CHOLMOD(malloc) (lnz, sizeof (Int), Common) ; if (Common->status < CHOLMOD_OK) { return ; /* out of memory */ } if (!allocate_simplicial_numeric (L, Common)) { CHOLMOD(free) (lnz, sizeof (Int), Li, Common) ; return ; /* out of memory */ } /* ============================================== commit the changes to L */ L->i = Li ; L->nzmax = lnz ; /* ---------------------------------------------------------------------- */ /* convert the supernodal L, using template routine */ /* ---------------------------------------------------------------------- */ switch (L->xtype) { case CHOLMOD_REAL: r_ll_super_to_simplicial_numeric (L, to_packed, to_ll, Common) ; break ; case CHOLMOD_COMPLEX: c_ll_super_to_simplicial_numeric (L, to_packed, to_ll, Common) ; break ; } /* ---------------------------------------------------------------------- */ /* free unused parts of L */ /* ---------------------------------------------------------------------- */ L->super = CHOLMOD(free) (nsuper+1, sizeof (Int), L->super, Common) ; L->pi = CHOLMOD(free) (nsuper+1, sizeof (Int), L->pi, Common) ; L->px = CHOLMOD(free) (nsuper+1, sizeof (Int), L->px, Common) ; L->s = CHOLMOD(free) (L->ssize, sizeof (Int), L->s, Common) ; L->ssize = 0 ; L->xsize = 0 ; L->nsuper = 0 ; L->maxesize = 0 ; L->maxcsize = 0 ; L->is_super = FALSE ; DEBUG (CHOLMOD(dump_factor) (L, "done LL super to simplicial", Common)) ; } /* ========================================================================== */ /* === super_symbolic_to_ll_super =========================================== */ /* ========================================================================== */ /* Convert a supernodal symbolic factorization to a supernodal numeric * factorization by allocating L->x. Contents of L->x are undefined. */ static int super_symbolic_to_ll_super ( int to_xtype, cholmod_factor *L, cholmod_common *Common ) { double *Lx ; Int wentry = (to_xtype == CHOLMOD_REAL) ? 1 : 2 ; PRINT1 (("convert super sym to num\n")) ; ASSERT (L->xtype == CHOLMOD_PATTERN && L->is_super) ; Lx = CHOLMOD(malloc) (L->xsize, wentry * sizeof (double), Common) ; PRINT1 (("xsize %g\n", (double) L->xsize)) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; /* out of memory */ } /* ============================================== commit the changes to L */ if (L->xsize == 1) { /* the caller won't expect to access this entry, but some CHOLMOD * routines may. Set it to zero so that valgrind doesn't complain. */ switch (to_xtype) { case CHOLMOD_REAL: Lx [0] = 0 ; break ; case CHOLMOD_COMPLEX: Lx [0] = 0 ; Lx [1] = 0 ; break ; } } L->x = Lx ; L->xtype = to_xtype ; L->dtype = DTYPE ; L->minor = L->n ; return (TRUE) ; } /* ========================================================================== */ /* === cholmod_change_factor ================================================ */ /* ========================================================================== */ /* Convert a factor L. Some conversions simply allocate uninitialized space * that meant to be filled later. * * If the conversion fails, the factor is left in its original form, with one * exception. Converting a supernodal symbolic factor to a simplicial numeric * one (with L=D=I) may leave the factor in simplicial symbolic form. * * Memory allocated for each conversion is listed below. */ int CHOLMOD(change_factor) ( /* ---- input ---- */ int to_xtype, /* convert to CHOLMOD_PATTERN, _REAL, _COMPLEX, or * _ZOMPLEX */ int to_ll, /* TRUE: convert to LL', FALSE: LDL' */ int to_super, /* TRUE: convert to supernodal, FALSE: simplicial */ int to_packed, /* TRUE: pack simplicial columns, FALSE: do not pack */ int to_monotonic, /* TRUE: put simplicial columns in order, FALSE: not */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ /* --------------- */ cholmod_common *Common ) { /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (L, FALSE) ; RETURN_IF_XTYPE_INVALID (L, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; if (to_xtype < CHOLMOD_PATTERN || to_xtype > CHOLMOD_ZOMPLEX) { ERROR (CHOLMOD_INVALID, "xtype invalid") ; return (FALSE) ; } Common->status = CHOLMOD_OK ; PRINT1 (("-----convert from (%d,%d,%d,%d,%d) to (%d,%d,%d,%d,%d)\n", L->xtype, L->is_ll, L->is_super, L_is_packed (L, Common), L->is_monotonic, to_xtype, to_ll, to_super, to_packed, to_monotonic)) ; /* ensure all parameters are TRUE/FALSE */ to_ll = BOOLEAN (to_ll) ; to_super = BOOLEAN (to_super) ; ASSERT (BOOLEAN (L->is_ll) == L->is_ll) ; ASSERT (BOOLEAN (L->is_super) == L->is_super) ; if (to_super && to_xtype == CHOLMOD_ZOMPLEX) { ERROR (CHOLMOD_INVALID, "supernodal zomplex L not supported") ; return (FALSE) ; } /* ---------------------------------------------------------------------- */ /* convert */ /* ---------------------------------------------------------------------- */ if (to_xtype == CHOLMOD_PATTERN) { /* ------------------------------------------------------------------ */ /* convert to symbolic */ /* ------------------------------------------------------------------ */ if (!to_super) { /* -------------------------------------------------------------- */ /* convert any factor into a simplicial symbolic factor */ /* -------------------------------------------------------------- */ any_to_simplicial_symbolic (L, to_ll, Common) ; /* cannot fail */ } else { /* -------------------------------------------------------------- */ /* convert to a supernodal symbolic factor */ /* -------------------------------------------------------------- */ if (L->xtype != CHOLMOD_PATTERN && L->is_super) { /* convert from supernodal numeric to supernodal symbolic. * this preserves symbolic pattern of L, discards numeric * values */ ll_super_to_super_symbolic (L, Common) ; /* cannot fail */ } else if (L->xtype == CHOLMOD_PATTERN && !(L->is_super)) { /* convert from simplicial symbolic to supernodal symbolic. * contents of supernodal pattern are uninitialized. Not meant * for the end user. */ simplicial_symbolic_to_super_symbolic (L, Common) ; } else { /* cannot convert from simplicial numeric to supernodal * symbolic */ ERROR (CHOLMOD_INVALID, "cannot convert L to supernodal symbolic") ; } } } else { /* ------------------------------------------------------------------ */ /* convert to numeric */ /* ------------------------------------------------------------------ */ if (to_super) { /* -------------------------------------------------------------- */ /* convert to supernodal numeric factor */ /* -------------------------------------------------------------- */ if (L->xtype == CHOLMOD_PATTERN) { if (L->is_super) { /* Convert supernodal symbolic to supernodal numeric. * Contents of supernodal numeric values are uninitialized. * This is used by cholmod_super_numeric. Not meant for * the end user. */ super_symbolic_to_ll_super (to_xtype, L, Common) ; } else { /* Convert simplicial symbolic to supernodal numeric. * Contents not defined. This is used by * Core/cholmod_copy_factor only. Not meant for the end * user. */ if (!simplicial_symbolic_to_super_symbolic (L, Common)) { /* failure, convert back to simplicial symbolic */ any_to_simplicial_symbolic (L, to_ll, Common) ; } else { /* conversion to super symbolic OK, allocate numeric * part */ super_symbolic_to_ll_super (to_xtype, L, Common) ; } } } else { /* nothing to do if L is already in supernodal numeric form */ if (!(L->is_super)) { ERROR (CHOLMOD_INVALID, "cannot convert simplicial L to supernodal") ; } /* FUTURE WORK: convert to/from supernodal LL' and LDL' */ } } else { /* -------------------------------------------------------------- */ /* convert any factor to simplicial numeric */ /* -------------------------------------------------------------- */ if (L->xtype == CHOLMOD_PATTERN && !(L->is_super)) { /* ---------------------------------------------------------- */ /* convert simplicial symbolic to simplicial numeric (L=I,D=I)*/ /* ---------------------------------------------------------- */ simplicial_symbolic_to_simplicial_numeric (L, to_ll, to_packed, to_xtype, Common) ; } else if (L->xtype != CHOLMOD_PATTERN && L->is_super) { /* ---------------------------------------------------------- */ /* convert a supernodal LL' to simplicial numeric */ /* ---------------------------------------------------------- */ ll_super_to_simplicial_numeric (L, to_packed, to_ll, Common) ; } else if (L->xtype == CHOLMOD_PATTERN && L->is_super) { /* ---------------------------------------------------------- */ /* convert a supernodal symbolic to simplicial numeric (L=D=I)*/ /* ---------------------------------------------------------- */ any_to_simplicial_symbolic (L, to_ll, Common) ; /* if the following fails, it leaves the factor in simplicial * symbolic form */ simplicial_symbolic_to_simplicial_numeric (L, to_ll, to_packed, to_xtype, Common) ; } else { /* ---------------------------------------------------------- */ /* change a simplicial numeric factor */ /* ---------------------------------------------------------- */ /* change LL' to LDL', LDL' to LL', or leave as-is. pack the * columns of L, or leave as-is. Ensure the columns are * monotonic, or leave as-is. */ change_simplicial_numeric (L, to_ll, to_packed, to_monotonic, Common) ; } } } /* ---------------------------------------------------------------------- */ /* return result */ /* ---------------------------------------------------------------------- */ return (Common->status >= CHOLMOD_OK) ; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Core/cholmod_band.c��������������������������������������������������������������0000644�0001762�0000144�00000022757�13652535054�017064� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Core/cholmod_band ==================================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Core Module. Copyright (C) 2005-2006, * Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* C = tril (triu (A,k1), k2) * * C is a matrix consisting of the diagonals of A from k1 to k2. * * k=0 is the main diagonal of A, k=1 is the superdiagonal, k=-1 is the * subdiagonal, and so on. If A is m-by-n, then: * * k1=-m C = tril (A,k2) * k2=n C = triu (A,k1) * k1=0 and k2=0 C = diag(A), except C is a matrix, not a vector * * Values of k1 and k2 less than -m are treated as -m, and values greater * than n are treated as n. * * A can be of any symmetry (upper, lower, or unsymmetric); C is returned in * the same form, and packed. If A->stype > 0, entries in the lower * triangular part of A are ignored, and the opposite is true if * A->stype < 0. If A has sorted columns, then so does C. * C has the same size as A. * * If inplace is TRUE, then the matrix A is modified in place. * Only packed matrices can be converted in place. * * C can be returned as a numerical valued matrix (if A has numerical values * and mode > 0), as a pattern-only (mode == 0), or as a pattern-only but with * the diagonal entries removed (mode < 0). * * workspace: none * * A can have an xtype of pattern or real. Complex and zomplex cases supported * only if mode <= 0 (in which case the numerical values are ignored). */ #include "cholmod_internal.h" #include "cholmod_core.h" static cholmod_sparse *band /* returns C, or NULL if failure */ ( /* ---- input or in/out if inplace is TRUE --- */ cholmod_sparse *A, /* ---- input ---- */ SuiteSparse_long k1, /* ignore entries below the k1-st diagonal */ SuiteSparse_long k2, /* ignore entries above the k2-nd diagonal */ int mode, /* >0: numerical, 0: pattern, <0: pattern (no diagonal) */ int inplace, /* if TRUE, then convert A in place */ /* --------------- */ cholmod_common *Common ) { double *Ax, *Cx ; Int packed, nz, j, p, pend, i, ncol, nrow, jlo, jhi, ilo, ihi, sorted, values, diag ; Int *Ap, *Anz, *Ai, *Cp, *Ci ; cholmod_sparse *C ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (A, NULL) ; values = (mode > 0) && (A->xtype != CHOLMOD_PATTERN) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, values ? CHOLMOD_REAL : CHOLMOD_ZOMPLEX, NULL) ; packed = A->packed ; diag = (mode >= 0) ; if (inplace && !packed) { /* cannot operate on an unpacked matrix in place */ ERROR (CHOLMOD_INVALID, "cannot operate on unpacked matrix in-place") ; return (NULL) ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ PRINT1 (("k1 %ld k2 %ld\n", k1, k2)) ; Ap = A->p ; Anz = A->nz ; Ai = A->i ; Ax = A->x ; sorted = A->sorted ; if (A->stype > 0) { /* ignore any entries in strictly lower triangular part of A */ k1 = MAX (k1, 0) ; } if (A->stype < 0) { /* ignore any entries in strictly upper triangular part of A */ k2 = MIN (k2, 0) ; } ncol = A->ncol ; nrow = A->nrow ; /* ensure k1 and k2 are in the range -nrow to +ncol to * avoid possible integer overflow if k1 and k2 are huge */ k1 = MAX (-nrow, k1) ; k1 = MIN (k1, ncol) ; k2 = MAX (-nrow, k2) ; k2 = MIN (k2, ncol) ; /* consider columns jlo to jhi. columns outside this range are empty */ jlo = MAX (k1, 0) ; jhi = MIN (k2+nrow, ncol) ; if (k1 > k2) { /* nothing to do */ jlo = ncol ; jhi = ncol ; } /* ---------------------------------------------------------------------- */ /* allocate C, or operate on A in place */ /* ---------------------------------------------------------------------- */ if (inplace) { /* convert A in place */ C = A ; } else { /* count the number of entries in the result C */ nz = 0 ; if (sorted) { for (j = jlo ; j < jhi ; j++) { ilo = j-k2 ; ihi = j-k1 ; p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; if (i > ihi) { break ; } if (i >= ilo && (diag || i != j)) { nz++ ; } } } } else { for (j = jlo ; j < jhi ; j++) { ilo = j-k2 ; ihi = j-k1 ; p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; if (i >= ilo && i <= ihi && (diag || i != j)) { nz++ ; } } } } /* allocate C; A will not be modified. C is sorted if A is sorted */ C = CHOLMOD(allocate_sparse) (A->nrow, ncol, nz, sorted, TRUE, A->stype, values ? A->xtype : CHOLMOD_PATTERN, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory */ } } Cp = C->p ; Ci = C->i ; Cx = C->x ; /* ---------------------------------------------------------------------- */ /* construct C */ /* ---------------------------------------------------------------------- */ /* columns 0 to jlo-1 are empty */ for (j = 0 ; j < jlo ; j++) { Cp [j] = 0 ; } nz = 0 ; if (sorted) { if (values) { /* pattern and values */ ASSERT (diag) ; for (j = jlo ; j < jhi ; j++) { ilo = j-k2 ; ihi = j-k1 ; p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; Cp [j] = nz ; for ( ; p < pend ; p++) { i = Ai [p] ; if (i > ihi) { break ; } if (i >= ilo) { Ci [nz] = i ; Cx [nz] = Ax [p] ; nz++ ; } } } } else { /* pattern only, perhaps with no diagonal */ for (j = jlo ; j < jhi ; j++) { ilo = j-k2 ; ihi = j-k1 ; p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; Cp [j] = nz ; for ( ; p < pend ; p++) { i = Ai [p] ; if (i > ihi) { break ; } if (i >= ilo && (diag || i != j)) { Ci [nz++] = i ; } } } } } else { if (values) { /* pattern and values */ ASSERT (diag) ; for (j = jlo ; j < jhi ; j++) { ilo = j-k2 ; ihi = j-k1 ; p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; Cp [j] = nz ; for ( ; p < pend ; p++) { i = Ai [p] ; if (i >= ilo && i <= ihi) { Ci [nz] = i ; Cx [nz] = Ax [p] ; nz++ ; } } } } else { /* pattern only, perhaps with no diagonal */ for (j = jlo ; j < jhi ; j++) { ilo = j-k2 ; ihi = j-k1 ; p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; Cp [j] = nz ; for ( ; p < pend ; p++) { i = Ai [p] ; if (i >= ilo && i <= ihi && (diag || i != j)) { Ci [nz++] = i ; } } } } } /* columns jhi to ncol-1 are empty */ for (j = jhi ; j <= ncol ; j++) { Cp [j] = nz ; } /* ---------------------------------------------------------------------- */ /* reduce A in size if done in place */ /* ---------------------------------------------------------------------- */ if (inplace) { /* free the unused parts of A, and reduce A->i and A->x in size */ ASSERT (MAX (1,nz) <= A->nzmax) ; CHOLMOD(reallocate_sparse) (nz, A, Common) ; ASSERT (Common->status >= CHOLMOD_OK) ; } /* ---------------------------------------------------------------------- */ /* return the result C */ /* ---------------------------------------------------------------------- */ DEBUG (i = CHOLMOD(dump_sparse) (C, "band", Common)) ; ASSERT (IMPLIES (mode < 0, i == 0)) ; return (C) ; } /* ========================================================================== */ /* === cholmod_band ========================================================= */ /* ========================================================================== */ cholmod_sparse *CHOLMOD(band) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to extract band matrix from */ SuiteSparse_long k1, /* ignore entries below the k1-st diagonal */ SuiteSparse_long k2, /* ignore entries above the k2-nd diagonal */ int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) */ /* --------------- */ cholmod_common *Common ) { return (band (A, k1, k2, mode, FALSE, Common)) ; } /* ========================================================================== */ /* === cholmod_band_inplace ================================================= */ /* ========================================================================== */ int CHOLMOD(band_inplace) ( /* ---- input ---- */ SuiteSparse_long k1, /* ignore entries below the k1-st diagonal */ SuiteSparse_long k2, /* ignore entries above the k2-nd diagonal */ int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) */ /* ---- in/out --- */ cholmod_sparse *A, /* matrix from which entries not in band are removed */ /* --------------- */ cholmod_common *Common ) { return (band (A, k1, k2, mode, TRUE, Common) != NULL) ; } �����������������Matrix/src/CHOLMOD/Core/cholmod_dense.c�������������������������������������������������������������0000644�0001762�0000144�00000047223�13652535054�017251� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Core/cholmod_dense =================================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Core Module. Copyright (C) 2005-2013, * Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* Core utility routines for the cholmod_dense object: * * The solve routines and some of the MatrixOps and Modify routines use dense * matrices as inputs. These are held in column-major order. With a leading * dimension of d, the entry in row i and column j is held in x [i+j*d]. * * Primary routines: * ----------------- * cholmod_allocate_dense allocate a dense matrix * cholmod_free_dense free a dense matrix * * Secondary routines: * ------------------- * cholmod_zeros allocate a dense matrix of all zeros * cholmod_ones allocate a dense matrix of all ones * cholmod_eye allocate a dense identity matrix * cholmod_sparse_to_dense create a dense matrix copy of a sparse matrix * cholmod_dense_to_sparse create a sparse matrix copy of a dense matrix * cholmod_copy_dense create a copy of a dense matrix * cholmod_copy_dense2 copy a dense matrix (pre-allocated) * * All routines in this file can handle the real, complex, and zomplex cases. * Pattern-only dense matrices are not supported. cholmod_sparse_to_dense can * take a pattern-only input sparse matrix, however, and cholmod_dense_to_sparse * can generate a pattern-only output sparse matrix. */ #include "cholmod_internal.h" #include "cholmod_core.h" /* ========================================================================== */ /* === TEMPLATE ============================================================= */ /* ========================================================================== */ #define PATTERN #include "t_cholmod_dense.c" #define REAL #include "t_cholmod_dense.c" #define COMPLEX #include "t_cholmod_dense.c" #define ZOMPLEX #include "t_cholmod_dense.c" /* ========================================================================== */ /* === cholmod_allocate_dense =============================================== */ /* ========================================================================== */ /* Allocate a dense matrix with leading dimension d. The space is not * initialized. */ cholmod_dense *CHOLMOD(allocate_dense) ( /* ---- input ---- */ size_t nrow, /* # of rows of matrix */ size_t ncol, /* # of columns of matrix */ size_t d, /* leading dimension */ int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ /* --------------- */ cholmod_common *Common ) { cholmod_dense *X ; size_t nzmax, nzmax0 ; int ok = TRUE ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; if (d < nrow) { ERROR (CHOLMOD_INVALID, "leading dimension invalid") ; return (NULL) ; } if (xtype < CHOLMOD_REAL || xtype > CHOLMOD_ZOMPLEX) { ERROR (CHOLMOD_INVALID, "xtype invalid") ; return (NULL) ; } /* ensure the dimensions do not cause integer overflow */ (void) CHOLMOD(add_size_t) (ncol, 2, &ok) ; /* nzmax = MAX (1, d*ncol) ; */ nzmax = CHOLMOD(mult_size_t) (d, ncol, &ok) ; nzmax = MAX (1, nzmax) ; if (!ok || nrow > Int_max || ncol > Int_max || nzmax > Int_max) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (NULL) ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate header */ /* ---------------------------------------------------------------------- */ X = CHOLMOD(malloc) (sizeof (cholmod_dense), 1, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory */ } PRINT1 (("cholmod_allocate_dense %d-by-%d nzmax %d xtype %d\n", nrow, ncol, nzmax, xtype)) ; X->nrow = nrow ; X->ncol = ncol ; X->nzmax = nzmax ; X->xtype = xtype ; X->dtype = DTYPE ; X->x = NULL ; X->z = NULL ; X->d = d ; /* ---------------------------------------------------------------------- */ /* allocate the matrix itself */ /* ---------------------------------------------------------------------- */ nzmax0 = 0 ; CHOLMOD(realloc_multiple) (nzmax, 0, xtype, NULL, NULL, &(X->x), &(X->z), &nzmax0, Common) ; if (Common->status < CHOLMOD_OK) { CHOLMOD(free_dense) (&X, Common) ; return (NULL) ; /* out of memory */ } return (X) ; } /* ========================================================================== */ /* === cholmod_zeros ======================================================== */ /* ========================================================================== */ /* Allocate a dense matrix and set it to zero */ cholmod_dense *CHOLMOD(zeros) ( /* ---- input ---- */ size_t nrow, /* # of rows of matrix */ size_t ncol, /* # of columns of matrix */ int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ /* --------------- */ cholmod_common *Common ) { cholmod_dense *X ; double *Xx, *Xz ; Int i, nz ; /* ---------------------------------------------------------------------- */ /* allocate a dense matrix and set it to zero */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; X = CHOLMOD(allocate_dense) (nrow, ncol, nrow, xtype, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* NULL Common, out of memory, or inputs invalid */ } Xx = X->x ; Xz = X->z ; nz = MAX (1, X->nzmax) ; switch (xtype) { case CHOLMOD_REAL: for (i = 0 ; i < nz ; i++) { Xx [i] = 0 ; } break ; case CHOLMOD_COMPLEX: for (i = 0 ; i < 2*nz ; i++) { Xx [i] = 0 ; } break ; case CHOLMOD_ZOMPLEX: for (i = 0 ; i < nz ; i++) { Xx [i] = 0 ; } for (i = 0 ; i < nz ; i++) { Xz [i] = 0 ; } break ; } return (X) ; } /* ========================================================================== */ /* === cholmod_ones ========================================================= */ /* ========================================================================== */ /* Allocate a dense matrix and set it to zero */ cholmod_dense *CHOLMOD(ones) ( /* ---- input ---- */ size_t nrow, /* # of rows of matrix */ size_t ncol, /* # of columns of matrix */ int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ /* --------------- */ cholmod_common *Common ) { cholmod_dense *X ; double *Xx, *Xz ; Int i, nz ; /* ---------------------------------------------------------------------- */ /* allocate a dense matrix and set it to all ones */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; X = CHOLMOD(allocate_dense) (nrow, ncol, nrow, xtype, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* NULL Common, out of memory, or inputs invalid */ } Xx = X->x ; Xz = X->z ; nz = MAX (1, X->nzmax) ; switch (xtype) { case CHOLMOD_REAL: for (i = 0 ; i < nz ; i++) { Xx [i] = 1 ; } break ; case CHOLMOD_COMPLEX: for (i = 0 ; i < nz ; i++) { Xx [2*i ] = 1 ; Xx [2*i+1] = 0 ; } break ; case CHOLMOD_ZOMPLEX: for (i = 0 ; i < nz ; i++) { Xx [i] = 1 ; } for (i = 0 ; i < nz ; i++) { Xz [i] = 0 ; } break ; } return (X) ; } /* ========================================================================== */ /* === cholmod_eye ========================================================== */ /* ========================================================================== */ /* Allocate a dense matrix and set it to the identity matrix */ cholmod_dense *CHOLMOD(eye) ( /* ---- input ---- */ size_t nrow, /* # of rows of matrix */ size_t ncol, /* # of columns of matrix */ int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ /* --------------- */ cholmod_common *Common ) { cholmod_dense *X ; double *Xx, *Xz ; Int i, n, nz ; /* ---------------------------------------------------------------------- */ /* allocate a dense matrix and set it to the identity matrix */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; X = CHOLMOD(zeros) (nrow, ncol, xtype, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* NULL Common, out of memory, or inputs invalid */ } nz = MAX (1, nrow*ncol) ; Xx = X->x ; Xz = X->z ; n = MIN (nrow, ncol) ; switch (xtype) { case CHOLMOD_REAL: case CHOLMOD_ZOMPLEX: for (i = 0 ; i < n ; i++) { Xx [i + i*nrow] = 1 ; } break ; case CHOLMOD_COMPLEX: for (i = 0 ; i < n ; i++) { Xx [2 * (i + i*nrow)] = 1 ; } break ; } return (X) ; } /* ========================================================================== */ /* === cholmod_free_dense =================================================== */ /* ========================================================================== */ /* free a dense matrix * * workspace: none */ int CHOLMOD(free_dense) ( /* ---- in/out --- */ cholmod_dense **XHandle, /* dense matrix to deallocate, NULL on output */ /* --------------- */ cholmod_common *Common ) { cholmod_dense *X ; RETURN_IF_NULL_COMMON (FALSE) ; if (XHandle == NULL) { /* nothing to do */ return (TRUE) ; } X = *XHandle ; if (X == NULL) { /* nothing to do */ return (TRUE) ; } switch (X->xtype) { case CHOLMOD_REAL: X->x = CHOLMOD(free) (X->nzmax, sizeof (double), X->x, Common) ; break ; case CHOLMOD_COMPLEX: X->x = CHOLMOD(free) (X->nzmax, 2*sizeof (double), X->x, Common) ; break ; case CHOLMOD_ZOMPLEX: X->x = CHOLMOD(free) (X->nzmax, sizeof (double), X->x, Common) ; X->z = CHOLMOD(free) (X->nzmax, sizeof (double), X->z, Common) ; break ; } *XHandle = CHOLMOD(free) (1, sizeof (cholmod_dense), (*XHandle), Common) ; return (TRUE) ; } /* ========================================================================== */ /* === cholmod_ensure_dense ================================================= */ /* ========================================================================== */ /* Ensure that the input matrix has a certain size and type. If not, free * the existing matrix and reallocate one of the right size and type. * Returns a pointer to the cholmod_dense matrix, possibly reallocated. * Also modifies the input matrix handle, XHandle, if necessary. */ cholmod_dense *CHOLMOD(ensure_dense) ( /* ---- input/output ---- */ cholmod_dense **XHandle, /* matrix handle to check */ /* ---- input ---- */ size_t nrow, /* # of rows of matrix */ size_t ncol, /* # of columns of matrix */ size_t d, /* leading dimension */ int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ /* --------------- */ cholmod_common *Common ) { cholmod_dense *X ; RETURN_IF_NULL_COMMON (NULL) ; if (XHandle == NULL) { ERROR (CHOLMOD_INVALID, "matrix invalid") ; return (NULL) ; } X = *XHandle ; if (X == NULL || X->nrow != nrow || X->ncol != ncol || X->d != d || X->xtype != xtype) { /* Matrix X is not allocated, or has the wrong size. Free it and * reallocate it in the right size and shape. If an error occurs * (out of memory or inputs nrow, etc invalid), then the error is * set in cholmod_allocate_dense and X is returned as NULL. */ CHOLMOD(free_dense) (XHandle, Common) ; X = CHOLMOD(allocate_dense) (nrow, ncol, d, xtype, Common) ; *XHandle = X ; } return (X) ; } /* ========================================================================== */ /* === cholmod_sparse_to_dense ============================================== */ /* ========================================================================== */ /* Convert a sparse matrix to a dense matrix. * The output dense matrix has the same xtype as the input sparse matrix, * except that a pattern-only sparse matrix A is converted into a real dense * matrix X, with 1's and 0's. All xtypes are supported. */ cholmod_dense *CHOLMOD(sparse_to_dense) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to copy */ /* --------------- */ cholmod_common *Common ) { cholmod_dense *X = NULL ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (A, NULL) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, NULL) ; if (A->stype && A->nrow != A->ncol) { ERROR (CHOLMOD_INVALID, "matrix invalid") ; return (NULL) ; } Common->status = CHOLMOD_OK ; ASSERT (CHOLMOD(dump_sparse) (A, "A", Common) >= 0) ; /* ---------------------------------------------------------------------- */ /* convert the matrix, using template routine */ /* ---------------------------------------------------------------------- */ switch (A->xtype) { case CHOLMOD_PATTERN: X = p_cholmod_sparse_to_dense (A, Common) ; break ; case CHOLMOD_REAL: X = r_cholmod_sparse_to_dense (A, Common) ; break ; case CHOLMOD_COMPLEX: X = c_cholmod_sparse_to_dense (A, Common) ; break ; case CHOLMOD_ZOMPLEX: X = z_cholmod_sparse_to_dense (A, Common) ; break ; } return (X) ; } /* ========================================================================== */ /* === cholmod_dense_to_sparse ============================================== */ /* ========================================================================== */ /* Convert a dense matrix to a sparse matrix, similar to the MATLAB statements: * * C = sparse (X) values = TRUE * C = spones (sparse (X)) values = FALSE * * except that X must be double (it can be of many different types in MATLAB) * * The resulting sparse matrix C has the same numeric xtype as the input dense * matrix X, unless "values" is FALSE (in which case C is real, where C(i,j)=1 * if (i,j) is an entry in X. */ cholmod_sparse *CHOLMOD(dense_to_sparse) ( /* ---- input ---- */ cholmod_dense *X, /* matrix to copy */ int values, /* TRUE if values to be copied, FALSE otherwise */ /* --------------- */ cholmod_common *Common ) { cholmod_sparse *C = NULL ; DEBUG (CHOLMOD(dump_dense) (X, "X", Common)) ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (X, NULL) ; RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, NULL) ; if (X->d < X->nrow) { ERROR (CHOLMOD_INVALID, "matrix invalid") ; return (NULL) ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* convert the matrix, using template routine */ /* ---------------------------------------------------------------------- */ switch (X->xtype) { case CHOLMOD_REAL: C = r_cholmod_dense_to_sparse (X, values, Common) ; break ; case CHOLMOD_COMPLEX: C = c_cholmod_dense_to_sparse (X, values, Common) ; break ; case CHOLMOD_ZOMPLEX: C = z_cholmod_dense_to_sparse (X, values, Common) ; break ; } return (C) ; } /* ========================================================================== */ /* === cholmod_copy_dense2 ================================================== */ /* ========================================================================== */ /* Y = X, where X and Y are both already allocated. The leading dimensions of * X and Y may differ, but both must be >= the # of rows in X and Y. * Entries in rows nrow to d-1 are not copied from X, since the space might not * be initialized. Y->nzmax is unchanged. X->nzmax is typically * (X->d)*(X->ncol), but a user might modify that condition outside of any * CHOLMOD routine. * * The two dense matrices X and Y must have the same numeric xtype. */ int CHOLMOD(copy_dense2) ( /* ---- input ---- */ cholmod_dense *X, /* matrix to copy */ /* ---- output --- */ cholmod_dense *Y, /* copy of matrix X */ /* --------------- */ cholmod_common *Common ) { /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (X, FALSE) ; RETURN_IF_NULL (Y, FALSE) ; RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; RETURN_IF_XTYPE_INVALID (Y, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; if (X->nrow != Y->nrow || X->ncol != Y->ncol || X->xtype != Y->xtype) { ERROR (CHOLMOD_INVALID, "X and Y must have same dimensions and xtype") ; return (FALSE) ; } if (X->d < X->nrow || Y->d < Y->nrow || (X->d * X->ncol) > X->nzmax || (Y->d * Y->ncol) > Y->nzmax) { ERROR (CHOLMOD_INVALID, "X and/or Y invalid") ; return (FALSE) ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* copy the matrix, using template routine */ /* ---------------------------------------------------------------------- */ switch (X->xtype) { case CHOLMOD_REAL: r_cholmod_copy_dense2 (X, Y) ; break ; case CHOLMOD_COMPLEX: c_cholmod_copy_dense2 (X, Y) ; break ; case CHOLMOD_ZOMPLEX: z_cholmod_copy_dense2 (X, Y) ; break ; } return (TRUE) ; } /* ========================================================================== */ /* === cholmod_copy_dense =================================================== */ /* ========================================================================== */ /* Y = X, copy a dense matrix */ cholmod_dense *CHOLMOD(copy_dense) ( /* ---- input ---- */ cholmod_dense *X, /* matrix to copy */ /* --------------- */ cholmod_common *Common ) { cholmod_dense *Y ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (X, NULL) ; RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, NULL) ; Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate result */ /* ---------------------------------------------------------------------- */ Y = CHOLMOD(allocate_dense) (X->nrow, X->ncol, X->d, X->xtype, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory or X invalid */ } /* ---------------------------------------------------------------------- */ /* Y = X */ /* ---------------------------------------------------------------------- */ /* This cannot fail (X and Y are allocated, and have the same nrow, ncol * d, and xtype) */ CHOLMOD(copy_dense2) (X, Y, Common) ; /* ---------------------------------------------------------------------- */ /* return result */ /* ---------------------------------------------------------------------- */ return (Y) ; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Core/cholmod_copy.c��������������������������������������������������������������0000644�0001762�0000144�00000026754�13652535054�017133� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Core/cholmod_copy ==================================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Core Module. Copyright (C) 2005-2006, * Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* C = A, which allocates C and copies A into C, with possible change of * stype. The diagonal can optionally be removed. The numerical entries * can optionally be copied. This routine differs from cholmod_copy_sparse, * which makes an exact copy of a sparse matrix. * * A can be of any type (packed/unpacked, upper/lower/unsymmetric). C is * packed and can be of any stype (upper/lower/unsymmetric), except that if * A is rectangular C can only be unsymmetric. If the stype of A and C * differ, then the appropriate conversion is made. * * Symmetry of A (A->stype): * <0: lower: assume A is symmetric with just tril(A); the rest of A is ignored * 0 unsym: assume A is unsymmetric; consider all entries in A * >0 upper: assume A is symmetric with just triu(A); the rest of A is ignored * * Symmetry of C (stype parameter): * <0 lower: return just tril(C) * 0 unsym: return all of C * >0 upper: return just triu(C) * * In MATLAB: Using cholmod_copy: * ---------- ---------------------------- * C = A ; A unsymmetric, C unsymmetric * C = tril (A) ; A unsymmetric, C lower * C = triu (A) ; A unsymmetric, C upper * U = triu (A) ; L = tril (U',-1) ; C = L+U ; A upper, C unsymmetric * C = triu (A)' ; A upper, C lower * C = triu (A) ; A upper, C upper * L = tril (A) ; U = triu (L',1) ; C = L+U ; A lower, C unsymmetric * C = tril (A) ; A lower, C lower * C = tril (A)' ; A lower, C upper * * workspace: Iwork (max (nrow,ncol)) * * A can have an xtype of pattern or real. Complex and zomplex cases only * supported when mode <= 0 (in which case the numerical values are ignored). */ #include "cholmod_internal.h" #include "cholmod_core.h" /* ========================================================================== */ /* === copy_sym_to_unsym ==================================================== */ /* ========================================================================== */ /* Construct an unsymmetric copy of a symmetric sparse matrix. This does the * work for as C = cholmod_copy (A, 0, mode, Common) when A is symmetric. * In this case, extra space can be added to C. */ static cholmod_sparse *copy_sym_to_unsym ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to copy */ int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) * -2: pattern only, no diagonal, add 50% + n extra * space to C */ /* --------------- */ cholmod_common *Common ) { double aij ; double *Ax, *Cx ; Int *Ap, *Ai, *Anz, *Cp, *Ci, *Wj, *Iwork ; cholmod_sparse *C ; Int nrow, ncol, nz, packed, j, p, pend, i, pc, up, lo, values, diag, astype, extra ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ nrow = A->nrow ; ncol = A->ncol ; Ap = A->p ; Anz = A->nz ; Ai = A->i ; Ax = A->x ; packed = A->packed ; values = (mode > 0) && (A->xtype != CHOLMOD_PATTERN) ; diag = (mode >= 0) ; astype = SIGN (A->stype) ; up = (astype > 0) ; lo = (astype < 0) ; ASSERT (astype != 0) ; /* ---------------------------------------------------------------------- */ /* create an unsymmetric copy of a symmetric matrix */ /* ---------------------------------------------------------------------- */ Iwork = Common->Iwork ; Wj = Iwork ; /* size ncol (i/i/l) */ /* In MATLAB notation, for converting a symmetric/upper matrix: * U = triu (A) ; * L = tril (U',-1) ; * C = L + U ; * * For converting a symmetric/lower matrix to unsymmetric: * L = tril (A) ; * U = triu (L',1) ; * C = L + U ; */ ASSERT (up || lo) ; PRINT1 (("copy: convert symmetric to unsym\n")) ; /* count the number of entries in each column of C */ for (j = 0 ; j < ncol ; j++) { Wj [j] = 0 ; } for (j = 0 ; j < ncol ; j++) { p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; if (i == j) { /* the diagonal entry A(i,i) will appear just once * (unless it is excluded with mode < 0) */ if (diag) { Wj [j]++ ; } } else if ((up && i < j) || (lo && i > j)) { /* upper case: A(i,j) is in the strictly upper part; * A(j,i) will be added to the strictly lower part of C. * lower case is the opposite. */ Wj [j]++ ; Wj [i]++ ; } } } nz = 0 ; for (j = 0 ; j < ncol ; j++) { nz += Wj [j] ; } extra = (mode == -2) ? (nz/2 + ncol) : 0 ; /* allocate C. C is sorted if and only if A is sorted */ C = CHOLMOD(allocate_sparse) (nrow, ncol, nz + extra, A->sorted, TRUE, 0, values ? A->xtype : CHOLMOD_PATTERN, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; } Cp = C->p ; Ci = C->i ; Cx = C->x ; /* construct the column pointers for C */ p = 0 ; for (j = 0 ; j < ncol ; j++) { Cp [j] = p ; p += Wj [j] ; } Cp [ncol] = p ; for (j = 0 ; j < ncol ; j++) { Wj [j] = Cp [j] ; } /* construct C */ if (values) { /* pattern and values */ ASSERT (diag) ; for (j = 0 ; j < ncol ; j++) { p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; aij = Ax [p] ; if (i == j) { /* add diagonal entry A(i,i) to column i */ pc = Wj [i]++ ; Ci [pc] = i ; Cx [pc] = aij ; } else if ((up && i < j) || (lo && i > j)) { /* add A(i,j) to column j */ pc = Wj [j]++ ; Ci [pc] = i ; Cx [pc] = aij ; /* add A(j,i) to column i */ pc = Wj [i]++ ; Ci [pc] = j ; Cx [pc] = aij ; } } } } else { /* pattern only, possibly excluding the diagonal */ for (j = 0 ; j < ncol ; j++) { p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; if (i == j) { /* add diagonal entry A(i,i) to column i * (unless it is excluded with mode < 0) */ if (diag) { Ci [Wj [i]++] = i ; } } else if ((up && i < j) || (lo && i > j)) { /* add A(i,j) to column j */ Ci [Wj [j]++] = i ; /* add A(j,i) to column i */ Ci [Wj [i]++] = j ; } } } } /* ---------------------------------------------------------------------- */ /* return the result */ /* ---------------------------------------------------------------------- */ DEBUG (i = CHOLMOD(dump_sparse) (C, "copy_sym_to_unsym", Common)) ; PRINT1 (("mode %d nnzdiag "ID"\n", mode, i)) ; ASSERT (IMPLIES (mode < 0, i == 0)) ; return (C) ; } /* ========================================================================== */ /* === cholmod_copy ========================================================= */ /* ========================================================================== */ cholmod_sparse *CHOLMOD(copy) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to copy */ int stype, /* requested stype of C */ int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) */ /* --------------- */ cholmod_common *Common ) { cholmod_sparse *C ; Int nrow, ncol, up, lo, values, diag, astype ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (A, NULL) ; values = (mode > 0) && (A->xtype != CHOLMOD_PATTERN) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, values ? CHOLMOD_REAL : CHOLMOD_ZOMPLEX, NULL) ; nrow = A->nrow ; ncol = A->ncol ; if ((stype || A->stype) && nrow != ncol) { /* inputs invalid */ ERROR (CHOLMOD_INVALID, "matrix invalid") ; return (NULL) ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ CHOLMOD(allocate_work) (0, MAX (nrow,ncol), 0, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ return (NULL) ; } /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ diag = (mode >= 0) ; astype = SIGN (A->stype) ; stype = SIGN (stype) ; up = (astype > 0) ; lo = (astype < 0) ; /* ---------------------------------------------------------------------- */ /* copy the matrix */ /* ---------------------------------------------------------------------- */ if (astype == stype) { /* ------------------------------------------------------------------ */ /* symmetry of A and C are the same */ /* ------------------------------------------------------------------ */ /* copy A into C, keeping the same symmetry. If A is symmetric * entries in the ignored part of A are not copied into C */ C = CHOLMOD(band) (A, -nrow, ncol, mode, Common) ; } else if (!astype) { /* ------------------------------------------------------------------ */ /* convert unsymmetric matrix A into a symmetric matrix C */ /* ------------------------------------------------------------------ */ if (stype > 0) { /* C = triu (A) */ C = CHOLMOD(band) (A, 0, ncol, mode, Common) ; } else { /* C = tril (A) */ C = CHOLMOD(band) (A, -nrow, 0, mode, Common) ; } if (Common->status < CHOLMOD_OK) { /* out of memory */ return (NULL) ; } C->stype = stype ; } else if (astype == -stype) { /* ------------------------------------------------------------------ */ /* transpose a symmetric matrix */ /* ------------------------------------------------------------------ */ /* converting upper to lower or lower to upper */ /* workspace: Iwork (nrow) */ C = CHOLMOD(transpose) (A, values, Common) ; if (!diag) { /* remove diagonal, if requested */ CHOLMOD(band_inplace) (-nrow, ncol, -1, C, Common) ; } } else { /* ------------------------------------------------------------------ */ /* create an unsymmetric copy of a symmetric matrix */ /* ------------------------------------------------------------------ */ C = copy_sym_to_unsym (A, mode, Common) ; } /* ---------------------------------------------------------------------- */ /* return if error */ /* ---------------------------------------------------------------------- */ if (Common->status < CHOLMOD_OK) { /* out of memory */ return (NULL) ; } /* ---------------------------------------------------------------------- */ /* return the result */ /* ---------------------------------------------------------------------- */ DEBUG (diag = CHOLMOD(dump_sparse) (C, "copy", Common)) ; PRINT1 (("mode %d nnzdiag "ID"\n", mode, diag)) ; ASSERT (IMPLIES (mode < 0, diag == 0)) ; return (C) ; } ��������������������Matrix/src/CHOLMOD/Include/�������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14547723665�015000� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Include/cholmod_core.h�����������������������������������������������������������0000644�0001762�0000144�00000310752�14406303520�017570� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Include/cholmod_core.h =============================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Include/cholmod_core.h. * Copyright (C) 2005-2019, Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* CHOLMOD Core module: basic CHOLMOD objects and routines. * Required by all CHOLMOD modules. Requires no other module or package. * * The CHOLMOD modules are: * * Core basic data structures and definitions * Check check/print the 5 CHOLMOD objects, & 3 types of integer vectors * Cholesky sparse Cholesky factorization * Modify sparse Cholesky update/downdate/row-add/row-delete * MatrixOps sparse matrix functions (add, multiply, norm, ...) * Supernodal supernodal sparse Cholesky factorization * Partition graph-partitioning based orderings * * The CHOLMOD objects: * -------------------- * * cholmod_common parameters, statistics, and workspace * cholmod_sparse a sparse matrix in compressed column form * cholmod_factor an LL' or LDL' factorization * cholmod_dense a dense matrix * cholmod_triplet a sparse matrix in "triplet" form * * The Core module described here defines the CHOLMOD data structures, and * basic operations on them. To create and solve a sparse linear system Ax=b, * the user must create A and b, populate them with values, and then pass them * to the routines in the CHOLMOD Cholesky module. There are two primary * methods for creating A: (1) allocate space for a column-oriented sparse * matrix and fill it with pattern and values, or (2) create a triplet form * matrix and convert it to a sparse matrix. The latter option is simpler. * * The matrices b and x are typically dense matrices, but can also be sparse. * You can allocate and free them as dense matrices with the * cholmod_allocate_dense and cholmod_free_dense routines. * * The cholmod_factor object contains the symbolic and numeric LL' or LDL' * factorization of sparse symmetric matrix. The matrix must be positive * definite for an LL' factorization. It need only be symmetric and have well- * conditioned leading submatrices for it to have an LDL' factorization * (CHOLMOD does not pivot for numerical stability). It is typically created * with the cholmod_factorize routine in the Cholesky module, but can also * be initialized to L=D=I in the Core module and then modified by the Modify * module. It must be freed with cholmod_free_factor, defined below. * * The Core routines for each object are described below. Each list is split * into two parts: the primary routines and secondary routines. * * ============================================================================ * === cholmod_common ========================================================= * ============================================================================ * * The Common object contains control parameters, statistics, and * You must call cholmod_start before calling any other CHOLMOD routine, and * must call cholmod_finish as your last call to CHOLMOD, with two exceptions: * you may call cholmod_print_common and cholmod_check_common in the Check * module after calling cholmod_finish. * * cholmod_start first call to CHOLMOD * cholmod_finish last call to CHOLMOD * ----------------------------- * cholmod_defaults restore default parameters * cholmod_maxrank maximum rank for update/downdate * cholmod_allocate_work allocate workspace in Common * cholmod_free_work free workspace in Common * cholmod_clear_flag clear Flag workspace in Common * cholmod_error called when CHOLMOD encounters an error * cholmod_dbound for internal use in CHOLMOD only * cholmod_hypot compute sqrt (x*x + y*y) accurately * cholmod_divcomplex complex division, c = a/b * * ============================================================================ * === cholmod_sparse ========================================================= * ============================================================================ * * A sparse matrix is held in compressed column form. In the basic type * ("packed", which corresponds to a MATLAB sparse matrix), an n-by-n matrix * with nz entries is held in three arrays: p of size n+1, i of size nz, and x * of size nz. Row indices of column j are held in i [p [j] ... p [j+1]-1] and * in the same locations in x. There may be no duplicate entries in a column. * Row indices in each column may be sorted or unsorted (CHOLMOD keeps track). * A->stype determines the storage mode: 0 if both upper/lower parts are stored, * -1 if A is symmetric and just tril(A) is stored, +1 if symmetric and triu(A) * is stored. * * cholmod_allocate_sparse allocate a sparse matrix * cholmod_free_sparse free a sparse matrix * ----------------------------- * cholmod_reallocate_sparse change the size (# entries) of sparse matrix * cholmod_nnz number of nonzeros in a sparse matrix * cholmod_speye sparse identity matrix * cholmod_spzeros sparse zero matrix * cholmod_transpose transpose a sparse matrix * cholmod_ptranspose transpose/permute a sparse matrix * cholmod_transpose_unsym transpose/permute an unsymmetric sparse matrix * cholmod_transpose_sym transpose/permute a symmetric sparse matrix * cholmod_sort sort row indices in each column of sparse matrix * cholmod_band C = tril (triu (A,k1), k2) * cholmod_band_inplace A = tril (triu (A,k1), k2) * cholmod_aat C = A*A' * cholmod_copy_sparse C = A, create an exact copy of a sparse matrix * cholmod_copy C = A, with possible change of stype * cholmod_add C = alpha*A + beta*B * cholmod_sparse_xtype change the xtype of a sparse matrix * * ============================================================================ * === cholmod_factor ========================================================= * ============================================================================ * * The data structure for an LL' or LDL' factorization is too complex to * describe in one sentence. This object can hold the symbolic analysis alone, * or in combination with a "simplicial" (similar to a sparse matrix) or * "supernodal" form of the numerical factorization. Only the routine to free * a factor is primary, since a factor object is created by the factorization * routine (cholmod_factorize). It must be freed with cholmod_free_factor. * * cholmod_free_factor free a factor * ----------------------------- * cholmod_allocate_factor allocate a factor (LL' or LDL') * cholmod_reallocate_factor change the # entries in a factor * cholmod_change_factor change the type of factor (e.g., LDL' to LL') * cholmod_pack_factor pack the columns of a factor * cholmod_reallocate_column resize a single column of a factor * cholmod_factor_to_sparse create a sparse matrix copy of a factor * cholmod_copy_factor create a copy of a factor * cholmod_factor_xtype change the xtype of a factor * * Note that there is no cholmod_sparse_to_factor routine to create a factor * as a copy of a sparse matrix. It could be done, after a fashion, but a * lower triangular sparse matrix would not necessarily have a chordal graph, * which would break the many CHOLMOD routines that rely on this property. * * ============================================================================ * === cholmod_dense ========================================================== * ============================================================================ * * The solve routines and some of the MatrixOps and Modify routines use dense * matrices as inputs. These are held in column-major order. With a leading * dimension of d, the entry in row i and column j is held in x [i+j*d]. * * cholmod_allocate_dense allocate a dense matrix * cholmod_free_dense free a dense matrix * ----------------------------- * cholmod_zeros allocate a dense matrix of all zeros * cholmod_ones allocate a dense matrix of all ones * cholmod_eye allocate a dense identity matrix * cholmod_sparse_to_dense create a dense matrix copy of a sparse matrix * cholmod_dense_to_sparse create a sparse matrix copy of a dense matrix * cholmod_copy_dense create a copy of a dense matrix * cholmod_copy_dense2 copy a dense matrix (pre-allocated) * cholmod_dense_xtype change the xtype of a dense matrix * cholmod_ensure_dense ensure a dense matrix has a given size and type * * ============================================================================ * === cholmod_triplet ======================================================== * ============================================================================ * * A sparse matrix held in triplet form is the simplest one for a user to * create. It consists of a list of nz entries in arbitrary order, held in * three arrays: i, j, and x, each of length nk. The kth entry is in row i[k], * column j[k], with value x[k]. There may be duplicate values; if A(i,j) * appears more than once, its value is the sum of the entries with those row * and column indices. * * cholmod_allocate_triplet allocate a triplet matrix * cholmod_triplet_to_sparse create a sparse matrix copy of a triplet matrix * cholmod_free_triplet free a triplet matrix * ----------------------------- * cholmod_reallocate_triplet change the # of entries in a triplet matrix * cholmod_sparse_to_triplet create a triplet matrix copy of a sparse matrix * cholmod_copy_triplet create a copy of a triplet matrix * cholmod_triplet_xtype change the xtype of a triplet matrix * * ============================================================================ * === memory management ====================================================== * ============================================================================ * * cholmod_malloc malloc wrapper * cholmod_calloc calloc wrapper * cholmod_free free wrapper * cholmod_realloc realloc wrapper * cholmod_realloc_multiple realloc wrapper for multiple objects * * ============================================================================ * === Core CHOLMOD prototypes ================================================ * ============================================================================ * * All CHOLMOD routines (in all modules) use the following protocol for return * values, with one exception: * * int TRUE (1) if successful, or FALSE (0) otherwise. * (exception: cholmod_divcomplex) * SuiteSparse_long a value >= 0 if successful, or -1 otherwise. * double a value >= 0 if successful, or -1 otherwise. * size_t a value > 0 if successful, or 0 otherwise. * void * a non-NULL pointer to newly allocated memory if * successful, or NULL otherwise. * cholmod_sparse * a non-NULL pointer to a newly allocated matrix * if successful, or NULL otherwise. * cholmod_factor * a non-NULL pointer to a newly allocated factor * if successful, or NULL otherwise. * cholmod_triplet * a non-NULL pointer to a newly allocated triplet * matrix if successful, or NULL otherwise. * cholmod_dense * a non-NULL pointer to a newly allocated triplet * matrix if successful, or NULL otherwise. * * The last parameter to all routines is always a pointer to the CHOLMOD * Common object. * * TRUE and FALSE are not defined here, since they may conflict with the user * program. A routine that described here returning TRUE or FALSE returns 1 * or 0, respectively. Any TRUE/FALSE parameter is true if nonzero, false if * zero. */ #ifndef CHOLMOD_CORE_H #define CHOLMOD_CORE_H /* ========================================================================== */ /* === CHOLMOD version ====================================================== */ /* ========================================================================== */ /* All versions of CHOLMOD will include the following definitions. * As an example, to test if the version you are using is 1.3 or later: * * if (CHOLMOD_VERSION >= CHOLMOD_VER_CODE (1,3)) ... * * This also works during compile-time: * * #if CHOLMOD_VERSION >= CHOLMOD_VER_CODE (1,3) * printf ("This is version 1.3 or later\n") ; * #else * printf ("This is version is earlier than 1.3\n") ; * #endif */ #define CHOLMOD_HAS_VERSION_FUNCTION #define CHOLMOD_DATE "Oct 22, 2019" #define CHOLMOD_VER_CODE(main,sub) ((main) * 1000 + (sub)) #define CHOLMOD_MAIN_VERSION 3 #define CHOLMOD_SUB_VERSION 0 #define CHOLMOD_SUBSUB_VERSION 14 #define CHOLMOD_VERSION \ CHOLMOD_VER_CODE(CHOLMOD_MAIN_VERSION,CHOLMOD_SUB_VERSION) /* ========================================================================== */ /* === non-CHOLMOD include files ============================================ */ /* ========================================================================== */ /* This is the only non-CHOLMOD include file imposed on the user program. * It required for size_t definition used here. CHOLMOD itself includes other * ANSI C89 standard #include files, but does not expose them to the user. * * CHOLMOD assumes that your C compiler is ANSI C89 compliant. It does not make * use of ANSI C99 features. */ #include #include /* ========================================================================== */ /* === CUDA BLAS for the GPU ================================================ */ /* ========================================================================== */ /* The number of OMP threads should typically be set to the number of cores */ /* per socket inthe machine being used. This maximizes memory performance. */ #ifndef CHOLMOD_OMP_NUM_THREADS #define CHOLMOD_OMP_NUM_THREADS 4 #endif /* Define buffering parameters for GPU processing */ #ifndef SUITESPARSE_GPU_EXTERN_ON #ifdef GPU_BLAS #include #endif #endif #define CHOLMOD_DEVICE_SUPERNODE_BUFFERS 6 #define CHOLMOD_HOST_SUPERNODE_BUFFERS 8 #define CHOLMOD_DEVICE_STREAMS 2 /* ========================================================================== */ /* === CHOLMOD objects ====================================================== */ /* ========================================================================== */ /* Each CHOLMOD object has its own type code. */ #define CHOLMOD_COMMON 0 #define CHOLMOD_SPARSE 1 #define CHOLMOD_FACTOR 2 #define CHOLMOD_DENSE 3 #define CHOLMOD_TRIPLET 4 /* ========================================================================== */ /* === CHOLMOD Common ======================================================= */ /* ========================================================================== */ /* itype defines the types of integer used: */ #define CHOLMOD_INT 0 /* all integer arrays are int */ #define CHOLMOD_INTLONG 1 /* most are int, some are SuiteSparse_long */ #define CHOLMOD_LONG 2 /* all integer arrays are SuiteSparse_long */ /* The itype of all parameters for all CHOLMOD routines must match. * FUTURE WORK: CHOLMOD_INTLONG is not yet supported. */ /* dtype defines what the numerical type is (double or float): */ #define CHOLMOD_DOUBLE 0 /* all numerical values are double */ #define CHOLMOD_SINGLE 1 /* all numerical values are float */ /* The dtype of all parameters for all CHOLMOD routines must match. * * Scalar floating-point values are always passed as double arrays of size 2 * (for the real and imaginary parts). They are typecast to float as needed. * FUTURE WORK: the float case is not supported yet. */ /* xtype defines the kind of numerical values used: */ #define CHOLMOD_PATTERN 0 /* pattern only, no numerical values */ #define CHOLMOD_REAL 1 /* a real matrix */ #define CHOLMOD_COMPLEX 2 /* a complex matrix (ANSI C99 compatible) */ #define CHOLMOD_ZOMPLEX 3 /* a complex matrix (MATLAB compatible) */ /* The xtype of all parameters for all CHOLMOD routines must match. * * CHOLMOD_PATTERN: x and z are ignored. * CHOLMOD_DOUBLE: x is non-null of size nzmax, z is ignored. * CHOLMOD_COMPLEX: x is non-null of size 2*nzmax doubles, z is ignored. * CHOLMOD_ZOMPLEX: x and z are non-null of size nzmax * * In the real case, z is ignored. The kth entry in the matrix is x [k]. * There are two methods for the complex case. In the ANSI C99-compatible * CHOLMOD_COMPLEX case, the real and imaginary parts of the kth entry * are in x [2*k] and x [2*k+1], respectively. z is ignored. In the * MATLAB-compatible CHOLMOD_ZOMPLEX case, the real and imaginary * parts of the kth entry are in x [k] and z [k]. * * Scalar floating-point values are always passed as double arrays of size 2 * (real and imaginary parts). The imaginary part of a scalar is ignored if * the routine operates on a real matrix. * * These Modules support complex and zomplex matrices, with a few exceptions: * * Check all routines * Cholesky all routines * Core all except cholmod_aat, add, band, copy * Demo all routines * Partition all routines * Supernodal all routines support any real, complex, or zomplex input. * There will never be a supernodal zomplex L; a complex * supernodal L is created if A is zomplex. * Tcov all routines * Valgrind all routines * * These Modules provide partial support for complex and zomplex matrices: * * MATLAB all routines support real and zomplex only, not complex, * with the exception of ldlupdate, which supports * real matrices only. This is a minor constraint since * MATLAB's matrices are all real or zomplex. * MatrixOps only norm_dense, norm_sparse, and sdmult support complex * and zomplex * * These Modules do not support complex and zomplex matrices at all: * * Modify all routines support real matrices only */ /* Definitions for cholmod_common: */ #define CHOLMOD_MAXMETHODS 9 /* maximum number of different methods that */ /* cholmod_analyze can try. Must be >= 9. */ /* Common->status values. zero means success, negative means a fatal error, * positive is a warning. */ #define CHOLMOD_OK 0 /* success */ #define CHOLMOD_NOT_INSTALLED (-1) /* failure: method not installed */ #define CHOLMOD_OUT_OF_MEMORY (-2) /* failure: out of memory */ #define CHOLMOD_TOO_LARGE (-3) /* failure: integer overflow occured */ #define CHOLMOD_INVALID (-4) /* failure: invalid input */ #define CHOLMOD_GPU_PROBLEM (-5) /* failure: GPU fatal error */ #define CHOLMOD_NOT_POSDEF (1) /* warning: matrix not pos. def. */ #define CHOLMOD_DSMALL (2) /* warning: D for LDL' or diag(L) or */ /* LL' has tiny absolute value */ /* ordering method (also used for L->ordering) */ #define CHOLMOD_NATURAL 0 /* use natural ordering */ #define CHOLMOD_GIVEN 1 /* use given permutation */ #define CHOLMOD_AMD 2 /* use minimum degree (AMD) */ #define CHOLMOD_METIS 3 /* use METIS' nested dissection */ #define CHOLMOD_NESDIS 4 /* use CHOLMOD's version of nested dissection:*/ /* node bisector applied recursively, followed * by constrained minimum degree (CSYMAMD or * CCOLAMD) */ #define CHOLMOD_COLAMD 5 /* use AMD for A, COLAMD for A*A' */ /* POSTORDERED is not a method, but a result of natural ordering followed by a * weighted postorder. It is used for L->ordering, not method [ ].ordering. */ #define CHOLMOD_POSTORDERED 6 /* natural ordering, postordered. */ /* supernodal strategy (for Common->supernodal) */ #define CHOLMOD_SIMPLICIAL 0 /* always do simplicial */ #define CHOLMOD_AUTO 1 /* select simpl/super depending on matrix */ #define CHOLMOD_SUPERNODAL 2 /* always do supernodal */ typedef struct cholmod_common_struct { /* ---------------------------------------------------------------------- */ /* parameters for symbolic/numeric factorization and update/downdate */ /* ---------------------------------------------------------------------- */ double dbound ; /* Smallest absolute value of diagonal entries of D * for LDL' factorization and update/downdate/rowadd/ * rowdel, or the diagonal of L for an LL' factorization. * Entries in the range 0 to dbound are replaced with dbound. * Entries in the range -dbound to 0 are replaced with -dbound. No * changes are made to the diagonal if dbound <= 0. Default: zero */ double grow0 ; /* For a simplicial factorization, L->i and L->x can * grow if necessary. grow0 is the factor by which * it grows. For the initial space, L is of size MAX (1,grow0) times * the required space. If L runs out of space, the new size of L is * MAX(1.2,grow0) times the new required space. If you do not plan on * modifying the LDL' factorization in the Modify module, set grow0 to * zero (or set grow2 to 0, see below). Default: 1.2 */ double grow1 ; size_t grow2 ; /* For a simplicial factorization, each column j of L * is initialized with space equal to * grow1*L->ColCount[j] + grow2. If grow0 < 1, grow1 < 1, or grow2 == 0, * then the space allocated is exactly equal to L->ColCount[j]. If the * column j runs out of space, it increases to grow1*need + grow2 in * size, where need is the total # of nonzeros in that column. If you do * not plan on modifying the factorization in the Modify module, set * grow2 to zero. Default: grow1 = 1.2, grow2 = 5. */ size_t maxrank ; /* rank of maximum update/downdate. Valid values: * 2, 4, or 8. A value < 2 is set to 2, and a * value > 8 is set to 8. It is then rounded up to the next highest * power of 2, if not already a power of 2. Workspace (Xwork, below) of * size nrow-by-maxrank double's is allocated for the update/downdate. * If an update/downdate of rank-k is requested, with k > maxrank, * it is done in steps of maxrank. Default: 8, which is fastest. * Memory usage can be reduced by setting maxrank to 2 or 4. */ double supernodal_switch ; /* supernodal vs simplicial factorization */ int supernodal ; /* If Common->supernodal <= CHOLMOD_SIMPLICIAL * (0) then cholmod_analyze performs a * simplicial analysis. If >= CHOLMOD_SUPERNODAL (2), then a supernodal * analysis is performed. If == CHOLMOD_AUTO (1) and * flop/nnz(L) < Common->supernodal_switch, then a simplicial analysis * is done. A supernodal analysis done otherwise. * Default: CHOLMOD_AUTO. Default supernodal_switch = 40 */ int final_asis ; /* If TRUE, then ignore the other final_* parameters * (except for final_pack). * The factor is left as-is when done. Default: TRUE.*/ int final_super ; /* If TRUE, leave a factor in supernodal form when * supernodal factorization is finished. If FALSE, * then convert to a simplicial factor when done. * Default: TRUE */ int final_ll ; /* If TRUE, leave factor in LL' form when done. * Otherwise, leave in LDL' form. Default: FALSE */ int final_pack ; /* If TRUE, pack the columns when done. If TRUE, and * cholmod_factorize is called with a symbolic L, L is * allocated with exactly the space required, using L->ColCount. If you * plan on modifying the factorization, set Common->final_pack to FALSE, * and each column will be given a little extra slack space for future * growth in fill-in due to updates. Default: TRUE */ int final_monotonic ; /* If TRUE, ensure columns are monotonic when done. * Default: TRUE */ int final_resymbol ;/* if cholmod_factorize performed a supernodal * factorization, final_resymbol is true, and * final_super is FALSE (convert a simplicial numeric factorization), * then numerically zero entries that resulted from relaxed supernodal * amalgamation are removed. This does not remove entries that are zero * due to exact numeric cancellation, since doing so would break the * update/downdate rowadd/rowdel routines. Default: FALSE. */ /* supernodal relaxed amalgamation parameters: */ double zrelax [3] ; size_t nrelax [3] ; /* Let ns be the total number of columns in two adjacent supernodes. * Let z be the fraction of zero entries in the two supernodes if they * are merged (z includes zero entries from prior amalgamations). The * two supernodes are merged if: * (ns <= nrelax [0]) || (no new zero entries added) || * (ns <= nrelax [1] && z < zrelax [0]) || * (ns <= nrelax [2] && z < zrelax [1]) || (z < zrelax [2]) * * Default parameters result in the following rule: * (ns <= 4) || (no new zero entries added) || * (ns <= 16 && z < 0.8) || (ns <= 48 && z < 0.1) || (z < 0.05) */ int prefer_zomplex ; /* X = cholmod_solve (sys, L, B, Common) computes * x=A\b or solves a related system. If L and B are * both real, then X is real. Otherwise, X is returned as * CHOLMOD_COMPLEX if Common->prefer_zomplex is FALSE, or * CHOLMOD_ZOMPLEX if Common->prefer_zomplex is TRUE. This parameter * is needed because there is no supernodal zomplex L. Suppose the * caller wants all complex matrices to be stored in zomplex form * (MATLAB, for example). A supernodal L is returned in complex form * if A is zomplex. B can be real, and thus X = cholmod_solve (L,B) * should return X as zomplex. This cannot be inferred from the input * arguments L and B. Default: FALSE, since all data types are * supported in CHOLMOD_COMPLEX form and since this is the native type * of LAPACK and the BLAS. Note that the MATLAB/cholmod.c mexFunction * sets this parameter to TRUE, since MATLAB matrices are in * CHOLMOD_ZOMPLEX form. */ int prefer_upper ; /* cholmod_analyze and cholmod_factorize work * fastest when a symmetric matrix is stored in * upper triangular form when a fill-reducing ordering is used. In * MATLAB, this corresponds to how x=A\b works. When the matrix is * ordered as-is, they work fastest when a symmetric matrix is in lower * triangular form. In MATLAB, R=chol(A) does the opposite. This * parameter affects only how cholmod_read returns a symmetric matrix. * If TRUE (the default case), a symmetric matrix is always returned in * upper-triangular form (A->stype = 1). */ int quick_return_if_not_posdef ; /* if TRUE, the supernodal numeric * factorization will return quickly if * the matrix is not positive definite. Default: FALSE. */ int prefer_binary ; /* cholmod_read_triplet converts a symmetric * pattern-only matrix into a real matrix. If * prefer_binary is FALSE, the diagonal entries are set to 1 + the degree * of the row/column, and off-diagonal entries are set to -1 (resulting * in a positive definite matrix if the diagonal is zero-free). Most * symmetric patterns are the pattern a positive definite matrix. If * this parameter is TRUE, then the matrix is returned with a 1 in each * entry, instead. Default: FALSE. Added in v1.3. */ /* ---------------------------------------------------------------------- */ /* printing and error handling options */ /* ---------------------------------------------------------------------- */ int print ; /* print level. Default: 3 */ int precise ; /* if TRUE, print 16 digits. Otherwise print 5 */ /* CHOLMOD print_function replaced with SuiteSparse_config.print_func */ int try_catch ; /* if TRUE, then ignore errors; CHOLMOD is in the middle * of a try/catch block. No error message is printed * and the Common->error_handler function is not called. */ void (*error_handler) (int status, const char *file, int line, const char *message) ; /* Common->error_handler is the user's error handling routine. If not * NULL, this routine is called if an error occurs in CHOLMOD. status * can be CHOLMOD_OK (0), negative for a fatal error, and positive for * a warning. file is a string containing the name of the source code * file where the error occured, and line is the line number in that * file. message is a string describing the error in more detail. */ /* ---------------------------------------------------------------------- */ /* ordering options */ /* ---------------------------------------------------------------------- */ /* The cholmod_analyze routine can try many different orderings and select * the best one. It can also try one ordering method multiple times, with * different parameter settings. The default is to use three orderings, * the user's permutation (if provided), AMD which is the fastest ordering * and generally gives good fill-in, and METIS. CHOLMOD's nested dissection * (METIS with a constrained AMD) usually gives a better ordering than METIS * alone (by about 5% to 10%) but it takes more time. * * If you know the method that is best for your matrix, set Common->nmethods * to 1 and set Common->method [0] to the set of parameters for that method. * If you set it to 1 and do not provide a permutation, then only AMD will * be called. * * If METIS is not available, the default # of methods tried is 2 (the user * permutation, if any, and AMD). * * To try other methods, set Common->nmethods to the number of methods you * want to try. The suite of default methods and their parameters is * described in the cholmod_defaults routine, and summarized here: * * Common->method [i]: * i = 0: user-provided ordering (cholmod_analyze_p only) * i = 1: AMD (for both A and A*A') * i = 2: METIS * i = 3: CHOLMOD's nested dissection (NESDIS), default parameters * i = 4: natural * i = 5: NESDIS with nd_small = 20000 * i = 6: NESDIS with nd_small = 4, no constrained minimum degree * i = 7: NESDIS with no dense node removal * i = 8: AMD for A, COLAMD for A*A' * * You can modify the suite of methods you wish to try by modifying * Common.method [...] after calling cholmod_start or cholmod_defaults. * * For example, to use AMD, followed by a weighted postordering: * * Common->nmethods = 1 ; * Common->method [0].ordering = CHOLMOD_AMD ; * Common->postorder = TRUE ; * * To use the natural ordering (with no postordering): * * Common->nmethods = 1 ; * Common->method [0].ordering = CHOLMOD_NATURAL ; * Common->postorder = FALSE ; * * If you are going to factorize hundreds or more matrices with the same * nonzero pattern, you may wish to spend a great deal of time finding a * good permutation. In this case, try setting Common->nmethods to 9. * The time spent in cholmod_analysis will be very high, but you need to * call it only once. * * cholmod_analyze sets Common->current to a value between 0 and nmethods-1. * Each ordering method uses the set of options defined by this parameter. */ int nmethods ; /* The number of ordering methods to try. Default: 0. * nmethods = 0 is a special case. cholmod_analyze * will try the user-provided ordering (if given) and AMD. Let fl and * lnz be the flop count and nonzeros in L from AMD's ordering. Let * anz be the number of nonzeros in the upper or lower triangular part * of the symmetric matrix A. If fl/lnz < 500 or lnz/anz < 5, then this * is a good ordering, and METIS is not attempted. Otherwise, METIS is * tried. The best ordering found is used. If nmethods > 0, the * methods used are given in the method[ ] array, below. The first * three methods in the default suite of orderings is (1) use the given * permutation (if provided), (2) use AMD, and (3) use METIS. Maximum * allowed value is CHOLMOD_MAXMETHODS. */ int current ; /* The current method being tried. Default: 0. Valid * range is 0 to nmethods-1. */ int selected ; /* The best method found. */ /* The suite of ordering methods and parameters: */ struct cholmod_method_struct { /* statistics for this method */ double lnz ; /* nnz(L) excl. zeros from supernodal amalgamation, * for a "pure" L */ double fl ; /* flop count for a "pure", real simplicial LL' * factorization, with no extra work due to * amalgamation. Subtract n to get the LDL' flop count. Multiply * by about 4 if the matrix is complex or zomplex. */ /* ordering method parameters */ double prune_dense ;/* dense row/col control for AMD, SYMAMD, CSYMAMD, * and NESDIS (cholmod_nested_dissection). For a * symmetric n-by-n matrix, rows/columns with more than * MAX (16, prune_dense * sqrt (n)) entries are removed prior to * ordering. They appear at the end of the re-ordered matrix. * * If prune_dense < 0, only completely dense rows/cols are removed. * * This paramater is also the dense column control for COLAMD and * CCOLAMD. For an m-by-n matrix, columns with more than * MAX (16, prune_dense * sqrt (MIN (m,n))) entries are removed prior * to ordering. They appear at the end of the re-ordered matrix. * CHOLMOD factorizes A*A', so it calls COLAMD and CCOLAMD with A', * not A. Thus, this parameter affects the dense *row* control for * CHOLMOD's matrix, and the dense *column* control for COLAMD and * CCOLAMD. * * Removing dense rows and columns improves the run-time of the * ordering methods. It has some impact on ordering quality * (usually minimal, sometimes good, sometimes bad). * * Default: 10. */ double prune_dense2 ;/* dense row control for COLAMD and CCOLAMD. * Rows with more than MAX (16, dense2 * sqrt (n)) * for an m-by-n matrix are removed prior to ordering. CHOLMOD's * matrix is transposed before ordering it with COLAMD or CCOLAMD, * so this controls the dense *columns* of CHOLMOD's matrix, and * the dense *rows* of COLAMD's or CCOLAMD's matrix. * * If prune_dense2 < 0, only completely dense rows/cols are removed. * * Default: -1. Note that this is not the default for COLAMD and * CCOLAMD. -1 is best for Cholesky. 10 is best for LU. */ double nd_oksep ; /* in NESDIS, when a node separator is computed, it * discarded if nsep >= nd_oksep*n, where nsep is * the number of nodes in the separator, and n is the size of the * graph being cut. Valid range is 0 to 1. If 1 or greater, the * separator is discarded if it consists of the entire graph. * Default: 1 */ double other_1 [4] ; /* future expansion */ size_t nd_small ; /* do not partition graphs with fewer nodes than * nd_small, in NESDIS. Default: 200 (same as * METIS) */ size_t other_2 [4] ; /* future expansion */ int aggressive ; /* Aggresive absorption in AMD, COLAMD, SYMAMD, * CCOLAMD, and CSYMAMD. Default: TRUE */ int order_for_lu ; /* CCOLAMD can be optimized to produce an ordering * for LU or Cholesky factorization. CHOLMOD only * performs a Cholesky factorization. However, you may wish to use * CHOLMOD as an interface for CCOLAMD but use it for your own LU * factorization. In this case, order_for_lu should be set to FALSE. * When factorizing in CHOLMOD itself, you should *** NEVER *** set * this parameter FALSE. Default: TRUE. */ int nd_compress ; /* If TRUE, compress the graph and subgraphs before * partitioning them in NESDIS. Default: TRUE */ int nd_camd ; /* If 1, follow the nested dissection ordering * with a constrained minimum degree ordering that * respects the partitioning just found (using CAMD). If 2, use * CSYMAMD instead. If you set nd_small very small, you may not need * this ordering, and can save time by setting it to zero (no * constrained minimum degree ordering). Default: 1. */ int nd_components ; /* The nested dissection ordering finds a node * separator that splits the graph into two parts, * which may be unconnected. If nd_components is TRUE, each of * these connected components is split independently. If FALSE, * each part is split as a whole, even if it consists of more than * one connected component. Default: FALSE */ /* fill-reducing ordering to use */ int ordering ; size_t other_3 [4] ; /* future expansion */ } method [CHOLMOD_MAXMETHODS + 1] ; int postorder ; /* If TRUE, cholmod_analyze follows the ordering with a * weighted postorder of the elimination tree. Improves * supernode amalgamation. Does not affect fundamental nnz(L) and * flop count. Default: TRUE. */ int default_nesdis ; /* Default: FALSE. If FALSE, then the default * ordering strategy (when Common->nmethods == 0) * is to try the given ordering (if present), AMD, and then METIS if AMD * reports high fill-in. If Common->default_nesdis is TRUE then NESDIS * is used instead in the default strategy. */ /* ---------------------------------------------------------------------- */ /* memory management, complex divide, and hypot function pointers moved */ /* ---------------------------------------------------------------------- */ /* Function pointers moved from here (in CHOLMOD 2.2.0) to SuiteSparse_config.[ch]. See CHOLMOD/Include/cholmod_back.h for a set of macros that can be #include'd or copied into your application to define these function pointers on any version of CHOLMOD. */ /* ---------------------------------------------------------------------- */ /* METIS workarounds */ /* ---------------------------------------------------------------------- */ /* These workarounds were put into place for METIS 4.0.1. They are safe to use with METIS 5.1.0, but they might not longer be necessary. */ double metis_memory ; /* This is a parameter for CHOLMOD's interface to * METIS, not a parameter to METIS itself. METIS * uses an amount of memory that is difficult to estimate precisely * beforehand. If it runs out of memory, it terminates your program. * All routines in CHOLMOD except for CHOLMOD's interface to METIS * return an error status and safely return to your program if they run * out of memory. To mitigate this problem, the CHOLMOD interface * can allocate a single block of memory equal in size to an empirical * upper bound of METIS's memory usage times the Common->metis_memory * parameter, and then immediately free it. It then calls METIS. If * this pre-allocation fails, it is possible that METIS will fail as * well, and so CHOLMOD returns with an out-of-memory condition without * calling METIS. * * METIS_NodeND (used in the CHOLMOD_METIS ordering option) with its * default parameter settings typically uses about (4*nz+40n+4096) * times sizeof(int) memory, where nz is equal to the number of entries * in A for the symmetric case or AA' if an unsymmetric matrix is * being ordered (where nz includes both the upper and lower parts * of A or AA'). The observed "upper bound" (with 2 exceptions), * measured in an instrumented copy of METIS 4.0.1 on thousands of * matrices, is (10*nz+50*n+4096) * sizeof(int). Two large matrices * exceeded this bound, one by almost a factor of 2 (Gupta/gupta2). * * If your program is terminated by METIS, try setting metis_memory to * 2.0, or even higher if needed. By default, CHOLMOD assumes that METIS * does not have this problem (so that CHOLMOD will work correctly when * this issue is fixed in METIS). Thus, the default value is zero. * This work-around is not guaranteed anyway. * * If a matrix exceeds this predicted memory usage, AMD is attempted * instead. It, too, may run out of memory, but if it does so it will * not terminate your program. */ double metis_dswitch ; /* METIS_NodeND in METIS 4.0.1 gives a seg */ size_t metis_nswitch ; /* fault with one matrix of order n = 3005 and * nz = 6,036,025. This is a very dense graph. * The workaround is to use AMD instead of METIS for matrices of dimension * greater than Common->metis_nswitch (default 3000) or more and with * density of Common->metis_dswitch (default 0.66) or more. * cholmod_nested_dissection has no problems with the same matrix, even * though it uses METIS_ComputeVertexSeparator on this matrix. If this * seg fault does not affect you, set metis_nswitch to zero or less, * and CHOLMOD will not switch to AMD based just on the density of the * matrix (it will still switch to AMD if the metis_memory parameter * causes the switch). */ /* ---------------------------------------------------------------------- */ /* workspace */ /* ---------------------------------------------------------------------- */ /* CHOLMOD has several routines that take less time than the size of * workspace they require. Allocating and initializing the workspace would * dominate the run time, unless workspace is allocated and initialized * just once. CHOLMOD allocates this space when needed, and holds it here * between calls to CHOLMOD. cholmod_start sets these pointers to NULL * (which is why it must be the first routine called in CHOLMOD). * cholmod_finish frees the workspace (which is why it must be the last * call to CHOLMOD). */ size_t nrow ; /* size of Flag and Head */ SuiteSparse_long mark ; /* mark value for Flag array */ size_t iworksize ; /* size of Iwork. Upper bound: 6*nrow+ncol */ size_t xworksize ; /* size of Xwork, in bytes. * maxrank*nrow*sizeof(double) for update/downdate. * 2*nrow*sizeof(double) otherwise */ /* initialized workspace: contents needed between calls to CHOLMOD */ void *Flag ; /* size nrow, an integer array. Kept cleared between * calls to cholmod rouines (Flag [i] < mark) */ void *Head ; /* size nrow+1, an integer array. Kept cleared between * calls to cholmod routines (Head [i] = EMPTY) */ void *Xwork ; /* a double array. Its size varies. It is nrow for * most routines (cholmod_rowfac, cholmod_add, * cholmod_aat, cholmod_norm, cholmod_ssmult) for the real case, twice * that when the input matrices are complex or zomplex. It is of size * 2*nrow for cholmod_rowadd and cholmod_rowdel. For cholmod_updown, * its size is maxrank*nrow where maxrank is 2, 4, or 8. Kept cleared * between calls to cholmod (set to zero). */ /* uninitialized workspace, contents not needed between calls to CHOLMOD */ void *Iwork ; /* size iworksize, 2*nrow+ncol for most routines, * up to 6*nrow+ncol for cholmod_analyze. */ int itype ; /* If CHOLMOD_LONG, Flag, Head, and Iwork are * SuiteSparse_long. Otherwise all three are int. */ int dtype ; /* double or float */ /* Common->itype and Common->dtype are used to define the types of all * sparse matrices, triplet matrices, dense matrices, and factors * created using this Common struct. The itypes and dtypes of all * parameters to all CHOLMOD routines must match. */ int no_workspace_reallocate ; /* this is an internal flag, used as a * precaution by cholmod_analyze. It is normally false. If true, * cholmod_allocate_work is not allowed to reallocate any workspace; * they must use the existing workspace in Common (Iwork, Flag, Head, * and Xwork). Added for CHOLMOD v1.1 */ /* ---------------------------------------------------------------------- */ /* statistics */ /* ---------------------------------------------------------------------- */ /* fl and lnz are set only in cholmod_analyze and cholmod_rowcolcounts, * in the Cholesky modudle. modfl is set only in the Modify module. */ int status ; /* error code */ double fl ; /* LL' flop count from most recent analysis */ double lnz ; /* fundamental nz in L */ double anz ; /* nonzeros in tril(A) if A is symmetric/lower, * triu(A) if symmetric/upper, or tril(A*A') if * unsymmetric, in last call to cholmod_analyze. */ double modfl ; /* flop count from most recent update/downdate/ * rowadd/rowdel (excluding flops to modify the * solution to Lx=b, if computed) */ size_t malloc_count ; /* # of objects malloc'ed minus the # free'd*/ size_t memory_usage ; /* peak memory usage in bytes */ size_t memory_inuse ; /* current memory usage in bytes */ double nrealloc_col ; /* # of column reallocations */ double nrealloc_factor ;/* # of factor reallocations due to col. reallocs */ double ndbounds_hit ; /* # of times diagonal modified by dbound */ double rowfacfl ; /* # of flops in last call to cholmod_rowfac */ double aatfl ; /* # of flops to compute A(:,f)*A(:,f)' */ int called_nd ; /* TRUE if the last call to * cholmod_analyze called NESDIS or METIS. */ int blas_ok ; /* FALSE if BLAS int overflow; TRUE otherwise */ /* ---------------------------------------------------------------------- */ /* SuiteSparseQR control parameters: */ /* ---------------------------------------------------------------------- */ double SPQR_grain ; /* task size is >= max (total flops / grain) */ double SPQR_small ; /* task size is >= small */ int SPQR_shrink ; /* controls stack realloc method */ int SPQR_nthreads ; /* number of TBB threads, 0 = auto */ /* ---------------------------------------------------------------------- */ /* SuiteSparseQR statistics */ /* ---------------------------------------------------------------------- */ /* was other1 [0:3] */ double SPQR_flopcount ; /* flop count for SPQR */ double SPQR_analyze_time ; /* analysis time in seconds for SPQR */ double SPQR_factorize_time ; /* factorize time in seconds for SPQR */ double SPQR_solve_time ; /* backsolve time in seconds */ /* was SPQR_xstat [0:3] */ double SPQR_flopcount_bound ; /* upper bound on flop count */ double SPQR_tol_used ; /* tolerance used */ double SPQR_norm_E_fro ; /* Frobenius norm of dropped entries */ /* was SPQR_istat [0:9] */ SuiteSparse_long SPQR_istat [10] ; /* ---------------------------------------------------------------------- */ /* GPU configuration and statistics */ /* ---------------------------------------------------------------------- */ /* useGPU: 1 if gpu-acceleration is requested */ /* 0 if gpu-acceleration is prohibited */ /* -1 if gpu-acceleration is undefined in which case the */ /* environment CHOLMOD_USE_GPU will be queried and used. */ /* useGPU=-1 is only used by CHOLMOD and treated as 0 by SPQR */ int useGPU; /* for CHOLMOD: */ size_t maxGpuMemBytes; double maxGpuMemFraction; /* for SPQR: */ size_t gpuMemorySize; /* Amount of memory in bytes on the GPU */ double gpuKernelTime; /* Time taken by GPU kernels */ SuiteSparse_long gpuFlops; /* Number of flops performed by the GPU */ int gpuNumKernelLaunches; /* Number of GPU kernel launches */ /* If not using the GPU, these items are not used, but they should be present so that the CHOLMOD Common has the same size whether the GPU is used or not. This way, all packages will agree on the size of the CHOLMOD Common, regardless of whether or not they are compiled with the GPU libraries or not */ #ifdef GPU_BLAS /* in CUDA, these three types are pointers */ #define CHOLMOD_CUBLAS_HANDLE cublasHandle_t #define CHOLMOD_CUDASTREAM cudaStream_t #define CHOLMOD_CUDAEVENT cudaEvent_t #else /* ... so make them void * pointers if the GPU is not being used */ #define CHOLMOD_CUBLAS_HANDLE void * #define CHOLMOD_CUDASTREAM void * #define CHOLMOD_CUDAEVENT void * #endif CHOLMOD_CUBLAS_HANDLE cublasHandle ; /* a set of streams for general use */ CHOLMOD_CUDASTREAM gpuStream[CHOLMOD_HOST_SUPERNODE_BUFFERS]; CHOLMOD_CUDAEVENT cublasEventPotrf [3] ; CHOLMOD_CUDAEVENT updateCKernelsComplete; CHOLMOD_CUDAEVENT updateCBuffersFree[CHOLMOD_HOST_SUPERNODE_BUFFERS]; void *dev_mempool; /* pointer to single allocation of device memory */ size_t dev_mempool_size; void *host_pinned_mempool; /* pointer to single allocation of pinned mem */ size_t host_pinned_mempool_size; size_t devBuffSize; int ibuffer; double syrkStart ; /* time syrk started */ /* run times of the different parts of CHOLMOD (GPU and CPU) */ double cholmod_cpu_gemm_time ; double cholmod_cpu_syrk_time ; double cholmod_cpu_trsm_time ; double cholmod_cpu_potrf_time ; double cholmod_gpu_gemm_time ; double cholmod_gpu_syrk_time ; double cholmod_gpu_trsm_time ; double cholmod_gpu_potrf_time ; double cholmod_assemble_time ; double cholmod_assemble_time2 ; /* number of times the BLAS are called on the CPU and the GPU */ size_t cholmod_cpu_gemm_calls ; size_t cholmod_cpu_syrk_calls ; size_t cholmod_cpu_trsm_calls ; size_t cholmod_cpu_potrf_calls ; size_t cholmod_gpu_gemm_calls ; size_t cholmod_gpu_syrk_calls ; size_t cholmod_gpu_trsm_calls ; size_t cholmod_gpu_potrf_calls ; } cholmod_common ; /* size_t BLAS statistcs in Common: */ #define CHOLMOD_CPU_GEMM_CALLS cholmod_cpu_gemm_calls #define CHOLMOD_CPU_SYRK_CALLS cholmod_cpu_syrk_calls #define CHOLMOD_CPU_TRSM_CALLS cholmod_cpu_trsm_calls #define CHOLMOD_CPU_POTRF_CALLS cholmod_cpu_potrf_calls #define CHOLMOD_GPU_GEMM_CALLS cholmod_gpu_gemm_calls #define CHOLMOD_GPU_SYRK_CALLS cholmod_gpu_syrk_calls #define CHOLMOD_GPU_TRSM_CALLS cholmod_gpu_trsm_calls #define CHOLMOD_GPU_POTRF_CALLS cholmod_gpu_potrf_calls /* double BLAS statistics in Common: */ #define CHOLMOD_CPU_GEMM_TIME cholmod_cpu_gemm_time #define CHOLMOD_CPU_SYRK_TIME cholmod_cpu_syrk_time #define CHOLMOD_CPU_TRSM_TIME cholmod_cpu_trsm_time #define CHOLMOD_CPU_POTRF_TIME cholmod_cpu_potrf_time #define CHOLMOD_GPU_GEMM_TIME cholmod_gpu_gemm_time #define CHOLMOD_GPU_SYRK_TIME cholmod_gpu_syrk_time #define CHOLMOD_GPU_TRSM_TIME cholmod_gpu_trsm_time #define CHOLMOD_GPU_POTRF_TIME cholmod_gpu_potrf_time #define CHOLMOD_ASSEMBLE_TIME cholmod_assemble_time #define CHOLMOD_ASSEMBLE_TIME2 cholmod_assemble_time2 /* for supernodal analysis */ #define CHOLMOD_ANALYZE_FOR_SPQR 0 #define CHOLMOD_ANALYZE_FOR_CHOLESKY 1 #define CHOLMOD_ANALYZE_FOR_SPQRGPU 2 /* -------------------------------------------------------------------------- */ /* cholmod_start: first call to CHOLMOD */ /* -------------------------------------------------------------------------- */ int cholmod_start ( cholmod_common *Common ) ; int cholmod_l_start (cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_finish: last call to CHOLMOD */ /* -------------------------------------------------------------------------- */ int cholmod_finish ( cholmod_common *Common ) ; int cholmod_l_finish (cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_defaults: restore default parameters */ /* -------------------------------------------------------------------------- */ int cholmod_defaults ( cholmod_common *Common ) ; int cholmod_l_defaults (cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_maxrank: return valid maximum rank for update/downdate */ /* -------------------------------------------------------------------------- */ size_t cholmod_maxrank /* returns validated value of Common->maxrank */ ( /* ---- input ---- */ size_t n, /* A and L will have n rows */ /* --------------- */ cholmod_common *Common ) ; size_t cholmod_l_maxrank (size_t, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_allocate_work: allocate workspace in Common */ /* -------------------------------------------------------------------------- */ int cholmod_allocate_work ( /* ---- input ---- */ size_t nrow, /* size: Common->Flag (nrow), Common->Head (nrow+1) */ size_t iworksize, /* size of Common->Iwork */ size_t xworksize, /* size of Common->Xwork */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_allocate_work (size_t, size_t, size_t, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_free_work: free workspace in Common */ /* -------------------------------------------------------------------------- */ int cholmod_free_work ( cholmod_common *Common ) ; int cholmod_l_free_work (cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_clear_flag: clear Flag workspace in Common */ /* -------------------------------------------------------------------------- */ /* use a macro for speed */ #define CHOLMOD_CLEAR_FLAG(Common) \ { \ Common->mark++ ; \ if (Common->mark <= 0) \ { \ Common->mark = EMPTY ; \ CHOLMOD (clear_flag) (Common) ; \ } \ } SuiteSparse_long cholmod_clear_flag ( cholmod_common *Common ) ; SuiteSparse_long cholmod_l_clear_flag (cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_error: called when CHOLMOD encounters an error */ /* -------------------------------------------------------------------------- */ int cholmod_error ( /* ---- input ---- */ int status, /* error status */ const char *file, /* name of source code file where error occured */ int line, /* line number in source code file where error occured*/ const char *message,/* error message */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_error (int, const char *, int, const char *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_dbound: for internal use in CHOLMOD only */ /* -------------------------------------------------------------------------- */ double cholmod_dbound /* returns modified diagonal entry of D or L */ ( /* ---- input ---- */ double dj, /* diagonal entry of D for LDL' or L for LL' */ /* --------------- */ cholmod_common *Common ) ; double cholmod_l_dbound (double, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_hypot: compute sqrt (x*x + y*y) accurately */ /* -------------------------------------------------------------------------- */ double cholmod_hypot ( /* ---- input ---- */ double x, double y ) ; double cholmod_l_hypot (double, double) ; /* -------------------------------------------------------------------------- */ /* cholmod_divcomplex: complex division, c = a/b */ /* -------------------------------------------------------------------------- */ int cholmod_divcomplex /* return 1 if divide-by-zero, 0 otherise */ ( /* ---- input ---- */ double ar, double ai, /* real and imaginary parts of a */ double br, double bi, /* real and imaginary parts of b */ /* ---- output --- */ double *cr, double *ci /* real and imaginary parts of c */ ) ; int cholmod_l_divcomplex (double, double, double, double, double *, double *) ; /* ========================================================================== */ /* === Core/cholmod_sparse ================================================== */ /* ========================================================================== */ /* A sparse matrix stored in compressed-column form. */ typedef struct cholmod_sparse_struct { size_t nrow ; /* the matrix is nrow-by-ncol */ size_t ncol ; size_t nzmax ; /* maximum number of entries in the matrix */ /* pointers to int or SuiteSparse_long: */ void *p ; /* p [0..ncol], the column pointers */ void *i ; /* i [0..nzmax-1], the row indices */ /* for unpacked matrices only: */ void *nz ; /* nz [0..ncol-1], the # of nonzeros in each col. In * packed form, the nonzero pattern of column j is in * A->i [A->p [j] ... A->p [j+1]-1]. In unpacked form, column j is in * A->i [A->p [j] ... A->p [j]+A->nz[j]-1] instead. In both cases, the * numerical values (if present) are in the corresponding locations in * the array x (or z if A->xtype is CHOLMOD_ZOMPLEX). */ /* pointers to double or float: */ void *x ; /* size nzmax or 2*nzmax, if present */ void *z ; /* size nzmax, if present */ int stype ; /* Describes what parts of the matrix are considered: * * 0: matrix is "unsymmetric": use both upper and lower triangular parts * (the matrix may actually be symmetric in pattern and value, but * both parts are explicitly stored and used). May be square or * rectangular. * >0: matrix is square and symmetric, use upper triangular part. * Entries in the lower triangular part are ignored. * <0: matrix is square and symmetric, use lower triangular part. * Entries in the upper triangular part are ignored. * * Note that stype>0 and stype<0 are different for cholmod_sparse and * cholmod_triplet. See the cholmod_triplet data structure for more * details. */ int itype ; /* CHOLMOD_INT: p, i, and nz are int. * CHOLMOD_INTLONG: p is SuiteSparse_long, * i and nz are int. * CHOLMOD_LONG: p, i, and nz are SuiteSparse_long */ int xtype ; /* pattern, real, complex, or zomplex */ int dtype ; /* x and z are double or float */ int sorted ; /* TRUE if columns are sorted, FALSE otherwise */ int packed ; /* TRUE if packed (nz ignored), FALSE if unpacked * (nz is required) */ } cholmod_sparse ; typedef struct cholmod_descendant_score_t { double score; SuiteSparse_long d; } descendantScore; /* For sorting descendant supernodes with qsort */ int cholmod_score_comp (struct cholmod_descendant_score_t *i, struct cholmod_descendant_score_t *j); int cholmod_l_score_comp (struct cholmod_descendant_score_t *i, struct cholmod_descendant_score_t *j); /* -------------------------------------------------------------------------- */ /* cholmod_allocate_sparse: allocate a sparse matrix */ /* -------------------------------------------------------------------------- */ cholmod_sparse *cholmod_allocate_sparse ( /* ---- input ---- */ size_t nrow, /* # of rows of A */ size_t ncol, /* # of columns of A */ size_t nzmax, /* max # of nonzeros of A */ int sorted, /* TRUE if columns of A sorted, FALSE otherwise */ int packed, /* TRUE if A will be packed, FALSE otherwise */ int stype, /* stype of A */ int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ /* --------------- */ cholmod_common *Common ) ; cholmod_sparse *cholmod_l_allocate_sparse (size_t, size_t, size_t, int, int, int, int, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_free_sparse: free a sparse matrix */ /* -------------------------------------------------------------------------- */ int cholmod_free_sparse ( /* ---- in/out --- */ cholmod_sparse **A, /* matrix to deallocate, NULL on output */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_free_sparse (cholmod_sparse **, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_reallocate_sparse: change the size (# entries) of sparse matrix */ /* -------------------------------------------------------------------------- */ int cholmod_reallocate_sparse ( /* ---- input ---- */ size_t nznew, /* new # of entries in A */ /* ---- in/out --- */ cholmod_sparse *A, /* matrix to reallocate */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_reallocate_sparse ( size_t, cholmod_sparse *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_nnz: return number of nonzeros in a sparse matrix */ /* -------------------------------------------------------------------------- */ SuiteSparse_long cholmod_nnz ( /* ---- input ---- */ cholmod_sparse *A, /* --------------- */ cholmod_common *Common ) ; SuiteSparse_long cholmod_l_nnz (cholmod_sparse *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_speye: sparse identity matrix */ /* -------------------------------------------------------------------------- */ cholmod_sparse *cholmod_speye ( /* ---- input ---- */ size_t nrow, /* # of rows of A */ size_t ncol, /* # of columns of A */ int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ /* --------------- */ cholmod_common *Common ) ; cholmod_sparse *cholmod_l_speye (size_t, size_t, int, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_spzeros: sparse zero matrix */ /* -------------------------------------------------------------------------- */ cholmod_sparse *cholmod_spzeros ( /* ---- input ---- */ size_t nrow, /* # of rows of A */ size_t ncol, /* # of columns of A */ size_t nzmax, /* max # of nonzeros of A */ int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ /* --------------- */ cholmod_common *Common ) ; cholmod_sparse *cholmod_l_spzeros (size_t, size_t, size_t, int, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_transpose: transpose a sparse matrix */ /* -------------------------------------------------------------------------- */ /* Return A' or A.' The "values" parameter is 0, 1, or 2 to denote the pattern * transpose, the array transpose (A.'), and the complex conjugate transpose * (A'). */ cholmod_sparse *cholmod_transpose ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to transpose */ int values, /* 0: pattern, 1: array transpose, 2: conj. transpose */ /* --------------- */ cholmod_common *Common ) ; cholmod_sparse *cholmod_l_transpose (cholmod_sparse *, int, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_transpose_unsym: transpose an unsymmetric sparse matrix */ /* -------------------------------------------------------------------------- */ /* Compute F = A', A (:,f)', or A (p,f)', where A is unsymmetric and F is * already allocated. See cholmod_transpose for a simpler routine. */ int cholmod_transpose_unsym ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to transpose */ int values, /* 0: pattern, 1: array transpose, 2: conj. transpose */ int *Perm, /* size nrow, if present (can be NULL) */ int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ /* ---- output --- */ cholmod_sparse *F, /* F = A', A(:,f)', or A(p,f)' */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_transpose_unsym (cholmod_sparse *, int, SuiteSparse_long *, SuiteSparse_long *, size_t, cholmod_sparse *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_transpose_sym: transpose a symmetric sparse matrix */ /* -------------------------------------------------------------------------- */ /* Compute F = A' or A (p,p)', where A is symmetric and F is already allocated. * See cholmod_transpose for a simpler routine. */ int cholmod_transpose_sym ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to transpose */ int values, /* 0: pattern, 1: array transpose, 2: conj. transpose */ int *Perm, /* size nrow, if present (can be NULL) */ /* ---- output --- */ cholmod_sparse *F, /* F = A' or A(p,p)' */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_transpose_sym (cholmod_sparse *, int, SuiteSparse_long *, cholmod_sparse *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_ptranspose: transpose a sparse matrix */ /* -------------------------------------------------------------------------- */ /* Return A' or A(p,p)' if A is symmetric. Return A', A(:,f)', or A(p,f)' if * A is unsymmetric. */ cholmod_sparse *cholmod_ptranspose ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to transpose */ int values, /* 0: pattern, 1: array transpose, 2: conj. transpose */ int *Perm, /* if non-NULL, F = A(p,f) or A(p,p) */ int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ /* --------------- */ cholmod_common *Common ) ; cholmod_sparse *cholmod_l_ptranspose (cholmod_sparse *, int, SuiteSparse_long *, SuiteSparse_long *, size_t, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_sort: sort row indices in each column of sparse matrix */ /* -------------------------------------------------------------------------- */ int cholmod_sort ( /* ---- in/out --- */ cholmod_sparse *A, /* matrix to sort */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_sort (cholmod_sparse *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_band: C = tril (triu (A,k1), k2) */ /* -------------------------------------------------------------------------- */ cholmod_sparse *cholmod_band ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to extract band matrix from */ SuiteSparse_long k1, /* ignore entries below the k1-st diagonal */ SuiteSparse_long k2, /* ignore entries above the k2-nd diagonal */ int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) */ /* --------------- */ cholmod_common *Common ) ; cholmod_sparse *cholmod_l_band (cholmod_sparse *, SuiteSparse_long, SuiteSparse_long, int, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_band_inplace: A = tril (triu (A,k1), k2) */ /* -------------------------------------------------------------------------- */ int cholmod_band_inplace ( /* ---- input ---- */ SuiteSparse_long k1, /* ignore entries below the k1-st diagonal */ SuiteSparse_long k2, /* ignore entries above the k2-nd diagonal */ int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) */ /* ---- in/out --- */ cholmod_sparse *A, /* matrix from which entries not in band are removed */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_band_inplace (SuiteSparse_long, SuiteSparse_long, int, cholmod_sparse *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_aat: C = A*A' or A(:,f)*A(:,f)' */ /* -------------------------------------------------------------------------- */ cholmod_sparse *cholmod_aat ( /* ---- input ---- */ cholmod_sparse *A, /* input matrix; C=A*A' is constructed */ int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag), * -2: pattern only, no diagonal, add 50%+n extra * space to C */ /* --------------- */ cholmod_common *Common ) ; cholmod_sparse *cholmod_l_aat (cholmod_sparse *, SuiteSparse_long *, size_t, int, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_copy_sparse: C = A, create an exact copy of a sparse matrix */ /* -------------------------------------------------------------------------- */ cholmod_sparse *cholmod_copy_sparse ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to copy */ /* --------------- */ cholmod_common *Common ) ; cholmod_sparse *cholmod_l_copy_sparse (cholmod_sparse *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_copy: C = A, with possible change of stype */ /* -------------------------------------------------------------------------- */ cholmod_sparse *cholmod_copy ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to copy */ int stype, /* requested stype of C */ int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) */ /* --------------- */ cholmod_common *Common ) ; cholmod_sparse *cholmod_l_copy (cholmod_sparse *, int, int, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_add: C = alpha*A + beta*B */ /* -------------------------------------------------------------------------- */ cholmod_sparse *cholmod_add ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to add */ cholmod_sparse *B, /* matrix to add */ double alpha [2], /* scale factor for A */ double beta [2], /* scale factor for B */ int values, /* if TRUE compute the numerical values of C */ int sorted, /* if TRUE, sort columns of C */ /* --------------- */ cholmod_common *Common ) ; cholmod_sparse *cholmod_l_add (cholmod_sparse *, cholmod_sparse *, double [2], double [2], int, int, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_sparse_xtype: change the xtype of a sparse matrix */ /* -------------------------------------------------------------------------- */ int cholmod_sparse_xtype ( /* ---- input ---- */ int to_xtype, /* requested xtype (pattern, real, complex, zomplex) */ /* ---- in/out --- */ cholmod_sparse *A, /* sparse matrix to change */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_sparse_xtype (int, cholmod_sparse *, cholmod_common *) ; /* ========================================================================== */ /* === Core/cholmod_factor ================================================== */ /* ========================================================================== */ /* A symbolic and numeric factorization, either simplicial or supernodal. * In all cases, the row indices in the columns of L are kept sorted. */ typedef struct cholmod_factor_struct { /* ---------------------------------------------------------------------- */ /* for both simplicial and supernodal factorizations */ /* ---------------------------------------------------------------------- */ size_t n ; /* L is n-by-n */ size_t minor ; /* If the factorization failed, L->minor is the column * at which it failed (in the range 0 to n-1). A value * of n means the factorization was successful or * the matrix has not yet been factorized. */ /* ---------------------------------------------------------------------- */ /* symbolic ordering and analysis */ /* ---------------------------------------------------------------------- */ void *Perm ; /* size n, permutation used */ void *ColCount ; /* size n, column counts for simplicial L */ void *IPerm ; /* size n, inverse permutation. Only created by * cholmod_solve2 if Bset is used. */ /* ---------------------------------------------------------------------- */ /* simplicial factorization */ /* ---------------------------------------------------------------------- */ size_t nzmax ; /* size of i and x */ void *p ; /* p [0..ncol], the column pointers */ void *i ; /* i [0..nzmax-1], the row indices */ void *x ; /* x [0..nzmax-1], the numerical values */ void *z ; void *nz ; /* nz [0..ncol-1], the # of nonzeros in each column. * i [p [j] ... p [j]+nz[j]-1] contains the row indices, * and the numerical values are in the same locatins * in x. The value of i [p [k]] is always k. */ void *next ; /* size ncol+2. next [j] is the next column in i/x */ void *prev ; /* size ncol+2. prev [j] is the prior column in i/x. * head of the list is ncol+1, and the tail is ncol. */ /* ---------------------------------------------------------------------- */ /* supernodal factorization */ /* ---------------------------------------------------------------------- */ /* Note that L->x is shared with the simplicial data structure. L->x has * size L->nzmax for a simplicial factor, and size L->xsize for a supernodal * factor. */ size_t nsuper ; /* number of supernodes */ size_t ssize ; /* size of s, integer part of supernodes */ size_t xsize ; /* size of x, real part of supernodes */ size_t maxcsize ; /* size of largest update matrix */ size_t maxesize ; /* max # of rows in supernodes, excl. triangular part */ void *super ; /* size nsuper+1, first col in each supernode */ void *pi ; /* size nsuper+1, pointers to integer patterns */ void *px ; /* size nsuper+1, pointers to real parts */ void *s ; /* size ssize, integer part of supernodes */ /* ---------------------------------------------------------------------- */ /* factorization type */ /* ---------------------------------------------------------------------- */ int ordering ; /* ordering method used */ int is_ll ; /* TRUE if LL', FALSE if LDL' */ int is_super ; /* TRUE if supernodal, FALSE if simplicial */ int is_monotonic ; /* TRUE if columns of L appear in order 0..n-1. * Only applicable to simplicial numeric types. */ /* There are 8 types of factor objects that cholmod_factor can represent * (only 6 are used): * * Numeric types (xtype is not CHOLMOD_PATTERN) * -------------------------------------------- * * simplicial LDL': (is_ll FALSE, is_super FALSE). Stored in compressed * column form, using the simplicial components above (nzmax, p, i, * x, z, nz, next, and prev). The unit diagonal of L is not stored, * and D is stored in its place. There are no supernodes. * * simplicial LL': (is_ll TRUE, is_super FALSE). Uses the same storage * scheme as the simplicial LDL', except that D does not appear. * The first entry of each column of L is the diagonal entry of * that column of L. * * supernodal LDL': (is_ll FALSE, is_super TRUE). Not used. * FUTURE WORK: add support for supernodal LDL' * * supernodal LL': (is_ll TRUE, is_super TRUE). A supernodal factor, * using the supernodal components described above (nsuper, ssize, * xsize, maxcsize, maxesize, super, pi, px, s, x, and z). * * * Symbolic types (xtype is CHOLMOD_PATTERN) * ----------------------------------------- * * simplicial LDL': (is_ll FALSE, is_super FALSE). Nothing is present * except Perm and ColCount. * * simplicial LL': (is_ll TRUE, is_super FALSE). Identical to the * simplicial LDL', except for the is_ll flag. * * supernodal LDL': (is_ll FALSE, is_super TRUE). Not used. * FUTURE WORK: add support for supernodal LDL' * * supernodal LL': (is_ll TRUE, is_super TRUE). A supernodal symbolic * factorization. The simplicial symbolic information is present * (Perm and ColCount), as is all of the supernodal factorization * except for the numerical values (x and z). */ int itype ; /* The integer arrays are Perm, ColCount, p, i, nz, * next, prev, super, pi, px, and s. If itype is * CHOLMOD_INT, all of these are int arrays. * CHOLMOD_INTLONG: p, pi, px are SuiteSparse_long, others int. * CHOLMOD_LONG: all integer arrays are SuiteSparse_long. */ int xtype ; /* pattern, real, complex, or zomplex */ int dtype ; /* x and z double or float */ int useGPU; /* Indicates the symbolic factorization supports * GPU acceleration */ } cholmod_factor ; /* -------------------------------------------------------------------------- */ /* cholmod_allocate_factor: allocate a factor (symbolic LL' or LDL') */ /* -------------------------------------------------------------------------- */ cholmod_factor *cholmod_allocate_factor ( /* ---- input ---- */ size_t n, /* L is n-by-n */ /* --------------- */ cholmod_common *Common ) ; cholmod_factor *cholmod_l_allocate_factor (size_t, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_free_factor: free a factor */ /* -------------------------------------------------------------------------- */ int cholmod_free_factor ( /* ---- in/out --- */ cholmod_factor **L, /* factor to free, NULL on output */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_free_factor (cholmod_factor **, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_reallocate_factor: change the # entries in a factor */ /* -------------------------------------------------------------------------- */ int cholmod_reallocate_factor ( /* ---- input ---- */ size_t nznew, /* new # of entries in L */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_reallocate_factor (size_t, cholmod_factor *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_change_factor: change the type of factor (e.g., LDL' to LL') */ /* -------------------------------------------------------------------------- */ int cholmod_change_factor ( /* ---- input ---- */ int to_xtype, /* to CHOLMOD_PATTERN, _REAL, _COMPLEX, _ZOMPLEX */ int to_ll, /* TRUE: convert to LL', FALSE: LDL' */ int to_super, /* TRUE: convert to supernodal, FALSE: simplicial */ int to_packed, /* TRUE: pack simplicial columns, FALSE: do not pack */ int to_monotonic, /* TRUE: put simplicial columns in order, FALSE: not */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_change_factor ( int, int, int, int, int, cholmod_factor *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_pack_factor: pack the columns of a factor */ /* -------------------------------------------------------------------------- */ /* Pack the columns of a simplicial factor. Unlike cholmod_change_factor, * it can pack the columns of a factor even if they are not stored in their * natural order (non-monotonic). */ int cholmod_pack_factor ( /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_pack_factor (cholmod_factor *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_reallocate_column: resize a single column of a factor */ /* -------------------------------------------------------------------------- */ int cholmod_reallocate_column ( /* ---- input ---- */ size_t j, /* the column to reallocate */ size_t need, /* required size of column j */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_reallocate_column (size_t, size_t, cholmod_factor *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_factor_to_sparse: create a sparse matrix copy of a factor */ /* -------------------------------------------------------------------------- */ /* Only operates on numeric factors, not symbolic ones */ cholmod_sparse *cholmod_factor_to_sparse ( /* ---- in/out --- */ cholmod_factor *L, /* factor to copy, converted to symbolic on output */ /* --------------- */ cholmod_common *Common ) ; cholmod_sparse *cholmod_l_factor_to_sparse (cholmod_factor *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_copy_factor: create a copy of a factor */ /* -------------------------------------------------------------------------- */ cholmod_factor *cholmod_copy_factor ( /* ---- input ---- */ cholmod_factor *L, /* factor to copy */ /* --------------- */ cholmod_common *Common ) ; cholmod_factor *cholmod_l_copy_factor (cholmod_factor *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_factor_xtype: change the xtype of a factor */ /* -------------------------------------------------------------------------- */ int cholmod_factor_xtype ( /* ---- input ---- */ int to_xtype, /* requested xtype (real, complex, or zomplex) */ /* ---- in/out --- */ cholmod_factor *L, /* factor to change */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_factor_xtype (int, cholmod_factor *, cholmod_common *) ; /* ========================================================================== */ /* === Core/cholmod_dense =================================================== */ /* ========================================================================== */ /* A dense matrix in column-oriented form. It has no itype since it contains * no integers. Entry in row i and column j is located in x [i+j*d]. */ typedef struct cholmod_dense_struct { size_t nrow ; /* the matrix is nrow-by-ncol */ size_t ncol ; size_t nzmax ; /* maximum number of entries in the matrix */ size_t d ; /* leading dimension (d >= nrow must hold) */ void *x ; /* size nzmax or 2*nzmax, if present */ void *z ; /* size nzmax, if present */ int xtype ; /* pattern, real, complex, or zomplex */ int dtype ; /* x and z double or float */ } cholmod_dense ; /* -------------------------------------------------------------------------- */ /* cholmod_allocate_dense: allocate a dense matrix (contents uninitialized) */ /* -------------------------------------------------------------------------- */ cholmod_dense *cholmod_allocate_dense ( /* ---- input ---- */ size_t nrow, /* # of rows of matrix */ size_t ncol, /* # of columns of matrix */ size_t d, /* leading dimension */ int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ /* --------------- */ cholmod_common *Common ) ; cholmod_dense *cholmod_l_allocate_dense (size_t, size_t, size_t, int, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_zeros: allocate a dense matrix and set it to zero */ /* -------------------------------------------------------------------------- */ cholmod_dense *cholmod_zeros ( /* ---- input ---- */ size_t nrow, /* # of rows of matrix */ size_t ncol, /* # of columns of matrix */ int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ /* --------------- */ cholmod_common *Common ) ; cholmod_dense *cholmod_l_zeros (size_t, size_t, int, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_ones: allocate a dense matrix and set it to all ones */ /* -------------------------------------------------------------------------- */ cholmod_dense *cholmod_ones ( /* ---- input ---- */ size_t nrow, /* # of rows of matrix */ size_t ncol, /* # of columns of matrix */ int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ /* --------------- */ cholmod_common *Common ) ; cholmod_dense *cholmod_l_ones (size_t, size_t, int, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_eye: allocate a dense matrix and set it to the identity matrix */ /* -------------------------------------------------------------------------- */ cholmod_dense *cholmod_eye ( /* ---- input ---- */ size_t nrow, /* # of rows of matrix */ size_t ncol, /* # of columns of matrix */ int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ /* --------------- */ cholmod_common *Common ) ; cholmod_dense *cholmod_l_eye (size_t, size_t, int, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_free_dense: free a dense matrix */ /* -------------------------------------------------------------------------- */ int cholmod_free_dense ( /* ---- in/out --- */ cholmod_dense **X, /* dense matrix to deallocate, NULL on output */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_free_dense (cholmod_dense **, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_ensure_dense: ensure a dense matrix has a given size and type */ /* -------------------------------------------------------------------------- */ cholmod_dense *cholmod_ensure_dense ( /* ---- input/output ---- */ cholmod_dense **XHandle, /* matrix handle to check */ /* ---- input ---- */ size_t nrow, /* # of rows of matrix */ size_t ncol, /* # of columns of matrix */ size_t d, /* leading dimension */ int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ /* --------------- */ cholmod_common *Common ) ; cholmod_dense *cholmod_l_ensure_dense (cholmod_dense **, size_t, size_t, size_t, int, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_sparse_to_dense: create a dense matrix copy of a sparse matrix */ /* -------------------------------------------------------------------------- */ cholmod_dense *cholmod_sparse_to_dense ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to copy */ /* --------------- */ cholmod_common *Common ) ; cholmod_dense *cholmod_l_sparse_to_dense (cholmod_sparse *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_dense_to_sparse: create a sparse matrix copy of a dense matrix */ /* -------------------------------------------------------------------------- */ cholmod_sparse *cholmod_dense_to_sparse ( /* ---- input ---- */ cholmod_dense *X, /* matrix to copy */ int values, /* TRUE if values to be copied, FALSE otherwise */ /* --------------- */ cholmod_common *Common ) ; cholmod_sparse *cholmod_l_dense_to_sparse (cholmod_dense *, int, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_copy_dense: create a copy of a dense matrix */ /* -------------------------------------------------------------------------- */ cholmod_dense *cholmod_copy_dense ( /* ---- input ---- */ cholmod_dense *X, /* matrix to copy */ /* --------------- */ cholmod_common *Common ) ; cholmod_dense *cholmod_l_copy_dense (cholmod_dense *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_copy_dense2: copy a dense matrix (pre-allocated) */ /* -------------------------------------------------------------------------- */ int cholmod_copy_dense2 ( /* ---- input ---- */ cholmod_dense *X, /* matrix to copy */ /* ---- output --- */ cholmod_dense *Y, /* copy of matrix X */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_copy_dense2 (cholmod_dense *, cholmod_dense *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_dense_xtype: change the xtype of a dense matrix */ /* -------------------------------------------------------------------------- */ int cholmod_dense_xtype ( /* ---- input ---- */ int to_xtype, /* requested xtype (real, complex,or zomplex) */ /* ---- in/out --- */ cholmod_dense *X, /* dense matrix to change */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_dense_xtype (int, cholmod_dense *, cholmod_common *) ; /* ========================================================================== */ /* === Core/cholmod_triplet ================================================= */ /* ========================================================================== */ /* A sparse matrix stored in triplet form. */ typedef struct cholmod_triplet_struct { size_t nrow ; /* the matrix is nrow-by-ncol */ size_t ncol ; size_t nzmax ; /* maximum number of entries in the matrix */ size_t nnz ; /* number of nonzeros in the matrix */ void *i ; /* i [0..nzmax-1], the row indices */ void *j ; /* j [0..nzmax-1], the column indices */ void *x ; /* size nzmax or 2*nzmax, if present */ void *z ; /* size nzmax, if present */ int stype ; /* Describes what parts of the matrix are considered: * * 0: matrix is "unsymmetric": use both upper and lower triangular parts * (the matrix may actually be symmetric in pattern and value, but * both parts are explicitly stored and used). May be square or * rectangular. * >0: matrix is square and symmetric. Entries in the lower triangular * part are transposed and added to the upper triangular part when * the matrix is converted to cholmod_sparse form. * <0: matrix is square and symmetric. Entries in the upper triangular * part are transposed and added to the lower triangular part when * the matrix is converted to cholmod_sparse form. * * Note that stype>0 and stype<0 are different for cholmod_sparse and * cholmod_triplet. The reason is simple. You can permute a symmetric * triplet matrix by simply replacing a row and column index with their * new row and column indices, via an inverse permutation. Suppose * P = L->Perm is your permutation, and Pinv is an array of size n. * Suppose a symmetric matrix A is represent by a triplet matrix T, with * entries only in the upper triangular part. Then the following code: * * Ti = T->i ; * Tj = T->j ; * for (k = 0 ; k < n ; k++) Pinv [P [k]] = k ; * for (k = 0 ; k < nz ; k++) Ti [k] = Pinv [Ti [k]] ; * for (k = 0 ; k < nz ; k++) Tj [k] = Pinv [Tj [k]] ; * * creates the triplet form of C=P*A*P'. However, if T initially * contains just the upper triangular entries (T->stype = 1), after * permutation it has entries in both the upper and lower triangular * parts. These entries should be transposed when constructing the * cholmod_sparse form of A, which is what cholmod_triplet_to_sparse * does. Thus: * * C = cholmod_triplet_to_sparse (T, 0, &Common) ; * * will return the matrix C = P*A*P'. * * Since the triplet matrix T is so simple to generate, it's quite easy * to remove entries that you do not want, prior to converting T to the * cholmod_sparse form. So if you include these entries in T, CHOLMOD * assumes that there must be a reason (such as the one above). Thus, * no entry in a triplet matrix is ever ignored. */ int itype ; /* CHOLMOD_LONG: i and j are SuiteSparse_long. Otherwise int */ int xtype ; /* pattern, real, complex, or zomplex */ int dtype ; /* x and z are double or float */ } cholmod_triplet ; /* -------------------------------------------------------------------------- */ /* cholmod_allocate_triplet: allocate a triplet matrix */ /* -------------------------------------------------------------------------- */ cholmod_triplet *cholmod_allocate_triplet ( /* ---- input ---- */ size_t nrow, /* # of rows of T */ size_t ncol, /* # of columns of T */ size_t nzmax, /* max # of nonzeros of T */ int stype, /* stype of T */ int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ /* --------------- */ cholmod_common *Common ) ; cholmod_triplet *cholmod_l_allocate_triplet (size_t, size_t, size_t, int, int, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_free_triplet: free a triplet matrix */ /* -------------------------------------------------------------------------- */ int cholmod_free_triplet ( /* ---- in/out --- */ cholmod_triplet **T, /* triplet matrix to deallocate, NULL on output */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_free_triplet (cholmod_triplet **, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_reallocate_triplet: change the # of entries in a triplet matrix */ /* -------------------------------------------------------------------------- */ int cholmod_reallocate_triplet ( /* ---- input ---- */ size_t nznew, /* new # of entries in T */ /* ---- in/out --- */ cholmod_triplet *T, /* triplet matrix to modify */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_reallocate_triplet (size_t, cholmod_triplet *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_sparse_to_triplet: create a triplet matrix copy of a sparse matrix*/ /* -------------------------------------------------------------------------- */ cholmod_triplet *cholmod_sparse_to_triplet ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to copy */ /* --------------- */ cholmod_common *Common ) ; cholmod_triplet *cholmod_l_sparse_to_triplet (cholmod_sparse *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_triplet_to_sparse: create a sparse matrix copy of a triplet matrix*/ /* -------------------------------------------------------------------------- */ cholmod_sparse *cholmod_triplet_to_sparse ( /* ---- input ---- */ cholmod_triplet *T, /* matrix to copy */ size_t nzmax, /* allocate at least this much space in output matrix */ /* --------------- */ cholmod_common *Common ) ; cholmod_sparse *cholmod_l_triplet_to_sparse (cholmod_triplet *, size_t, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_copy_triplet: create a copy of a triplet matrix */ /* -------------------------------------------------------------------------- */ cholmod_triplet *cholmod_copy_triplet ( /* ---- input ---- */ cholmod_triplet *T, /* matrix to copy */ /* --------------- */ cholmod_common *Common ) ; cholmod_triplet *cholmod_l_copy_triplet (cholmod_triplet *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_triplet_xtype: change the xtype of a triplet matrix */ /* -------------------------------------------------------------------------- */ int cholmod_triplet_xtype ( /* ---- input ---- */ int to_xtype, /* requested xtype (pattern, real, complex,or zomplex)*/ /* ---- in/out --- */ cholmod_triplet *T, /* triplet matrix to change */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_triplet_xtype (int, cholmod_triplet *, cholmod_common *) ; /* ========================================================================== */ /* === Core/cholmod_memory ================================================== */ /* ========================================================================== */ /* The user may make use of these, just like malloc and free. You can even * malloc an object and safely free it with cholmod_free, and visa versa * (except that the memory usage statistics will be corrupted). These routines * do differ from malloc and free. If cholmod_free is given a NULL pointer, * for example, it does nothing (unlike the ANSI free). cholmod_realloc does * not return NULL if given a non-NULL pointer and a nonzero size, even if it * fails (it returns the original pointer and sets an error code in * Common->status instead). * * CHOLMOD keeps track of the amount of memory it has allocated, and so the * cholmod_free routine also takes the size of the object being freed. This * is only used for statistics. If you, the user of CHOLMOD, pass the wrong * size, the only consequence is that the memory usage statistics will be * corrupted. */ void *cholmod_malloc /* returns pointer to the newly malloc'd block */ ( /* ---- input ---- */ size_t n, /* number of items */ size_t size, /* size of each item */ /* --------------- */ cholmod_common *Common ) ; void *cholmod_l_malloc (size_t, size_t, cholmod_common *) ; void *cholmod_calloc /* returns pointer to the newly calloc'd block */ ( /* ---- input ---- */ size_t n, /* number of items */ size_t size, /* size of each item */ /* --------------- */ cholmod_common *Common ) ; void *cholmod_l_calloc (size_t, size_t, cholmod_common *) ; void *cholmod_free /* always returns NULL */ ( /* ---- input ---- */ size_t n, /* number of items */ size_t size, /* size of each item */ /* ---- in/out --- */ void *p, /* block of memory to free */ /* --------------- */ cholmod_common *Common ) ; void *cholmod_l_free (size_t, size_t, void *, cholmod_common *) ; void *cholmod_realloc /* returns pointer to reallocated block */ ( /* ---- input ---- */ size_t nnew, /* requested # of items in reallocated block */ size_t size, /* size of each item */ /* ---- in/out --- */ void *p, /* block of memory to realloc */ size_t *n, /* current size on input, nnew on output if successful*/ /* --------------- */ cholmod_common *Common ) ; void *cholmod_l_realloc (size_t, size_t, void *, size_t *, cholmod_common *) ; int cholmod_realloc_multiple ( /* ---- input ---- */ size_t nnew, /* requested # of items in reallocated blocks */ int nint, /* number of int/SuiteSparse_long blocks */ int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ /* ---- in/out --- */ void **Iblock, /* int or SuiteSparse_long block */ void **Jblock, /* int or SuiteSparse_long block */ void **Xblock, /* complex, double, or float block */ void **Zblock, /* zomplex case only: double or float block */ size_t *n, /* current size of the I,J,X,Z blocks on input, * nnew on output if successful */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_realloc_multiple (size_t, int, int, void **, void **, void **, void **, size_t *, cholmod_common *) ; /* ========================================================================== */ /* === version control ====================================================== */ /* ========================================================================== */ int cholmod_version /* returns CHOLMOD_VERSION */ ( /* output, contents not defined on input. Not used if NULL. version [0] = CHOLMOD_MAIN_VERSION version [1] = CHOLMOD_SUB_VERSION version [2] = CHOLMOD_SUBSUB_VERSION */ int version [3] ) ; int cholmod_l_version (int version [3]) ; /* Versions prior to 2.1.1 do not have the above function. The following code fragment will work with any version of CHOLMOD: #ifdef CHOLMOD_HAS_VERSION_FUNCTION v = cholmod_version (NULL) ; #else v = CHOLMOD_VERSION ; #endif */ /* ========================================================================== */ /* === symmetry types ======================================================= */ /* ========================================================================== */ #define CHOLMOD_MM_RECTANGULAR 1 #define CHOLMOD_MM_UNSYMMETRIC 2 #define CHOLMOD_MM_SYMMETRIC 3 #define CHOLMOD_MM_HERMITIAN 4 #define CHOLMOD_MM_SKEW_SYMMETRIC 5 #define CHOLMOD_MM_SYMMETRIC_POSDIAG 6 #define CHOLMOD_MM_HERMITIAN_POSDIAG 7 /* ========================================================================== */ /* === Numerical relop macros =============================================== */ /* ========================================================================== */ /* These macros correctly handle the NaN case. * * CHOLMOD_IS_NAN(x): * True if x is NaN. False otherwise. The commonly-existing isnan(x) * function could be used, but it's not in Kernighan & Ritchie 2nd edition * (ANSI C89). It may appear in , but I'm not certain about * portability. The expression x != x is true if and only if x is NaN, * according to the IEEE 754 floating-point standard. * * CHOLMOD_IS_ZERO(x): * True if x is zero. False if x is nonzero, NaN, or +/- Inf. * This is (x == 0) if the compiler is IEEE 754 compliant. * * CHOLMOD_IS_NONZERO(x): * True if x is nonzero, NaN, or +/- Inf. False if x zero. * This is (x != 0) if the compiler is IEEE 754 compliant. * * CHOLMOD_IS_LT_ZERO(x): * True if x is < zero or -Inf. False if x is >= 0, NaN, or +Inf. * This is (x < 0) if the compiler is IEEE 754 compliant. * * CHOLMOD_IS_GT_ZERO(x): * True if x is > zero or +Inf. False if x is <= 0, NaN, or -Inf. * This is (x > 0) if the compiler is IEEE 754 compliant. * * CHOLMOD_IS_LE_ZERO(x): * True if x is <= zero or -Inf. False if x is > 0, NaN, or +Inf. * This is (x <= 0) if the compiler is IEEE 754 compliant. */ #ifdef CHOLMOD_WINDOWS /* Yes, this is exceedingly ugly. Blame Microsoft, which hopelessly */ /* violates the IEEE 754 floating-point standard in a bizarre way. */ /* If you're using an IEEE 754-compliant compiler, then x != x is true */ /* iff x is NaN. For Microsoft, (x < x) is true iff x is NaN. */ /* So either way, this macro safely detects a NaN. */ #define CHOLMOD_IS_NAN(x) (((x) != (x)) || (((x) < (x)))) #define CHOLMOD_IS_ZERO(x) (((x) == 0.) && !CHOLMOD_IS_NAN(x)) #define CHOLMOD_IS_NONZERO(x) (((x) != 0.) || CHOLMOD_IS_NAN(x)) #define CHOLMOD_IS_LT_ZERO(x) (((x) < 0.) && !CHOLMOD_IS_NAN(x)) #define CHOLMOD_IS_GT_ZERO(x) (((x) > 0.) && !CHOLMOD_IS_NAN(x)) #define CHOLMOD_IS_LE_ZERO(x) (((x) <= 0.) && !CHOLMOD_IS_NAN(x)) #else /* These all work properly, according to the IEEE 754 standard ... except on */ /* a PC with windows. Works fine in Linux on the same PC... */ #define CHOLMOD_IS_NAN(x) ((x) != (x)) #define CHOLMOD_IS_ZERO(x) ((x) == 0.) #define CHOLMOD_IS_NONZERO(x) ((x) != 0.) #define CHOLMOD_IS_LT_ZERO(x) ((x) < 0.) #define CHOLMOD_IS_GT_ZERO(x) ((x) > 0.) #define CHOLMOD_IS_LE_ZERO(x) ((x) <= 0.) #endif #endif ����������������������Matrix/src/CHOLMOD/Include/cholmod_internal.h�������������������������������������������������������0000644�0001762�0000144�00000033065�13652535054�020466� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Include/cholmod_internal.h =========================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Include/cholmod_internal.h. * Copyright (C) 2005-2013, Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* CHOLMOD internal include file. * * This file contains internal definitions for CHOLMOD, not meant to be included * in user code. They define macros that are not prefixed with CHOLMOD_. This * file can safely #include'd in user code if you want to make use of the * macros defined here, and don't mind the possible name conflicts with your * code, however. * * Required by all CHOLMOD routines. Not required by any user routine that * uses CHOLMOMD. Unless debugging is enabled, this file does not require any * CHOLMOD module (not even the Core module). * * If debugging is enabled, all CHOLMOD modules require the Check module. * Enabling debugging requires that this file be editted. Debugging cannot be * enabled with a compiler flag. This is because CHOLMOD is exceedingly slow * when debugging is enabled. Debugging is meant for development of CHOLMOD * itself, not by users of CHOLMOD. */ #ifndef CHOLMOD_INTERNAL_H #define CHOLMOD_INTERNAL_H /* ========================================================================== */ /* === large file I/O ======================================================= */ /* ========================================================================== */ /* Definitions for large file I/O must come before any other #includes. If * this causes problems (may not be portable to all platforms), then compile * CHOLMOD with -DNLARGEFILE. You must do this for MATLAB 6.5 and earlier, * for example. */ #include "cholmod_io64.h" /* ========================================================================== */ /* === debugging and basic includes ========================================= */ /* ========================================================================== */ /* turn off debugging */ #ifndef NDEBUG #define NDEBUG #endif /* Uncomment this line to enable debugging. CHOLMOD will be very slow. #undef NDEBUG */ #ifdef MATLAB_MEX_FILE #include "mex.h" #endif #if !defined(NPRINT) || !defined(NDEBUG) #include #endif #include #include #include #include #include /* ========================================================================== */ /* === basic definitions ==================================================== */ /* ========================================================================== */ /* Some non-conforming compilers insist on defining TRUE and FALSE. */ #undef TRUE #undef FALSE #define TRUE 1 #define FALSE 0 #define BOOLEAN(x) ((x) ? TRUE : FALSE) /* NULL should already be defined, but ensure it is here. */ #ifndef NULL #define NULL ((void *) 0) #endif /* FLIP is a "negation about -1", and is used to mark an integer i that is * normally non-negative. FLIP (EMPTY) is EMPTY. FLIP of a number > EMPTY * is negative, and FLIP of a number < EMTPY is positive. FLIP (FLIP (i)) = i * for all integers i. UNFLIP (i) is >= EMPTY. */ #define EMPTY (-1) #define FLIP(i) (-(i)-2) #define UNFLIP(i) (((i) < EMPTY) ? FLIP (i) : (i)) /* MAX and MIN are not safe to use for NaN's */ #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define MAX3(a,b,c) (((a) > (b)) ? (MAX (a,c)) : (MAX (b,c))) #define MAX4(a,b,c,d) (((a) > (b)) ? (MAX3 (a,c,d)) : (MAX3 (b,c,d))) #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #define IMPLIES(p,q) (!(p) || (q)) /* find the sign: -1 if x < 0, 1 if x > 0, zero otherwise. * Not safe for NaN's */ #define SIGN(x) (((x) < 0) ? (-1) : (((x) > 0) ? 1 : 0)) /* round up an integer x to a multiple of s */ #define ROUNDUP(x,s) ((s) * (((x) + ((s) - 1)) / (s))) #define ERROR(status,msg) \ CHOLMOD(error) (status, __FILE__, __LINE__, msg, Common) /* Check a pointer and return if null. Set status to invalid, unless the * status is already "out of memory" */ #define RETURN_IF_NULL(A,result) \ { \ if ((A) == NULL) \ { \ if (Common->status != CHOLMOD_OUT_OF_MEMORY) \ { \ ERROR (CHOLMOD_INVALID, "argument missing") ; \ } \ return (result) ; \ } \ } /* Return if Common is NULL or invalid */ #define RETURN_IF_NULL_COMMON(result) \ { \ if (Common == NULL) \ { \ return (result) ; \ } \ if (Common->itype != ITYPE || Common->dtype != DTYPE) \ { \ Common->status = CHOLMOD_INVALID ; \ return (result) ; \ } \ } #define IS_NAN(x) CHOLMOD_IS_NAN(x) #define IS_ZERO(x) CHOLMOD_IS_ZERO(x) #define IS_NONZERO(x) CHOLMOD_IS_NONZERO(x) #define IS_LT_ZERO(x) CHOLMOD_IS_LT_ZERO(x) #define IS_GT_ZERO(x) CHOLMOD_IS_GT_ZERO(x) #define IS_LE_ZERO(x) CHOLMOD_IS_LE_ZERO(x) /* 1e308 is a huge number that doesn't take many characters to print in a * file, in CHOLMOD/Check/cholmod_read and _write. Numbers larger than this * are interpretted as Inf, since sscanf doesn't read in Inf's properly. * This assumes IEEE double precision arithmetic. DBL_MAX would be a little * better, except that it takes too many digits to print in a file. */ #define HUGE_DOUBLE 1e308 /* ========================================================================== */ /* === int/long and double/float definitions ================================ */ /* ========================================================================== */ /* CHOLMOD is designed for 3 types of integer variables: * * (1) all integers are int * (2) most integers are int, some are SuiteSparse_long * (3) all integers are SuiteSparse_long * * and two kinds of floating-point values: * * (1) double * (2) float * * the complex types (ANSI-compatible complex, and MATLAB-compatable zomplex) * are based on the double or float type, and are not selected here. They * are typically selected via template routines. * * This gives 6 different modes in which CHOLMOD can be compiled (only the * first two are currently supported): * * DINT double, int prefix: cholmod_ * DLONG double, SuiteSparse_long prefix: cholmod_l_ * DMIX double, mixed int/SuiteSparse_long prefix: cholmod_m_ * SINT float, int prefix: cholmod_si_ * SLONG float, SuiteSparse_long prefix: cholmod_sl_ * SMIX float, mixed int/log prefix: cholmod_sm_ * * These are selected with compile time flags (-DDLONG, for example). If no * flag is selected, the default is DINT. * * All six versions use the same include files. The user-visible include files * are completely independent of which int/long/double/float version is being * used. The integer / real types in all data structures (sparse, triplet, * dense, common, and triplet) are defined at run-time, not compile-time, so * there is only one "cholmod_sparse" data type. Void pointers are used inside * that data structure to point to arrays of the proper type. Each data * structure has an itype and dtype field which determines the kind of basic * types used. These are defined in Include/cholmod_core.h. * * FUTURE WORK: support all six types (float, and mixed int/long) * * SuiteSparse_long is normally defined as long. However, for WIN64 it is * __int64. It can also be redefined for other platforms, by modifying * SuiteSparse_config.h. */ #include "SuiteSparse_config.h" /* -------------------------------------------------------------------------- */ /* Size_max: the largest value of size_t */ /* -------------------------------------------------------------------------- */ #define Size_max ((size_t) (-1)) /* routines for doing arithmetic on size_t, and checking for overflow */ size_t cholmod_add_size_t (size_t a, size_t b, int *ok) ; size_t cholmod_mult_size_t (size_t a, size_t k, int *ok) ; size_t cholmod_l_add_size_t (size_t a, size_t b, int *ok) ; size_t cholmod_l_mult_size_t (size_t a, size_t k, int *ok) ; /* -------------------------------------------------------------------------- */ /* double (also complex double), SuiteSparse_long */ /* -------------------------------------------------------------------------- */ #ifdef DLONG #define Real double #define Int SuiteSparse_long #define Int_max SuiteSparse_long_max #define CHOLMOD(name) cholmod_l_ ## name #define LONG #define DOUBLE #define ITYPE CHOLMOD_LONG #define DTYPE CHOLMOD_DOUBLE #define ID SuiteSparse_long_id /* -------------------------------------------------------------------------- */ /* double (also complex double), int: this is the default */ /* -------------------------------------------------------------------------- */ #else #ifndef DINT #define DINT #endif #define INT #define DOUBLE #define Real double #define Int int #define Int_max INT_MAX #define CHOLMOD(name) cholmod_ ## name #define ITYPE CHOLMOD_INT #define DTYPE CHOLMOD_DOUBLE #define ID "%d" /* GPU acceleration is not available for the int version of CHOLMOD */ #undef GPU_BLAS #endif /* ========================================================================== */ /* === real/complex arithmetic ============================================== */ /* ========================================================================== */ #include "cholmod_complexity.h" /* ========================================================================== */ /* === Architecture and BLAS ================================================ */ /* ========================================================================== */ #define BLAS_OK Common->blas_ok #include "cholmod_blas.h" /* ========================================================================== */ /* === debugging definitions ================================================ */ /* ========================================================================== */ #ifndef NDEBUG #include #include "cholmod.h" /* The cholmod_dump routines are in the Check module. No CHOLMOD routine * calls the cholmod_check_* or cholmod_print_* routines in the Check module, * since they use Common workspace that may already be in use. Instead, they * use the cholmod_dump_* routines defined there, which allocate their own * workspace if they need it. */ #ifndef EXTERN #define EXTERN extern #endif /* double, int */ EXTERN int cholmod_dump ; EXTERN int cholmod_dump_malloc ; SuiteSparse_long cholmod_dump_sparse (cholmod_sparse *, const char *, cholmod_common *) ; int cholmod_dump_factor (cholmod_factor *, const char *, cholmod_common *) ; int cholmod_dump_triplet (cholmod_triplet *, const char *, cholmod_common *) ; int cholmod_dump_dense (cholmod_dense *, const char *, cholmod_common *) ; int cholmod_dump_subset (int *, size_t, size_t, const char *, cholmod_common *) ; int cholmod_dump_perm (int *, size_t, size_t, const char *, cholmod_common *) ; int cholmod_dump_parent (int *, size_t, const char *, cholmod_common *) ; void cholmod_dump_init (const char *, cholmod_common *) ; int cholmod_dump_mem (const char *, SuiteSparse_long, cholmod_common *) ; void cholmod_dump_real (const char *, Real *, SuiteSparse_long, SuiteSparse_long, int, int, cholmod_common *) ; void cholmod_dump_super (SuiteSparse_long, int *, int *, int *, int *, double *, int, cholmod_common *) ; int cholmod_dump_partition (SuiteSparse_long, int *, int *, int *, int *, SuiteSparse_long, cholmod_common *) ; int cholmod_dump_work(int, int, SuiteSparse_long, cholmod_common *) ; /* double, SuiteSparse_long */ EXTERN int cholmod_l_dump ; EXTERN int cholmod_l_dump_malloc ; SuiteSparse_long cholmod_l_dump_sparse (cholmod_sparse *, const char *, cholmod_common *) ; int cholmod_l_dump_factor (cholmod_factor *, const char *, cholmod_common *) ; int cholmod_l_dump_triplet (cholmod_triplet *, const char *, cholmod_common *); int cholmod_l_dump_dense (cholmod_dense *, const char *, cholmod_common *) ; int cholmod_l_dump_subset (SuiteSparse_long *, size_t, size_t, const char *, cholmod_common *) ; int cholmod_l_dump_perm (SuiteSparse_long *, size_t, size_t, const char *, cholmod_common *) ; int cholmod_l_dump_parent (SuiteSparse_long *, size_t, const char *, cholmod_common *) ; void cholmod_l_dump_init (const char *, cholmod_common *) ; int cholmod_l_dump_mem (const char *, SuiteSparse_long, cholmod_common *) ; void cholmod_l_dump_real (const char *, Real *, SuiteSparse_long, SuiteSparse_long, int, int, cholmod_common *) ; void cholmod_l_dump_super (SuiteSparse_long, SuiteSparse_long *, SuiteSparse_long *, SuiteSparse_long *, SuiteSparse_long *, double *, int, cholmod_common *) ; int cholmod_l_dump_partition (SuiteSparse_long, SuiteSparse_long *, SuiteSparse_long *, SuiteSparse_long *, SuiteSparse_long *, SuiteSparse_long, cholmod_common *) ; int cholmod_l_dump_work(int, int, SuiteSparse_long, cholmod_common *) ; #define DEBUG_INIT(s,Common) { CHOLMOD(dump_init)(s, Common) ; } #define ASSERT(expression) (assert (expression)) #define PRK(k,params) \ { \ if (CHOLMOD(dump) >= (k) && SuiteSparse_config.printf_func != NULL) \ { \ (SuiteSparse_config.printf_func) params ; \ } \ } #define PRINT0(params) PRK (0, params) #define PRINT1(params) PRK (1, params) #define PRINT2(params) PRK (2, params) #define PRINT3(params) PRK (3, params) #define PRINTM(params) \ { \ if (CHOLMOD(dump_malloc) > 0) \ { \ printf params ; \ } \ } #define DEBUG(statement) statement #else /* Debugging disabled (the normal case) */ #define PRK(k,params) #define DEBUG_INIT(s,Common) #define PRINT0(params) #define PRINT1(params) #define PRINT2(params) #define PRINT3(params) #define PRINTM(params) #define ASSERT(expression) #define DEBUG(statement) #endif #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Include/cholmod_camd.h�����������������������������������������������������������0000644�0001762�0000144�00000006622�13652535054�017555� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Include/cholmod_camd.h =============================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Include/cholmod_camd.h. * Copyright (C) 2005-2013, Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* CHOLMOD Partition module, interface to CAMD, CCOLAMD, and CSYMAMD * * An interface to CCOLAMD and CSYMAMD, constrained minimum degree ordering * methods which order a matrix following constraints determined via nested * dissection. * * These functions do not require METIS. They are installed unless NCAMD * is defined: * cholmod_ccolamd interface to CCOLAMD ordering * cholmod_csymamd interface to CSYMAMD ordering * cholmod_camd interface to CAMD ordering * * Requires the Core and Cholesky modules, and two packages: CAMD, * and CCOLAMD. Used by functions in the Partition Module. */ #ifndef CHOLMOD_CAMD_H #define CHOLMOD_CAMD_H #include "cholmod_core.h" /* -------------------------------------------------------------------------- */ /* cholmod_ccolamd */ /* -------------------------------------------------------------------------- */ /* Order AA' or A(:,f)*A(:,f)' using CCOLAMD. */ int cholmod_ccolamd ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to order */ int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ int *Cmember, /* size A->nrow. Cmember [i] = c if row i is in the * constraint set c. c must be >= 0. The # of * constraint sets is max (Cmember) + 1. If Cmember is * NULL, then it is interpretted as Cmember [i] = 0 for * all i */ /* ---- output --- */ int *Perm, /* size A->nrow, output permutation */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_ccolamd (cholmod_sparse *, SuiteSparse_long *, size_t, SuiteSparse_long *, SuiteSparse_long *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_csymamd */ /* -------------------------------------------------------------------------- */ /* Order A using CSYMAMD. */ int cholmod_csymamd ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to order */ /* ---- output --- */ int *Cmember, /* size nrow. see cholmod_ccolamd above */ int *Perm, /* size A->nrow, output permutation */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_csymamd (cholmod_sparse *, SuiteSparse_long *, SuiteSparse_long *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_camd */ /* -------------------------------------------------------------------------- */ /* Order A using CAMD. */ int cholmod_camd ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to order */ int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ /* ---- output --- */ int *Cmember, /* size nrow. see cholmod_ccolamd above */ int *Perm, /* size A->nrow, output permutation */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_camd (cholmod_sparse *, SuiteSparse_long *, size_t, SuiteSparse_long *, SuiteSparse_long *, cholmod_common *) ; #endif ��������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Include/README.txt���������������������������������������������������������������0000644�0001762�0000144�00000002405�11770402705�016457� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CHOLMOD: a sparse Cholesky factorization package. http://www.suitesparse.com The Include/*.h files in this directory provide a basic documentation of all user-callable routines and user-visible data structures in the CHOLMOD package. Start with cholmod.h, which describes the general structure of the parameter lists of CHOLMOD routines. cholmod_core.h describes the data structures and basic operations on them (creating and deleting them). cholmod.h single include file for all user programs cholmod_config.h CHOLMOD compile-time configuration cholmod_core.h Core module: data structures and basic support routines cholmod_check.h Check module: check/print CHOLMOD data structures cholmod_cholesky.h Cholesky module: LL' and LDL' factorization cholmod_matrixops.h MatrixOps module: sparse matrix operators (add, mult,..) cholmod_modify.h Modify module: update/downdate/... cholmod_partition.h Partition module: nested dissection ordering cholmod_supernodal.h Supernodal module: supernodal Cholesky These include files are not used in user programs, but in CHOLMOD only: cholmod_blas.h BLAS definitions cholmod_complexity.h complex arithmetic cholmod_template.h complex arithmetic for template routines cholmod_internal.h internal definitions, not visible to user program �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Include/cholmod.h����������������������������������������������������������������0000644�0001762�0000144�00000007202�13652535054�016564� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Include/cholmod.h ==================================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Include/cholmod.h. * Copyright (C) 2005-2013, Univ. of Florida. Author: Timothy A. Davis * http://www.suitesparse.com * * Portions of CHOLMOD (the Core and Partition Modules) are copyrighted by the * University of Florida. The Modify Module is co-authored by William W. * Hager, Univ. of Florida. * * Acknowledgements: this work was supported in part by the National Science * Foundation (NFS CCR-0203270 and DMS-9803599), and a grant from Sandia * National Laboratories (Dept. of Energy) which supported the development of * CHOLMOD's Partition Module. * -------------------------------------------------------------------------- */ /* CHOLMOD include file, for inclusion user programs. * * The include files listed below include a short description of each user- * callable routine. Each routine in CHOLMOD has a consistent interface. * More details about the CHOLMOD data types is in the cholmod_core.h file. * * Naming convention: * ------------------ * * All routine names, data types, and CHOLMOD library files use the * cholmod_ prefix. All macros and other #define's use the CHOLMOD * prefix. * * Return value: * ------------- * * Most CHOLMOD routines return an int (TRUE (1) if successful, or FALSE * (0) otherwise. A SuiteSparse_long or double return value is >= 0 if * successful, or -1 otherwise. A size_t return value is > 0 if * successful, or 0 otherwise. * * If a routine returns a pointer, it is a pointer to a newly allocated * object or NULL if a failure occured, with one exception. cholmod_free * always returns NULL. * * "Common" parameter: * ------------------ * * The last parameter in all CHOLMOD routines is a pointer to the CHOLMOD * "Common" object. This contains control parameters, statistics, and * workspace used between calls to CHOLMOD. It is always an input/output * parameter. * * Input, Output, and Input/Output parameters: * ------------------------------------------- * * Input parameters are listed first. They are not modified by CHOLMOD. * * Input/output are listed next. They must be defined on input, and * are modified on output. * * Output parameters are listed next. If they are pointers, they must * point to allocated space on input, but their contents are not defined * on input. * * Workspace parameters appear next. They are used in only two routines * in the Supernodal module. * * The cholmod_common *Common parameter always appears as the last * parameter. It is always an input/output parameter. */ #ifndef CHOLMOD_H #define CHOLMOD_H /* make it easy for C++ programs to include CHOLMOD */ #ifdef __cplusplus extern "C" { #endif /* assume large file support. If problems occur, compile with -DNLARGEFILE */ #include "cholmod_io64.h" #include "SuiteSparse_config.h" #include "cholmod_config.h" /* CHOLMOD always includes the Core module. */ #include "cholmod_core.h" #ifndef NCHECK #include "cholmod_check.h" #endif #ifndef NCHOLESKY #include "cholmod_cholesky.h" #endif #ifndef NMATRIXOPS #include "cholmod_matrixops.h" #endif #ifndef NMODIFY #include "cholmod_modify.h" #endif #ifndef NCAMD #include "cholmod_camd.h" #endif #ifndef NPARTITION #include "cholmod_partition.h" #endif #ifndef NSUPERNODAL #include "cholmod_supernodal.h" #endif #ifdef GPU_BLAS #include "cholmod_gpu.h" #endif #ifdef __cplusplus } #endif #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Include/cholmod_io64.h�����������������������������������������������������������0000644�0001762�0000144�00000002632�13652535054�017427� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Include/cholmod_io64 ================================================= */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Include/cholmod_io64.h. * Copyright (C) 2005-2006, Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* Definitions required for large file I/O, which must come before any other * #includes. These are not used if -DNLARGEFILE is defined at compile time. * Large file support may not be portable across all platforms and compilers; * if you encounter an error here, compile your code with -DNLARGEFILE. In * particular, you must use -DNLARGEFILE for MATLAB 6.5 or earlier (which does * not have the io64.h include file). */ #ifndef CHOLMOD_IO_H #define CHOLMOD_IO_H /* skip all of this if NLARGEFILE is defined at the compiler command line */ #ifndef NLARGEFILE #if defined(MATLAB_MEX_FILE) || defined(MATHWORKS) /* CHOLMOD is being compiled as a MATLAB mexFunction, or for use in MATLAB */ #include "io64.h" #else /* CHOLMOD is being compiled in a stand-alone library */ #undef _LARGEFILE64_SOURCE #define _LARGEFILE64_SOURCE #undef _FILE_OFFSET_BITS #define _FILE_OFFSET_BITS 64 #endif #endif #endif ������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Include/cholmod_template.h�������������������������������������������������������0000644�0001762�0000144�00000022456�13652535054�020467� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Include/cholmod_template.h =========================================== */ /* ========================================================================== */ /* -------------------------------------------------------------------------- */ /* undefine current xtype macros, and then define macros for current type */ /* -------------------------------------------------------------------------- */ #undef TEMPLATE #undef TEMPLATE2 #undef XTYPE #undef XTYPE2 #undef XTYPE_OK #undef ENTRY_IS_NONZERO #undef ENTRY_IS_ZERO #undef ENTRY_IS_ONE #undef IMAG_IS_NONZERO #undef ASSEMBLE #undef ASSIGN #undef ASSIGN_CONJ #undef ASSIGN2 #undef ASSIGN2_CONJ #undef ASSIGN_REAL #undef MULT #undef MULTADD #undef ADD #undef ADD_REAL #undef MULTSUB #undef MULTADDCONJ #undef MULTSUBCONJ #undef LLDOT #undef CLEAR #undef DIV #undef DIV_REAL #undef MULT_REAL #undef CLEAR_IMAG #undef LDLDOT #undef PREFIX #undef ENTRY_SIZE #undef XPRINT0 #undef XPRINT1 #undef XPRINT2 #undef XPRINT3 /* -------------------------------------------------------------------------- */ /* pattern */ /* -------------------------------------------------------------------------- */ #ifdef PATTERN #define PREFIX p_ #define TEMPLATE(name) P_TEMPLATE(name) #define TEMPLATE2(name) P_TEMPLATE(name) #define XTYPE CHOLMOD_PATTERN #define XTYPE2 CHOLMOD_REAL #define XTYPE_OK(type) (TRUE) #define ENTRY_IS_NONZERO(ax,az,q) (TRUE) #define ENTRY_IS_ZERO(ax,az,q) (FALSE) #define ENTRY_IS_ONE(ax,az,q) (TRUE) #define IMAG_IS_NONZERO(ax,az,q) (FALSE) #define ENTRY_SIZE 0 #define ASSEMBLE(x,z,p,ax,az,q) #define ASSIGN(x,z,p,ax,az,q) #define ASSIGN_CONJ(x,z,p,ax,az,q) #define ASSIGN2(x,z,p,ax,az,q) P_ASSIGN2(x,z,p,ax,az,q) #define ASSIGN2_CONJ(x,z,p,ax,az,q) P_ASSIGN2(x,z,p,ax,az,q) #define ASSIGN_REAL(x,p,ax,q) #define MULT(x,z,p,ax,az,q,bx,bz,pb) #define MULTADD(x,z,p,ax,az,q,bx,bz,pb) #define ADD(x,z,p,ax,az,q,bx,bz,pb) #define ADD_REAL(x,p, ax,q, bx,r) #define MULTSUB(x,z,p,ax,az,q,bx,bz,pb) #define MULTADDCONJ(x,z,p,ax,az,q,bx,bz,pb) #define MULTSUBCONJ(x,z,p,ax,az,q,bx,bz,pb) #define LLDOT(x,p,ax,az,q) #define CLEAR(x,z,p) #define CLEAR_IMAG(x,z,p) #define DIV(x,z,p,ax,az,q) #define DIV_REAL(x,z,p, ax,az,q, bx,r) #define MULT_REAL(x,z,p, ax,az,q, bx,r) #define LDLDOT(x,p, ax,az,q, bx,r) #define XPRINT0(x,z,p) P_PRINT(0,x,z,p) #define XPRINT1(x,z,p) P_PRINT(1,x,z,p) #define XPRINT2(x,z,p) P_PRINT(2,x,z,p) #define XPRINT3(x,z,p) P_PRINT(3,x,z,p) /* -------------------------------------------------------------------------- */ /* real */ /* -------------------------------------------------------------------------- */ #elif defined (REAL) #define PREFIX r_ #define TEMPLATE(name) R_TEMPLATE(name) #define TEMPLATE2(name) R_TEMPLATE(name) #define XTYPE CHOLMOD_REAL #define XTYPE2 CHOLMOD_REAL #define XTYPE_OK(type) R_XTYPE_OK(type) #define ENTRY_IS_NONZERO(ax,az,q) R_IS_NONZERO(ax,az,q) #define ENTRY_IS_ZERO(ax,az,q) R_IS_ZERO(ax,az,q) #define ENTRY_IS_ONE(ax,az,q) R_IS_ONE(ax,az,q) #define IMAG_IS_NONZERO(ax,az,q) (FALSE) #define ENTRY_SIZE 1 #define ASSEMBLE(x,z,p,ax,az,q) R_ASSEMBLE(x,z,p,ax,az,q) #define ASSIGN(x,z,p,ax,az,q) R_ASSIGN(x,z,p,ax,az,q) #define ASSIGN_CONJ(x,z,p,ax,az,q) R_ASSIGN(x,z,p,ax,az,q) #define ASSIGN2(x,z,p,ax,az,q) R_ASSIGN(x,z,p,ax,az,q) #define ASSIGN2_CONJ(x,z,p,ax,az,q) R_ASSIGN(x,z,p,ax,az,q) #define ASSIGN_REAL(x,p,ax,q) R_ASSIGN_REAL(x,p,ax,q) #define MULT(x,z,p,ax,az,q,bx,bz,pb) R_MULT(x,z,p,ax,az,q,bx,bz,pb) #define MULTADD(x,z,p,ax,az,q,bx,bz,pb) R_MULTADD(x,z,p,ax,az,q,bx,bz,pb) #define ADD(x,z,p,ax,az,q,bx,bz,pb) R_ADD(x,z,p,ax,az,q,bx,bz,pb) #define ADD_REAL(x,p, ax,q, bx,r) R_ADD_REAL(x,p, ax,q, bx,r) #define MULTSUB(x,z,p,ax,az,q,bx,bz,pb) R_MULTSUB(x,z,p,ax,az,q,bx,bz,pb) #define MULTADDCONJ(x,z,p,ax,az,q,bx,bz,pb) \ R_MULTADDCONJ(x,z,p,ax,az,q,bx,bz,pb) #define MULTSUBCONJ(x,z,p,ax,az,q,bx,bz,pb) \ R_MULTSUBCONJ(x,z,p,ax,az,q,bx,bz,pb) #define LLDOT(x,p,ax,az,q) R_LLDOT(x,p,ax,az,q) #define CLEAR(x,z,p) R_CLEAR(x,z,p) #define CLEAR_IMAG(x,z,p) R_CLEAR_IMAG(x,z,p) #define DIV(x,z,p,ax,az,q) R_DIV(x,z,p,ax,az,q) #define DIV_REAL(x,z,p, ax,az,q, bx,r) R_DIV_REAL(x,z,p, ax,az,q, bx,r) #define MULT_REAL(x,z,p, ax,az,q, bx,r) R_MULT_REAL(x,z,p, ax,az,q, bx,r) #define LDLDOT(x,p, ax,az,q, bx,r) R_LDLDOT(x,p, ax,az,q, bx,r) #define XPRINT0(x,z,p) R_PRINT(0,x,z,p) #define XPRINT1(x,z,p) R_PRINT(1,x,z,p) #define XPRINT2(x,z,p) R_PRINT(2,x,z,p) #define XPRINT3(x,z,p) R_PRINT(3,x,z,p) /* -------------------------------------------------------------------------- */ /* complex */ /* -------------------------------------------------------------------------- */ #elif defined (COMPLEX) #define PREFIX c_ #ifdef NCONJUGATE #define TEMPLATE(name) CT_TEMPLATE(name) #define TEMPLATE2(name) CT_TEMPLATE(name) #else #define TEMPLATE(name) C_TEMPLATE(name) #define TEMPLATE2(name) C_TEMPLATE(name) #endif #define ASSEMBLE(x,z,p,ax,az,q) C_ASSEMBLE(x,z,p,ax,az,q) #define ASSIGN(x,z,p,ax,az,q) C_ASSIGN(x,z,p,ax,az,q) #define ASSIGN_CONJ(x,z,p,ax,az,q) C_ASSIGN_CONJ(x,z,p,ax,az,q) #define ASSIGN2(x,z,p,ax,az,q) C_ASSIGN(x,z,p,ax,az,q) #define ASSIGN2_CONJ(x,z,p,ax,az,q) C_ASSIGN_CONJ(x,z,p,ax,az,q) #define ASSIGN_REAL(x,p,ax,q) C_ASSIGN_REAL(x,p,ax,q) #define XTYPE CHOLMOD_COMPLEX #define XTYPE2 CHOLMOD_COMPLEX #define XTYPE_OK(type) C_XTYPE_OK(type) #define ENTRY_IS_NONZERO(ax,az,q) C_IS_NONZERO(ax,az,q) #define ENTRY_IS_ZERO(ax,az,q) C_IS_ZERO(ax,az,q) #define ENTRY_IS_ONE(ax,az,q) C_IS_ONE(ax,az,q) #define IMAG_IS_NONZERO(ax,az,q) C_IMAG_IS_NONZERO(ax,az,q) #define ENTRY_SIZE 2 #define MULTADD(x,z,p,ax,az,q,bx,bz,pb) C_MULTADD(x,z,p,ax,az,q,bx,bz,pb) #define MULT(x,z,p,ax,az,q,bx,bz,pb) C_MULT(x,z,p,ax,az,q,bx,bz,pb) #define ADD(x,z,p,ax,az,q,bx,bz,pb) C_ADD(x,z,p,ax,az,q,bx,bz,pb) #define ADD_REAL(x,p, ax,q, bx,r) C_ADD_REAL(x,p, ax,q, bx,r) #define MULTSUB(x,z,p,ax,az,q,bx,bz,pb) C_MULTSUB(x,z,p,ax,az,q,bx,bz,pb) #define MULTADDCONJ(x,z,p,ax,az,q,bx,bz,pb) \ C_MULTADDCONJ(x,z,p,ax,az,q,bx,bz,pb) #define MULTSUBCONJ(x,z,p,ax,az,q,bx,bz,pb) \ C_MULTSUBCONJ(x,z,p,ax,az,q,bx,bz,pb) #define LLDOT(x,p,ax,az,q) C_LLDOT(x,p,ax,az,q) #define CLEAR(x,z,p) C_CLEAR(x,z,p) #define CLEAR_IMAG(x,z,p) C_CLEAR_IMAG(x,z,p) #define DIV(x,z,p,ax,az,q) C_DIV(x,z,p,ax,az,q) #define DIV_REAL(x,z,p, ax,az,q, bx,r) C_DIV_REAL(x,z,p, ax,az,q, bx,r) #define MULT_REAL(x,z,p, ax,az,q, bx,r) C_MULT_REAL(x,z,p, ax,az,q, bx,r) #define LDLDOT(x,p, ax,az,q, bx,r) C_LDLDOT(x,p, ax,az,q, bx,r) #define XPRINT0(x,z,p) C_PRINT(0,x,z,p) #define XPRINT1(x,z,p) C_PRINT(1,x,z,p) #define XPRINT2(x,z,p) C_PRINT(2,x,z,p) #define XPRINT3(x,z,p) C_PRINT(3,x,z,p) /* -------------------------------------------------------------------------- */ /* zomplex */ /* -------------------------------------------------------------------------- */ #elif defined (ZOMPLEX) #define PREFIX z_ #ifdef NCONJUGATE #define TEMPLATE(name) ZT_TEMPLATE(name) #define TEMPLATE2(name) CT_TEMPLATE(name) #else #define TEMPLATE(name) Z_TEMPLATE(name) #define TEMPLATE2(name) C_TEMPLATE(name) #endif #define ASSEMBLE(x,z,p,ax,az,q) Z_ASSEMBLE(x,z,p,ax,az,q) #define ASSIGN(x,z,p,ax,az,q) Z_ASSIGN(x,z,p,ax,az,q) #define ASSIGN_CONJ(x,z,p,ax,az,q) Z_ASSIGN_CONJ(x,z,p,ax,az,q) #define ASSIGN2(x,z,p,ax,az,q) Z_ASSIGN(x,z,p,ax,az,q) #define ASSIGN2_CONJ(x,z,p,ax,az,q) Z_ASSIGN_CONJ(x,z,p,ax,az,q) #define ASSIGN_REAL(x,p,ax,q) Z_ASSIGN_REAL(x,p,ax,q) #define XTYPE CHOLMOD_ZOMPLEX #define XTYPE2 CHOLMOD_ZOMPLEX #define XTYPE_OK(type) Z_XTYPE_OK(type) #define ENTRY_IS_NONZERO(ax,az,q) Z_IS_NONZERO(ax,az,q) #define ENTRY_IS_ZERO(ax,az,q) Z_IS_ZERO(ax,az,q) #define ENTRY_IS_ONE(ax,az,q) Z_IS_ONE(ax,az,q) #define IMAG_IS_NONZERO(ax,az,q) Z_IMAG_IS_NONZERO(ax,az,q) #define ENTRY_SIZE 1 #define MULTADD(x,z,p,ax,az,q,bx,bz,pb) Z_MULTADD(x,z,p,ax,az,q,bx,bz,pb) #define MULT(x,z,p,ax,az,q,bx,bz,pb) Z_MULT(x,z,p,ax,az,q,bx,bz,pb) #define ADD(x,z,p,ax,az,q,bx,bz,pb) Z_ADD(x,z,p,ax,az,q,bx,bz,pb) #define ADD_REAL(x,p, ax,q, bx,r) Z_ADD_REAL(x,p, ax,q, bx,r) #define MULTSUB(x,z,p,ax,az,q,bx,bz,pb) Z_MULTSUB(x,z,p,ax,az,q,bx,bz,pb) #define MULTADDCONJ(x,z,p,ax,az,q,bx,bz,pb) \ Z_MULTADDCONJ(x,z,p,ax,az,q,bx,bz,pb) #define MULTSUBCONJ(x,z,p,ax,az,q,bx,bz,pb) \ Z_MULTSUBCONJ(x,z,p,ax,az,q,bx,bz,pb) #define LLDOT(x,p,ax,az,q) Z_LLDOT(x,p,ax,az,q) #define CLEAR(x,z,p) Z_CLEAR(x,z,p) #define CLEAR_IMAG(x,z,p) Z_CLEAR_IMAG(x,z,p) #define DIV(x,z,p,ax,az,q) Z_DIV(x,z,p,ax,az,q) #define DIV_REAL(x,z,p, ax,az,q, bx,r) Z_DIV_REAL(x,z,p, ax,az,q, bx,r) #define MULT_REAL(x,z,p, ax,az,q, bx,r) Z_MULT_REAL(x,z,p, ax,az,q, bx,r) #define LDLDOT(x,p, ax,az,q, bx,r) Z_LDLDOT(x,p, ax,az,q, bx,r) #define XPRINT0(x,z,p) Z_PRINT(0,x,z,p) #define XPRINT1(x,z,p) Z_PRINT(1,x,z,p) #define XPRINT2(x,z,p) Z_PRINT(2,x,z,p) #define XPRINT3(x,z,p) Z_PRINT(3,x,z,p) #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Include/cholmod_supernodal.h�����������������������������������������������������0000644�0001762�0000144�00000014120�14406303520�021002� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Include/cholmod_supernodal.h ========================================= */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Include/cholmod_supernodal.h. * Copyright (C) 2005-2006, Timothy A. Davis * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* CHOLMOD Supernodal module. * * Supernodal analysis, factorization, and solve. The simplest way to use * these routines is via the Cholesky module. It does not provide any * fill-reducing orderings, but does accept the orderings computed by the * Cholesky module. It does not require the Cholesky module itself, however. * * Primary routines: * ----------------- * cholmod_super_symbolic supernodal symbolic analysis * cholmod_super_numeric supernodal numeric factorization * cholmod_super_lsolve supernodal Lx=b solve * cholmod_super_ltsolve supernodal L'x=b solve * * Prototypes for the BLAS and LAPACK routines that CHOLMOD uses are listed * below, including how they are used in CHOLMOD. * * BLAS routines: * -------------- * dtrsv solve Lx=b or L'x=b, L non-unit diagonal, x and b stride-1 * dtrsm solve LX=B or L'X=b, L non-unit diagonal * dgemv y=y-A*x or y=y-A'*x (x and y stride-1) * dgemm C=A*B', C=C-A*B, or C=C-A'*B * dsyrk C=tril(A*A') * * LAPACK routines: * ---------------- * dpotrf LAPACK: A=chol(tril(A)) * * Requires the Core module, and two external packages: LAPACK and the BLAS. * Optionally used by the Cholesky module. */ #ifndef CHOLMOD_SUPERNODAL_H #define CHOLMOD_SUPERNODAL_H #include "cholmod_core.h" /* -------------------------------------------------------------------------- */ /* cholmod_super_symbolic */ /* -------------------------------------------------------------------------- */ /* Analyzes A, AA', or A(:,f)*A(:,f)' in preparation for a supernodal numeric * factorization. The user need not call this directly; cholmod_analyze is * a "simple" wrapper for this routine. */ int cholmod_super_symbolic ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to analyze */ cholmod_sparse *F, /* F = A' or A(:,f)' */ int *Parent, /* elimination tree */ /* ---- in/out --- */ cholmod_factor *L, /* simplicial symbolic on input, * supernodal symbolic on output */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_super_symbolic (cholmod_sparse *, cholmod_sparse *, SuiteSparse_long *, cholmod_factor *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_super_symbolic2 */ /* -------------------------------------------------------------------------- */ /* Analyze for supernodal Cholesky or multifrontal QR */ int cholmod_super_symbolic2 ( /* ---- input ---- */ int for_whom, /* FOR_SPQR (0): for SPQR but not GPU-accelerated FOR_CHOLESKY (1): for Cholesky (GPU or not) FOR_SPQRGPU (2): for SPQR with GPU acceleration */ cholmod_sparse *A, /* matrix to analyze */ cholmod_sparse *F, /* F = A' or A(:,f)' */ int *Parent, /* elimination tree */ /* ---- in/out --- */ cholmod_factor *L, /* simplicial symbolic on input, * supernodal symbolic on output */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_super_symbolic2 (int, cholmod_sparse *, cholmod_sparse *, SuiteSparse_long *, cholmod_factor *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_super_numeric */ /* -------------------------------------------------------------------------- */ /* Computes the numeric LL' factorization of A, AA', or A(:,f)*A(:,f)' using * a BLAS-based supernodal method. The user need not call this directly; * cholmod_factorize is a "simple" wrapper for this routine. */ int cholmod_super_numeric ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to factorize */ cholmod_sparse *F, /* F = A' or A(:,f)' */ double beta [2], /* beta*I is added to diagonal of matrix to factorize */ /* ---- in/out --- */ cholmod_factor *L, /* factorization */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_super_numeric (cholmod_sparse *, cholmod_sparse *, double [2], cholmod_factor *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_super_lsolve */ /* -------------------------------------------------------------------------- */ /* Solve Lx=b where L is from a supernodal numeric factorization. The user * need not call this routine directly. cholmod_solve is a "simple" wrapper * for this routine. */ int cholmod_super_lsolve ( /* ---- input ---- */ cholmod_factor *L, /* factor to use for the forward solve */ /* ---- output ---- */ cholmod_dense *X, /* b on input, solution to Lx=b on output */ /* ---- workspace */ cholmod_dense *E, /* workspace of size nrhs*(L->maxesize) */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_super_lsolve (cholmod_factor *, cholmod_dense *, cholmod_dense *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_super_ltsolve */ /* -------------------------------------------------------------------------- */ /* Solve L'x=b where L is from a supernodal numeric factorization. The user * need not call this routine directly. cholmod_solve is a "simple" wrapper * for this routine. */ int cholmod_super_ltsolve ( /* ---- input ---- */ cholmod_factor *L, /* factor to use for the backsolve */ /* ---- output ---- */ cholmod_dense *X, /* b on input, solution to L'x=b on output */ /* ---- workspace */ cholmod_dense *E, /* workspace of size nrhs*(L->maxesize) */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_super_ltsolve (cholmod_factor *, cholmod_dense *, cholmod_dense *, cholmod_common *) ; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Include/cholmod_cholesky.h�������������������������������������������������������0000644�0001762�0000144�00000054702�14406303520�020461� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Include/cholmod_cholesky.h =========================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Include/cholmod_cholesky.h. Copyright (C) 2005-2013, Timothy A. Davis * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* CHOLMOD Cholesky module. * * Sparse Cholesky routines: analysis, factorization, and solve. * * The primary routines are all that a user requires to order, analyze, and * factorize a sparse symmetric positive definite matrix A (or A*A'), and * to solve Ax=b (or A*A'x=b). The primary routines rely on the secondary * routines, the CHOLMOD Core module, and the AMD and COLAMD packages. They * make optional use of the CHOLMOD Supernodal and Partition modules, the * METIS package, and the CCOLAMD package. * * Primary routines: * ----------------- * * cholmod_analyze order and analyze (simplicial or supernodal) * cholmod_factorize simplicial or supernodal Cholesky factorization * cholmod_solve solve a linear system (simplicial or supernodal) * cholmod_solve2 like cholmod_solve, but reuse workspace * cholmod_spsolve solve a linear system (sparse x and b) * * Secondary routines: * ------------------ * * cholmod_analyze_p analyze, with user-provided permutation or f set * cholmod_factorize_p factorize, with user-provided permutation or f * cholmod_analyze_ordering analyze a fill-reducing ordering * cholmod_etree find the elimination tree * cholmod_rowcolcounts compute the row/column counts of L * cholmod_amd order using AMD * cholmod_colamd order using COLAMD * cholmod_rowfac incremental simplicial factorization * cholmod_rowfac_mask rowfac, specific to LPDASA * cholmod_rowfac_mask2 rowfac, specific to LPDASA * cholmod_row_subtree find the nonzero pattern of a row of L * cholmod_resymbol recompute the symbolic pattern of L * cholmod_resymbol_noperm recompute the symbolic pattern of L, no L->Perm * cholmod_postorder postorder a tree * * Requires the Core module, and two packages: AMD and COLAMD. * Optionally uses the Supernodal and Partition modules. * Required by the Partition module. */ #ifndef CHOLMOD_CHOLESKY_H #define CHOLMOD_CHOLESKY_H #include "cholmod_config.h" #include "cholmod_core.h" #ifndef NPARTITION #include "cholmod_partition.h" #endif #ifndef NSUPERNODAL #include "cholmod_supernodal.h" #endif /* -------------------------------------------------------------------------- */ /* cholmod_analyze: order and analyze (simplicial or supernodal) */ /* -------------------------------------------------------------------------- */ /* Orders and analyzes A, AA', PAP', or PAA'P' and returns a symbolic factor * that can later be passed to cholmod_factorize. */ cholmod_factor *cholmod_analyze ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to order and analyze */ /* --------------- */ cholmod_common *Common ) ; cholmod_factor *cholmod_l_analyze (cholmod_sparse *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_analyze_p: analyze, with user-provided permutation or f set */ /* -------------------------------------------------------------------------- */ /* Orders and analyzes A, AA', PAP', PAA'P', FF', or PFF'P and returns a * symbolic factor that can later be passed to cholmod_factorize, where * F = A(:,fset) if fset is not NULL and A->stype is zero. * UserPerm is tried if non-NULL. */ cholmod_factor *cholmod_analyze_p ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to order and analyze */ int *UserPerm, /* user-provided permutation, size A->nrow */ int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ /* --------------- */ cholmod_common *Common ) ; cholmod_factor *cholmod_l_analyze_p (cholmod_sparse *, SuiteSparse_long *, SuiteSparse_long *, size_t, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_analyze_p2: analyze for sparse Cholesky or sparse QR */ /* -------------------------------------------------------------------------- */ cholmod_factor *cholmod_analyze_p2 ( /* ---- input ---- */ int for_whom, /* FOR_SPQR (0): for SPQR but not GPU-accelerated FOR_CHOLESKY (1): for Cholesky (GPU or not) FOR_SPQRGPU (2): for SPQR with GPU acceleration */ cholmod_sparse *A, /* matrix to order and analyze */ int *UserPerm, /* user-provided permutation, size A->nrow */ int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ /* --------------- */ cholmod_common *Common ) ; cholmod_factor *cholmod_l_analyze_p2 (int, cholmod_sparse *, SuiteSparse_long *, SuiteSparse_long *, size_t, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_factorize: simplicial or supernodal Cholesky factorization */ /* -------------------------------------------------------------------------- */ /* Factorizes PAP' (or PAA'P' if A->stype is 0), using a factor obtained * from cholmod_analyze. The analysis can be re-used simply by calling this * routine a second time with another matrix. A must have the same nonzero * pattern as that passed to cholmod_analyze. */ int cholmod_factorize ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to factorize */ /* ---- in/out --- */ cholmod_factor *L, /* resulting factorization */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_factorize (cholmod_sparse *, cholmod_factor *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_factorize_p: factorize, with user-provided permutation or fset */ /* -------------------------------------------------------------------------- */ /* Same as cholmod_factorize, but with more options. */ int cholmod_factorize_p ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to factorize */ double beta [2], /* factorize beta*I+A or beta*I+A'*A */ int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ /* ---- in/out --- */ cholmod_factor *L, /* resulting factorization */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_factorize_p (cholmod_sparse *, double [2], SuiteSparse_long *, size_t, cholmod_factor *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_solve: solve a linear system (simplicial or supernodal) */ /* -------------------------------------------------------------------------- */ /* Solves one of many linear systems with a dense right-hand-side, using the * factorization from cholmod_factorize (or as modified by any other CHOLMOD * routine). D is identity for LL' factorizations. */ #define CHOLMOD_A 0 /* solve Ax=b */ #define CHOLMOD_LDLt 1 /* solve LDL'x=b */ #define CHOLMOD_LD 2 /* solve LDx=b */ #define CHOLMOD_DLt 3 /* solve DL'x=b */ #define CHOLMOD_L 4 /* solve Lx=b */ #define CHOLMOD_Lt 5 /* solve L'x=b */ #define CHOLMOD_D 6 /* solve Dx=b */ #define CHOLMOD_P 7 /* permute x=Px */ #define CHOLMOD_Pt 8 /* permute x=P'x */ cholmod_dense *cholmod_solve /* returns the solution X */ ( /* ---- input ---- */ int sys, /* system to solve */ cholmod_factor *L, /* factorization to use */ cholmod_dense *B, /* right-hand-side */ /* --------------- */ cholmod_common *Common ) ; cholmod_dense *cholmod_l_solve (int, cholmod_factor *, cholmod_dense *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_solve2: like cholmod_solve, but with reusable workspace */ /* -------------------------------------------------------------------------- */ int cholmod_solve2 /* returns TRUE on success, FALSE on failure */ ( /* ---- input ---- */ int sys, /* system to solve */ cholmod_factor *L, /* factorization to use */ cholmod_dense *B, /* right-hand-side */ cholmod_sparse *Bset, /* ---- output --- */ cholmod_dense **X_Handle, /* solution, allocated if need be */ cholmod_sparse **Xset_Handle, /* ---- workspace */ cholmod_dense **Y_Handle, /* workspace, or NULL */ cholmod_dense **E_Handle, /* workspace, or NULL */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_solve2 (int, cholmod_factor *, cholmod_dense *, cholmod_sparse *, cholmod_dense **, cholmod_sparse **, cholmod_dense **, cholmod_dense **, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_spsolve: solve a linear system with a sparse right-hand-side */ /* -------------------------------------------------------------------------- */ cholmod_sparse *cholmod_spsolve ( /* ---- input ---- */ int sys, /* system to solve */ cholmod_factor *L, /* factorization to use */ cholmod_sparse *B, /* right-hand-side */ /* --------------- */ cholmod_common *Common ) ; cholmod_sparse *cholmod_l_spsolve (int, cholmod_factor *, cholmod_sparse *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_etree: find the elimination tree of A or A'*A */ /* -------------------------------------------------------------------------- */ int cholmod_etree ( /* ---- input ---- */ cholmod_sparse *A, /* ---- output --- */ int *Parent, /* size ncol. Parent [j] = p if p is the parent of j */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_etree (cholmod_sparse *, SuiteSparse_long *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_rowcolcounts: compute the row/column counts of L */ /* -------------------------------------------------------------------------- */ int cholmod_rowcolcounts ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to analyze */ int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ int *Parent, /* size nrow. Parent [i] = p if p is the parent of i */ int *Post, /* size nrow. Post [k] = i if i is the kth node in * the postordered etree. */ /* ---- output --- */ int *RowCount, /* size nrow. RowCount [i] = # entries in the ith row of * L, including the diagonal. */ int *ColCount, /* size nrow. ColCount [i] = # entries in the ith * column of L, including the diagonal. */ int *First, /* size nrow. First [i] = k is the least postordering * of any descendant of i. */ int *Level, /* size nrow. Level [i] is the length of the path from * i to the root, with Level [root] = 0. */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_rowcolcounts (cholmod_sparse *, SuiteSparse_long *, size_t, SuiteSparse_long *, SuiteSparse_long *, SuiteSparse_long *, SuiteSparse_long *, SuiteSparse_long *, SuiteSparse_long *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_analyze_ordering: analyze a fill-reducing ordering */ /* -------------------------------------------------------------------------- */ int cholmod_analyze_ordering ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to analyze */ int ordering, /* ordering method used */ int *Perm, /* size n, fill-reducing permutation to analyze */ int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ /* ---- output --- */ int *Parent, /* size n, elimination tree */ int *Post, /* size n, postordering of elimination tree */ int *ColCount, /* size n, nnz in each column of L */ /* ---- workspace */ int *First, /* size nworkspace for cholmod_postorder */ int *Level, /* size n workspace for cholmod_postorder */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_analyze_ordering (cholmod_sparse *, int, SuiteSparse_long *, SuiteSparse_long *, size_t, SuiteSparse_long *, SuiteSparse_long *, SuiteSparse_long *, SuiteSparse_long *, SuiteSparse_long *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_amd: order using AMD */ /* -------------------------------------------------------------------------- */ /* Finds a permutation P to reduce fill-in in the factorization of P*A*P' * or P*A*A'P' */ int cholmod_amd ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to order */ int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ /* ---- output --- */ int *Perm, /* size A->nrow, output permutation */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_amd (cholmod_sparse *, SuiteSparse_long *, size_t, SuiteSparse_long *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_colamd: order using COLAMD */ /* -------------------------------------------------------------------------- */ /* Finds a permutation P to reduce fill-in in the factorization of P*A*A'*P'. * Orders F*F' where F = A (:,fset) if fset is not NULL */ int cholmod_colamd ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to order */ int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ int postorder, /* if TRUE, follow with a coletree postorder */ /* ---- output --- */ int *Perm, /* size A->nrow, output permutation */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_colamd (cholmod_sparse *, SuiteSparse_long *, size_t, int, SuiteSparse_long *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_rowfac: incremental simplicial factorization */ /* -------------------------------------------------------------------------- */ /* Partial or complete simplicial factorization. Rows and columns kstart:kend-1 * of L and D must be initially equal to rows/columns kstart:kend-1 of the * identity matrix. Row k can only be factorized if all descendants of node * k in the elimination tree have been factorized. */ int cholmod_rowfac ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to factorize */ cholmod_sparse *F, /* used for A*A' case only. F=A' or A(:,fset)' */ double beta [2], /* factorize beta*I+A or beta*I+A'*A */ size_t kstart, /* first row to factorize */ size_t kend, /* last row to factorize is kend-1 */ /* ---- in/out --- */ cholmod_factor *L, /* --------------- */ cholmod_common *Common ) ; int cholmod_l_rowfac (cholmod_sparse *, cholmod_sparse *, double [2], size_t, size_t, cholmod_factor *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_rowfac_mask: incremental simplicial factorization */ /* -------------------------------------------------------------------------- */ /* cholmod_rowfac_mask is a version of cholmod_rowfac that is specific to * LPDASA. It is unlikely to be needed by any other application. */ int cholmod_rowfac_mask ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to factorize */ cholmod_sparse *F, /* used for A*A' case only. F=A' or A(:,fset)' */ double beta [2], /* factorize beta*I+A or beta*I+A'*A */ size_t kstart, /* first row to factorize */ size_t kend, /* last row to factorize is kend-1 */ int *mask, /* if mask[i] >= 0, then set row i to zero */ int *RLinkUp, /* link list of rows to compute */ /* ---- in/out --- */ cholmod_factor *L, /* --------------- */ cholmod_common *Common ) ; int cholmod_l_rowfac_mask (cholmod_sparse *, cholmod_sparse *, double [2], size_t, size_t, SuiteSparse_long *, SuiteSparse_long *, cholmod_factor *, cholmod_common *) ; int cholmod_rowfac_mask2 ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to factorize */ cholmod_sparse *F, /* used for A*A' case only. F=A' or A(:,fset)' */ double beta [2], /* factorize beta*I+A or beta*I+A'*A */ size_t kstart, /* first row to factorize */ size_t kend, /* last row to factorize is kend-1 */ int *mask, /* if mask[i] >= maskmark, then set row i to zero */ int maskmark, int *RLinkUp, /* link list of rows to compute */ /* ---- in/out --- */ cholmod_factor *L, /* --------------- */ cholmod_common *Common ) ; int cholmod_l_rowfac_mask2 (cholmod_sparse *, cholmod_sparse *, double [2], size_t, size_t, SuiteSparse_long *, SuiteSparse_long, SuiteSparse_long *, cholmod_factor *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_row_subtree: find the nonzero pattern of a row of L */ /* -------------------------------------------------------------------------- */ /* Find the nonzero pattern of x for the system Lx=b where L = (0:k-1,0:k-1) * and b = kth column of A or A*A' (rows 0 to k-1 only) */ int cholmod_row_subtree ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to analyze */ cholmod_sparse *F, /* used for A*A' case only. F=A' or A(:,fset)' */ size_t k, /* row k of L */ int *Parent, /* elimination tree */ /* ---- output --- */ cholmod_sparse *R, /* pattern of L(k,:), n-by-1 with R->nzmax >= n */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_row_subtree (cholmod_sparse *, cholmod_sparse *, size_t, SuiteSparse_long *, cholmod_sparse *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_lsolve_pattern: find the nonzero pattern of x=L\b */ /* -------------------------------------------------------------------------- */ int cholmod_lsolve_pattern ( /* ---- input ---- */ cholmod_sparse *B, /* sparse right-hand-side (a single sparse column) */ cholmod_factor *L, /* the factor L from which parent(i) is derived */ /* ---- output --- */ cholmod_sparse *X, /* pattern of X=L\B, n-by-1 with X->nzmax >= n */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_lsolve_pattern (cholmod_sparse *, cholmod_factor *, cholmod_sparse *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_row_lsubtree: find the nonzero pattern of a row of L */ /* -------------------------------------------------------------------------- */ /* Identical to cholmod_row_subtree, except that it finds the elimination tree * from L itself. */ int cholmod_row_lsubtree ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to analyze */ int *Fi, size_t fnz, /* nonzero pattern of kth row of A', not required * for the symmetric case. Need not be sorted. */ size_t k, /* row k of L */ cholmod_factor *L, /* the factor L from which parent(i) is derived */ /* ---- output --- */ cholmod_sparse *R, /* pattern of L(k,:), n-by-1 with R->nzmax >= n */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_row_lsubtree (cholmod_sparse *, SuiteSparse_long *, size_t, size_t, cholmod_factor *, cholmod_sparse *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_resymbol: recompute the symbolic pattern of L */ /* -------------------------------------------------------------------------- */ /* Remove entries from L that are not in the factorization of P*A*P', P*A*A'*P', * or P*F*F'*P' (depending on A->stype and whether fset is NULL or not). * * cholmod_resymbol is the same as cholmod_resymbol_noperm, except that it * first permutes A according to L->Perm. A can be upper/lower/unsymmetric, * in contrast to cholmod_resymbol_noperm (which can be lower or unsym). */ int cholmod_resymbol ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to analyze */ int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ int pack, /* if TRUE, pack the columns of L */ /* ---- in/out --- */ cholmod_factor *L, /* factorization, entries pruned on output */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_resymbol (cholmod_sparse *, SuiteSparse_long *, size_t, int, cholmod_factor *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_resymbol_noperm: recompute the symbolic pattern of L, no L->Perm */ /* -------------------------------------------------------------------------- */ /* Remove entries from L that are not in the factorization of A, A*A', * or F*F' (depending on A->stype and whether fset is NULL or not). */ int cholmod_resymbol_noperm ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to analyze */ int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ int pack, /* if TRUE, pack the columns of L */ /* ---- in/out --- */ cholmod_factor *L, /* factorization, entries pruned on output */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_resymbol_noperm (cholmod_sparse *, SuiteSparse_long *, size_t, int, cholmod_factor *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_rcond: compute rough estimate of reciprocal of condition number */ /* -------------------------------------------------------------------------- */ double cholmod_rcond /* return min(diag(L)) / max(diag(L)) */ ( /* ---- input ---- */ cholmod_factor *L, /* --------------- */ cholmod_common *Common ) ; double cholmod_l_rcond (cholmod_factor *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_postorder: Compute the postorder of a tree */ /* -------------------------------------------------------------------------- */ SuiteSparse_long cholmod_postorder /* return # of nodes postordered */ ( /* ---- input ---- */ int *Parent, /* size n. Parent [j] = p if p is the parent of j */ size_t n, int *Weight_p, /* size n, optional. Weight [j] is weight of node j */ /* ---- output --- */ int *Post, /* size n. Post [k] = j is kth in postordered tree */ /* --------------- */ cholmod_common *Common ) ; SuiteSparse_long cholmod_l_postorder (SuiteSparse_long *, size_t, SuiteSparse_long *, SuiteSparse_long *, cholmod_common *) ; #endif ��������������������������������������������������������������Matrix/src/CHOLMOD/Include/cholmod_modify.h���������������������������������������������������������0000644�0001762�0000144�00000032403�14406303520�020121� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Include/cholmod_modify.h ============================================= */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Include/cholmod_modify.h. * Copyright (C) 2005-2006, Timothy A. Davis and William W. Hager * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* CHOLMOD Modify module. * * Sparse Cholesky modification routines: update / downdate / rowadd / rowdel. * Can also modify a corresponding solution to Lx=b when L is modified. This * module is most useful when applied on a Cholesky factorization computed by * the Cholesky module, but it does not actually require the Cholesky module. * The Core module can create an identity Cholesky factorization (LDL' where * L=D=I) that can then by modified by these routines. * * Primary routines: * ----------------- * * cholmod_updown multiple rank update/downdate * cholmod_rowadd add a row to an LDL' factorization * cholmod_rowdel delete a row from an LDL' factorization * * Secondary routines: * ------------------- * * cholmod_updown_solve update/downdate, and modify solution to Lx=b * cholmod_updown_mark update/downdate, and modify solution to partial Lx=b * cholmod_updown_mask update/downdate for LPDASA * cholmod_updown_mask2 update/downdate for LPDASA * cholmod_rowadd_solve add a row, and update solution to Lx=b * cholmod_rowadd_mark add a row, and update solution to partial Lx=b * cholmod_rowdel_solve delete a row, and downdate Lx=b * cholmod_rowdel_mark delete a row, and downdate solution to partial Lx=b * * Requires the Core module. Not required by any other CHOLMOD module. */ #ifndef CHOLMOD_MODIFY_H #define CHOLMOD_MODIFY_H #include "cholmod_core.h" /* -------------------------------------------------------------------------- */ /* cholmod_updown: multiple rank update/downdate */ /* -------------------------------------------------------------------------- */ /* Compute the new LDL' factorization of LDL'+CC' (an update) or LDL'-CC' * (a downdate). The factor object L need not be an LDL' factorization; it * is converted to one if it isn't. */ int cholmod_updown ( /* ---- input ---- */ int update, /* TRUE for update, FALSE for downdate */ cholmod_sparse *C, /* the incoming sparse update */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_updown (int, cholmod_sparse *, cholmod_factor *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_updown_solve: update/downdate, and modify solution to Lx=b */ /* -------------------------------------------------------------------------- */ /* Does the same as cholmod_updown, except that it also updates/downdates the * solution to Lx=b+DeltaB. x and b must be n-by-1 dense matrices. b is not * need as input to this routine, but a sparse change to b is (DeltaB). Only * entries in DeltaB corresponding to columns modified in L are accessed; the * rest must be zero. */ int cholmod_updown_solve ( /* ---- input ---- */ int update, /* TRUE for update, FALSE for downdate */ cholmod_sparse *C, /* the incoming sparse update */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ cholmod_dense *X, /* solution to Lx=b (size n-by-1) */ cholmod_dense *DeltaB, /* change in b, zero on output */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_updown_solve (int, cholmod_sparse *, cholmod_factor *, cholmod_dense *, cholmod_dense *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_updown_mark: update/downdate, and modify solution to partial Lx=b */ /* -------------------------------------------------------------------------- */ /* Does the same as cholmod_updown_solve, except only part of L is used in * the update/downdate of the solution to Lx=b. This routine is an "expert" * routine. It is meant for use in LPDASA only. See cholmod_updown.c for * a description of colmark. */ int cholmod_updown_mark ( /* ---- input ---- */ int update, /* TRUE for update, FALSE for downdate */ cholmod_sparse *C, /* the incoming sparse update */ int *colmark, /* int array of size n. See cholmod_updown.c */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ cholmod_dense *X, /* solution to Lx=b (size n-by-1) */ cholmod_dense *DeltaB, /* change in b, zero on output */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_updown_mark (int, cholmod_sparse *, SuiteSparse_long *, cholmod_factor *, cholmod_dense *, cholmod_dense *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_updown_mask: update/downdate, for LPDASA */ /* -------------------------------------------------------------------------- */ /* Does the same as cholmod_updown_mark, except has an additional "mask" * argument. This routine is an "expert" routine. It is meant for use in * LPDASA only. See cholmod_updown.c for a description of mask. */ int cholmod_updown_mask ( /* ---- input ---- */ int update, /* TRUE for update, FALSE for downdate */ cholmod_sparse *C, /* the incoming sparse update */ int *colmark, /* int array of size n. See cholmod_updown.c */ int *mask, /* size n */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ cholmod_dense *X, /* solution to Lx=b (size n-by-1) */ cholmod_dense *DeltaB, /* change in b, zero on output */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_updown_mask (int, cholmod_sparse *, SuiteSparse_long *, SuiteSparse_long *, cholmod_factor *, cholmod_dense *, cholmod_dense *, cholmod_common *) ; int cholmod_updown_mask2 ( /* ---- input ---- */ int update, /* TRUE for update, FALSE for downdate */ cholmod_sparse *C, /* the incoming sparse update */ int *colmark, /* int array of size n. See cholmod_updown.c */ int *mask, /* size n */ int maskmark, /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ cholmod_dense *X, /* solution to Lx=b (size n-by-1) */ cholmod_dense *DeltaB, /* change in b, zero on output */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_updown_mask2 (int, cholmod_sparse *, SuiteSparse_long *, SuiteSparse_long *, SuiteSparse_long, cholmod_factor *, cholmod_dense *, cholmod_dense *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_rowadd: add a row to an LDL' factorization (a rank-2 update) */ /* -------------------------------------------------------------------------- */ /* cholmod_rowadd adds a row to the LDL' factorization. It computes the kth * row and kth column of L, and then updates the submatrix L (k+1:n,k+1:n) * accordingly. The kth row and column of L must originally be equal to the * kth row and column of the identity matrix. The kth row/column of L is * computed as the factorization of the kth row/column of the matrix to * factorize, which is provided as a single n-by-1 sparse matrix R. */ int cholmod_rowadd ( /* ---- input ---- */ size_t k, /* row/column index to add */ cholmod_sparse *R, /* row/column of matrix to factorize (n-by-1) */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_rowadd (size_t, cholmod_sparse *, cholmod_factor *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_rowadd_solve: add a row, and update solution to Lx=b */ /* -------------------------------------------------------------------------- */ /* Does the same as cholmod_rowadd, and also updates the solution to Lx=b * See cholmod_updown for a description of how Lx=b is updated. There is on * additional parameter: bk specifies the new kth entry of b. */ int cholmod_rowadd_solve ( /* ---- input ---- */ size_t k, /* row/column index to add */ cholmod_sparse *R, /* row/column of matrix to factorize (n-by-1) */ double bk [2], /* kth entry of the right-hand-side b */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ cholmod_dense *X, /* solution to Lx=b (size n-by-1) */ cholmod_dense *DeltaB, /* change in b, zero on output */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_rowadd_solve (size_t, cholmod_sparse *, double [2], cholmod_factor *, cholmod_dense *, cholmod_dense *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_rowadd_mark: add a row, and update solution to partial Lx=b */ /* -------------------------------------------------------------------------- */ /* Does the same as cholmod_rowadd_solve, except only part of L is used in * the update/downdate of the solution to Lx=b. This routine is an "expert" * routine. It is meant for use in LPDASA only. */ int cholmod_rowadd_mark ( /* ---- input ---- */ size_t k, /* row/column index to add */ cholmod_sparse *R, /* row/column of matrix to factorize (n-by-1) */ double bk [2], /* kth entry of the right hand side, b */ int *colmark, /* int array of size n. See cholmod_updown.c */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ cholmod_dense *X, /* solution to Lx=b (size n-by-1) */ cholmod_dense *DeltaB, /* change in b, zero on output */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_rowadd_mark (size_t, cholmod_sparse *, double [2], SuiteSparse_long *, cholmod_factor *, cholmod_dense *, cholmod_dense *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_rowdel: delete a row from an LDL' factorization (a rank-2 update) */ /* -------------------------------------------------------------------------- */ /* Sets the kth row and column of L to be the kth row and column of the identity * matrix, and updates L(k+1:n,k+1:n) accordingly. To reduce the running time, * the caller can optionally provide the nonzero pattern (or an upper bound) of * kth row of L, as the sparse n-by-1 vector R. Provide R as NULL if you want * CHOLMOD to determine this itself, which is easier for the caller, but takes * a little more time. */ int cholmod_rowdel ( /* ---- input ---- */ size_t k, /* row/column index to delete */ cholmod_sparse *R, /* NULL, or the nonzero pattern of kth row of L */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_rowdel (size_t, cholmod_sparse *, cholmod_factor *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_rowdel_solve: delete a row, and downdate Lx=b */ /* -------------------------------------------------------------------------- */ /* Does the same as cholmod_rowdel, but also downdates the solution to Lx=b. * When row/column k of A is "deleted" from the system A*y=b, this can induce * a change to x, in addition to changes arising when L and b are modified. * If this is the case, the kth entry of y is required as input (yk) */ int cholmod_rowdel_solve ( /* ---- input ---- */ size_t k, /* row/column index to delete */ cholmod_sparse *R, /* NULL, or the nonzero pattern of kth row of L */ double yk [2], /* kth entry in the solution to A*y=b */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ cholmod_dense *X, /* solution to Lx=b (size n-by-1) */ cholmod_dense *DeltaB, /* change in b, zero on output */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_rowdel_solve (size_t, cholmod_sparse *, double [2], cholmod_factor *, cholmod_dense *, cholmod_dense *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_rowdel_mark: delete a row, and downdate solution to partial Lx=b */ /* -------------------------------------------------------------------------- */ /* Does the same as cholmod_rowdel_solve, except only part of L is used in * the update/downdate of the solution to Lx=b. This routine is an "expert" * routine. It is meant for use in LPDASA only. */ int cholmod_rowdel_mark ( /* ---- input ---- */ size_t k, /* row/column index to delete */ cholmod_sparse *R, /* NULL, or the nonzero pattern of kth row of L */ double yk [2], /* kth entry in the solution to A*y=b */ int *colmark, /* int array of size n. See cholmod_updown.c */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ cholmod_dense *X, /* solution to Lx=b (size n-by-1) */ cholmod_dense *DeltaB, /* change in b, zero on output */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_rowdel_mark (size_t, cholmod_sparse *, double [2], SuiteSparse_long *, cholmod_factor *, cholmod_dense *, cholmod_dense *, cholmod_common *) ; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Include/License.txt��������������������������������������������������������������0000644�0001762�0000144�00000000412�11770402705�017100� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CHOLMOD/Include/* files. Copyright (C) 2005-2006, either Univ. of Florida or T. Davis, depending on the file. Refer to each include file in this directory; each file is licensed separately, according to the Module for which it contains definitions and prototypes. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Include/cholmod_blas.h�����������������������������������������������������������0000644�0001762�0000144�00000034455�13711014777�017577� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Include/cholmod_blas.h =============================================== */ /* ========================================================================== */ /* For R's Matrix package (by Martin Maechler), need FCLEN FCONE : * _NOT_ the full #include * --- but just */ #define USE_FC_LEN_T #include // included by R.h, so define USE_FC_LEN_T early #ifdef FC_LEN_T //# pragma message ( "FC_LEN_T is defined -- FCLEN and FCONE are defined using it" ) // _instead of_ # include // for size_t if needed // use a "hack" : but this fails # define size_t long int // --> try to use size_t as it has been defined earlier # define FCLEN ,FC_LEN_T # define FCONE ,(FC_LEN_T)1 #else # define FCLEN # define FCONE #endif /* ----------------------------------------------------------------------------- * CHOLMOD/Include/cholmod_blas.h. * Copyright (C) 2005-2006, Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* This does not need to be included in the user's program. */ #ifndef CHOLMOD_BLAS_H #define CHOLMOD_BLAS_H /* ========================================================================== */ /* === Architecture ========================================================= */ /* ========================================================================== */ #if defined (__sun) || defined (MSOL2) || defined (ARCH_SOL2) #define CHOLMOD_SOL2 #define CHOLMOD_ARCHITECTURE "Sun Solaris" #elif defined (__sgi) || defined (MSGI) || defined (ARCH_SGI) #define CHOLMOD_SGI #define CHOLMOD_ARCHITECTURE "SGI Irix" #elif defined (__linux) || defined (MGLNX86) || defined (ARCH_GLNX86) #define CHOLMOD_LINUX #define CHOLMOD_ARCHITECTURE "Linux" #elif defined (__APPLE__) #define CHOLMOD_MAC #define CHOLMOD_ARCHITECTURE "Mac" #elif defined (_AIX) || defined (MIBM_RS) || defined (ARCH_IBM_RS) #define CHOLMOD_AIX #define CHOLMOD_ARCHITECTURE "IBM AIX" /* recent reports from IBM AIX seem to indicate that this is not needed: */ /* #define BLAS_NO_UNDERSCORE */ #elif defined (__alpha) || defined (MALPHA) || defined (ARCH_ALPHA) #define CHOLMOD_ALPHA #define CHOLMOD_ARCHITECTURE "Compaq Alpha" #elif defined (_WIN32) || defined (WIN32) || defined (_WIN64) || defined (WIN64) #if defined (__MINGW32__) || defined (__MINGW32__) #define CHOLMOD_MINGW #elif defined (__CYGWIN32__) || defined (__CYGWIN32__) #define CHOLMOD_CYGWIN #else #define CHOLMOD_WINDOWS #define BLAS_NO_UNDERSCORE #endif #define CHOLMOD_ARCHITECTURE "Microsoft Windows" #elif defined (__hppa) || defined (__hpux) || defined (MHPUX) || defined (ARCH_HPUX) #define CHOLMOD_HP #define CHOLMOD_ARCHITECTURE "HP Unix" #define BLAS_NO_UNDERSCORE #elif defined (__hp700) || defined (MHP700) || defined (ARCH_HP700) #define CHOLMOD_HP #define CHOLMOD_ARCHITECTURE "HP 700 Unix" #define BLAS_NO_UNDERSCORE #else /* If the architecture is unknown, and you call the BLAS, you may need to */ /* define BLAS_BY_VALUE, BLAS_NO_UNDERSCORE, and/or BLAS_CHAR_ARG yourself. */ #define CHOLMOD_ARCHITECTURE "unknown" #endif /* ========================================================================== */ /* === BLAS and LAPACK names ================================================ */ /* ========================================================================== */ /* Prototypes for the various versions of the BLAS. */ /* Determine if the 64-bit Sun Performance BLAS is to be used */ #if defined(CHOLMOD_SOL2) && !defined(NSUNPERF) && defined(BLAS64) #define SUN64 #endif #ifdef SUN64 #define BLAS_DTRSV dtrsv_64_ #define BLAS_DGEMV dgemv_64_ #define BLAS_DTRSM dtrsm_64_ #define BLAS_DGEMM dgemm_64_ #define BLAS_DSYRK dsyrk_64_ #define BLAS_DGER dger_64_ #define BLAS_DSCAL dscal_64_ #define LAPACK_DPOTRF dpotrf_64_ #define BLAS_ZTRSV ztrsv_64_ #define BLAS_ZGEMV zgemv_64_ #define BLAS_ZTRSM ztrsm_64_ #define BLAS_ZGEMM zgemm_64_ #define BLAS_ZHERK zherk_64_ #define BLAS_ZGER zgeru_64_ #define BLAS_ZSCAL zscal_64_ #define LAPACK_ZPOTRF zpotrf_64_ #elif defined (BLAS_NO_UNDERSCORE) #define BLAS_DTRSV dtrsv #define BLAS_DGEMV dgemv #define BLAS_DTRSM dtrsm #define BLAS_DGEMM dgemm #define BLAS_DSYRK dsyrk #define BLAS_DGER dger #define BLAS_DSCAL dscal #define LAPACK_DPOTRF dpotrf #define BLAS_ZTRSV ztrsv #define BLAS_ZGEMV zgemv #define BLAS_ZTRSM ztrsm #define BLAS_ZGEMM zgemm #define BLAS_ZHERK zherk #define BLAS_ZGER zgeru #define BLAS_ZSCAL zscal #define LAPACK_ZPOTRF zpotrf #else #define BLAS_DTRSV dtrsv_ #define BLAS_DGEMV dgemv_ #define BLAS_DTRSM dtrsm_ #define BLAS_DGEMM dgemm_ #define BLAS_DSYRK dsyrk_ #define BLAS_DGER dger_ #define BLAS_DSCAL dscal_ #define LAPACK_DPOTRF dpotrf_ #define BLAS_ZTRSV ztrsv_ #define BLAS_ZGEMV zgemv_ #define BLAS_ZTRSM ztrsm_ #define BLAS_ZGEMM zgemm_ #define BLAS_ZHERK zherk_ #define BLAS_ZGER zgeru_ #define BLAS_ZSCAL zscal_ #define LAPACK_ZPOTRF zpotrf_ #endif /* ========================================================================== */ /* === BLAS and LAPACK integer arguments ==================================== */ /* ========================================================================== */ /* Compile CHOLMOD, UMFPACK, and SPQR with -DBLAS64 if you have a BLAS that * uses 64-bit integers */ #if defined (LONGBLAS) || defined (BLAS64) #define BLAS_INT SuiteSparse_long #else #define BLAS_INT int #endif /* If the BLAS integer is smaller than the basic CHOLMOD integer, then we need * to check for integer overflow when converting from Int to BLAS_INT. If * any integer overflows, the externally-defined BLAS_OK variable is * set to FALSE. BLAS_OK should be set to TRUE before calling any * BLAS_* macro. */ #define CHECK_BLAS_INT (sizeof (BLAS_INT) < sizeof (Int)) #define EQ(K,k) (((BLAS_INT) K) == ((Int) k)) /* ========================================================================== */ /* === BLAS and LAPACK prototypes and macros ================================ */ /* ========================================================================== */ void BLAS_DGEMV (char *trans, BLAS_INT *m, BLAS_INT *n, double *alpha, double *A, BLAS_INT *lda, double *X, BLAS_INT *incx, double *beta, double *Y, BLAS_INT *incy FCLEN) ; #define BLAS_dgemv(trans,m,n,alpha,A,lda,X,incx,beta,Y,incy) \ { \ BLAS_INT M = m, N = n, LDA = lda, INCX = incx, INCY = incy ; \ if (CHECK_BLAS_INT && !(EQ (M,m) && EQ (N,n) && EQ (LDA,lda) && \ EQ (INCX,incx) && EQ (INCY,incy))) \ { \ BLAS_OK = FALSE ; \ } \ if (!CHECK_BLAS_INT || BLAS_OK) \ { \ BLAS_DGEMV (trans, &M, &N, alpha, A, &LDA, X, &INCX, beta, Y, &INCY FCONE) ; \ } \ } void BLAS_ZGEMV (char *trans, BLAS_INT *m, BLAS_INT *n, double *alpha, double *A, BLAS_INT *lda, double *X, BLAS_INT *incx, double *beta, double *Y, BLAS_INT *incy FCLEN) ; #define BLAS_zgemv(trans,m,n,alpha,A,lda,X,incx,beta,Y,incy) \ { \ BLAS_INT M = m, N = n, LDA = lda, INCX = incx, INCY = incy ; \ if (CHECK_BLAS_INT && !(EQ (M,m) && EQ (N,n) && EQ (LDA,lda) && \ EQ (INCX,incx) && EQ (INCY,incy))) \ { \ BLAS_OK = FALSE ; \ } \ if (!CHECK_BLAS_INT || BLAS_OK) \ { \ BLAS_ZGEMV (trans, &M, &N, alpha, A, &LDA, X, &INCX, beta, Y, &INCY FCONE) ; \ } \ } void BLAS_DTRSV (char *uplo, char *trans, char *diag, BLAS_INT *n, double *A, BLAS_INT *lda, double *X, BLAS_INT *incx FCLEN FCLEN FCLEN) ; #define BLAS_dtrsv(uplo,trans,diag,n,A,lda,X,incx) \ { \ BLAS_INT N = n, LDA = lda, INCX = incx ; \ if (CHECK_BLAS_INT && !(EQ (N,n) && EQ (LDA,lda) && EQ (INCX,incx))) \ { \ BLAS_OK = FALSE ; \ } \ if (!CHECK_BLAS_INT || BLAS_OK) \ { \ BLAS_DTRSV (uplo, trans, diag, &N, A, &LDA, X, &INCX FCONE FCONE FCONE) ; \ } \ } void BLAS_ZTRSV (char *uplo, char *trans, char *diag, BLAS_INT *n, double *A, BLAS_INT *lda, double *X, BLAS_INT *incx FCLEN FCLEN FCLEN) ; #define BLAS_ztrsv(uplo,trans,diag,n,A,lda,X,incx) \ { \ BLAS_INT N = n, LDA = lda, INCX = incx ; \ if (CHECK_BLAS_INT && !(EQ (N,n) && EQ (LDA,lda) && EQ (INCX,incx))) \ { \ BLAS_OK = FALSE ; \ } \ if (!CHECK_BLAS_INT || BLAS_OK) \ { \ BLAS_ZTRSV (uplo, trans, diag, &N, A, &LDA, X, &INCX FCONE FCONE FCONE) ; \ } \ } void BLAS_DTRSM (char *side, char *uplo, char *transa, char *diag, BLAS_INT *m, BLAS_INT *n, double *alpha, double *A, BLAS_INT *lda, double *B, BLAS_INT *ldb FCLEN FCLEN FCLEN FCLEN) ; #define BLAS_dtrsm(side,uplo,transa,diag,m,n,alpha,A,lda,B,ldb) \ { \ BLAS_INT M = m, N = n, LDA = lda, LDB = ldb ; \ if (CHECK_BLAS_INT && !(EQ (M,m) && EQ (N,n) && EQ (LDA,lda) && \ EQ (LDB,ldb))) \ { \ BLAS_OK = FALSE ; \ } \ if (!CHECK_BLAS_INT || BLAS_OK) \ { \ BLAS_DTRSM (side, uplo, transa, diag, &M, &N, alpha, A, &LDA, B, &LDB FCONE FCONE FCONE FCONE);\ } \ } void BLAS_ZTRSM (char *side, char *uplo, char *transa, char *diag, BLAS_INT *m, BLAS_INT *n, double *alpha, double *A, BLAS_INT *lda, double *B, BLAS_INT *ldb FCLEN FCLEN FCLEN FCLEN) ; #define BLAS_ztrsm(side,uplo,transa,diag,m,n,alpha,A,lda,B,ldb) \ { \ BLAS_INT M = m, N = n, LDA = lda, LDB = ldb ; \ if (CHECK_BLAS_INT && !(EQ (M,m) && EQ (N,n) && EQ (LDA,lda) && \ EQ (LDB,ldb))) \ { \ BLAS_OK = FALSE ; \ } \ if (!CHECK_BLAS_INT || BLAS_OK) \ { \ BLAS_ZTRSM (side, uplo, transa, diag, &M, &N, alpha, A, &LDA, B, &LDB FCONE FCONE FCONE FCONE);\ } \ } void BLAS_DGEMM (char *transa, char *transb, BLAS_INT *m, BLAS_INT *n, BLAS_INT *k, double *alpha, double *A, BLAS_INT *lda, double *B, BLAS_INT *ldb, double *beta, double *C, BLAS_INT *ldc FCLEN FCLEN) ; #define BLAS_dgemm(transa,transb,m,n,k,alpha,A,lda,B,ldb,beta,C,ldc) \ { \ BLAS_INT M = m, N = n, K = k, LDA = lda, LDB = ldb, LDC = ldc ; \ if (CHECK_BLAS_INT && !(EQ (M,m) && EQ (N,n) && EQ (K,k) && \ EQ (LDA,lda) && EQ (LDB,ldb) && EQ (LDC,ldc))) \ { \ BLAS_OK = FALSE ; \ } \ if (!CHECK_BLAS_INT || BLAS_OK) \ { \ BLAS_DGEMM (transa, transb, &M, &N, &K, alpha, A, &LDA, B, &LDB, beta, \ C, &LDC FCONE FCONE) ; \ } \ } void BLAS_ZGEMM (char *transa, char *transb, BLAS_INT *m, BLAS_INT *n, BLAS_INT *k, double *alpha, double *A, BLAS_INT *lda, double *B, BLAS_INT *ldb, double *beta, double *C, BLAS_INT *ldc FCLEN FCLEN) ; #define BLAS_zgemm(transa,transb,m,n,k,alpha,A,lda,B,ldb,beta,C,ldc) \ { \ BLAS_INT M = m, N = n, K = k, LDA = lda, LDB = ldb, LDC = ldc ; \ if (CHECK_BLAS_INT && !(EQ (M,m) && EQ (N,n) && EQ (K,k) && \ EQ (LDA,lda) && EQ (LDB,ldb) && EQ (LDC,ldc))) \ { \ BLAS_OK = FALSE ; \ } \ if (!CHECK_BLAS_INT || BLAS_OK) \ { \ BLAS_ZGEMM (transa, transb, &M, &N, &K, alpha, A, &LDA, B, &LDB, beta, \ C, &LDC FCONE FCONE) ; \ } \ } void BLAS_DSYRK (char *uplo, char *trans, BLAS_INT *n, BLAS_INT *k, double *alpha, double *A, BLAS_INT *lda, double *beta, double *C, BLAS_INT *ldc FCLEN FCLEN) ; #define BLAS_dsyrk(uplo,trans,n,k,alpha,A,lda,beta,C,ldc) \ { \ BLAS_INT N = n, K = k, LDA = lda, LDC = ldc ; \ if (CHECK_BLAS_INT && !(EQ (N,n) && EQ (K,k) && EQ (LDA,lda) && \ EQ (LDC,ldc))) \ { \ BLAS_OK = FALSE ; \ } \ if (!CHECK_BLAS_INT || BLAS_OK) \ { \ BLAS_DSYRK (uplo, trans, &N, &K, alpha, A, &LDA, beta, C, &LDC FCONE FCONE) ; \ } \ } \ void BLAS_ZHERK (char *uplo, char *trans, BLAS_INT *n, BLAS_INT *k, double *alpha, double *A, BLAS_INT *lda, double *beta, double *C, BLAS_INT *ldc FCLEN FCLEN) ; #define BLAS_zherk(uplo,trans,n,k,alpha,A,lda,beta,C,ldc) \ { \ BLAS_INT N = n, K = k, LDA = lda, LDC = ldc ; \ if (CHECK_BLAS_INT && !(EQ (N,n) && EQ (K,k) && EQ (LDA,lda) && \ EQ (LDC,ldc))) \ { \ BLAS_OK = FALSE ; \ } \ if (!CHECK_BLAS_INT || BLAS_OK) \ { \ BLAS_ZHERK (uplo, trans, &N, &K, alpha, A, &LDA, beta, C, &LDC FCONE FCONE) ; \ } \ } \ void LAPACK_DPOTRF (char *uplo, BLAS_INT *n, double *A, BLAS_INT *lda, BLAS_INT *info FCLEN) ; #define LAPACK_dpotrf(uplo,n,A,lda,info) \ { \ BLAS_INT N = n, LDA = lda, INFO = 1 ; \ if (CHECK_BLAS_INT && !(EQ (N,n) && EQ (LDA,lda))) \ { \ BLAS_OK = FALSE ; \ } \ if (!CHECK_BLAS_INT || BLAS_OK) \ { \ LAPACK_DPOTRF (uplo, &N, A, &LDA, &INFO FCONE) ; \ } \ info = INFO ; \ } void LAPACK_ZPOTRF (char *uplo, BLAS_INT *n, double *A, BLAS_INT *lda, BLAS_INT *info FCLEN) ; #define LAPACK_zpotrf(uplo,n,A,lda,info) \ { \ BLAS_INT N = n, LDA = lda, INFO = 1 ; \ if (CHECK_BLAS_INT && !(EQ (N,n) && EQ (LDA,lda))) \ { \ BLAS_OK = FALSE ; \ } \ if (!CHECK_BLAS_INT || BLAS_OK) \ { \ LAPACK_ZPOTRF (uplo, &N, A, &LDA, &INFO FCONE) ; \ } \ info = INFO ; \ } /* ========================================================================== */ void BLAS_DSCAL (BLAS_INT *n, double *alpha, double *Y, BLAS_INT *incy) ; #define BLAS_dscal(n,alpha,Y,incy) \ { \ BLAS_INT N = n, INCY = incy ; \ if (CHECK_BLAS_INT && !(EQ (N,n) && EQ (INCY,incy))) \ { \ BLAS_OK = FALSE ; \ } \ if (!CHECK_BLAS_INT || BLAS_OK) \ { \ BLAS_DSCAL (&N, alpha, Y, &INCY) ; \ } \ } void BLAS_ZSCAL (BLAS_INT *n, double *alpha, double *Y, BLAS_INT *incy) ; #define BLAS_zscal(n,alpha,Y,incy) \ { \ BLAS_INT N = n, INCY = incy ; \ if (CHECK_BLAS_INT && !(EQ (N,n) && EQ (INCY,incy))) \ { \ BLAS_OK = FALSE ; \ } \ if (!CHECK_BLAS_INT || BLAS_OK) \ { \ BLAS_ZSCAL (&N, alpha, Y, &INCY) ; \ } \ } void BLAS_DGER (BLAS_INT *m, BLAS_INT *n, double *alpha, double *X, BLAS_INT *incx, double *Y, BLAS_INT *incy, double *A, BLAS_INT *lda) ; #define BLAS_dger(m,n,alpha,X,incx,Y,incy,A,lda) \ { \ BLAS_INT M = m, N = n, LDA = lda, INCX = incx, INCY = incy ; \ if (CHECK_BLAS_INT && !(EQ (M,m) && EQ (N,n) && EQ (LDA,lda) && \ EQ (INCX,incx) && EQ (INCY,incy))) \ { \ BLAS_OK = FALSE ; \ } \ if (!CHECK_BLAS_INT || BLAS_OK) \ { \ BLAS_DGER (&M, &N, alpha, X, &INCX, Y, &INCY, A, &LDA) ; \ } \ } void BLAS_ZGER (BLAS_INT *m, BLAS_INT *n, double *alpha, double *X, BLAS_INT *incx, double *Y, BLAS_INT *incy, double *A, BLAS_INT *lda) ; #define BLAS_zgeru(m,n,alpha,X,incx,Y,incy,A,lda) \ { \ BLAS_INT M = m, N = n, LDA = lda, INCX = incx, INCY = incy ; \ if (CHECK_BLAS_INT && !(EQ (M,m) && EQ (N,n) && EQ (LDA,lda) && \ EQ (INCX,incx) && EQ (INCY,incy))) \ { \ BLAS_OK = FALSE ; \ } \ if (!CHECK_BLAS_INT || BLAS_OK) \ { \ BLAS_ZGER (&M, &N, alpha, X, &INCX, Y, &INCY, A, &LDA) ; \ } \ } #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Include/cholmod_partition.h������������������������������������������������������0000644�0001762�0000144�00000015354�13652535054�020664� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Include/cholmod_partition.h ========================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Include/cholmod_partition.h. * Copyright (C) 2005-2013, Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* CHOLMOD Partition module. * * Graph partitioning and graph-partition-based orderings. Includes an * interface to CCOLAMD and CSYMAMD, constrained minimum degree ordering * methods which order a matrix following constraints determined via nested * dissection. * * These functions require METIS: * cholmod_nested_dissection CHOLMOD nested dissection ordering * cholmod_metis METIS nested dissection ordering (METIS_NodeND) * cholmod_bisect graph partitioner (currently based on METIS) * cholmod_metis_bisector direct interface to METIS_ComputeVertexSeparator * * Requires the Core and Cholesky modules, and three packages: METIS, CAMD, * and CCOLAMD. Optionally used by the Cholesky module. * * Note that METIS does not have a version that uses SuiteSparse_long integers. * If you try to use cholmod_nested_dissection, cholmod_metis, cholmod_bisect, * or cholmod_metis_bisector on a matrix that is too large, an error code will * be returned. METIS does have an "idxtype", which could be redefined as * SuiteSparse_long, if you wish to edit METIS or use compile-time flags to * redefine idxtype. */ #ifndef CHOLMOD_PARTITION_H #define CHOLMOD_PARTITION_H #include "cholmod_core.h" #include "cholmod_camd.h" /* -------------------------------------------------------------------------- */ /* cholmod_nested_dissection */ /* -------------------------------------------------------------------------- */ /* Order A, AA', or A(:,f)*A(:,f)' using CHOLMOD's nested dissection method * (METIS's node bisector applied recursively to compute the separator tree * and constraint sets, followed by CCOLAMD using the constraints). Usually * finds better orderings than METIS_NodeND, but takes longer. */ SuiteSparse_long cholmod_nested_dissection /* returns # of components */ ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to order */ int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ /* ---- output --- */ int *Perm, /* size A->nrow, output permutation */ int *CParent, /* size A->nrow. On output, CParent [c] is the parent * of component c, or EMPTY if c is a root, and where * c is in the range 0 to # of components minus 1 */ int *Cmember, /* size A->nrow. Cmember [j] = c if node j of A is * in component c */ /* --------------- */ cholmod_common *Common ) ; SuiteSparse_long cholmod_l_nested_dissection (cholmod_sparse *, SuiteSparse_long *, size_t, SuiteSparse_long *, SuiteSparse_long *, SuiteSparse_long *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_metis */ /* -------------------------------------------------------------------------- */ /* Order A, AA', or A(:,f)*A(:,f)' using METIS_NodeND. */ int cholmod_metis ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to order */ int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ int postorder, /* if TRUE, follow with etree or coletree postorder */ /* ---- output --- */ int *Perm, /* size A->nrow, output permutation */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_metis (cholmod_sparse *, SuiteSparse_long *, size_t, int, SuiteSparse_long *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_bisect */ /* -------------------------------------------------------------------------- */ /* Finds a node bisector of A, A*A', A(:,f)*A(:,f)'. */ SuiteSparse_long cholmod_bisect /* returns # of nodes in separator */ ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to bisect */ int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ int compress, /* if TRUE, compress the graph first */ /* ---- output --- */ int *Partition, /* size A->nrow. Node i is in the left graph if * Partition [i] = 0, the right graph if 1, and in the * separator if 2. */ /* --------------- */ cholmod_common *Common ) ; SuiteSparse_long cholmod_l_bisect (cholmod_sparse *, SuiteSparse_long *, size_t, int, SuiteSparse_long *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_metis_bisector */ /* -------------------------------------------------------------------------- */ /* Find a set of nodes that bisects the graph of A or AA' (direct interface * to METIS_ComputeVertexSeperator). */ SuiteSparse_long cholmod_metis_bisector /* returns separator size */ ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to bisect */ int *Anw, /* size A->nrow, node weights, can be NULL, */ /* which means the graph is unweighted. */ int *Aew, /* size nz, edge weights (silently ignored). */ /* This option was available with METIS 4, but not */ /* in METIS 5. This argument is now unused, but */ /* it remains for backward compatibilty, so as not */ /* to change the API for cholmod_metis_bisector. */ /* ---- output --- */ int *Partition, /* size A->nrow */ /* --------------- */ cholmod_common *Common ) ; SuiteSparse_long cholmod_l_metis_bisector (cholmod_sparse *, SuiteSparse_long *, SuiteSparse_long *, SuiteSparse_long *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_collapse_septree */ /* -------------------------------------------------------------------------- */ /* Collapse nodes in a separator tree. */ SuiteSparse_long cholmod_collapse_septree ( /* ---- input ---- */ size_t n, /* # of nodes in the graph */ size_t ncomponents, /* # of nodes in the separator tree (must be <= n) */ double nd_oksep, /* collapse if #sep >= nd_oksep * #nodes in subtree */ size_t nd_small, /* collapse if #nodes in subtree < nd_small */ /* ---- in/out --- */ int *CParent, /* size ncomponents; from cholmod_nested_dissection */ int *Cmember, /* size n; from cholmod_nested_dissection */ /* --------------- */ cholmod_common *Common ) ; SuiteSparse_long cholmod_l_collapse_septree (size_t, size_t, double, size_t, SuiteSparse_long *, SuiteSparse_long *, cholmod_common *) ; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Include/cholmod_matrixops.h������������������������������������������������������0000644�0001762�0000144�00000020424�14406303520�020660� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Include/cholmod_matrixops.h ========================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Include/cholmod_matrixops.h. * Copyright (C) 2005-2006, Timothy A. Davis * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* CHOLMOD MatrixOps module. * * Basic operations on sparse and dense matrices. * * cholmod_drop A = entries in A with abs. value >= tol * cholmod_norm_dense s = norm (X), 1-norm, inf-norm, or 2-norm * cholmod_norm_sparse s = norm (A), 1-norm or inf-norm * cholmod_horzcat C = [A,B] * cholmod_scale A = diag(s)*A, A*diag(s), s*A or diag(s)*A*diag(s) * cholmod_sdmult Y = alpha*(A*X) + beta*Y or alpha*(A'*X) + beta*Y * cholmod_ssmult C = A*B * cholmod_submatrix C = A (i,j), where i and j are arbitrary vectors * cholmod_vertcat C = [A ; B] * * A, B, C: sparse matrices (cholmod_sparse) * X, Y: dense matrices (cholmod_dense) * s: scalar or vector * * Requires the Core module. Not required by any other CHOLMOD module. */ #ifndef CHOLMOD_MATRIXOPS_H #define CHOLMOD_MATRIXOPS_H #include "cholmod_core.h" /* -------------------------------------------------------------------------- */ /* cholmod_drop: drop entries with small absolute value */ /* -------------------------------------------------------------------------- */ int cholmod_drop ( /* ---- input ---- */ double tol, /* keep entries with absolute value > tol */ /* ---- in/out --- */ cholmod_sparse *A, /* matrix to drop entries from */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_drop (double, cholmod_sparse *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_norm_dense: s = norm (X), 1-norm, inf-norm, or 2-norm */ /* -------------------------------------------------------------------------- */ double cholmod_norm_dense ( /* ---- input ---- */ cholmod_dense *X, /* matrix to compute the norm of */ int norm, /* type of norm: 0: inf. norm, 1: 1-norm, 2: 2-norm */ /* --------------- */ cholmod_common *Common ) ; double cholmod_l_norm_dense (cholmod_dense *, int, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_norm_sparse: s = norm (A), 1-norm or inf-norm */ /* -------------------------------------------------------------------------- */ double cholmod_norm_sparse ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to compute the norm of */ int norm, /* type of norm: 0: inf. norm, 1: 1-norm */ /* --------------- */ cholmod_common *Common ) ; double cholmod_l_norm_sparse (cholmod_sparse *, int, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_horzcat: C = [A,B] */ /* -------------------------------------------------------------------------- */ cholmod_sparse *cholmod_horzcat ( /* ---- input ---- */ cholmod_sparse *A, /* left matrix to concatenate */ cholmod_sparse *B, /* right matrix to concatenate */ int values, /* if TRUE compute the numerical values of C */ /* --------------- */ cholmod_common *Common ) ; cholmod_sparse *cholmod_l_horzcat (cholmod_sparse *, cholmod_sparse *, int, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_scale: A = diag(s)*A, A*diag(s), s*A or diag(s)*A*diag(s) */ /* -------------------------------------------------------------------------- */ /* scaling modes, selected by the scale input parameter: */ #define CHOLMOD_SCALAR 0 /* A = s*A */ #define CHOLMOD_ROW 1 /* A = diag(s)*A */ #define CHOLMOD_COL 2 /* A = A*diag(s) */ #define CHOLMOD_SYM 3 /* A = diag(s)*A*diag(s) */ int cholmod_scale ( /* ---- input ---- */ cholmod_dense *S, /* scale factors (scalar or vector) */ int scale, /* type of scaling to compute */ /* ---- in/out --- */ cholmod_sparse *A, /* matrix to scale */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_scale (cholmod_dense *, int, cholmod_sparse *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_sdmult: Y = alpha*(A*X) + beta*Y or alpha*(A'*X) + beta*Y */ /* -------------------------------------------------------------------------- */ /* Sparse matrix times dense matrix */ int cholmod_sdmult ( /* ---- input ---- */ cholmod_sparse *A, /* sparse matrix to multiply */ int transpose, /* use A if 0, or A' otherwise */ double alpha [2], /* scale factor for A */ double beta [2], /* scale factor for Y */ cholmod_dense *X, /* dense matrix to multiply */ /* ---- in/out --- */ cholmod_dense *Y, /* resulting dense matrix */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_sdmult (cholmod_sparse *, int, double [2], double [2], cholmod_dense *, cholmod_dense *Y, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_ssmult: C = A*B */ /* -------------------------------------------------------------------------- */ /* Sparse matrix times sparse matrix */ cholmod_sparse *cholmod_ssmult ( /* ---- input ---- */ cholmod_sparse *A, /* left matrix to multiply */ cholmod_sparse *B, /* right matrix to multiply */ int stype, /* requested stype of C */ int values, /* TRUE: do numerical values, FALSE: pattern only */ int sorted, /* if TRUE then return C with sorted columns */ /* --------------- */ cholmod_common *Common ) ; cholmod_sparse *cholmod_l_ssmult (cholmod_sparse *, cholmod_sparse *, int, int, int, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_submatrix: C = A (r,c), where i and j are arbitrary vectors */ /* -------------------------------------------------------------------------- */ /* rsize < 0 denotes ":" in MATLAB notation, or more precisely 0:(A->nrow)-1. * In this case, r can be NULL. An rsize of zero, or r = NULL and rsize >= 0, * denotes "[ ]" in MATLAB notation (the empty set). * Similar rules hold for csize. */ cholmod_sparse *cholmod_submatrix ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to subreference */ int *rset, /* set of row indices, duplicates OK */ SuiteSparse_long rsize, /* size of r; rsize < 0 denotes ":" */ int *cset, /* set of column indices, duplicates OK */ SuiteSparse_long csize, /* size of c; csize < 0 denotes ":" */ int values, /* if TRUE compute the numerical values of C */ int sorted, /* if TRUE then return C with sorted columns */ /* --------------- */ cholmod_common *Common ) ; cholmod_sparse *cholmod_l_submatrix (cholmod_sparse *, SuiteSparse_long *, SuiteSparse_long, SuiteSparse_long *, SuiteSparse_long, int, int, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_vertcat: C = [A ; B] */ /* -------------------------------------------------------------------------- */ cholmod_sparse *cholmod_vertcat ( /* ---- input ---- */ cholmod_sparse *A, /* left matrix to concatenate */ cholmod_sparse *B, /* right matrix to concatenate */ int values, /* if TRUE compute the numerical values of C */ /* --------------- */ cholmod_common *Common ) ; cholmod_sparse *cholmod_l_vertcat (cholmod_sparse *, cholmod_sparse *, int, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_symmetry: determine if a sparse matrix is symmetric */ /* -------------------------------------------------------------------------- */ int cholmod_symmetry ( /* ---- input ---- */ cholmod_sparse *A, int option, /* ---- output ---- */ int *xmatched, int *pmatched, int *nzoffdiag, int *nzdiag, /* --------------- */ cholmod_common *Common ) ; int cholmod_l_symmetry (cholmod_sparse *, int, SuiteSparse_long *, SuiteSparse_long *, SuiteSparse_long *, SuiteSparse_long *, cholmod_common *) ; #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Include/cholmod_check.h����������������������������������������������������������0000644�0001762�0000144�00000035003�13652535054�017721� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Include/cholmod_check.h ============================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Include/cholmod_check.h. Copyright (C) 2005-2006, Timothy A. Davis * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* CHOLMOD Check module. * * Routines that check and print the 5 basic data types in CHOLMOD, and 3 kinds * of integer vectors (subset, perm, and parent), and read in matrices from a * file: * * cholmod_check_common check/print the Common object * cholmod_print_common * * cholmod_check_sparse check/print a sparse matrix in column-oriented form * cholmod_print_sparse * * cholmod_check_dense check/print a dense matrix * cholmod_print_dense * * cholmod_check_factor check/print a Cholesky factorization * cholmod_print_factor * * cholmod_check_triplet check/print a sparse matrix in triplet form * cholmod_print_triplet * * cholmod_check_subset check/print a subset (integer vector in given range) * cholmod_print_subset * * cholmod_check_perm check/print a permutation (an integer vector) * cholmod_print_perm * * cholmod_check_parent check/print an elimination tree (an integer vector) * cholmod_print_parent * * cholmod_read_triplet read a matrix in triplet form (any Matrix Market * "coordinate" format, or a generic triplet format). * * cholmod_read_sparse read a matrix in sparse form (same file format as * cholmod_read_triplet). * * cholmod_read_dense read a dense matrix (any Matrix Market "array" * format, or a generic dense format). * * cholmod_write_sparse write a sparse matrix to a Matrix Market file. * * cholmod_write_dense write a dense matrix to a Matrix Market file. * * cholmod_print_common and cholmod_check_common are the only two routines that * you may call after calling cholmod_finish. * * Requires the Core module. Not required by any CHOLMOD module, except when * debugging is enabled (in which case all modules require the Check module). * * See cholmod_read.c for a description of the file formats supported by the * cholmod_read_* routines. */ #ifndef CHOLMOD_CHECK_H #define CHOLMOD_CHECK_H #include "cholmod_core.h" #include /* -------------------------------------------------------------------------- */ /* cholmod_check_common: check the Common object */ /* -------------------------------------------------------------------------- */ int cholmod_check_common ( cholmod_common *Common ) ; int cholmod_l_check_common (cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_print_common: print the Common object */ /* -------------------------------------------------------------------------- */ int cholmod_print_common ( /* ---- input ---- */ const char *name, /* printed name of Common object */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_print_common (const char *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_gpu_stats: print the GPU / CPU statistics */ /* -------------------------------------------------------------------------- */ int cholmod_gpu_stats (cholmod_common *) ; int cholmod_l_gpu_stats (cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_check_sparse: check a sparse matrix */ /* -------------------------------------------------------------------------- */ int cholmod_check_sparse ( /* ---- input ---- */ cholmod_sparse *A, /* sparse matrix to check */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_check_sparse (cholmod_sparse *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_print_sparse */ /* -------------------------------------------------------------------------- */ int cholmod_print_sparse ( /* ---- input ---- */ cholmod_sparse *A, /* sparse matrix to print */ const char *name, /* printed name of sparse matrix */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_print_sparse (cholmod_sparse *, const char *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_check_dense: check a dense matrix */ /* -------------------------------------------------------------------------- */ int cholmod_check_dense ( /* ---- input ---- */ cholmod_dense *X, /* dense matrix to check */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_check_dense (cholmod_dense *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_print_dense: print a dense matrix */ /* -------------------------------------------------------------------------- */ int cholmod_print_dense ( /* ---- input ---- */ cholmod_dense *X, /* dense matrix to print */ const char *name, /* printed name of dense matrix */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_print_dense (cholmod_dense *, const char *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_check_factor: check a factor */ /* -------------------------------------------------------------------------- */ int cholmod_check_factor ( /* ---- input ---- */ cholmod_factor *L, /* factor to check */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_check_factor (cholmod_factor *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_print_factor: print a factor */ /* -------------------------------------------------------------------------- */ int cholmod_print_factor ( /* ---- input ---- */ cholmod_factor *L, /* factor to print */ const char *name, /* printed name of factor */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_print_factor (cholmod_factor *, const char *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_check_triplet: check a sparse matrix in triplet form */ /* -------------------------------------------------------------------------- */ int cholmod_check_triplet ( /* ---- input ---- */ cholmod_triplet *T, /* triplet matrix to check */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_check_triplet (cholmod_triplet *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_print_triplet: print a triplet matrix */ /* -------------------------------------------------------------------------- */ int cholmod_print_triplet ( /* ---- input ---- */ cholmod_triplet *T, /* triplet matrix to print */ const char *name, /* printed name of triplet matrix */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_print_triplet (cholmod_triplet *, const char *, cholmod_common *); /* -------------------------------------------------------------------------- */ /* cholmod_check_subset: check a subset */ /* -------------------------------------------------------------------------- */ int cholmod_check_subset ( /* ---- input ---- */ int *Set, /* Set [0:len-1] is a subset of 0:n-1. Duplicates OK */ SuiteSparse_long len, /* size of Set (an integer array) */ size_t n, /* 0:n-1 is valid range */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_check_subset (SuiteSparse_long *, SuiteSparse_long, size_t, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_print_subset: print a subset */ /* -------------------------------------------------------------------------- */ int cholmod_print_subset ( /* ---- input ---- */ int *Set, /* Set [0:len-1] is a subset of 0:n-1. Duplicates OK */ SuiteSparse_long len, /* size of Set (an integer array) */ size_t n, /* 0:n-1 is valid range */ const char *name, /* printed name of Set */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_print_subset (SuiteSparse_long *, SuiteSparse_long, size_t, const char *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_check_perm: check a permutation */ /* -------------------------------------------------------------------------- */ int cholmod_check_perm ( /* ---- input ---- */ int *Perm, /* Perm [0:len-1] is a permutation of subset of 0:n-1 */ size_t len, /* size of Perm (an integer array) */ size_t n, /* 0:n-1 is valid range */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_check_perm (SuiteSparse_long *, size_t, size_t, cholmod_common *); /* -------------------------------------------------------------------------- */ /* cholmod_print_perm: print a permutation vector */ /* -------------------------------------------------------------------------- */ int cholmod_print_perm ( /* ---- input ---- */ int *Perm, /* Perm [0:len-1] is a permutation of subset of 0:n-1 */ size_t len, /* size of Perm (an integer array) */ size_t n, /* 0:n-1 is valid range */ const char *name, /* printed name of Perm */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_print_perm (SuiteSparse_long *, size_t, size_t, const char *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_check_parent: check an elimination tree */ /* -------------------------------------------------------------------------- */ int cholmod_check_parent ( /* ---- input ---- */ int *Parent, /* Parent [0:n-1] is an elimination tree */ size_t n, /* size of Parent */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_check_parent (SuiteSparse_long *, size_t, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_print_parent */ /* -------------------------------------------------------------------------- */ int cholmod_print_parent ( /* ---- input ---- */ int *Parent, /* Parent [0:n-1] is an elimination tree */ size_t n, /* size of Parent */ const char *name, /* printed name of Parent */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_print_parent (SuiteSparse_long *, size_t, const char *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_read_sparse: read a sparse matrix from a file */ /* -------------------------------------------------------------------------- */ cholmod_sparse *cholmod_read_sparse ( /* ---- input ---- */ FILE *f, /* file to read from, must already be open */ /* --------------- */ cholmod_common *Common ) ; cholmod_sparse *cholmod_l_read_sparse (FILE *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_read_triplet: read a triplet matrix from a file */ /* -------------------------------------------------------------------------- */ cholmod_triplet *cholmod_read_triplet ( /* ---- input ---- */ FILE *f, /* file to read from, must already be open */ /* --------------- */ cholmod_common *Common ) ; cholmod_triplet *cholmod_l_read_triplet (FILE *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_read_dense: read a dense matrix from a file */ /* -------------------------------------------------------------------------- */ cholmod_dense *cholmod_read_dense ( /* ---- input ---- */ FILE *f, /* file to read from, must already be open */ /* --------------- */ cholmod_common *Common ) ; cholmod_dense *cholmod_l_read_dense (FILE *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_read_matrix: read a sparse or dense matrix from a file */ /* -------------------------------------------------------------------------- */ void *cholmod_read_matrix ( /* ---- input ---- */ FILE *f, /* file to read from, must already be open */ int prefer, /* If 0, a sparse matrix is always return as a * cholmod_triplet form. It can have any stype * (symmetric-lower, unsymmetric, or * symmetric-upper). * If 1, a sparse matrix is returned as an unsymmetric * cholmod_sparse form (A->stype == 0), with both * upper and lower triangular parts present. * This is what the MATLAB mread mexFunction does, * since MATLAB does not have an stype. * If 2, a sparse matrix is returned with an stype of 0 * or 1 (unsymmetric, or symmetric with upper part * stored). * This argument has no effect for dense matrices. */ /* ---- output---- */ int *mtype, /* CHOLMOD_TRIPLET, CHOLMOD_SPARSE or CHOLMOD_DENSE */ /* --------------- */ cholmod_common *Common ) ; void *cholmod_l_read_matrix (FILE *, int, int *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_write_sparse: write a sparse matrix to a file */ /* -------------------------------------------------------------------------- */ int cholmod_write_sparse ( /* ---- input ---- */ FILE *f, /* file to write to, must already be open */ cholmod_sparse *A, /* matrix to print */ cholmod_sparse *Z, /* optional matrix with pattern of explicit zeros */ const char *comments, /* optional filename of comments to include */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_write_sparse (FILE *, cholmod_sparse *, cholmod_sparse *, const char *c, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_write_dense: write a dense matrix to a file */ /* -------------------------------------------------------------------------- */ int cholmod_write_dense ( /* ---- input ---- */ FILE *f, /* file to write to, must already be open */ cholmod_dense *X, /* matrix to print */ const char *comments, /* optional filename of comments to include */ /* --------------- */ cholmod_common *Common ) ; int cholmod_l_write_dense (FILE *, cholmod_dense *, const char *, cholmod_common *) ; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Include/cholmod_complexity.h�����������������������������������������������������0000644�0001762�0000144�00000022310�13652535054�021036� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Include/cholmod_complexity.h ========================================= */ /* ========================================================================== */ /* Define operations on pattern, real, complex, and zomplex objects. * * The xtype of an object defines it numerical type. A qttern object has no * numerical values (A->x and A->z are NULL). A real object has no imaginary * qrt (A->x is used, A->z is NULL). A complex object has an imaginary qrt * that is stored interleaved with its real qrt (A->x is of size 2*nz, A->z * is NULL). A zomplex object has both real and imaginary qrts, which are * stored seqrately, as in MATLAB (A->x and A->z are both used). * * XTYPE is CHOLMOD_PATTERN, _REAL, _COMPLEX or _ZOMPLEX, and is the xtype of * the template routine under construction. XTYPE2 is equal to XTYPE, except * if XTYPE is CHOLMOD_PATTERN, in which case XTYPE is CHOLMOD_REAL. * XTYPE and XTYPE2 are defined in cholmod_template.h. */ /* -------------------------------------------------------------------------- */ /* pattern */ /* -------------------------------------------------------------------------- */ #define P_TEMPLATE(name) p_ ## name #define P_ASSIGN2(x,z,p,ax,az,q) x [p] = 1 #define P_PRINT(k,x,z,p) PRK(k, ("1")) /* -------------------------------------------------------------------------- */ /* real */ /* -------------------------------------------------------------------------- */ #define R_TEMPLATE(name) r_ ## name #define R_ASSEMBLE(x,z,p,ax,az,q) x [p] += ax [q] #define R_ASSIGN(x,z,p,ax,az,q) x [p] = ax [q] #define R_ASSIGN_CONJ(x,z,p,ax,az,q) x [p] = ax [q] #define R_ASSIGN_REAL(x,p,ax,q) x [p] = ax [q] #define R_XTYPE_OK(type) ((type) == CHOLMOD_REAL) #define R_IS_NONZERO(ax,az,q) IS_NONZERO (ax [q]) #define R_IS_ZERO(ax,az,q) IS_ZERO (ax [q]) #define R_IS_ONE(ax,az,q) (ax [q] == 1) #define R_MULT(x,z,p, ax,az,q, bx,bz,r) x [p] = ax [q] * bx [r] #define R_MULTADD(x,z,p, ax,az,q, bx,bz,r) x [p] += ax [q] * bx [r] #define R_MULTSUB(x,z,p, ax,az,q, bx,bz,r) x [p] -= ax [q] * bx [r] #define R_MULTADDCONJ(x,z,p, ax,az,q, bx,bz,r) x [p] += ax [q] * bx [r] #define R_MULTSUBCONJ(x,z,p, ax,az,q, bx,bz,r) x [p] -= ax [q] * bx [r] #define R_ADD(x,z,p, ax,az,q, bx,bz,r) x [p] = ax [q] + bx [r] #define R_ADD_REAL(x,p, ax,q, bx,r) x [p] = ax [q] + bx [r] #define R_CLEAR(x,z,p) x [p] = 0 #define R_CLEAR_IMAG(x,z,p) #define R_DIV(x,z,p,ax,az,q) x [p] /= ax [q] #define R_LLDOT(x,p, ax,az,q) x [p] -= ax [q] * ax [q] #define R_PRINT(k,x,z,p) PRK(k, ("%24.16e", x [p])) #define R_DIV_REAL(x,z,p, ax,az,q, bx,r) x [p] = ax [q] / bx [r] #define R_MULT_REAL(x,z,p, ax,az,q, bx,r) x [p] = ax [q] * bx [r] #define R_LDLDOT(x,p, ax,az,q, bx,r) x [p] -=(ax[q] * ax[q])/ bx[r] /* -------------------------------------------------------------------------- */ /* complex */ /* -------------------------------------------------------------------------- */ #define C_TEMPLATE(name) c_ ## name #define CT_TEMPLATE(name) ct_ ## name #define C_ASSEMBLE(x,z,p,ax,az,q) \ x [2*(p) ] += ax [2*(q) ] ; \ x [2*(p)+1] += ax [2*(q)+1] #define C_ASSIGN(x,z,p,ax,az,q) \ x [2*(p) ] = ax [2*(q) ] ; \ x [2*(p)+1] = ax [2*(q)+1] #define C_ASSIGN_REAL(x,p,ax,q) x [2*(p)] = ax [2*(q)] #define C_ASSIGN_CONJ(x,z,p,ax,az,q) \ x [2*(p) ] = ax [2*(q) ] ; \ x [2*(p)+1] = -ax [2*(q)+1] #define C_XTYPE_OK(type) ((type) == CHOLMOD_COMPLEX) #define C_IS_NONZERO(ax,az,q) \ (IS_NONZERO (ax [2*(q)]) || IS_NONZERO (ax [2*(q)+1])) #define C_IS_ZERO(ax,az,q) \ (IS_ZERO (ax [2*(q)]) && IS_ZERO (ax [2*(q)+1])) #define C_IS_ONE(ax,az,q) \ ((ax [2*(q)] == 1) && IS_ZERO (ax [2*(q)+1])) #define C_IMAG_IS_NONZERO(ax,az,q) (IS_NONZERO (ax [2*(q)+1])) #define C_MULT(x,z,p, ax,az,q, bx,bz,r) \ x [2*(p) ] = ax [2*(q) ] * bx [2*(r)] - ax [2*(q)+1] * bx [2*(r)+1] ; \ x [2*(p)+1] = ax [2*(q)+1] * bx [2*(r)] + ax [2*(q) ] * bx [2*(r)+1] #define C_MULTADD(x,z,p, ax,az,q, bx,bz,r) \ x [2*(p) ] += ax [2*(q) ] * bx [2*(r)] - ax [2*(q)+1] * bx [2*(r)+1] ; \ x [2*(p)+1] += ax [2*(q)+1] * bx [2*(r)] + ax [2*(q) ] * bx [2*(r)+1] #define C_MULTSUB(x,z,p, ax,az,q, bx,bz,r) \ x [2*(p) ] -= ax [2*(q) ] * bx [2*(r)] - ax [2*(q)+1] * bx [2*(r)+1] ; \ x [2*(p)+1] -= ax [2*(q)+1] * bx [2*(r)] + ax [2*(q) ] * bx [2*(r)+1] /* s += conj(a)*b */ #define C_MULTADDCONJ(x,z,p, ax,az,q, bx,bz,r) \ x [2*(p) ] += ax [2*(q) ] * bx [2*(r)] + ax [2*(q)+1] * bx [2*(r)+1] ; \ x [2*(p)+1] += (-ax [2*(q)+1]) * bx [2*(r)] + ax [2*(q) ] * bx [2*(r)+1] /* s -= conj(a)*b */ #define C_MULTSUBCONJ(x,z,p, ax,az,q, bx,bz,r) \ x [2*(p) ] -= ax [2*(q) ] * bx [2*(r)] + ax [2*(q)+1] * bx [2*(r)+1] ; \ x [2*(p)+1] -= (-ax [2*(q)+1]) * bx [2*(r)] + ax [2*(q) ] * bx [2*(r)+1] #define C_ADD(x,z,p, ax,az,q, bx,bz,r) \ x [2*(p) ] = ax [2*(q) ] + bx [2*(r) ] ; \ x [2*(p)+1] = ax [2*(q)+1] + bx [2*(r)+1] #define C_ADD_REAL(x,p, ax,q, bx,r) \ x [2*(p)] = ax [2*(q)] + bx [2*(r)] #define C_CLEAR(x,z,p) \ x [2*(p) ] = 0 ; \ x [2*(p)+1] = 0 #define C_CLEAR_IMAG(x,z,p) \ x [2*(p)+1] = 0 /* s = s / a */ #define C_DIV(x,z,p,ax,az,q) \ SuiteSparse_config.divcomplex_func ( \ x [2*(p)], x [2*(p)+1], \ ax [2*(q)], ax [2*(q)+1], \ &x [2*(p)], &x [2*(p)+1]) /* s -= conj(a)*a ; note that the result of conj(a)*a is real */ #define C_LLDOT(x,p, ax,az,q) \ x [2*(p)] -= ax [2*(q)] * ax [2*(q)] + ax [2*(q)+1] * ax [2*(q)+1] #define C_PRINT(k,x,z,p) PRK(k, ("(%24.16e,%24.16e)", x [2*(p)], x [2*(p)+1])) #define C_DIV_REAL(x,z,p, ax,az,q, bx,r) \ x [2*(p) ] = ax [2*(q) ] / bx [2*(r)] ; \ x [2*(p)+1] = ax [2*(q)+1] / bx [2*(r)] #define C_MULT_REAL(x,z,p, ax,az,q, bx,r) \ x [2*(p) ] = ax [2*(q) ] * bx [2*(r)] ; \ x [2*(p)+1] = ax [2*(q)+1] * bx [2*(r)] /* s -= conj(a)*a/t */ #define C_LDLDOT(x,p, ax,az,q, bx,r) \ x [2*(p)] -= (ax [2*(q)] * ax [2*(q)] + ax [2*(q)+1] * ax [2*(q)+1]) / bx[r] /* -------------------------------------------------------------------------- */ /* zomplex */ /* -------------------------------------------------------------------------- */ #define Z_TEMPLATE(name) z_ ## name #define ZT_TEMPLATE(name) zt_ ## name #define Z_ASSEMBLE(x,z,p,ax,az,q) \ x [p] += ax [q] ; \ z [p] += az [q] #define Z_ASSIGN(x,z,p,ax,az,q) \ x [p] = ax [q] ; \ z [p] = az [q] #define Z_ASSIGN_REAL(x,p,ax,q) x [p] = ax [q] #define Z_ASSIGN_CONJ(x,z,p,ax,az,q) \ x [p] = ax [q] ; \ z [p] = -az [q] #define Z_XTYPE_OK(type) ((type) == CHOLMOD_ZOMPLEX) #define Z_IS_NONZERO(ax,az,q) \ (IS_NONZERO (ax [q]) || IS_NONZERO (az [q])) #define Z_IS_ZERO(ax,az,q) \ (IS_ZERO (ax [q]) && IS_ZERO (az [q])) #define Z_IS_ONE(ax,az,q) \ ((ax [q] == 1) && IS_ZERO (az [q])) #define Z_IMAG_IS_NONZERO(ax,az,q) (IS_NONZERO (az [q])) #define Z_MULT(x,z,p, ax,az,q, bx,bz,r) \ x [p] = ax [q] * bx [r] - az [q] * bz [r] ; \ z [p] = az [q] * bx [r] + ax [q] * bz [r] #define Z_MULTADD(x,z,p, ax,az,q, bx,bz,r) \ x [p] += ax [q] * bx [r] - az [q] * bz [r] ; \ z [p] += az [q] * bx [r] + ax [q] * bz [r] #define Z_MULTSUB(x,z,p, ax,az,q, bx,bz,r) \ x [p] -= ax [q] * bx [r] - az [q] * bz [r] ; \ z [p] -= az [q] * bx [r] + ax [q] * bz [r] #define Z_MULTADDCONJ(x,z,p, ax,az,q, bx,bz,r) \ x [p] += ax [q] * bx [r] + az [q] * bz [r] ; \ z [p] += (-az [q]) * bx [r] + ax [q] * bz [r] #define Z_MULTSUBCONJ(x,z,p, ax,az,q, bx,bz,r) \ x [p] -= ax [q] * bx [r] + az [q] * bz [r] ; \ z [p] -= (-az [q]) * bx [r] + ax [q] * bz [r] #define Z_ADD(x,z,p, ax,az,q, bx,bz,r) \ x [p] = ax [q] + bx [r] ; \ z [p] = az [q] + bz [r] #define Z_ADD_REAL(x,p, ax,q, bx,r) \ x [p] = ax [q] + bx [r] #define Z_CLEAR(x,z,p) \ x [p] = 0 ; \ z [p] = 0 #define Z_CLEAR_IMAG(x,z,p) \ z [p] = 0 /* s = s / a */ #define Z_DIV(x,z,p,ax,az,q) \ SuiteSparse_config.divcomplex_func \ (x [p], z [p], ax [q], az [q], &x [p], &z [p]) /* s -= conj(a)*a ; note that the result of conj(a)*a is real */ #define Z_LLDOT(x,p, ax,az,q) \ x [p] -= ax [q] * ax [q] + az [q] * az [q] #define Z_PRINT(k,x,z,p) PRK(k, ("(%24.16e,%24.16e)", x [p], z [p])) #define Z_DIV_REAL(x,z,p, ax,az,q, bx,r) \ x [p] = ax [q] / bx [r] ; \ z [p] = az [q] / bx [r] #define Z_MULT_REAL(x,z,p, ax,az,q, bx,r) \ x [p] = ax [q] * bx [r] ; \ z [p] = az [q] * bx [r] /* s -= conj(a)*a/t */ #define Z_LDLDOT(x,p, ax,az,q, bx,r) \ x [p] -= (ax [q] * ax [q] + az [q] * az [q]) / bx[r] /* -------------------------------------------------------------------------- */ /* all classes */ /* -------------------------------------------------------------------------- */ /* Check if A->xtype and the two arrays A->x and A->z are valid. Set status to * invalid, unless status is already "out of memory". A can be a sparse matrix, * dense matrix, factor, or triplet. */ #define RETURN_IF_XTYPE_INVALID(A,xtype1,xtype2,result) \ { \ if ((A)->xtype < (xtype1) || (A)->xtype > (xtype2) || \ ((A)->xtype != CHOLMOD_PATTERN && ((A)->x) == NULL) || \ ((A)->xtype == CHOLMOD_ZOMPLEX && ((A)->z) == NULL)) \ { \ if (Common->status != CHOLMOD_OUT_OF_MEMORY) \ { \ ERROR (CHOLMOD_INVALID, "invalid xtype") ; \ } \ return (result) ; \ } \ } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Include/cholmod_config.h���������������������������������������������������������0000644�0001762�0000144�00000005071�13652535054�020113� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Include/cholmod_config.h ============================================= */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Include/cholmod_config.h. * Copyright (C) 2005-2013, Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* CHOLMOD configuration file, for inclusion in user programs. * * You do not have to edit any CHOLMOD files to compile and install CHOLMOD. * However, if you do not use all of CHOLMOD's modules, you need to compile * with the appropriate flag, or edit this file to add the appropriate #define. * * Compiler flags for CHOLMOD: * * -DNCHECK do not include the Check module. * -DNCHOLESKY do not include the Cholesky module. * -DNPARTITION do not include the Partition module. * -DNCAMD do not include the interfaces to CAMD, * CCOLAMD, CSYMAND in Partition module. * -DNMATRIXOPS do not include the MatrixOps module. * -DNMODIFY do not include the Modify module. * -DNSUPERNODAL do not include the Supernodal module. * * -DNPRINT do not print anything * * -D'LONGBLAS=long' or -DLONGBLAS='long long' defines the integers used by * LAPACK and the BLAS. Use LONGBLAS=long on Solaris to use * the 64-bit Sun Performance BLAS in cholmod_l_* routines. * You may need to use -D'LONGBLAS=long long' on the SGI * (this is not tested). * * -DNSUNPERF for Solaris only. If defined, do not use the Sun * Performance Library. The default is to use SunPerf. * You must compile CHOLMOD with -xlic_lib=sunperf. * * The Core Module is always included in the CHOLMOD library. */ #ifndef CHOLMOD_CONFIG_H #define CHOLMOD_CONFIG_H /* Use the compiler flag, or uncomment the definition(s), if you want to use * one or more non-default installation options: */ /* #define NCHECK #define NCHOLESKY #define NCAMD #define NPARTITION #define NMATRIXOPS #define NMODIFY #define NSUPERNODAL #define NPRINT #define LONGBLAS long #define LONGBLAS long long #define NSUNPERF */ /* The option disables the MatrixOps, Modify, and Supernodal modules. The existence of this #define here, and its use in these 3 modules, does not affect the license itself; see CHOLMOD/Doc/License.txt for your actual license. */ #ifdef NGPL #define NMATRIXOPS #define NMODIFY #define NSUPERNODAL #endif #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Cholesky/������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14547723665�015176� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Cholesky/cholmod_solve.c���������������������������������������������������������0000644�0001762�0000144�00000141157�13652535054�020175� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Cholesky/cholmod_solve =============================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Cholesky Module. Copyright (C) 2005-2013, Timothy A. Davis * -------------------------------------------------------------------------- */ /* Solve one of the following systems. D is identity for an LL' factorization, * in which the D operation is skipped: * * Ax=b 0: CHOLMOD_A x = P' * (L' \ (D \ (L \ (P * b)))) * LDL'x=b 1: CHOLMOD_LDLt x = (L' \ (D \ (L \ ( b)))) * LDx=b 2: CHOLMOD_LD x = ( (D \ (L \ ( b)))) * DL'x=b 3: CHOLMOD_DLt x = (L' \ (D \ ( ( b)))) * Lx=b 4: CHOLMOD_L x = ( ( (L \ ( b)))) * L'x=b 5: CHOLMOD_Lt x = (L' \ ( ( ( b)))) * Dx=b 6: CHOLMOD_D x = ( (D \ ( ( b)))) * x=Pb 7: CHOLMOD_P x = ( ( ( (P * b)))) * x=P'b 8: CHOLMOD_Pt x = P' * ( ( ( ( b)))) * * The factorization can be simplicial LDL', simplicial LL', or supernodal LL'. * For an LL' factorization, D is the identity matrix. Thus CHOLMOD_LD and * CHOLMOD_L solve the same system if an LL' factorization was performed, * for example. * * The supernodal solver uses BLAS routines dtrsv, dgemv, dtrsm, and dgemm, * or their complex counterparts ztrsv, zgemv, ztrsm, and zgemm. * * If both L and B are real, then X is returned real. If either is complex * or zomplex, X is returned as either complex or zomplex, depending on the * Common->prefer_zomplex parameter. * * Supports any numeric xtype (pattern-only matrices not supported). * * This routine does not check to see if the diagonal of L or D is zero, * because sometimes a partial solve can be done with indefinite or singular * matrix. If you wish to check in your own code, test L->minor. If * L->minor == L->n, then the matrix has no zero diagonal entries. * If k = L->minor < L->n, then L(k,k) is zero for an LL' factorization, or * D(k,k) is zero for an LDL' factorization. * * This routine returns X as NULL only if it runs out of memory. If L is * indefinite or singular, then X may contain Inf's or NaN's, but it will * exist on output. */ #ifndef NCHOLESKY #include "cholmod_internal.h" #include "cholmod_cholesky.h" #ifndef NSUPERNODAL #include "cholmod_supernodal.h" #endif /* ========================================================================== */ /* === TEMPLATE ============================================================= */ /* ========================================================================== */ #define REAL #include "t_cholmod_solve.c" #define COMPLEX #include "t_cholmod_solve.c" #define ZOMPLEX #include "t_cholmod_solve.c" /* ========================================================================== */ /* === Permutation macro ==================================================== */ /* ========================================================================== */ /* If Perm is NULL, it is interpretted as the identity permutation */ #define P(k) ((Perm == NULL) ? (k) : Perm [k]) /* ========================================================================== */ /* === perm ================================================================= */ /* ========================================================================== */ /* Y = B (P (1:nrow), k1 : min (k1+ncols,ncol)-1) where B is nrow-by-ncol. * * Creates a permuted copy of a contiguous set of columns of B. * Y is already allocated on input. Y must be of sufficient size. Let nk be * the number of columns accessed in B. Y->xtype determines the complexity of * the result. * * If B is real and Y is complex (or zomplex), only the real part of B is * copied into Y. The imaginary part of Y is set to zero. * * If B is complex (or zomplex) and Y is real, both the real and imaginary and * parts of B are returned in Y. Y is returned as nrow-by-2*nk. The even * columns of Y contain the real part of B and the odd columns contain the * imaginary part of B. Y->nzmax must be >= 2*nrow*nk. Otherise, Y is * returned as nrow-by-nk with leading dimension nrow. Y->nzmax must be >= * nrow*nk. * * The case where the input (B) is real and the output (Y) is zomplex is * not used. */ static void perm ( /* ---- input ---- */ cholmod_dense *B, /* input matrix B */ Int *Perm, /* optional input permutation (can be NULL) */ Int k1, /* first column of B to copy */ Int ncols, /* last column to copy is min(k1+ncols,B->ncol)-1 */ /* ---- in/out --- */ cholmod_dense *Y /* output matrix Y, already allocated */ ) { double *Yx, *Yz, *Bx, *Bz ; Int k2, nk, p, k, j, nrow, ncol, d, dual, dj, j2 ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ ncol = B->ncol ; nrow = B->nrow ; k2 = MIN (k1+ncols, ncol) ; nk = MAX (k2 - k1, 0) ; dual = (Y->xtype == CHOLMOD_REAL && B->xtype != CHOLMOD_REAL) ? 2 : 1 ; d = B->d ; Bx = B->x ; Bz = B->z ; Yx = Y->x ; Yz = Y->z ; Y->nrow = nrow ; Y->ncol = dual*nk ; Y->d = nrow ; ASSERT (((Int) Y->nzmax) >= nrow*nk*dual) ; /* ---------------------------------------------------------------------- */ /* Y = B (P (1:nrow), k1:k2-1) */ /* ---------------------------------------------------------------------- */ switch (Y->xtype) { case CHOLMOD_REAL: switch (B->xtype) { case CHOLMOD_REAL: /* Y real, B real */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = nrow * (j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Yx [k + j2] = Bx [p] ; /* real */ } } break ; case CHOLMOD_COMPLEX: /* Y real, B complex. Y is nrow-by-2*nk */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = nrow * 2 * (j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Yx [k + j2 ] = Bx [2*p ] ; /* real */ Yx [k + j2 + nrow] = Bx [2*p+1] ; /* imag */ } } break ; case CHOLMOD_ZOMPLEX: /* Y real, B zomplex. Y is nrow-by-2*nk */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = nrow * 2 * (j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Yx [k + j2 ] = Bx [p] ; /* real */ Yx [k + j2 + nrow] = Bz [p] ; /* imag */ } } break ; } break ; case CHOLMOD_COMPLEX: switch (B->xtype) { case CHOLMOD_REAL: /* Y complex, B real */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = nrow * 2 * (j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Yx [2*k + j2] = Bx [p] ; /* real */ Yx [2*k+1 + j2] = 0 ; /* imag */ } } break ; case CHOLMOD_COMPLEX: /* Y complex, B complex */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = nrow * 2 * (j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Yx [2*k + j2] = Bx [2*p ] ; /* real */ Yx [2*k+1 + j2] = Bx [2*p+1] ; /* imag */ } } break ; case CHOLMOD_ZOMPLEX: /* Y complex, B zomplex */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = nrow * 2 * (j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Yx [2*k + j2] = Bx [p] ; /* real */ Yx [2*k+1 + j2] = Bz [p] ; /* imag */ } } break ; } break ; case CHOLMOD_ZOMPLEX: switch (B->xtype) { #if 0 case CHOLMOD_REAL: /* this case is not used */ break ; #endif case CHOLMOD_COMPLEX: /* Y zomplex, B complex */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = nrow * (j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Yx [k + j2] = Bx [2*p ] ; /* real */ Yz [k + j2] = Bx [2*p+1] ; /* imag */ } } break ; case CHOLMOD_ZOMPLEX: /* Y zomplex, B zomplex */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = nrow * (j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Yx [k + j2] = Bx [p] ; /* real */ Yz [k + j2] = Bz [p] ; /* imag */ } } break ; } break ; } } /* ========================================================================== */ /* === iperm ================================================================ */ /* ========================================================================== */ /* X (P (1:nrow), k1 : min (k1+ncols,ncol)-1) = Y where X is nrow-by-ncol. * * Copies and permutes Y into a contiguous set of columns of X. X is already * allocated on input. Y must be of sufficient size. Let nk be the number * of columns accessed in X. X->xtype determines the complexity of the result. * * If X is real and Y is complex (or zomplex), only the real part of B is * copied into X. The imaginary part of Y is ignored. * * If X is complex (or zomplex) and Y is real, both the real and imaginary and * parts of Y are returned in X. Y is nrow-by-2*nk. The even * columns of Y contain the real part of B and the odd columns contain the * imaginary part of B. Y->nzmax must be >= 2*nrow*nk. Otherise, Y is * nrow-by-nk with leading dimension nrow. Y->nzmax must be >= nrow*nk. * * The case where the input (Y) is complex and the output (X) is real, * and the case where the input (Y) is zomplex and the output (X) is real, * are not used. */ static void iperm ( /* ---- input ---- */ cholmod_dense *Y, /* input matrix Y */ Int *Perm, /* optional input permutation (can be NULL) */ Int k1, /* first column of B to copy */ Int ncols, /* last column to copy is min(k1+ncols,B->ncol)-1 */ /* ---- in/out --- */ cholmod_dense *X /* output matrix X, already allocated */ ) { double *Yx, *Yz, *Xx, *Xz ; Int k2, nk, p, k, j, nrow, ncol, d, dj, j2 ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ ncol = X->ncol ; nrow = X->nrow ; k2 = MIN (k1+ncols, ncol) ; nk = MAX (k2 - k1, 0) ; d = X->d ; Xx = X->x ; Xz = X->z ; Yx = Y->x ; Yz = Y->z ; ASSERT (((Int) Y->nzmax) >= nrow*nk* ((X->xtype != CHOLMOD_REAL && Y->xtype == CHOLMOD_REAL) ? 2:1)) ; /* ---------------------------------------------------------------------- */ /* X (P (1:nrow), k1:k2-1) = Y */ /* ---------------------------------------------------------------------- */ switch (Y->xtype) { case CHOLMOD_REAL: switch (X->xtype) { case CHOLMOD_REAL: /* Y real, X real */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = nrow * (j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Xx [p] = Yx [k + j2] ; /* real */ } } break ; case CHOLMOD_COMPLEX: /* Y real, X complex. Y is nrow-by-2*nk */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = nrow * 2 * (j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Xx [2*p ] = Yx [k + j2 ] ; /* real */ Xx [2*p+1] = Yx [k + j2 + nrow] ; /* imag */ } } break ; case CHOLMOD_ZOMPLEX: /* Y real, X zomplex. Y is nrow-by-2*nk */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = nrow * 2 * (j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Xx [p] = Yx [k + j2 ] ; /* real */ Xz [p] = Yx [k + j2 + nrow] ; /* imag */ } } break ; } break ; case CHOLMOD_COMPLEX: switch (X->xtype) { #if 0 case CHOLMOD_REAL: /* this case is not used */ break ; #endif case CHOLMOD_COMPLEX: /* Y complex, X complex */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = nrow * 2 * (j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Xx [2*p ] = Yx [2*k + j2] ; /* real */ Xx [2*p+1] = Yx [2*k+1 + j2] ; /* imag */ } } break ; case CHOLMOD_ZOMPLEX: /* Y complex, X zomplex */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = nrow * 2 * (j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Xx [p] = Yx [2*k + j2] ; /* real */ Xz [p] = Yx [2*k+1 + j2] ; /* imag */ } } break ; } break ; case CHOLMOD_ZOMPLEX: switch (X->xtype) { #if 0 case CHOLMOD_REAL: /* this case is not used */ break ; #endif case CHOLMOD_COMPLEX: /* Y zomplex, X complex */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = nrow * (j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Xx [2*p ] = Yx [k + j2] ; /* real */ Xx [2*p+1] = Yz [k + j2] ; /* imag */ } } break ; case CHOLMOD_ZOMPLEX: /* Y zomplex, X zomplex */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = nrow * (j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Xx [p] = Yx [k + j2] ; /* real */ Xz [p] = Yz [k + j2] ; /* imag */ } } break ; } break ; } } /* ========================================================================== */ /* === ptrans =============================================================== */ /* ========================================================================== */ /* Y = B (P (1:nrow), k1 : min (k1+ncols,ncol)-1)' where B is nrow-by-ncol. * * Creates a permuted and transposed copy of a contiguous set of columns of B. * Y is already allocated on input. Y must be of sufficient size. Let nk be * the number of columns accessed in B. Y->xtype determines the complexity of * the result. * * If B is real and Y is complex (or zomplex), only the real part of B is * copied into Y. The imaginary part of Y is set to zero. * * If B is complex (or zomplex) and Y is real, both the real and imaginary and * parts of B are returned in Y. Y is returned as 2*nk-by-nrow. The even * rows of Y contain the real part of B and the odd rows contain the * imaginary part of B. Y->nzmax must be >= 2*nrow*nk. Otherise, Y is * returned as nk-by-nrow with leading dimension nk. Y->nzmax must be >= * nrow*nk. * * The array transpose is performed, not the complex conjugate transpose. */ static void ptrans ( /* ---- input ---- */ cholmod_dense *B, /* input matrix B */ Int *Perm, /* optional input permutation (can be NULL) */ Int k1, /* first column of B to copy */ Int ncols, /* last column to copy is min(k1+ncols,B->ncol)-1 */ /* ---- in/out --- */ cholmod_dense *Y /* output matrix Y, already allocated */ ) { double *Yx, *Yz, *Bx, *Bz ; Int k2, nk, p, k, j, nrow, ncol, d, dual, dj, j2 ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ ncol = B->ncol ; nrow = B->nrow ; k2 = MIN (k1+ncols, ncol) ; nk = MAX (k2 - k1, 0) ; dual = (Y->xtype == CHOLMOD_REAL && B->xtype != CHOLMOD_REAL) ? 2 : 1 ; d = B->d ; Bx = B->x ; Bz = B->z ; Yx = Y->x ; Yz = Y->z ; Y->nrow = dual*nk ; Y->ncol = nrow ; Y->d = dual*nk ; ASSERT (((Int) Y->nzmax) >= nrow*nk*dual) ; /* ---------------------------------------------------------------------- */ /* Y = B (P (1:nrow), k1:k2-1)' */ /* ---------------------------------------------------------------------- */ switch (Y->xtype) { case CHOLMOD_REAL: switch (B->xtype) { case CHOLMOD_REAL: /* Y real, B real */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = j-k1 ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Yx [j2 + k*nk] = Bx [p] ; /* real */ } } break ; case CHOLMOD_COMPLEX: /* Y real, B complex. Y is 2*nk-by-nrow */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = 2*(j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Yx [j2 + k*2*nk] = Bx [2*p ] ; /* real */ Yx [j2+1 + k*2*nk] = Bx [2*p+1] ; /* imag */ } } break ; case CHOLMOD_ZOMPLEX: /* Y real, B zomplex. Y is 2*nk-by-nrow */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = 2*(j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Yx [j2 + k*2*nk] = Bx [p] ; /* real */ Yx [j2+1 + k*2*nk] = Bz [p] ; /* imag */ } } break ; } break ; case CHOLMOD_COMPLEX: switch (B->xtype) { case CHOLMOD_REAL: /* Y complex, B real */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = 2*(j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Yx [j2 + k*2*nk] = Bx [p] ; /* real */ Yx [j2+1 + k*2*nk] = 0 ; /* imag */ } } break ; case CHOLMOD_COMPLEX: /* Y complex, B complex */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = 2*(j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Yx [j2 + k*2*nk] = Bx [2*p ] ; /* real */ Yx [j2+1 + k*2*nk] = Bx [2*p+1] ; /* imag */ } } break ; case CHOLMOD_ZOMPLEX: /* Y complex, B zomplex */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = 2*(j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Yx [j2 + k*2*nk] = Bx [p] ; /* real */ Yx [j2+1 + k*2*nk] = Bz [p] ; /* imag */ } } break ; } break ; case CHOLMOD_ZOMPLEX: switch (B->xtype) { case CHOLMOD_REAL: /* Y zomplex, B real */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = j-k1 ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Yx [j2 + k*nk] = Bx [p] ; /* real */ Yz [j2 + k*nk] = 0 ; /* imag */ } } break ; case CHOLMOD_COMPLEX: /* Y zomplex, B complex */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = j-k1 ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Yx [j2 + k*nk] = Bx [2*p ] ; /* real */ Yz [j2 + k*nk] = Bx [2*p+1] ; /* imag */ } } break ; case CHOLMOD_ZOMPLEX: /* Y zomplex, B zomplex */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = j-k1 ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Yx [j2 + k*nk] = Bx [p] ; /* real */ Yz [j2 + k*nk] = Bz [p] ; /* imag */ } } break ; } break ; } } /* ========================================================================== */ /* === iptrans ============================================================== */ /* ========================================================================== */ /* X (P (1:nrow), k1 : min (k1+ncols,ncol)-1) = Y' where X is nrow-by-ncol. * * Copies into a permuted and transposed contiguous set of columns of X. * X is already allocated on input. Y must be of sufficient size. Let nk be * the number of columns accessed in X. X->xtype determines the complexity of * the result. * * If X is real and Y is complex (or zomplex), only the real part of Y is * copied into X. The imaginary part of Y is ignored. * * If X is complex (or zomplex) and Y is real, both the real and imaginary and * parts of X are returned in Y. Y is 2*nk-by-nrow. The even * rows of Y contain the real part of X and the odd rows contain the * imaginary part of X. Y->nzmax must be >= 2*nrow*nk. Otherise, Y is * nk-by-nrow with leading dimension nk. Y->nzmax must be >= nrow*nk. * * The case where Y is complex or zomplex, and X is real, is not used. * * The array transpose is performed, not the complex conjugate transpose. */ static void iptrans ( /* ---- input ---- */ cholmod_dense *Y, /* input matrix Y */ Int *Perm, /* optional input permutation (can be NULL) */ Int k1, /* first column of X to copy into */ Int ncols, /* last column to copy is min(k1+ncols,X->ncol)-1 */ /* ---- in/out --- */ cholmod_dense *X /* output matrix X, already allocated */ ) { double *Yx, *Yz, *Xx, *Xz ; Int k2, nk, p, k, j, nrow, ncol, d, dj, j2 ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ ncol = X->ncol ; nrow = X->nrow ; k2 = MIN (k1+ncols, ncol) ; nk = MAX (k2 - k1, 0) ; d = X->d ; Xx = X->x ; Xz = X->z ; Yx = Y->x ; Yz = Y->z ; ASSERT (((Int) Y->nzmax) >= nrow*nk* ((X->xtype != CHOLMOD_REAL && Y->xtype == CHOLMOD_REAL) ? 2:1)) ; /* ---------------------------------------------------------------------- */ /* X (P (1:nrow), k1:k2-1) = Y' */ /* ---------------------------------------------------------------------- */ switch (Y->xtype) { case CHOLMOD_REAL: switch (X->xtype) { case CHOLMOD_REAL: /* Y real, X real */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = j-k1 ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Xx [p] = Yx [j2 + k*nk] ; /* real */ } } break ; case CHOLMOD_COMPLEX: /* Y real, X complex. Y is 2*nk-by-nrow */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = 2*(j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Xx [2*p ] = Yx [j2 + k*2*nk] ; /* real */ Xx [2*p+1] = Yx [j2+1 + k*2*nk] ; /* imag */ } } break ; case CHOLMOD_ZOMPLEX: /* Y real, X zomplex. Y is 2*nk-by-nrow */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = 2*(j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Xx [p] = Yx [j2 + k*2*nk] ; /* real */ Xz [p] = Yx [j2+1 + k*2*nk] ; /* imag */ } } break ; } break ; case CHOLMOD_COMPLEX: switch (X->xtype) { #if 0 case CHOLMOD_REAL: /* this case is not used */ break ; #endif case CHOLMOD_COMPLEX: /* Y complex, X complex */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = 2*(j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Xx [2*p ] = Yx [j2 + k*2*nk] ; /* real */ Xx [2*p+1] = Yx [j2+1 + k*2*nk] ; /* imag */ } } break ; case CHOLMOD_ZOMPLEX: /* Y complex, X zomplex */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = 2*(j-k1) ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Xx [p] = Yx [j2 + k*2*nk] ; /* real */ Xz [p] = Yx [j2+1 + k*2*nk] ; /* imag */ } } break ; } break ; case CHOLMOD_ZOMPLEX: switch (X->xtype) { #if 0 case CHOLMOD_REAL: /* this case is not used */ break ; #endif case CHOLMOD_COMPLEX: /* Y zomplex, X complex */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = j-k1 ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Xx [2*p ] = Yx [j2 + k*nk] ; /* real */ Xx [2*p+1] = Yz [j2 + k*nk] ; /* imag */ } } break ; case CHOLMOD_ZOMPLEX: /* Y zomplex, X zomplex */ for (j = k1 ; j < k2 ; j++) { dj = d*j ; j2 = j-k1 ; for (k = 0 ; k < nrow ; k++) { p = P(k) + dj ; Xx [p] = Yx [j2 + k*nk] ; /* real */ Xz [p] = Yz [j2 + k*nk] ; /* imag */ } } break ; } break ; } } /* ========================================================================== */ /* === cholmod_solve ======================================================== */ /* ========================================================================== */ /* Solve a linear system. * * The factorization can be simplicial LDL', simplicial LL', or supernodal LL'. * The Dx=b solve returns silently for the LL' factorizations (it is implicitly * identity). */ cholmod_dense *CHOLMOD(solve) ( /* ---- input ---- */ int sys, /* system to solve */ cholmod_factor *L, /* factorization to use */ cholmod_dense *B, /* right-hand-side */ /* --------------- */ cholmod_common *Common ) { cholmod_dense *Y = NULL, *X = NULL ; cholmod_dense *E = NULL ; int ok ; /* do the solve, allocating workspaces as needed */ ok = CHOLMOD (solve2) (sys, L, B, NULL, &X, NULL, &Y, &E, Common) ; /* free workspaces if allocated, and free result if an error occured */ CHOLMOD(free_dense) (&Y, Common) ; CHOLMOD(free_dense) (&E, Common) ; if (!ok) { CHOLMOD(free_dense) (&X, Common) ; } return (X) ; } /* ========================================================================== */ /* === cholmod_solve2 ======================================================= */ /* ========================================================================== */ /* This function acts just like cholmod_solve, except that the solution X and * the internal workspace (Y and E) can be passed in preallocated. If the * solution X or any required workspaces are not allocated on input, or if they * are the wrong size or type, then this function frees them and reallocates * them as the proper size and type. Thus, if you have a sequence of solves to * do, you can let this function allocate X, Y, and E on the first call. * Subsequent calls to cholmod_solve2 can then reuse this space. You must * then free the workspaces Y and E (and X if desired) when you are finished. * For example, the first call to cholmod_l_solve2, below, will solve the * requested system. The next 2 calls (with different right-hand-sides but * the same value of "sys") will resuse the workspace and solution X from the * first call. Finally, when all solves are done, you must free the workspaces * Y and E (otherwise you will have a memory leak), and you should also free X * when you are done with it. Note that on input, X, Y, and E must be either * valid cholmod_dense matrices, or initialized to NULL. You cannot pass in an * uninitialized X, Y, or E. * * cholmod_dense *X = NULL, *Y = NULL, *E = NULL ; * ... * cholmod_l_solve2 (sys, L, B1, NULL, &X, NULL, &Y, &E, Common) ; * cholmod_l_solve2 (sys, L, B2, NULL, &X, NULL, &Y, &E, Common) ; * cholmod_l_solve2 (sys, L, B3, NULL, &X, NULL, &Y, &E, Common) ; * cholmod_l_free_dense (&X, Common) ; * cholmod_l_free_dense (&Y, Common) ; * cholmod_l_free_dense (&E, Common) ; * * The equivalent when using cholmod_l_solve is: * * cholmod_dense *X = NULL, *Y = NULL, *E = NULL ; * ... * X = cholmod_l_solve (sys, L, B1, Common) ; * cholmod_l_free_dense (&X, Common) ; * X = cholmod_l_solve (sys, L, B2, Common) ; * cholmod_l_free_dense (&X, Common) ; * X = cholmod_l_solve (sys, L, B3, Common) ; * cholmod_l_free_dense (&X, Common) ; * * Both methods work fine, but in the 2nd method with cholmod_solve, the * internal workspaces (Y and E) are allocated and freed on each call. * * Bset is an optional sparse column (pattern only) that specifies a set * of row indices. It is ignored if NULL, or if sys is CHOLMOD_P or * CHOLMOD_Pt. If it is present and not ignored, B must be a dense column * vector, and only entries B(i) where i is in the pattern of Bset are * considered. All others are treated as if they were zero (they are not * accessed). L must be a simplicial factorization, not supernodal. L is * converted from supernodal to simplicial if necessary. The solution X is * defined only for entries in the output sparse pattern of Xset. * The xtype (real/complex/zomplex) of L and B must match. * * NOTE: If Bset is present and L is supernodal, it is converted to simplicial * on output. */ int CHOLMOD(solve2) /* returns TRUE on success, FALSE on failure */ ( /* ---- input ---- */ int sys, /* system to solve */ cholmod_factor *L, /* factorization to use */ cholmod_dense *B, /* right-hand-side */ cholmod_sparse *Bset, /* ---- output --- */ cholmod_dense **X_Handle, /* solution, allocated if need be */ cholmod_sparse **Xset_Handle, /* ---- workspace */ cholmod_dense **Y_Handle, /* workspace, or NULL */ cholmod_dense **E_Handle, /* workspace, or NULL */ /* --------------- */ cholmod_common *Common ) { double *Yx, *Yz, *Bx, *Bz, *Xx, *Xz ; cholmod_dense *Y = NULL, *X = NULL ; cholmod_sparse *C, *Yset, C_header, Yset_header, *Xset ; Int *Perm = NULL, *IPerm = NULL ; Int n, nrhs, ncols, ctype, xtype, k1, nr, ytype, k, blen, p, i, d, nrow ; Int Cp [2], Ysetp [2], *Ci, *Yseti, ysetlen ; Int *Bsetp, *Bseti, *Bsetnz, *Xseti, *Xsetp, *Iwork ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (L, FALSE) ; RETURN_IF_NULL (B, FALSE) ; RETURN_IF_XTYPE_INVALID (L, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; RETURN_IF_XTYPE_INVALID (B, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; if (sys < CHOLMOD_A || sys > CHOLMOD_Pt) { ERROR (CHOLMOD_INVALID, "invalid system") ; return (FALSE) ; } DEBUG (CHOLMOD(dump_factor) (L, "L", Common)) ; DEBUG (CHOLMOD(dump_dense) (B, "B", Common)) ; nrhs = B->ncol ; n = (Int) L->n ; d = (Int) B->d ; nrow = (Int) B->nrow ; if (d < n || nrow != n) { ERROR (CHOLMOD_INVALID, "dimensions of L and B do not match") ; return (FALSE) ; } if (Bset) { if (nrhs != 1) { ERROR (CHOLMOD_INVALID, "Bset requires a single right-hand side") ; return (FALSE) ; } if (L->xtype != B->xtype) { ERROR (CHOLMOD_INVALID, "Bset requires xtype of L and B to match") ; return (FALSE) ; } DEBUG (CHOLMOD(dump_sparse) (Bset, "Bset", Common)) ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ if ((sys == CHOLMOD_P || sys == CHOLMOD_Pt || sys == CHOLMOD_A) && L->ordering != CHOLMOD_NATURAL) { /* otherwise, Perm is NULL, and the identity permutation is used */ Perm = L->Perm ; } /* ---------------------------------------------------------------------- */ /* allocate the result X (or resuse the space from a prior call) */ /* ---------------------------------------------------------------------- */ ctype = (Common->prefer_zomplex) ? CHOLMOD_ZOMPLEX : CHOLMOD_COMPLEX ; if (Bset) { xtype = L->xtype ; } else if (sys == CHOLMOD_P || sys == CHOLMOD_Pt) { /* x=Pb and x=P'b return X real if B is real; X is the preferred * complex/zcomplex type if B is complex or zomplex */ xtype = (B->xtype == CHOLMOD_REAL) ? CHOLMOD_REAL : ctype ; } else if (L->xtype == CHOLMOD_REAL && B->xtype == CHOLMOD_REAL) { /* X is real if both L and B are real */ xtype = CHOLMOD_REAL ; } else { /* X is complex, use the preferred complex/zomplex type */ xtype = ctype ; } /* ensure X has the right size and type */ X = CHOLMOD(ensure_dense) (X_Handle, n, nrhs, n, xtype, Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; } /* ---------------------------------------------------------------------- */ /* solve using L, D, L', P, or some combination */ /* ---------------------------------------------------------------------- */ if (Bset) { /* ------------------------------------------------------------------ */ /* solve for a subset of x, with a sparse b */ /* ------------------------------------------------------------------ */ Int save_realloc_state ; #ifndef NSUPERNODAL /* convert a supernodal L to simplicial when using Bset */ if (L->is_super) { /* Can only use Bset on a simplicial factorization. The supernodal * factor L is converted to simplicial, leaving the xtype unchanged * (real, complex, or zomplex). Since the supernodal factorization * is already LL', it is left in that form. This conversion uses * the ll_super_to_simplicial_numeric function in * cholmod_change_factor. */ CHOLMOD(change_factor) ( CHOLMOD_REAL, /* ignored, since L is already numeric */ TRUE, /* convert to LL' (no change to num. values) */ FALSE, /* convert to simplicial */ FALSE, /* do not pack the columns of L */ FALSE, /* (ignored) */ L, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory, L is returned unchanged */ return (FALSE) ; } } #endif /* L, X, and B are all the same xtype */ /* ensure Y is the the right size */ Y = CHOLMOD(ensure_dense) (Y_Handle, 1, n, 1, L->xtype, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ return (FALSE) ; } /* ------------------------------------------------------------------ */ /* get the inverse permutation, constructing it if needed */ /* ------------------------------------------------------------------ */ DEBUG (CHOLMOD (dump_perm) (Perm, n,n, "Perm", Common)) ; if ((sys == CHOLMOD_A || sys == CHOLMOD_P) && Perm != NULL) { /* The inverse permutation IPerm is used for the c=Pb step, which is needed only for solving Ax=b or x=Pb. No other steps should use IPerm */ if (L->IPerm == NULL) { /* construct the inverse permutation. This is done only once * and then stored in L permanently. */ L->IPerm = CHOLMOD(malloc) (n, sizeof (Int), Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ return (FALSE) ; } IPerm = L->IPerm ; for (k = 0 ; k < n ; k++) { IPerm [Perm [k]] = k ; } } /* x=A\b and x=Pb both need IPerm */ IPerm = L->IPerm ; } if (sys == CHOLMOD_P) { /* x=Pb needs to turn off the subsequent x=P'b permutation */ Perm = NULL ; } DEBUG (CHOLMOD (dump_perm) (Perm, n,n, "Perm", Common)) ; DEBUG (CHOLMOD (dump_perm) (IPerm, n,n, "IPerm", Common)) ; /* ------------------------------------------------------------------ */ /* ensure Xset is the right size and type */ /* ------------------------------------------------------------------ */ /* Xset is n-by-1, nzmax >= n, pattern-only, packed, unsorted */ Xset = *Xset_Handle ; if (Xset == NULL || (Int) Xset->nrow != n || (Int) Xset->ncol != 1 || (Int) Xset->nzmax < n || Xset->itype != CHOLMOD_PATTERN) { /* this is done only once, for the 1st call to cholmod_solve */ CHOLMOD(free_sparse) (Xset_Handle, Common) ; Xset = CHOLMOD(allocate_sparse) (n, 1, n, FALSE, TRUE, 0, CHOLMOD_PATTERN, Common) ; *Xset_Handle = Xset ; } Xset->sorted = FALSE ; Xset->stype = 0 ; if (Common->status < CHOLMOD_OK) { /* out of memory */ return (FALSE) ; } /* -------------------------------------------------------------- */ /* ensure Flag of size n, and 3*n Int workspace is available */ /* -------------------------------------------------------------- */ /* does no work if prior calls already allocated enough space */ CHOLMOD(allocate_work) (n, 3*n, 0, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ return (FALSE) ; } /* [ use Iwork (n:3n-1) for Ci and Yseti */ Iwork = Common->Iwork ; /* Iwork (0:n-1) is not used because it is used by check_perm, print_perm, check_sparse, and print_sparse */ Ci = Iwork + n ; Yseti = Ci + n ; /* reallocating workspace would break Ci and Yseti */ save_realloc_state = Common->no_workspace_reallocate ; Common->no_workspace_reallocate = TRUE ; /* -------------------------------------------------------------- */ /* C = permuted Bset, to correspond to the permutation of L */ /* -------------------------------------------------------------- */ /* C = IPerm (Bset) */ DEBUG (CHOLMOD(dump_sparse) (Bset, "Bset", Common)) ; Bsetp = Bset->p ; Bseti = Bset->i ; Bsetnz = Bset->nz ; blen = (Bset->packed) ? Bsetp [1] : Bsetnz [0] ; /* C = spones (P*B) or C = spones (B) if IPerm is NULL */ C = &C_header ; C->nrow = n ; C->ncol = 1 ; C->nzmax = n ; C->packed = TRUE ; C->stype = 0 ; C->itype = ITYPE ; C->xtype = CHOLMOD_PATTERN ; C->dtype = CHOLMOD_DOUBLE ; C->nz = NULL ; C->p = Cp ; C->i = Ci ; C->x = NULL ; C->z = NULL ; C->sorted = FALSE ; Cp [0] = 0 ; Cp [1] = blen ; for (p = 0 ; p < blen ; p++) { Int iold = Bseti [p] ; Ci [p] = IPerm ? IPerm [iold] : iold ; } DEBUG (CHOLMOD (dump_sparse) (C, "C", Common)) ; /* create a sparse column Yset from Iwork (n:2n-1) */ Yset = &Yset_header ; Yset->nrow = n ; Yset->ncol = 1 ; Yset->nzmax = n ; Yset->packed = TRUE ; Yset->stype = 0 ; Yset->itype = ITYPE ; Yset->xtype = CHOLMOD_PATTERN ; Yset->dtype = CHOLMOD_DOUBLE ; Yset->nz = NULL ; Yset->p = Ysetp ; Yset->i = Yseti ; Yset->x = NULL ; Yset->z = NULL ; Yset->sorted = FALSE ; Ysetp [0] = 0 ; Ysetp [1] = 0 ; DEBUG (CHOLMOD (dump_sparse) (Yset, "Yset empty", Common)) ; /* -------------------------------------------------------------- */ /* Yset = nonzero pattern of L\C, or just C itself */ /* -------------------------------------------------------------- */ /* this takes O(ysetlen) time */ if (sys == CHOLMOD_P || sys == CHOLMOD_Pt || sys == CHOLMOD_D) { Ysetp [1] = blen ; for (p = 0 ; p < blen ; p++) { Yseti [p] = Ci [p] ; } } else { if (!CHOLMOD(lsolve_pattern) (C, L, Yset, Common)) { Common->no_workspace_reallocate = save_realloc_state ; return (FALSE) ; } } DEBUG (CHOLMOD (dump_sparse) (Yset, "Yset", Common)) ; /* -------------------------------------------------------------- */ /* clear the parts of Y that we will use in the solve */ /* -------------------------------------------------------------- */ Yx = Y->x ; Yz = Y->z ; ysetlen = Ysetp [1] ; switch (L->xtype) { case CHOLMOD_REAL: for (p = 0 ; p < ysetlen ; p++) { i = Yseti [p] ; Yx [i] = 0 ; } break ; case CHOLMOD_COMPLEX: for (p = 0 ; p < ysetlen ; p++) { i = Yseti [p] ; Yx [2*i ] = 0 ; Yx [2*i+1] = 0 ; } break ; case CHOLMOD_ZOMPLEX: for (p = 0 ; p < ysetlen ; p++) { i = Yseti [p] ; Yx [i] = 0 ; Yz [i] = 0 ; } break ; } DEBUG (CHOLMOD (dump_dense) (Y, "Y (Yset) = 0", Common)) ; /* -------------------------------------------------------------- */ /* scatter and permute B into Y */ /* -------------------------------------------------------------- */ /* Y (C) = B (Bset) */ Bx = B->x ; Bz = B->z ; switch (L->xtype) { case CHOLMOD_REAL: for (p = 0 ; p < blen ; p++) { Int iold = Bseti [p] ; Int inew = Ci [p] ; Yx [inew] = Bx [iold] ; } break ; case CHOLMOD_COMPLEX: for (p = 0 ; p < blen ; p++) { Int iold = Bseti [p] ; Int inew = Ci [p] ; Yx [2*inew ] = Bx [2*iold ] ; Yx [2*inew+1] = Bx [2*iold+1] ; } break ; case CHOLMOD_ZOMPLEX: for (p = 0 ; p < blen ; p++) { Int iold = Bseti [p] ; Int inew = Ci [p] ; Yx [inew] = Bx [iold] ; Yz [inew] = Bz [iold] ; } break ; } DEBUG (CHOLMOD (dump_dense) (Y, "Y (C) = B (Bset)", Common)) ; /* -------------------------------------------------------------- */ /* solve Y = (L' \ (L \ Y'))', or other system, with template */ /* -------------------------------------------------------------- */ /* the solve only iterates over columns in Yseti [0...ysetlen-1] */ if (! (sys == CHOLMOD_P || sys == CHOLMOD_Pt)) { switch (L->xtype) { case CHOLMOD_REAL: r_simplicial_solver (sys, L, Y, Yseti, ysetlen) ; break ; case CHOLMOD_COMPLEX: c_simplicial_solver (sys, L, Y, Yseti, ysetlen) ; break ; case CHOLMOD_ZOMPLEX: z_simplicial_solver (sys, L, Y, Yseti, ysetlen) ; break ; } } DEBUG (CHOLMOD (dump_dense) (Y, "Y after solve", Common)) ; /* -------------------------------------------------------------- */ /* X = P'*Y, but only for rows in Yset, and create Xset */ /* -------------------------------------------------------------- */ /* X (Perm (Yset)) = Y (Yset) */ Xx = X->x ; Xz = X->z ; Xseti = Xset->i ; Xsetp = Xset->p ; switch (L->xtype) { case CHOLMOD_REAL: for (p = 0 ; p < ysetlen ; p++) { Int inew = Yseti [p] ; Int iold = Perm ? Perm [inew] : inew ; Xx [iold] = Yx [inew] ; Xseti [p] = iold ; } break ; case CHOLMOD_COMPLEX: for (p = 0 ; p < ysetlen ; p++) { Int inew = Yseti [p] ; Int iold = Perm ? Perm [inew] : inew ; Xx [2*iold ] = Yx [2*inew] ; Xx [2*iold+1] = Yx [2*inew+1] ; Xseti [p] = iold ; } break ; case CHOLMOD_ZOMPLEX: for (p = 0 ; p < ysetlen ; p++) { Int inew = Yseti [p] ; Int iold = Perm ? Perm [inew] : inew ; Xx [iold] = Yx [inew] ; Xz [iold] = Yz [inew] ; Xseti [p] = iold ; } break ; } Xsetp [0] = 0 ; Xsetp [1] = ysetlen ; DEBUG (CHOLMOD(dump_sparse) (Xset, "Xset", Common)) ; DEBUG (CHOLMOD(dump_dense) (X, "X", Common)) ; Common->no_workspace_reallocate = save_realloc_state ; /* done using Iwork (n:3n-1) for Ci and Yseti ] */ } else if (sys == CHOLMOD_P) { /* ------------------------------------------------------------------ */ /* x = P*b */ /* ------------------------------------------------------------------ */ perm (B, Perm, 0, nrhs, X) ; } else if (sys == CHOLMOD_Pt) { /* ------------------------------------------------------------------ */ /* x = P'*b */ /* ------------------------------------------------------------------ */ iperm (B, Perm, 0, nrhs, X) ; } else if (L->is_super) { /* ------------------------------------------------------------------ */ /* solve using a supernodal LL' factorization */ /* ------------------------------------------------------------------ */ #ifndef NSUPERNODAL /* allocate workspace */ cholmod_dense *E ; Int dual ; Common->blas_ok = TRUE ; dual = (L->xtype == CHOLMOD_REAL && B->xtype != CHOLMOD_REAL) ? 2 : 1 ; Y = CHOLMOD(ensure_dense) (Y_Handle, n, dual*nrhs, n, L->xtype, Common); E = CHOLMOD(ensure_dense) (E_Handle, dual*nrhs, L->maxesize, dual*nrhs, L->xtype, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ return (FALSE) ; } perm (B, Perm, 0, nrhs, Y) ; /* Y = P*B */ if (sys == CHOLMOD_A || sys == CHOLMOD_LDLt) { CHOLMOD(super_lsolve) (L, Y, E, Common) ; /* Y = L\Y */ CHOLMOD(super_ltsolve) (L, Y, E, Common) ; /* Y = L'\Y*/ } else if (sys == CHOLMOD_L || sys == CHOLMOD_LD) { CHOLMOD(super_lsolve) (L, Y, E, Common) ; /* Y = L\Y */ } else if (sys == CHOLMOD_Lt || sys == CHOLMOD_DLt) { CHOLMOD(super_ltsolve) (L, Y, E, Common) ; /* Y = L'\Y*/ } iperm (Y, Perm, 0, nrhs, X) ; /* X = P'*Y */ if (CHECK_BLAS_INT && !Common->blas_ok) { /* Integer overflow in the BLAS. This is probably impossible, * since the BLAS were used to create the supernodal factorization. * It might be possible for the calls to the BLAS to differ between * factorization and forward/backsolves, however. This statement * is untested; it does not appear in the compiled code if * CHECK_BLAS_INT is true (when the same integer is used in * CHOLMOD and the BLAS. */ return (FALSE) ; } #else /* CHOLMOD Supernodal module not installed */ ERROR (CHOLMOD_NOT_INSTALLED,"Supernodal module not installed") ; #endif } else { /* ------------------------------------------------------------------ */ /* solve using a simplicial LL' or LDL' factorization */ /* ------------------------------------------------------------------ */ if (L->xtype == CHOLMOD_REAL && B->xtype == CHOLMOD_REAL) { /* L, B, and Y are all real */ /* solve with up to 4 columns of B at a time */ ncols = 4 ; nr = MAX (4, nrhs) ; ytype = CHOLMOD_REAL ; } else if (L->xtype == CHOLMOD_REAL) { /* L is real and B is complex or zomplex */ /* solve with one column of B (real/imag), at a time */ ncols = 1 ; nr = 2 ; ytype = CHOLMOD_REAL ; } else { /* L is complex or zomplex, B is real/complex/zomplex, Y has the * same complexity as L. Solve with one column of B at a time. */ ncols = 1 ; nr = 1 ; ytype = L->xtype ; } Y = CHOLMOD(ensure_dense) (Y_Handle, nr, n, nr, ytype, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ return (FALSE) ; } for (k1 = 0 ; k1 < nrhs ; k1 += ncols) { /* -------------------------------------------------------------- */ /* Y = B (P, k1:k1+ncols-1)' = (P * B (:,...))' */ /* -------------------------------------------------------------- */ ptrans (B, Perm, k1, ncols, Y) ; /* -------------------------------------------------------------- */ /* solve Y = (L' \ (L \ Y'))', or other system, with template */ /* -------------------------------------------------------------- */ switch (L->xtype) { case CHOLMOD_REAL: r_simplicial_solver (sys, L, Y, NULL, 0) ; break ; case CHOLMOD_COMPLEX: c_simplicial_solver (sys, L, Y, NULL, 0) ; break ; case CHOLMOD_ZOMPLEX: z_simplicial_solver (sys, L, Y, NULL, 0) ; break ; } /* -------------------------------------------------------------- */ /* X (P, k1:k2+ncols-1) = Y' */ /* -------------------------------------------------------------- */ iptrans (Y, Perm, k1, ncols, X) ; } } DEBUG (CHOLMOD(dump_dense) (X, "X result", Common)) ; return (TRUE) ; } #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Cholesky/t_cholmod_ltsolve.c�����������������������������������������������������0000644�0001762�0000144�00000054266�13652535054�021064� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Cholesky/t_cholmod_ltsolve =========================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Cholesky Module. Copyright (C) 2005-2013, Timothy A. Davis * -------------------------------------------------------------------------- */ /* Template routine to solve L'x=b with unit or non-unit diagonal, or * solve DL'x=b. * * The numeric xtype of L and Y must match. Y contains b on input and x on * output, stored in row-form. Y is nrow-by-n, where nrow must equal 1 for the * complex or zomplex cases, and nrow <= 4 for the real case. * * This file is not compiled separately. It is included in t_cholmod_solve.c * instead. It contains no user-callable routines. * * workspace: none * * Supports real, complex, and zomplex factors. */ /* undefine all prior definitions */ #undef FORM_NAME #undef LSOLVE #undef DIAG /* -------------------------------------------------------------------------- */ /* define the method */ /* -------------------------------------------------------------------------- */ #ifdef LL /* LL': solve Lx=b with non-unit diagonal */ #define FORM_NAME(prefix,rank) prefix ## ll_ltsolve_ ## rank #define DIAG #elif defined (LD) /* LDL': solve LDx=b */ #define FORM_NAME(prefix,rank) prefix ## ldl_dltsolve_ ## rank #define DIAG #else /* LDL': solve Lx=b with unit diagonal */ #define FORM_NAME(prefix,rank) prefix ## ldl_ltsolve_ ## rank #endif /* LSOLVE(k) defines the name of a routine for an n-by-k right-hand-side. */ #define LSOLVE(prefix,rank) FORM_NAME(prefix,rank) #ifdef REAL /* ========================================================================== */ /* === LSOLVE (1) =========================================================== */ /* ========================================================================== */ /* Solve L'x=b, where b has 1 column */ static void LSOLVE (PREFIX,1) ( cholmod_factor *L, double X [ ] /* n-by-1 in row form */ ) { double *Lx = L->x ; Int *Li = L->i ; Int *Lp = L->p ; Int *Lnz = L->nz ; Int j, n = L->n ; for (j = n-1 ; j >= 0 ; ) { /* get the start, end, and length of column j */ Int p = Lp [j] ; Int lnz = Lnz [j] ; Int pend = p + lnz ; /* find a chain of supernodes (up to j, j-1, and j-2) */ if (j < 4 || lnz != Lnz [j-1] - 1 || Li [Lp [j-1]+1] != j) { /* -------------------------------------------------------------- */ /* solve with a single column of L */ /* -------------------------------------------------------------- */ double y = X [j] ; #ifdef DIAG double d = Lx [p] ; #endif #ifdef LD y /= d ; #endif for (p++ ; p < pend ; p++) { y -= Lx [p] * X [Li [p]] ; } #ifdef LL X [j] = y / d ; #else X [j] = y ; #endif j-- ; /* advance to the next column of L */ } else if (lnz != Lnz [j-2]-2 || Li [Lp [j-2]+2] != j) { /* -------------------------------------------------------------- */ /* solve with a supernode of two columns of L */ /* -------------------------------------------------------------- */ double y [2], t ; Int q = Lp [j-1] ; #ifdef DIAG double d [2] ; d [0] = Lx [p] ; d [1] = Lx [q] ; #endif t = Lx [q+1] ; #ifdef LD y [0] = X [j ] / d [0] ; y [1] = X [j-1] / d [1] ; #else y [0] = X [j ] ; y [1] = X [j-1] ; #endif for (p++, q += 2 ; p < pend ; p++, q++) { Int i = Li [p] ; y [0] -= Lx [p] * X [i] ; y [1] -= Lx [q] * X [i] ; } #ifdef LL y [0] /= d [0] ; y [1] = (y [1] - t * y [0]) / d [1] ; #else y [1] -= t * y [0] ; #endif X [j ] = y [0] ; X [j-1] = y [1] ; j -= 2 ; /* advance to the next column of L */ } else { /* -------------------------------------------------------------- */ /* solve with a supernode of three columns of L */ /* -------------------------------------------------------------- */ double y [3], t [3] ; Int q = Lp [j-1] ; Int r = Lp [j-2] ; #ifdef DIAG double d [3] ; d [0] = Lx [p] ; d [1] = Lx [q] ; d [2] = Lx [r] ; #endif t [0] = Lx [q+1] ; t [1] = Lx [r+1] ; t [2] = Lx [r+2] ; #ifdef LD y [0] = X [j] / d [0] ; y [1] = X [j-1] / d [1] ; y [2] = X [j-2] / d [2] ; #else y [0] = X [j] ; y [1] = X [j-1] ; y [2] = X [j-2] ; #endif for (p++, q += 2, r += 3 ; p < pend ; p++, q++, r++) { Int i = Li [p] ; y [0] -= Lx [p] * X [i] ; y [1] -= Lx [q] * X [i] ; y [2] -= Lx [r] * X [i] ; } #ifdef LL y [0] /= d [0] ; y [1] = (y [1] - t [0] * y [0]) / d [1] ; y [2] = (y [2] - t [2] * y [0] - t [1] * y [1]) / d [2] ; #else y [1] -= t [0] * y [0] ; y [2] -= t [2] * y [0] + t [1] * y [1] ; #endif X [j-2] = y [2] ; X [j-1] = y [1] ; X [j ] = y [0] ; j -= 3 ; /* advance to the next column of L */ } } } /* ========================================================================== */ /* === LSOLVE (2) =========================================================== */ /* ========================================================================== */ /* Solve L'x=b, where b has 2 columns */ static void LSOLVE (PREFIX,2) ( cholmod_factor *L, double X [ ][2] /* n-by-2 in row form */ ) { double *Lx = L->x ; Int *Li = L->i ; Int *Lp = L->p ; Int *Lnz = L->nz ; Int j, n = L->n ; for (j = n-1 ; j >= 0 ; ) { /* get the start, end, and length of column j */ Int p = Lp [j] ; Int lnz = Lnz [j] ; Int pend = p + lnz ; /* find a chain of supernodes (up to j, j-1, and j-2) */ if (j < 4 || lnz != Lnz [j-1] - 1 || Li [Lp [j-1]+1] != j) { /* -------------------------------------------------------------- */ /* solve with a single column of L */ /* -------------------------------------------------------------- */ double y [2] ; #ifdef DIAG double d = Lx [p] ; #endif #ifdef LD y [0] = X [j][0] / d ; y [1] = X [j][1] / d ; #else y [0] = X [j][0] ; y [1] = X [j][1] ; #endif for (p++ ; p < pend ; p++) { Int i = Li [p] ; y [0] -= Lx [p] * X [i][0] ; y [1] -= Lx [p] * X [i][1] ; } #ifdef LL X [j][0] = y [0] / d ; X [j][1] = y [1] / d ; #else X [j][0] = y [0] ; X [j][1] = y [1] ; #endif j-- ; /* advance to the next column of L */ } else if (lnz != Lnz [j-2]-2 || Li [Lp [j-2]+2] != j) { /* -------------------------------------------------------------- */ /* solve with a supernode of two columns of L */ /* -------------------------------------------------------------- */ double y [2][2], t ; Int q = Lp [j-1] ; #ifdef DIAG double d [2] ; d [0] = Lx [p] ; d [1] = Lx [q] ; #endif t = Lx [q+1] ; #ifdef LD y [0][0] = X [j ][0] / d [0] ; y [0][1] = X [j ][1] / d [0] ; y [1][0] = X [j-1][0] / d [1] ; y [1][1] = X [j-1][1] / d [1] ; #else y [0][0] = X [j ][0] ; y [0][1] = X [j ][1] ; y [1][0] = X [j-1][0] ; y [1][1] = X [j-1][1] ; #endif for (p++, q += 2 ; p < pend ; p++, q++) { Int i = Li [p] ; y [0][0] -= Lx [p] * X [i][0] ; y [0][1] -= Lx [p] * X [i][1] ; y [1][0] -= Lx [q] * X [i][0] ; y [1][1] -= Lx [q] * X [i][1] ; } #ifdef LL y [0][0] /= d [0] ; y [0][1] /= d [0] ; y [1][0] = (y [1][0] - t * y [0][0]) / d [1] ; y [1][1] = (y [1][1] - t * y [0][1]) / d [1] ; #else y [1][0] -= t * y [0][0] ; y [1][1] -= t * y [0][1] ; #endif X [j ][0] = y [0][0] ; X [j ][1] = y [0][1] ; X [j-1][0] = y [1][0] ; X [j-1][1] = y [1][1] ; j -= 2 ; /* advance to the next column of L */ } else { /* -------------------------------------------------------------- */ /* solve with a supernode of three columns of L */ /* -------------------------------------------------------------- */ double y [3][2], t [3] ; Int q = Lp [j-1] ; Int r = Lp [j-2] ; #ifdef DIAG double d [3] ; d [0] = Lx [p] ; d [1] = Lx [q] ; d [2] = Lx [r] ; #endif t [0] = Lx [q+1] ; t [1] = Lx [r+1] ; t [2] = Lx [r+2] ; #ifdef LD y [0][0] = X [j ][0] / d [0] ; y [0][1] = X [j ][1] / d [0] ; y [1][0] = X [j-1][0] / d [1] ; y [1][1] = X [j-1][1] / d [1] ; y [2][0] = X [j-2][0] / d [2] ; y [2][1] = X [j-2][1] / d [2] ; #else y [0][0] = X [j ][0] ; y [0][1] = X [j ][1] ; y [1][0] = X [j-1][0] ; y [1][1] = X [j-1][1] ; y [2][0] = X [j-2][0] ; y [2][1] = X [j-2][1] ; #endif for (p++, q += 2, r += 3 ; p < pend ; p++, q++, r++) { Int i = Li [p] ; y [0][0] -= Lx [p] * X [i][0] ; y [0][1] -= Lx [p] * X [i][1] ; y [1][0] -= Lx [q] * X [i][0] ; y [1][1] -= Lx [q] * X [i][1] ; y [2][0] -= Lx [r] * X [i][0] ; y [2][1] -= Lx [r] * X [i][1] ; } #ifdef LL y [0][0] /= d [0] ; y [0][1] /= d [0] ; y [1][0] = (y [1][0] - t [0] * y [0][0]) / d [1] ; y [1][1] = (y [1][1] - t [0] * y [0][1]) / d [1] ; y [2][0] = (y [2][0] - t [2] * y [0][0] - t [1] * y [1][0]) / d [2]; y [2][1] = (y [2][1] - t [2] * y [0][1] - t [1] * y [1][1]) / d [2]; #else y [1][0] -= t [0] * y [0][0] ; y [1][1] -= t [0] * y [0][1] ; y [2][0] -= t [2] * y [0][0] + t [1] * y [1][0] ; y [2][1] -= t [2] * y [0][1] + t [1] * y [1][1] ; #endif X [j ][0] = y [0][0] ; X [j ][1] = y [0][1] ; X [j-1][0] = y [1][0] ; X [j-1][1] = y [1][1] ; X [j-2][0] = y [2][0] ; X [j-2][1] = y [2][1] ; j -= 3 ; /* advance to the next column of L */ } } } /* ========================================================================== */ /* === LSOLVE (3) =========================================================== */ /* ========================================================================== */ /* Solve L'x=b, where b has 3 columns */ static void LSOLVE (PREFIX,3) ( cholmod_factor *L, double X [ ][3] /* n-by-3 in row form */ ) { double *Lx = L->x ; Int *Li = L->i ; Int *Lp = L->p ; Int *Lnz = L->nz ; Int j, n = L->n ; for (j = n-1 ; j >= 0 ; ) { /* get the start, end, and length of column j */ Int p = Lp [j] ; Int lnz = Lnz [j] ; Int pend = p + lnz ; /* find a chain of supernodes (up to j, j-1, and j-2) */ if (j < 4 || lnz != Lnz [j-1] - 1 || Li [Lp [j-1]+1] != j) { /* -------------------------------------------------------------- */ /* solve with a single column of L */ /* -------------------------------------------------------------- */ double y [3] ; #ifdef DIAG double d = Lx [p] ; #endif #ifdef LD y [0] = X [j][0] / d ; y [1] = X [j][1] / d ; y [2] = X [j][2] / d ; #else y [0] = X [j][0] ; y [1] = X [j][1] ; y [2] = X [j][2] ; #endif for (p++ ; p < pend ; p++) { Int i = Li [p] ; y [0] -= Lx [p] * X [i][0] ; y [1] -= Lx [p] * X [i][1] ; y [2] -= Lx [p] * X [i][2] ; } #ifdef LL X [j][0] = y [0] / d ; X [j][1] = y [1] / d ; X [j][2] = y [2] / d ; #else X [j][0] = y [0] ; X [j][1] = y [1] ; X [j][2] = y [2] ; #endif j-- ; /* advance to the next column of L */ } else if (lnz != Lnz [j-2]-2 || Li [Lp [j-2]+2] != j) { /* -------------------------------------------------------------- */ /* solve with a supernode of two columns of L */ /* -------------------------------------------------------------- */ double y [2][3], t ; Int q = Lp [j-1] ; #ifdef DIAG double d [2] ; d [0] = Lx [p] ; d [1] = Lx [q] ; #endif t = Lx [q+1] ; #ifdef LD y [0][0] = X [j ][0] / d [0] ; y [0][1] = X [j ][1] / d [0] ; y [0][2] = X [j ][2] / d [0] ; y [1][0] = X [j-1][0] / d [1] ; y [1][1] = X [j-1][1] / d [1] ; y [1][2] = X [j-1][2] / d [1] ; #else y [0][0] = X [j ][0] ; y [0][1] = X [j ][1] ; y [0][2] = X [j ][2] ; y [1][0] = X [j-1][0] ; y [1][1] = X [j-1][1] ; y [1][2] = X [j-1][2] ; #endif for (p++, q += 2 ; p < pend ; p++, q++) { Int i = Li [p] ; y [0][0] -= Lx [p] * X [i][0] ; y [0][1] -= Lx [p] * X [i][1] ; y [0][2] -= Lx [p] * X [i][2] ; y [1][0] -= Lx [q] * X [i][0] ; y [1][1] -= Lx [q] * X [i][1] ; y [1][2] -= Lx [q] * X [i][2] ; } #ifdef LL y [0][0] /= d [0] ; y [0][1] /= d [0] ; y [0][2] /= d [0] ; y [1][0] = (y [1][0] - t * y [0][0]) / d [1] ; y [1][1] = (y [1][1] - t * y [0][1]) / d [1] ; y [1][2] = (y [1][2] - t * y [0][2]) / d [1] ; #else y [1][0] -= t * y [0][0] ; y [1][1] -= t * y [0][1] ; y [1][2] -= t * y [0][2] ; #endif X [j ][0] = y [0][0] ; X [j ][1] = y [0][1] ; X [j ][2] = y [0][2] ; X [j-1][0] = y [1][0] ; X [j-1][1] = y [1][1] ; X [j-1][2] = y [1][2] ; j -= 2 ; /* advance to the next column of L */ } else { /* -------------------------------------------------------------- */ /* solve with a supernode of three columns of L */ /* -------------------------------------------------------------- */ double y [3][3], t [3] ; Int q = Lp [j-1] ; Int r = Lp [j-2] ; #ifdef DIAG double d [3] ; d [0] = Lx [p] ; d [1] = Lx [q] ; d [2] = Lx [r] ; #endif t [0] = Lx [q+1] ; t [1] = Lx [r+1] ; t [2] = Lx [r+2] ; #ifdef LD y [0][0] = X [j ][0] / d [0] ; y [0][1] = X [j ][1] / d [0] ; y [0][2] = X [j ][2] / d [0] ; y [1][0] = X [j-1][0] / d [1] ; y [1][1] = X [j-1][1] / d [1] ; y [1][2] = X [j-1][2] / d [1] ; y [2][0] = X [j-2][0] / d [2] ; y [2][1] = X [j-2][1] / d [2] ; y [2][2] = X [j-2][2] / d [2] ; #else y [0][0] = X [j ][0] ; y [0][1] = X [j ][1] ; y [0][2] = X [j ][2] ; y [1][0] = X [j-1][0] ; y [1][1] = X [j-1][1] ; y [1][2] = X [j-1][2] ; y [2][0] = X [j-2][0] ; y [2][1] = X [j-2][1] ; y [2][2] = X [j-2][2] ; #endif for (p++, q += 2, r += 3 ; p < pend ; p++, q++, r++) { Int i = Li [p] ; y [0][0] -= Lx [p] * X [i][0] ; y [0][1] -= Lx [p] * X [i][1] ; y [0][2] -= Lx [p] * X [i][2] ; y [1][0] -= Lx [q] * X [i][0] ; y [1][1] -= Lx [q] * X [i][1] ; y [1][2] -= Lx [q] * X [i][2] ; y [2][0] -= Lx [r] * X [i][0] ; y [2][1] -= Lx [r] * X [i][1] ; y [2][2] -= Lx [r] * X [i][2] ; } #ifdef LL y [0][0] /= d [0] ; y [0][1] /= d [0] ; y [0][2] /= d [0] ; y [1][0] = (y [1][0] - t [0] * y [0][0]) / d [1] ; y [1][1] = (y [1][1] - t [0] * y [0][1]) / d [1] ; y [1][2] = (y [1][2] - t [0] * y [0][2]) / d [1] ; y [2][0] = (y [2][0] - t [2] * y [0][0] - t [1] * y [1][0]) / d [2]; y [2][1] = (y [2][1] - t [2] * y [0][1] - t [1] * y [1][1]) / d [2]; y [2][2] = (y [2][2] - t [2] * y [0][2] - t [1] * y [1][2]) / d [2]; #else y [1][0] -= t [0] * y [0][0] ; y [1][1] -= t [0] * y [0][1] ; y [1][2] -= t [0] * y [0][2] ; y [2][0] -= t [2] * y [0][0] + t [1] * y [1][0] ; y [2][1] -= t [2] * y [0][1] + t [1] * y [1][1] ; y [2][2] -= t [2] * y [0][2] + t [1] * y [1][2] ; #endif X [j ][0] = y [0][0] ; X [j ][1] = y [0][1] ; X [j ][2] = y [0][2] ; X [j-1][0] = y [1][0] ; X [j-1][1] = y [1][1] ; X [j-1][2] = y [1][2] ; X [j-2][0] = y [2][0] ; X [j-2][1] = y [2][1] ; X [j-2][2] = y [2][2] ; j -= 3 ; /* advance to the next column of L */ } } } /* ========================================================================== */ /* === LSOLVE (4) =========================================================== */ /* ========================================================================== */ /* Solve L'x=b, where b has 4 columns */ static void LSOLVE (PREFIX,4) ( cholmod_factor *L, double X [ ][4] /* n-by-4 in row form */ ) { double *Lx = L->x ; Int *Li = L->i ; Int *Lp = L->p ; Int *Lnz = L->nz ; Int j, n = L->n ; for (j = n-1 ; j >= 0 ; ) { /* get the start, end, and length of column j */ Int p = Lp [j] ; Int lnz = Lnz [j] ; Int pend = p + lnz ; /* find a chain of supernodes (up to j, j-1, and j-2) */ if (j < 4 || lnz != Lnz [j-1] - 1 || Li [Lp [j-1]+1] != j) { /* -------------------------------------------------------------- */ /* solve with a single column of L */ /* -------------------------------------------------------------- */ double y [4] ; #ifdef DIAG double d = Lx [p] ; #endif #ifdef LD y [0] = X [j][0] / d ; y [1] = X [j][1] / d ; y [2] = X [j][2] / d ; y [3] = X [j][3] / d ; #else y [0] = X [j][0] ; y [1] = X [j][1] ; y [2] = X [j][2] ; y [3] = X [j][3] ; #endif for (p++ ; p < pend ; p++) { Int i = Li [p] ; y [0] -= Lx [p] * X [i][0] ; y [1] -= Lx [p] * X [i][1] ; y [2] -= Lx [p] * X [i][2] ; y [3] -= Lx [p] * X [i][3] ; } #ifdef LL X [j][0] = y [0] / d ; X [j][1] = y [1] / d ; X [j][2] = y [2] / d ; X [j][3] = y [3] / d ; #else X [j][0] = y [0] ; X [j][1] = y [1] ; X [j][2] = y [2] ; X [j][3] = y [3] ; #endif j-- ; /* advance to the next column of L */ } else /* if (j == 1 || lnz != Lnz [j-2]-2 || Li [Lp [j-2]+2] != j) */ { /* -------------------------------------------------------------- */ /* solve with a supernode of two columns of L */ /* -------------------------------------------------------------- */ double y [2][4], t ; Int q = Lp [j-1] ; #ifdef DIAG double d [2] ; d [0] = Lx [p] ; d [1] = Lx [q] ; #endif t = Lx [q+1] ; #ifdef LD y [0][0] = X [j ][0] / d [0] ; y [0][1] = X [j ][1] / d [0] ; y [0][2] = X [j ][2] / d [0] ; y [0][3] = X [j ][3] / d [0] ; y [1][0] = X [j-1][0] / d [1] ; y [1][1] = X [j-1][1] / d [1] ; y [1][2] = X [j-1][2] / d [1] ; y [1][3] = X [j-1][3] / d [1] ; #else y [0][0] = X [j ][0] ; y [0][1] = X [j ][1] ; y [0][2] = X [j ][2] ; y [0][3] = X [j ][3] ; y [1][0] = X [j-1][0] ; y [1][1] = X [j-1][1] ; y [1][2] = X [j-1][2] ; y [1][3] = X [j-1][3] ; #endif for (p++, q += 2 ; p < pend ; p++, q++) { Int i = Li [p] ; y [0][0] -= Lx [p] * X [i][0] ; y [0][1] -= Lx [p] * X [i][1] ; y [0][2] -= Lx [p] * X [i][2] ; y [0][3] -= Lx [p] * X [i][3] ; y [1][0] -= Lx [q] * X [i][0] ; y [1][1] -= Lx [q] * X [i][1] ; y [1][2] -= Lx [q] * X [i][2] ; y [1][3] -= Lx [q] * X [i][3] ; } #ifdef LL y [0][0] /= d [0] ; y [0][1] /= d [0] ; y [0][2] /= d [0] ; y [0][3] /= d [0] ; y [1][0] = (y [1][0] - t * y [0][0]) / d [1] ; y [1][1] = (y [1][1] - t * y [0][1]) / d [1] ; y [1][2] = (y [1][2] - t * y [0][2]) / d [1] ; y [1][3] = (y [1][3] - t * y [0][3]) / d [1] ; #else y [1][0] -= t * y [0][0] ; y [1][1] -= t * y [0][1] ; y [1][2] -= t * y [0][2] ; y [1][3] -= t * y [0][3] ; #endif X [j ][0] = y [0][0] ; X [j ][1] = y [0][1] ; X [j ][2] = y [0][2] ; X [j ][3] = y [0][3] ; X [j-1][0] = y [1][0] ; X [j-1][1] = y [1][1] ; X [j-1][2] = y [1][2] ; X [j-1][3] = y [1][3] ; j -= 2 ; /* advance to the next column of L */ } /* NOTE: with 4 right-hand-sides, it suffices to exploit dynamic * supernodes of just size 1 and 2. 3-column supernodes are not * needed. */ } } #endif /* ========================================================================== */ /* === LSOLVE (k) =========================================================== */ /* ========================================================================== */ static void LSOLVE (PREFIX,k) ( cholmod_factor *L, cholmod_dense *Y, /* nr-by-n where nr is 1 to 4 */ Int *Yseti, Int ysetlen ) { #ifdef DIAG double d [1] ; #endif double yx [2] ; #ifdef ZOMPLEX double yz [1] ; double *Lz = L->z ; double *Xz = Y->z ; #endif double *Lx = L->x ; double *Xx = Y->x ; Int *Li = L->i ; Int *Lp = L->p ; Int *Lnz = L->nz ; Int n = L->n, jj, jjiters ; ASSERT (L->xtype == Y->xtype) ; /* L and Y must have the same xtype */ ASSERT (L->n == Y->ncol) ; /* dimensions must match */ ASSERT (Y->nrow == Y->d) ; /* leading dimension of Y = # rows of Y */ ASSERT (L->xtype != CHOLMOD_PATTERN) ; /* L is not symbolic */ ASSERT (!(L->is_super)) ; /* L is simplicial LL' or LDL' */ #ifdef REAL if (Yseti == NULL) { /* ------------------------------------------------------------------ */ /* real case, no Yseti, with 1 to 4 RHS's and dynamic supernodes */ /* ------------------------------------------------------------------ */ ASSERT (Y->nrow <= 4) ; switch (Y->nrow) { case 1: LSOLVE (PREFIX,1) (L, Y->x) ; break ; case 2: LSOLVE (PREFIX,2) (L, Y->x) ; break ; case 3: LSOLVE (PREFIX,3) (L, Y->x) ; break ; case 4: LSOLVE (PREFIX,4) (L, Y->x) ; break ; } } else #endif { /* ------------------------------------------------------------------ */ /* solve a complex linear system or solve with Yseti */ /* ------------------------------------------------------------------ */ ASSERT (Y->nrow == 1) ; jjiters = Yseti ? ysetlen : n ; for (jj = jjiters-1 ; jj >= 0 ; jj--) { Int j = Yseti ? Yseti [jj] : jj ; /* get the start, end, and length of column j */ Int p = Lp [j] ; Int lnz = Lnz [j] ; Int pend = p + lnz ; /* y = X [j] ; */ ASSIGN (yx,yz,0, Xx,Xz,j) ; #ifdef DIAG /* d = Lx [p] ; */ ASSIGN_REAL (d,0, Lx,p) ; #endif #ifdef LD /* y /= d ; */ DIV_REAL (yx,yz,0, yx,yz,0, d,0) ; #endif for (p++ ; p < pend ; p++) { /* y -= conj (Lx [p]) * X [Li [p]] ; */ Int i = Li [p] ; MULTSUBCONJ (yx,yz,0, Lx,Lz,p, Xx,Xz,i) ; } #ifdef LL /* X [j] = y / d ; */ DIV_REAL (Xx,Xz,j, yx,yz,0, d,0) ; #else /* X [j] = y ; */ ASSIGN (Xx,Xz,j, yx,yz,0) ; #endif } } } /* prepare for the next inclusion of this file in cholmod_solve.c */ #undef LL #undef LD ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Cholesky/cholmod_etree.c���������������������������������������������������������0000644�0001762�0000144�00000015423�13652535054�020145� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Cholesky/cholmod_etree =============================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Cholesky Module. Copyright (C) 2005-2006, Timothy A. Davis * -------------------------------------------------------------------------- */ /* Compute the elimination tree of A or A'*A * * In the symmetric case, the upper triangular part of A is used. Entries not * in this part of the matrix are ignored. Computing the etree of a symmetric * matrix from just its lower triangular entries is not supported. * * In the unsymmetric case, all of A is used, and the etree of A'*A is computed. * * References: * * J. Liu, "A compact row storage scheme for Cholesky factors", ACM Trans. * Math. Software, vol 12, 1986, pp. 127-148. * * J. Liu, "The role of elimination trees in sparse factorization", SIAM J. * Matrix Analysis & Applic., vol 11, 1990, pp. 134-172. * * J. Gilbert, X. Li, E. Ng, B. Peyton, "Computing row and column counts for * sparse QR and LU factorization", BIT, vol 41, 2001, pp. 693-710. * * workspace: symmetric: Iwork (nrow), unsymmetric: Iwork (nrow+ncol) * * Supports any xtype (pattern, real, complex, or zomplex) */ #ifndef NCHOLESKY #include "cholmod_internal.h" #include "cholmod_cholesky.h" /* ========================================================================== */ /* === update_etree ========================================================= */ /* ========================================================================== */ static void update_etree ( /* inputs, not modified */ Int k, /* process the edge (k,i) in the input graph */ Int i, /* inputs, modified on output */ Int Parent [ ], /* Parent [t] = p if p is the parent of t */ Int Ancestor [ ] /* Ancestor [t] is the ancestor of node t in the partially-constructed etree */ ) { Int a ; for ( ; ; ) /* traverse the path from k to the root of the tree */ { a = Ancestor [k] ; if (a == i) { /* final ancestor reached; no change to tree */ return ; } /* perform path compression */ Ancestor [k] = i ; if (a == EMPTY) { /* final ancestor undefined; this is a new edge in the tree */ Parent [k] = i ; return ; } /* traverse up to the ancestor of k */ k = a ; } } /* ========================================================================== */ /* === cholmod_etree ======================================================== */ /* ========================================================================== */ /* Find the elimination tree of A or A'*A */ int CHOLMOD(etree) ( /* ---- input ---- */ cholmod_sparse *A, /* ---- output --- */ Int *Parent, /* size ncol. Parent [j] = p if p is the parent of j */ /* --------------- */ cholmod_common *Common ) { Int *Ap, *Ai, *Anz, *Ancestor, *Prev, *Iwork ; Int i, j, jprev, p, pend, nrow, ncol, packed, stype ; size_t s ; int ok = TRUE ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_NULL (Parent, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ stype = A->stype ; /* s = A->nrow + (stype ? 0 : A->ncol) */ s = CHOLMOD(add_size_t) (A->nrow, (stype ? 0 : A->ncol), &ok) ; if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (FALSE) ; } CHOLMOD(allocate_work) (0, s, 0, Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; /* out of memory */ } ASSERT (CHOLMOD(dump_sparse) (A, "etree", Common) >= 0) ; Iwork = Common->Iwork ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ ncol = A->ncol ; /* the number of columns of A */ nrow = A->nrow ; /* the number of rows of A */ Ap = A->p ; /* size ncol+1, column pointers for A */ Ai = A->i ; /* the row indices of A */ Anz = A->nz ; /* number of nonzeros in each column of A */ packed = A->packed ; Ancestor = Iwork ; /* size ncol (i/i/l) */ for (j = 0 ; j < ncol ; j++) { Parent [j] = EMPTY ; Ancestor [j] = EMPTY ; } /* ---------------------------------------------------------------------- */ /* compute the etree */ /* ---------------------------------------------------------------------- */ if (stype > 0) { /* ------------------------------------------------------------------ */ /* symmetric (upper) case: compute etree (A) */ /* ------------------------------------------------------------------ */ for (j = 0 ; j < ncol ; j++) { /* for each row i in column j of triu(A), excluding the diagonal */ p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; if (i < j) { update_etree (i, j, Parent, Ancestor) ; } } } } else if (stype == 0) { /* ------------------------------------------------------------------ */ /* unsymmetric case: compute etree (A'*A) */ /* ------------------------------------------------------------------ */ Prev = Iwork + ncol ; /* size nrow (i/i/l) */ for (i = 0 ; i < nrow ; i++) { Prev [i] = EMPTY ; } for (j = 0 ; j < ncol ; j++) { /* for each row i in column j of A */ p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { /* a graph is constructed dynamically with one path per row * of A. If the ith row of A contains column indices * (j1,j2,j3,j4) then the new graph has edges (j1,j2), (j2,j3), * and (j3,j4). When at node i of this path-graph, all edges * (jprev,j) are considered, where jprev>>>> finding etree of post-permuted matrix\n") ; */ cholmod_etree (symmetric ? SS:FF, Parent2, Common) ; /* cholmod_print_parent (Parent2, n, "Parent2, w/colcnt", Common) ; for (k = 0 ; k < n ; k++) { printf ("k %d Parent old %d new %d\n", k, Lparent [k], Parent2 [k]) ; } */ for (k = 0 ; k < n ; k++) { ASSERT (Lparent [k] == Parent2 [k]) ; } /* workspace: Iwork (2*nrow) */ cholmod_postorder (Parent2, n, NULL, Post2, Common) ; cholmod_rowcolcounts (symmetric ? FF:SS, fset, nf, Parent2, Post2, NULL, ColCount2, First, Level, Common) ; for (k = 0 ; k < n ; k++) { ASSERT (Lcolcount [k] == ColCount2 [k]) ; } cholmod_free (n, sizeof (int), ColCount2, Common) ; cholmod_free (n, sizeof (int), Parent2, Common) ; cholmod_free (n, sizeof (int), Post2, Common) ; cholmod_free_sparse (&C1, Common) ; cholmod_free_sparse (&C2, Common) ; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Cholesky/t_cholmod_solve.c�������������������������������������������������������0000644�0001762�0000144�00000012056�13652535054�020513� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Cholesky/t_cholmod_solve ============================================= */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Cholesky Module. Copyright (C) 2005-2013, Timothy A. Davis * -------------------------------------------------------------------------- */ /* Template routine for cholmod_solve. Supports any numeric xtype (real, * complex, or zomplex). The xtypes of all matrices (L and Y) must match. */ #include "cholmod_template.h" /* ========================================================================== */ /* === simplicial template solvers ========================================== */ /* ========================================================================== */ /* LL': solve Lx=b with non-unit diagonal */ #define LL #include "t_cholmod_lsolve.c" /* LDL': solve LDx=b */ #define LD #include "t_cholmod_lsolve.c" /* LDL': solve Lx=b with unit diagonal */ #include "t_cholmod_lsolve.c" /* LL': solve L'x=b with non-unit diagonal */ #define LL #include "t_cholmod_ltsolve.c" /* LDL': solve DL'x=b */ #define LD #include "t_cholmod_ltsolve.c" /* LDL': solve L'x=b with unit diagonal */ #include "t_cholmod_ltsolve.c" /* ========================================================================== */ /* === t_ldl_dsolve ========================================================= */ /* ========================================================================== */ /* Solve Dx=b for an LDL' factorization, where Y holds b' on input and x' on * output. * * The number of right-hand-sides (nrhs) is not restricted, even if Yseti * is present. */ static void TEMPLATE (ldl_dsolve) ( cholmod_factor *L, cholmod_dense *Y, /* nr-by-n with leading dimension nr */ Int *Yseti, Int ysetlen ) { double d [1] ; double *Lx, *Yx, *Yz ; Int *Lp ; Int n, nrhs, k, p, k1, k2, kk, kkiters ; ASSERT (L->xtype == Y->xtype) ; /* L and Y must have the same xtype */ ASSERT (L->n == Y->ncol) ; /* dimensions must match */ ASSERT (Y->nrow == Y->d) ; /* leading dimension of Y = # rows of Y */ ASSERT (L->xtype != CHOLMOD_PATTERN) ; /* L is not symbolic */ ASSERT (!(L->is_super) && !(L->is_ll)) ; /* L is simplicial LDL' */ nrhs = Y->nrow ; n = L->n ; Lp = L->p ; Lx = L->x ; Yx = Y->x ; Yz = Y->z ; kkiters = Yseti ? ysetlen : n ; for (kk = 0 ; kk < kkiters ; kk++) { k = Yseti ? Yseti [kk] : kk ; k1 = k*nrhs ; k2 = (k+1)*nrhs ; ASSIGN_REAL (d,0, Lx,Lp[k]) ; for (p = k1 ; p < k2 ; p++) { DIV_REAL (Yx,Yz,p, Yx,Yz,p, d,0) ; } } } /* ========================================================================== */ /* === t_simplicial_solver ================================================== */ /* ========================================================================== */ /* Solve a linear system, where Y' contains the (array-transposed) right-hand * side on input, and the solution on output. No permutations are applied; * these must have already been applied to Y on input. * * Yseti [0..ysetlen-1] is an optional list of indices from * cholmod_lsolve_pattern. The solve is performed only on the columns of L * corresponding to entries in Yseti. Ignored if NULL. If present, most * functions require that Y' consist of a single dense column. */ static void TEMPLATE (simplicial_solver) ( int sys, /* system to solve */ cholmod_factor *L, /* factor to use, a simplicial LL' or LDL' */ cholmod_dense *Y, /* right-hand-side on input, solution on output */ Int *Yseti, Int ysetlen ) { if (L->is_ll) { /* The factorization is LL' */ if (sys == CHOLMOD_A || sys == CHOLMOD_LDLt) { /* Solve Ax=b or LL'x=b */ TEMPLATE (ll_lsolve_k) (L, Y, Yseti, ysetlen) ; TEMPLATE (ll_ltsolve_k) (L, Y, Yseti, ysetlen) ; } else if (sys == CHOLMOD_L || sys == CHOLMOD_LD) { /* Solve Lx=b */ TEMPLATE (ll_lsolve_k) (L, Y, Yseti, ysetlen) ; } else if (sys == CHOLMOD_Lt || sys == CHOLMOD_DLt) { /* Solve L'x=b */ TEMPLATE (ll_ltsolve_k) (L, Y, Yseti, ysetlen) ; } } else { /* The factorization is LDL' */ if (sys == CHOLMOD_A || sys == CHOLMOD_LDLt) { /* Solve Ax=b or LDL'x=b */ TEMPLATE (ldl_lsolve_k) (L, Y, Yseti, ysetlen) ; TEMPLATE (ldl_dltsolve_k) (L, Y, Yseti, ysetlen) ; } else if (sys == CHOLMOD_LD) { /* Solve LDx=b */ TEMPLATE (ldl_ldsolve_k) (L, Y, Yseti, ysetlen) ; } else if (sys == CHOLMOD_L) { /* Solve Lx=b */ TEMPLATE (ldl_lsolve_k) (L, Y, Yseti, ysetlen) ; } else if (sys == CHOLMOD_Lt) { /* Solve L'x=b */ TEMPLATE (ldl_ltsolve_k) (L, Y, Yseti, ysetlen) ; } else if (sys == CHOLMOD_DLt) { /* Solve DL'x=b */ TEMPLATE (ldl_dltsolve_k) (L, Y, Yseti, ysetlen) ; } else if (sys == CHOLMOD_D) { /* Solve Dx=b */ TEMPLATE (ldl_dsolve) (L, Y, Yseti, ysetlen) ; } } } #undef PATTERN #undef REAL #undef COMPLEX #undef ZOMPLEX ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Cholesky/t_cholmod_rowfac.c������������������������������������������������������0000644�0001762�0000144�00000032023�13652535054�020640� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Cholesky/t_cholmod_rowfac ============================================ */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Cholesky Module. Copyright (C) 2005-2006, Timothy A. Davis * -------------------------------------------------------------------------- */ /* Template routine for cholmod_rowfac. Supports any numeric xtype * (real, complex, or zomplex). * * workspace: Iwork (n), Flag (n), Xwork (n if real, 2*n if complex) */ #include "cholmod_template.h" #ifdef MASK static int TEMPLATE (cholmod_rowfac_mask) #else static int TEMPLATE (cholmod_rowfac) #endif ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to factorize */ cholmod_sparse *F, /* used for A*A' case only. F=A' or A(:,f)' */ double beta [2], /* factorize beta*I+A or beta*I+AA' (beta [0] only) */ size_t kstart, /* first row to factorize */ size_t kend, /* last row to factorize is kend-1 */ #ifdef MASK /* These inputs are used for cholmod_rowfac_mask only */ Int *mask, /* size A->nrow. if mask[i] >= maskmark then W(i) is set to zero */ Int maskmark, Int *RLinkUp, /* size A->nrow. link list of rows to compute */ #endif /* ---- in/out --- */ cholmod_factor *L, /* --------------- */ cholmod_common *Common ) { double yx [2], lx [2], fx [2], dk [1], di [1], fl = 0 ; #ifdef ZOMPLEX double yz [1], lz [1], fz [1] ; #endif double *Ax, *Az, *Lx, *Lz, *Wx, *Wz, *Fx, *Fz ; Int *Ap, *Anz, *Ai, *Lp, *Lnz, *Li, *Lnext, *Flag, *Stack, *Fp, *Fi, *Fnz, *Iwork ; Int i, p, k, t, pf, pfend, top, s, mark, pend, n, lnz, is_ll, multadds, use_dbound, packed, stype, Fpacked, sorted, nzmax, len, parent ; #ifndef REAL Int dk_imaginary ; #endif /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ PRINT1 (("\nin cholmod_rowfac, kstart %d kend %d stype %d\n", kstart, kend, A->stype)) ; DEBUG (CHOLMOD(dump_factor) (L, "Initial L", Common)) ; n = A->nrow ; stype = A->stype ; if (stype > 0) { /* symmetric upper case: F is not needed. It may be NULL */ Fp = NULL ; Fi = NULL ; Fx = NULL ; Fz = NULL ; Fnz = NULL ; Fpacked = TRUE ; } else { /* unsymmetric case: F is required. */ Fp = F->p ; Fi = F->i ; Fx = F->x ; Fz = F->z ; Fnz = F->nz ; Fpacked = F->packed ; } Ap = A->p ; /* size A->ncol+1, column pointers of A */ Ai = A->i ; /* size nz = Ap [A->ncol], row indices of A */ Ax = A->x ; /* size nz, numeric values of A */ Az = A->z ; Anz = A->nz ; packed = A->packed ; sorted = A->sorted ; use_dbound = IS_GT_ZERO (Common->dbound) ; /* get the current factors L (and D for LDL'); allocate space if needed */ is_ll = L->is_ll ; if (L->xtype == CHOLMOD_PATTERN) { /* ------------------------------------------------------------------ */ /* L is symbolic only; allocate and initialize L (and D for LDL') */ /* ------------------------------------------------------------------ */ /* workspace: none */ CHOLMOD(change_factor) (A->xtype, is_ll, FALSE, FALSE, TRUE, L, Common); if (Common->status < CHOLMOD_OK) { /* out of memory */ return (FALSE) ; } ASSERT (L->minor == (size_t) n) ; } else if (kstart == 0 && kend == (size_t) n) { /* ------------------------------------------------------------------ */ /* refactorization; reset L->nz and L->minor to restart factorization */ /* ------------------------------------------------------------------ */ L->minor = n ; Lnz = L->nz ; for (k = 0 ; k < n ; k++) { Lnz [k] = 1 ; } } ASSERT (is_ll == L->is_ll) ; ASSERT (L->xtype != CHOLMOD_PATTERN) ; DEBUG (CHOLMOD(dump_factor) (L, "L ready", Common)) ; DEBUG (CHOLMOD(dump_sparse) (A, "A ready", Common)) ; DEBUG (if (stype == 0) CHOLMOD(dump_sparse) (F, "F ready", Common)) ; /* inputs, can be modified on output: */ Lp = L->p ; /* size n+1 */ ASSERT (Lp != NULL) ; /* outputs, contents defined on input for incremental case only: */ Lnz = L->nz ; /* size n */ Lnext = L->next ; /* size n+2 */ Li = L->i ; /* size L->nzmax, can change in size */ Lx = L->x ; /* size L->nzmax or 2*L->nzmax, can change in size */ Lz = L->z ; /* size L->nzmax for zomplex case, can change in size */ nzmax = L->nzmax ; ASSERT (Lnz != NULL && Li != NULL && Lx != NULL) ; /* ---------------------------------------------------------------------- */ /* get workspace */ /* ---------------------------------------------------------------------- */ Iwork = Common->Iwork ; Stack = Iwork ; /* size n (i/i/l) */ Flag = Common->Flag ; /* size n, Flag [i] < mark must hold */ Wx = Common->Xwork ; /* size n if real, 2*n if complex or * zomplex. Xwork [i] == 0 must hold. */ Wz = Wx + n ; /* size n for zomplex case only */ mark = Common->mark ; ASSERT ((Int) Common->xworksize >= (L->xtype == CHOLMOD_REAL ? 1:2)*n) ; /* ---------------------------------------------------------------------- */ /* compute LDL' or LL' factorization by rows */ /* ---------------------------------------------------------------------- */ #ifdef MASK #define NEXT(k) k = RLinkUp [k] #else #define NEXT(k) k++ #endif for (k = kstart ; k < ((Int) kend) ; NEXT(k)) { PRINT1 (("\n===============K "ID" Lnz [k] "ID"\n", k, Lnz [k])) ; /* ------------------------------------------------------------------ */ /* compute pattern of kth row of L and scatter kth input column */ /* ------------------------------------------------------------------ */ /* column k of L is currently empty */ ASSERT (Lnz [k] == 1) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 2*n, Common)) ; top = n ; /* Stack is empty */ Flag [k] = mark ; /* do not include diagonal entry in Stack */ /* use Li [Lp [i]+1] for etree */ #define PARENT(i) (Lnz [i] > 1) ? (Li [Lp [i] + 1]) : EMPTY if (stype > 0) { /* scatter kth col of triu (beta*I+AA'), get pattern L(k,:) */ p = Ap [k] ; pend = (packed) ? (Ap [k+1]) : (p + Anz [k]) ; /* W [i] = Ax [i] ; scatter column of A */ #define SCATTER ASSIGN(Wx,Wz,i, Ax,Az,p) SUBTREE ; #undef SCATTER } else { /* scatter kth col of triu (beta*I+AA'), get pattern L(k,:) */ pf = Fp [k] ; pfend = (Fpacked) ? (Fp [k+1]) : (pf + Fnz [k]) ; for ( ; pf < pfend ; pf++) { /* get nonzero entry F (t,k) */ t = Fi [pf] ; /* fk = Fx [pf] */ ASSIGN (fx, fz, 0, Fx, Fz, pf) ; p = Ap [t] ; pend = (packed) ? (Ap [t+1]) : (p + Anz [t]) ; multadds = 0 ; /* W [i] += Ax [p] * fx ; scatter column of A*A' */ #define SCATTER MULTADD (Wx,Wz,i, Ax,Az,p, fx,fz,0) ; multadds++ ; SUBTREE ; #undef SCATTER #ifdef REAL fl += 2 * ((double) multadds) ; #else fl += 8 * ((double) multadds) ; #endif } } #undef PARENT /* ------------------------------------------------------------------ */ /* if mask is present, set the corresponding entries in W to zero */ /* ------------------------------------------------------------------ */ #ifdef MASK /* remove the dead element of Wx */ if (mask != NULL) { #if 0 /* older version */ for (p = n; p > top;) { i = Stack [--p] ; if ( mask [i] >= 0 ) { CLEAR (Wx,Wz,i) ; /* set W(i) to zero */ } } #endif for (s = top ; s < n ; s++) { i = Stack [s] ; if (mask [i] >= maskmark) { CLEAR (Wx,Wz,i) ; /* set W(i) to zero */ } } } #endif /* nonzero pattern of kth row of L is now in Stack [top..n-1]. * Flag [Stack [top..n-1]] is equal to mark, but no longer needed */ /* mark = CHOLMOD(clear_flag) (Common) ; */ CHOLMOD_CLEAR_FLAG (Common) ; mark = Common->mark ; /* ------------------------------------------------------------------ */ /* compute kth row of L and store in column form */ /* ------------------------------------------------------------------ */ /* Solve L (0:k-1, 0:k-1) * y (0:k-1) = b (0:k-1) where * b (0:k) = A (0:k,k) or A(0:k,:) * F(:,k) is in W and Stack. * * For LDL' factorization: * L (k, 0:k-1) = y (0:k-1) ./ D (0:k-1) * D (k) = b (k) - L (k, 0:k-1) * y (0:k-1) * * For LL' factorization: * L (k, 0:k-1) = y (0:k-1) * L (k,k) = sqrt (b (k) - L (k, 0:k-1) * L (0:k-1, k)) */ /* dk = W [k] + beta */ ADD_REAL (dk,0, Wx,k, beta,0) ; #ifndef REAL /* In the unsymmetric case, the imaginary part of W[k] must be real, * since F is assumed to be the complex conjugate transpose of A. In * the symmetric case, W[k] is the diagonal of A. If the imaginary part * of W[k] is nonzero, then the Cholesky factorization cannot be * computed; A is not positive definite */ dk_imaginary = (stype > 0) ? (IMAG_IS_NONZERO (Wx,Wz,k)) : FALSE ; #endif /* W [k] = 0.0 ; */ CLEAR (Wx,Wz,k) ; for (s = top ; s < n ; s++) { /* get i for each nonzero entry L(k,i) */ i = Stack [s] ; /* y = W [i] ; */ ASSIGN (yx,yz,0, Wx,Wz,i) ; /* W [i] = 0.0 ; */ CLEAR (Wx,Wz,i) ; lnz = Lnz [i] ; p = Lp [i] ; ASSERT (lnz > 0 && Li [p] == i) ; pend = p + lnz ; /* di = Lx [p] ; the diagonal entry L or D(i,i), which is real */ ASSIGN_REAL (di,0, Lx,p) ; if (i >= (Int) L->minor || IS_ZERO (di [0])) { /* For the LL' factorization, L(i,i) is zero. For the LDL', * D(i,i) is zero. Skip column i of L, and set L(k,i) = 0. */ CLEAR (lx,lz,0) ; p = pend ; } else if (is_ll) { #ifdef REAL fl += 2 * ((double) (pend - p - 1)) + 3 ; #else fl += 8 * ((double) (pend - p - 1)) + 6 ; #endif /* forward solve using L (i:(k-1),i) */ /* divide by L(i,i), which must be real and nonzero */ /* y /= di [0] */ DIV_REAL (yx,yz,0, yx,yz,0, di,0) ; for (p++ ; p < pend ; p++) { /* W [Li [p]] -= Lx [p] * y ; */ MULTSUB (Wx,Wz,Li[p], Lx,Lz,p, yx,yz,0) ; } /* do not scale L; compute dot product for L(k,k) */ /* L(k,i) = conj(y) ; */ ASSIGN_CONJ (lx,lz,0, yx,yz,0) ; /* d -= conj(y) * y ; */ LLDOT (dk,0, yx,yz,0) ; } else { #ifdef REAL fl += 2 * ((double) (pend - p - 1)) + 3 ; #else fl += 8 * ((double) (pend - p - 1)) + 6 ; #endif /* forward solve using D (i,i) and L ((i+1):(k-1),i) */ for (p++ ; p < pend ; p++) { /* W [Li [p]] -= Lx [p] * y ; */ MULTSUB (Wx,Wz,Li[p], Lx,Lz,p, yx,yz,0) ; } /* Scale L (k,0:k-1) for LDL' factorization, compute D (k,k)*/ #ifdef REAL /* L(k,i) = y/d */ lx [0] = yx [0] / di [0] ; /* d -= L(k,i) * y */ dk [0] -= lx [0] * yx [0] ; #else /* L(k,i) = conj(y) ; */ ASSIGN_CONJ (lx,lz,0, yx,yz,0) ; /* L(k,i) /= di ; */ DIV_REAL (lx,lz,0, lx,lz,0, di,0) ; /* d -= conj(y) * y / di */ LDLDOT (dk,0, yx,yz,0, di,0) ; #endif } /* determine if column i of L can hold the new L(k,i) entry */ if (p >= Lp [Lnext [i]]) { /* column i needs to grow */ PRINT1 (("Factor Colrealloc "ID", old Lnz "ID"\n", i, Lnz [i])); if (!CHOLMOD(reallocate_column) (i, lnz + 1, L, Common)) { /* out of memory, L is now simplicial symbolic */ for (i = 0 ; i < n ; i++) { /* W [i] = 0 ; */ CLEAR (Wx,Wz,i) ; } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, n, Common)) ; return (FALSE) ; } Li = L->i ; /* L->i, L->x, L->z may have moved */ Lx = L->x ; Lz = L->z ; p = Lp [i] + lnz ; /* contents of L->p changed */ ASSERT (p < Lp [Lnext [i]]) ; } /* store L (k,i) in the column form matrix of L */ Li [p] = k ; /* Lx [p] = L(k,i) ; */ ASSIGN (Lx,Lz,p, lx,lz,0) ; Lnz [i]++ ; } /* ------------------------------------------------------------------ */ /* ensure abs (d) >= dbound if dbound is given, and store it in L */ /* ------------------------------------------------------------------ */ p = Lp [k] ; Li [p] = k ; if (k >= (Int) L->minor) { /* the matrix is already not positive definite */ dk [0] = 0 ; } else if (use_dbound) { /* modify the diagonal to force LL' or LDL' to exist */ dk [0] = CHOLMOD(dbound) (is_ll ? fabs (dk [0]) : dk [0], Common) ; } else if ((is_ll ? (IS_LE_ZERO (dk [0])) : (IS_ZERO (dk [0]))) #ifndef REAL || dk_imaginary #endif ) { /* the matrix has just been found to be not positive definite */ dk [0] = 0 ; L->minor = k ; ERROR (CHOLMOD_NOT_POSDEF, "not positive definite") ; } if (is_ll) { /* this is counted as one flop, below */ dk [0] = sqrt (dk [0]) ; } /* Lx [p] = D(k,k) = d ; real part only */ ASSIGN_REAL (Lx,p, dk,0) ; CLEAR_IMAG (Lx,Lz,p) ; } #undef NEXT if (is_ll) fl += MAX ((Int) kend - (Int) kstart, 0) ; /* count sqrt's */ Common->rowfacfl = fl ; DEBUG (CHOLMOD(dump_factor) (L, "final cholmod_rowfac", Common)) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, n, Common)) ; return (TRUE) ; } #undef PATTERN #undef REAL #undef COMPLEX #undef ZOMPLEX �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Cholesky/cholmod_rowcolcounts.c��������������������������������������������������0000644�0001762�0000144�00000043311�13652535054�021577� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Cholesky/cholmod_rowcolcounts ======================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Cholesky Module. Copyright (C) 2005-2006, Timothy A. Davis * -------------------------------------------------------------------------- */ /* Compute the row and column counts of the Cholesky factor L of the matrix * A or A*A'. The etree and its postordering must already be computed (see * cholmod_etree and cholmod_postorder) and given as inputs to this routine. * * For the symmetric case (LL'=A), A is accessed by column. Only the lower * triangular part of A is used. Entries not in this part of the matrix are * ignored. This is the same as storing the upper triangular part of A by * rows, with entries in the lower triangular part being ignored. NOTE: this * representation is the TRANSPOSE of the input to cholmod_etree. * * For the unsymmetric case (LL'=AA'), A is accessed by column. Equivalently, * if A is viewed as a matrix in compressed-row form, this routine computes * the row and column counts for L where LL'=A'A. If the input vector f is * present, then F*F' is analyzed instead, where F = A(:,f). * * The set f is held in fset and fsize. * fset = NULL means ":" in MATLAB. fset is ignored. * fset != NULL means f = fset [0..fset-1]. * fset != NULL and fsize = 0 means f is the empty set. * Common->status is set to CHOLMOD_INVALID if fset is invalid. * * In both cases, the columns of A need not be sorted. * A can be packed or unpacked. * * References: * J. Gilbert, E. Ng, B. Peyton, "An efficient algorithm to compute row and * column counts for sparse Cholesky factorization", SIAM J. Matrix Analysis & * Applic., vol 15, 1994, pp. 1075-1091. * * J. Gilbert, X. Li, E. Ng, B. Peyton, "Computing row and column counts for * sparse QR and LU factorization", BIT, vol 41, 2001, pp. 693-710. * * workspace: * if symmetric: Flag (nrow), Iwork (2*nrow) * if unsymmetric: Flag (nrow), Iwork (2*nrow+ncol), Head (nrow+1) * * Supports any xtype (pattern, real, complex, or zomplex). */ #ifndef NCHOLESKY #include "cholmod_internal.h" #include "cholmod_cholesky.h" /* ========================================================================== */ /* === initialize_node ====================================================== */ /* ========================================================================== */ static Int initialize_node /* initial work for kth node in postordered etree */ ( Int k, /* at the kth step of the algorithm (and kth node) */ Int Post [ ], /* Post [k] = i, the kth node in postordered etree */ Int Parent [ ], /* Parent [i] is the parent of i in the etree */ Int ColCount [ ], /* ColCount [c] is the current weight of node c */ Int PrevNbr [ ] /* PrevNbr [u] = k if u was last considered at step k */ ) { Int p, parent ; /* determine p, the kth node in the postordered etree */ p = Post [k] ; /* adjust the weight if p is not a root of the etree */ parent = Parent [p] ; if (parent != EMPTY) { ColCount [parent]-- ; } /* flag node p to exclude self edges (p,p) */ PrevNbr [p] = k ; return (p) ; } /* ========================================================================== */ /* === process_edge ========================================================= */ /* ========================================================================== */ /* edge (p,u) is being processed. p < u is a descendant of its ancestor u in * the etree. node p is the kth node in the postordered etree. */ static void process_edge ( Int p, /* process edge (p,u) of the matrix */ Int u, Int k, /* we are at the kth node in the postordered etree */ Int First [ ], /* First [i] = k if the postordering of first * descendent of node i is k */ Int PrevNbr [ ], /* u was last considered at step k = PrevNbr [u] */ Int ColCount [ ], /* ColCount [c] is the current weight of node c */ Int PrevLeaf [ ], /* s = PrevLeaf [u] means that s was the last leaf * seen in the subtree rooted at u. */ Int RowCount [ ], /* RowCount [i] is # of nonzeros in row i of L, * including the diagonal. Not computed if NULL. */ Int SetParent [ ], /* the FIND/UNION data structure, which forms a set * of trees. A root i has i = SetParent [i]. Following * a path from i to the root q of the subtree containing * i means that q is the SetParent representative of i. * All nodes in the tree could have their SetParent * equal to the root q; the tree representation is used * to save time. When a path is traced from i to its * root q, the path is re-traversed to set the SetParent * of the whole path to be the root q. */ Int Level [ ] /* Level [i] = length of path from node i to root */ ) { Int prevleaf, q, s, sparent ; if (First [p] > PrevNbr [u]) { /* p is a leaf of the subtree of u */ ColCount [p]++ ; prevleaf = PrevLeaf [u] ; if (prevleaf == EMPTY) { /* p is the first leaf of subtree of u; RowCount will be incremented * by the length of the path in the etree from p up to u. */ q = u ; } else { /* q = FIND (prevleaf): find the root q of the * SetParent tree containing prevleaf */ for (q = prevleaf ; q != SetParent [q] ; q = SetParent [q]) { ; } /* the root q has been found; re-traverse the path and * perform path compression */ s = prevleaf ; for (s = prevleaf ; s != q ; s = sparent) { sparent = SetParent [s] ; SetParent [s] = q ; } /* adjust the RowCount and ColCount; RowCount will be incremented by * the length of the path from p to the SetParent root q, and * decrement the ColCount of q by one. */ ColCount [q]-- ; } if (RowCount != NULL) { /* if RowCount is being computed, increment it by the length of * the path from p to q */ RowCount [u] += (Level [p] - Level [q]) ; } /* p is a leaf of the subtree of u, so mark PrevLeaf [u] to be p */ PrevLeaf [u] = p ; } /* flag u has having been processed at step k */ PrevNbr [u] = k ; } /* ========================================================================== */ /* === finalize_node ======================================================== */ /* ========================================================================== */ static void finalize_node /* compute UNION (p, Parent [p]) */ ( Int p, Int Parent [ ], /* Parent [p] is the parent of p in the etree */ Int SetParent [ ] /* see process_edge, above */ ) { /* all nodes in the SetParent tree rooted at p now have as their final * root the node Parent [p]. This computes UNION (p, Parent [p]) */ if (Parent [p] != EMPTY) { SetParent [p] = Parent [p] ; } } /* ========================================================================== */ /* === cholmod_rowcolcounts ================================================= */ /* ========================================================================== */ int CHOLMOD(rowcolcounts) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to analyze */ Int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ Int *Parent, /* size nrow. Parent [i] = p if p is the parent of i */ Int *Post, /* size nrow. Post [k] = i if i is the kth node in * the postordered etree. */ /* ---- output --- */ Int *RowCount, /* size nrow. RowCount [i] = # entries in the ith row of * L, including the diagonal. */ Int *ColCount, /* size nrow. ColCount [i] = # entries in the ith * column of L, including the diagonal. */ Int *First, /* size nrow. First [i] = k is the least postordering * of any descendant of i. */ Int *Level, /* size nrow. Level [i] is the length of the path from * i to the root, with Level [root] = 0. */ /* --------------- */ cholmod_common *Common ) { double fl, ff ; Int *Ap, *Ai, *Anz, *PrevNbr, *SetParent, *Head, *PrevLeaf, *Anext, *Ipost, *Iwork ; Int i, j, r, k, len, s, p, pend, inew, stype, nf, anz, inode, parent, nrow, ncol, packed, use_fset, jj ; size_t w ; int ok = TRUE ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_NULL (Parent, FALSE) ; RETURN_IF_NULL (Post, FALSE) ; RETURN_IF_NULL (ColCount, FALSE) ; RETURN_IF_NULL (First, FALSE) ; RETURN_IF_NULL (Level, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; stype = A->stype ; if (stype > 0) { /* symmetric with upper triangular part not supported */ ERROR (CHOLMOD_INVALID, "symmetric upper not supported") ; return (FALSE) ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ nrow = A->nrow ; /* the number of rows of A */ ncol = A->ncol ; /* the number of columns of A */ /* w = 2*nrow + (stype ? 0 : ncol) */ w = CHOLMOD(mult_size_t) (nrow, 2, &ok) ; w = CHOLMOD(add_size_t) (w, (stype ? 0 : ncol), &ok) ; if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (FALSE) ; } CHOLMOD(allocate_work) (nrow, w, 0, Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; } ASSERT (CHOLMOD(dump_perm) (Post, nrow, nrow, "Post", Common)) ; ASSERT (CHOLMOD(dump_parent) (Parent, nrow, "Parent", Common)) ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ Ap = A->p ; /* size ncol+1, column pointers for A */ Ai = A->i ; /* the row indices of A, of size nz=Ap[ncol+1] */ Anz = A->nz ; packed = A->packed ; ASSERT (IMPLIES (!packed, Anz != NULL)) ; /* ---------------------------------------------------------------------- */ /* get workspace */ /* ---------------------------------------------------------------------- */ Iwork = Common->Iwork ; SetParent = Iwork ; /* size nrow (i/i/l) */ PrevNbr = Iwork + nrow ; /* size nrow (i/i/l) */ Anext = Iwork + 2*((size_t) nrow) ; /* size ncol (i/i/l) (unsym only) */ PrevLeaf = Common->Flag ; /* size nrow */ Head = Common->Head ; /* size nrow+1 (unsym only)*/ /* ---------------------------------------------------------------------- */ /* find the first descendant and level of each node in the tree */ /* ---------------------------------------------------------------------- */ /* First [i] = k if the postordering of first descendent of node i is k */ /* Level [i] = length of path from node i to the root (Level [root] = 0) */ for (i = 0 ; i < nrow ; i++) { First [i] = EMPTY ; } /* postorder traversal of the etree */ for (k = 0 ; k < nrow ; k++) { /* node i of the etree is the kth node in the postordered etree */ i = Post [k] ; /* i is a leaf if First [i] is still EMPTY */ /* ColCount [i] starts at 1 if i is a leaf, zero otherwise */ ColCount [i] = (First [i] == EMPTY) ? 1 : 0 ; /* traverse the path from node i to the root, stopping if we find a * node r whose First [r] is already defined. */ len = 0 ; for (r = i ; (r != EMPTY) && (First [r] == EMPTY) ; r = Parent [r]) { First [r] = k ; len++ ; } if (r == EMPTY) { /* we hit a root node, the level of which is zero */ len-- ; } else { /* we stopped at node r, where Level [r] is already defined */ len += Level [r] ; } /* re-traverse the path from node i to r; set the level of each node */ for (s = i ; s != r ; s = Parent [s]) { Level [s] = len-- ; } } /* ---------------------------------------------------------------------- */ /* AA' case: sort columns of A according to first postordered row index */ /* ---------------------------------------------------------------------- */ fl = 0.0 ; if (stype == 0) { /* [ use PrevNbr [0..nrow-1] as workspace for Ipost */ Ipost = PrevNbr ; /* Ipost [i] = k if i is the kth node in the postordered etree. */ for (k = 0 ; k < nrow ; k++) { Ipost [Post [k]] = k ; } use_fset = (fset != NULL) ; if (use_fset) { nf = fsize ; /* clear Anext to check fset */ for (j = 0 ; j < ncol ; j++) { Anext [j] = -2 ; } /* find the first postordered row in each column of A (post,f) * and place the column in the corresponding link list */ for (jj = 0 ; jj < nf ; jj++) { j = fset [jj] ; if (j < 0 || j > ncol || Anext [j] != -2) { /* out-of-range or duplicate entry in fset */ ERROR (CHOLMOD_INVALID, "fset invalid") ; return (FALSE) ; } /* flag column j as having been seen */ Anext [j] = EMPTY ; } /* fset is now valid */ ASSERT (CHOLMOD(dump_perm) (fset, nf, ncol, "fset", Common)) ; } else { nf = ncol ; } for (jj = 0 ; jj < nf ; jj++) { j = (use_fset) ? (fset [jj]) : jj ; /* column j is in the fset; find the smallest row (if any) */ p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; ff = (double) MAX (0, pend - p) ; fl += ff*ff + ff ; if (pend > p) { k = Ipost [Ai [p]] ; for ( ; p < pend ; p++) { inew = Ipost [Ai [p]] ; k = MIN (k, inew) ; } /* place column j in link list k */ ASSERT (k >= 0 && k < nrow) ; Anext [j] = Head [k] ; Head [k] = j ; } } /* Ipost no longer needed for inverse postordering ] * Head [k] contains a link list of all columns whose first * postordered row index is equal to k, for k = 0 to nrow-1. */ } /* ---------------------------------------------------------------------- */ /* compute the row counts and node weights */ /* ---------------------------------------------------------------------- */ if (RowCount != NULL) { for (i = 0 ; i < nrow ; i++) { RowCount [i] = 1 ; } } for (i = 0 ; i < nrow ; i++) { PrevLeaf [i] = EMPTY ; PrevNbr [i] = EMPTY ; SetParent [i] = i ; /* every node is in its own set, by itself */ } if (stype != 0) { /* ------------------------------------------------------------------ */ /* symmetric case: LL' = A */ /* ------------------------------------------------------------------ */ /* also determine the number of entries in triu(A) */ anz = nrow ; for (k = 0 ; k < nrow ; k++) { /* j is the kth node in the postordered etree */ j = initialize_node (k, Post, Parent, ColCount, PrevNbr) ; /* for all nonzeros A(i,j) below the diagonal, in column j of A */ p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; if (i > j) { /* j is a descendant of i in etree(A) */ anz++ ; process_edge (j, i, k, First, PrevNbr, ColCount, PrevLeaf, RowCount, SetParent, Level) ; } } /* update SetParent: UNION (j, Parent [j]) */ finalize_node (j, Parent, SetParent) ; } Common->anz = anz ; } else { /* ------------------------------------------------------------------ */ /* unsymmetric case: LL' = AA' */ /* ------------------------------------------------------------------ */ for (k = 0 ; k < nrow ; k++) { /* inode is the kth node in the postordered etree */ inode = initialize_node (k, Post, Parent, ColCount, PrevNbr) ; /* for all cols j whose first postordered row is k: */ for (j = Head [k] ; j != EMPTY ; j = Anext [j]) { /* k is the first postordered row in column j of A */ /* for all rows i in column j: */ p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; /* has i already been considered at this step k */ if (PrevNbr [i] < k) { /* inode is a descendant of i in etree(AA') */ /* process edge (inode,i) and set PrevNbr[i] to k */ process_edge (inode, i, k, First, PrevNbr, ColCount, PrevLeaf, RowCount, SetParent, Level) ; } } } /* clear link list k */ Head [k] = EMPTY ; /* update SetParent: UNION (inode, Parent [inode]) */ finalize_node (inode, Parent, SetParent) ; } } /* ---------------------------------------------------------------------- */ /* finish computing the column counts */ /* ---------------------------------------------------------------------- */ for (j = 0 ; j < nrow ; j++) { parent = Parent [j] ; if (parent != EMPTY) { /* add the ColCount of j to its parent */ ColCount [parent] += ColCount [j] ; } } /* ---------------------------------------------------------------------- */ /* clear workspace */ /* ---------------------------------------------------------------------- */ Common->mark = EMPTY ; /* CHOLMOD(clear_flag) (Common) ; */ CHOLMOD_CLEAR_FLAG (Common) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; /* ---------------------------------------------------------------------- */ /* flop count and nnz(L) for subsequent LL' numerical factorization */ /* ---------------------------------------------------------------------- */ /* use double to avoid integer overflow. lnz cannot be NaN. */ Common->aatfl = fl ; Common->lnz = 0. ; fl = 0 ; for (j = 0 ; j < nrow ; j++) { ff = (double) (ColCount [j]) ; Common->lnz += ff ; fl += ff*ff ; } Common->fl = fl ; PRINT1 (("rowcol fl %g lnz %g\n", Common->fl, Common->lnz)) ; return (TRUE) ; } #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Cholesky/cholmod_resymbol.c������������������������������������������������������0000644�0001762�0000144�00000044047�13652535054�020701� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Cholesky/cholmod_resymbol ============================================ */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Cholesky Module. Copyright (C) 2005-2006, Timothy A. Davis * -------------------------------------------------------------------------- */ /* Recompute the symbolic pattern of L. Entries not in the symbolic pattern * are dropped. L->Perm can be used (or not) to permute the input matrix A. * * These routines are used after a supernodal factorization is converted into * a simplicial one, to remove zero entries that were added due to relaxed * supernode amalgamation. They can also be used after a series of downdates * to remove entries that would no longer be present if the matrix were * factorized from scratch. A downdate (cholmod_updown) does not remove any * entries from L. * * workspace: Flag (nrow), Head (nrow+1), * if symmetric: Iwork (2*nrow) * if unsymmetric: Iwork (2*nrow+ncol). * Allocates up to 2 copies of its input matrix A (pattern only). */ #ifndef NCHOLESKY #include "cholmod_internal.h" #include "cholmod_cholesky.h" /* ========================================================================== */ /* === cholmod_resymbol ===================================================== */ /* ========================================================================== */ /* Remove entries from L that are not in the factorization of P*A*P', P*A*A'*P', * or P*F*F'*P' (depending on A->stype and whether fset is NULL or not). * * cholmod_resymbol is the same as cholmod_resymbol_noperm, except that it * first permutes A according to L->Perm. A can be upper/lower/unsymmetric, * in contrast to cholmod_resymbol_noperm (which can be lower or unsym). */ int CHOLMOD(resymbol) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to analyze */ Int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ int pack, /* if TRUE, pack the columns of L */ /* ---- in/out --- */ cholmod_factor *L, /* factorization, entries pruned on output */ /* --------------- */ cholmod_common *Common ) { cholmod_sparse *H, *F, *G ; Int stype, nrow, ncol ; size_t s ; int ok = TRUE ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_NULL (L, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; RETURN_IF_XTYPE_INVALID (L, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; Common->status = CHOLMOD_OK ; if (L->is_super) { /* cannot operate on a supernodal factorization */ ERROR (CHOLMOD_INVALID, "cannot operate on supernodal L") ; return (FALSE) ; } if (L->n != A->nrow) { /* dimensions must agree */ ERROR (CHOLMOD_INVALID, "A and L dimensions do not match") ; return (FALSE) ; } /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ stype = A->stype ; nrow = A->nrow ; ncol = A->ncol ; /* s = 2*nrow + (stype ? 0 : ncol) */ s = CHOLMOD(mult_size_t) (nrow, 2, &ok) ; s = CHOLMOD(add_size_t) (s, (stype ? 0 : ncol), &ok) ; if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (FALSE) ; } CHOLMOD(allocate_work) (nrow, s, 0, Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; } /* ---------------------------------------------------------------------- */ /* permute the input matrix if necessary */ /* ---------------------------------------------------------------------- */ H = NULL ; G = NULL ; if (stype > 0) { if (L->ordering == CHOLMOD_NATURAL) { /* F = triu(A)' */ /* workspace: Iwork (nrow) */ G = CHOLMOD(ptranspose) (A, 0, NULL, NULL, 0, Common) ; } else { /* F = triu(A(p,p))' */ /* workspace: Iwork (2*nrow) */ G = CHOLMOD(ptranspose) (A, 0, L->Perm, NULL, 0, Common) ; } F = G ; } else if (stype < 0) { if (L->ordering == CHOLMOD_NATURAL) { F = A ; } else { /* G = triu(A(p,p))' */ /* workspace: Iwork (2*nrow) */ G = CHOLMOD(ptranspose) (A, 0, L->Perm, NULL, 0, Common) ; /* H = G' */ /* workspace: Iwork (nrow) */ H = CHOLMOD(ptranspose) (G, 0, NULL, NULL, 0, Common) ; F = H ; } } else { if (L->ordering == CHOLMOD_NATURAL) { F = A ; } else { /* G = A(p,f)' */ /* workspace: Iwork (nrow if no fset; MAX (nrow,ncol) if fset)*/ G = CHOLMOD(ptranspose) (A, 0, L->Perm, fset, fsize, Common) ; /* H = G' */ /* workspace: Iwork (ncol) */ H = CHOLMOD(ptranspose) (G, 0, NULL, NULL, 0, Common) ; F = H ; } } /* No need to check for failure here. cholmod_resymbol_noperm will return * FALSE if F is NULL. */ /* ---------------------------------------------------------------------- */ /* resymbol */ /* ---------------------------------------------------------------------- */ ok = CHOLMOD(resymbol_noperm) (F, fset, fsize, pack, L, Common) ; /* ---------------------------------------------------------------------- */ /* free the temporary matrices, if they exist */ /* ---------------------------------------------------------------------- */ CHOLMOD(free_sparse) (&H, Common) ; CHOLMOD(free_sparse) (&G, Common) ; return (ok) ; } /* ========================================================================== */ /* === cholmod_resymbol_noperm ============================================== */ /* ========================================================================== */ /* Redo symbolic LDL' or LL' factorization of I + F*F' or I+A, where F=A(:,f). * * L already exists, but is a superset of the true dynamic pattern (simple * column downdates and row deletions haven't pruned anything). Just redo the * symbolic factorization and drop entries that are no longer there. The * diagonal is not modified. The number of nonzeros in column j of L * (L->nz[j]) can decrease. The column pointers (L->p[j]) remain unchanged if * pack is FALSE or if L is not monotonic. Otherwise, the columns of L are * packed in place. * * For the symmetric case, the columns of the lower triangular part of A * are accessed by column. NOTE that this the transpose of the general case. * * For the unsymmetric case, F=A(:,f) is accessed by column. * * A need not be sorted, and can be packed or unpacked. If L->Perm is not * identity, then A must already be permuted according to the permutation used * to factorize L. The advantage of using this routine is that it does not * need to create permuted copies of A first. * * This routine can be called if L is only partially factored via cholmod_rowfac * since all it does is prune. If an entry is in F*F' or A, but not in L, it * isn't added to L. * * L must be simplicial LDL' or LL'; it cannot be supernodal or symbolic. * * The set f is held in fset and fsize. * fset = NULL means ":" in MATLAB. fset is ignored. * fset != NULL means f = fset [0..fset-1]. * fset != NULL and fsize = 0 means f is the empty set. * There can be no duplicates in fset. * Common->status is set to CHOLMOD_INVALID if fset is invalid. * * workspace: Flag (nrow), Head (nrow+1), * if symmetric: Iwork (2*nrow) * if unsymmetric: Iwork (2*nrow+ncol). * Unlike cholmod_resymbol, this routine does not allocate any temporary * copies of its input matrix. */ int CHOLMOD(resymbol_noperm) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to analyze */ Int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ int pack, /* if TRUE, pack the columns of L */ /* ---- in/out --- */ cholmod_factor *L, /* factorization, entries pruned on output */ /* --------------- */ cholmod_common *Common ) { double *Lx, *Lz ; Int i, j, k, row, parent, p, pend, pdest, ncol, apacked, sorted, nrow, nf, use_fset, mark, jj, stype, xtype ; Int *Ap, *Ai, *Anz, *Li, *Lp, *Lnz, *Flag, *Head, *Link, *Anext, *Iwork ; size_t s ; int ok = TRUE ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_NULL (L, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; RETURN_IF_XTYPE_INVALID (L, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; ncol = A->ncol ; nrow = A->nrow ; stype = A->stype ; ASSERT (IMPLIES (stype != 0, nrow == ncol)) ; if (stype > 0) { /* symmetric, with upper triangular part, not supported */ ERROR (CHOLMOD_INVALID, "symmetric upper not supported ") ; return (FALSE) ; } if (L->is_super) { /* cannot operate on a supernodal or symbolic factorization */ ERROR (CHOLMOD_INVALID, "cannot operate on supernodal L") ; return (FALSE) ; } if (L->n != A->nrow) { /* dimensions must agree */ ERROR (CHOLMOD_INVALID, "A and L dimensions do not match") ; return (FALSE) ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ /* s = 2*nrow + (stype ? 0 : ncol) */ s = CHOLMOD(mult_size_t) (nrow, 2, &ok) ; if (stype != 0) { s = CHOLMOD(add_size_t) (s, ncol, &ok) ; } if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (FALSE) ; } CHOLMOD(allocate_work) (nrow, s, 0, Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; /* out of memory */ } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ Ai = A->i ; Ap = A->p ; Anz = A->nz ; apacked = A->packed ; sorted = A->sorted ; Li = L->i ; Lx = L->x ; Lz = L->z ; Lp = L->p ; Lnz = L->nz ; xtype = L->xtype ; /* If L is monotonic on input, then it can be packed or * unpacked on output, depending on the pack input parameter. */ /* cannot pack a non-monotonic matrix */ if (!(L->is_monotonic)) { pack = FALSE ; } ASSERT (L->nzmax >= (size_t) (Lp [L->n])) ; pdest = 0 ; PRINT1 (("\n\n===================== Resymbol pack %d Apacked %d\n", pack, A->packed)) ; ASSERT (CHOLMOD(dump_sparse) (A, "ReSymbol A:", Common) >= 0) ; DEBUG (CHOLMOD(dump_factor) (L, "ReSymbol initial L (i, x):", Common)) ; /* ---------------------------------------------------------------------- */ /* get workspace */ /* ---------------------------------------------------------------------- */ Flag = Common->Flag ; /* size nrow */ Head = Common->Head ; /* size nrow+1 */ Iwork = Common->Iwork ; Link = Iwork ; /* size nrow (i/i/l) [ */ Lnz = Iwork + nrow ; /* size nrow (i/i/l), if L not packed */ Anext = Iwork + 2*((size_t) nrow) ; /* size ncol (i/i/l), unsym. only */ for (j = 0 ; j < nrow ; j++) { Link [j] = EMPTY ; } /* use Lnz in L itself */ Lnz = L->nz ; ASSERT (Lnz != NULL) ; /* ---------------------------------------------------------------------- */ /* for the unsymmetric case, queue each column of A (:,f) */ /* ---------------------------------------------------------------------- */ /* place each column of the basis set on the link list corresponding to */ /* the smallest row index in that column */ if (stype == 0) { use_fset = (fset != NULL) ; if (use_fset) { nf = fsize ; /* This is the only O(ncol) loop in cholmod_resymbol. * It is required only to check the fset. */ for (j = 0 ; j < ncol ; j++) { Anext [j] = -2 ; } for (jj = 0 ; jj < nf ; jj++) { j = fset [jj] ; if (j < 0 || j > ncol || Anext [j] != -2) { /* out-of-range or duplicate entry in fset */ ERROR (CHOLMOD_INVALID, "fset invalid") ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; return (FALSE) ; } /* flag column j as having been seen */ Anext [j] = EMPTY ; } /* the fset is now valid */ ASSERT (CHOLMOD(dump_perm) (fset, nf, ncol, "fset", Common)) ; } else { nf = ncol ; } for (jj = 0 ; jj < nf ; jj++) { j = (use_fset) ? (fset [jj]) : jj ; /* column j is the fset; find the smallest row (if any) */ p = Ap [j] ; pend = (apacked) ? (Ap [j+1]) : (p + Anz [j]) ; if (pend > p) { k = Ai [p] ; if (!sorted) { for ( ; p < pend ; p++) { k = MIN (k, Ai [p]) ; } } /* place column j on link list k */ ASSERT (k >= 0 && k < nrow) ; Anext [j] = Head [k] ; Head [k] = j ; } } } /* ---------------------------------------------------------------------- */ /* recompute symbolic LDL' factorization */ /* ---------------------------------------------------------------------- */ for (k = 0 ; k < nrow ; k++) { #ifndef NDEBUG PRINT1 (("\n\n================== Initial column k = "ID"\n", k)) ; for (p = Lp [k] ; p < Lp [k] + Lnz [k] ; p++) { PRINT1 ((" row: "ID" value: ", Li [p])) ; PRINT1 (("\n")) ; } PRINT1 (("Recomputing LDL, column k = "ID"\n", k)) ; #endif /* ------------------------------------------------------------------ */ /* compute column k of I+F*F' or I+A */ /* ------------------------------------------------------------------ */ /* flag the diagonal entry */ /* mark = CHOLMOD(clear_flag) (Common) ; */ CHOLMOD_CLEAR_FLAG (Common) ; mark = Common->mark ; Flag [k] = mark ; PRINT1 ((" row: "ID" (diagonal)\n", k)) ; if (stype != 0) { /* merge column k of A into Flag (lower triangular part only) */ p = Ap [k] ; pend = (apacked) ? (Ap [k+1]) : (p + Anz [k]) ; for ( ; p < pend ; p++) { i = Ai [p] ; if (i > k) { Flag [i] = mark ; } } } else { /* for each column j whos first row index is in row k */ for (j = Head [k] ; j != EMPTY ; j = Anext [j]) { /* merge column j of A into Flag */ PRINT1 ((" ---- A column "ID"\n", j)) ; p = Ap [j] ; pend = (apacked) ? (Ap [j+1]) : (p + Anz [j]) ; PRINT1 ((" length "ID" adding\n", pend-p)) ; for ( ; p < pend ; p++) { #ifndef NDEBUG ASSERT (Ai [p] >= k && Ai [p] < nrow) ; if (Flag [Ai [p]] < mark) PRINT1 ((" row "ID"\n", Ai [p])) ; #endif Flag [Ai [p]] = mark ; } } /* clear the kth link list */ Head [k] = EMPTY ; } /* ------------------------------------------------------------------ */ /* compute pruned pattern of kth column of L = union of children */ /* ------------------------------------------------------------------ */ /* for each column j of L whose parent is k */ for (j = Link [k] ; j != EMPTY ; j = Link [j]) { /* merge column j of L into Flag */ PRINT1 ((" ---- L column "ID"\n", k)) ; ASSERT (j < k) ; ASSERT (Lnz [j] > 0) ; p = Lp [j] ; pend = p + Lnz [j] ; ASSERT (Li [p] == j && Li [p+1] == k) ; p++ ; /* skip past the diagonal entry */ for ( ; p < pend ; p++) { /* add to pattern */ ASSERT (Li [p] >= k && Li [p] < nrow) ; Flag [Li [p]] = mark ; } } /* ------------------------------------------------------------------ */ /* prune the kth column of L */ /* ------------------------------------------------------------------ */ PRINT1 (("Final column of L:\n")) ; p = Lp [k] ; pend = p + Lnz [k] ; if (pack) { /* shift column k upwards */ Lp [k] = pdest ; } else { /* leave column k in place, just reduce Lnz [k] */ pdest = p ; } for ( ; p < pend ; p++) { ASSERT (pdest < pend) ; ASSERT (pdest <= p) ; row = Li [p] ; ASSERT (row >= k && row < nrow) ; if (Flag [row] == mark) { /* keep this entry */ Li [pdest] = row ; if (xtype == CHOLMOD_REAL) { Lx [pdest] = Lx [p] ; } else if (xtype == CHOLMOD_COMPLEX) { Lx [2*pdest ] = Lx [2*p ] ; Lx [2*pdest+1] = Lx [2*p+1] ; } else if (xtype == CHOLMOD_ZOMPLEX) { Lx [pdest] = Lx [p] ; Lz [pdest] = Lz [p] ; } pdest++ ; } } /* ------------------------------------------------------------------ */ /* prepare this column for its parent */ /* ------------------------------------------------------------------ */ Lnz [k] = pdest - Lp [k] ; PRINT1 ((" L("ID") length "ID"\n", k, Lnz [k])) ; ASSERT (Lnz [k] > 0) ; /* parent is the first entry in the column after the diagonal */ parent = (Lnz [k] > 1) ? (Li [Lp [k] + 1]) : EMPTY ; PRINT1 (("parent ("ID") = "ID"\n", k, parent)) ; ASSERT ((parent > k && parent < nrow) || (parent == EMPTY)) ; if (parent != EMPTY) { Link [k] = Link [parent] ; Link [parent] = k ; } } /* done using Iwork for Link, Lnz (if needed), and Anext ] */ /* ---------------------------------------------------------------------- */ /* convert L to packed, if requested */ /* ---------------------------------------------------------------------- */ if (pack) { /* finalize Lp */ Lp [nrow] = pdest ; /* Shrink L to be just large enough. It cannot fail. */ /* workspace: none */ ASSERT ((size_t) (Lp [nrow]) <= L->nzmax) ; CHOLMOD(reallocate_factor) (Lp [nrow], L, Common) ; ASSERT (Common->status >= CHOLMOD_OK) ; } /* ---------------------------------------------------------------------- */ /* clear workspace */ /* ---------------------------------------------------------------------- */ /* CHOLMOD(clear_flag) (Common) ; */ CHOLMOD_CLEAR_FLAG (Common) ; DEBUG (CHOLMOD(dump_factor) (L, "ReSymbol final L (i, x):", Common)) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; return (TRUE) ; } #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Cholesky/cholmod_spsolve.c�������������������������������������������������������0000644�0001762�0000144�00000023276�13652535054�020541� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Cholesky/cholmod_spsolve ============================================= */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Cholesky Module. Copyright (C) 2005-2006, Timothy A. Davis * -------------------------------------------------------------------------- */ /* Given an LL' or LDL' factorization of A, solve one of the following systems: * * Ax=b 0: CHOLMOD_A also applies the permutation L->Perm * LDL'x=b 1: CHOLMOD_LDLt does not apply L->Perm * LDx=b 2: CHOLMOD_LD * DL'x=b 3: CHOLMOD_DLt * Lx=b 4: CHOLMOD_L * L'x=b 5: CHOLMOD_Lt * Dx=b 6: CHOLMOD_D * x=Pb 7: CHOLMOD_P apply a permutation (P is L->Perm) * x=P'b 8: CHOLMOD_Pt apply an inverse permutation * * where b and x are sparse. If L and b are real, then x is real. Otherwise, * x is complex or zomplex, depending on the Common->prefer_zomplex parameter. * All xtypes of x and b are supported (real, complex, and zomplex). */ #ifndef NCHOLESKY #include "cholmod_internal.h" #include "cholmod_cholesky.h" /* ========================================================================== */ /* === EXPAND_AS_NEEDED ===================================================== */ /* ========================================================================== */ /* Double the size of the sparse matrix X, if we have run out of space. */ #define EXPAND_AS_NEEDED \ if (xnz >= nzmax) \ { \ nzmax *= 2 ; \ CHOLMOD(reallocate_sparse) (nzmax, X, Common) ; \ if (Common->status < CHOLMOD_OK) \ { \ CHOLMOD(free_sparse) (&X, Common) ; \ CHOLMOD(free_dense) (&X4, Common) ; \ CHOLMOD(free_dense) (&B4, Common) ; \ return (NULL) ; \ } \ Xi = X->i ; \ Xx = X->x ; \ Xz = X->z ; \ } /* ========================================================================== */ /* === cholmod_spolve ======================================================= */ /* ========================================================================== */ cholmod_sparse *CHOLMOD(spsolve) /* returns the sparse solution X */ ( /* ---- input ---- */ int sys, /* system to solve */ cholmod_factor *L, /* factorization to use */ cholmod_sparse *B, /* right-hand-side */ /* --------------- */ cholmod_common *Common ) { double x, z ; cholmod_dense *X4, *B4 ; cholmod_sparse *X ; double *Bx, *Bz, *Xx, *Xz, *B4x, *B4z, *X4x, *X4z ; Int *Bi, *Bp, *Xp, *Xi, *Bnz ; Int n, nrhs, q, p, i, j, jfirst, jlast, packed, block, pend, j_n, xtype ; size_t xnz, nzmax ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (L, NULL) ; RETURN_IF_NULL (B, NULL) ; RETURN_IF_XTYPE_INVALID (L, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, NULL) ; RETURN_IF_XTYPE_INVALID (B, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, NULL) ; if (L->n != B->nrow) { ERROR (CHOLMOD_INVALID, "dimensions of L and B do not match") ; return (NULL) ; } if (B->stype) { ERROR (CHOLMOD_INVALID, "B cannot be stored in symmetric mode") ; return (NULL) ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate workspace B4 and initial result X */ /* ---------------------------------------------------------------------- */ n = L->n ; nrhs = B->ncol ; /* X is real if both L and B are real, complex/zomplex otherwise */ xtype = (L->xtype == CHOLMOD_REAL && B->xtype == CHOLMOD_REAL) ? CHOLMOD_REAL : (Common->prefer_zomplex ? CHOLMOD_ZOMPLEX : CHOLMOD_COMPLEX) ; /* solve up to 4 columns at a time */ block = MIN (nrhs, 4) ; /* initial size of X is at most 4*n */ nzmax = n*block ; X = CHOLMOD(spzeros) (n, nrhs, nzmax, xtype, Common) ; B4 = CHOLMOD(zeros) (n, block, B->xtype, Common) ; if (Common->status < CHOLMOD_OK) { CHOLMOD(free_sparse) (&X, Common) ; CHOLMOD(free_dense) (&B4, Common) ; return (NULL) ; } Bp = B->p ; Bi = B->i ; Bx = B->x ; Bz = B->z ; Bnz = B->nz ; packed = B->packed ; Xp = X->p ; Xi = X->i ; Xx = X->x ; Xz = X->z ; xnz = 0 ; B4x = B4->x ; B4z = B4->z ; /* ---------------------------------------------------------------------- */ /* solve in chunks of 4 columns at a time */ /* ---------------------------------------------------------------------- */ for (jfirst = 0 ; jfirst < nrhs ; jfirst += block) { /* ------------------------------------------------------------------ */ /* adjust the number of columns of B4 */ /* ------------------------------------------------------------------ */ jlast = MIN (nrhs, jfirst + block) ; B4->ncol = jlast - jfirst ; /* ------------------------------------------------------------------ */ /* scatter B(jfirst:jlast-1) into B4 */ /* ------------------------------------------------------------------ */ for (j = jfirst ; j < jlast ; j++) { p = Bp [j] ; pend = (packed) ? (Bp [j+1]) : (p + Bnz [j]) ; j_n = (j-jfirst)*n ; switch (B->xtype) { case CHOLMOD_REAL: for ( ; p < pend ; p++) { B4x [Bi [p] + j_n] = Bx [p] ; } break ; case CHOLMOD_COMPLEX: for ( ; p < pend ; p++) { q = Bi [p] + j_n ; B4x [2*q ] = Bx [2*p ] ; B4x [2*q+1] = Bx [2*p+1] ; } break ; case CHOLMOD_ZOMPLEX: for ( ; p < pend ; p++) { q = Bi [p] + j_n ; B4x [q] = Bx [p] ; B4z [q] = Bz [p] ; } break ; } } /* ------------------------------------------------------------------ */ /* solve the system (X4 = A\B4 or other system) */ /* ------------------------------------------------------------------ */ X4 = CHOLMOD(solve) (sys, L, B4, Common) ; if (Common->status < CHOLMOD_OK) { CHOLMOD(free_sparse) (&X, Common) ; CHOLMOD(free_dense) (&B4, Common) ; CHOLMOD(free_dense) (&X4, Common) ; return (NULL) ; } ASSERT (X4->xtype == xtype) ; X4x = X4->x ; X4z = X4->z ; /* ------------------------------------------------------------------ */ /* append the solution onto X */ /* ------------------------------------------------------------------ */ for (j = jfirst ; j < jlast ; j++) { Xp [j] = xnz ; j_n = (j-jfirst)*n ; if ( xnz + n <= nzmax) { /* ---------------------------------------------------------- */ /* X is guaranteed to be large enough */ /* ---------------------------------------------------------- */ switch (xtype) { case CHOLMOD_REAL: for (i = 0 ; i < n ; i++) { x = X4x [i + j_n] ; if (IS_NONZERO (x)) { Xi [xnz] = i ; Xx [xnz] = x ; xnz++ ; } } break ; case CHOLMOD_COMPLEX: for (i = 0 ; i < n ; i++) { x = X4x [2*(i + j_n) ] ; z = X4x [2*(i + j_n)+1] ; if (IS_NONZERO (x) || IS_NONZERO (z)) { Xi [xnz] = i ; Xx [2*xnz ] = x ; Xx [2*xnz+1] = z ; xnz++ ; } } break ; case CHOLMOD_ZOMPLEX: for (i = 0 ; i < n ; i++) { x = X4x [i + j_n] ; z = X4z [i + j_n] ; if (IS_NONZERO (x) || IS_NONZERO (z)) { Xi [xnz] = i ; Xx [xnz] = x ; Xz [xnz] = z ; xnz++ ; } } break ; } } else { /* ---------------------------------------------------------- */ /* X may need to increase in size */ /* ---------------------------------------------------------- */ switch (xtype) { case CHOLMOD_REAL: for (i = 0 ; i < n ; i++) { x = X4x [i + j_n] ; if (IS_NONZERO (x)) { EXPAND_AS_NEEDED ; Xi [xnz] = i ; Xx [xnz] = x ; xnz++ ; } } break ; case CHOLMOD_COMPLEX: for (i = 0 ; i < n ; i++) { x = X4x [2*(i + j_n) ] ; z = X4x [2*(i + j_n)+1] ; if (IS_NONZERO (x) || IS_NONZERO (z)) { EXPAND_AS_NEEDED ; Xi [xnz] = i ; Xx [2*xnz ] = x ; Xx [2*xnz+1] = z ; xnz++ ; } } break ; case CHOLMOD_ZOMPLEX: for (i = 0 ; i < n ; i++) { x = X4x [i + j_n] ; z = X4z [i + j_n] ; if (IS_NONZERO (x) || IS_NONZERO (z)) { EXPAND_AS_NEEDED ; Xi [xnz] = i ; Xx [xnz] = x ; Xz [xnz] = z ; xnz++ ; } } break ; } } } CHOLMOD(free_dense) (&X4, Common) ; /* ------------------------------------------------------------------ */ /* clear B4 for next iteration */ /* ------------------------------------------------------------------ */ if (jlast < nrhs) { for (j = jfirst ; j < jlast ; j++) { p = Bp [j] ; pend = (packed) ? (Bp [j+1]) : (p + Bnz [j]) ; j_n = (j-jfirst)*n ; switch (B->xtype) { case CHOLMOD_REAL: for ( ; p < pend ; p++) { B4x [Bi [p] + j_n] = 0 ; } break ; case CHOLMOD_COMPLEX: for ( ; p < pend ; p++) { q = Bi [p] + j_n ; B4x [2*q ] = 0 ; B4x [2*q+1] = 0 ; } break ; case CHOLMOD_ZOMPLEX: for ( ; p < pend ; p++) { q = Bi [p] + j_n ; B4x [q] = 0 ; B4z [q] = 0 ; } break ; } } } } Xp [nrhs] = xnz ; /* ---------------------------------------------------------------------- */ /* reduce X in size, free workspace, and return result */ /* ---------------------------------------------------------------------- */ ASSERT (xnz <= X->nzmax) ; CHOLMOD(reallocate_sparse) (xnz, X, Common) ; ASSERT (Common->status == CHOLMOD_OK) ; CHOLMOD(free_dense) (&B4, Common) ; return (X) ; } #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Cholesky/cholmod_postorder.c�����������������������������������������������������0000644�0001762�0000144�00000022403�13652535054�021056� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Cholesky/cholmod_postorder =========================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Cholesky Module. Copyright (C) 2005-2006, Timothy A. Davis * -------------------------------------------------------------------------- */ /* Compute the postorder of a tree. */ #ifndef NCHOLESKY #include "cholmod_internal.h" #include "cholmod_cholesky.h" /* ========================================================================== */ /* === dfs ================================================================== */ /* ========================================================================== */ /* The code below includes both a recursive and non-recursive depth-first-search * of a tree. The recursive code is simpler, but can lead to stack overflow. * It is left here for reference, to understand what the non-recursive code * is computing. To try the recursive version, uncomment the following * #define, or compile the code with -DRECURSIVE. Be aware that stack * overflow may occur. #define RECURSIVE */ #ifdef RECURSIVE /* recursive version: a working code for reference only, not actual use */ static Int dfs /* return the new value of k */ ( Int p, /* start a DFS at node p */ Int k, /* start the node numbering at k */ Int Post [ ], /* Post ordering, modified on output */ Int Head [ ], /* Head [p] = youngest child of p; EMPTY on output */ Int Next [ ], /* Next [j] = sibling of j; unmodified */ Int Pstack [ ] /* unused */ ) { Int j ; /* start a DFS at each child of node p */ for (j = Head [p] ; j != EMPTY ; j = Next [j]) { /* start a DFS at child node j */ k = dfs (j, k, Post, Head, Next, Pstack) ; } Post [k++] = p ; /* order node p as the kth node */ Head [p] = EMPTY ; /* link list p no longer needed */ return (k) ; /* the next node will be numbered k */ } #else /* non-recursive version for actual use */ static Int dfs /* return the new value of k */ ( Int p, /* start the DFS at a root node p */ Int k, /* start the node numbering at k */ Int Post [ ], /* Post ordering, modified on output */ Int Head [ ], /* Head [p] = youngest child of p; EMPTY on output */ Int Next [ ], /* Next [j] = sibling of j; unmodified */ Int Pstack [ ] /* workspace of size n, undefined on input or output */ ) { Int j, phead ; /* put the root node on the stack */ Pstack [0] = p ; phead = 0 ; /* while the stack is not empty, do: */ while (phead >= 0) { /* grab the node p from top of the stack and get its youngest child j */ p = Pstack [phead] ; j = Head [p] ; if (j == EMPTY) { /* all children of p ordered. remove p from stack and order it */ phead-- ; Post [k++] = p ; /* order node p as the kth node */ } else { /* leave p on the stack. Start a DFS at child node j by putting * j on the stack and removing j from the list of children of p. */ Head [p] = Next [j] ; Pstack [++phead] = j ; } } return (k) ; /* the next node will be numbered k */ } #endif /* ========================================================================== */ /* === cholmod_postorder ==================================================== */ /* ========================================================================== */ /* Postorder a tree. The tree is either an elimination tree (the output from * from cholmod_etree) or a component tree (from cholmod_nested_dissection). * * An elimination tree is a complete tree of n nodes with Parent [j] > j or * Parent [j] = EMPTY if j is a root. On output Post [0..n-1] is a complete * permutation vector. * * A component tree is a subset of 0..n-1. Parent [j] = -2 if node j is not * in the component tree. Parent [j] = EMPTY if j is a root of the component * tree, and Parent [j] is in the range 0 to n-1 if j is in the component * tree but not a root. On output, Post [k] is defined only for nodes in * the component tree. Post [k] = j if node j is the kth node in the * postordered component tree, where k is in the range 0 to the number of * components minus 1. * * Node j is ignored and not included in the postorder if Parent [j] < EMPTY. * * As a result, check_parent (Parent, n,...) may fail on input, since * cholmod_check_parent assumes Parent is an elimination tree. Similarly, * cholmod_check_perm (Post, ...) may fail on output, since Post is a partial * permutation if Parent is a component tree. * * An optional node weight can be given. When starting a postorder at node j, * the children of j are ordered in increasing order of their weight. * If no weights are given (Weight is NULL) then children are ordered in * increasing order of their node number. The weight of a node must be in the * range 0 to n-1. Weights outside that range are silently converted to that * range (weights < 0 are treated as zero, and weights >= n are treated as n-1). * * * workspace: Head (n), Iwork (2*n) */ SuiteSparse_long CHOLMOD(postorder) /* return # of nodes postordered */ ( /* ---- input ---- */ Int *Parent, /* size n. Parent [j] = p if p is the parent of j */ size_t n, Int *Weight, /* size n, optional. Weight [j] is weight of node j */ /* ---- output --- */ Int *Post, /* size n. Post [k] = j is kth in postordered tree */ /* --------------- */ cholmod_common *Common ) { Int *Head, *Next, *Pstack, *Iwork ; Int j, p, k, w, nextj ; size_t s ; int ok = TRUE ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (EMPTY) ; RETURN_IF_NULL (Parent, EMPTY) ; RETURN_IF_NULL (Post, EMPTY) ; Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ /* s = 2*n */ s = CHOLMOD(mult_size_t) (n, 2, &ok) ; if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (EMPTY) ; } CHOLMOD(allocate_work) (n, s, 0, Common) ; if (Common->status < CHOLMOD_OK) { return (EMPTY) ; } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ Head = Common->Head ; /* size n+1, initially all EMPTY */ Iwork = Common->Iwork ; Next = Iwork ; /* size n (i/i/l) */ Pstack = Iwork + n ; /* size n (i/i/l) */ /* ---------------------------------------------------------------------- */ /* construct a link list of children for each node */ /* ---------------------------------------------------------------------- */ if (Weight == NULL) { /* in reverse order so children are in ascending order in each list */ for (j = n-1 ; j >= 0 ; j--) { p = Parent [j] ; if (p >= 0 && p < ((Int) n)) { /* add j to the list of children for node p */ Next [j] = Head [p] ; Head [p] = j ; } } /* Head [p] = j if j is the youngest (least-numbered) child of p */ /* Next [j1] = j2 if j2 is the next-oldest sibling of j1 */ } else { /* First, construct a set of link lists according to Weight. * * Whead [w] = j if node j is the first node in bucket w. * Next [j1] = j2 if node j2 follows j1 in a link list. */ Int *Whead = Pstack ; /* use Pstack as workspace for Whead [ */ for (w = 0 ; w < ((Int) n) ; w++) { Whead [w] = EMPTY ; } /* do in forward order, so nodes that ties are ordered by node index */ for (j = 0 ; j < ((Int) n) ; j++) { p = Parent [j] ; if (p >= 0 && p < ((Int) n)) { w = Weight [j] ; w = MAX (0, w) ; w = MIN (w, ((Int) n) - 1) ; /* place node j at the head of link list for weight w */ Next [j] = Whead [w] ; Whead [w] = j ; } } /* traverse weight buckets, placing each node in its parent's list */ for (w = n-1 ; w >= 0 ; w--) { for (j = Whead [w] ; j != EMPTY ; j = nextj) { nextj = Next [j] ; /* put node j in the link list of its parent */ p = Parent [j] ; ASSERT (p >= 0 && p < ((Int) n)) ; Next [j] = Head [p] ; Head [p] = j ; } } /* Whead no longer needed ] */ /* Head [p] = j if j is the lightest child of p */ /* Next [j1] = j2 if j2 is the next-heaviest sibling of j1 */ } /* ---------------------------------------------------------------------- */ /* start a DFS at each root node of the etree */ /* ---------------------------------------------------------------------- */ k = 0 ; for (j = 0 ; j < ((Int) n) ; j++) { if (Parent [j] == EMPTY) { /* j is the root of a tree; start a DFS here */ k = dfs (j, k, Post, Head, Next, Pstack) ; } } /* this would normally be EMPTY already, unless Parent is invalid */ for (j = 0 ; j < ((Int) n) ; j++) { Head [j] = EMPTY ; } PRINT1 (("postordered "ID" nodes\n", k)) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; return (k) ; } #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Cholesky/t_cholmod_lsolve.c������������������������������������������������������0000644�0001762�0000144�00000063345�13652535054�020676� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Cholesky/t_cholmod_lsolve ============================================ */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Cholesky Module. Copyright (C) 2005-2013, Timothy A. Davis * -------------------------------------------------------------------------- */ /* Template routine to solve Lx=b with unit or non-unit diagonal, or * solve LDx=b. * * The numeric xtype of L and Y must match. Y contains b on input and x on * output, stored in row-form. Y is nrow-by-n, where nrow must equal 1 for the * complex or zomplex cases, and nrow <= 4 for the real case. * * This file is not compiled separately. It is included in t_cholmod_solve.c * instead. It contains no user-callable routines. * * workspace: none * * Supports real, complex, and zomplex factors. */ /* undefine all prior definitions */ #undef FORM_NAME #undef LSOLVE /* -------------------------------------------------------------------------- */ /* define the method */ /* -------------------------------------------------------------------------- */ #ifdef LL /* LL': solve Lx=b with non-unit diagonal */ #define FORM_NAME(prefix,rank) prefix ## ll_lsolve_ ## rank #elif defined (LD) /* LDL': solve LDx=b */ #define FORM_NAME(prefix,rank) prefix ## ldl_ldsolve_ ## rank #else /* LDL': solve Lx=b with unit diagonal */ #define FORM_NAME(prefix,rank) prefix ## ldl_lsolve_ ## rank #endif /* LSOLVE(k) defines the name of a routine for an n-by-k right-hand-side. */ #define LSOLVE(prefix,rank) FORM_NAME(prefix,rank) #ifdef REAL /* ========================================================================== */ /* === LSOLVE (1) =========================================================== */ /* ========================================================================== */ /* Solve Lx=b, where b has 1 column */ static void LSOLVE (PREFIX,1) ( cholmod_factor *L, double X [ ] /* n-by-1 in row form */ ) { double *Lx = L->x ; Int *Li = L->i ; Int *Lp = L->p ; Int *Lnz = L->nz ; Int j, n = L->n ; for (j = 0 ; j < n ; ) { /* get the start, end, and length of column j */ Int p = Lp [j] ; Int lnz = Lnz [j] ; Int pend = p + lnz ; /* find a chain of supernodes (up to j, j+1, and j+2) */ if (lnz < 4 || lnz != Lnz [j+1] + 1 || Li [p+1] != j+1) { /* -------------------------------------------------------------- */ /* solve with a single column of L */ /* -------------------------------------------------------------- */ double y = X [j] ; #ifdef LL y /= Lx [p] ; X [j] = y ; #elif defined (LD) X [j] = y / Lx [p] ; #endif for (p++ ; p < pend ; p++) { X [Li [p]] -= Lx [p] * y ; } j++ ; /* advance to next column of L */ } else if (lnz != Lnz [j+2] + 2 || Li [p+2] != j+2) { /* -------------------------------------------------------------- */ /* solve with a supernode of two columns of L */ /* -------------------------------------------------------------- */ double y [2] ; Int q = Lp [j+1] ; #ifdef LL y [0] = X [j] / Lx [p] ; y [1] = (X [j+1] - Lx [p+1] * y [0]) / Lx [q] ; X [j ] = y [0] ; X [j+1] = y [1] ; #elif defined (LD) y [0] = X [j] ; y [1] = X [j+1] - Lx [p+1] * y [0] ; X [j ] = y [0] / Lx [p] ; X [j+1] = y [1] / Lx [q] ; #else y [0] = X [j] ; y [1] = X [j+1] - Lx [p+1] * y [0] ; X [j+1] = y [1] ; #endif for (p += 2, q++ ; p < pend ; p++, q++) { X [Li [p]] -= Lx [p] * y [0] + Lx [q] * y [1] ; } j += 2 ; /* advance to next column of L */ } else { /* -------------------------------------------------------------- */ /* solve with a supernode of three columns of L */ /* -------------------------------------------------------------- */ double y [3] ; Int q = Lp [j+1] ; Int r = Lp [j+2] ; #ifdef LL y [0] = X [j] / Lx [p] ; y [1] = (X [j+1] - Lx [p+1] * y [0]) / Lx [q] ; y [2] = (X [j+2] - Lx [p+2] * y [0] - Lx [q+1] * y [1]) / Lx [r] ; X [j ] = y [0] ; X [j+1] = y [1] ; X [j+2] = y [2] ; #elif defined (LD) y [0] = X [j] ; y [1] = X [j+1] - Lx [p+1] * y [0] ; y [2] = X [j+2] - Lx [p+2] * y [0] - Lx [q+1] * y [1] ; X [j ] = y [0] / Lx [p] ; X [j+1] = y [1] / Lx [q] ; X [j+2] = y [2] / Lx [r] ; #else y [0] = X [j] ; y [1] = X [j+1] - Lx [p+1] * y [0] ; y [2] = X [j+2] - Lx [p+2] * y [0] - Lx [q+1] * y [1] ; X [j+1] = y [1] ; X [j+2] = y [2] ; #endif for (p += 3, q += 2, r++ ; p < pend ; p++, q++, r++) { X [Li [p]] -= Lx [p] * y [0] + Lx [q] * y [1] + Lx [r] * y [2] ; } j += 3 ; /* advance to next column of L */ } } } /* ========================================================================== */ /* === LSOLVE (2) =========================================================== */ /* ========================================================================== */ /* Solve Lx=b, where b has 2 columns */ static void LSOLVE (PREFIX,2) ( cholmod_factor *L, double X [ ][2] /* n-by-2 in row form */ ) { double *Lx = L->x ; Int *Li = L->i ; Int *Lp = L->p ; Int *Lnz = L->nz ; Int j, n = L->n ; for (j = 0 ; j < n ; ) { /* get the start, end, and length of column j */ Int p = Lp [j] ; Int lnz = Lnz [j] ; Int pend = p + lnz ; /* find a chain of supernodes (up to j, j+1, and j+2) */ if (lnz < 4 || lnz != Lnz [j+1] + 1 || Li [p+1] != j+1) { /* -------------------------------------------------------------- */ /* solve with a single column of L */ /* -------------------------------------------------------------- */ double y [2] ; y [0] = X [j][0] ; y [1] = X [j][1] ; #ifdef LL y [0] /= Lx [p] ; y [1] /= Lx [p] ; X [j][0] = y [0] ; X [j][1] = y [1] ; #elif defined (LD) X [j][0] = y [0] / Lx [p] ; X [j][1] = y [1] / Lx [p] ; #endif for (p++ ; p < pend ; p++) { Int i = Li [p] ; X [i][0] -= Lx [p] * y [0] ; X [i][1] -= Lx [p] * y [1] ; } j++ ; /* advance to next column of L */ } else if (lnz != Lnz [j+2] + 2 || Li [p+2] != j+2) { /* -------------------------------------------------------------- */ /* solve with a supernode of two columns of L */ /* -------------------------------------------------------------- */ double y [2][2] ; Int q = Lp [j+1] ; y [0][0] = X [j][0] ; y [0][1] = X [j][1] ; #ifdef LL y [0][0] /= Lx [p] ; y [0][1] /= Lx [p] ; y [1][0] = (X [j+1][0] - Lx [p+1] * y [0][0]) / Lx [q] ; y [1][1] = (X [j+1][1] - Lx [p+1] * y [0][1]) / Lx [q] ; X [j ][0] = y [0][0] ; X [j ][1] = y [0][1] ; X [j+1][0] = y [1][0] ; X [j+1][1] = y [1][1] ; #elif defined (LD) y [1][0] = X [j+1][0] - Lx [p+1] * y [0][0] ; y [1][1] = X [j+1][1] - Lx [p+1] * y [0][1] ; X [j ][0] = y [0][0] / Lx [p] ; X [j ][1] = y [0][1] / Lx [p] ; X [j+1][0] = y [1][0] / Lx [q] ; X [j+1][1] = y [1][1] / Lx [q] ; #else y [1][0] = X [j+1][0] - Lx [p+1] * y [0][0] ; y [1][1] = X [j+1][1] - Lx [p+1] * y [0][1] ; X [j+1][0] = y [1][0] ; X [j+1][1] = y [1][1] ; #endif for (p += 2, q++ ; p < pend ; p++, q++) { Int i = Li [p] ; X [i][0] -= Lx [p] * y [0][0] + Lx [q] * y [1][0] ; X [i][1] -= Lx [p] * y [0][1] + Lx [q] * y [1][1] ; } j += 2 ; /* advance to next column of L */ } else { /* -------------------------------------------------------------- */ /* solve with a supernode of three columns of L */ /* -------------------------------------------------------------- */ double y [3][2] ; Int q = Lp [j+1] ; Int r = Lp [j+2] ; y [0][0] = X [j][0] ; y [0][1] = X [j][1] ; #ifdef LL y [0][0] /= Lx [p] ; y [0][1] /= Lx [p] ; y [1][0] = (X [j+1][0] - Lx[p+1] * y[0][0]) / Lx [q] ; y [1][1] = (X [j+1][1] - Lx[p+1] * y[0][1]) / Lx [q] ; y [2][0] = (X [j+2][0] - Lx[p+2] * y[0][0] - Lx[q+1]*y[1][0])/Lx[r]; y [2][1] = (X [j+2][1] - Lx[p+2] * y[0][1] - Lx[q+1]*y[1][1])/Lx[r]; X [j ][0] = y [0][0] ; X [j ][1] = y [0][1] ; X [j+1][0] = y [1][0] ; X [j+1][1] = y [1][1] ; X [j+2][0] = y [2][0] ; X [j+2][1] = y [2][1] ; #elif defined (LD) y [1][0] = X [j+1][0] - Lx [p+1] * y [0][0] ; y [1][1] = X [j+1][1] - Lx [p+1] * y [0][1] ; y [2][0] = X [j+2][0] - Lx [p+2] * y [0][0] - Lx [q+1] * y [1][0] ; y [2][1] = X [j+2][1] - Lx [p+2] * y [0][1] - Lx [q+1] * y [1][1] ; X [j ][0] = y [0][0] / Lx [p] ; X [j ][1] = y [0][1] / Lx [p] ; X [j+1][0] = y [1][0] / Lx [q] ; X [j+1][1] = y [1][1] / Lx [q] ; X [j+2][0] = y [2][0] / Lx [r] ; X [j+2][1] = y [2][1] / Lx [r] ; #else y [1][0] = X [j+1][0] - Lx [p+1] * y [0][0] ; y [1][1] = X [j+1][1] - Lx [p+1] * y [0][1] ; y [2][0] = X [j+2][0] - Lx [p+2] * y [0][0] - Lx [q+1] * y [1][0] ; y [2][1] = X [j+2][1] - Lx [p+2] * y [0][1] - Lx [q+1] * y [1][1] ; X [j+1][0] = y [1][0] ; X [j+1][1] = y [1][1] ; X [j+2][0] = y [2][0] ; X [j+2][1] = y [2][1] ; #endif for (p += 3, q += 2, r++ ; p < pend ; p++, q++, r++) { Int i = Li [p] ; X[i][0] -= Lx[p] * y[0][0] + Lx[q] * y[1][0] + Lx[r] * y[2][0] ; X[i][1] -= Lx[p] * y[0][1] + Lx[q] * y[1][1] + Lx[r] * y[2][1] ; } j += 3 ; /* advance to next column of L */ } } } /* ========================================================================== */ /* === LSOLVE (3) =========================================================== */ /* ========================================================================== */ /* Solve Lx=b, where b has 3 columns */ static void LSOLVE (PREFIX,3) ( cholmod_factor *L, double X [ ][3] /* n-by-3 in row form */ ) { double *Lx = L->x ; Int *Li = L->i ; Int *Lp = L->p ; Int *Lnz = L->nz ; Int j, n = L->n ; for (j = 0 ; j < n ; ) { /* get the start, end, and length of column j */ Int p = Lp [j] ; Int lnz = Lnz [j] ; Int pend = p + lnz ; /* find a chain of supernodes (up to j, j+1, and j+2) */ if (lnz < 4 || lnz != Lnz [j+1] + 1 || Li [p+1] != j+1) { /* -------------------------------------------------------------- */ /* solve with a single column of L */ /* -------------------------------------------------------------- */ double y [3] ; y [0] = X [j][0] ; y [1] = X [j][1] ; y [2] = X [j][2] ; #ifdef LL y [0] /= Lx [p] ; y [1] /= Lx [p] ; y [2] /= Lx [p] ; X [j][0] = y [0] ; X [j][1] = y [1] ; X [j][2] = y [2] ; #elif defined (LD) X [j][0] = y [0] / Lx [p] ; X [j][1] = y [1] / Lx [p] ; X [j][2] = y [2] / Lx [p] ; #endif for (p++ ; p < pend ; p++) { Int i = Li [p] ; double lx = Lx [p] ; X [i][0] -= lx * y [0] ; X [i][1] -= lx * y [1] ; X [i][2] -= lx * y [2] ; } j++ ; /* advance to next column of L */ } else if (lnz != Lnz [j+2] + 2 || Li [p+2] != j+2) { /* -------------------------------------------------------------- */ /* solve with a supernode of two columns of L */ /* -------------------------------------------------------------- */ double y [2][3] ; Int q = Lp [j+1] ; y [0][0] = X [j][0] ; y [0][1] = X [j][1] ; y [0][2] = X [j][2] ; #ifdef LL y [0][0] /= Lx [p] ; y [0][1] /= Lx [p] ; y [0][2] /= Lx [p] ; y [1][0] = (X [j+1][0] - Lx [p+1] * y [0][0]) / Lx [q] ; y [1][1] = (X [j+1][1] - Lx [p+1] * y [0][1]) / Lx [q] ; y [1][2] = (X [j+1][2] - Lx [p+1] * y [0][2]) / Lx [q] ; X [j ][0] = y [0][0] ; X [j ][1] = y [0][1] ; X [j ][2] = y [0][2] ; X [j+1][0] = y [1][0] ; X [j+1][1] = y [1][1] ; X [j+1][2] = y [1][2] ; #elif defined (LD) y [1][0] = X [j+1][0] - Lx [p+1] * y [0][0] ; y [1][1] = X [j+1][1] - Lx [p+1] * y [0][1] ; y [1][2] = X [j+1][2] - Lx [p+1] * y [0][2] ; X [j ][0] = y [0][0] / Lx [p] ; X [j ][1] = y [0][1] / Lx [p] ; X [j ][2] = y [0][2] / Lx [p] ; X [j+1][0] = y [1][0] / Lx [q] ; X [j+1][1] = y [1][1] / Lx [q] ; X [j+1][2] = y [1][2] / Lx [q] ; #else y [1][0] = X [j+1][0] - Lx [p+1] * y [0][0] ; y [1][1] = X [j+1][1] - Lx [p+1] * y [0][1] ; y [1][2] = X [j+1][2] - Lx [p+1] * y [0][2] ; X [j+1][0] = y [1][0] ; X [j+1][1] = y [1][1] ; X [j+1][2] = y [1][2] ; #endif for (p += 2, q++ ; p < pend ; p++, q++) { Int i = Li [p] ; double lx [2] ; lx [0] = Lx [p] ; lx [1] = Lx [q] ; X [i][0] -= lx [0] * y [0][0] + lx [1] * y [1][0] ; X [i][1] -= lx [0] * y [0][1] + lx [1] * y [1][1] ; X [i][2] -= lx [0] * y [0][2] + lx [1] * y [1][2] ; } j += 2 ; /* advance to next column of L */ } else { /* -------------------------------------------------------------- */ /* solve with a supernode of three columns of L */ /* -------------------------------------------------------------- */ double y [3][3] ; Int q = Lp [j+1] ; Int r = Lp [j+2] ; y [0][0] = X [j][0] ; y [0][1] = X [j][1] ; y [0][2] = X [j][2] ; #ifdef LL y [0][0] /= Lx [p] ; y [0][1] /= Lx [p] ; y [0][2] /= Lx [p] ; y [1][0] = (X [j+1][0] - Lx[p+1] * y[0][0]) / Lx [q] ; y [1][1] = (X [j+1][1] - Lx[p+1] * y[0][1]) / Lx [q] ; y [1][2] = (X [j+1][2] - Lx[p+1] * y[0][2]) / Lx [q] ; y [2][0] = (X [j+2][0] - Lx[p+2] * y[0][0] - Lx[q+1]*y[1][0])/Lx[r]; y [2][1] = (X [j+2][1] - Lx[p+2] * y[0][1] - Lx[q+1]*y[1][1])/Lx[r]; y [2][2] = (X [j+2][2] - Lx[p+2] * y[0][2] - Lx[q+1]*y[1][2])/Lx[r]; X [j ][0] = y [0][0] ; X [j ][1] = y [0][1] ; X [j ][2] = y [0][2] ; X [j+1][0] = y [1][0] ; X [j+1][1] = y [1][1] ; X [j+1][2] = y [1][2] ; X [j+2][0] = y [2][0] ; X [j+2][1] = y [2][1] ; X [j+2][2] = y [2][2] ; #elif defined (LD) y [1][0] = X [j+1][0] - Lx [p+1] * y [0][0] ; y [1][1] = X [j+1][1] - Lx [p+1] * y [0][1] ; y [1][2] = X [j+1][2] - Lx [p+1] * y [0][2] ; y [2][0] = X [j+2][0] - Lx [p+2] * y [0][0] - Lx [q+1] * y [1][0] ; y [2][1] = X [j+2][1] - Lx [p+2] * y [0][1] - Lx [q+1] * y [1][1] ; y [2][2] = X [j+2][2] - Lx [p+2] * y [0][2] - Lx [q+1] * y [1][2] ; X [j ][0] = y [0][0] / Lx [p] ; X [j ][1] = y [0][1] / Lx [p] ; X [j ][2] = y [0][2] / Lx [p] ; X [j+1][0] = y [1][0] / Lx [q] ; X [j+1][1] = y [1][1] / Lx [q] ; X [j+1][2] = y [1][2] / Lx [q] ; X [j+2][0] = y [2][0] / Lx [r] ; X [j+2][1] = y [2][1] / Lx [r] ; X [j+2][2] = y [2][2] / Lx [r] ; #else y [1][0] = X [j+1][0] - Lx [p+1] * y [0][0] ; y [1][1] = X [j+1][1] - Lx [p+1] * y [0][1] ; y [1][2] = X [j+1][2] - Lx [p+1] * y [0][2] ; y [2][0] = X [j+2][0] - Lx [p+2] * y [0][0] - Lx [q+1] * y [1][0] ; y [2][1] = X [j+2][1] - Lx [p+2] * y [0][1] - Lx [q+1] * y [1][1] ; y [2][2] = X [j+2][2] - Lx [p+2] * y [0][2] - Lx [q+1] * y [1][2] ; X [j+1][0] = y [1][0] ; X [j+1][1] = y [1][1] ; X [j+1][2] = y [1][2] ; X [j+2][0] = y [2][0] ; X [j+2][1] = y [2][1] ; X [j+2][2] = y [2][2] ; #endif for (p += 3, q += 2, r++ ; p < pend ; p++, q++, r++) { Int i = Li [p] ; double lx [3] ; lx [0] = Lx [p] ; lx [1] = Lx [q] ; lx [2] = Lx [r] ; X [i][0] -= lx[0] * y[0][0] + lx[1] * y[1][0] + lx[2] * y[2][0]; X [i][1] -= lx[0] * y[0][1] + lx[1] * y[1][1] + lx[2] * y[2][1]; X [i][2] -= lx[0] * y[0][2] + lx[1] * y[1][2] + lx[2] * y[2][2]; } j += 3 ; /* advance to next column of L */ } } } /* ========================================================================== */ /* === LSOLVE (4) =========================================================== */ /* ========================================================================== */ /* Solve Lx=b, where b has 4 columns */ static void LSOLVE (PREFIX,4) ( cholmod_factor *L, double X [ ][4] /* n-by-4 in row form */ ) { double *Lx = L->x ; Int *Li = L->i ; Int *Lp = L->p ; Int *Lnz = L->nz ; Int j, n = L->n ; for (j = 0 ; j < n ; ) { /* get the start, end, and length of column j */ Int p = Lp [j] ; Int lnz = Lnz [j] ; Int pend = p + lnz ; /* find a chain of supernodes (up to j, j+1, and j+2) */ if (lnz < 4 || lnz != Lnz [j+1] + 1 || Li [p+1] != j+1) { /* -------------------------------------------------------------- */ /* solve with a single column of L */ /* -------------------------------------------------------------- */ double y [4] ; y [0] = X [j][0] ; y [1] = X [j][1] ; y [2] = X [j][2] ; y [3] = X [j][3] ; #ifdef LL y [0] /= Lx [p] ; y [1] /= Lx [p] ; y [2] /= Lx [p] ; y [3] /= Lx [p] ; X [j][0] = y [0] ; X [j][1] = y [1] ; X [j][2] = y [2] ; X [j][3] = y [3] ; #elif defined (LD) X [j][0] = y [0] / Lx [p] ; X [j][1] = y [1] / Lx [p] ; X [j][2] = y [2] / Lx [p] ; X [j][3] = y [3] / Lx [p] ; #endif for (p++ ; p < pend ; p++) { Int i = Li [p] ; double lx = Lx [p] ; X [i][0] -= lx * y [0] ; X [i][1] -= lx * y [1] ; X [i][2] -= lx * y [2] ; X [i][3] -= lx * y [3] ; } j++ ; /* advance to next column of L */ } else if (lnz != Lnz [j+2] + 2 || Li [p+2] != j+2) { /* -------------------------------------------------------------- */ /* solve with a supernode of two columns of L */ /* -------------------------------------------------------------- */ double y [2][4] ; Int q = Lp [j+1] ; y [0][0] = X [j][0] ; y [0][1] = X [j][1] ; y [0][2] = X [j][2] ; y [0][3] = X [j][3] ; #ifdef LL y [0][0] /= Lx [p] ; y [0][1] /= Lx [p] ; y [0][2] /= Lx [p] ; y [0][3] /= Lx [p] ; y [1][0] = (X [j+1][0] - Lx [p+1] * y [0][0]) / Lx [q] ; y [1][1] = (X [j+1][1] - Lx [p+1] * y [0][1]) / Lx [q] ; y [1][2] = (X [j+1][2] - Lx [p+1] * y [0][2]) / Lx [q] ; y [1][3] = (X [j+1][3] - Lx [p+1] * y [0][3]) / Lx [q] ; X [j ][0] = y [0][0] ; X [j ][1] = y [0][1] ; X [j ][2] = y [0][2] ; X [j ][3] = y [0][3] ; X [j+1][0] = y [1][0] ; X [j+1][1] = y [1][1] ; X [j+1][2] = y [1][2] ; X [j+1][3] = y [1][3] ; #elif defined (LD) y [1][0] = X [j+1][0] - Lx [p+1] * y [0][0] ; y [1][1] = X [j+1][1] - Lx [p+1] * y [0][1] ; y [1][2] = X [j+1][2] - Lx [p+1] * y [0][2] ; y [1][3] = X [j+1][3] - Lx [p+1] * y [0][3] ; X [j ][0] = y [0][0] / Lx [p] ; X [j ][1] = y [0][1] / Lx [p] ; X [j ][2] = y [0][2] / Lx [p] ; X [j ][3] = y [0][3] / Lx [p] ; X [j+1][0] = y [1][0] / Lx [q] ; X [j+1][1] = y [1][1] / Lx [q] ; X [j+1][2] = y [1][2] / Lx [q] ; X [j+1][3] = y [1][3] / Lx [q] ; #else y [1][0] = X [j+1][0] - Lx [p+1] * y [0][0] ; y [1][1] = X [j+1][1] - Lx [p+1] * y [0][1] ; y [1][2] = X [j+1][2] - Lx [p+1] * y [0][2] ; y [1][3] = X [j+1][3] - Lx [p+1] * y [0][3] ; X [j+1][0] = y [1][0] ; X [j+1][1] = y [1][1] ; X [j+1][2] = y [1][2] ; X [j+1][3] = y [1][3] ; #endif for (p += 2, q++ ; p < pend ; p++, q++) { Int i = Li [p] ; double lx [2] ; lx [0] = Lx [p] ; lx [1] = Lx [q] ; X [i][0] -= lx [0] * y [0][0] + lx [1] * y [1][0] ; X [i][1] -= lx [0] * y [0][1] + lx [1] * y [1][1] ; X [i][2] -= lx [0] * y [0][2] + lx [1] * y [1][2] ; X [i][3] -= lx [0] * y [0][3] + lx [1] * y [1][3] ; } j += 2 ; /* advance to next column of L */ } else { /* -------------------------------------------------------------- */ /* solve with a supernode of three columns of L */ /* -------------------------------------------------------------- */ double y [3][4] ; Int q = Lp [j+1] ; Int r = Lp [j+2] ; y [0][0] = X [j][0] ; y [0][1] = X [j][1] ; y [0][2] = X [j][2] ; y [0][3] = X [j][3] ; #ifdef LL y [0][0] /= Lx [p] ; y [0][1] /= Lx [p] ; y [0][2] /= Lx [p] ; y [0][3] /= Lx [p] ; y [1][0] = (X [j+1][0] - Lx[p+1] * y[0][0]) / Lx [q] ; y [1][1] = (X [j+1][1] - Lx[p+1] * y[0][1]) / Lx [q] ; y [1][2] = (X [j+1][2] - Lx[p+1] * y[0][2]) / Lx [q] ; y [1][3] = (X [j+1][3] - Lx[p+1] * y[0][3]) / Lx [q] ; y [2][0] = (X [j+2][0] - Lx[p+2] * y[0][0] - Lx[q+1]*y[1][0])/Lx[r]; y [2][1] = (X [j+2][1] - Lx[p+2] * y[0][1] - Lx[q+1]*y[1][1])/Lx[r]; y [2][2] = (X [j+2][2] - Lx[p+2] * y[0][2] - Lx[q+1]*y[1][2])/Lx[r]; y [2][3] = (X [j+2][3] - Lx[p+2] * y[0][3] - Lx[q+1]*y[1][3])/Lx[r]; X [j ][0] = y [0][0] ; X [j ][1] = y [0][1] ; X [j ][2] = y [0][2] ; X [j ][3] = y [0][3] ; X [j+1][0] = y [1][0] ; X [j+1][1] = y [1][1] ; X [j+1][2] = y [1][2] ; X [j+1][3] = y [1][3] ; X [j+2][0] = y [2][0] ; X [j+2][1] = y [2][1] ; X [j+2][2] = y [2][2] ; X [j+2][3] = y [2][3] ; #elif defined (LD) y [1][0] = X [j+1][0] - Lx [p+1] * y [0][0] ; y [1][1] = X [j+1][1] - Lx [p+1] * y [0][1] ; y [1][2] = X [j+1][2] - Lx [p+1] * y [0][2] ; y [1][3] = X [j+1][3] - Lx [p+1] * y [0][3] ; y [2][0] = X [j+2][0] - Lx [p+2] * y [0][0] - Lx [q+1] * y [1][0] ; y [2][1] = X [j+2][1] - Lx [p+2] * y [0][1] - Lx [q+1] * y [1][1] ; y [2][2] = X [j+2][2] - Lx [p+2] * y [0][2] - Lx [q+1] * y [1][2] ; y [2][3] = X [j+2][3] - Lx [p+2] * y [0][3] - Lx [q+1] * y [1][3] ; X [j ][0] = y [0][0] / Lx [p] ; X [j ][1] = y [0][1] / Lx [p] ; X [j ][2] = y [0][2] / Lx [p] ; X [j ][3] = y [0][3] / Lx [p] ; X [j+1][0] = y [1][0] / Lx [q] ; X [j+1][1] = y [1][1] / Lx [q] ; X [j+1][2] = y [1][2] / Lx [q] ; X [j+1][3] = y [1][3] / Lx [q] ; X [j+2][0] = y [2][0] / Lx [r] ; X [j+2][1] = y [2][1] / Lx [r] ; X [j+2][2] = y [2][2] / Lx [r] ; X [j+2][3] = y [2][3] / Lx [r] ; #else y [1][0] = X [j+1][0] - Lx [p+1] * y [0][0] ; y [1][1] = X [j+1][1] - Lx [p+1] * y [0][1] ; y [1][2] = X [j+1][2] - Lx [p+1] * y [0][2] ; y [1][3] = X [j+1][3] - Lx [p+1] * y [0][3] ; y [2][0] = X [j+2][0] - Lx [p+2] * y [0][0] - Lx [q+1] * y [1][0] ; y [2][1] = X [j+2][1] - Lx [p+2] * y [0][1] - Lx [q+1] * y [1][1] ; y [2][2] = X [j+2][2] - Lx [p+2] * y [0][2] - Lx [q+1] * y [1][2] ; y [2][3] = X [j+2][3] - Lx [p+2] * y [0][3] - Lx [q+1] * y [1][3] ; X [j+1][0] = y [1][0] ; X [j+1][1] = y [1][1] ; X [j+1][2] = y [1][2] ; X [j+1][3] = y [1][3] ; X [j+2][0] = y [2][0] ; X [j+2][1] = y [2][1] ; X [j+2][2] = y [2][2] ; X [j+2][3] = y [2][3] ; #endif for (p += 3, q += 2, r++ ; p < pend ; p++, q++, r++) { Int i = Li [p] ; double lx [3] ; lx [0] = Lx [p] ; lx [1] = Lx [q] ; lx [2] = Lx [r] ; X [i][0] -= lx[0] * y[0][0] + lx[1] * y[1][0] + lx[2] * y[2][0]; X [i][1] -= lx[0] * y[0][1] + lx[1] * y[1][1] + lx[2] * y[2][1]; X [i][2] -= lx[0] * y[0][2] + lx[1] * y[1][2] + lx[2] * y[2][2]; X [i][3] -= lx[0] * y[0][3] + lx[1] * y[1][3] + lx[2] * y[2][3]; } j += 3 ; /* advance to next column of L */ } } } #endif /* ========================================================================== */ /* === LSOLVE (k) =========================================================== */ /* ========================================================================== */ static void LSOLVE (PREFIX,k) ( cholmod_factor *L, cholmod_dense *Y, /* nr-by-n where nr is 1 to 4 */ Int *Yseti, Int ysetlen ) { double yx [2] ; #ifdef ZOMPLEX double yz [1] ; double *Lz = L->z ; double *Xz = Y->z ; #endif double *Lx = L->x ; double *Xx = Y->x ; Int *Li = L->i ; Int *Lp = L->p ; Int *Lnz = L->nz ; Int n = L->n, jj, jjiters ; ASSERT (L->xtype == Y->xtype) ; /* L and Y must have the same xtype */ ASSERT (L->n == Y->ncol) ; /* dimensions must match */ ASSERT (Y->nrow == Y->d) ; /* leading dimension of Y = # rows of Y */ ASSERT (L->xtype != CHOLMOD_PATTERN) ; /* L is not symbolic */ ASSERT (!(L->is_super)) ; /* L is simplicial LL' or LDL' */ #ifdef REAL if (Yseti == NULL) { /* ------------------------------------------------------------------ */ /* real case, no Yseti, with 1 to 4 RHS's and dynamic supernodes */ /* ------------------------------------------------------------------ */ ASSERT (Y->nrow <= 4) ; switch (Y->nrow) { case 1: LSOLVE (PREFIX,1) (L, Y->x) ; break ; case 2: LSOLVE (PREFIX,2) (L, Y->x) ; break ; case 3: LSOLVE (PREFIX,3) (L, Y->x) ; break ; case 4: LSOLVE (PREFIX,4) (L, Y->x) ; break ; } } else #endif { /* ------------------------------------------------------------------ */ /* solve a complex linear system or solve with Yseti */ /* ------------------------------------------------------------------ */ ASSERT (Y->nrow == 1) ; jjiters = Yseti ? ysetlen : n ; for (jj = 0 ; jj < jjiters ; jj++) { Int j = Yseti ? Yseti [jj] : jj ; /* get the start, end, and length of column j */ Int p = Lp [j] ; Int lnz = Lnz [j] ; Int pend = p + lnz ; /* y = X [j] ; */ ASSIGN (yx,yz,0, Xx,Xz,j) ; #ifdef LL /* y /= Lx [p] ; */ /* X [j] = y ; */ DIV_REAL (yx,yz,0, yx,yz,0, Lx,p) ; ASSIGN (Xx,Xz,j, yx,yz,0) ; #elif defined (LD) /* X [j] = y / Lx [p] ; */ DIV_REAL (Xx,Xz,j, yx,yz,0, Lx,p) ; #endif for (p++ ; p < pend ; p++) { /* X [Li [p]] -= Lx [p] * y ; */ Int i = Li [p] ; MULTSUB (Xx,Xz,i, Lx,Lz,p, yx,yz,0) ; } } } } /* prepare for the next inclusion of this file in cholmod_solve.c */ #undef LL #undef LD �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Cholesky/License.txt�������������������������������������������������������������0000644�0001762�0000144�00000002047�11770402705�017304� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CHOLMOD/Cholesky module, Copyright (C) 2005-2006, Timothy A. Davis CHOLMOD is also available under other licenses; contact authors for details. http://www.suitesparse.com Note that this license is for the CHOLMOD/Cholesky module only. All CHOLMOD modules are licensed separately. -------------------------------------------------------------------------------- This Module is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This Module 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this Module; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Cholesky/cholmod_analyze.c�������������������������������������������������������0000644�0001762�0000144�00000077727�13652535054�020523� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Cholesky/cholmod_analyze ============================================= */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Cholesky Module. Copyright (C) 2005-2013, Timothy A. Davis * -------------------------------------------------------------------------- */ /* Order and analyze a matrix (either simplicial or supernodal), in prepartion * for numerical factorization via cholmod_factorize or via the "expert" * routines cholmod_rowfac and cholmod_super_numeric. * * symmetric case: A or A(p,p) * unsymmetric case: AA', A(p,:)*A(p,:)', A(:,f)*A(:,f)', or A(p,f)*A(p,f)' * * For the symmetric case, only the upper or lower triangular part of A is * accessed (depending on the type of A). LL'=A (or permuted A) is analzed. * For the unsymmetric case (LL'=AA' or permuted A). * * There can be no duplicate entries in p or f. p is of length m if A is * m-by-n. f can be length 0 to n. * * In both cases, the columns of A need not be sorted. A can be in packed * or unpacked form. * * Ordering options include: * * natural: A is not permuted to reduce fill-in * given: a permutation can be provided to this routine (UserPerm) * AMD: approximate minumum degree (AMD for the symmetric case, * COLAMD for the AA' case). * METIS: nested dissection with METIS_NodeND * NESDIS: nested dissection using METIS_ComputeVertexSeparator, * typically followed by a constrained minimum degree * (CAMD for the symmetric case, CCOLAMD for the AA' case). * * Multiple ordering options can be tried (up to 9 of them), and the best one * is selected (the one that gives the smallest number of nonzeros in the * simplicial factor L). If one method fails, cholmod_analyze keeps going, and * picks the best among the methods that succeeded. This routine fails (and * returns NULL) if either initial memory allocation fails, all ordering methods * fail, or the supernodal analysis (if requested) fails. By default, the 9 * methods available are: * * 1) given permutation (skipped if UserPerm is NULL) * 2) AMD (symmetric case) or COLAMD (unsymmetric case) * 3) METIS with default parameters * 4) NESDIS with default parameters (stopping the partitioning when * the graph is of size nd_small = 200 or less, remove nodes with * more than max (16, prune_dense * sqrt (n)) nodes where * prune_dense = 10, and follow partitioning with CCOLAMD, a * constrained minimum degree ordering). * 5) natural * 6) NESDIS, nd_small = 20000, prune_dense = 10 * 7) NESDIS, nd_small = 4, prune_dense = 10, no min degree * 8) NESDIS, nd_small = 200, prune_dense = 0 * 9) COLAMD for A*A' or AMD for A * * By default, the first two are tried, and METIS is tried if AMD reports a high * flop count and fill-in. Let fl denote the flop count for the AMD, ordering, * nnz(L) the # of nonzeros in L, and nnz(tril(A)) (or A*A'). If * fl/nnz(L) >= 500 and nnz(L)/nnz(tril(A)) >= 5, then METIS is attempted. The * best ordering is used (UserPerm if given, AMD, and METIS if attempted). If * you do not have METIS, only the first two will be tried (user permutation, * if provided, and AMD/COLAMD). This default behavior is obtained when * Common->nmethods is zero. In this case, methods 0, 1, and 2 in * Common->method [..] are reset to User-provided, AMD, and METIS (or NESDIS * if Common->default_nesdis is set to the non-default value of TRUE), * respectively. * * You can modify these 9 methods and the number of methods tried by changing * parameters in the Common argument. If you know the best ordering for your * matrix, set Common->nmethods to 1 and set Common->method[0].ordering to the * requested ordering method. Parameters for each method can also be modified * (refer to cholmod.h for details). * * Note that it is possible for METIS to terminate your program if it runs out * of memory. This is not the case for any CHOLMOD or minimum degree ordering * routine (AMD, COLAMD, CAMD, CCOLAMD, or CSYMAMD). Since NESDIS relies on * METIS, it too can terminate your program. * * The factor L is returned as simplicial symbolic (L->is_super FALSE) if * Common->supernodal <= CHOLMOD_SIMPLICIAL (0) or as supernodal symbolic if * Common->supernodal >= CHOLMOD_SUPERNODAL (2). If Common->supernodal is * equal to CHOLMOD_AUTO (1), then L is simplicial if the flop count per * nonzero in L is less than Common->supernodal_switch (default: 40), and * is returned as a supernodal factor otherwise. * * In both cases, L->xtype is CHOLMOD_PATTERN. * A subsequent call to cholmod_factorize will perform a * simplicial or supernodal factorization, depending on the type of L. * * For the simplicial case, L contains the fill-reducing permutation (L->Perm) * and the counts of nonzeros in each column of L (L->ColCount). For the * supernodal case, L also contains the nonzero pattern of each supernode. * * workspace: Flag (nrow), Head (nrow+1) * if symmetric: Iwork (6*nrow) * if unsymmetric: Iwork (6*nrow+ncol). * calls various ordering routines, which typically allocate O(nnz(A)) * temporary workspace ((2 to 3)*nnz(A) * sizeof (Int) is typical, but it * can be much higher if A*A' must be explicitly formed for METIS). Also * allocates up to 2 temporary (permuted/transpose) copies of the nonzero * pattern of A, and up to 3*n*sizeof(Int) additional workspace. * * Supports any xtype (pattern, real, complex, or zomplex) */ #ifndef NCHOLESKY #include "cholmod_internal.h" #include "cholmod_cholesky.h" #ifndef NSUPERNODAL #include "cholmod_supernodal.h" #endif #ifndef NPARTITION #include "cholmod_partition.h" #endif /* ========================================================================== */ /* === cholmod_analyze ====================================================== */ /* ========================================================================== */ /* Orders and analyzes A, AA', PAP', or PAA'P' and returns a symbolic factor * that can later be passed to cholmod_factorize. */ cholmod_factor *CHOLMOD(analyze) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to order and analyze */ /* --------------- */ cholmod_common *Common ) { return (CHOLMOD(analyze_p2) (TRUE, A, NULL, NULL, 0, Common)) ; } /* ========================================================================== */ /* === cholmod_analyze_p ==================================================== */ /* ========================================================================== */ /* Orders and analyzes A, AA', PAP', PAA'P', FF', or PFF'P and returns a * symbolic factor that can later be passed to cholmod_factorize, where * F = A(:,fset) if fset is not NULL and A->stype is zero. * UserPerm is tried if non-NULL. */ cholmod_factor *CHOLMOD(analyze_p) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to order and analyze */ Int *UserPerm, /* user-provided permutation, size A->nrow */ Int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ /* --------------- */ cholmod_common *Common ) { return (CHOLMOD(analyze_p2) (TRUE, A, UserPerm, fset, fsize, Common)) ; } /* ========================================================================== */ /* === permute_matrices ===================================================== */ /* ========================================================================== */ /* Permute and transpose a matrix. Allocates the A1 and A2 matrices, if needed, * or returns them as NULL if not needed. */ static int permute_matrices ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to permute */ Int ordering, /* ordering method used */ Int *Perm, /* fill-reducing permutation */ Int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ Int do_rowcolcounts,/* if TRUE, compute both S and F. If FALSE, only * S is needed for the symmetric case, and only F for * the unsymmetric case */ /* ---- output --- */ cholmod_sparse **A1_handle, /* see comments below for A1, A2, S, F */ cholmod_sparse **A2_handle, cholmod_sparse **S_handle, cholmod_sparse **F_handle, /* --------------- */ cholmod_common *Common ) { cholmod_sparse *A1, *A2, *S, *F ; *A1_handle = NULL ; *A2_handle = NULL ; *S_handle = NULL ; *F_handle = NULL ; A1 = NULL ; A2 = NULL ; if (ordering == CHOLMOD_NATURAL) { /* ------------------------------------------------------------------ */ /* natural ordering of A */ /* ------------------------------------------------------------------ */ if (A->stype < 0) { /* symmetric lower case: A already in lower form, so S=A' */ /* workspace: Iwork (nrow) */ A2 = CHOLMOD(ptranspose) (A, 0, NULL, NULL, 0, Common) ; F = A ; S = A2 ; } else if (A->stype > 0) { /* symmetric upper case: F = pattern of triu (A)', S = A */ /* workspace: Iwork (nrow) */ if (do_rowcolcounts) { /* F not needed for symmetric case if do_rowcolcounts FALSE */ A1 = CHOLMOD(ptranspose) (A, 0, NULL, fset, fsize, Common) ; } F = A1 ; S = A ; } else { /* unsymmetric case: F = pattern of A (:,f)', S = A */ /* workspace: Iwork (nrow if no fset, MAX(nrow,ncol) if fset) */ A1 = CHOLMOD(ptranspose) (A, 0, NULL, fset, fsize, Common) ; F = A1 ; S = A ; } } else { /* ------------------------------------------------------------------ */ /* A is permuted */ /* ------------------------------------------------------------------ */ if (A->stype < 0) { /* symmetric lower case: S = tril (A (p,p))' and F = S' */ /* workspace: Iwork (2*nrow) */ A2 = CHOLMOD(ptranspose) (A, 0, Perm, NULL, 0, Common) ; S = A2 ; /* workspace: Iwork (nrow) */ if (do_rowcolcounts) { /* F not needed for symmetric case if do_rowcolcounts FALSE */ A1 = CHOLMOD(ptranspose) (A2, 0, NULL, NULL, 0, Common) ; } F = A1 ; } else if (A->stype > 0) { /* symmetric upper case: F = triu (A (p,p))' and S = F' */ /* workspace: Iwork (2*nrow) */ A1 = CHOLMOD(ptranspose) (A, 0, Perm, NULL, 0, Common) ; F = A1 ; /* workspace: Iwork (nrow) */ A2 = CHOLMOD(ptranspose) (A1, 0, NULL, NULL, 0, Common) ; S = A2 ; } else { /* unsymmetric case: F = A (p,f)' and S = F' */ /* workspace: Iwork (nrow if no fset, MAX(nrow,ncol) if fset) */ A1 = CHOLMOD(ptranspose) (A, 0, Perm, fset, fsize, Common) ; F = A1 ; if (do_rowcolcounts) { /* S not needed for unsymmetric case if do_rowcolcounts FALSE */ /* workspace: Iwork (nrow) */ A2 = CHOLMOD(ptranspose) (A1, 0, NULL, NULL, 0, Common) ; } S = A2 ; } } /* If any cholmod_*transpose fails, one or more matrices will be NULL */ *A1_handle = A1 ; *A2_handle = A2 ; *S_handle = S ; *F_handle = F ; return (Common->status == CHOLMOD_OK) ; } /* ========================================================================== */ /* === cholmod_analyze_ordering ============================================= */ /* ========================================================================== */ /* Given a matrix A and its fill-reducing permutation, compute the elimination * tree, its (non-weighted) postordering, and the number of nonzeros in each * column of L. Also computes the flop count, the total nonzeros in L, and * the nonzeros in A (Common->fl, Common->lnz, and Common->anz). * * The column counts of L, flop count, and other statistics from * cholmod_rowcolcounts are not computed if ColCount is NULL. * * workspace: Iwork (2*nrow if symmetric, 2*nrow+ncol if unsymmetric), * Flag (nrow), Head (nrow+1) */ int CHOLMOD(analyze_ordering) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to analyze */ int ordering, /* ordering method used */ Int *Perm, /* size n, fill-reducing permutation to analyze */ Int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ /* ---- output --- */ Int *Parent, /* size n, elimination tree */ Int *Post, /* size n, postordering of elimination tree */ Int *ColCount, /* size n, nnz in each column of L */ /* ---- workspace */ Int *First, /* size n workspace for cholmod_postorder */ Int *Level, /* size n workspace for cholmod_postorder */ /* --------------- */ cholmod_common *Common ) { cholmod_sparse *A1, *A2, *S, *F ; Int n, ok, do_rowcolcounts ; /* check inputs */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; n = A->nrow ; do_rowcolcounts = (ColCount != NULL) ; /* permute A according to Perm and fset */ ok = permute_matrices (A, ordering, Perm, fset, fsize, do_rowcolcounts, &A1, &A2, &S, &F, Common) ; /* find etree of S (symmetric upper/lower case) or F (unsym case) */ /* workspace: symmmetric: Iwork (nrow), unsym: Iwork (nrow+ncol) */ ok = ok && CHOLMOD(etree) (A->stype ? S:F, Parent, Common) ; /* postorder the etree (required by cholmod_rowcolcounts) */ /* workspace: Iwork (2*nrow) */ ok = ok && (CHOLMOD(postorder) (Parent, n, NULL, Post, Common) == n) ; /* cholmod_postorder doesn't set Common->status if it returns < n */ Common->status = (!ok && Common->status == CHOLMOD_OK) ? CHOLMOD_INVALID : Common->status ; /* analyze LL'=S or SS' or S(:,f)*S(:,f)' */ /* workspace: * if symmetric: Flag (nrow), Iwork (2*nrow) * if unsymmetric: Flag (nrow), Iwork (2*nrow+ncol), Head (nrow+1) */ if (do_rowcolcounts) { ok = ok && CHOLMOD(rowcolcounts) (A->stype ? F:S, fset, fsize, Parent, Post, NULL, ColCount, First, Level, Common) ; } /* free temporary matrices and return result */ CHOLMOD(free_sparse) (&A1, Common) ; CHOLMOD(free_sparse) (&A2, Common) ; return (ok) ; } /* ========================================================================== */ /* === Free workspace and return L ========================================== */ /* ========================================================================== */ #define FREE_WORKSPACE_AND_RETURN \ { \ Common->no_workspace_reallocate = FALSE ; \ CHOLMOD(free) (n, sizeof (Int), Lparent, Common) ; \ CHOLMOD(free) (n, sizeof (Int), Perm, Common) ; \ CHOLMOD(free) (n, sizeof (Int), ColCount, Common) ; \ if (Common->status < CHOLMOD_OK) \ { \ CHOLMOD(free_factor) (&L, Common) ; \ } \ ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; \ return (L) ; \ } /* ========================================================================== */ /* === cholmod_analyze_p2 =================================================== */ /* ========================================================================== */ /* Ordering and analysis for sparse Cholesky or sparse QR. */ cholmod_factor *CHOLMOD(analyze_p2) ( /* ---- input ---- */ int for_whom, /* FOR_SPQR (0): for SPQR but not GPU-accelerated FOR_CHOLESKY (1): for Cholesky (GPU or not) FOR_SPQRGPU (2): for SPQR with GPU acceleration */ cholmod_sparse *A, /* matrix to order and analyze */ Int *UserPerm, /* user-provided permutation, size A->nrow */ Int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ /* --------------- */ cholmod_common *Common ) { double lnz_best ; Int *First, *Level, *Work4n, *Cmember, *CParent, *ColCount, *Lperm, *Parent, *Post, *Perm, *Lparent, *Lcolcount ; cholmod_factor *L ; Int k, n, ordering, method, nmethods, status, default_strategy, ncol, uncol, skip_analysis, skip_best ; Int amd_backup ; size_t s ; int ok = TRUE ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (A, NULL) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, NULL) ; Common->status = CHOLMOD_OK ; status = CHOLMOD_OK ; Common->selected = EMPTY ; Common->called_nd = FALSE ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ n = A->nrow ; ncol = A->ncol ; uncol = (A->stype == 0) ? (A->ncol) : 0 ; /* ---------------------------------------------------------------------- */ /* set the default strategy */ /* ---------------------------------------------------------------------- */ lnz_best = (double) EMPTY ; skip_best = FALSE ; nmethods = MIN (Common->nmethods, CHOLMOD_MAXMETHODS) ; nmethods = MAX (0, nmethods) ; #ifndef NDEBUG PRINT1 (("cholmod_analyze_p2 :: nmethods "ID"\n", nmethods)) ; for (method = 0 ; method < nmethods ; method++) { PRINT1 ((" "ID": ordering "ID"\n", method, Common->method [method].ordering)) ; } #endif default_strategy = (nmethods == 0) ; if (default_strategy) { /* default strategy: try UserPerm, if given. Try AMD for A, or AMD * to order A*A'. Try METIS for the symmetric case only if AMD reports * a high degree of fill-in and flop count. METIS is not tried if the * Partition Module isn't installed. If Common->default_nesdis is * TRUE, then NESDIS is used as the 3rd ordering instead. */ Common->method [0].ordering = CHOLMOD_GIVEN ;/* skip if UserPerm NULL */ Common->method [1].ordering = CHOLMOD_AMD ; Common->method [2].ordering = (Common->default_nesdis ? CHOLMOD_NESDIS : CHOLMOD_METIS) ; amd_backup = FALSE ; #ifndef NPARTITION nmethods = 3 ; #else nmethods = 2 ; #endif } else { /* If only METIS and NESDIS are selected, or if 2 or more methods are * being tried, then enable AMD backup */ amd_backup = (nmethods > 1) || (nmethods == 1 && (Common->method [0].ordering == CHOLMOD_METIS || Common->method [0].ordering == CHOLMOD_NESDIS)) ; } #ifdef NSUPERNODAL /* CHOLMOD Supernodal module not installed, just do simplicial analysis */ Common->supernodal = CHOLMOD_SIMPLICIAL ; #endif /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ /* Note: enough space needs to be allocated here so that routines called by * cholmod_analyze do not reallocate the space. */ /* s = 6*n + uncol */ s = CHOLMOD(mult_size_t) (n, 6, &ok) ; s = CHOLMOD(add_size_t) (s, uncol, &ok) ; if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (NULL) ; } CHOLMOD(allocate_work) (n, s, 0, Common) ; if (Common->status < CHOLMOD_OK) { return (NULL) ; /* out of memory */ } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; /* ensure that subsequent routines, called by cholmod_analyze, do not * reallocate any workspace. This is set back to FALSE in the * FREE_WORKSPACE_AND_RETURN macro, which is the only way this function * returns to its caller. */ Common->no_workspace_reallocate = TRUE ; /* Use the last 4*n Int's in Iwork for Parent, First, Level, and Post, since * other CHOLMOD routines will use the first 2n+uncol space. The ordering * routines (cholmod_amd, cholmod_colamd, cholmod_ccolamd, cholmod_metis) * are an exception. They can use all 6n + ncol space, since the contents * of Parent, First, Level, and Post are not needed across calls to those * routines. */ Work4n = Common->Iwork ; Work4n += 2*((size_t) n) + uncol ; Parent = Work4n ; First = Work4n + n ; Level = Work4n + 2*((size_t) n) ; Post = Work4n + 3*((size_t) n) ; /* note that this assignment means that cholmod_nested_dissection, * cholmod_ccolamd, and cholmod_camd can use only the first 4n+uncol * space in Common->Iwork */ Cmember = Post ; CParent = Level ; /* ---------------------------------------------------------------------- */ /* allocate more workspace, and an empty simplicial symbolic factor */ /* ---------------------------------------------------------------------- */ L = CHOLMOD(allocate_factor) (n, Common) ; Lparent = CHOLMOD(malloc) (n, sizeof (Int), Common) ; Perm = CHOLMOD(malloc) (n, sizeof (Int), Common) ; ColCount = CHOLMOD(malloc) (n, sizeof (Int), Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ FREE_WORKSPACE_AND_RETURN ; } Lperm = L->Perm ; Lcolcount = L->ColCount ; Common->anz = EMPTY ; /* ---------------------------------------------------------------------- */ /* try all the requested ordering options and backup to AMD if needed */ /* ---------------------------------------------------------------------- */ /* turn off error handling [ */ Common->try_catch = TRUE ; for (method = 0 ; method <= nmethods ; method++) { /* ------------------------------------------------------------------ */ /* determine the method to try */ /* ------------------------------------------------------------------ */ Common->fl = EMPTY ; Common->lnz = EMPTY ; skip_analysis = FALSE ; if (method == nmethods) { /* All methods failed: backup to AMD */ if (Common->selected == EMPTY && amd_backup) { PRINT1 (("All methods requested failed: backup to AMD\n")) ; ordering = CHOLMOD_AMD ; } else { break ; } } else { ordering = Common->method [method].ordering ; } Common->current = method ; PRINT1 (("method "ID": Try method: "ID"\n", method, ordering)) ; /* ------------------------------------------------------------------ */ /* find the fill-reducing permutation */ /* ------------------------------------------------------------------ */ if (ordering == CHOLMOD_NATURAL) { /* -------------------------------------------------------------- */ /* natural ordering */ /* -------------------------------------------------------------- */ for (k = 0 ; k < n ; k++) { Perm [k] = k ; } } else if (ordering == CHOLMOD_GIVEN) { /* -------------------------------------------------------------- */ /* use given ordering of A, if provided */ /* -------------------------------------------------------------- */ if (UserPerm == NULL) { /* this is not an error condition */ PRINT1 (("skip, no user perm given\n")) ; continue ; } for (k = 0 ; k < n ; k++) { /* UserPerm is checked in cholmod_ptranspose */ Perm [k] = UserPerm [k] ; } } else if (ordering == CHOLMOD_AMD) { /* -------------------------------------------------------------- */ /* AMD ordering of A, A*A', or A(:,f)*A(:,f)' */ /* -------------------------------------------------------------- */ amd_backup = FALSE ; /* no need to try AMD twice ... */ CHOLMOD(amd) (A, fset, fsize, Perm, Common) ; skip_analysis = TRUE ; } else if (ordering == CHOLMOD_COLAMD) { /* -------------------------------------------------------------- */ /* AMD for symmetric case, COLAMD for A*A' or A(:,f)*A(:,f)' */ /* -------------------------------------------------------------- */ if (A->stype) { CHOLMOD(amd) (A, fset, fsize, Perm, Common) ; skip_analysis = TRUE ; } else { /* Alternative: CHOLMOD(ccolamd) (A, fset, fsize, NULL, Perm, Common) ; */ /* do not postorder, it is done later, below */ /* workspace: Iwork (4*nrow+uncol), Flag (nrow), Head (nrow+1)*/ CHOLMOD(colamd) (A, fset, fsize, FALSE, Perm, Common) ; } } else if (ordering == CHOLMOD_METIS) { /* -------------------------------------------------------------- */ /* use METIS_NodeND directly (via a CHOLMOD wrapper) */ /* -------------------------------------------------------------- */ #ifndef NPARTITION /* postorder parameter is false, because it will be later, below */ /* workspace: Iwork (4*nrow+uncol), Flag (nrow), Head (nrow+1) */ Common->called_nd = TRUE ; CHOLMOD(metis) (A, fset, fsize, FALSE, Perm, Common) ; #else Common->status = CHOLMOD_NOT_INSTALLED ; #endif } else if (ordering == CHOLMOD_NESDIS) { /* -------------------------------------------------------------- */ /* use CHOLMOD's nested dissection */ /* -------------------------------------------------------------- */ /* this method is based on METIS' node bissection routine * (METIS_ComputeVertexSeparator). In contrast to METIS_NodeND, * it calls CAMD or CCOLAMD on the whole graph, instead of MMD * on just the leaves. */ #ifndef NPARTITION /* workspace: Flag (nrow), Head (nrow+1), Iwork (2*nrow) */ Common->called_nd = TRUE ; CHOLMOD(nested_dissection) (A, fset, fsize, Perm, CParent, Cmember, Common) ; #else Common->status = CHOLMOD_NOT_INSTALLED ; #endif } else { /* -------------------------------------------------------------- */ /* invalid ordering method */ /* -------------------------------------------------------------- */ Common->status = CHOLMOD_INVALID ; PRINT1 (("No such ordering: "ID"\n", ordering)) ; } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; if (Common->status < CHOLMOD_OK) { /* out of memory, or method failed */ status = MIN (status, Common->status) ; Common->status = CHOLMOD_OK ; continue ; } /* ------------------------------------------------------------------ */ /* analyze the ordering */ /* ------------------------------------------------------------------ */ if (!skip_analysis) { if (!CHOLMOD(analyze_ordering) (A, ordering, Perm, fset, fsize, Parent, Post, ColCount, First, Level, Common)) { /* ordering method failed; clear status and try next method */ status = MIN (status, Common->status) ; Common->status = CHOLMOD_OK ; continue ; } } ASSERT (Common->fl >= 0 && Common->lnz >= 0) ; Common->method [method].fl = Common->fl ; Common->method [method].lnz = Common->lnz ; PRINT1 (("lnz %g fl %g\n", Common->lnz, Common->fl)) ; /* ------------------------------------------------------------------ */ /* pick the best method */ /* ------------------------------------------------------------------ */ /* fl.pt. compare, but lnz can never be NaN */ if (Common->selected == EMPTY || Common->lnz < lnz_best) { Common->selected = method ; PRINT1 (("this is best so far, method "ID"\n", method)) ; L->ordering = ordering ; lnz_best = Common->lnz ; for (k = 0 ; k < n ; k++) { Lperm [k] = Perm [k] ; } /* save the results of cholmod_analyze_ordering, if it was called */ skip_best = skip_analysis ; if (!skip_analysis) { /* save the column count; becomes permanent part of L */ for (k = 0 ; k < n ; k++) { Lcolcount [k] = ColCount [k] ; } /* Parent is needed for weighted postordering and for supernodal * analysis. Does not become a permanent part of L */ for (k = 0 ; k < n ; k++) { Lparent [k] = Parent [k] ; } } } /* ------------------------------------------------------------------ */ /* determine if METIS is to be skipped */ /* ------------------------------------------------------------------ */ if (default_strategy && ordering == CHOLMOD_AMD) { if ((Common->fl < 500 * Common->lnz) || (Common->lnz < 5 * Common->anz)) { /* AMD found an ordering with less than 500 flops per nonzero in * L, or one with a fill-in ratio (nnz(L)/nnz(A)) of less than * 5. This is pretty good, and it's unlikely that METIS will do * better (this heuristic is based on tests on all symmetric * positive definite matrices in the UF sparse matrix * collection, and it works well across a wide range of * problems). METIS can take much more time than AMD. */ break ; } } } /* turn error printing back on ] */ Common->try_catch = FALSE ; /* ---------------------------------------------------------------------- */ /* return if no ordering method succeeded */ /* ---------------------------------------------------------------------- */ if (Common->selected == EMPTY) { /* All methods failed. * If two or more methods failed, they may have failed for different * reasons. Both would clear Common->status and skip to the next * method. Common->status needs to be restored here to the worst error * obtained in any of the methods. CHOLMOD_INVALID is worse * than CHOLMOD_OUT_OF_MEMORY, since the former implies something may * be wrong with the user's input. CHOLMOD_OUT_OF_MEMORY is simply an * indication of lack of resources. */ if (status >= CHOLMOD_OK) { /* this can occur if nmethods = 1, ordering = CHOLMOD_GIVEN, but UserPerm is NULL */ status = CHOLMOD_INVALID ; } ERROR (status, "all methods failed") ; FREE_WORKSPACE_AND_RETURN ; } /* ---------------------------------------------------------------------- */ /* do the analysis for AMD, if skipped */ /* ---------------------------------------------------------------------- */ Common->fl = Common->method [Common->selected].fl ; Common->lnz = Common->method [Common->selected].lnz ; ASSERT (Common->lnz >= 0) ; if (skip_best) { if (!CHOLMOD(analyze_ordering) (A, L->ordering, Lperm, fset, fsize, Lparent, Post, Lcolcount, First, Level, Common)) { /* out of memory, or method failed */ FREE_WORKSPACE_AND_RETURN ; } } /* ---------------------------------------------------------------------- */ /* postorder the etree, weighted by the column counts */ /* ---------------------------------------------------------------------- */ if (Common->postorder) { /* combine the fill-reducing ordering with the weighted postorder */ /* workspace: Iwork (2*nrow) */ if (CHOLMOD(postorder) (Lparent, n, Lcolcount, Post, Common) == n) { /* use First and Level as workspace [ */ Int *Wi = First, *InvPost = Level ; Int newchild, oldchild, newparent, oldparent ; for (k = 0 ; k < n ; k++) { Wi [k] = Lperm [Post [k]] ; } for (k = 0 ; k < n ; k++) { Lperm [k] = Wi [k] ; } for (k = 0 ; k < n ; k++) { Wi [k] = Lcolcount [Post [k]] ; } for (k = 0 ; k < n ; k++) { Lcolcount [k] = Wi [k] ; } for (k = 0 ; k < n ; k++) { InvPost [Post [k]] = k ; } /* updated Lparent needed only for supernodal case */ for (newchild = 0 ; newchild < n ; newchild++) { oldchild = Post [newchild] ; oldparent = Lparent [oldchild] ; newparent = (oldparent == EMPTY) ? EMPTY : InvPost [oldparent] ; Wi [newchild] = newparent ; } for (k = 0 ; k < n ; k++) { Lparent [k] = Wi [k] ; } /* done using Iwork as workspace ] */ /* L is now postordered, no longer in natural ordering */ if (L->ordering == CHOLMOD_NATURAL) { L->ordering = CHOLMOD_POSTORDERED ; } } } /* ---------------------------------------------------------------------- */ /* supernodal analysis, if requested or if selected automatically */ /* ---------------------------------------------------------------------- */ #ifndef NSUPERNODAL if (Common->supernodal > CHOLMOD_AUTO || (Common->supernodal == CHOLMOD_AUTO && Common->lnz > 0 && (Common->fl / Common->lnz) >= Common->supernodal_switch)) { cholmod_sparse *S, *F, *A2, *A1 ; permute_matrices (A, L->ordering, Lperm, fset, fsize, TRUE, &A1, &A2, &S, &F, Common) ; /* workspace: Flag (nrow), Head (nrow), Iwork (5*nrow) */ CHOLMOD(super_symbolic2) (for_whom, S, F, Lparent, L, Common) ; PRINT1 (("status %d\n", Common->status)) ; CHOLMOD(free_sparse) (&A1, Common) ; CHOLMOD(free_sparse) (&A2, Common) ; } #endif /* ---------------------------------------------------------------------- */ /* free temporary matrices and workspace, and return result L */ /* ---------------------------------------------------------------------- */ FREE_WORKSPACE_AND_RETURN ; } #endif �����������������������������������������Matrix/src/CHOLMOD/Cholesky/cholmod_amd.c�����������������������������������������������������������0000644�0001762�0000144�00000014651�13652535054�017604� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Cholesky/cholmod_amd ================================================= */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Cholesky Module. Copyright (C) 2005-2006, Timothy A. Davis * -------------------------------------------------------------------------- */ /* CHOLMOD interface to the AMD ordering routine. Orders A if the matrix is * symmetric. On output, Perm [k] = i if row/column i of A is the kth * row/column of P*A*P'. This corresponds to A(p,p) in MATLAB notation. * * If A is unsymmetric, cholmod_amd orders A*A'. On output, Perm [k] = i if * row/column i of A*A' is the kth row/column of P*A*A'*P'. This corresponds to * A(p,:)*A(p,:)' in MATLAB notation. If f is present, A(p,f)*A(p,f)' is * ordered. * * Computes the flop count for a subsequent LL' factorization, the number * of nonzeros in L, and the number of nonzeros in the matrix ordered (A, * A*A' or A(:,f)*A(:,f)'). * * workspace: Iwork (6*nrow). Head (nrow). * * Allocates a temporary copy of A+A' or A*A' (with * both upper and lower triangular parts) as input to AMD. * * Supports any xtype (pattern, real, complex, or zomplex) */ #ifndef NCHOLESKY #include "cholmod_internal.h" #include "amd.h" #include "cholmod_cholesky.h" #if (!defined (AMD_VERSION) || (AMD_VERSION < AMD_VERSION_CODE (2,0))) #error "AMD v2.0 or later is required" #endif /* ========================================================================== */ /* === cholmod_amd ========================================================== */ /* ========================================================================== */ int CHOLMOD(amd) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to order */ Int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ /* ---- output --- */ Int *Perm, /* size A->nrow, output permutation */ /* --------------- */ cholmod_common *Common ) { double Info [AMD_INFO], Control2 [AMD_CONTROL], *Control ; Int *Cp, *Len, *Nv, *Head, *Elen, *Degree, *Wi, *Iwork, *Next ; cholmod_sparse *C ; Int j, n, cnz ; size_t s ; int ok = TRUE ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; n = A->nrow ; RETURN_IF_NULL (Perm, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; Common->status = CHOLMOD_OK ; if (n == 0) { /* nothing to do */ Common->fl = 0 ; Common->lnz = 0 ; Common->anz = 0 ; return (TRUE) ; } /* ---------------------------------------------------------------------- */ /* get workspace */ /* ---------------------------------------------------------------------- */ /* Note: this is less than the space used in cholmod_analyze, so if * cholmod_amd is being called by that routine, no space will be * allocated. */ /* s = MAX (6*n, A->ncol) */ s = CHOLMOD(mult_size_t) (n, 6, &ok) ; if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (FALSE) ; } s = MAX (s, A->ncol) ; CHOLMOD(allocate_work) (n, s, 0, Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; } Iwork = Common->Iwork ; Degree = Iwork ; /* size n */ Wi = Iwork + n ; /* size n */ Len = Iwork + 2*((size_t) n) ; /* size n */ Nv = Iwork + 3*((size_t) n) ; /* size n */ Next = Iwork + 4*((size_t) n) ; /* size n */ Elen = Iwork + 5*((size_t) n) ; /* size n */ Head = Common->Head ; /* size n+1, but only n is used */ /* ---------------------------------------------------------------------- */ /* construct the input matrix for AMD */ /* ---------------------------------------------------------------------- */ if (A->stype == 0) { /* C = A*A' or A(:,f)*A(:,f)', add extra space of nnz(C)/2+n to C */ C = CHOLMOD(aat) (A, fset, fsize, -2, Common) ; } else { /* C = A+A', but use only the upper triangular part of A if A->stype = 1 * and only the lower part of A if A->stype = -1. Add extra space of * nnz(C)/2+n to C. */ C = CHOLMOD(copy) (A, 0, -2, Common) ; } if (Common->status < CHOLMOD_OK) { /* out of memory, fset invalid, or other error */ return (FALSE) ; } Cp = C->p ; for (j = 0 ; j < n ; j++) { Len [j] = Cp [j+1] - Cp [j] ; } /* C does not include the diagonal, and both upper and lower parts. * Common->anz includes the diagonal, and just the lower part of C */ cnz = Cp [n] ; Common->anz = cnz / 2 + n ; /* ---------------------------------------------------------------------- */ /* order C using AMD */ /* ---------------------------------------------------------------------- */ /* get parameters */ if (Common->current < 0 || Common->current >= CHOLMOD_MAXMETHODS) { /* use AMD defaults */ Control = NULL ; } else { Control = Control2 ; Control [AMD_DENSE] = Common->method [Common->current].prune_dense ; Control [AMD_AGGRESSIVE] = Common->method [Common->current].aggressive ; } #ifdef LONG amd_l2 (n, C->p, C->i, Len, C->nzmax, cnz, Nv, Next, Perm, Head, Elen, Degree, Wi, Control, Info) ; #else amd_2 (n, C->p, C->i, Len, C->nzmax, cnz, Nv, Next, Perm, Head, Elen, Degree, Wi, Control, Info) ; #endif /* LL' flop count. Need to subtract n for LL' flop count. Note that this * is a slight upper bound which is often exact (see AMD/Source/amd_2.c for * details). cholmod_analyze computes an exact flop count and fill-in. */ Common->fl = Info [AMD_NDIV] + 2 * Info [AMD_NMULTSUBS_LDL] + n ; /* Info [AMD_LNZ] excludes the diagonal */ Common->lnz = n + Info [AMD_LNZ] ; /* ---------------------------------------------------------------------- */ /* free the AMD workspace and clear the persistent workspace in Common */ /* ---------------------------------------------------------------------- */ ASSERT (IMPLIES (Common->status == CHOLMOD_OK, CHOLMOD(dump_perm) (Perm, n, n, "AMD2 perm", Common))) ; CHOLMOD(free_sparse) (&C, Common) ; for (j = 0 ; j <= n ; j++) { Head [j] = EMPTY ; } return (TRUE) ; } #endif ���������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Cholesky/cholmod_rcond.c���������������������������������������������������������0000644�0001762�0000144�00000011075�13652535054�020145� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Cholesky/cholmod_rcond =============================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Cholesky Module. Copyright (C) 2005-2006, Timothy A. Davis * -------------------------------------------------------------------------- */ /* Return a rough estimate of the reciprocal of the condition number: * the minimum entry on the diagonal of L (or absolute entry of D for an LDL' * factorization) divided by the maximum entry (squared for LL'). L can be * real, complex, or zomplex. Returns -1 on error, 0 if the matrix is singular * or has a zero entry on the diagonal of L, 1 if the matrix is 0-by-0, or * min(diag(L))/max(diag(L)) otherwise. Never returns NaN; if L has a NaN on * the diagonal it returns zero instead. * * For an LL' factorization, (min(diag(L))/max(diag(L)))^2 is returned. * For an LDL' factorization, (min(diag(D))/max(diag(D))) is returned. */ #ifndef NCHOLESKY #include "cholmod_internal.h" #include "cholmod_cholesky.h" /* ========================================================================== */ /* === LMINMAX ============================================================== */ /* ========================================================================== */ /* Update lmin and lmax for one entry L(j,j) */ #define FIRST_LMINMAX(Ljj,lmin,lmax) \ { \ double ljj = Ljj ; \ if (IS_NAN (ljj)) \ { \ return (0) ; \ } \ lmin = ljj ; \ lmax = ljj ; \ } #define LMINMAX(Ljj,lmin,lmax) \ { \ double ljj = Ljj ; \ if (IS_NAN (ljj)) \ { \ return (0) ; \ } \ if (ljj < lmin) \ { \ lmin = ljj ; \ } \ else if (ljj > lmax) \ { \ lmax = ljj ; \ } \ } /* ========================================================================== */ /* === cholmod_rcond ======================================================== */ /* ========================================================================== */ double CHOLMOD(rcond) /* return min(diag(L)) / max(diag(L)) */ ( /* ---- input ---- */ cholmod_factor *L, /* --------------- */ cholmod_common *Common ) { double lmin, lmax, rcond ; double *Lx ; Int *Lpi, *Lpx, *Super, *Lp ; Int n, e, nsuper, s, k1, k2, psi, psend, psx, nsrow, nscol, jj, j ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (EMPTY) ; RETURN_IF_NULL (L, EMPTY) ; RETURN_IF_XTYPE_INVALID (L, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, EMPTY) ; Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ n = L->n ; if (n == 0) { return (1) ; } if (L->minor < L->n) { return (0) ; } e = (L->xtype == CHOLMOD_COMPLEX) ? 2 : 1 ; if (L->is_super) { /* L is supernodal */ nsuper = L->nsuper ; /* number of supernodes in L */ Lpi = L->pi ; /* column pointers for integer pattern */ Lpx = L->px ; /* column pointers for numeric values */ Super = L->super ; /* supernode sizes */ Lx = L->x ; /* numeric values */ FIRST_LMINMAX (Lx [0], lmin, lmax) ; /* first diagonal entry of L */ for (s = 0 ; s < nsuper ; s++) { k1 = Super [s] ; /* first column in supernode s */ k2 = Super [s+1] ; /* last column in supernode is k2-1 */ psi = Lpi [s] ; /* first row index is L->s [psi] */ psend = Lpi [s+1] ; /* last row index is L->s [psend-1] */ psx = Lpx [s] ; /* first numeric entry is Lx [psx] */ nsrow = psend - psi ; /* supernode is nsrow-by-nscol */ nscol = k2 - k1 ; for (jj = 0 ; jj < nscol ; jj++) { LMINMAX (Lx [e * (psx + jj + jj*nsrow)], lmin, lmax) ; } } } else { /* L is simplicial */ Lp = L->p ; Lx = L->x ; if (L->is_ll) { /* LL' factorization */ FIRST_LMINMAX (Lx [Lp [0]], lmin, lmax) ; for (j = 1 ; j < n ; j++) { LMINMAX (Lx [e * Lp [j]], lmin, lmax) ; } } else { /* LDL' factorization, the diagonal might be negative */ FIRST_LMINMAX (fabs (Lx [Lp [0]]), lmin, lmax) ; for (j = 1 ; j < n ; j++) { LMINMAX (fabs (Lx [e * Lp [j]]), lmin, lmax) ; } } } rcond = lmin / lmax ; if (L->is_ll) { rcond = rcond*rcond ; } return (rcond) ; } #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Cholesky/cholmod_factorize.c�����������������������������������������������������0000644�0001762�0000144�00000033734�13652535054�021034� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Cholesky/cholmod_factorize =========================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Cholesky Module. Copyright (C) 2005-2006, Timothy A. Davis * -------------------------------------------------------------------------- */ /* Computes the numerical factorization of a symmetric matrix. The primary * inputs to this routine are a sparse matrix A and the symbolic factor L from * cholmod_analyze or a prior numerical factor L. If A is symmetric, this * routine factorizes A(p,p)+beta*I (beta can be zero), where p is the * fill-reducing permutation (L->Perm). If A is unsymmetric, either * A(p,:)*A(p,:)'+beta*I or A(p,f)*A(p,f)'+beta*I is factorized. The set f and * the nonzero pattern of the matrix A must be the same as the matrix passed to * cholmod_analyze for the supernodal case. For the simplicial case, it can * be different, but it should be the same for best performance. beta is real. * * A simplicial factorization or supernodal factorization is chosen, based on * the type of the factor L. If L->is_super is TRUE, a supernodal LL' * factorization is computed. Otherwise, a simplicial numeric factorization * is computed, either LL' or LDL', depending on Common->final_ll. * * Once the factorization is complete, it can be left as is or optionally * converted into any simplicial numeric type, depending on the * Common->final_* parameters. If converted from a supernodal to simplicial * type, and the Common->final_resymbol parameter is true, then numerically * zero entries in L due to relaxed supernodal amalgamation are removed from * the simplicial factor (they are always left in the supernodal form of L). * Entries that are numerically zero but present in the simplicial symbolic * pattern of L are left in place (that is, the graph of L remains chordal). * This is required for the update/downdate/rowadd/rowdel routines to work * properly. * * workspace: Flag (nrow), Head (nrow+1), * if symmetric: Iwork (2*nrow+2*nsuper) * if unsymmetric: Iwork (2*nrow+MAX(2*nsuper,ncol)) * where nsuper is 0 if simplicial, or the # of relaxed supernodes in * L otherwise (nsuper <= nrow). * if simplicial: W (nrow). * Allocates up to two temporary copies of its input matrix (including * both pattern and numerical values). * * If the matrix is not positive definite the routine returns TRUE, but * sets Common->status to CHOLMOD_NOT_POSDEF and L->minor is set to the * column at which the failure occurred. Columns L->minor to L->n-1 are * set to zero. * * Supports any xtype (pattern, real, complex, or zomplex), except that the * input matrix A cannot be pattern-only. If L is simplicial, its numeric * xtype matches A on output. If L is supernodal, its xtype is real if A is * real, or complex if A is complex or zomplex. */ #ifndef NCHOLESKY #include "cholmod_internal.h" #include "cholmod_cholesky.h" #ifndef NSUPERNODAL #include "cholmod_supernodal.h" #endif /* ========================================================================== */ /* === cholmod_factorize ==================================================== */ /* ========================================================================== */ /* Factorizes PAP' (or PAA'P' if A->stype is 0), using a factor obtained * from cholmod_analyze. The analysis can be re-used simply by calling this * routine a second time with another matrix. A must have the same nonzero * pattern as that passed to cholmod_analyze. */ int CHOLMOD(factorize) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to factorize */ /* ---- in/out --- */ cholmod_factor *L, /* resulting factorization */ /* --------------- */ cholmod_common *Common ) { double zero [2] ; zero [0] = 0 ; zero [1] = 0 ; return (CHOLMOD(factorize_p) (A, zero, NULL, 0, L, Common)) ; } /* ========================================================================== */ /* === cholmod_factorize_p ================================================== */ /* ========================================================================== */ /* Same as cholmod_factorize, but with more options. */ int CHOLMOD(factorize_p) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to factorize */ double beta [2], /* factorize beta*I+A or beta*I+A'*A */ Int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ /* ---- in/out --- */ cholmod_factor *L, /* resulting factorization */ /* --------------- */ cholmod_common *Common ) { cholmod_sparse *S, *F, *A1, *A2 ; Int nrow, ncol, stype, convert, n, nsuper, grow2, status ; size_t s, t, uncol ; int ok = TRUE ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_NULL (L, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; RETURN_IF_XTYPE_INVALID (L, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; nrow = A->nrow ; ncol = A->ncol ; n = L->n ; stype = A->stype ; if (L->n != A->nrow) { ERROR (CHOLMOD_INVALID, "A and L dimensions do not match") ; return (FALSE) ; } if (stype != 0 && nrow != ncol) { ERROR (CHOLMOD_INVALID, "matrix invalid") ; return (FALSE) ; } DEBUG (CHOLMOD(dump_sparse) (A, "A for cholmod_factorize", Common)) ; Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ nsuper = (L->is_super ? L->nsuper : 0) ; uncol = ((stype != 0) ? 0 : ncol) ; /* s = 2*nrow + MAX (uncol, 2*nsuper) */ s = CHOLMOD(mult_size_t) (nsuper, 2, &ok) ; s = MAX (uncol, s) ; t = CHOLMOD(mult_size_t) (nrow, 2, &ok) ; s = CHOLMOD(add_size_t) (s, t, &ok) ; if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (FALSE) ; } CHOLMOD(allocate_work) (nrow, s, 0, Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; } S = NULL ; F = NULL ; A1 = NULL ; A2 = NULL ; /* convert to another form when done, if requested */ convert = !(Common->final_asis) ; /* ---------------------------------------------------------------------- */ /* perform supernodal LL' or simplicial LDL' factorization */ /* ---------------------------------------------------------------------- */ if (L->is_super) { #ifndef NSUPERNODAL /* ------------------------------------------------------------------ */ /* supernodal factorization */ /* ------------------------------------------------------------------ */ if (L->ordering == CHOLMOD_NATURAL) { /* -------------------------------------------------------------- */ /* natural ordering */ /* -------------------------------------------------------------- */ if (stype > 0) { /* S = tril (A'), F not needed */ /* workspace: Iwork (nrow) */ A1 = CHOLMOD(ptranspose) (A, 2, NULL, NULL, 0, Common) ; S = A1 ; } else if (stype < 0) { /* This is the fastest option for the natural ordering */ /* S = A; F not needed */ S = A ; } else { /* F = A(:,f)' */ /* workspace: Iwork (nrow) */ /* workspace: Iwork (nrow if no fset; MAX (nrow,ncol) if fset)*/ A1 = CHOLMOD(ptranspose) (A, 2, NULL, fset, fsize, Common) ; F = A1 ; /* S = A */ S = A ; } } else { /* -------------------------------------------------------------- */ /* permute the input matrix before factorization */ /* -------------------------------------------------------------- */ if (stype > 0) { /* This is the fastest option for factoring a permuted matrix */ /* S = tril (PAP'); F not needed */ /* workspace: Iwork (2*nrow) */ A1 = CHOLMOD(ptranspose) (A, 2, L->Perm, NULL, 0, Common) ; S = A1 ; } else if (stype < 0) { /* A2 = triu (PAP') */ /* workspace: Iwork (2*nrow) */ A2 = CHOLMOD(ptranspose) (A, 2, L->Perm, NULL, 0, Common) ; /* S = tril (A2'); F not needed */ /* workspace: Iwork (nrow) */ A1 = CHOLMOD(ptranspose) (A2, 2, NULL, NULL, 0, Common) ; S = A1 ; CHOLMOD(free_sparse) (&A2, Common) ; ASSERT (A2 == NULL) ; } else { /* F = A(p,f)' */ /* workspace: Iwork (nrow if no fset; MAX (nrow,ncol) if fset)*/ A1 = CHOLMOD(ptranspose) (A, 2, L->Perm, fset, fsize, Common) ; F = A1 ; /* S = F' */ /* workspace: Iwork (nrow) */ A2 = CHOLMOD(ptranspose) (F, 2, NULL, NULL, 0, Common) ; S = A2 ; } } /* ------------------------------------------------------------------ */ /* supernodal factorization */ /* ------------------------------------------------------------------ */ /* workspace: Flag (nrow), Head (nrow+1), Iwork (2*nrow+2*nsuper) */ if (Common->status == CHOLMOD_OK) { CHOLMOD(super_numeric) (S, F, beta, L, Common) ; } status = Common->status ; ASSERT (IMPLIES (status >= CHOLMOD_OK, L->xtype != CHOLMOD_PATTERN)) ; /* ------------------------------------------------------------------ */ /* convert to final form, if requested */ /* ------------------------------------------------------------------ */ if (Common->status >= CHOLMOD_OK && convert) { /* workspace: none */ ok = CHOLMOD(change_factor) (L->xtype, Common->final_ll, Common->final_super, Common->final_pack, Common->final_monotonic, L, Common) ; if (ok && Common->final_resymbol && !(L->is_super)) { /* workspace: Flag (nrow), Head (nrow+1), * if symmetric: Iwork (2*nrow) * if unsymmetric: Iwork (2*nrow+ncol) */ CHOLMOD(resymbol_noperm) (S, fset, fsize, Common->final_pack, L, Common) ; } } #else /* ------------------------------------------------------------------ */ /* CHOLMOD Supernodal module not installed */ /* ------------------------------------------------------------------ */ status = CHOLMOD_NOT_INSTALLED ; ERROR (CHOLMOD_NOT_INSTALLED,"Supernodal module not installed") ; #endif } else { /* ------------------------------------------------------------------ */ /* simplicial LDL' factorization */ /* ------------------------------------------------------------------ */ /* Permute the input matrix A if necessary. cholmod_rowfac requires * triu(A) in column form for the symmetric case, and A in column form * for the unsymmetric case (the matrix S). The unsymmetric case * requires A in row form, or equivalently A' in column form (the * matrix F). */ if (L->ordering == CHOLMOD_NATURAL) { /* -------------------------------------------------------------- */ /* natural ordering */ /* -------------------------------------------------------------- */ if (stype > 0) { /* F is not needed, S = A */ S = A ; } else if (stype < 0) { /* F is not needed, S = A' */ /* workspace: Iwork (nrow) */ A2 = CHOLMOD(ptranspose) (A, 2, NULL, NULL, 0, Common) ; S = A2 ; } else { /* F = A (:,f)' */ /* workspace: Iwork (nrow if no fset; MAX (nrow,ncol) if fset)*/ A1 = CHOLMOD(ptranspose) (A, 2, NULL, fset, fsize, Common) ; F = A1 ; S = A ; } } else { /* -------------------------------------------------------------- */ /* permute the input matrix before factorization */ /* -------------------------------------------------------------- */ if (stype > 0) { /* F = tril (A (p,p)') */ /* workspace: Iwork (2*nrow) */ A1 = CHOLMOD(ptranspose) (A, 2, L->Perm, NULL, 0, Common) ; /* A2 = triu (F') */ /* workspace: Iwork (nrow) */ A2 = CHOLMOD(ptranspose) (A1, 2, NULL, NULL, 0, Common) ; /* the symmetric case does not need F, free it and set to NULL*/ CHOLMOD(free_sparse) (&A1, Common) ; } else if (stype < 0) { /* A2 = triu (A (p,p)'), F not needed. This is the fastest * way to factorize a matrix using the simplicial routine * (cholmod_rowfac). */ /* workspace: Iwork (2*nrow) */ A2 = CHOLMOD(ptranspose) (A, 2, L->Perm, NULL, 0, Common) ; } else { /* F = A (p,f)' */ /* workspace: Iwork (nrow if no fset; MAX (nrow,ncol) if fset)*/ A1 = CHOLMOD(ptranspose) (A, 2, L->Perm, fset, fsize, Common) ; F = A1 ; /* A2 = F' */ /* workspace: Iwork (nrow) */ A2 = CHOLMOD(ptranspose) (F, 2, NULL, NULL, 0, Common) ; } S = A2 ; } /* ------------------------------------------------------------------ */ /* simplicial LDL' or LL' factorization */ /* ------------------------------------------------------------------ */ /* factorize beta*I+S (symmetric) or beta*I+F*F' (unsymmetric) */ /* workspace: Flag (nrow), W (nrow), Iwork (2*nrow) */ if (Common->status == CHOLMOD_OK) { grow2 = Common->grow2 ; L->is_ll = BOOLEAN (Common->final_ll) ; if (L->xtype == CHOLMOD_PATTERN && Common->final_pack) { /* allocate a factor with exactly the space required */ Common->grow2 = 0 ; } CHOLMOD(rowfac) (S, F, beta, 0, nrow, L, Common) ; Common->grow2 = grow2 ; } status = Common->status ; /* ------------------------------------------------------------------ */ /* convert to final form, if requested */ /* ------------------------------------------------------------------ */ if (Common->status >= CHOLMOD_OK && convert) { /* workspace: none */ CHOLMOD(change_factor) (L->xtype, L->is_ll, FALSE, Common->final_pack, Common->final_monotonic, L, Common) ; } } /* ---------------------------------------------------------------------- */ /* free A1 and A2 if they exist */ /* ---------------------------------------------------------------------- */ CHOLMOD(free_sparse) (&A1, Common) ; CHOLMOD(free_sparse) (&A2, Common) ; Common->status = MAX (Common->status, status) ; return (Common->status >= CHOLMOD_OK) ; } #endif ������������������������������������Matrix/src/CHOLMOD/Cholesky/cholmod_rowfac.c��������������������������������������������������������0000644�0001762�0000144�00000060373�13652535054�020326� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Cholesky/cholmod_rowfac ============================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Cholesky Module. Copyright (C) 2005-2013, Timothy A. Davis * -------------------------------------------------------------------------- */ /* Full or incremental numerical LDL' or LL' factorization (simplicial, not * supernodal) cholmod_factorize is the "easy" wrapper for this code, but it * does not provide access to incremental factorization. * * cholmod_rowfac computes the full or incremental LDL' or LL' factorization of * A+beta*I (where A is symmetric) or A*F+beta*I (where A and F are unsymmetric * and only the upper triangular part of A*F+beta*I is used). It computes * L (and D, for LDL') one row at a time. beta is real. * * A is nrow-by-ncol or nrow-by-nrow. In "packed" form it is a conventional * column-oriented sparse matrix. Row indices of column j are in * Ai [Ap [j] ... Ap [j+1]-1] and values in the same locations of Ax. * will be faster if A has sorted columns. In "unpacked" form the column * of A ends at Ap [j] + Anz [j] - 1 instead of Ap [j+1] - 1. * * Row indices in each column of A can be sorted or unsorted, but the routine * routine works fastest if A is sorted, or if only triu(A) is provided * for the symmetric case. * * The unit-diagonal nrow-by-nrow output matrix L is returned in "unpacked" * column form, with row indices of column j in Li [Lp [j] ... * Lp [j] + Lnz [j] - 1] and values in the same location in Lx. The row * indices in each column of L are in sorted order. The unit diagonal of L * is not stored. * * L can be a simplicial symbolic or numeric (L->is_super must be FALSE). * A symbolic factor is converted immediately into a numeric factor containing * the identity matrix. * * For a full factorization, kstart = 0 and kend = nrow. The existing nonzero * entries (numerical values in L->x and L->z for the zomplex case, and indices * in L->i), if any, are overwritten. * * To compute an incremental factorization, select kstart and kend as the range * of rows of L you wish to compute. A correct factorization will be computed * only if all descendants of all nodes k = kstart to kend-1 in the etree have * been factorized by a prior call to this routine, and if rows kstart to kend-1 * have not been factorized. This condition is NOT checked on input. * * --------------- * Symmetric case: * --------------- * * The factorization (in MATLAB notation) is: * * S = beta*I + A * S = triu (S) + triu (S,1)' * L*D*L' = S, or L*L' = S * * A is a conventional sparse matrix in compressed column form. Only the * diagonal and upper triangular part of A is accessed; the lower * triangular part is ignored and assumed to be equal to the upper * triangular part. For an incremental factorization, only columns kstart * to kend-1 of A are accessed. F is not used. * * --------------- * Unsymmetric case: * --------------- * * The factorization (in MATLAB notation) is: * * S = beta*I + A*F * S = triu (S) + triu (S,1)' * L*D*L' = S, or L*L' = S * * The typical case is F=A'. Alternatively, if F=A(:,f)', then this * routine factorizes S = beta*I + A(:,f)*A(:,f)'. * * All of A and F are accessed, but only the upper triangular part of A*F * is used. F must be of size A->ncol by A->nrow. F is used for the * unsymmetric case only. F can be packed or unpacked and it need not be * sorted. * * For a complete factorization of beta*I + A*A', * this routine performs a number of flops exactly equal to: * * sum (for each column j of A) of (Anz (j)^2 + Anz (j)), to form S * + * sum (for each column j of L) of (Lnz (j)^2 + 3*Lnz (j)), to factorize S * * where Anz (j) is the number of nonzeros in column j of A, and Lnz (j) * is the number of nonzero in column j of L below the diagonal. * * * workspace: Flag (nrow), W (nrow if real, 2*nrow if complex/zomplex), * Iwork (nrow) * * Supports any xtype, except a pattern-only input matrix A cannot be * factorized. */ #ifndef NCHOLESKY #include "cholmod_internal.h" #include "cholmod_cholesky.h" /* ========================================================================== */ /* === subtree ============================================================== */ /* ========================================================================== */ /* Compute the nonzero pattern of the sparse triangular solve Lx=b, where L in * this case is L(0:k-1,0:k-1), and b is a column of A. This is done by * traversing the kth row-subtree of the elimination tree of L, starting from * each nonzero entry in b. The pattern is returned postordered, and is valid * for a subsequent numerical triangular solve of Lx=b. The elimination tree * can be provided in a Parent array, or extracted from the pattern of L itself. * * The pattern of x = inv(L)*b is returned in Stack [top...]. * Also scatters b, or a multiple of b, into the work vector W. * * The SCATTER macro is defines how the numerical values of A or A*A' are to be * scattered. * * PARENT(i) is a macro the defines how the etree is accessed. It is either: * #define PARENT(i) Parent [i] * #define PARENT(i) (Lnz [i] > 1) ? (Li [Lp [i] + 1]) : EMPTY */ #define SUBTREE \ for ( ; p < pend ; p++) \ { \ i = Ai [p] ; \ if (i <= k) \ { \ /* scatter the column of A, or A*A' into Wx and Wz */ \ SCATTER ; \ /* start at node i and traverse up the subtree, stop at node k */ \ for (len = 0 ; i < k && i != EMPTY && Flag [i] < mark ; i = parent) \ { \ /* L(k,i) is nonzero, and seen for the first time */ \ Stack [len++] = i ; /* place i on the stack */ \ Flag [i] = mark ; /* mark i as visited */ \ parent = PARENT (i) ; /* traverse up the etree to the parent */ \ } \ /* move the path down to the bottom of the stack */ \ while (len > 0) \ { \ Stack [--top] = Stack [--len] ; \ } \ } \ else if (sorted) \ { \ break ; \ } \ } /* ========================================================================== */ /* === TEMPLATE ============================================================= */ /* ========================================================================== */ #define REAL #include "t_cholmod_rowfac.c" #define COMPLEX #include "t_cholmod_rowfac.c" #define ZOMPLEX #include "t_cholmod_rowfac.c" #define MASK #define REAL #include "t_cholmod_rowfac.c" #define COMPLEX #include "t_cholmod_rowfac.c" #define ZOMPLEX #include "t_cholmod_rowfac.c" #undef MASK /* ========================================================================== */ /* === cholmod_row_subtree ================================================== */ /* ========================================================================== */ /* Compute the nonzero pattern of the solution to the lower triangular system * L(0:k-1,0:k-1) * x = A (0:k-1,k) if A is symmetric, or * L(0:k-1,0:k-1) * x = A (0:k-1,:) * A (:,k)' if A is unsymmetric. * This gives the nonzero pattern of row k of L (excluding the diagonal). * The pattern is returned postordered. * * The symmetric case requires A to be in symmetric-upper form. * * The result is returned in R, a pre-allocated sparse matrix of size nrow-by-1, * with R->nzmax >= nrow. R is assumed to be packed (Rnz [0] is not updated); * the number of entries in R is given by Rp [0]. * * FUTURE WORK: a very minor change to this routine could allow it to compute * the nonzero pattern of x for any system Lx=b. The SUBTREE macro would need * to change, to eliminate its dependence on k. * * workspace: Flag (nrow) */ int CHOLMOD(row_subtree) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to analyze */ cholmod_sparse *F, /* used for A*A' case only. F=A' or A(:,f)' */ size_t krow, /* row k of L */ Int *Parent, /* elimination tree */ /* ---- output --- */ cholmod_sparse *R, /* pattern of L(k,:), 1-by-n with R->nzmax >= n */ /* --------------- */ cholmod_common *Common ) { Int *Rp, *Stack, *Flag, *Ap, *Ai, *Anz, *Fp, *Fi, *Fnz ; Int p, pend, parent, t, stype, nrow, k, pf, pfend, Fpacked, packed, sorted, top, len, i, mark ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_NULL (R, FALSE) ; RETURN_IF_NULL (Parent, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; RETURN_IF_XTYPE_INVALID (R, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; stype = A->stype ; if (stype == 0) { RETURN_IF_NULL (F, FALSE) ; RETURN_IF_XTYPE_INVALID (F, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; } if (krow >= A->nrow) { ERROR (CHOLMOD_INVALID, "subtree: k invalid") ; return (FALSE) ; } if (R->ncol != 1 || A->nrow != R->nrow || A->nrow > R->nzmax) { ERROR (CHOLMOD_INVALID, "subtree: R invalid") ; return (FALSE) ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ nrow = A->nrow ; CHOLMOD(allocate_work) (nrow, 0, 0, Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ if (stype > 0) { /* symmetric upper case: F is not needed. It may be NULL */ Fp = NULL ; Fi = NULL ; Fnz = NULL ; Fpacked = TRUE ; } else if (stype == 0) { /* unsymmetric case: F is required. */ Fp = F->p ; Fi = F->i ; Fnz = F->nz ; Fpacked = F->packed ; } else { /* symmetric lower triangular form not supported */ ERROR (CHOLMOD_INVALID, "symmetric lower not supported") ; return (FALSE) ; } Ap = A->p ; Ai = A->i ; Anz = A->nz ; packed = A->packed ; sorted = A->sorted ; k = krow ; Stack = R->i ; /* ---------------------------------------------------------------------- */ /* get workspace */ /* ---------------------------------------------------------------------- */ Flag = Common->Flag ; /* size nrow, Flag [i] < mark must hold */ /* mark = CHOLMOD(clear_flag) (Common) ; */ CHOLMOD_CLEAR_FLAG (Common) ; mark = Common->mark ; /* ---------------------------------------------------------------------- */ /* compute the pattern of L(k,:) */ /* ---------------------------------------------------------------------- */ top = nrow ; /* Stack is empty */ Flag [k] = mark ; /* do not include diagonal entry in Stack */ #define SCATTER /* do not scatter numerical values */ #define PARENT(i) Parent [i] /* use Parent for etree */ if (stype != 0) { /* scatter kth col of triu (A), get pattern L(k,:) */ p = Ap [k] ; pend = (packed) ? (Ap [k+1]) : (p + Anz [k]) ; SUBTREE ; } else { /* scatter kth col of triu (beta*I+AA'), get pattern L(k,:) */ pf = Fp [k] ; pfend = (Fpacked) ? (Fp [k+1]) : (pf + Fnz [k]) ; for ( ; pf < pfend ; pf++) { /* get nonzero entry F (t,k) */ t = Fi [pf] ; p = Ap [t] ; pend = (packed) ? (Ap [t+1]) : (p + Anz [t]) ; SUBTREE ; } } #undef SCATTER #undef PARENT /* shift the stack upwards, to the first part of R */ len = nrow - top ; for (i = 0 ; i < len ; i++) { Stack [i] = Stack [top + i] ; } Rp = R->p ; Rp [0] = 0 ; Rp [1] = len ; R->sorted = FALSE ; CHOLMOD(clear_flag) (Common) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; return (TRUE) ; } /* ========================================================================== */ /* === cholmod_lsolve_pattern =============================================== */ /* ========================================================================== */ /* Compute the nonzero pattern of Y=L\B. L must be simplicial, and B * must be a single sparse column vector with B->stype = 0. The values of * B are not used; it just specifies a nonzero pattern. The pattern of * Y is not sorted, but is in topological order instead (suitable for a * sparse forward/backsolve). */ int CHOLMOD(lsolve_pattern) ( /* ---- input ---- */ cholmod_sparse *B, /* sparse right-hand-side (a single sparse column) */ cholmod_factor *L, /* the factor L from which parent(i) is derived */ /* ---- output --- */ cholmod_sparse *Yset, /* pattern of Y=L\B, n-by-1 with Y->nzmax >= n */ /* --------------- */ cholmod_common *Common ) { size_t krow ; RETURN_IF_NULL (B, FALSE) ; krow = B->nrow ; return (CHOLMOD(row_lsubtree) (B, NULL, 0, krow, L, Yset, Common)) ; } /* ========================================================================== */ /* === cholmod_row_lsubtree ================================================= */ /* ========================================================================== */ /* Identical to cholmod_row_subtree, except that the elimination tree is * obtained from L itself, as the first off-diagonal entry in each column. * L must be simplicial, not supernodal. * * If krow = A->nrow, then A must be a single sparse column vector, (A->stype * must be zero), and the nonzero pattern of x=L\b is computed, where b=A(:,0) * is the single sparse right-hand-side. The inputs Fi and fnz are ignored. * See CHOLMOD(lsolve_pattern) above for a simpler interface for this case. */ int CHOLMOD(row_lsubtree) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to analyze */ Int *Fi, size_t fnz, /* nonzero pattern of kth row of A', not required * for the symmetric case. Need not be sorted. */ size_t krow, /* row k of L */ cholmod_factor *L, /* the factor L from which parent(i) is derived */ /* ---- output --- */ cholmod_sparse *R, /* pattern of L(k,:), n-by-1 with R->nzmax >= n */ /* --------------- */ cholmod_common *Common ) { Int *Rp, *Stack, *Flag, *Ap, *Ai, *Anz, *Lp, *Li, *Lnz ; Int p, pend, parent, t, stype, nrow, k, pf, packed, sorted, top, len, i, mark, ka ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_NULL (R, FALSE) ; RETURN_IF_NULL (L, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; RETURN_IF_XTYPE_INVALID (R, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; RETURN_IF_XTYPE_INVALID (L, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; nrow = A->nrow ; stype = A->stype ; if (stype < 0) { /* symmetric lower triangular form not supported */ ERROR (CHOLMOD_INVALID, "symmetric lower not supported") ; return (FALSE) ; } if (krow > nrow) { ERROR (CHOLMOD_INVALID, "lsubtree: krow invalid") ; return (FALSE) ; } else if (krow == nrow) { /* find pattern of x=L\b where b=A(:,0) */ k = nrow ; /* compute all of the result; don't stop in SUBTREE */ ka = 0 ; /* use column A(:,0) */ if (stype != 0 || A->ncol != 1) { /* A must be unsymmetric (it's a single sparse column vector) */ ERROR (CHOLMOD_INVALID, "lsubtree: A invalid") ; return (FALSE) ; } } else { /* find pattern of L(k,:) using A(:,k) and Fi if A unsymmetric */ k = krow ; /* which row of L to compute */ ka = k ; /* which column of A to use */ if (stype == 0) { RETURN_IF_NULL (Fi, FALSE) ; } } if (R->ncol != 1 || nrow != R->nrow || nrow > R->nzmax || ((krow == nrow || stype != 0) && ka >= A->ncol)) { ERROR (CHOLMOD_INVALID, "lsubtree: R invalid") ; return (FALSE) ; } if (L->is_super) { ERROR (CHOLMOD_INVALID, "lsubtree: L invalid (cannot be supernodal)") ; return (FALSE) ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ CHOLMOD(allocate_work) (nrow, 0, 0, Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ Ap = A->p ; Ai = A->i ; Anz = A->nz ; packed = A->packed ; sorted = A->sorted ; Stack = R->i ; Lp = L->p ; Li = L->i ; Lnz = L->nz ; /* ---------------------------------------------------------------------- */ /* get workspace */ /* ---------------------------------------------------------------------- */ Flag = Common->Flag ; /* size nrow, Flag [i] < mark must hold */ mark = CHOLMOD(clear_flag) (Common) ; /* ---------------------------------------------------------------------- */ /* compute the pattern of L(k,:) */ /* ---------------------------------------------------------------------- */ top = nrow ; /* Stack is empty */ if (k < nrow) { Flag [k] = mark ; /* do not include diagonal entry in Stack */ } #define SCATTER /* do not scatter numerical values */ #define PARENT(i) (Lnz [i] > 1) ? (Li [Lp [i] + 1]) : EMPTY if (krow == nrow || stype != 0) { /* scatter kth col of triu (A), get pattern L(k,:) */ p = Ap [ka] ; pend = (packed) ? (Ap [ka+1]) : (p + Anz [ka]) ; SUBTREE ; } else { /* scatter kth col of triu (beta*I+AA'), get pattern L(k,:) */ for (pf = 0 ; pf < (Int) fnz ; pf++) { /* get nonzero entry F (t,k) */ t = Fi [pf] ; p = Ap [t] ; pend = (packed) ? (Ap [t+1]) : (p + Anz [t]) ; SUBTREE ; } } #undef SCATTER #undef PARENT /* shift the stack upwards, to the first part of R */ len = nrow - top ; for (i = 0 ; i < len ; i++) { Stack [i] = Stack [top + i] ; } Rp = R->p ; Rp [0] = 0 ; Rp [1] = len ; R->sorted = FALSE ; CHOLMOD(clear_flag) (Common) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; return (TRUE) ; } /* ========================================================================== */ /* === cholmod_rowfac ======================================================= */ /* ========================================================================== */ /* This is the incremental factorization for general purpose usage. */ int CHOLMOD(rowfac) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to factorize */ cholmod_sparse *F, /* used for A*A' case only. F=A' or A(:,f)' */ double beta [2], /* factorize beta*I+A or beta*I+AA' */ size_t kstart, /* first row to factorize */ size_t kend, /* last row to factorize is kend-1 */ /* ---- in/out --- */ cholmod_factor *L, /* --------------- */ cholmod_common *Common ) { return (CHOLMOD(rowfac_mask2) (A, F, beta, kstart, kend, NULL, 0, NULL, L, Common)) ; } /* ========================================================================== */ /* === cholmod_rowfac_mask ================================================== */ /* ========================================================================== */ /* This is meant for use in LPDASA only. */ int CHOLMOD(rowfac_mask) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to factorize */ cholmod_sparse *F, /* used for A*A' case only. F=A' or A(:,f)' */ double beta [2], /* factorize beta*I+A or beta*I+AA' */ size_t kstart, /* first row to factorize */ size_t kend, /* last row to factorize is kend-1 */ Int *mask, /* size A->nrow. if mask[i] >= 0 row i is set to zero */ Int *RLinkUp, /* size A->nrow. link list of rows to compute */ /* ---- in/out --- */ cholmod_factor *L, /* --------------- */ cholmod_common *Common ) { Int maskmark = 0 ; return (CHOLMOD(rowfac_mask2) (A, F, beta, kstart, kend, mask, maskmark, RLinkUp, L, Common)) ; } /* ========================================================================== */ /* === cholmod_rowfac_mask2 ================================================= */ /* ========================================================================== */ /* This is meant for use in LPDASA only. */ int CHOLMOD(rowfac_mask2) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to factorize */ cholmod_sparse *F, /* used for A*A' case only. F=A' or A(:,f)' */ double beta [2], /* factorize beta*I+A or beta*I+AA' */ size_t kstart, /* first row to factorize */ size_t kend, /* last row to factorize is kend-1 */ Int *mask, /* size A->nrow. if mask[i] >= maskmark row i is set to zero */ Int maskmark, /* for mask [i] test */ Int *RLinkUp, /* size A->nrow. link list of rows to compute */ /* ---- in/out --- */ cholmod_factor *L, /* --------------- */ cholmod_common *Common ) { Int n ; size_t s ; int ok = TRUE ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_NULL (L, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; RETURN_IF_XTYPE_INVALID (L, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; if (L->xtype != CHOLMOD_PATTERN && A->xtype != L->xtype) { ERROR (CHOLMOD_INVALID, "xtype of A and L do not match") ; return (FALSE) ; } if (L->is_super) { ERROR (CHOLMOD_INVALID, "can only do simplicial factorization"); return (FALSE) ; } if (A->stype == 0) { RETURN_IF_NULL (F, FALSE) ; if (A->xtype != F->xtype) { ERROR (CHOLMOD_INVALID, "xtype of A and F do not match") ; return (FALSE) ; } } if (A->stype < 0) { /* symmetric lower triangular form not supported */ ERROR (CHOLMOD_INVALID, "symmetric lower not supported") ; return (FALSE) ; } if (kend > L->n) { ERROR (CHOLMOD_INVALID, "kend invalid") ; return (FALSE) ; } if (A->nrow != L->n) { ERROR (CHOLMOD_INVALID, "dimensions of A and L do not match") ; return (FALSE) ; } Common->status = CHOLMOD_OK ; Common->rowfacfl = 0 ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ /* Xwork is of size n for the real case, 2*n for complex/zomplex */ n = L->n ; /* s = ((A->xtype != CHOLMOD_REAL) ? 2:1)*n */ s = CHOLMOD(mult_size_t) (n, ((A->xtype != CHOLMOD_REAL) ? 2:1), &ok) ; if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (FALSE) ; } CHOLMOD(allocate_work) (n, n, s, Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, A->nrow, Common)) ; /* ---------------------------------------------------------------------- */ /* factorize the matrix, using template routine */ /* ---------------------------------------------------------------------- */ if (RLinkUp == NULL) { switch (A->xtype) { case CHOLMOD_REAL: ok = r_cholmod_rowfac (A, F, beta, kstart, kend, L, Common) ; break ; case CHOLMOD_COMPLEX: ok = c_cholmod_rowfac (A, F, beta, kstart, kend, L, Common) ; break ; case CHOLMOD_ZOMPLEX: ok = z_cholmod_rowfac (A, F, beta, kstart, kend, L, Common) ; break ; } } else { switch (A->xtype) { case CHOLMOD_REAL: ok = r_cholmod_rowfac_mask (A, F, beta, kstart, kend, mask, maskmark, RLinkUp, L, Common) ; break ; case CHOLMOD_COMPLEX: ok = c_cholmod_rowfac_mask (A, F, beta, kstart, kend, mask, maskmark, RLinkUp, L, Common) ; break ; case CHOLMOD_ZOMPLEX: ok = z_cholmod_rowfac_mask (A, F, beta, kstart, kend, mask, maskmark, RLinkUp, L, Common) ; break ; } } return (ok) ; } #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Cholesky/cholmod_colamd.c��������������������������������������������������������0000644�0001762�0000144�00000015062�13652535054�020277� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Cholesky/cholmod_colamd ============================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Cholesky Module. Copyright (C) 2005-2006, Timothy A. Davis * -------------------------------------------------------------------------- */ /* CHOLMOD interface to the COLAMD ordering routine (version 2.4 or later). * Finds a permutation p such that the Cholesky factorization of PAA'P' is * sparser than AA' using colamd. If the postorder input parameter is TRUE, * the column etree is found and postordered, and the colamd ordering is then * combined with its postordering. A must be unsymmetric. * * There can be no duplicate entries in f. * f can be length 0 to n if A is m-by-n. * * workspace: Iwork (4*nrow+ncol), Head (nrow+1), Flag (nrow) * Allocates a copy of its input matrix, which * is then used as CCOLAMD's workspace. * * Supports any xtype (pattern, real, complex, or zomplex) */ #ifndef NCHOLESKY #include "cholmod_internal.h" #include "colamd.h" #include "cholmod_cholesky.h" #if (!defined (COLAMD_VERSION) || (COLAMD_VERSION < COLAMD_VERSION_CODE (2,5))) #error "COLAMD v2.5 or later is required" #endif /* ========================================================================== */ /* === cholmod_colamd ======================================================= */ /* ========================================================================== */ int CHOLMOD(colamd) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to order */ Int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ int postorder, /* if TRUE, follow with a coletree postorder */ /* ---- output --- */ Int *Perm, /* size A->nrow, output permutation */ /* --------------- */ cholmod_common *Common ) { double knobs [COLAMD_KNOBS] ; cholmod_sparse *C ; Int *NewPerm, *Parent, *Post, *Work2n ; Int k, nrow, ncol ; size_t s, alen ; int ok = TRUE ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_NULL (Perm, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; if (A->stype != 0) { ERROR (CHOLMOD_INVALID, "matrix must be unsymmetric") ; return (FALSE) ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ nrow = A->nrow ; ncol = A->ncol ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ /* Note: this is less than the space used in cholmod_analyze, so if * cholmod_colamd is being called by that routine, no space will be * allocated. */ /* s = 4*nrow + ncol */ s = CHOLMOD(mult_size_t) (nrow, 4, &ok) ; s = CHOLMOD(add_size_t) (s, ncol, &ok) ; #ifdef LONG alen = colamd_l_recommended (A->nzmax, ncol, nrow) ; colamd_l_set_defaults (knobs) ; #else alen = colamd_recommended (A->nzmax, ncol, nrow) ; colamd_set_defaults (knobs) ; #endif if (!ok || alen == 0) { ERROR (CHOLMOD_TOO_LARGE, "matrix invalid or too large") ; return (FALSE) ; } CHOLMOD(allocate_work) (0, s, 0, Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; } /* ---------------------------------------------------------------------- */ /* allocate COLAMD workspace */ /* ---------------------------------------------------------------------- */ C = CHOLMOD(allocate_sparse) (ncol, nrow, alen, TRUE, TRUE, 0, CHOLMOD_PATTERN, Common) ; /* ---------------------------------------------------------------------- */ /* copy (and transpose) the input matrix A into the colamd workspace */ /* ---------------------------------------------------------------------- */ /* C = A (:,f)', which also packs A if needed. */ /* workspace: Iwork (nrow if no fset; MAX (nrow,ncol) if fset) */ ok = CHOLMOD(transpose_unsym) (A, 0, NULL, fset, fsize, C, Common) ; /* ---------------------------------------------------------------------- */ /* order the matrix (destroys the contents of C->i and C->p) */ /* ---------------------------------------------------------------------- */ /* get parameters */ if (Common->current < 0 || Common->current >= CHOLMOD_MAXMETHODS) { /* this is the CHOLMOD default, not the COLAMD default */ knobs [COLAMD_DENSE_ROW] = -1 ; } else { /* get the knobs from the Common parameters */ knobs [COLAMD_DENSE_COL] = Common->method[Common->current].prune_dense ; knobs [COLAMD_DENSE_ROW] = Common->method[Common->current].prune_dense2; knobs [COLAMD_AGGRESSIVE] = Common->method[Common->current].aggressive ; } if (ok) { Int *Cp ; Int stats [COLAMD_STATS] ; Cp = C->p ; #ifdef LONG colamd_l (ncol, nrow, alen, C->i, Cp, knobs, stats) ; #else colamd (ncol, nrow, alen, C->i, Cp, knobs, stats) ; #endif ok = stats [COLAMD_STATUS] ; ok = (ok == COLAMD_OK || ok == COLAMD_OK_BUT_JUMBLED) ; /* permutation returned in C->p, if the ordering succeeded */ for (k = 0 ; k < nrow ; k++) { Perm [k] = Cp [k] ; } } CHOLMOD(free_sparse) (&C, Common) ; /* ---------------------------------------------------------------------- */ /* column etree postordering */ /* ---------------------------------------------------------------------- */ if (postorder) { /* use the last 2*n space in Iwork for Parent and Post */ Work2n = Common->Iwork ; Work2n += 2*((size_t) nrow) + ncol ; Parent = Work2n ; /* size nrow (i/i/l) */ Post = Work2n + nrow ; /* size nrow (i/i/l) */ /* workspace: Iwork (2*nrow+ncol), Flag (nrow), Head (nrow+1) */ ok = ok && CHOLMOD(analyze_ordering) (A, CHOLMOD_COLAMD, Perm, fset, fsize, Parent, Post, NULL, NULL, NULL, Common) ; /* combine the colamd permutation with its postordering */ if (ok) { NewPerm = Common->Iwork ; /* size nrow (i/i/l) */ for (k = 0 ; k < nrow ; k++) { NewPerm [k] = Perm [Post [k]] ; } for (k = 0 ; k < nrow ; k++) { Perm [k] = NewPerm [k] ; } } } return (ok) ; } #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Lib/�����������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14547724215�014113� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Lib/Makefile���������������������������������������������������������������������0000644�0001762�0000144�00000044100�14547724215�015552� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#=============================================================================== # CHOLOMD/Lib/Makefile: for compiling the CHOLMOD library #=============================================================================== default: lib PKG_CPPFLAGS = -I../../AMD/Include -I../../AMD/Source \ -I../../COLAMD/Include \ -I../Include -I../../SuiteSparse_config -DNPARTITION -DNPRINT # -I../../CCOLAMD \ # -I../../CAMD/Include -I../../CAMD/Source \ # -I../../Metis \ #------------------------------------------------------------------------------- # ../Include/ directory contains all include files: #------------------------------------------------------------------------------- INC = ../Include/cholmod.h \ ../Include/cholmod_blas.h \ ../Include/cholmod_check.h \ ../Include/cholmod_cholesky.h \ ../Include/cholmod_complexity.h \ ../Include/cholmod_config.h \ ../Include/cholmod_core.h \ ../Include/cholmod_internal.h \ ../Include/cholmod_matrixops.h \ ../Include/cholmod_modify.h \ ../Include/cholmod_partition.h \ ../Include/cholmod_supernodal.h \ ../Include/cholmod_template.h #------------------------------------------------------------------------------- # The 7 CHOLMOD library modules (int, double) #------------------------------------------------------------------------------- CORE = cholmod_aat.o cholmod_add.o cholmod_band.o \ cholmod_change_factor.o cholmod_common.o cholmod_complex.o \ cholmod_copy.o cholmod_dense.o cholmod_error.o cholmod_factor.o \ cholmod_memory.o cholmod_sparse.o \ cholmod_transpose.o cholmod_triplet.o \ cholmod_version.o CHECK = cholmod_check.o cholmod_read.o cholmod_write.o CHOLESKY = cholmod_amd.o cholmod_analyze.o cholmod_colamd.o \ cholmod_etree.o cholmod_factorize.o cholmod_postorder.o \ cholmod_rcond.o cholmod_resymbol.o cholmod_rowcolcounts.o \ cholmod_rowfac.o cholmod_solve.o cholmod_spsolve.o MATRIXOPS = cholmod_drop.o cholmod_horzcat.o cholmod_norm.o \ cholmod_scale.o cholmod_sdmult.o cholmod_ssmult.o \ cholmod_submatrix.o cholmod_vertcat.o cholmod_symmetry.o PARTITION = cholmod_ccolamd.o cholmod_csymamd.o \ cholmod_metis.o cholmod_nesdis.o cholmod_camd.o MODIFY = cholmod_rowadd.o cholmod_rowdel.o cholmod_updown.o SUPERNODAL = cholmod_super_numeric.o cholmod_super_solve.o \ cholmod_super_symbolic.o DI = $(CORE) $(CHECK) $(CHOLESKY) $(MATRIXOPS) $(MODIFY) $(SUPERNODAL) # $(PARTITION) #------------------------------------------------------------------------------- # CHOLMOD library modules (long, double) #------------------------------------------------------------------------------- LCORE = cholmod_l_aat.o cholmod_l_add.o cholmod_l_band.o \ cholmod_l_change_factor.o cholmod_l_common.o cholmod_l_complex.o \ cholmod_l_copy.o cholmod_l_dense.o cholmod_l_error.o \ cholmod_l_factor.o cholmod_l_memory.o \ cholmod_l_sparse.o cholmod_l_transpose.o cholmod_l_triplet.o \ cholmod_l_version.o LCHECK = cholmod_l_check.o cholmod_l_read.o cholmod_l_write.o LCHOLESKY = cholmod_l_amd.o cholmod_l_analyze.o cholmod_l_colamd.o \ cholmod_l_etree.o cholmod_l_factorize.o cholmod_l_postorder.o \ cholmod_l_rcond.o cholmod_l_resymbol.o cholmod_l_rowcolcounts.o \ cholmod_l_rowfac.o cholmod_l_solve.o cholmod_l_spsolve.o LMATRIXOPS = cholmod_l_drop.o cholmod_l_horzcat.o cholmod_l_norm.o \ cholmod_l_scale.o cholmod_l_sdmult.o cholmod_l_ssmult.o \ cholmod_l_submatrix.o cholmod_l_vertcat.o cholmod_l_symmetry.o LPARTITION = cholmod_l_ccolamd.o cholmod_l_csymamd.o \ cholmod_l_metis.o cholmod_l_nesdis.o cholmod_l_camd.o LMODIFY = cholmod_l_rowadd.o cholmod_l_rowdel.o cholmod_l_updown.o LSUPERNODAL = cholmod_l_super_numeric.o cholmod_l_super_solve.o \ cholmod_l_super_symbolic.o DL = $(LCORE) $(LCHECK) $(LCHOLESKY) $(LMATRIXOPS) $(LMODIFY) $(LSUPERNODAL) #$(LPARTITION) #------------------------------------------------------------------------------- OBJS = $(DI) $(DL) # ^^ With 64-bit being standard, # we want to have e.g. dense n x m matrices where n x m >> max_int, # and this *only* works for the *_l_* routines, i.e., those compiled with # 'DLONG' defined. LIB = ../../CHOLMOD.a C = $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) lib: $(LIB) $(LIB): $(OBJS) $(AR) -rucs $(LIB) $(OBJS) mostlyclean: clean clean: @-rm -rf .libs _libs $(LIB) @-rm -f $(OBJS) $(OBJ): $(INC) #------------------------------------------------------------------------------- # Check Module: #------------------------------------------------------------------------------- cholmod_check.o: ../Check/cholmod_check.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Check/cholmod_check.c -o $@ cholmod_read.o: ../Check/cholmod_read.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Check/cholmod_read.c -o $@ cholmod_write.o: ../Check/cholmod_write.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Check/cholmod_write.c -o $@ #------------------------------------------------------------------------------- cholmod_l_check.o: ../Check/cholmod_check.c $(C) -DDLONG -c $(I) ../Check/cholmod_check.c -o $@ cholmod_l_read.o: ../Check/cholmod_read.c $(C) -DDLONG -c $(I) ../Check/cholmod_read.c -o $@ cholmod_l_write.o: ../Check/cholmod_write.c $(C) -DDLONG -c $(I) ../Check/cholmod_write.c -o $@ #------------------------------------------------------------------------------- # Core Module: #------------------------------------------------------------------------------- cholmod_common.o: ../Core/cholmod_common.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Core/cholmod_common.c -o $@ cholmod_dense.o: ../Core/cholmod_dense.c ../Core/t_cholmod_dense.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Core/cholmod_dense.c -o $@ cholmod_factor.o: ../Core/cholmod_factor.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Core/cholmod_factor.c -o $@ cholmod_change_factor.o: ../Core/cholmod_change_factor.c \ ../Core/t_cholmod_change_factor.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Core/cholmod_change_factor.c -o $@ cholmod_memory.o: ../Core/cholmod_memory.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Core/cholmod_memory.c -o $@ cholmod_sparse.o: ../Core/cholmod_sparse.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Core/cholmod_sparse.c -o $@ cholmod_complex.o: ../Core/cholmod_complex.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Core/cholmod_complex.c -o $@ cholmod_transpose.o: ../Core/cholmod_transpose.c ../Core/t_cholmod_transpose.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Core/cholmod_transpose.c -o $@ cholmod_band.o: ../Core/cholmod_band.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Core/cholmod_band.c -o $@ cholmod_copy.o: ../Core/cholmod_copy.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Core/cholmod_copy.c -o $@ cholmod_triplet.o: ../Core/cholmod_triplet.c ../Core/t_cholmod_triplet.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Core/cholmod_triplet.c -o $@ cholmod_error.o: ../Core/cholmod_error.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Core/cholmod_error.c -o $@ cholmod_aat.o: ../Core/cholmod_aat.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Core/cholmod_aat.c -o $@ cholmod_add.o: ../Core/cholmod_add.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Core/cholmod_add.c -o $@ cholmod_version.o: ../Core/cholmod_version.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Core/cholmod_version.c -o $@ #------------------------------------------------------------------------------- cholmod_l_common.o: ../Core/cholmod_common.c $(C) -DDLONG -c $(I) ../Core/cholmod_common.c -o $@ cholmod_l_dense.o: ../Core/cholmod_dense.c ../Core/t_cholmod_dense.c $(C) -DDLONG -c $(I) ../Core/cholmod_dense.c -o $@ cholmod_l_factor.o: ../Core/cholmod_factor.c $(C) -DDLONG -c $(I) ../Core/cholmod_factor.c -o $@ cholmod_l_change_factor.o: ../Core/cholmod_change_factor.c \ ../Core/t_cholmod_change_factor.c $(C) -DDLONG -c $(I) ../Core/cholmod_change_factor.c -o $@ cholmod_l_memory.o: ../Core/cholmod_memory.c $(C) -DDLONG -c $(I) ../Core/cholmod_memory.c -o $@ cholmod_l_sparse.o: ../Core/cholmod_sparse.c $(C) -DDLONG -c $(I) ../Core/cholmod_sparse.c -o $@ cholmod_l_complex.o: ../Core/cholmod_complex.c $(C) -DDLONG -c $(I) ../Core/cholmod_complex.c -o $@ cholmod_l_transpose.o: ../Core/cholmod_transpose.c ../Core/t_cholmod_transpose.c $(C) -DDLONG -c $(I) ../Core/cholmod_transpose.c -o $@ cholmod_l_band.o: ../Core/cholmod_band.c $(C) -DDLONG -c $(I) ../Core/cholmod_band.c -o $@ cholmod_l_copy.o: ../Core/cholmod_copy.c $(C) -DDLONG -c $(I) ../Core/cholmod_copy.c -o $@ cholmod_l_triplet.o: ../Core/cholmod_triplet.c ../Core/t_cholmod_triplet.c $(C) -DDLONG -c $(I) ../Core/cholmod_triplet.c -o $@ cholmod_l_error.o: ../Core/cholmod_error.c $(C) -DDLONG -c $(I) ../Core/cholmod_error.c -o $@ cholmod_l_aat.o: ../Core/cholmod_aat.c $(C) -DDLONG -c $(I) ../Core/cholmod_aat.c -o $@ cholmod_l_add.o: ../Core/cholmod_add.c $(C) -DDLONG -c $(I) ../Core/cholmod_add.c -o $@ cholmod_l_version.o: ../Core/cholmod_version.c $(C) -DDLONG -c $(I) ../Core/cholmod_version.c -o $@ #------------------------------------------------------------------------------- # Cholesky Module: #------------------------------------------------------------------------------- cholmod_amd.o: ../Cholesky/cholmod_amd.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Cholesky/cholmod_amd.c -o $@ cholmod_analyze.o: ../Cholesky/cholmod_analyze.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Cholesky/cholmod_analyze.c -o $@ cholmod_colamd.o: ../Cholesky/cholmod_colamd.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Cholesky/cholmod_colamd.c -o $@ cholmod_etree.o: ../Cholesky/cholmod_etree.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Cholesky/cholmod_etree.c -o $@ cholmod_factorize.o: ../Cholesky/cholmod_factorize.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Cholesky/cholmod_factorize.c -o $@ cholmod_postorder.o: ../Cholesky/cholmod_postorder.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Cholesky/cholmod_postorder.c -o $@ cholmod_rcond.o: ../Cholesky/cholmod_rcond.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Cholesky/cholmod_rcond.c -o $@ cholmod_resymbol.o: ../Cholesky/cholmod_resymbol.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Cholesky/cholmod_resymbol.c -o $@ cholmod_rowcolcounts.o: ../Cholesky/cholmod_rowcolcounts.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Cholesky/cholmod_rowcolcounts.c -o $@ cholmod_solve.o: ../Cholesky/cholmod_solve.c ../Cholesky/t_cholmod_lsolve.c \ ../Cholesky/t_cholmod_ltsolve.c ../Cholesky/t_cholmod_solve.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Cholesky/cholmod_solve.c -o $@ cholmod_spsolve.o: ../Cholesky/cholmod_spsolve.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Cholesky/cholmod_spsolve.c -o $@ cholmod_rowfac.o: ../Cholesky/cholmod_rowfac.c ../Cholesky/t_cholmod_rowfac.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Cholesky/cholmod_rowfac.c -o $@ #------------------------------------------------------------------------------- cholmod_l_amd.o: ../Cholesky/cholmod_amd.c $(C) -DDLONG -c $(I) ../Cholesky/cholmod_amd.c -o $@ cholmod_l_analyze.o: ../Cholesky/cholmod_analyze.c $(C) -DDLONG -c $(I) ../Cholesky/cholmod_analyze.c -o $@ cholmod_l_colamd.o: ../Cholesky/cholmod_colamd.c $(C) -DDLONG -c $(I) ../Cholesky/cholmod_colamd.c -o $@ cholmod_l_etree.o: ../Cholesky/cholmod_etree.c $(C) -DDLONG -c $(I) ../Cholesky/cholmod_etree.c -o $@ cholmod_l_factorize.o: ../Cholesky/cholmod_factorize.c $(C) -DDLONG -c $(I) ../Cholesky/cholmod_factorize.c -o $@ cholmod_l_postorder.o: ../Cholesky/cholmod_postorder.c $(C) -DDLONG -c $(I) ../Cholesky/cholmod_postorder.c -o $@ cholmod_l_rcond.o: ../Cholesky/cholmod_rcond.c $(C) -DDLONG -c $(I) ../Cholesky/cholmod_rcond.c -o $@ cholmod_l_resymbol.o: ../Cholesky/cholmod_resymbol.c $(C) -DDLONG -c $(I) ../Cholesky/cholmod_resymbol.c -o $@ cholmod_l_rowcolcounts.o: ../Cholesky/cholmod_rowcolcounts.c $(C) -DDLONG -c $(I) ../Cholesky/cholmod_rowcolcounts.c -o $@ cholmod_l_solve.o: ../Cholesky/cholmod_solve.c ../Cholesky/t_cholmod_lsolve.c \ ../Cholesky/t_cholmod_ltsolve.c ../Cholesky/t_cholmod_solve.c $(C) -DDLONG -c $(I) ../Cholesky/cholmod_solve.c -o $@ cholmod_l_spsolve.o: ../Cholesky/cholmod_spsolve.c $(C) -DDLONG -c $(I) ../Cholesky/cholmod_spsolve.c -o $@ cholmod_l_rowfac.o: ../Cholesky/cholmod_rowfac.c ../Cholesky/t_cholmod_rowfac.c $(C) -DDLONG -c $(I) ../Cholesky/cholmod_rowfac.c -o $@ #------------------------------------------------------------------------------- # Partition Module: #------------------------------------------------------------------------------- cholmod_ccolamd.o: ../Partition/cholmod_ccolamd.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Partition/cholmod_ccolamd.c -o $@ cholmod_csymamd.o: ../Partition/cholmod_csymamd.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Partition/cholmod_csymamd.c -o $@ cholmod_camd.o: ../Partition/cholmod_camd.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Partition/cholmod_camd.c -o $@ cholmod_metis.o: ../Partition/cholmod_metis.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Partition/cholmod_metis.c -o $@ cholmod_nesdis.o: ../Partition/cholmod_nesdis.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Partition/cholmod_nesdis.c -o $@ #------------------------------------------------------------------------------- cholmod_l_ccolamd.o: ../Partition/cholmod_ccolamd.c $(C) -DDLONG -c $(I) ../Partition/cholmod_ccolamd.c -o $@ cholmod_l_csymamd.o: ../Partition/cholmod_csymamd.c $(C) -DDLONG -c $(I) ../Partition/cholmod_csymamd.c -o $@ cholmod_l_camd.o: ../Partition/cholmod_camd.c $(C) -DDLONG -c $(I) ../Partition/cholmod_camd.c -o $@ cholmod_l_metis.o: ../Partition/cholmod_metis.c $(C) -DDLONG -c $(I) ../Partition/cholmod_metis.c -o $@ cholmod_l_nesdis.o: ../Partition/cholmod_nesdis.c $(C) -DDLONG -c $(I) ../Partition/cholmod_nesdis.c -o $@ #------------------------------------------------------------------------------- # MatrixOps Module: #------------------------------------------------------------------------------- cholmod_horzcat.o: ../MatrixOps/cholmod_horzcat.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../MatrixOps/cholmod_horzcat.c -o $@ cholmod_norm.o: ../MatrixOps/cholmod_norm.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../MatrixOps/cholmod_norm.c -o $@ cholmod_scale.o: ../MatrixOps/cholmod_scale.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../MatrixOps/cholmod_scale.c -o $@ cholmod_drop.o: ../MatrixOps/cholmod_drop.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../MatrixOps/cholmod_drop.c -o $@ cholmod_sdmult.o: ../MatrixOps/cholmod_sdmult.c \ ../MatrixOps/t_cholmod_sdmult.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../MatrixOps/cholmod_sdmult.c -o $@ cholmod_ssmult.o: ../MatrixOps/cholmod_ssmult.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../MatrixOps/cholmod_ssmult.c -o $@ cholmod_submatrix.o: ../MatrixOps/cholmod_submatrix.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../MatrixOps/cholmod_submatrix.c -o $@ cholmod_vertcat.o: ../MatrixOps/cholmod_vertcat.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../MatrixOps/cholmod_vertcat.c -o $@ cholmod_symmetry.o: ../MatrixOps/cholmod_symmetry.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../MatrixOps/cholmod_symmetry.c -o $@ #------------------------------------------------------------------------------- cholmod_l_horzcat.o: ../MatrixOps/cholmod_horzcat.c $(C) -DDLONG -c $(I) ../MatrixOps/cholmod_horzcat.c -o $@ cholmod_l_norm.o: ../MatrixOps/cholmod_norm.c $(C) -DDLONG -c $(I) ../MatrixOps/cholmod_norm.c -o $@ cholmod_l_scale.o: ../MatrixOps/cholmod_scale.c $(C) -DDLONG -c $(I) ../MatrixOps/cholmod_scale.c -o $@ cholmod_l_drop.o: ../MatrixOps/cholmod_drop.c $(C) -DDLONG -c $(I) ../MatrixOps/cholmod_drop.c -o $@ cholmod_l_sdmult.o: ../MatrixOps/cholmod_sdmult.c \ ../MatrixOps/t_cholmod_sdmult.c $(C) -DDLONG -c $(I) ../MatrixOps/cholmod_sdmult.c -o $@ cholmod_l_ssmult.o: ../MatrixOps/cholmod_ssmult.c $(C) -DDLONG -c $(I) ../MatrixOps/cholmod_ssmult.c -o $@ cholmod_l_submatrix.o: ../MatrixOps/cholmod_submatrix.c $(C) -DDLONG -c $(I) ../MatrixOps/cholmod_submatrix.c -o $@ cholmod_l_vertcat.o: ../MatrixOps/cholmod_vertcat.c $(C) -DDLONG -c $(I) ../MatrixOps/cholmod_vertcat.c -o $@ cholmod_l_symmetry.o: ../MatrixOps/cholmod_symmetry.c $(C) -DDLONG -c $(I) ../MatrixOps/cholmod_symmetry.c -o $@ #------------------------------------------------------------------------------- # Modify Module: #------------------------------------------------------------------------------- cholmod_rowadd.o: ../Modify/cholmod_rowadd.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Modify/cholmod_rowadd.c -o $@ cholmod_rowdel.o: ../Modify/cholmod_rowdel.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Modify/cholmod_rowdel.c -o $@ cholmod_updown.o: ../Modify/cholmod_updown.c \ ../Modify/t_cholmod_updown.c ../Modify/t_cholmod_updown_numkr.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Modify/cholmod_updown.c -o $@ #------------------------------------------------------------------------------- cholmod_l_rowadd.o: ../Modify/cholmod_rowadd.c $(C) -DDLONG -c $(I) ../Modify/cholmod_rowadd.c -o $@ cholmod_l_rowdel.o: ../Modify/cholmod_rowdel.c $(C) -DDLONG -c $(I) ../Modify/cholmod_rowdel.c -o $@ cholmod_l_updown.o: ../Modify/cholmod_updown.c \ ../Modify/t_cholmod_updown.c ../Modify/t_cholmod_updown_numkr.c $(C) -DDLONG -c $(I) ../Modify/cholmod_updown.c -o $@ #------------------------------------------------------------------------------- # Supernodal Module: #------------------------------------------------------------------------------- cholmod_super_numeric.o: ../Supernodal/cholmod_super_numeric.c \ ../Supernodal/t_cholmod_gpu.c \ ../Supernodal/t_cholmod_super_numeric.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Supernodal/cholmod_super_numeric.c -o $@ cholmod_super_symbolic.o: ../Supernodal/cholmod_super_symbolic.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Supernodal/cholmod_super_symbolic.c -o $@ cholmod_super_solve.o: ../Supernodal/cholmod_super_solve.c \ ../Supernodal/t_cholmod_super_solve.c $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c ../Supernodal/cholmod_super_solve.c -o $@ #------------------------------------------------------------------------------- cholmod_l_super_numeric.o: ../Supernodal/cholmod_super_numeric.c \ ../Supernodal/t_cholmod_super_numeric.c $(C) -DDLONG -c $(I) ../Supernodal/cholmod_super_numeric.c -o $@ cholmod_l_super_symbolic.o: ../Supernodal/cholmod_super_symbolic.c $(C) -DDLONG -c $(I) ../Supernodal/cholmod_super_symbolic.c -o $@ cholmod_l_super_solve.o: ../Supernodal/cholmod_super_solve.c \ ../Supernodal/t_cholmod_super_solve.c $(C) -DDLONG -c $(I) ../Supernodal/cholmod_super_solve.c -o $@ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/MatrixOps/�����������������������������������������������������������������������0000755�0001762�0000144�00000000000�14547723665�015343� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/MatrixOps/cholmod_norm.c���������������������������������������������������������0000644�0001762�0000144�00000026113�13652535054�020157� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === MatrixOps/cholmod_norm =============================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/MatrixOps Module. Copyright (C) 2005-2006, Timothy A. Davis * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* r = norm (A), compute the infinity-norm, 1-norm, or 2-norm of a sparse or * dense matrix. Can compute the 2-norm only for a dense column vector. * Returns -1 if an error occurs. * * Pattern, real, complex, and zomplex sparse matrices are supported. */ #ifndef NGPL #ifndef NMATRIXOPS #include "cholmod_internal.h" #include "cholmod_matrixops.h" /* ========================================================================== */ /* === abs_value ============================================================ */ /* ========================================================================== */ /* Compute the absolute value of a real, complex, or zomplex value */ static double abs_value ( int xtype, double *Ax, double *Az, Int p, cholmod_common *Common ) { double s = 0 ; switch (xtype) { case CHOLMOD_PATTERN: s = 1 ; break ; case CHOLMOD_REAL: s = fabs (Ax [p]) ; break ; case CHOLMOD_COMPLEX: s = SuiteSparse_config.hypot_func (Ax [2*p], Ax [2*p+1]) ; break ; case CHOLMOD_ZOMPLEX: s = SuiteSparse_config.hypot_func (Ax [p], Az [p]) ; break ; } return (s) ; } /* ========================================================================== */ /* === cholmod_norm_dense =================================================== */ /* ========================================================================== */ double CHOLMOD(norm_dense) ( /* ---- input ---- */ cholmod_dense *X, /* matrix to compute the norm of */ int norm, /* type of norm: 0: inf. norm, 1: 1-norm, 2: 2-norm */ /* --------------- */ cholmod_common *Common ) { double xnorm, s, x, z ; double *Xx, *Xz, *W ; Int nrow, ncol, d, i, j, use_workspace, xtype ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (EMPTY) ; RETURN_IF_NULL (X, EMPTY) ; RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, EMPTY) ; Common->status = CHOLMOD_OK ; ncol = X->ncol ; if (norm < 0 || norm > 2 || (norm == 2 && ncol > 1)) { ERROR (CHOLMOD_INVALID, "invalid norm") ; return (EMPTY) ; } /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ nrow = X->nrow ; d = X->d ; Xx = X->x ; Xz = X->z ; xtype = X->xtype ; /* ---------------------------------------------------------------------- */ /* allocate workspace, if needed */ /* ---------------------------------------------------------------------- */ W = NULL ; use_workspace = (norm == 0 && ncol > 4) ; if (use_workspace) { CHOLMOD(allocate_work) (0, 0, nrow, Common) ; W = Common->Xwork ; if (Common->status < CHOLMOD_OK) { /* oops, no workspace */ use_workspace = FALSE ; } } /* ---------------------------------------------------------------------- */ /* compute the norm */ /* ---------------------------------------------------------------------- */ xnorm = 0 ; if (use_workspace) { /* ------------------------------------------------------------------ */ /* infinity-norm = max row sum, using stride-1 access of X */ /* ------------------------------------------------------------------ */ DEBUG (for (i = 0 ; i < nrow ; i++) ASSERT (W [i] == 0)) ; /* this is faster than stride-d, but requires O(nrow) workspace */ for (j = 0 ; j < ncol ; j++) { for (i = 0 ; i < nrow ; i++) { W [i] += abs_value (xtype, Xx, Xz, i+j*d, Common) ; } } for (i = 0 ; i < nrow ; i++) { s = W [i] ; if ((IS_NAN (s) || s > xnorm) && !IS_NAN (xnorm)) { xnorm = s ; } W [i] = 0 ; } } else if (norm == 0) { /* ------------------------------------------------------------------ */ /* infinity-norm = max row sum, using stride-d access of X */ /* ------------------------------------------------------------------ */ for (i = 0 ; i < nrow ; i++) { s = 0 ; for (j = 0 ; j < ncol ; j++) { s += abs_value (xtype, Xx, Xz, i+j*d, Common) ; } if ((IS_NAN (s) || s > xnorm) && !IS_NAN (xnorm)) { xnorm = s ; } } } else if (norm == 1) { /* ------------------------------------------------------------------ */ /* 1-norm = max column sum */ /* ------------------------------------------------------------------ */ for (j = 0 ; j < ncol ; j++) { s = 0 ; for (i = 0 ; i < nrow ; i++) { s += abs_value (xtype, Xx, Xz, i+j*d, Common) ; } if ((IS_NAN (s) || s > xnorm) && !IS_NAN (xnorm)) { xnorm = s ; } } } else { /* ------------------------------------------------------------------ */ /* 2-norm = sqrt (sum (X.^2)) */ /* ------------------------------------------------------------------ */ switch (xtype) { case CHOLMOD_REAL: for (i = 0 ; i < nrow ; i++) { x = Xx [i] ; xnorm += x*x ; } break ; case CHOLMOD_COMPLEX: for (i = 0 ; i < nrow ; i++) { x = Xx [2*i ] ; z = Xx [2*i+1] ; xnorm += x*x + z*z ; } break ; case CHOLMOD_ZOMPLEX: for (i = 0 ; i < nrow ; i++) { x = Xx [i] ; z = Xz [i] ; xnorm += x*x + z*z ; } break ; } xnorm = sqrt (xnorm) ; } /* ---------------------------------------------------------------------- */ /* return result */ /* ---------------------------------------------------------------------- */ return (xnorm) ; } /* ========================================================================== */ /* === cholmod_norm_sparse ================================================== */ /* ========================================================================== */ double CHOLMOD(norm_sparse) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to compute the norm of */ int norm, /* type of norm: 0: inf. norm, 1: 1-norm */ /* --------------- */ cholmod_common *Common ) { double anorm, s ; double *Ax, *Az, *W ; Int *Ap, *Ai, *Anz ; Int i, j, p, pend, nrow, ncol, packed, xtype ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (EMPTY) ; RETURN_IF_NULL (A, EMPTY) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, EMPTY) ; Common->status = CHOLMOD_OK ; ncol = A->ncol ; nrow = A->nrow ; if (norm < 0 || norm > 1) { ERROR (CHOLMOD_INVALID, "invalid norm") ; return (EMPTY) ; } if (A->stype && nrow != ncol) { ERROR (CHOLMOD_INVALID, "matrix invalid") ; return (EMPTY) ; } /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ Ap = A->p ; Ai = A->i ; Ax = A->x ; Az = A->z ; Anz = A->nz ; packed = A->packed ; xtype = A->xtype ; /* ---------------------------------------------------------------------- */ /* allocate workspace, if needed */ /* ---------------------------------------------------------------------- */ W = NULL ; if (A->stype || norm == 0) { CHOLMOD(allocate_work) (0, 0, nrow, Common) ; W = Common->Xwork ; if (Common->status < CHOLMOD_OK) { /* out of memory */ return (EMPTY) ; } DEBUG (for (i = 0 ; i < nrow ; i++) ASSERT (W [i] == 0)) ; } /* ---------------------------------------------------------------------- */ /* compute the norm */ /* ---------------------------------------------------------------------- */ anorm = 0 ; if (A->stype > 0) { /* ------------------------------------------------------------------ */ /* A is symmetric with upper triangular part stored */ /* ------------------------------------------------------------------ */ /* infinity-norm = 1-norm = max row/col sum */ for (j = 0 ; j < ncol ; j++) { p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; s = abs_value (xtype, Ax, Az, p, Common) ; if (i == j) { W [i] += s ; } else if (i < j) { W [i] += s ; W [j] += s ; } } } } else if (A->stype < 0) { /* ------------------------------------------------------------------ */ /* A is symmetric with lower triangular part stored */ /* ------------------------------------------------------------------ */ /* infinity-norm = 1-norm = max row/col sum */ for (j = 0 ; j < ncol ; j++) { p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; s = abs_value (xtype, Ax, Az, p, Common) ; if (i == j) { W [i] += s ; } else if (i > j) { W [i] += s ; W [j] += s ; } } } } else if (norm == 0) { /* ------------------------------------------------------------------ */ /* A is unsymmetric, compute the infinity-norm */ /* ------------------------------------------------------------------ */ /* infinity-norm = max row sum */ for (j = 0 ; j < ncol ; j++) { p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { W [Ai [p]] += abs_value (xtype, Ax, Az, p, Common) ; } } } else { /* ------------------------------------------------------------------ */ /* A is unsymmetric, compute the 1-norm */ /* ------------------------------------------------------------------ */ /* 1-norm = max column sum */ for (j = 0 ; j < ncol ; j++) { p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; if (xtype == CHOLMOD_PATTERN) { s = pend - p ; } else { s = 0 ; for ( ; p < pend ; p++) { s += abs_value (xtype, Ax, Az, p, Common) ; } } if ((IS_NAN (s) || s > anorm) && !IS_NAN (anorm)) { anorm = s ; } } } /* ---------------------------------------------------------------------- */ /* compute the max row sum */ /* ---------------------------------------------------------------------- */ if (A->stype || norm == 0) { for (i = 0 ; i < nrow ; i++) { s = W [i] ; if ((IS_NAN (s) || s > anorm) && !IS_NAN (anorm)) { anorm = s ; } W [i] = 0 ; } } /* ---------------------------------------------------------------------- */ /* return result */ /* ---------------------------------------------------------------------- */ return (anorm) ; } #endif #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/MatrixOps/cholmod_horzcat.c������������������������������������������������������0000644�0001762�0000144�00000013712�13652535054�020657� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === MatrixOps/cholmod_horzcat ============================================ */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/MatrixOps Module. Copyright (C) 2005-2006, Timothy A. Davis * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* Horizontal concatenation, C = [A , B] in MATLAB notation. * * A and B can be up/lo/unsym; C is unsymmetric and packed. * A and B must have the same number of rows. * C is sorted if both A and B are sorted. * * workspace: Iwork (max (A->nrow, A->ncol, B->nrow, B->ncol)). * allocates temporary copies of A and B if they are symmetric. * * A and B must have the same numeric xtype, unless values is FALSE. * A and B cannot be complex or zomplex, unless values is FALSE. */ #ifndef NGPL #ifndef NMATRIXOPS #include "cholmod_internal.h" #include "cholmod_matrixops.h" /* ========================================================================== */ /* === cholmod_horzcat ====================================================== */ /* ========================================================================== */ cholmod_sparse *CHOLMOD(horzcat) ( /* ---- input ---- */ cholmod_sparse *A, /* left matrix to concatenate */ cholmod_sparse *B, /* right matrix to concatenate */ int values, /* if TRUE compute the numerical values of C */ /* --------------- */ cholmod_common *Common ) { double *Ax, *Bx, *Cx ; Int *Ap, *Ai, *Anz, *Bp, *Bi, *Bnz, *Cp, *Ci ; cholmod_sparse *C, *A2, *B2 ; Int apacked, bpacked, ancol, bncol, ncol, nrow, anz, bnz, nz, j, p, pend, pdest ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (A, NULL) ; RETURN_IF_NULL (B, NULL) ; values = values && (A->xtype != CHOLMOD_PATTERN) && (B->xtype != CHOLMOD_PATTERN) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, values ? CHOLMOD_REAL : CHOLMOD_ZOMPLEX, NULL) ; RETURN_IF_XTYPE_INVALID (B, CHOLMOD_PATTERN, values ? CHOLMOD_REAL : CHOLMOD_ZOMPLEX, NULL) ; if (A->nrow != B->nrow) { /* A and B must have the same number of rows */ ERROR (CHOLMOD_INVALID, "A and B must have same # rows") ; return (NULL) ; } /* A and B must have the same numerical type if values is TRUE (both must * be CHOLMOD_REAL, this is implicitly checked above) */ Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ ancol = A->ncol ; bncol = B->ncol ; nrow = A->nrow ; CHOLMOD(allocate_work) (0, MAX3 (nrow, ancol, bncol), 0, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ return (NULL) ; } /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ /* convert A to unsymmetric, if necessary */ A2 = NULL ; if (A->stype != 0) { /* workspace: Iwork (max (A->nrow,A->ncol)) */ A2 = CHOLMOD(copy) (A, 0, values, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ return (NULL) ; } A = A2 ; } /* convert B to unsymmetric, if necessary */ B2 = NULL ; if (B->stype != 0) { /* workspace: Iwork (max (B->nrow,B->ncol)) */ B2 = CHOLMOD(copy) (B, 0, values, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ CHOLMOD(free_sparse) (&A2, Common) ; return (NULL) ; } B = B2 ; } Ap = A->p ; Anz = A->nz ; Ai = A->i ; Ax = A->x ; apacked = A->packed ; Bp = B->p ; Bnz = B->nz ; Bi = B->i ; Bx = B->x ; bpacked = B->packed ; /* ---------------------------------------------------------------------- */ /* allocate C */ /* ---------------------------------------------------------------------- */ anz = CHOLMOD(nnz) (A, Common) ; bnz = CHOLMOD(nnz) (B, Common) ; ncol = ancol + bncol ; nz = anz + bnz ; C = CHOLMOD(allocate_sparse) (nrow, ncol, nz, A->sorted && B->sorted, TRUE, 0, values ? A->xtype : CHOLMOD_PATTERN, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ CHOLMOD(free_sparse) (&A2, Common) ; CHOLMOD(free_sparse) (&B2, Common) ; return (NULL) ; } Cp = C->p ; Ci = C->i ; Cx = C->x ; /* ---------------------------------------------------------------------- */ /* C = [A , B] */ /* ---------------------------------------------------------------------- */ pdest = 0 ; /* copy A as the first A->ncol columns of C */ for (j = 0 ; j < ancol ; j++) { /* A(:,j) is the jth column of C */ p = Ap [j] ; pend = (apacked) ? (Ap [j+1]) : (p + Anz [j]) ; Cp [j] = pdest ; for ( ; p < pend ; p++) { Ci [pdest] = Ai [p] ; if (values) Cx [pdest] = Ax [p] ; pdest++ ; } } /* copy B as the next B->ncol columns of C */ for (j = 0 ; j < bncol ; j++) { /* B(:,j) is the (ancol+j)th column of C */ p = Bp [j] ; pend = (bpacked) ? (Bp [j+1]) : (p + Bnz [j]) ; Cp [ancol + j] = pdest ; for ( ; p < pend ; p++) { Ci [pdest] = Bi [p] ; if (values) Cx [pdest] = Bx [p] ; pdest++ ; } } Cp [ncol] = pdest ; ASSERT (pdest == anz + bnz) ; /* ---------------------------------------------------------------------- */ /* free the unsymmetric copies of A and B, and return C */ /* ---------------------------------------------------------------------- */ CHOLMOD(free_sparse) (&A2, Common) ; CHOLMOD(free_sparse) (&B2, Common) ; return (C) ; } #endif #endif ������������������������������������������������������Matrix/src/CHOLMOD/MatrixOps/cholmod_symmetry.c�����������������������������������������������������0000644�0001762�0000144�00000037672�13652535054�021111� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === MatrixOps/cholmod_symmetry =========================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/MatrixOps Module. Copyright (C) 2005-2006, Timothy A. Davis * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* Determines if a sparse matrix is rectangular, unsymmetric, symmetric, * skew-symmetric, or Hermitian. It does so by looking at its numerical values * of both upper and lower triangular parts of a CHOLMOD "unsymmetric" * matrix, where A->stype == 0. The transpose of A is NOT constructed. * * If not unsymmetric, it also determines if the matrix has a diagonal whose * entries are all real and positive (and thus a candidate for sparse Cholesky * if A->stype is changed to a nonzero value). * * Note that a Matrix Market "general" matrix is either rectangular or * unsymmetric. * * The row indices in the column of each matrix MUST be sorted for this function * to work properly (A->sorted must be TRUE). This routine returns EMPTY if * A->stype is not zero, or if A->sorted is FALSE. The exception to this rule * is if A is rectangular. * * If option == 0, then this routine returns immediately when it finds a * non-positive diagonal entry (or one with nonzero imaginary part). If the * matrix is not a candidate for sparse Cholesky, it returns the value * CHOLMOD_MM_UNSYMMETRIC, even if the matrix might in fact be symmetric or * Hermitian. * * This routine is useful inside the MATLAB backslash, which must look at an * arbitrary matrix (A->stype == 0) and determine if it is a candidate for * sparse Cholesky. In that case, option should be 0. * * This routine is also useful when writing a MATLAB matrix to a file in * Rutherford/Boeing or Matrix Market format. Those formats require a * determination as to the symmetry of the matrix, and thus this routine should * not return upon encountering the first non-positive diagonal. In this case, * option should be 1. * * If option is 2, this function can be used to compute the numerical and * pattern symmetry, where 0 is a completely unsymmetric matrix, and 1 is a * perfectly symmetric matrix. This option is used when computing the following * statistics for the matrices in the UF Sparse Matrix Collection. * * numerical symmetry: number of matched offdiagonal nonzeros over * the total number of offdiagonal entries. A real entry A(i,j), i ~= j, * is matched if A (j,i) == A (i,j), but this is only counted if both * A(j,i) and A(i,j) are nonzero. This does not depend on Z. * (If A is complex, then the above test is modified; A (i,j) is matched * if conj (A (j,i)) == A (i,j)). * * Then numeric symmetry = xmatched / nzoffdiag, or 1 if nzoffdiag = 0. * * pattern symmetry: number of matched offdiagonal entries over the * total number of offdiagonal entries. An entry A(i,j), i ~= j, is * matched if A (j,i) is also an entry. * * Then pattern symmetry = pmatched / nzoffdiag, or 1 if nzoffdiag = 0. * * The symmetry of a matrix with no offdiagonal entries is equal to 1. * * A workspace of size ncol integers is allocated; EMPTY is returned if this * allocation fails. * * Summary of return values: * * EMPTY (-1) out of memory, stype not zero, A not sorted * CHOLMOD_MM_RECTANGULAR 1 A is rectangular * CHOLMOD_MM_UNSYMMETRIC 2 A is unsymmetric * CHOLMOD_MM_SYMMETRIC 3 A is symmetric, but with non-pos. diagonal * CHOLMOD_MM_HERMITIAN 4 A is Hermitian, but with non-pos. diagonal * CHOLMOD_MM_SKEW_SYMMETRIC 5 A is skew symmetric * CHOLMOD_MM_SYMMETRIC_POSDIAG 6 A is symmetric with positive diagonal * CHOLMOD_MM_HERMITIAN_POSDIAG 7 A is Hermitian with positive diagonal * * See also the spsym mexFunction, which is a MATLAB interface for this code. * * If the matrix is a candidate for sparse Cholesky, it will return a result * CHOLMOD_MM_SYMMETRIC_POSDIAG if real, or CHOLMOD_MM_HERMITIAN_POSDIAG if * complex. Otherwise, it will return a value less than this. This is true * regardless of the value of the option parameter. */ #ifndef NGPL #ifndef NMATRIXOPS #include "cholmod_internal.h" #include "cholmod_matrixops.h" /* ========================================================================== */ /* === get_value ============================================================ */ /* ========================================================================== */ /* Get the pth value in the matrix. */ static void get_value ( double *Ax, /* real values, or real/imag. for CHOLMOD_COMPLEX type */ double *Az, /* imaginary values for CHOLMOD_ZOMPLEX type */ Int p, /* get the pth entry */ Int xtype, /* A->xtype: pattern, real, complex, or zomplex */ double *x, /* the real part */ double *z /* the imaginary part */ ) { switch (xtype) { case CHOLMOD_PATTERN: *x = 1 ; *z = 0 ; break ; case CHOLMOD_REAL: *x = Ax [p] ; *z = 0 ; break ; case CHOLMOD_COMPLEX: *x = Ax [2*p] ; *z = Ax [2*p+1] ; break ; case CHOLMOD_ZOMPLEX: *x = Ax [p] ; *z = Az [p] ; break ; } } /* ========================================================================== */ /* === cholmod_symmetry ===================================================== */ /* ========================================================================== */ /* Determine the symmetry of a matrix, and check its diagonal. * * option 0: Do not count # of matched pairs. Quick return if the * the matrix has a zero, negative, or imaginary diagonal entry. * * option 1: Do not count # of matched pairs. Do not return quickly if * the matrix has a zero, negative, or imaginary diagonal entry. * The result 1 to 7 is accurately computed: * * EMPTY (-1) out of memory, stype not zero, A not sorted * CHOLMOD_MM_RECTANGULAR 1 A is rectangular * CHOLMOD_MM_UNSYMMETRIC 2 A is unsymmetric * CHOLMOD_MM_SYMMETRIC 3 A is symmetric, with non-pos. diagonal * CHOLMOD_MM_HERMITIAN 4 A is Hermitian, with non-pos. diagonal * CHOLMOD_MM_SKEW_SYMMETRIC 5 A is skew symmetric * CHOLMOD_MM_SYMMETRIC_POSDIAG 6 is symmetric with positive diagonal * CHOLMOD_MM_HERMITIAN_POSDIAG 7 A is Hermitian with positive diagonal * * The routine returns as soon as the above is determined (that is, it * can return as soon as it determines the matrix is unsymmetric). * * option 2: All of the above, but also compute the number of matched off- * diagonal entries (of two types). xmatched is the number of * nonzero entries for which A(i,j) = conj(A(j,i)). pmatched is * the number of entries (i,j) for which A(i,j) and A(j,i) are both in * the pattern of A (the value doesn't matter). nzoffdiag is the total * number of off-diagonal entries in the pattern. nzdiag is the number of * diagonal entries in the pattern. * * With option 0 or 1, or if the matrix is rectangular, xmatched, pmatched, * nzoffdiag, and nzdiag are not computed. * * Note that a matched pair, A(i,j) and A(j,i) for i != j, is counted twice * (once per entry). */ int CHOLMOD(symmetry) ( /* ---- input ---- */ cholmod_sparse *A, int option, /* option 0, 1, or 2 (see above) */ /* ---- output --- */ /* outputs ignored if any are NULL */ Int *p_xmatched, /* # of matched numerical entries */ Int *p_pmatched, /* # of matched entries in pattern */ Int *p_nzoffdiag, /* # of off diagonal entries */ Int *p_nzdiag, /* # of diagonal entries */ /* --------------- */ cholmod_common *Common ) { double aij_real = 0, aij_imag = 0, aji_real = 0, aji_imag = 0 ; double *Ax, *Az ; Int *Ap, *Ai, *Anz, *munch ; Int packed, nrow, ncol, xtype, is_symmetric, is_skew, is_hermitian, posdiag, j, p, pend, i, piend, result, xmatched, pmatched, nzdiag, i2, found ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (EMPTY) ; RETURN_IF_NULL (A, EMPTY) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, EMPTY) ; Common->status = CHOLMOD_OK ; ASSERT (CHOLMOD(dump_sparse) (A, "cholmod_symmetry", Common) >= 0) ; if (p_xmatched == NULL || p_pmatched == NULL || p_nzoffdiag == NULL || p_nzdiag == NULL) { /* option 2 is not performed if any output parameter is NULL */ option = MAX (option, 1) ; } /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ Ap = A->p ; Ai = A->i ; Ax = A->x ; Az = A->z ; Anz = A->nz ; packed = A->packed ; ncol = A->ncol ; nrow = A->nrow ; xtype = A->xtype ; /* ---------------------------------------------------------------------- */ /* check if rectangular, unsorted, or stype is not zero */ /* ---------------------------------------------------------------------- */ if (nrow != ncol) { /* matrix is rectangular */ return (CHOLMOD_MM_RECTANGULAR) ; } if (!(A->sorted) || A->stype != 0) { /* this function cannot determine the type or symmetry */ return (EMPTY) ; } /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ /* this function requires uninitialized Int workspace of size ncol */ CHOLMOD(allocate_work) (0, ncol, 0, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ return (EMPTY) ; } munch = Common->Iwork ; /* the munch array is size ncol */ /* ---------------------------------------------------------------------- */ /* determine symmetry of a square matrix */ /* ---------------------------------------------------------------------- */ /* a complex or zomplex matrix is Hermitian until proven otherwise */ is_hermitian = (xtype >= CHOLMOD_COMPLEX) ; /* any matrix is symmetric until proven otherwise */ is_symmetric = TRUE ; /* a non-pattern matrix is skew-symmetric until proven otherwise */ is_skew = (xtype != CHOLMOD_PATTERN) ; /* a matrix has positive diagonal entries until proven otherwise */ posdiag = TRUE ; /* munch pointers start at the top of each column */ for (j = 0 ; j < ncol ; j++) { munch [j] = Ap [j] ; } xmatched = 0 ; pmatched = 0 ; nzdiag = 0 ; for (j = 0 ; j < ncol ; j++) /* examine each column of A */ { /* ------------------------------------------------------------------ */ /* look at the entire munch column j */ /* ------------------------------------------------------------------ */ /* start at the munch point of column j, and go to end of the column */ p = munch [j] ; pend = (packed) ? (Ap [j+1]) : (Ap [j] + Anz [j]) ; for ( ; p < pend ; p++) { /* get the row index of A(i,j) */ i = Ai [p] ; if (i < j) { /* ---------------------------------------------------------- */ /* A(i,j) in triu(A), but matching A(j,i) not in tril(A) */ /* ---------------------------------------------------------- */ /* entry A(i,j) is unmatched; it appears in the upper triangular * part, but not the lower triangular part. The matrix is * unsymmetric. */ is_hermitian = FALSE ; is_symmetric = FALSE ; is_skew = FALSE ; } else if (i == j) { /* ---------------------------------------------------------- */ /* the diagonal A(j,j) is present; check its value */ /* ---------------------------------------------------------- */ get_value (Ax, Az, p, xtype, &aij_real, &aij_imag) ; if (aij_real != 0. || aij_imag != 0.) { /* diagonal is nonzero; matrix is not skew-symmetric */ nzdiag++ ; is_skew = FALSE ; } if (aij_real <= 0. || aij_imag != 0.) { /* diagonal negative or imaginary; not chol candidate */ posdiag = FALSE ; } if (aij_imag != 0.) { /* imaginary part is present; not Hermitian */ is_hermitian = FALSE ; } } else /* i > j */ { /* ---------------------------------------------------------- */ /* consider column i, up to and including row j */ /* ---------------------------------------------------------- */ /* munch the entry at top of column i up to and incl row j */ piend = (packed) ? (Ap [i+1]) : (Ap [i] + Anz [i]) ; found = FALSE ; for ( ; munch [i] < piend ; munch [i]++) { i2 = Ai [munch [i]] ; if (i2 < j) { /* -------------------------------------------------- */ /* A(i2,i) in triu(A) but A(i,i2) not in tril(A) */ /* -------------------------------------------------- */ /* The matrix is unsymmetric. */ is_hermitian = FALSE ; is_symmetric = FALSE ; is_skew = FALSE ; } else if (i2 == j) { /* -------------------------------------------------- */ /* both A(i,j) and A(j,i) exist in the matrix */ /* -------------------------------------------------- */ /* this is one more matching entry in the pattern */ pmatched += 2 ; found = TRUE ; /* get the value of A(i,j) */ get_value (Ax, Az, p, xtype, &aij_real, &aij_imag) ; /* get the value of A(j,i) */ get_value (Ax, Az, munch [i], xtype, &aji_real, &aji_imag) ; /* compare A(i,j) with A(j,i) */ if (aij_real != aji_real || aij_imag != aji_imag) { /* the matrix cannot be symmetric */ is_symmetric = FALSE ; } if (aij_real != -aji_real || aij_imag != aji_imag) { /* the matrix cannot be skew-symmetric */ is_skew = FALSE ; } if (aij_real != aji_real || aij_imag != -aji_imag) { /* the matrix cannot be Hermitian */ is_hermitian = FALSE ; } else { /* A(i,j) and A(j,i) are numerically matched */ xmatched += 2 ; } } else /* i2 > j */ { /* -------------------------------------------------- */ /* entry A(i2,i) is not munched; consider it later */ /* -------------------------------------------------- */ break ; } } if (!found) { /* A(i,j) in tril(A) but A(j,i) not in triu(A). * The matrix is unsymmetric. */ is_hermitian = FALSE ; is_symmetric = FALSE ; is_skew = FALSE ; } } if (option < 2 && !(is_symmetric || is_skew || is_hermitian)) { /* matrix is unsymmetric; terminate the test */ return (CHOLMOD_MM_UNSYMMETRIC) ; } } /* ------------------------------------------------------------------ */ /* quick return if not Cholesky candidate */ /* ------------------------------------------------------------------ */ if (option < 1 && (!posdiag || nzdiag <= j)) { /* Diagonal entry not present, or present but negative or with * nonzero imaginary part. Quick return for option 0. */ return (CHOLMOD_MM_UNSYMMETRIC) ; } } /* ---------------------------------------------------------------------- */ /* return the results */ /* ---------------------------------------------------------------------- */ if (nzdiag < ncol) { /* not all diagonal entries are present */ posdiag = FALSE ; } if (option >= 2) { *p_xmatched = xmatched ; *p_pmatched = pmatched ; *p_nzoffdiag = CHOLMOD(nnz) (A, Common) - nzdiag ; *p_nzdiag = nzdiag ; } result = CHOLMOD_MM_UNSYMMETRIC ; if (is_hermitian) { /* complex Hermitian matrix, with either pos. or non-pos. diagonal */ result = posdiag ? CHOLMOD_MM_HERMITIAN_POSDIAG : CHOLMOD_MM_HERMITIAN ; } else if (is_symmetric) { /* real or complex symmetric matrix, with pos. or non-pos. diagonal */ result = posdiag ? CHOLMOD_MM_SYMMETRIC_POSDIAG : CHOLMOD_MM_SYMMETRIC ; } else if (is_skew) { /* real or complex skew-symmetric matrix */ result = CHOLMOD_MM_SKEW_SYMMETRIC ; } return (result) ; } #endif #endif ����������������������������������������������������������������������Matrix/src/CHOLMOD/MatrixOps/cholmod_ssmult.c�������������������������������������������������������0000644�0001762�0000144�00000033470�13652535054�020537� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === MatrixOps/cholmod_ssmult ============================================= */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/MatrixOps Module. Copyright (C) 2005-2006, Timothy A. Davis * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* C = A*B. Multiply two sparse matrices. * * A and B can be packed or unpacked, sorted or unsorted, and of any stype. * If A or B are symmetric, an internal unsymmetric copy is made first, however. * C is computed as if A and B are unsymmetric, and then if the stype input * parameter requests a symmetric form (upper or lower) the matrix is converted * into that form. * * C is returned as packed, and either unsorted or sorted, depending on the * "sorted" input parameter. If C is returned sorted, then either C = (B'*A')' * or C = (A*B)'' is computed, depending on the number of nonzeros in A, B, and * C. * * workspace: * if C unsorted: Flag (A->nrow), W (A->nrow) if values * if C sorted: Flag (B->ncol), W (B->ncol) if values * Iwork (max (A->ncol, A->nrow, B->nrow, B->ncol)) * allocates temporary copies for A, B, and C, if required. * * Only pattern and real matrices are supported. Complex and zomplex matrices * are supported only when the numerical values are not computed ("values" * is FALSE). */ #ifndef NGPL #ifndef NMATRIXOPS #include "cholmod_internal.h" #include "cholmod_matrixops.h" /* ========================================================================== */ /* === cholmod_ssmult ======================================================= */ /* ========================================================================== */ cholmod_sparse *CHOLMOD(ssmult) ( /* ---- input ---- */ cholmod_sparse *A, /* left matrix to multiply */ cholmod_sparse *B, /* right matrix to multiply */ int stype, /* requested stype of C */ int values, /* TRUE: do numerical values, FALSE: pattern only */ int sorted, /* if TRUE then return C with sorted columns */ /* --------------- */ cholmod_common *Common ) { double bjt ; double *Ax, *Bx, *Cx, *W ; Int *Ap, *Anz, *Ai, *Bp, *Bnz, *Bi, *Cp, *Ci, *Flag ; cholmod_sparse *C, *A2, *B2, *A3, *B3, *C2 ; Int apacked, bpacked, j, i, pa, paend, pb, pbend, ncol, mark, cnz, t, p, nrow, anz, bnz, do_swap_and_transpose, n1, n2 ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (A, NULL) ; RETURN_IF_NULL (B, NULL) ; values = values && (A->xtype != CHOLMOD_PATTERN) && (B->xtype != CHOLMOD_PATTERN) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, values ? CHOLMOD_REAL : CHOLMOD_ZOMPLEX, NULL) ; RETURN_IF_XTYPE_INVALID (B, CHOLMOD_PATTERN, values ? CHOLMOD_REAL : CHOLMOD_ZOMPLEX, NULL) ; if (A->ncol != B->nrow) { /* inner dimensions must agree */ ERROR (CHOLMOD_INVALID, "A and B inner dimensions must match") ; return (NULL) ; } /* A and B must have the same numerical type if values is TRUE (both must * be CHOLMOD_REAL, this is implicitly checked above) */ Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ if (A->nrow <= 1) { /* C will be implicitly sorted, so no need to sort it here */ sorted = FALSE ; } if (sorted) { n1 = MAX (A->nrow, B->ncol) ; } else { n1 = A->nrow ; } n2 = MAX4 (A->ncol, A->nrow, B->nrow, B->ncol) ; CHOLMOD(allocate_work) (n1, n2, values ? n1 : 0, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ return (NULL) ; } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1 : 0, Common)) ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ /* convert A to unsymmetric, if necessary */ A2 = NULL ; B2 = NULL ; if (A->stype) { /* workspace: Iwork (max (A->nrow,A->ncol)) */ A2 = CHOLMOD(copy) (A, 0, values, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1:0, Common)) ; return (NULL) ; } A = A2 ; } /* convert B to unsymmetric, if necessary */ if (B->stype) { /* workspace: Iwork (max (B->nrow,B->ncol)) */ B2 = CHOLMOD(copy) (B, 0, values, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ CHOLMOD(free_sparse) (&A2, Common) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1:0, Common)) ; return (NULL) ; } B = B2 ; } ASSERT (CHOLMOD(dump_sparse) (A, "A", Common) >= 0) ; ASSERT (CHOLMOD(dump_sparse) (B, "B", Common) >= 0) ; /* get the A matrix */ Ap = A->p ; Anz = A->nz ; Ai = A->i ; Ax = A->x ; apacked = A->packed ; /* get the B matrix */ Bp = B->p ; Bnz = B->nz ; Bi = B->i ; Bx = B->x ; bpacked = B->packed ; /* get the size of C */ nrow = A->nrow ; ncol = B->ncol ; /* get workspace */ W = Common->Xwork ; /* size nrow, unused if values is FALSE */ Flag = Common->Flag ; /* size nrow, Flag [0..nrow-1] < mark on input*/ /* ---------------------------------------------------------------------- */ /* count the number of entries in the result C */ /* ---------------------------------------------------------------------- */ cnz = 0 ; for (j = 0 ; j < ncol ; j++) { /* clear the Flag array */ /* mark = CHOLMOD(clear_flag) (Common) ; */ CHOLMOD_CLEAR_FLAG (Common) ; mark = Common->mark ; /* for each nonzero B(t,j) in column j, do: */ pb = Bp [j] ; pbend = (bpacked) ? (Bp [j+1]) : (pb + Bnz [j]) ; for ( ; pb < pbend ; pb++) { /* B(t,j) is nonzero */ t = Bi [pb] ; /* add the nonzero pattern of A(:,t) to the pattern of C(:,j) */ pa = Ap [t] ; paend = (apacked) ? (Ap [t+1]) : (pa + Anz [t]) ; for ( ; pa < paend ; pa++) { i = Ai [pa] ; if (Flag [i] != mark) { Flag [i] = mark ; cnz++ ; } } } if (cnz < 0) { break ; /* integer overflow case */ } } /* mark = CHOLMOD(clear_flag) (Common) ; */ CHOLMOD_CLEAR_FLAG (Common) ; mark = Common->mark ; /* ---------------------------------------------------------------------- */ /* check for integer overflow */ /* ---------------------------------------------------------------------- */ if (cnz < 0) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; CHOLMOD(free_sparse) (&A2, Common) ; CHOLMOD(free_sparse) (&B2, Common) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1:0, Common)) ; return (NULL) ; } /* ---------------------------------------------------------------------- */ /* Determine how to return C sorted (if requested) */ /* ---------------------------------------------------------------------- */ do_swap_and_transpose = FALSE ; if (sorted) { /* Determine the best way to return C with sorted columns. Computing * C = (B'*A')' takes cnz + anz + bnz time (ignoring O(n) terms). * Sorting C when done, C = (A*B)'', takes 2*cnz time. Pick the one * with the least amount of work. */ anz = CHOLMOD(nnz) (A, Common) ; bnz = CHOLMOD(nnz) (B, Common) ; do_swap_and_transpose = (anz + bnz < cnz) ; if (do_swap_and_transpose) { /* -------------------------------------------------------------- */ /* C = (B'*A')' */ /* -------------------------------------------------------------- */ /* workspace: Iwork (A->nrow) */ A3 = CHOLMOD(ptranspose) (A, values, NULL, NULL, 0, Common) ; CHOLMOD(free_sparse) (&A2, Common) ; A2 = A3 ; if (Common->status < CHOLMOD_OK) { /* out of memory */ CHOLMOD(free_sparse) (&A2, Common) ; CHOLMOD(free_sparse) (&B2, Common) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1:0, Common)); return (NULL) ; } /* workspace: Iwork (B->nrow) */ B3 = CHOLMOD(ptranspose) (B, values, NULL, NULL, 0, Common) ; CHOLMOD(free_sparse) (&B2, Common) ; B2 = B3 ; if (Common->status < CHOLMOD_OK) { /* out of memory */ CHOLMOD(free_sparse) (&A2, Common) ; CHOLMOD(free_sparse) (&B2, Common) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1:0, Common)); return (NULL) ; } A = B2 ; B = A2 ; /* get the new A matrix */ Ap = A->p ; Anz = A->nz ; Ai = A->i ; Ax = A->x ; apacked = A->packed ; /* get the new B matrix */ Bp = B->p ; Bnz = B->nz ; Bi = B->i ; Bx = B->x ; bpacked = B->packed ; /* get the size of C' */ nrow = A->nrow ; ncol = B->ncol ; } } /* ---------------------------------------------------------------------- */ /* allocate C */ /* ---------------------------------------------------------------------- */ C = CHOLMOD(allocate_sparse) (nrow, ncol, cnz, FALSE, TRUE, 0, values ? A->xtype : CHOLMOD_PATTERN, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ CHOLMOD(free_sparse) (&A2, Common) ; CHOLMOD(free_sparse) (&B2, Common) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1:0, Common)) ; return (NULL) ; } Cp = C->p ; Ci = C->i ; Cx = C->x ; /* ---------------------------------------------------------------------- */ /* C = A*B */ /* ---------------------------------------------------------------------- */ cnz = 0 ; if (values) { /* pattern and values */ for (j = 0 ; j < ncol ; j++) { /* clear the Flag array */ /* mark = CHOLMOD(clear_flag (Common)) ; */ CHOLMOD_CLEAR_FLAG (Common) ; mark = Common->mark ; /* start column j of C */ Cp [j] = cnz ; /* for each nonzero B(t,j) in column j, do: */ pb = Bp [j] ; pbend = (bpacked) ? (Bp [j+1]) : (pb + Bnz [j]) ; for ( ; pb < pbend ; pb++) { /* B(t,j) is nonzero */ t = Bi [pb] ; bjt = Bx [pb] ; /* add the nonzero pattern of A(:,t) to the pattern of C(:,j) * and scatter the values into W */ pa = Ap [t] ; paend = (apacked) ? (Ap [t+1]) : (pa + Anz [t]) ; for ( ; pa < paend ; pa++) { i = Ai [pa] ; if (Flag [i] != mark) { Flag [i] = mark ; Ci [cnz++] = i ; } W [i] += Ax [pa] * bjt ; } } /* gather the values into C(:,j) */ for (p = Cp [j] ; p < cnz ; p++) { i = Ci [p] ; Cx [p] = W [i] ; W [i] = 0 ; } } } else { /* pattern only */ for (j = 0 ; j < ncol ; j++) { /* clear the Flag array */ /* mark = CHOLMOD(clear_flag) (Common) ; */ CHOLMOD_CLEAR_FLAG (Common) ; mark = Common->mark ; /* start column j of C */ Cp [j] = cnz ; /* for each nonzero B(t,j) in column j, do: */ pb = Bp [j] ; pbend = (bpacked) ? (Bp [j+1]) : (pb + Bnz [j]) ; for ( ; pb < pbend ; pb++) { /* B(t,j) is nonzero */ t = Bi [pb] ; /* add the nonzero pattern of A(:,t) to the pattern of C(:,j) */ pa = Ap [t] ; paend = (apacked) ? (Ap [t+1]) : (pa + Anz [t]) ; for ( ; pa < paend ; pa++) { i = Ai [pa] ; if (Flag [i] != mark) { Flag [i] = mark ; Ci [cnz++] = i ; } } } } } Cp [ncol] = cnz ; ASSERT (MAX (1,cnz) == C->nzmax) ; /* ---------------------------------------------------------------------- */ /* clear workspace and free temporary matrices */ /* ---------------------------------------------------------------------- */ CHOLMOD(free_sparse) (&A2, Common) ; CHOLMOD(free_sparse) (&B2, Common) ; /* CHOLMOD(clear_flag) (Common) ; */ CHOLMOD_CLEAR_FLAG (Common) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1:0, Common)) ; /* ---------------------------------------------------------------------- */ /* convert C to a symmetric upper/lower matrix if requested */ /* ---------------------------------------------------------------------- */ /* convert C in place, which cannot fail since no memory is allocated */ if (stype > 0) { /* C = triu (C), in place */ (void) CHOLMOD(band_inplace) (0, ncol, values, C, Common) ; C->stype = 1 ; } else if (stype < 0) { /* C = tril (C), in place */ (void) CHOLMOD(band_inplace) (-nrow, 0, values, C, Common) ; C->stype = -1 ; } ASSERT (Common->status >= CHOLMOD_OK) ; /* ---------------------------------------------------------------------- */ /* sort C, if requested */ /* ---------------------------------------------------------------------- */ if (sorted) { if (do_swap_and_transpose) { /* workspace: Iwork (C->ncol), which is A->nrow since C=(B'*A') */ C2 = CHOLMOD(ptranspose) (C, values, NULL, NULL, 0, Common) ; CHOLMOD(free_sparse) (&C, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1:0, Common)); return (NULL) ; } C = C2 ; } else { /* workspace: Iwork (max (C->nrow,C->ncol)) */ if (!CHOLMOD(sort) (C, Common)) { /* out of memory */ CHOLMOD(free_sparse) (&C, Common) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1:0, Common)); return (NULL) ; } } } /* ---------------------------------------------------------------------- */ /* return result */ /* ---------------------------------------------------------------------- */ DEBUG (CHOLMOD(dump_sparse) (C, "ssmult", Common) >= 0) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1:0, Common)) ; return (C) ; } #endif #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/MatrixOps/cholmod_scale.c��������������������������������������������������������0000644�0001762�0000144�00000014065�13652535054�020276� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === MatrixOps/cholmod_scale ============================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/MatrixOps Module. Copyright (C) 2005-2006, Timothy A. Davis * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* scale a matrix: A = diag(s)*A, A*diag(s), s*A, or diag(s)*A*diag(s) * * A can be of any type (packed/unpacked, upper/lower/unsymmetric). * The symmetry of A is ignored; all entries in the matrix are modified. * * If A is m-by-n unsymmetric but scaled symmtrically, the result is * A = diag (s (1:m)) * A * diag (s (1:n)). * * Note: diag(s) should be interpretted as spdiags(s,0,n,n) where n=length(s). * * Row or column scaling of a symmetric matrix still results in a symmetric * matrix, since entries are still ignored by other routines. * For example, when row-scaling a symmetric matrix where just the upper * triangular part is stored (and lower triangular entries ignored) * A = diag(s)*triu(A) is performed, where the result A is also * symmetric-upper. This has the effect of modifying the implicit lower * triangular part. In MATLAB notation: * * U = diag(s)*triu(A) ; * L = tril (U',-1) * A = L + U ; * * The scale parameter determines the kind of scaling to perform: * * CHOLMOD_SCALAR: s[0]*A * CHOLMOD_ROW: diag(s)*A * CHOLMOD_COL: A*diag(s) * CHOLMOD_SYM: diag(s)*A*diag(s) * * The size of S depends on the scale parameter: * * CHOLMOD_SCALAR: size 1 * CHOLMOD_ROW: size nrow-by-1 or 1-by-nrow * CHOLMOD_COL: size ncol-by-1 or 1-by-ncol * CHOLMOD_SYM: size max(nrow,ncol)-by-1, or 1-by-max(nrow,ncol) * * workspace: none * * Only real matrices are supported. */ #ifndef NGPL #ifndef NMATRIXOPS #include "cholmod_internal.h" #include "cholmod_matrixops.h" /* ========================================================================== */ /* === cholmod_scale ======================================================== */ /* ========================================================================== */ int CHOLMOD(scale) ( /* ---- input ---- */ cholmod_dense *S, /* scale factors (scalar or vector) */ int scale, /* type of scaling to compute */ /* ---- in/out --- */ cholmod_sparse *A, /* matrix to scale */ /* --------------- */ cholmod_common *Common ) { double t ; double *Ax, *s ; Int *Ap, *Anz, *Ai ; Int packed, j, ncol, nrow, p, pend, sncol, snrow, nn, ok ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_NULL (S, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_REAL, CHOLMOD_REAL, FALSE) ; RETURN_IF_XTYPE_INVALID (S, CHOLMOD_REAL, CHOLMOD_REAL, FALSE) ; ncol = A->ncol ; nrow = A->nrow ; sncol = S->ncol ; snrow = S->nrow ; if (scale == CHOLMOD_SCALAR) { ok = (snrow == 1 && sncol == 1) ; } else if (scale == CHOLMOD_ROW) { ok = (snrow == nrow && sncol == 1) || (snrow == 1 && sncol == nrow) ; } else if (scale == CHOLMOD_COL) { ok = (snrow == ncol && sncol == 1) || (snrow == 1 && sncol == ncol) ; } else if (scale == CHOLMOD_SYM) { nn = MAX (nrow, ncol) ; ok = (snrow == nn && sncol == 1) || (snrow == 1 && sncol == nn) ; } else { /* scale invalid */ ERROR (CHOLMOD_INVALID, "invalid scaling option") ; return (FALSE) ; } if (!ok) { /* S is wrong size */ ERROR (CHOLMOD_INVALID, "invalid scale factors") ; return (FALSE) ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ Ap = A->p ; Anz = A->nz ; Ai = A->i ; Ax = A->x ; packed = A->packed ; s = S->x ; /* ---------------------------------------------------------------------- */ /* scale the matrix */ /* ---------------------------------------------------------------------- */ if (scale == CHOLMOD_ROW) { /* ------------------------------------------------------------------ */ /* A = diag(s)*A, row scaling */ /* ------------------------------------------------------------------ */ for (j = 0 ; j < ncol ; j++) { p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { Ax [p] *= s [Ai [p]] ; } } } else if (scale == CHOLMOD_COL) { /* ------------------------------------------------------------------ */ /* A = A*diag(s), column scaling */ /* ------------------------------------------------------------------ */ for (j = 0 ; j < ncol ; j++) { t = s [j] ; p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { Ax [p] *= t ; } } } else if (scale == CHOLMOD_SYM) { /* ------------------------------------------------------------------ */ /* A = diag(s)*A*diag(s), symmetric scaling */ /* ------------------------------------------------------------------ */ for (j = 0 ; j < ncol ; j++) { t = s [j] ; p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { Ax [p] *= t * s [Ai [p]] ; } } } else if (scale == CHOLMOD_SCALAR) { /* ------------------------------------------------------------------ */ /* A = s[0] * A, scalar scaling */ /* ------------------------------------------------------------------ */ t = s [0] ; for (j = 0 ; j < ncol ; j++) { p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { Ax [p] *= t ; } } } ASSERT (CHOLMOD(dump_sparse) (A, "A scaled", Common) >= 0) ; return (TRUE) ; } #endif #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/MatrixOps/License.txt������������������������������������������������������������0000644�0001762�0000144�00000002030�11770402705�017441� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CHOLMOD/MatrixOps Module. Copyright (C) 2005-2006, Timothy A. Davis CHOLMOD is also available under other licenses; contact authors for details. http://www.suitesparse.com Note that this license is for the CHOLMOD/MatrixOps module only. All CHOLMOD modules are licensed separately. -------------------------------------------------------------------------------- This Module 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 2 of the License, or (at your option) any later version. This Module 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 Module; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/MatrixOps/cholmod_vertcat.c������������������������������������������������������0000644�0001762�0000144�00000013513�13652535054�020654� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === MatrixOps/cholmod_vertcat ============================================ */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/MatrixOps Module. Copyright (C) 2005-2006, Timothy A. Davis * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* Vertical concatenation, C = [A ; B] in MATLAB notation. * * A and B can be up/lo/unsym; C is unsymmetric and packed. * A and B must have the same number of columns. * C is sorted if both A and B are sorted. * * workspace: Iwork (max (A->nrow, A->ncol, B->nrow, B->ncol)). * allocates temporary copies of A and B if they are symmetric. * * Only pattern and real matrices are supported. Complex and zomplex matrices * are supported only if "values" is FALSE. */ #ifndef NGPL #ifndef NMATRIXOPS #include "cholmod_internal.h" #include "cholmod_matrixops.h" /* ========================================================================== */ /* === cholmod_vertcat ====================================================== */ /* ========================================================================== */ cholmod_sparse *CHOLMOD(vertcat) ( /* ---- input ---- */ cholmod_sparse *A, /* left matrix to concatenate */ cholmod_sparse *B, /* right matrix to concatenate */ int values, /* if TRUE compute the numerical values of C */ /* --------------- */ cholmod_common *Common ) { double *Ax, *Bx, *Cx ; Int *Ap, *Ai, *Anz, *Bp, *Bi, *Bnz, *Cp, *Ci ; cholmod_sparse *C, *A2, *B2 ; Int apacked, bpacked, anrow, bnrow, ncol, nrow, anz, bnz, nz, j, p, pend, pdest ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (A, NULL) ; RETURN_IF_NULL (B, NULL) ; values = values && (A->xtype != CHOLMOD_PATTERN) && (B->xtype != CHOLMOD_PATTERN) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, values ? CHOLMOD_REAL : CHOLMOD_ZOMPLEX, NULL) ; RETURN_IF_XTYPE_INVALID (B, CHOLMOD_PATTERN, values ? CHOLMOD_REAL : CHOLMOD_ZOMPLEX, NULL) ; if (A->ncol != B->ncol) { /* A and B must have the same number of columns */ ERROR (CHOLMOD_INVALID, "A and B must have same # of columns") ; return (NULL) ; } /* A and B must have the same numerical type if values is TRUE (both must * be CHOLMOD_REAL, this is implicitly checked above) */ Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ anrow = A->nrow ; bnrow = B->nrow ; ncol = A->ncol ; CHOLMOD(allocate_work) (0, MAX3 (anrow, bnrow, ncol), 0, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ return (NULL) ; } /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ /* convert A to unsymmetric, if necessary */ A2 = NULL ; if (A->stype != 0) { /* workspace: Iwork (max (A->nrow,A->ncol)) */ A2 = CHOLMOD(copy) (A, 0, values, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ return (NULL) ; } A = A2 ; } /* convert B to unsymmetric, if necessary */ B2 = NULL ; if (B->stype != 0) { /* workspace: Iwork (max (B->nrow,B->ncol)) */ B2 = CHOLMOD(copy) (B, 0, values, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ CHOLMOD(free_sparse) (&A2, Common) ; return (NULL) ; } B = B2 ; } Ap = A->p ; Anz = A->nz ; Ai = A->i ; Ax = A->x ; apacked = A->packed ; Bp = B->p ; Bnz = B->nz ; Bi = B->i ; Bx = B->x ; bpacked = B->packed ; /* ---------------------------------------------------------------------- */ /* allocate C */ /* ---------------------------------------------------------------------- */ anz = CHOLMOD(nnz) (A, Common) ; bnz = CHOLMOD(nnz) (B, Common) ; nrow = anrow + bnrow ; nz = anz + bnz ; C = CHOLMOD(allocate_sparse) (nrow, ncol, nz, A->sorted && B->sorted, TRUE, 0, values ? A->xtype : CHOLMOD_PATTERN, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ CHOLMOD(free_sparse) (&A2, Common) ; CHOLMOD(free_sparse) (&B2, Common) ; return (NULL) ; } Cp = C->p ; Ci = C->i ; Cx = C->x ; /* ---------------------------------------------------------------------- */ /* C = [A ; B] */ /* ---------------------------------------------------------------------- */ pdest = 0 ; for (j = 0 ; j < ncol ; j++) { /* attach A(:,j) as the first part of C(:,j) */ p = Ap [j] ; pend = (apacked) ? (Ap [j+1]) : (p + Anz [j]) ; Cp [j] = pdest ; for ( ; p < pend ; p++) { Ci [pdest] = Ai [p] ; if (values) { Cx [pdest] = Ax [p] ; } pdest++ ; } /* attach B(:,j) as the second part of C(:,j) */ p = Bp [j] ; pend = (bpacked) ? (Bp [j+1]) : (p + Bnz [j]) ; for ( ; p < pend ; p++) { Ci [pdest] = Bi [p] + anrow ; if (values) { Cx [pdest] = Bx [p] ; } pdest++ ; } } Cp [ncol] = pdest ; ASSERT (pdest == nz) ; /* ---------------------------------------------------------------------- */ /* free the unsymmetric copies of A and B, and return C */ /* ---------------------------------------------------------------------- */ CHOLMOD(free_sparse) (&A2, Common) ; CHOLMOD(free_sparse) (&B2, Common) ; return (C) ; } #endif #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/MatrixOps/cholmod_sdmult.c�������������������������������������������������������0000644�0001762�0000144�00000012072�13652535054�020513� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === MatrixOps/cholmod_sdmult ============================================= */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/MatrixOps Module. Copyright (C) 2005-2006, Timothy A. Davis * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* Sparse matrix times dense matrix: * Y = alpha*(A*X) + beta*Y or Y = alpha*(A'*X) + beta*Y, * where A is sparse and X and Y are dense. * * when using A, X has A->ncol columns and Y has A->nrow rows * when using A', X has A->nrow columns and Y has A->ncol rows * * workspace: none in Common. Temporary workspace of size 4*(X->nrow) is used * if A is stored in symmetric form and X has four columns or more. If the * workspace is not available, a slower method is used instead that requires * no workspace. * * transpose = 0: use A * otherwise, use A' (complex conjugate transpose) * * transpose is ignored if the matrix is symmetric or Hermitian. * (the array transpose A.' is not supported). * * Supports real, complex, and zomplex matrices, but the xtypes of A, X, and Y * must all match. */ #ifndef NGPL #ifndef NMATRIXOPS #include "cholmod_internal.h" #include "cholmod_matrixops.h" /* ========================================================================== */ /* === TEMPLATE ============================================================= */ /* ========================================================================== */ #define REAL #include "t_cholmod_sdmult.c" #define COMPLEX #include "t_cholmod_sdmult.c" #define ZOMPLEX #include "t_cholmod_sdmult.c" /* ========================================================================== */ /* === cholmod_sdmult ======================================================= */ /* ========================================================================== */ int CHOLMOD(sdmult) ( /* ---- input ---- */ cholmod_sparse *A, /* sparse matrix to multiply */ int transpose, /* use A if 0, otherwise use A' */ double alpha [2], /* scale factor for A */ double beta [2], /* scale factor for Y */ cholmod_dense *X, /* dense matrix to multiply */ /* ---- in/out --- */ cholmod_dense *Y, /* resulting dense matrix */ /* --------------- */ cholmod_common *Common ) { double *w ; size_t nx, ny ; Int e ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_NULL (X, FALSE) ; RETURN_IF_NULL (Y, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; RETURN_IF_XTYPE_INVALID (Y, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; ny = transpose ? A->ncol : A->nrow ; /* required length of Y */ nx = transpose ? A->nrow : A->ncol ; /* required length of X */ if (X->nrow != nx || X->ncol != Y->ncol || Y->nrow != ny) { /* X and/or Y have the wrong dimension */ ERROR (CHOLMOD_INVALID, "X and/or Y have wrong dimensions") ; return (FALSE) ; } if (A->xtype != X->xtype || A->xtype != Y->xtype) { ERROR (CHOLMOD_INVALID, "A, X, and Y must have same xtype") ; return (FALSE) ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate workspace, if required */ /* ---------------------------------------------------------------------- */ w = NULL ; e = (A->xtype == CHOLMOD_REAL ? 1:2) ; if (A->stype && X->ncol >= 4) { w = CHOLMOD(malloc) (nx, 4*e*sizeof (double), Common) ; } if (Common->status < CHOLMOD_OK) { return (FALSE) ; /* out of memory */ } /* ---------------------------------------------------------------------- */ /* Y = alpha*op(A)*X + beta*Y via template routine */ /* ---------------------------------------------------------------------- */ ASSERT (CHOLMOD(dump_sparse) (A, "A", Common) >= 0) ; DEBUG (CHOLMOD(dump_dense) (X, "X", Common)) ; DEBUG (if (IS_NONZERO (beta [0]) || (IS_NONZERO (beta [1]) && A->xtype != CHOLMOD_REAL)) CHOLMOD(dump_dense) (Y, "Y", Common)) ; switch (A->xtype) { case CHOLMOD_REAL: r_cholmod_sdmult (A, transpose, alpha, beta, X, Y, w) ; break ; case CHOLMOD_COMPLEX: c_cholmod_sdmult (A, transpose, alpha, beta, X, Y, w) ; break ; case CHOLMOD_ZOMPLEX: z_cholmod_sdmult (A, transpose, alpha, beta, X, Y, w) ; break ; } /* ---------------------------------------------------------------------- */ /* free workspace */ /* ---------------------------------------------------------------------- */ CHOLMOD(free) (4*nx, e*sizeof (double), w, Common) ; DEBUG (CHOLMOD(dump_dense) (Y, "Y", Common)) ; return (TRUE) ; } #endif #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/MatrixOps/cholmod_drop.c���������������������������������������������������������0000644�0001762�0000144�00000011545�13652535054�020153� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === MatrixOps/cholmod_drop =============================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/MatrixOps Module. Copyright (C) 2005-2006, Timothy A. Davis * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* Drop small entries from A, and entries in the ignored part of A if A * is symmetric. None of the matrix operations drop small numerical entries * from a matrix, except for this one. NaN's and Inf's are kept. * * workspace: none * * Supports pattern and real matrices, complex and zomplex not supported. */ #ifndef NGPL #ifndef NMATRIXOPS #include "cholmod_internal.h" #include "cholmod_matrixops.h" /* ========================================================================== */ /* === cholmod_drop ========================================================= */ /* ========================================================================== */ int CHOLMOD(drop) ( /* ---- input ---- */ double tol, /* keep entries with absolute value > tol */ /* ---- in/out --- */ cholmod_sparse *A, /* matrix to drop entries from */ /* --------------- */ cholmod_common *Common ) { double aij ; double *Ax ; Int *Ap, *Ai, *Anz ; Int packed, i, j, nrow, ncol, p, pend, nz, values ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_REAL, FALSE) ; Common->status = CHOLMOD_OK ; ASSERT (CHOLMOD(dump_sparse) (A, "A predrop", Common) >= 0) ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ Ap = A->p ; Ai = A->i ; Ax = A->x ; Anz = A->nz ; packed = A->packed ; ncol = A->ncol ; nrow = A->nrow ; values = (A->xtype != CHOLMOD_PATTERN) ; nz = 0 ; if (values) { /* ------------------------------------------------------------------ */ /* drop small numerical entries from A, and entries in ignored part */ /* ------------------------------------------------------------------ */ if (A->stype > 0) { /* -------------------------------------------------------------- */ /* A is symmetric, with just upper triangular part stored */ /* -------------------------------------------------------------- */ for (j = 0 ; j < ncol ; j++) { p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; Ap [j] = nz ; for ( ; p < pend ; p++) { i = Ai [p] ; aij = Ax [p] ; if (i <= j && (fabs (aij) > tol || IS_NAN (aij))) { Ai [nz] = i ; Ax [nz] = aij ; nz++ ; } } } } else if (A->stype < 0) { /* -------------------------------------------------------------- */ /* A is symmetric, with just lower triangular part stored */ /* -------------------------------------------------------------- */ for (j = 0 ; j < ncol ; j++) { p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; Ap [j] = nz ; for ( ; p < pend ; p++) { i = Ai [p] ; aij = Ax [p] ; if (i >= j && (fabs (aij) > tol || IS_NAN (aij))) { Ai [nz] = i ; Ax [nz] = aij ; nz++ ; } } } } else { /* -------------------------------------------------------------- */ /* both parts of A present, just drop small entries */ /* -------------------------------------------------------------- */ for (j = 0 ; j < ncol ; j++) { p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; Ap [j] = nz ; for ( ; p < pend ; p++) { i = Ai [p] ; aij = Ax [p] ; if (fabs (aij) > tol || IS_NAN (aij)) { Ai [nz] = i ; Ax [nz] = aij ; nz++ ; } } } } Ap [ncol] = nz ; /* reduce A->i and A->x in size */ ASSERT (MAX (1,nz) <= A->nzmax) ; CHOLMOD(reallocate_sparse) (nz, A, Common) ; ASSERT (Common->status >= CHOLMOD_OK) ; } else { /* ------------------------------------------------------------------ */ /* consider only the pattern of A */ /* ------------------------------------------------------------------ */ /* Note that cholmod_band_inplace calls cholmod_reallocate_sparse */ if (A->stype > 0) { CHOLMOD(band_inplace) (0, ncol, 0, A, Common) ; } else if (A->stype < 0) { CHOLMOD(band_inplace) (-nrow, 0, 0, A, Common) ; } } ASSERT (CHOLMOD(dump_sparse) (A, "A dropped", Common) >= 0) ; return (TRUE) ; } #endif #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/MatrixOps/t_cholmod_sdmult.c�����������������������������������������������������0000644�0001762�0000144�00000044275�14303636216�021044� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === MatrixOps/t_cholmod_sdmult =========================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/MatrixOps Module. Copyright (C) 2005-2006, Timothy A. Davis * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* Template routine for cholmod_sdmult */ #include "cholmod_template.h" #undef ADVANCE #ifdef REAL #define ADVANCE(x,z,d) x += d #elif defined (COMPLEX) #define ADVANCE(x,z,d) x += 2*d #else #define ADVANCE(x,z,d) x += d ; z += d #endif /* ========================================================================== */ /* === t_cholmod_sdmult ===================================================== */ /* ========================================================================== */ static void TEMPLATE (cholmod_sdmult) ( /* ---- input ---- */ cholmod_sparse *A, /* sparse matrix to multiply */ int transpose, /* use A if 0, or A' otherwise */ double alpha [2], /* scale factor for A */ double beta [2], /* scale factor for Y */ cholmod_dense *X, /* dense matrix to multiply */ /* ---- in/out --- */ cholmod_dense *Y, /* resulting dense matrix */ /* -- workspace -- */ double *W /* size 4*nx if needed, twice that for c/zomplex case */ ) { double yx [8], xx [8], ax [2] ; #ifdef ZOMPLEX double yz [4], xz [4], az [1] ; double betaz [1], alphaz [1] ; #endif double *Ax, *Az, *Xx, *Xz, *Yx, *Yz, *w, *Wz ; Int *Ap, *Ai, *Anz ; size_t nx, ny, dx, dy ; Int packed, nrow, ncol, j, k, p, pend, kcol, i ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ #ifdef ZOMPLEX betaz [0] = beta [1] ; alphaz [0] = alpha [1] ; #endif ny = transpose ? A->ncol : A->nrow ; /* required length of Y */ nx = transpose ? A->nrow : A->ncol ; /* required length of X */ nrow = A->nrow ; ncol = A->ncol ; Ap = A->p ; Anz = A->nz ; Ai = A->i ; Ax = A->x ; Az = A->z ; packed = A->packed ; Xx = X->x ; Xz = X->z ; Yx = Y->x ; Yz = Y->z ; kcol = X->ncol ; dy = Y->d ; dx = X->d ; if (A->stype != 0 && kcol >= 4) { w = W ; Wz = W + 4*nx ; } /* ---------------------------------------------------------------------- */ /* Y = beta * Y */ /* ---------------------------------------------------------------------- */ if (ENTRY_IS_ZERO (beta, betaz, 0)) { for (k = 0 ; k < kcol ; k++) { for (i = 0 ; i < ((Int) ny) ; i++) { /* y [i] = 0. ; */ CLEAR (Yx, Yz, i) ; } /* y += dy ; */ ADVANCE (Yx,Yz,dy) ; } } else if (!ENTRY_IS_ONE (beta, betaz, 0)) { for (k = 0 ; k < kcol ; k++) { for (i = 0 ; i < ((Int) ny) ; i++) { /* y [i] *= beta [0] ; */ MULT (Yx,Yz,i, Yx,Yz,i, beta,betaz, 0) ; } /* y += dy ; */ ADVANCE (Yx,Yz,dy) ; } } if (ENTRY_IS_ZERO (alpha, alphaz, 0)) { /* nothing else to do */ return ; } /* ---------------------------------------------------------------------- */ /* Y += alpha * op(A) * X, where op(A)=A or A' */ /* ---------------------------------------------------------------------- */ Yx = Y->x ; Yz = Y->z ; k = 0 ; if (A->stype == 0) { if (transpose) { /* -------------------------------------------------------------- */ /* Y += alpha * A' * x, unsymmetric case */ /* -------------------------------------------------------------- */ if (kcol % 4 == 1) { for (j = 0 ; j < ncol ; j++) { /* yj = 0. ; */ CLEAR (yx, yz, 0) ; p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { /* yj += conj(Ax [p]) * x [Ai [p]] ; */ i = Ai [p] ; ASSIGN_CONJ (ax,az,0, Ax,Az,p) ; MULTADD (yx,yz,0, ax,az,0, Xx,Xz,i) ; } /* y [j] += alpha [0] * yj ; */ MULTADD (Yx,Yz,j, alpha,alphaz,0, yx,yz,0) ; } /* y += dy ; */ /* x += dx ; */ ADVANCE (Yx,Yz,dy) ; ADVANCE (Xx,Xz,dx) ; k++ ; } else if (kcol % 4 == 2) { for (j = 0 ; j < ncol ; j++) { /* yj0 = 0. ; */ /* yj1 = 0. ; */ CLEAR (yx,yz,0) ; CLEAR (yx,yz,1) ; p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; /* aij = conj (Ax [p]) ; */ ASSIGN_CONJ (ax,az,0, Ax,Az,p) ; /* yj0 += aij * x [i ] ; */ /* yj1 += aij * x [i+dx] ; */ MULTADD (yx,yz,0, ax,az,0, Xx,Xz,i) ; MULTADD (yx,yz,1, ax,az,0, Xx,Xz,i+dx) ; } /* y [j ] += alpha [0] * yj0 ; */ /* y [j+dy] += alpha [0] * yj1 ; */ MULTADD (Yx,Yz,j, alpha,alphaz,0, yx,yz,0) ; MULTADD (Yx,Yz,j+dy, alpha,alphaz,0, yx,yz,1) ; } /* y += 2*dy ; */ /* x += 2*dx ; */ ADVANCE (Yx,Yz,2*dy) ; ADVANCE (Xx,Xz,2*dx) ; k += 2 ; } else if (kcol % 4 == 3) { for (j = 0 ; j < ncol ; j++) { /* yj0 = 0. ; */ /* yj1 = 0. ; */ /* yj2 = 0. ; */ CLEAR (yx,yz,0) ; CLEAR (yx,yz,1) ; CLEAR (yx,yz,2) ; p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; /* aij = conj (Ax [p]) ; */ ASSIGN_CONJ (ax,az,0, Ax,Az,p) ; /* yj0 += aij * x [i ] ; */ /* yj1 += aij * x [i+ dx] ; */ /* yj2 += aij * x [i+2*dx] ; */ MULTADD (yx,yz,0, ax,az,0, Xx,Xz,i) ; MULTADD (yx,yz,1, ax,az,0, Xx,Xz,i+dx) ; MULTADD (yx,yz,2, ax,az,0, Xx,Xz,i+2*dx) ; } /* y [j ] += alpha [0] * yj0 ; */ /* y [j+ dy] += alpha [0] * yj1 ; */ /* y [j+2*dy] += alpha [0] * yj2 ; */ MULTADD (Yx,Yz,j, alpha,alphaz,0, yx,yz,0) ; MULTADD (Yx,Yz,j+dy, alpha,alphaz,0, yx,yz,1) ; MULTADD (Yx,Yz,j+2*dy, alpha,alphaz,0, yx,yz,2) ; } /* y += 3*dy ; */ /* x += 3*dx ; */ ADVANCE (Yx,Yz,3*dy) ; ADVANCE (Xx,Xz,3*dx) ; k += 3 ; } for ( ; k < kcol ; k += 4) { for (j = 0 ; j < ncol ; j++) { /* yj0 = 0. ; */ /* yj1 = 0. ; */ /* yj2 = 0. ; */ /* yj3 = 0. ; */ CLEAR (yx,yz,0) ; CLEAR (yx,yz,1) ; CLEAR (yx,yz,2) ; CLEAR (yx,yz,3) ; p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; /* aij = conj(Ax [p]) ; */ ASSIGN_CONJ (ax,az,0, Ax,Az,p) ; /* yj0 += aij * x [i ] ; */ /* yj1 += aij * x [i+ dx] ; */ /* yj2 += aij * x [i+2*dx] ; */ /* yj3 += aij * x [i+3*dx] ; */ MULTADD (yx,yz,0, ax,az,0, Xx,Xz,i) ; MULTADD (yx,yz,1, ax,az,0, Xx,Xz,i+dx) ; MULTADD (yx,yz,2, ax,az,0, Xx,Xz,i+2*dx) ; MULTADD (yx,yz,3, ax,az,0, Xx,Xz,i+3*dx) ; } /* y [j ] += alpha [0] * yj0 ; */ /* y [j+ dy] += alpha [0] * yj1 ; */ /* y [j+2*dy] += alpha [0] * yj2 ; */ /* y [j+3*dy] += alpha [0] * yj3 ; */ MULTADD (Yx,Yz,j, alpha,alphaz,0, yx,yz,0) ; MULTADD (Yx,Yz,j+dy, alpha,alphaz,0, yx,yz,1) ; MULTADD (Yx,Yz,j+2*dy, alpha,alphaz,0, yx,yz,2) ; MULTADD (Yx,Yz,j+3*dy, alpha,alphaz,0, yx,yz,3) ; } /* y += 4*dy ; */ /* x += 4*dx ; */ ADVANCE (Yx,Yz,4*dy) ; ADVANCE (Xx,Xz,4*dx) ; } } else { /* -------------------------------------------------------------- */ /* Y += alpha * A * x, unsymmetric case */ /* -------------------------------------------------------------- */ if (kcol % 4 == 1) { for (j = 0 ; j < ncol ; j++) { /* xj = alpha [0] * x [j] ; */ MULT (xx,xz,0, alpha,alphaz,0, Xx,Xz,j) ; p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { /* y [Ai [p]] += Ax [p] * xj ; */ i = Ai [p] ; MULTADD (Yx,Yz,i, Ax,Az,p, xx,xz,0) ; } } /* y += dy ; */ /* x += dx ; */ ADVANCE (Yx,Yz,dy) ; ADVANCE (Xx,Xz,dx) ; k++ ; } else if (kcol % 4 == 2) { for (j = 0 ; j < ncol ; j++) { /* xj0 = alpha [0] * x [j ] ; */ /* xj1 = alpha [0] * x [j+dx] ; */ MULT (xx,xz,0, alpha,alphaz,0, Xx,Xz,j) ; MULT (xx,xz,1, alpha,alphaz,0, Xx,Xz,j+dx) ; p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; /* aij = Ax [p] ; */ ASSIGN (ax,az,0, Ax,Az,p) ; /* y [i ] += aij * xj0 ; */ /* y [i+dy] += aij * xj1 ; */ MULTADD (Yx,Yz,i, ax,az,0, xx,xz,0) ; MULTADD (Yx,Yz,i+dy, ax,az,0, xx,xz,1) ; } } /* y += 2*dy ; */ /* x += 2*dx ; */ ADVANCE (Yx,Yz,2*dy) ; ADVANCE (Xx,Xz,2*dx) ; k += 2 ; } else if (kcol % 4 == 3) { for (j = 0 ; j < ncol ; j++) { /* xj0 = alpha [0] * x [j ] ; */ /* xj1 = alpha [0] * x [j+ dx] ; */ /* xj2 = alpha [0] * x [j+2*dx] ; */ MULT (xx,xz,0, alpha,alphaz,0, Xx,Xz,j) ; MULT (xx,xz,1, alpha,alphaz,0, Xx,Xz,j+dx) ; MULT (xx,xz,2, alpha,alphaz,0, Xx,Xz,j+2*dx) ; p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; /* aij = Ax [p] ; */ ASSIGN (ax,az,0, Ax,Az,p) ; /* y [i ] += aij * xj0 ; */ /* y [i+ dy] += aij * xj1 ; */ /* y [i+2*dy] += aij * xj2 ; */ MULTADD (Yx,Yz,i, ax,az,0, xx,xz,0) ; MULTADD (Yx,Yz,i+dy, ax,az,0, xx,xz,1) ; MULTADD (Yx,Yz,i+2*dy, ax,az,0, xx,xz,2) ; } } /* y += 3*dy ; */ /* x += 3*dx ; */ ADVANCE (Yx,Yz,3*dy) ; ADVANCE (Xx,Xz,3*dx) ; k += 3 ; } for ( ; k < kcol ; k += 4) { for (j = 0 ; j < ncol ; j++) { /* xj0 = alpha [0] * x [j ] ; */ /* xj1 = alpha [0] * x [j+ dx] ; */ /* xj2 = alpha [0] * x [j+2*dx] ; */ /* xj3 = alpha [0] * x [j+3*dx] ; */ MULT (xx,xz,0, alpha,alphaz,0, Xx,Xz,j) ; MULT (xx,xz,1, alpha,alphaz,0, Xx,Xz,j+dx) ; MULT (xx,xz,2, alpha,alphaz,0, Xx,Xz,j+2*dx) ; MULT (xx,xz,3, alpha,alphaz,0, Xx,Xz,j+3*dx) ; p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; /* aij = Ax [p] ; */ ASSIGN (ax,az,0, Ax,Az,p) ; /* y [i ] += aij * xj0 ; */ /* y [i+ dy] += aij * xj1 ; */ /* y [i+2*dy] += aij * xj2 ; */ /* y [i+3*dy] += aij * xj3 ; */ MULTADD (Yx,Yz,i, ax,az,0, xx,xz,0) ; MULTADD (Yx,Yz,i+dy, ax,az,0, xx,xz,1) ; MULTADD (Yx,Yz,i+2*dy, ax,az,0, xx,xz,2) ; MULTADD (Yx,Yz,i+3*dy, ax,az,0, xx,xz,3) ; } } /* y += 4*dy ; */ /* x += 4*dx ; */ ADVANCE (Yx,Yz,4*dy) ; ADVANCE (Xx,Xz,4*dx) ; } } } else { /* ------------------------------------------------------------------ */ /* Y += alpha * (A or A') * x, symmetric case (upper/lower) */ /* ------------------------------------------------------------------ */ /* Only the upper/lower triangular part and the diagonal of A is used. * Since both x and y are written to in the innermost loop, this * code can experience cache bank conflicts if x is used directly. * Thus, a copy is made of x, four columns at a time, if x has * four or more columns. */ if (kcol % 4 == 1) { for (j = 0 ; j < ncol ; j++) { /* yj = 0. ; */ CLEAR (yx,yz,0) ; /* xj = alpha [0] * x [j] ; */ MULT (xx,xz,0, alpha,alphaz,0, Xx,Xz,j) ; p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; if (i == j) { /* y [i] += Ax [p] * xj ; */ MULTADD (Yx,Yz,i, Ax,Az,p, xx,xz,0) ; } else if ((A->stype > 0 && i < j) || (A->stype < 0 && i > j)) { /* aij = Ax [p] ; */ ASSIGN (ax,az,0, Ax,Az,p) ; /* y [i] += aij * xj ; */ /* yj += aij * x [i] ; */ MULTADD (Yx,Yz,i, ax,az,0, xx,xz,0) ; MULTADDCONJ (yx,yz,0, ax,az,0, Xx,Xz,i) ; } } /* y [j] += alpha [0] * yj ; */ MULTADD (Yx,Yz,j, alpha,alphaz,0, yx,yz,0) ; } /* y += dy ; */ /* x += dx ; */ ADVANCE (Yx,Yz,dy) ; ADVANCE (Xx,Xz,dx) ; k++ ; } else if (kcol % 4 == 2) { for (j = 0 ; j < ncol ; j++) { /* yj0 = 0. ; */ /* yj1 = 0. ; */ CLEAR (yx,yz,0) ; CLEAR (yx,yz,1) ; /* xj0 = alpha [0] * x [j ] ; */ /* xj1 = alpha [0] * x [j+dx] ; */ MULT (xx,xz,0, alpha,alphaz,0, Xx,Xz,j) ; MULT (xx,xz,1, alpha,alphaz,0, Xx,Xz,j+dx) ; p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; if (i == j) { /* aij = Ax [p] ; */ ASSIGN (ax,az,0, Ax,Az,p) ; /* y [i ] += aij * xj0 ; */ /* y [i+dy] += aij * xj1 ; */ MULTADD (Yx,Yz,i, ax,az,0, xx,xz,0) ; MULTADD (Yx,Yz,i+dy, ax,az,0, xx,xz,1) ; } else if ((A->stype > 0 && i < j) || (A->stype < 0 && i > j)) { /* aij = Ax [p] ; */ ASSIGN (ax,az,0, Ax,Az,p) ; /* y [i ] += aij * xj0 ; */ /* y [i+dy] += aij * xj1 ; */ /* yj0 += aij * x [i ] ; */ /* yj1 += aij * x [i+dx] ; */ MULTADD (Yx,Yz,i, ax,az,0, xx,xz,0) ; MULTADD (Yx,Yz,i+dy, ax,az,0, xx,xz,1) ; MULTADDCONJ (yx,yz,0, ax,az,0, Xx,Xz,i) ; MULTADDCONJ (yx,yz,1, ax,az,0, Xx,Xz,i+dx) ; } } /* y [j ] += alpha [0] * yj0 ; */ /* y [j+dy] += alpha [0] * yj1 ; */ MULTADD (Yx,Yz,j, alpha,alphaz,0, yx,yz,0) ; MULTADD (Yx,Yz,j+dy, alpha,alphaz,0, yx,yz,1) ; } /* y += 2*dy ; */ /* x += 2*dx ; */ ADVANCE (Yx,Yz,2*dy) ; ADVANCE (Xx,Xz,2*dx) ; k += 2 ; } else if (kcol % 4 == 3) { for (j = 0 ; j < ncol ; j++) { /* yj0 = 0. ; */ /* yj1 = 0. ; */ /* yj2 = 0. ; */ CLEAR (yx,yz,0) ; CLEAR (yx,yz,1) ; CLEAR (yx,yz,2) ; /* xj0 = alpha [0] * x [j ] ; */ /* xj1 = alpha [0] * x [j+ dx] ; */ /* xj2 = alpha [0] * x [j+2*dx] ; */ MULT (xx,xz,0, alpha,alphaz,0, Xx,Xz,j) ; MULT (xx,xz,1, alpha,alphaz,0, Xx,Xz,j+dx) ; MULT (xx,xz,2, alpha,alphaz,0, Xx,Xz,j+2*dx) ; p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; if (i == j) { /* aij = Ax [p] ; */ ASSIGN (ax,az,0, Ax,Az,p) ; /* y [i ] += aij * xj0 ; */ /* y [i+ dy] += aij * xj1 ; */ /* y [i+2*dy] += aij * xj2 ; */ MULTADD (Yx,Yz,i, ax,az,0, xx,xz,0) ; MULTADD (Yx,Yz,i+dy, ax,az,0, xx,xz,1) ; MULTADD (Yx,Yz,i+2*dy, ax,az,0, xx,xz,2) ; } else if ((A->stype > 0 && i < j) || (A->stype < 0 && i > j)) { /* aij = Ax [p] ; */ ASSIGN (ax,az,0, Ax,Az,p) ; /* y [i ] += aij * xj0 ; */ /* y [i+ dy] += aij * xj1 ; */ /* y [i+2*dy] += aij * xj2 ; */ /* yj0 += aij * x [i ] ; */ /* yj1 += aij * x [i+ dx] ; */ /* yj2 += aij * x [i+2*dx] ; */ MULTADD (Yx,Yz,i, ax,az,0, xx,xz,0) ; MULTADD (Yx,Yz,i+dy, ax,az,0, xx,xz,1) ; MULTADD (Yx,Yz,i+2*dy, ax,az,0, xx,xz,2) ; MULTADDCONJ (yx,yz,0, ax,az,0, Xx,Xz,i) ; MULTADDCONJ (yx,yz,1, ax,az,0, Xx,Xz,i+dx) ; MULTADDCONJ (yx,yz,2, ax,az,0, Xx,Xz,i+2*dx) ; } } /* y [j ] += alpha [0] * yj0 ; */ /* y [j+ dy] += alpha [0] * yj1 ; */ /* y [j+2*dy] += alpha [0] * yj2 ; */ MULTADD (Yx,Yz,j, alpha,alphaz,0, yx,yz,0) ; MULTADD (Yx,Yz,j+dy, alpha,alphaz,0, yx,yz,1) ; MULTADD (Yx,Yz,j+2*dy, alpha,alphaz,0, yx,yz,2) ; } /* y += 3*dy ; */ /* x += 3*dx ; */ ADVANCE (Yx,Yz,3*dy) ; ADVANCE (Xx,Xz,3*dx) ; k += 3 ; } /* copy four columns of X into W, and put in row form */ for ( ; k < kcol ; k += 4) { for (j = 0 ; j < ncol ; j++) { /* w [4*j ] = x [j ] ; */ /* w [4*j+1] = x [j+ dx] ; */ /* w [4*j+2] = x [j+2*dx] ; */ /* w [4*j+3] = x [j+3*dx] ; */ ASSIGN (w,Wz,4*j , Xx,Xz,j ) ; ASSIGN (w,Wz,4*j+1, Xx,Xz,j+dx ) ; ASSIGN (w,Wz,4*j+2, Xx,Xz,j+2*dx) ; ASSIGN (w,Wz,4*j+3, Xx,Xz,j+3*dx) ; } for (j = 0 ; j < ncol ; j++) { /* yj0 = 0. ; */ /* yj1 = 0. ; */ /* yj2 = 0. ; */ /* yj3 = 0. ; */ CLEAR (yx,yz,0) ; CLEAR (yx,yz,1) ; CLEAR (yx,yz,2) ; CLEAR (yx,yz,3) ; /* xj0 = alpha [0] * w [4*j ] ; */ /* xj1 = alpha [0] * w [4*j+1] ; */ /* xj2 = alpha [0] * w [4*j+2] ; */ /* xj3 = alpha [0] * w [4*j+3] ; */ MULT (xx,xz,0, alpha,alphaz,0, w,Wz,4*j) ; MULT (xx,xz,1, alpha,alphaz,0, w,Wz,4*j+1) ; MULT (xx,xz,2, alpha,alphaz,0, w,Wz,4*j+2) ; MULT (xx,xz,3, alpha,alphaz,0, w,Wz,4*j+3) ; p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; if (i == j) { /* aij = Ax [p] ; */ ASSIGN (ax,az,0, Ax,Az,p) ; /* y [i ] += aij * xj0 ; */ /* y [i+ dy] += aij * xj1 ; */ /* y [i+2*dy] += aij * xj2 ; */ /* y [i+3*dy] += aij * xj3 ; */ MULTADD (Yx,Yz,i , ax,az,0, xx,xz,0) ; MULTADD (Yx,Yz,i+dy , ax,az,0, xx,xz,1) ; MULTADD (Yx,Yz,i+2*dy, ax,az,0, xx,xz,2) ; MULTADD (Yx,Yz,i+3*dy, ax,az,0, xx,xz,3) ; } else if ((A->stype > 0 && i < j) || (A->stype < 0 && i > j)) { /* aij = Ax [p] ; */ ASSIGN (ax,az,0, Ax,Az,p) ; /* y [i ] += aij * xj0 ; */ /* y [i+ dy] += aij * xj1 ; */ /* y [i+2*dy] += aij * xj2 ; */ /* y [i+3*dy] += aij * xj3 ; */ /* yj0 += aij * w [4*i ] ; */ /* yj1 += aij * w [4*i+1] ; */ /* yj2 += aij * w [4*i+2] ; */ /* yj3 += aij * w [4*i+3] ; */ MULTADD (Yx,Yz,i, ax,az,0, xx,xz,0) ; MULTADD (Yx,Yz,i+dy, ax,az,0, xx,xz,1) ; MULTADD (Yx,Yz,i+2*dy, ax,az,0, xx,xz,2) ; MULTADD (Yx,Yz,i+3*dy, ax,az,0, xx,xz,3) ; MULTADDCONJ (yx,yz,0, ax,az,0, w,Wz,4*i) ; MULTADDCONJ (yx,yz,1, ax,az,0, w,Wz,4*i+1) ; MULTADDCONJ (yx,yz,2, ax,az,0, w,Wz,4*i+2) ; MULTADDCONJ (yx,yz,3, ax,az,0, w,Wz,4*i+3) ; } } /* y [j ] += alpha [0] * yj0 ; */ /* y [j+ dy] += alpha [0] * yj1 ; */ /* y [j+2*dy] += alpha [0] * yj2 ; */ /* y [j+3*dy] += alpha [0] * yj3 ; */ MULTADD (Yx,Yz,j , alpha,alphaz,0, yx,yz,0) ; MULTADD (Yx,Yz,j+dy , alpha,alphaz,0, yx,yz,1) ; MULTADD (Yx,Yz,j+2*dy, alpha,alphaz,0, yx,yz,2) ; MULTADD (Yx,Yz,j+3*dy, alpha,alphaz,0, yx,yz,3) ; } /* y += 4*dy ; */ /* x += 4*dx ; */ ADVANCE (Yx,Yz,4*dy) ; ADVANCE (Xx,Xz,4*dx) ; } } } #undef PATTERN #undef REAL #undef COMPLEX #undef ZOMPLEX �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/MatrixOps/cholmod_submatrix.c����������������������������������������������������0000644�0001762�0000144�00000031334�13652535054�021223� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === MatrixOps/cholmod_submatrix ========================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/MatrixOps Module. Copyright (C) 2005-2006, Timothy A. Davis * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* C = A (rset,cset), where C becomes length(rset)-by-length(cset) in dimension. * rset and cset can have duplicate entries. A and C must be unsymmetric. C * is packed. If the sorted flag is TRUE on input, or rset is sorted and A is * sorted, then C is sorted; otherwise C is unsorted. * * A NULL rset or cset means "[ ]" in MATLAB notation. * If the length of rset or cset is negative, it denotes ":" in MATLAB notation. * * For permuting a matrix, this routine is an alternative to cholmod_ptranspose * (which permutes and transposes a matrix and can work on symmetric matrices). * * The time taken by this routine is O(A->nrow) if the Common workspace needs * to be initialized, plus O(C->nrow + C->ncol + nnz (A (:,cset))). Thus, if C * is small and the workspace is not initialized, the time can be dominated by * the call to cholmod_allocate_work. However, once the workspace is * allocated, subsequent calls take less time. * * workspace: Iwork (max (A->nrow + length (rset), length (cset))). * allocates temporary copy of C if it is to be returned sorted. * * Future work: A common case occurs where A has sorted columns, and rset is in * the form lo:hi in MATLAB notation. This routine could exploit that case * to run even faster when the matrix is sorted, particularly when lo is small. * * Only pattern and real matrices are supported. Complex and zomplex matrices * are supported only when "values" is FALSE. */ #ifndef NGPL #ifndef NMATRIXOPS #include "cholmod_internal.h" #include "cholmod_matrixops.h" /* ========================================================================== */ /* === check_subset ========================================================= */ /* ========================================================================== */ /* Check the rset or cset, and return TRUE if valid, FALSE if invalid */ static int check_subset (Int *set, Int len, Int n) { Int k ; if (set == NULL) { return (TRUE) ; } for (k = 0 ; k < len ; k++) { if (set [k] < 0 || set [k] >= n) { return (FALSE) ; } } return (TRUE) ; } /* ========================================================================== */ /* === cholmod_submatrix ==================================================== */ /* ========================================================================== */ cholmod_sparse *CHOLMOD(submatrix) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to subreference */ Int *rset, /* set of row indices, duplicates OK */ SuiteSparse_long rsize, /* size of rset, or -1 for ":" */ Int *cset, /* set of column indices, duplicates OK */ SuiteSparse_long csize, /* size of cset, or -1 for ":" */ int values, /* if TRUE compute the numerical values of C */ int sorted, /* if TRUE then return C with sorted columns */ /* --------------- */ cholmod_common *Common ) { double aij = 0 ; double *Ax, *Cx ; Int *Ap, *Ai, *Anz, *Ci, *Cp, *Head, *Rlen, *Rnext, *Iwork ; cholmod_sparse *C ; Int packed, ancol, anrow, cnrow, cncol, nnz, i, j, csorted, ilast, p, pend, pdest, ci, cj, head, nr, nc ; size_t s ; int ok = TRUE ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (A, NULL) ; values = (values && (A->xtype != CHOLMOD_PATTERN)) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, values ? CHOLMOD_REAL : CHOLMOD_ZOMPLEX, NULL) ; if (A->stype != 0) { /* A must be unsymmetric */ ERROR (CHOLMOD_INVALID, "symmetric upper or lower case not supported") ; return (NULL) ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ ancol = A->ncol ; anrow = A->nrow ; nr = rsize ; nc = csize ; if (rset == NULL) { /* nr = 0 denotes rset = [ ], nr < 0 denotes rset = 0:anrow-1 */ nr = (nr < 0) ? (-1) : 0 ; } if (cset == NULL) { /* nr = 0 denotes cset = [ ], nr < 0 denotes cset = 0:ancol-1 */ nc = (nc < 0) ? (-1) : 0 ; } cnrow = (nr < 0) ? anrow : nr ; /* negative rset means rset = 0:anrow-1 */ cncol = (nc < 0) ? ancol : nc ; /* negative cset means cset = 0:ancol-1 */ if (nr < 0 && nc < 0) { /* ------------------------------------------------------------------ */ /* C = A (:,:), use cholmod_copy instead */ /* ------------------------------------------------------------------ */ /* workspace: Iwork (max (C->nrow,C->ncol)) */ PRINT1 (("submatrix C = A (:,:)\n")) ; C = CHOLMOD(copy) (A, 0, values, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ return (NULL) ; } return (C) ; } PRINT1 (("submatrix nr "ID" nc "ID" Cnrow "ID" Cncol "ID"" " Anrow "ID" Ancol "ID"\n", nr, nc, cnrow, cncol, anrow, ancol)) ; /* s = MAX3 (anrow+MAX(0,nr), cncol, cnrow) ; */ s = CHOLMOD(add_size_t) (anrow, MAX (0,nr), &ok) ; if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (NULL) ; } s = MAX3 (s, ((size_t) cncol), ((size_t) cnrow)) ; CHOLMOD(allocate_work) (anrow, s, 0, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ return (NULL) ; } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ Ap = A->p ; Anz = A->nz ; Ai = A->i ; Ax = A->x ; packed = A->packed ; /* ---------------------------------------------------------------------- */ /* get workspace */ /* ---------------------------------------------------------------------- */ Head = Common->Head ; /* size anrow */ Iwork = Common->Iwork ; Rlen = Iwork ; /* size anrow (i/i/l) */ Rnext = Iwork + anrow ; /* size nr (i/i/l), not used if nr < 0 */ /* ---------------------------------------------------------------------- */ /* construct inverse of rset and compute nnz (C) */ /* ---------------------------------------------------------------------- */ PRINT1 (("nr "ID" nc "ID"\n", nr, nc)) ; PRINT1 (("anrow "ID" ancol "ID"\n", anrow, ancol)) ; PRINT1 (("cnrow "ID" cncol "ID"\n", cnrow, cncol)) ; DEBUG (for (i = 0 ; i < nr ; i++) PRINT2 (("rset ["ID"] = "ID"\n", i, rset [i]))); DEBUG (for (i = 0 ; i < nc ; i++) PRINT2 (("cset ["ID"] = "ID"\n", i, cset [i]))); /* C is sorted if A and rset are sorted, or if C has one row or less */ csorted = A->sorted || (cnrow <= 1) ; if (!check_subset (rset, nr, anrow)) { ERROR (CHOLMOD_INVALID, "invalid rset") ; return (NULL) ; } if (!check_subset (cset, nc, ancol)) { ERROR (CHOLMOD_INVALID, "invalid cset") ; return (NULL) ; } nnz = 0 ; if (nr < 0) { /* C = A (:,cset) where cset = [ ] or cset is not empty */ ASSERT (IMPLIES (cncol > 0, cset != NULL)) ; for (cj = 0 ; cj < cncol ; cj++) { /* construct column cj of C, which is column j of A */ j = cset [cj] ; nnz += (packed) ? (Ap [j+1] - Ap [j]) : MAX (0, Anz [j]) ; } } else { /* C = A (rset,cset), where rset is not empty but cset might be empty */ /* create link lists in reverse order to preserve natural order */ ilast = anrow ; for (ci = nr-1 ; ci >= 0 ; ci--) { /* row i of A becomes row ci of C; add ci to ith link list */ i = rset [ci] ; head = Head [i] ; Rlen [i] = (head == EMPTY) ? 1 : (Rlen [i] + 1) ; Rnext [ci] = head ; Head [i] = ci ; if (i > ilast) { /* row indices in columns of C will not be sorted */ csorted = FALSE ; } ilast = i ; } #ifndef NDEBUG for (i = 0 ; i < anrow ; i++) { Int k = 0 ; Int rlen = (Head [i] != EMPTY) ? Rlen [i] : -1 ; PRINT1 (("Row "ID" Rlen "ID": ", i, rlen)) ; for (ci = Head [i] ; ci != EMPTY ; ci = Rnext [ci]) { k++ ; PRINT2 ((""ID" ", ci)) ; } PRINT1 (("\n")) ; ASSERT (IMPLIES (Head [i] != EMPTY, k == Rlen [i])) ; } #endif /* count nonzeros in C */ for (cj = 0 ; cj < cncol ; cj++) { /* count rows in column cj of C, which is column j of A */ j = (nc < 0) ? cj : (cset [cj]) ; p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { /* row i of A becomes multiple rows (ci) of C */ i = Ai [p] ; ASSERT (i >= 0 && i < anrow) ; if (Head [i] != EMPTY) { nnz += Rlen [i] ; } } } } PRINT1 (("nnz (C) "ID"\n", nnz)) ; /* rset and cset are now valid */ DEBUG (CHOLMOD(dump_subset) (rset, rsize, anrow, "rset", Common)) ; DEBUG (CHOLMOD(dump_subset) (cset, csize, ancol, "cset", Common)) ; /* ---------------------------------------------------------------------- */ /* allocate C */ /* ---------------------------------------------------------------------- */ C = CHOLMOD(allocate_sparse) (cnrow, cncol, nnz, csorted, TRUE, 0, values ? A->xtype : CHOLMOD_PATTERN, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ for (i = 0 ; i < anrow ; i++) { Head [i] = EMPTY ; } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; return (NULL) ; } Cp = C->p ; Ci = C->i ; Cx = C->x ; /* ---------------------------------------------------------------------- */ /* C = A (rset,cset) */ /* ---------------------------------------------------------------------- */ pdest = 0 ; if (nnz == 0) { /* C has no nonzeros */ for (cj = 0 ; cj <= cncol ; cj++) { Cp [cj] = 0 ; } } else if (nr < 0) { /* C = A (:,cset), where cset is not empty */ for (cj = 0 ; cj < cncol ; cj++) { /* construct column cj of C, which is column j of A */ PRINT1 (("construct cj = j = "ID"\n", cj)) ; j = cset [cj] ; Cp [cj] = pdest ; p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { Ci [pdest] = Ai [p] ; if (values) { Cx [pdest] = Ax [p] ; } pdest++ ; ASSERT (pdest <= nnz) ; } } } else { /* C = A (rset,cset), where rset is not empty but cset might be empty */ for (cj = 0 ; cj < cncol ; cj++) { /* construct column cj of C, which is column j of A */ PRINT1 (("construct cj = "ID"\n", cj)) ; j = (nc < 0) ? cj : (cset [cj]) ; PRINT1 (("cj = "ID"\n", j)) ; Cp [cj] = pdest ; p = Ap [j] ; pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { /* row (Ai [p]) of A becomes multiple rows (ci) of C */ PRINT2 (("i: "ID" becomes: ", Ai [p])) ; if (values) { aij = Ax [p] ; } for (ci = Head [Ai [p]] ; ci != EMPTY ; ci = Rnext [ci]) { PRINT3 ((""ID" ", ci)) ; Ci [pdest] = ci ; if (values) { Cx [pdest] = aij ; } pdest++ ; ASSERT (pdest <= nnz) ; } PRINT2 (("\n")) ; } } } Cp [cncol] = pdest ; ASSERT (nnz == pdest) ; /* ---------------------------------------------------------------------- */ /* clear workspace */ /* ---------------------------------------------------------------------- */ for (ci = 0 ; ci < nr ; ci++) { Head [rset [ci]] = EMPTY ; } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; /* ---------------------------------------------------------------------- */ /* sort C, if requested */ /* ---------------------------------------------------------------------- */ ASSERT (CHOLMOD(dump_sparse) (C , "C before sort", Common) >= 0) ; if (sorted && !csorted) { /* workspace: Iwork (max (C->nrow,C->ncol)) */ if (!CHOLMOD(sort) (C, Common)) { /* out of memory */ CHOLMOD(free_sparse) (&C, Common) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; return (NULL) ; } } /* ---------------------------------------------------------------------- */ /* return result */ /* ---------------------------------------------------------------------- */ ASSERT (CHOLMOD(dump_sparse) (C , "Final C", Common) >= 0) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; return (C) ; } #endif #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Makefile�������������������������������������������������������������������������0000644�0001762�0000144�00000001223�14547724215�015043� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#------------------------------------------------------------------------------- # CHOLMOD Makefile #------------------------------------------------------------------------------- .PHONY : default all library purge clean distclean ccode default: all # Compile the C-callable libraries and the Demo programs. all: ( cd Lib ; $(MAKE) ) # Compile the C-callable libraries only. library: ( cd Lib ; $(MAKE) ) # Remove all files not in the original distribution purge: ( cd Lib ; $(MAKE) purge ) # Remove all files not in the original distribution, except keep the # compiled libraries. clean: ( cd Lib ; $(MAKE) clean ) distclean: purge ccode: all �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Partition/�����������������������������������������������������������������������0000755�0001762�0000144�00000000000�14547723665�015366� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Partition/cholmod_nesdis.c�������������������������������������������������������0000644�0001762�0000144�00000206461�13652535054�020522� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Partition/cholmod_nesdis ============================================= */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Partition Module. * Copyright (C) 2005-2006, Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* CHOLMOD nested dissection and graph partitioning. * * cholmod_bisect: * * Finds a set of nodes that partitions the graph into two parts. * Compresses the graph first. Requires METIS. * * cholmod_nested_dissection: * * Nested dissection, using its own compression and connected-commponents * algorithms, an external graph partitioner (METIS), and a constrained * minimum degree ordering algorithm (CCOLAMD or CSYMAMD). Typically * gives better orderings than METIS_NodeND (about 5% to 10% fewer * nonzeros in L). * * cholmod_collapse_septree: * * Prune the separator tree returned by cholmod_nested_dissection. * * This file contains several routines private to this file: * * partition compress and partition a graph * clear_flag clear Common->Flag, but do not modify negative entries * find_components find the connected components of a graph * * Supports any xtype (pattern, real, complex, or zomplex). */ #ifndef NPARTITION #include "cholmod_internal.h" #include "cholmod_partition.h" #include "cholmod_cholesky.h" /* ========================================================================== */ /* === partition ============================================================ */ /* ========================================================================== */ /* Find a set of nodes that partition a graph. The graph must be symmetric * with no diagonal entries. To compress the graph first, compress is TRUE * and on input Hash [j] holds the hash key for node j, which must be in the * range 0 to csize-1. The input graph (Cp, Ci) is destroyed. Cew is all 1's * on input and output. Cnw [j] > 0 is the initial weight of node j. On * output, Cnw [i] = 0 if node i is absorbed into j and the original weight * Cnw [i] is added to Cnw [j]. If compress is FALSE, the graph is not * compressed and Cnw and Hash are unmodified. The partition itself is held in * the output array Part of size n. Part [j] is 0, 1, or 2, depending on * whether node j is in the left part of the graph, the right part, or the * separator, respectively. Note that the input graph need not be connected, * and the output subgraphs (the three parts) may also be unconnected. * * Returns the size of the separator, in terms of the sum of the weights of * the nodes. It is guaranteed to be between 1 and the total weight of all * the nodes. If it is of size less than the total weight, then both the left * and right parts are guaranteed to be non-empty (this guarantee depends on * cholmod_metis_bisector). */ static SuiteSparse_long partition /* size of separator or -1 if failure */ ( /* inputs, not modified on output */ #ifndef NDEBUG Int csize, /* upper bound on # of edges in the graph; * csize >= MAX (n, nnz(C)) must hold. */ #endif int compress, /* if TRUE the compress the graph first */ /* input/output */ Int Hash [ ], /* Hash [i] = hash >= 0 is the hash function for node * i on input. On output, Hash [i] = FLIP (j) if node * i is absorbed into j. Hash [i] >= 0 if i has not * been absorbed. */ /* input graph, compressed graph of cn nodes on output */ cholmod_sparse *C, /* input/output */ Int Cnw [ ], /* size n. Cnw [j] > 0 is the weight of node j on * input. On output, if node i is absorbed into * node j, then Cnw [i] = 0 and the original weight of * node i is added to Cnw [j]. The sum of Cnw [0..n-1] * is not modified. */ /* workspace */ Int Cew [ ], /* size csize, all 1's on input and output */ /* more workspace, undefined on input and output */ Int Cmap [ ], /* size n (i/i/l) */ /* output */ Int Part [ ], /* size n, Part [j] = 0, 1, or 2. */ cholmod_common *Common ) { Int n, hash, head, i, j, k, p, pend, ilen, ilast, pi, piend, jlen, ok, cn, csep, pdest, nodes_pruned, nz, total_weight, jscattered ; Int *Cp, *Ci, *Next, *Hhead ; #ifndef NDEBUG Int cnt, pruned ; double work = 0, goodwork = 0 ; #endif /* ---------------------------------------------------------------------- */ /* quick return for small or empty graphs */ /* ---------------------------------------------------------------------- */ n = C->nrow ; Cp = C->p ; Ci = C->i ; nz = Cp [n] ; PRINT2 (("Partition start, n "ID" nz "ID"\n", n, nz)) ; total_weight = 0 ; for (j = 0 ; j < n ; j++) { ASSERT (Cnw [j] > 0) ; total_weight += Cnw [j] ; } if (n <= 2) { /* very small graph */ for (j = 0 ; j < n ; j++) { Part [j] = 2 ; } return (total_weight) ; } else if (nz <= 0) { /* no edges, this is easy */ PRINT2 (("diagonal matrix\n")) ; k = n/2 ; for (j = 0 ; j < k ; j++) { Part [j] = 0 ; } for ( ; j < n ; j++) { Part [j] = 1 ; } /* ensure the separator is not empty (required by nested dissection) */ Part [n-1] = 2 ; return (Cnw [n-1]) ; } #ifndef NDEBUG ASSERT (n > 1 && nz > 0) ; PRINT2 (("original graph:\n")) ; for (j = 0 ; j < n ; j++) { PRINT2 ((""ID": ", j)) ; for (p = Cp [j] ; p < Cp [j+1] ; p++) { i = Ci [p] ; PRINT3 ((""ID" ", i)) ; ASSERT (i >= 0 && i < n && i != j) ; } PRINT2 (("hash: "ID"\n", Hash [j])) ; } DEBUG (for (p = 0 ; p < csize ; p++) ASSERT (Cew [p] == 1)) ; #endif nodes_pruned = 0 ; if (compress) { /* ------------------------------------------------------------------ */ /* get workspace */ /* ------------------------------------------------------------------ */ Next = Part ; /* use Part as workspace for Next [ */ Hhead = Cew ; /* use Cew as workspace for Hhead [ */ /* ------------------------------------------------------------------ */ /* create the hash buckets */ /* ------------------------------------------------------------------ */ for (j = 0 ; j < n ; j++) { /* get the hash key for node j */ hash = Hash [j] ; ASSERT (hash >= 0 && hash < csize) ; head = Hhead [hash] ; if (head > EMPTY) { /* hash bucket for this hash key is empty. */ head = EMPTY ; } else { /* hash bucket for this hash key is not empty. get old head */ head = FLIP (head) ; ASSERT (head >= 0 && head < n) ; } /* node j becomes the new head of the hash bucket. FLIP it so that * we can tell the difference between an empty or non-empty hash * bucket. */ Hhead [hash] = FLIP (j) ; Next [j] = head ; ASSERT (head >= EMPTY && head < n) ; } #ifndef NDEBUG for (cnt = 0, k = 0 ; k < n ; k++) { ASSERT (Hash [k] >= 0 && Hash [k] < csize) ; /* k is alive */ hash = Hash [k] ; ASSERT (hash >= 0 && hash < csize) ; head = Hhead [hash] ; ASSERT (head < EMPTY) ; /* hash bucket not empty */ j = FLIP (head) ; ASSERT (j >= 0 && j < n) ; if (j == k) { PRINT2 (("hash "ID": ", hash)) ; for ( ; j != EMPTY ; j = Next [j]) { PRINT3 ((" "ID"", j)) ; ASSERT (j >= 0 && j < n) ; ASSERT (Hash [j] == hash) ; cnt++ ; ASSERT (cnt <= n) ; } PRINT2 (("\n")) ; } } ASSERT (cnt == n) ; #endif /* ------------------------------------------------------------------ */ /* scan the non-empty hash buckets for indistinguishable nodes */ /* ------------------------------------------------------------------ */ /* If there are no hash collisions and no compression occurs, this takes * O(n) time. If no hash collisions, but some nodes are removed, this * takes time O(n+e) where e is the sum of the degress of the nodes * that are removed. Even with many hash collisions (a rare case), * this algorithm has never been observed to perform more than nnz(A) * useless work. * * Cmap is used as workspace to mark nodes of the graph, [ * for comparing the nonzero patterns of two nodes i and j. */ #define Cmap_MARK(i) Cmap [i] = j #define Cmap_MARKED(i) (Cmap [i] == j) for (i = 0 ; i < n ; i++) { Cmap [i] = EMPTY ; } for (k = 0 ; k < n ; k++) { hash = Hash [k] ; ASSERT (hash >= FLIP (n-1) && hash < csize) ; if (hash < 0) { /* node k has already been absorbed into some other node */ ASSERT (FLIP (Hash [k]) >= 0 && FLIP (Hash [k] < n)) ; continue ; } head = Hhead [hash] ; ASSERT (head < EMPTY || head == 1) ; if (head == 1) { /* hash bucket is already empty */ continue ; } PRINT2 (("\n--------------------hash "ID":\n", hash)) ; for (j = FLIP (head) ; j != EMPTY && Next[j] > EMPTY ; j = Next [j]) { /* compare j with all nodes i following it in hash bucket */ ASSERT (j >= 0 && j < n && Hash [j] == hash) ; p = Cp [j] ; pend = Cp [j+1] ; jlen = pend - p ; jscattered = FALSE ; DEBUG (for (i = 0 ; i < n ; i++) ASSERT (!Cmap_MARKED (i))) ; DEBUG (pruned = FALSE) ; ilast = j ; for (i = Next [j] ; i != EMPTY ; i = Next [i]) { ASSERT (i >= 0 && i < n && Hash [i] == hash && i != j) ; pi = Cp [i] ; piend = Cp [i+1] ; ilen = piend - pi ; DEBUG (work++) ; if (ilen != jlen) { /* i and j have different degrees */ ilast = i ; continue ; } /* scatter the pattern of node j, if not already */ if (!jscattered) { Cmap_MARK (j) ; for ( ; p < pend ; p++) { Cmap_MARK (Ci [p]) ; } jscattered = TRUE ; DEBUG (work += jlen) ; } for (ok = Cmap_MARKED (i) ; ok && pi < piend ; pi++) { ok = Cmap_MARKED (Ci [pi]) ; DEBUG (work++) ; } if (ok) { /* found it. kill node i and merge it into j */ PRINT2 (("found "ID" absorbed into "ID"\n", i, j)) ; Hash [i] = FLIP (j) ; Cnw [j] += Cnw [i] ; Cnw [i] = 0 ; ASSERT (ilast != i && ilast >= 0 && ilast < n) ; Next [ilast] = Next [i] ; /* delete i from bucket */ nodes_pruned++ ; DEBUG (goodwork += (ilen+1)) ; DEBUG (pruned = TRUE) ; } else { /* i and j are different */ ilast = i ; } } DEBUG (if (pruned) goodwork += jlen) ; } /* empty the hash bucket, restoring Cew */ Hhead [hash] = 1 ; } DEBUG (if (((work - goodwork) / (double) nz) > 0.20) PRINT0 (( "work %12g good %12g nz %12g (wasted work/nz: %6.2f )\n", work, goodwork, (double) nz, (work - goodwork) / ((double) nz)))) ; /* All hash buckets now empty. Cmap no longer needed as workspace. ] * Cew no longer needed as Hhead; Cew is now restored to all ones. ] * Part no longer needed as workspace for Next. ] */ } /* Edge weights are all one, node weights reflect node absorption */ DEBUG (for (p = 0 ; p < csize ; p++) ASSERT (Cew [p] == 1)) ; DEBUG (for (cnt = 0, j = 0 ; j < n ; j++) cnt += Cnw [j]) ; ASSERT (cnt == total_weight) ; /* ---------------------------------------------------------------------- */ /* compress and partition the graph */ /* ---------------------------------------------------------------------- */ if (nodes_pruned == 0) { /* ------------------------------------------------------------------ */ /* no pruning done at all. Do not create the compressed graph */ /* ------------------------------------------------------------------ */ /* FUTURE WORK: could call CHACO, SCOTCH, ... here too */ csep = CHOLMOD(metis_bisector) (C, Cnw, Cew, Part, Common) ; } else if (nodes_pruned == n-1) { /* ------------------------------------------------------------------ */ /* only one node left. This is a dense graph */ /* ------------------------------------------------------------------ */ PRINT2 (("completely dense graph\n")) ; csep = total_weight ; for (j = 0 ; j < n ; j++) { Part [j] = 2 ; } } else { /* ------------------------------------------------------------------ */ /* compress the graph and partition the compressed graph */ /* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */ /* create the map from the uncompressed graph to the compressed graph */ /* ------------------------------------------------------------------ */ /* Cmap [j] = k if node j is alive and the kth node of compressed graph. * The mapping is done monotonically (that is, k <= j) to simplify the * uncompression later on. Cmap [j] = EMPTY if node j is dead. */ for (j = 0 ; j < n ; j++) { Cmap [j] = EMPTY ; } k = 0 ; for (j = 0 ; j < n ; j++) { if (Cnw [j] > 0) { ASSERT (k <= j) ; Cmap [j] = k++ ; } } cn = k ; /* # of nodes in compressed graph */ PRINT2 (("compressed graph from "ID" to "ID" nodes\n", n, cn)) ; ASSERT (cn > 1 && cn == n - nodes_pruned) ; /* ------------------------------------------------------------------ */ /* create the compressed graph */ /* ------------------------------------------------------------------ */ k = 0 ; pdest = 0 ; for (j = 0 ; j < n ; j++) { if (Cnw [j] > 0) { /* node j in the full graph is node k in the compressed graph */ ASSERT (k <= j && Cmap [j] == k) ; p = Cp [j] ; pend = Cp [j+1] ; Cp [k] = pdest ; Cnw [k] = Cnw [j] ; for ( ; p < pend ; p++) { /* prune dead nodes, and remap to new node numbering */ i = Ci [p] ; ASSERT (i >= 0 && i < n && i != j) ; i = Cmap [i] ; ASSERT (i >= EMPTY && i < cn && i != k) ; if (i > EMPTY) { ASSERT (pdest <= p) ; Ci [pdest++] = i ; } } k++ ; } } Cp [cn] = pdest ; C->nrow = cn ; C->ncol = cn ; /* affects mem stats unless restored when C free'd */ #ifndef NDEBUG PRINT2 (("pruned graph ("ID"/"ID") nodes, ("ID"/"ID") edges\n", cn, n, pdest, nz)) ; PRINT2 (("compressed graph:\n")) ; for (cnt = 0, j = 0 ; j < cn ; j++) { PRINT2 ((""ID": ", j)) ; for (p = Cp [j] ; p < Cp [j+1] ; p++) { i = Ci [p] ; PRINT3 ((""ID" ", i)) ; ASSERT (i >= 0 && i < cn && i != j) ; } PRINT2 (("weight: "ID"\n", Cnw [j])) ; ASSERT (Cnw [j] > 0) ; cnt += Cnw [j] ; } ASSERT (cnt == total_weight) ; for (j = 0 ; j < n ; j++) PRINT2 (("Cmap ["ID"] = "ID"\n", j, Cmap[j])); ASSERT (k == cn) ; #endif /* ------------------------------------------------------------------ */ /* find the separator of the compressed graph */ /* ------------------------------------------------------------------ */ /* FUTURE WORK: could call CHACO, SCOTCH, ... here too */ csep = CHOLMOD(metis_bisector) (C, Cnw, Cew, Part, Common) ; if (csep < 0) { /* failed */ return (-1) ; } PRINT2 (("Part: ")) ; DEBUG (for (j = 0 ; j < cn ; j++) PRINT2 ((""ID" ", Part [j]))) ; PRINT2 (("\n")) ; /* Cp and Ci no longer needed */ /* ------------------------------------------------------------------ */ /* find the separator of the uncompressed graph */ /* ------------------------------------------------------------------ */ /* expand the separator to live nodes in the uncompressed graph */ for (j = n-1 ; j >= 0 ; j--) { /* do this in reverse order so that Cnw can be expanded in place */ k = Cmap [j] ; ASSERT (k >= EMPTY && k < n) ; if (k > EMPTY) { /* node k in compressed graph and is node j in full graph */ ASSERT (k <= j) ; ASSERT (Hash [j] >= EMPTY) ; Part [j] = Part [k] ; Cnw [j] = Cnw [k] ; } else { /* node j is a dead node */ Cnw [j] = 0 ; DEBUG (Part [j] = EMPTY) ; ASSERT (Hash [j] < EMPTY) ; } } /* find the components for the dead nodes */ for (i = 0 ; i < n ; i++) { if (Hash [i] < EMPTY) { /* node i has been absorbed into node j */ j = FLIP (Hash [i]) ; ASSERT (Part [i] == EMPTY && j >= 0 && j < n && Cnw [i] == 0) ; Part [i] = Part [j] ; } ASSERT (Part [i] >= 0 && Part [i] <= 2) ; } #ifndef NDEBUG PRINT2 (("Part: ")) ; for (cnt = 0, j = 0 ; j < n ; j++) { ASSERT (Part [j] != EMPTY) ; PRINT2 ((""ID" ", Part [j])) ; if (Part [j] == 2) cnt += Cnw [j] ; } PRINT2 (("\n")) ; PRINT2 (("csep "ID" "ID"\n", cnt, csep)) ; ASSERT (cnt == csep) ; for (cnt = 0, j = 0 ; j < n ; j++) cnt += Cnw [j] ; ASSERT (cnt == total_weight) ; #endif } /* ---------------------------------------------------------------------- */ /* return the separator (or -1 if error) */ /* ---------------------------------------------------------------------- */ PRINT2 (("Partition done, n "ID" csep "ID"\n", n, csep)) ; return (csep) ; } /* ========================================================================== */ /* === clear_flag =========================================================== */ /* ========================================================================== */ /* A node j has been removed from the graph if Flag [j] < EMPTY. * If Flag [j] >= EMPTY && Flag [j] < mark, then node j is alive but unmarked. * Flag [j] == mark means that node j is alive and marked. Incrementing mark * means that all nodes are either (still) dead, or live but unmarked. * * If Map is NULL, then on output, Common->mark < Common->Flag [i] for all i * from 0 to Common->nrow. This is the same output condition as * cholmod_clear_flag, except that this routine maintains the Flag [i] < EMPTY * condition as well, if that condition was true on input. * * If Map is non-NULL, then on output, Common->mark < Common->Flag [i] for all * i in the set Map [0..cn-1]. * * workspace: Flag (nrow) */ static SuiteSparse_long clear_flag (Int *Map, Int cn, cholmod_common *Common) { Int nrow, i ; Int *Flag ; PRINT2 (("old mark %ld\n", Common->mark)) ; Common->mark++ ; PRINT2 (("new mark %ld\n", Common->mark)) ; if (Common->mark <= 0) { nrow = Common->nrow ; Flag = Common->Flag ; if (Map != NULL) { for (i = 0 ; i < cn ; i++) { /* if Flag [Map [i]] < EMPTY, leave it alone */ if (Flag [Map [i]] >= EMPTY) { Flag [Map [i]] = EMPTY ; } } /* now Flag [Map [i]] <= EMPTY for all i */ } else { for (i = 0 ; i < nrow ; i++) { /* if Flag [i] < EMPTY, leave it alone */ if (Flag [i] >= EMPTY) { Flag [i] = EMPTY ; } } /* now Flag [i] <= EMPTY for all i */ } Common->mark = 0 ; } return (Common->mark) ; } /* ========================================================================== */ /* === find_components ====================================================== */ /* ========================================================================== */ /* Find all connected components of the current subgraph C. The subgraph C * consists of the nodes of B that appear in the set Map [0..cn-1]. If Map * is NULL, then it is assumed to be the identity mapping * (Map [0..cn-1] = 0..cn-1). * * A node j does not appear in B if it has been ordered (Flag [j] < EMPTY, * which means that j has been ordered and is "deleted" from B). * * If the size of a component is large, it is placed on the component stack, * Cstack. Otherwise, its nodes are ordered and it is not placed on the Cstack. * * A component S is defined by a "representative node" (repnode for short) * called the snode, which is one of the nodes in the subgraph. Likewise, the * subgraph C is defined by its repnode, called cnode. * * If Part is not NULL on input, then Part [i] determines how the components * are placed on the stack. Components containing nodes i with Part [i] == 0 * are placed first, followed by components with Part [i] == 1. * * The first node placed in each of the two parts is flipped when placed in * the Cstack. This allows the components of the two parts to be found simply * by traversing the Cstack. * * workspace: Flag (nrow) */ static void find_components ( /* inputs, not modified on output */ cholmod_sparse *B, Int Map [ ], /* size n, only Map [0..cn-1] used */ Int cn, /* # of nodes in C */ Int cnode, /* root node of component C, or EMPTY if C is the * entire graph B */ Int Part [ ], /* size cn, optional */ /* input/output */ Int Bnz [ ], /* size n. Bnz [j] = # nonzeros in column j of B. * Reduce since B is pruned of dead nodes. */ Int CParent [ ], /* CParent [i] = j if component with repnode j is * the parent of the component with repnode i. * CParent [i] = EMPTY if the component with * repnode i is a root of the separator tree. * CParent [i] is -2 if i is not a repnode. */ Int Cstack [ ], /* component stack for nested dissection */ Int *top, /* Cstack [0..top] contains root nodes of the * the components currently in the stack */ /* workspace, undefined on input and output: */ Int Queue [ ], /* size n, for breadth-first search */ cholmod_common *Common ) { Int n, mark, cj, j, sj, sn, p, i, snode, pstart, pdest, pend, nd_components, part, first, save_mark ; Int *Bp, *Bi, *Flag ; /* ---------------------------------------------------------------------- */ /* get workspace */ /* ---------------------------------------------------------------------- */ PRINT2 (("find components: cn %d\n", cn)) ; Flag = Common->Flag ; /* size n */ /* force initialization of Flag [Map [0..cn-1]] */ save_mark = Common->mark ; /* save the current mark */ Common->mark = EMPTY ; /* clear Flag; preserve Flag [Map [i]] if Flag [Map [i]] already < EMPTY */ /* this takes O(cn) time */ mark = clear_flag (Map, cn, Common) ; Bp = B->p ; Bi = B->i ; n = B->nrow ; ASSERT (cnode >= EMPTY && cnode < n) ; ASSERT (IMPLIES (cnode >= 0, Flag [cnode] < EMPTY)) ; /* get ordering parameters */ nd_components = Common->method [Common->current].nd_components ; /* ---------------------------------------------------------------------- */ /* find the connected components of C via a breadth-first search */ /* ---------------------------------------------------------------------- */ part = (Part == NULL) ? 0 : 1 ; /* examine each part (part 1 and then part 0) */ for (part = (Part == NULL) ? 0 : 1 ; part >= 0 ; part--) { /* first is TRUE for the first connected component in each part */ first = TRUE ; /* find all connected components in the current part */ for (cj = 0 ; cj < cn ; cj++) { /* get node snode, which is node cj of C. It might already be in * the separator of C (and thus ordered, with Flag [snode] < EMPTY) */ snode = (Map == NULL) ? (cj) : (Map [cj]) ; ASSERT (snode >= 0 && snode < n) ; if (Flag [snode] >= EMPTY && Flag [snode] < mark && ((Part == NULL) || Part [cj] == part)) { /* ---------------------------------------------------------- */ /* find new connected component S */ /* ---------------------------------------------------------- */ /* node snode is the repnode of a connected component S, the * parent of which is cnode, the repnode of C. If cnode is * EMPTY then C is the original graph B. */ PRINT2 (("----------:::snode "ID" cnode "ID"\n", snode, cnode)); ASSERT (CParent [snode] == -2) ; if (first || nd_components) { /* If this is the first node in this part, then it becomes * the repnode of all components in this part, and all * components in this part form a single node in the * separator tree. If nd_components is TRUE, then all * connected components form their own node in the * separator tree. */ CParent [snode] = cnode ; } /* place j in the queue and mark it */ Queue [0] = snode ; Flag [snode] = mark ; sn = 1 ; /* breadth-first traversal, starting at node j */ for (sj = 0 ; sj < sn ; sj++) { /* get node j from head of Queue and traverse its edges */ j = Queue [sj] ; PRINT2 ((" j: "ID"\n", j)) ; ASSERT (j >= 0 && j < n) ; ASSERT (Flag [j] == mark) ; pstart = Bp [j] ; pdest = pstart ; pend = pstart + Bnz [j] ; for (p = pstart ; p < pend ; p++) { i = Bi [p] ; if (i != j && Flag [i] >= EMPTY) { /* node is still in the graph */ Bi [pdest++] = i ; if (Flag [i] < mark) { /* node i is in this component S, and unflagged * (first time node i has been seen in this BFS) * place node i in the queue and mark it */ Queue [sn++] = i ; Flag [i] = mark ; } } } /* edges to dead nodes have been removed */ Bnz [j] = pdest - pstart ; } /* ---------------------------------------------------------- */ /* order S if it is small; place it on Cstack otherwise */ /* ---------------------------------------------------------- */ PRINT2 (("sn "ID"\n", sn)) ; /* place the new component on the Cstack. Flip the node if * is the first connected component of the current part, * or if all components are treated as their own node in * the separator tree. */ Cstack [++(*top)] = (first || nd_components) ? FLIP (snode) : snode ; first = FALSE ; } } } /* restore the flag (normally taking O(1) time except for Int overflow) */ Common->mark = save_mark++ ; clear_flag (NULL, 0, Common) ; DEBUG (for (i = 0 ; i < n ; i++) ASSERT (Flag [i] < Common->mark)) ; } /* ========================================================================== */ /* === cholmod_bisect ======================================================= */ /* ========================================================================== */ /* Finds a node bisector of A, A*A', A(:,f)*A(:,f)'. * * workspace: Flag (nrow), * Iwork (nrow if symmetric, max (nrow,ncol) if unsymmetric). * Allocates a temporary matrix B=A*A' or B=A, * and O(nnz(A)) temporary memory space. */ SuiteSparse_long CHOLMOD(bisect) /* returns # of nodes in separator */ ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to bisect */ Int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ int compress, /* if TRUE, compress the graph first */ /* ---- output --- */ Int *Partition, /* size A->nrow. Node i is in the left graph if * Partition [i] = 0, the right graph if 1, and in the * separator if 2. */ /* --------------- */ cholmod_common *Common ) { Int *Bp, *Bi, *Hash, *Cmap, *Bnw, *Bew, *Iwork ; cholmod_sparse *B ; unsigned Int hash ; Int j, n, bnz, sepsize, p, pend ; size_t csize, s ; int ok = TRUE ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (EMPTY) ; RETURN_IF_NULL (A, EMPTY) ; RETURN_IF_NULL (Partition, EMPTY) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, EMPTY) ; Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* quick return */ /* ---------------------------------------------------------------------- */ n = A->nrow ; if (n == 0) { return (0) ; } /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ /* s = n + MAX (n, A->ncol) */ s = CHOLMOD(add_size_t) (A->nrow, MAX (A->nrow, A->ncol), &ok) ; if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (EMPTY) ; } CHOLMOD(allocate_work) (n, s, 0, Common) ; if (Common->status < CHOLMOD_OK) { return (EMPTY) ; } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; Iwork = Common->Iwork ; Hash = Iwork ; /* size n, (i/l/l) */ Cmap = Iwork + n ; /* size n, (i/i/l) */ /* ---------------------------------------------------------------------- */ /* convert the matrix to adjacency list form */ /* ---------------------------------------------------------------------- */ /* The input graph to must be symmetric, with no diagonal entries * present. The columns need not be sorted. */ /* B = A, A*A', or A(:,f)*A(:,f)', upper and lower parts present */ if (A->stype) { /* Add the upper/lower part to a symmetric lower/upper matrix by * converting to unsymmetric mode */ /* workspace: Iwork (nrow) */ B = CHOLMOD(copy) (A, 0, -1, Common) ; } else { /* B = A*A' or A(:,f)*A(:,f)', no diagonal */ /* workspace: Flag (nrow), Iwork (max (nrow,ncol)) */ B = CHOLMOD(aat) (A, fset, fsize, -1, Common) ; } if (Common->status < CHOLMOD_OK) { return (EMPTY) ; } Bp = B->p ; Bi = B->i ; bnz = Bp [n] ; ASSERT ((Int) (B->nrow) == n && (Int) (B->ncol) == n) ; /* B does not include the diagonal, and both upper and lower parts. * Common->anz includes the diagonal, and just the lower part of B */ Common->anz = bnz / 2 + ((double) n) ; /* Bew should be at least size n for the hash function to work well */ /* this cannot cause overflow, because the matrix is already created */ csize = MAX (((size_t) n) + 1, (size_t) bnz) ; /* create the graph using Flag as workspace for node weights [ */ Bnw = Common->Flag ; /* size n workspace */ /* compute hash for each node if compression requested */ if (compress) { for (j = 0 ; j < n ; j++) { hash = j ; pend = Bp [j+1] ; for (p = Bp [j] ; p < pend ; p++) { hash += Bi [p] ; ASSERT (Bi [p] != j) ; } /* finalize the hash key for node j */ hash %= csize ; Hash [j] = (Int) hash ; ASSERT (Hash [j] >= 0 && Hash [j] < csize) ; } } /* allocate edge weights */ Bew = CHOLMOD(malloc) (csize, sizeof (Int), Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ CHOLMOD(free_sparse) (&B, Common) ; CHOLMOD(free) (csize, sizeof (Int), Bew, Common) ; return (EMPTY) ; } /* graph has unit node and edge weights */ for (j = 0 ; j < n ; j++) { Bnw [j] = 1 ; } for (s = 0 ; s < csize ; s++) { Bew [s] = 1 ; } /* ---------------------------------------------------------------------- */ /* compress and partition the graph */ /* ---------------------------------------------------------------------- */ sepsize = partition ( #ifndef NDEBUG csize, #endif compress, Hash, B, Bnw, Bew, Cmap, Partition, Common) ; /* contents of Bp, Bi, Bnw, and Bew no longer needed ] */ /* If partition fails, free the workspace below and return sepsize < 0 */ /* ---------------------------------------------------------------------- */ /* free workspace */ /* ---------------------------------------------------------------------- */ B->ncol = n ; /* restore size for memory usage statistics */ CHOLMOD(free_sparse) (&B, Common) ; Common->mark = EMPTY ; CHOLMOD_CLEAR_FLAG (Common) ; CHOLMOD(free) (csize, sizeof (Int), Bew, Common) ; return (sepsize) ; } /* ========================================================================== */ /* === cholmod_nested_dissection ============================================ */ /* ========================================================================== */ /* This method uses a node bisector, applied recursively (but using a * non-recursive algorithm). Once the graph is partitioned, it calls a * constrained min degree code (CAMD or CSYMAMD for A+A', and CCOLAMD for A*A') * to order all the nodes in the graph - but obeying the constraints determined * by the separators. This routine is similar to METIS_NodeND, except for how * it treats the leaf nodes. METIS_NodeND orders the leaves of the separator * tree with MMD, ignoring the rest of the matrix when ordering a single leaf. * This routine orders the whole matrix with CSYMAMD or CCOLAMD, all at once, * when the graph partitioning is done. * * This function also returns a postorderd separator tree (CParent), and a * mapping of nodes in the graph to nodes in the separator tree (Cmember). * * workspace: Flag (nrow), Head (nrow+1), Iwork (4*nrow + (ncol if unsymmetric)) * Allocates a temporary matrix B=A*A' or B=A, * and O(nnz(A)) temporary memory space. * Allocates an additional 3*n*sizeof(Int) temporary workspace */ SuiteSparse_long CHOLMOD(nested_dissection) /* returns # of components, or -1 if error */ ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to order */ Int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ /* ---- output --- */ Int *Perm, /* size A->nrow, output permutation */ Int *CParent, /* size A->nrow. On output, CParent [c] is the parent * of component c, or EMPTY if c is a root, and where * c is in the range 0 to # of components minus 1 */ Int *Cmember, /* size A->nrow. Cmember [j] = c if node j of A is * in component c */ /* --------------- */ cholmod_common *Common ) { double prune_dense, nd_oksep ; Int *Bp, *Bi, *Bnz, *Cstack, *Imap, *Map, *Flag, *Head, *Next, *Bnw, *Iwork, *Ipost, *NewParent, *Hash, *Cmap, *Cp, *Ci, *Cew, *Cnw, *Part, *Post, *Work3n ; unsigned Int hash ; Int n, bnz, top, i, j, k, cnode, cdense, p, cj, cn, ci, cnz, mark, c, uncol, sepsize, parent, ncomponents, threshold, ndense, pstart, pdest, pend, nd_compress, nd_camd, csize, jnext, nd_small, total_weight, nchild, child = EMPTY ; cholmod_sparse *B, *C ; size_t s ; int ok = TRUE ; DEBUG (Int cnt) ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (EMPTY) ; RETURN_IF_NULL (A, EMPTY) ; RETURN_IF_NULL (Perm, EMPTY) ; RETURN_IF_NULL (CParent, EMPTY) ; RETURN_IF_NULL (Cmember, EMPTY) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, EMPTY) ; Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* quick return */ /* ---------------------------------------------------------------------- */ n = A->nrow ; if (n == 0) { return (1) ; } /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ /* get ordering parameters */ prune_dense = Common->method [Common->current].prune_dense ; nd_compress = Common->method [Common->current].nd_compress ; nd_oksep = Common->method [Common->current].nd_oksep ; nd_oksep = MAX (0, nd_oksep) ; nd_oksep = MIN (1, nd_oksep) ; nd_camd = Common->method [Common->current].nd_camd ; nd_small = Common->method [Common->current].nd_small ; nd_small = MAX (4, nd_small) ; PRINT0 (("nd_components %d nd_small %d nd_oksep %g\n", Common->method [Common->current].nd_components, nd_small, nd_oksep)) ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ /* s = 4*n + uncol */ uncol = (A->stype == 0) ? A->ncol : 0 ; s = CHOLMOD(mult_size_t) (n, 4, &ok) ; s = CHOLMOD(add_size_t) (s, uncol, &ok) ; if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (EMPTY) ; } CHOLMOD(allocate_work) (n, s, 0, Common) ; if (Common->status < CHOLMOD_OK) { return (EMPTY) ; } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; /* ---------------------------------------------------------------------- */ /* get workspace */ /* ---------------------------------------------------------------------- */ Flag = Common->Flag ; /* size n */ Head = Common->Head ; /* size n+1, all equal to -1 */ Iwork = Common->Iwork ; Imap = Iwork ; /* size n, same as Queue in find_components */ Map = Iwork + n ; /* size n */ Bnz = Iwork + 2*((size_t) n) ; /* size n */ Hash = Iwork + 3*((size_t) n) ; /* size n */ Work3n = CHOLMOD(malloc) (n, 3*sizeof (Int), Common) ; Part = Work3n ; /* size n */ Bnw = Part + n ; /* size n */ Cnw = Bnw + n ; /* size n */ Cstack = Perm ; /* size n, use Perm as workspace for Cstack [ */ Cmap = Cmember ; /* size n, use Cmember as workspace [ */ if (Common->status < CHOLMOD_OK) { return (EMPTY) ; } /* ---------------------------------------------------------------------- */ /* convert B to symmetric form with both upper/lower parts present */ /* ---------------------------------------------------------------------- */ /* B = A+A', A*A', or A(:,f)*A(:,f)', upper and lower parts present */ if (A->stype) { /* Add the upper/lower part to a symmetric lower/upper matrix by * converting to unsymmetric mode */ /* workspace: Iwork (nrow) */ B = CHOLMOD(copy) (A, 0, -1, Common) ; } else { /* B = A*A' or A(:,f)*A(:,f)', no diagonal */ /* workspace: Flag (nrow), Iwork (max (nrow,ncol)) */ B = CHOLMOD(aat) (A, fset, fsize, -1, Common) ; } if (Common->status < CHOLMOD_OK) { CHOLMOD(free) (3*n, sizeof (Int), Work3n, Common) ; return (EMPTY) ; } Bp = B->p ; Bi = B->i ; bnz = CHOLMOD(nnz) (B, Common) ; ASSERT ((Int) (B->nrow) == n && (Int) (B->ncol) == n) ; csize = MAX (n, bnz) ; ASSERT (CHOLMOD(dump_sparse) (B, "B for nd:", Common) >= 0) ; /* ---------------------------------------------------------------------- */ /* initializations */ /* ---------------------------------------------------------------------- */ /* all nodes start out unmarked and unordered (Type 4, see below) */ Common->mark = EMPTY ; CHOLMOD_CLEAR_FLAG (Common) ; ASSERT (Flag == Common->Flag) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; for (j = 0 ; j < n ; j++) { CParent [j] = -2 ; } /* prune dense nodes from B */ if (IS_NAN (prune_dense) || prune_dense < 0) { /* only remove completely dense nodes */ threshold = n-2 ; } else { /* remove nodes with degree more than threshold */ threshold = (Int) (MAX (16, prune_dense * sqrt ((double) (n)))) ; threshold = MIN (n, threshold) ; } ndense = 0 ; cnode = EMPTY ; cdense = EMPTY ; for (j = 0 ; j < n ; j++) { Bnz [j] = Bp [j+1] - Bp [j] ; if (Bnz [j] > threshold) { /* node j is dense, prune it from B */ PRINT2 (("j is dense %d\n", j)) ; ndense++ ; if (cnode == EMPTY) { /* first dense node found becomes root of this component, * which contains all of the dense nodes found here */ cdense = j ; cnode = j ; CParent [cnode] = EMPTY ; } Flag [j] = FLIP (cnode) ; } } B->packed = FALSE ; ASSERT (B->nz == NULL) ; if (ndense == n) { /* all nodes removed: Perm is identity, all nodes in component zero, * and the separator tree has just one node. */ PRINT2 (("all nodes are dense\n")) ; for (k = 0 ; k < n ; k++) { Perm [k] = k ; Cmember [k] = 0 ; } CParent [0] = EMPTY ; CHOLMOD(free_sparse) (&B, Common) ; CHOLMOD(free) (3*n, sizeof (Int), Work3n, Common) ; Common->mark = EMPTY ; CHOLMOD_CLEAR_FLAG (Common) ; return (1) ; } /* Cp and Ci are workspace to construct the subgraphs to partition */ C = CHOLMOD(allocate_sparse) (n, n, csize, FALSE, TRUE, 0, CHOLMOD_PATTERN, Common) ; Cew = CHOLMOD(malloc) (csize, sizeof (Int), Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ CHOLMOD(free_sparse) (&C, Common) ; CHOLMOD(free_sparse) (&B, Common) ; CHOLMOD(free) (csize, sizeof (Int), Cew, Common) ; CHOLMOD(free) (3*n, sizeof (Int), Work3n, Common) ; Common->mark = EMPTY ; CHOLMOD_CLEAR_FLAG (Common) ; PRINT2 (("out of memory for C, etc\n")) ; return (EMPTY) ; } Cp = C->p ; Ci = C->i ; /* create initial unit node and edge weights */ for (j = 0 ; j < n ; j++) { Bnw [j] = 1 ; } for (p = 0 ; p < csize ; p++) { Cew [p] = 1 ; } /* push the initial connnected components of B onto the Cstack */ top = EMPTY ; /* Cstack is empty */ /* workspace: Flag (nrow), Iwork (nrow); use Imap as workspace for Queue [*/ find_components (B, NULL, n, cnode, NULL, Bnz, CParent, Cstack, &top, Imap, Common) ; /* done using Imap as workspace for Queue ] */ /* Nodes can now be of Type 0, 1, 2, or 4 (see definition below) */ /* ---------------------------------------------------------------------- */ /* while Cstack is not empty, do: */ /* ---------------------------------------------------------------------- */ while (top >= 0) { /* clear the Flag array, but do not modify negative entries in Flag */ mark = clear_flag (NULL, 0, Common) ; DEBUG (for (i = 0 ; i < n ; i++) Imap [i] = EMPTY) ; /* ------------------------------------------------------------------ */ /* get node(s) from the top of the Cstack */ /* ------------------------------------------------------------------ */ /* i is the repnode of its (unordered) connected component. Get * all repnodes for all connected components of a single part. If * each connected component is to be ordered separately (nd_components * is TRUE), then this while loop iterates just once. */ cnode = EMPTY ; cn = 0 ; while (cnode == EMPTY) { i = Cstack [top--] ; if (i < 0) { /* this is the last node in this component */ i = FLIP (i) ; cnode = i ; } ASSERT (i >= 0 && i < n && Flag [i] >= EMPTY) ; /* place i in the queue and mark it */ Map [cn] = i ; Flag [i] = mark ; Imap [i] = cn ; cn++ ; } ASSERT (cnode != EMPTY) ; /* During ordering, there are five kinds of nodes in the graph of B, * based on Flag [j] and CParent [j] for nodes j = 0 to n-1: * * Type 0: If cnode is a repnode of an unordered component, then * CParent [cnode] is in the range EMPTY to n-1 and * Flag [cnode] >= EMPTY. This is a "live" node. * * Type 1: If cnode is a repnode of an ordered separator component, * then Flag [cnode] < EMPTY and FLAG [cnode] = FLIP (cnode). * CParent [cnode] is in the range EMPTY to n-1. cnode is a root of * the separator tree if CParent [cnode] == EMPTY. This node is dead. * * Type 2: If node j isn't a repnode, has not been absorbed via * graph compression into another node, but is in an ordered separator * component, then cnode = FLIP (Flag [j]) gives the repnode of the * component that contains j and CParent [j] is -2. This node is dead. * Note that Flag [j] < EMPTY. * * Type 3: If node i has been absorbed via graph compression into some * other node j = FLIP (Flag [i]) where j is not a repnode. * CParent [j] is -2. Node i may or may not be in an ordered * component. This node is dead. Note that Flag [j] < EMPTY. * * Type 4: If node j is "live" (not in an ordered component, and not * absorbed into any other node), then Flag [j] >= EMPTY. * * Only "live" nodes (of type 0 or 4) are placed in a subgraph to be * partitioned. Node j is alive if Flag [j] >= EMPTY, and dead if * Flag [j] < EMPTY. */ /* ------------------------------------------------------------------ */ /* create the subgraph for this connected component C */ /* ------------------------------------------------------------------ */ /* Do a breadth-first search of the graph starting at cnode. * use Map [0..cn-1] for nodes in the component C [ * use Cnw and Cew for node and edge weights of the resulting subgraph [ * use Cp and Ci for the resulting subgraph [ * use Imap [i] for all nodes i in B that are in the component C [ */ cnz = 0 ; total_weight = 0 ; for (cj = 0 ; cj < cn ; cj++) { /* get node j from the head of the queue; it is node cj of C */ j = Map [cj] ; ASSERT (Flag [j] == mark) ; Cp [cj] = cnz ; Cnw [cj] = Bnw [j] ; ASSERT (Cnw [cj] >= 0) ; total_weight += Cnw [cj] ; pstart = Bp [j] ; pdest = pstart ; pend = pstart + Bnz [j] ; hash = cj ; for (p = pstart ; p < pend ; p++) { i = Bi [p] ; /* prune diagonal entries and dead edges from B */ if (i != j && Flag [i] >= EMPTY) { /* live node i is in the current component */ Bi [pdest++] = i ; if (Flag [i] != mark) { /* First time node i has been seen, it is a new node * of C. place node i in the queue and mark it */ Map [cn] = i ; Flag [i] = mark ; Imap [i] = cn ; cn++ ; } /* place the edge (cj,ci) in the adjacency list of cj */ ci = Imap [i] ; ASSERT (ci >= 0 && ci < cn && ci != cj && cnz < csize) ; Ci [cnz++] = ci ; hash += ci ; } } /* edges to dead nodes have been removed */ Bnz [j] = pdest - pstart ; /* finalize the hash key for column j */ hash %= csize ; Hash [cj] = (Int) hash ; ASSERT (Hash [cj] >= 0 && Hash [cj] < csize) ; } Cp [cn] = cnz ; C->nrow = cn ; C->ncol = cn ; /* affects mem stats unless restored when C free'd */ /* contents of Imap no longer needed ] */ #ifndef NDEBUG for (cj = 0 ; cj < cn ; cj++) { j = Map [cj] ; PRINT2 (("----------------------------C column cj: "ID" j: "ID"\n", cj, j)) ; ASSERT (j >= 0 && j < n) ; ASSERT (Flag [j] >= EMPTY) ; for (p = Cp [cj] ; p < Cp [cj+1] ; p++) { ci = Ci [p] ; i = Map [ci] ; PRINT3 (("ci: "ID" i: "ID"\n", ci, i)) ; ASSERT (ci != cj && ci >= 0 && ci < cn) ; ASSERT (i != j && i >= 0 && i < n) ; ASSERT (Flag [i] >= EMPTY) ; } } #endif PRINT0 (("consider cn %d nd_small %d ", cn, nd_small)) ; if (cn < nd_small) /* could be 'total_weight < nd_small' instead */ { /* place all nodes in the separator */ PRINT0 ((" too small\n")) ; sepsize = total_weight ; } else { /* Cp and Ci now contain the component, with cn nodes and cnz * nonzeros. The mapping of a node cj into node j the main graph * B is given by Map [cj] = j */ PRINT0 ((" cut\n")) ; /* -------------------------------------------------------------- */ /* compress and partition the graph C */ /* -------------------------------------------------------------- */ /* The edge weights Cew [0..csize-1] are all 1's on input to and * output from the partition routine. */ sepsize = partition ( #ifndef NDEBUG csize, #endif nd_compress, Hash, C, Cnw, Cew, Cmap, Part, Common) ; /* contents of Cp and Ci no longer needed ] */ if (sepsize < 0) { /* failed */ C->ncol = n ; /* restore size for memory usage statistics */ CHOLMOD(free_sparse) (&C, Common) ; CHOLMOD(free_sparse) (&B, Common) ; CHOLMOD(free) (csize, sizeof (Int), Cew, Common) ; CHOLMOD(free) (3*n, sizeof (Int), Work3n, Common) ; Common->mark = EMPTY ; CHOLMOD_CLEAR_FLAG (Common) ; return (EMPTY) ; } /* -------------------------------------------------------------- */ /* compress B based on how C was compressed */ /* -------------------------------------------------------------- */ for (ci = 0 ; ci < cn ; ci++) { if (Hash [ci] < EMPTY) { /* ci is dead in C, having been absorbed into cj */ cj = FLIP (Hash [ci]) ; PRINT2 (("In C, "ID" absorbed into "ID" (wgt now "ID")\n", ci, cj, Cnw [cj])) ; /* i is dead in B, having been absorbed into j */ i = Map [ci] ; j = Map [cj] ; PRINT2 (("In B, "ID" (wgt "ID") => "ID" (wgt "ID")\n", i, Bnw [i], j, Bnw [j], Cnw [cj])) ; /* more than one node may be absorbed into j. This is * accounted for in Cnw [cj]. Assign it here rather * than += Bnw [i] */ Bnw [i] = 0 ; Bnw [j] = Cnw [cj] ; Flag [i] = FLIP (j) ; } } DEBUG (for (cnt = 0, j = 0 ; j < n ; j++) cnt += Bnw [j]) ; ASSERT (cnt == n) ; } /* contents of Cnw [0..cn-1] no longer needed ] */ /* ------------------------------------------------------------------ */ /* order the separator, and stack the components when C is split */ /* ------------------------------------------------------------------ */ /* one more component has been found: either the separator of C, * or all of C */ ASSERT (sepsize >= 0 && sepsize <= total_weight) ; PRINT0 (("sepsize %d tot %d : %8.4f ", sepsize, total_weight, ((double) sepsize) / ((double) total_weight))) ; if (sepsize == total_weight || sepsize == 0 || sepsize > nd_oksep * total_weight) { /* Order the nodes in the component. The separator is too large, * or empty. Note that the partition routine cannot return a * sepsize of zero, but it can return a separator consisting of the * whole graph. The "sepsize == 0" test is kept, above, in case the * partition routine changes. In either case, this component * remains unsplit, and becomes a leaf of the separator tree. */ PRINT2 (("cnode %d sepsize zero or all of graph: "ID"\n", cnode, sepsize)) ; for (cj = 0 ; cj < cn ; cj++) { j = Map [cj] ; Flag [j] = FLIP (cnode) ; PRINT2 ((" node cj: "ID" j: "ID" ordered\n", cj, j)) ; } ASSERT (Flag [cnode] == FLIP (cnode)) ; ASSERT (cnode != EMPTY && Flag [cnode] < EMPTY) ; PRINT0 (("discarded\n")) ; } else { /* Order the nodes in the separator of C and find a new repnode * cnode that is in the separator of C. This requires the separator * to be non-empty. */ PRINT0 (("sepsize not tiny: "ID"\n", sepsize)) ; parent = CParent [cnode] ; ASSERT (parent >= EMPTY && parent < n) ; CParent [cnode] = -2 ; cnode = EMPTY ; for (cj = 0 ; cj < cn ; cj++) { j = Map [cj] ; if (Part [cj] == 2) { /* All nodes in the separator become part of a component * whose repnode is cnode */ PRINT2 (("node cj: "ID" j: "ID" ordered\n", cj, j)) ; if (cnode == EMPTY) { PRINT2(("------------new cnode: cj "ID" j "ID"\n", cj, j)) ; cnode = j ; } Flag [j] = FLIP (cnode) ; } else { PRINT2 ((" node cj: "ID" j: "ID" not ordered\n", cj, j)) ; } } ASSERT (cnode != EMPTY && Flag [cnode] < EMPTY) ; ASSERT (CParent [cnode] == -2) ; CParent [cnode] = parent ; /* find the connected components when C is split, and push * them on the Cstack. Use Imap as workspace for Queue. [ */ /* workspace: Flag (nrow) */ find_components (B, Map, cn, cnode, Part, Bnz, CParent, Cstack, &top, Imap, Common) ; /* done using Imap as workspace for Queue ] */ } /* contents of Map [0..cn-1] no longer needed ] */ } /* done using Cmember as workspace for Cmap ] */ /* done using Perm as workspace for Cstack ] */ /* ---------------------------------------------------------------------- */ /* place nodes removed via compression into their proper component */ /* ---------------------------------------------------------------------- */ /* At this point, all nodes are of Type 1, 2, or 3, as defined above. */ for (i = 0 ; i < n ; i++) { /* find the repnode cnode that contains node i */ j = FLIP (Flag [i]) ; PRINT2 (("\nfind component for "ID", in: "ID"\n", i, j)) ; ASSERT (j >= 0 && j < n) ; DEBUG (cnt = 0) ; while (CParent [j] == -2) { j = FLIP (Flag [j]) ; PRINT2 ((" walk up to "ID" ", j)) ; ASSERT (j >= 0 && j < n) ; PRINT2 ((" CParent "ID"\n", CParent [j])) ; ASSERT (cnt < n) ; DEBUG (cnt++) ; } cnode = j ; ASSERT (cnode >= 0 && cnode < n) ; ASSERT (CParent [cnode] >= EMPTY && CParent [cnode] < n) ; PRINT2 (("i "ID" is in component with cnode "ID"\n", i, cnode)) ; ASSERT (Flag [cnode] == FLIP (cnode)) ; /* Mark all nodes along the path from i to cnode as being in the * component whos repnode is cnode. Perform path compression. */ j = FLIP (Flag [i]) ; Flag [i] = FLIP (cnode) ; DEBUG (cnt = 0) ; while (CParent [j] == -2) { ASSERT (j >= 0 && j < n) ; jnext = FLIP (Flag [j]) ; PRINT2 ((" "ID" walk "ID" set cnode to "ID"\n", i, j, cnode)) ; ASSERT (cnt < n) ; DEBUG (cnt++) ; Flag [j] = FLIP (cnode) ; j = jnext ; } } /* At this point, all nodes fall into Types 1 or 2, as defined above. */ #ifndef NDEBUG for (j = 0 ; j < n ; j++) { PRINT2 (("j %d CParent %d ", j, CParent [j])) ; if (CParent [j] >= EMPTY && CParent [j] < n) { /* case 1: j is a repnode of a component */ cnode = j ; PRINT2 ((" a repnode\n")) ; } else { /* case 2: j is not a repnode of a component */ cnode = FLIP (Flag [j]) ; PRINT2 ((" repnode is %d\n", cnode)) ; ASSERT (cnode >= 0 && cnode < n) ; ASSERT (CParent [cnode] >= EMPTY && CParent [cnode] < n) ; } ASSERT (Flag [cnode] == FLIP (cnode)) ; /* case 3 no longer holds */ } #endif /* ---------------------------------------------------------------------- */ /* free workspace */ /* ---------------------------------------------------------------------- */ C->ncol = n ; /* restore size for memory usage statistics */ CHOLMOD(free_sparse) (&C, Common) ; CHOLMOD(free_sparse) (&B, Common) ; CHOLMOD(free) (csize, sizeof (Int), Cew, Common) ; CHOLMOD(free) (3*n, sizeof (Int), Work3n, Common) ; /* ---------------------------------------------------------------------- */ /* handle dense nodes */ /* ---------------------------------------------------------------------- */ /* The separator tree has nodes with either no children or two or more * children - with one exception. There may exist a single root node with * exactly one child, which holds the dense rows/columns of the matrix. * Delete this node if it exists. */ if (ndense > 0) { ASSERT (CParent [cdense] == EMPTY) ; /* cdense has no parent */ /* find the children of cdense */ nchild = 0 ; for (j = 0 ; j < n ; j++) { if (CParent [j] == cdense) { nchild++ ; child = j ; } } if (nchild == 1) { /* the cdense node has just one child; merge the two nodes */ PRINT1 (("root has one child\n")) ; CParent [cdense] = -2 ; /* cdense is deleted */ CParent [child] = EMPTY ; /* child becomes a root */ for (j = 0 ; j < n ; j++) { if (Flag [j] == FLIP (cdense)) { /* j is a dense node */ PRINT1 (("dense %d\n", j)) ; Flag [j] = FLIP (child) ; } } } } /* ---------------------------------------------------------------------- */ /* postorder the components */ /* ---------------------------------------------------------------------- */ DEBUG (for (cnt = 0, j = 0 ; j < n ; j++) if (CParent [j] != -2) cnt++) ; /* use Cmember as workspace for Post [ */ Post = Cmember ; /* cholmod_postorder uses Head and Iwork [0..2n]. It does not use Flag, * which here holds the mapping of nodes to repnodes. It ignores all nodes * for which CParent [j] < -1, so it operates just on the repnodes. */ /* workspace: Head (n), Iwork (2*n) */ ncomponents = CHOLMOD(postorder) (CParent, n, NULL, Post, Common) ; ASSERT (cnt == ncomponents) ; /* use Iwork [0..n-1] as workspace for Ipost ( */ Ipost = Iwork ; DEBUG (for (j = 0 ; j < n ; j++) Ipost [j] = EMPTY) ; /* compute inverse postorder */ for (c = 0 ; c < ncomponents ; c++) { cnode = Post [c] ; ASSERT (cnode >= 0 && cnode < n) ; Ipost [cnode] = c ; ASSERT (Head [c] == EMPTY) ; } /* adjust the parent array */ /* Iwork [n..2n-1] used for NewParent [ */ NewParent = Iwork + n ; for (c = 0 ; c < ncomponents ; c++) { parent = CParent [Post [c]] ; NewParent [c] = (parent == EMPTY) ? EMPTY : (Ipost [parent]) ; } for (c = 0 ; c < ncomponents ; c++) { CParent [c] = NewParent [c] ; } ASSERT (CHOLMOD(dump_parent) (CParent, ncomponents, "CParent", Common)) ; /* Iwork [n..2n-1] no longer needed for NewParent ] */ /* Cmember no longer needed for Post ] */ #ifndef NDEBUG /* count the number of children of each node */ for (c = 0 ; c < ncomponents ; c++) { Cmember [c] = 0 ; } for (c = 0 ; c < ncomponents ; c++) { if (CParent [c] != EMPTY) Cmember [CParent [c]]++ ; } for (c = 0 ; c < ncomponents ; c++) { /* a node is either a leaf, or has 2 or more children */ ASSERT (Cmember [c] == 0 || Cmember [c] >= 2) ; } #endif /* ---------------------------------------------------------------------- */ /* place each node in its component */ /* ---------------------------------------------------------------------- */ for (j = 0 ; j < n ; j++) { /* node j is in the cth component, whose repnode is cnode */ cnode = FLIP (Flag [j]) ; PRINT2 (("j "ID" flag "ID" cnode "ID"\n", j, Flag [j], FLIP (Flag [j]))) ; ASSERT (cnode >= 0 && cnode < n) ; c = Ipost [cnode] ; ASSERT (c >= 0 && c < ncomponents) ; Cmember [j] = c ; } /* Flag no longer needed for the node-to-component mapping */ /* done using Iwork [0..n-1] as workspace for Ipost ) */ /* ---------------------------------------------------------------------- */ /* clear the Flag array */ /* ---------------------------------------------------------------------- */ Common->mark = EMPTY ; CHOLMOD_CLEAR_FLAG (Common) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; /* ---------------------------------------------------------------------- */ /* find the permutation */ /* ---------------------------------------------------------------------- */ PRINT1 (("nd_camd: %d A->stype %d\n", nd_camd, A->stype)) ; if (nd_camd) { /* ------------------------------------------------------------------ */ /* apply camd, csymamd, or ccolamd using the Cmember constraints */ /* ------------------------------------------------------------------ */ if (A->stype != 0) { /* ordering A+A', so fset and fsize are ignored. * Add the upper/lower part to a symmetric lower/upper matrix by * converting to unsymmetric mode * workspace: Iwork (nrow) */ B = CHOLMOD(copy) (A, 0, -1, Common) ; if (Common->status < CHOLMOD_OK) { PRINT0 (("make symmetric failed\n")) ; return (EMPTY) ; } ASSERT ((Int) (B->nrow) == n && (Int) (B->ncol) == n) ; PRINT2 (("nested dissection (2)\n")) ; B->stype = -1 ; if (nd_camd == 2) { /* workspace: Head (nrow+1), Iwork (nrow) if symmetric-upper */ ok = CHOLMOD(csymamd) (B, Cmember, Perm, Common) ; } else { /* workspace: Head (nrow), Iwork (4*nrow) */ ok = CHOLMOD(camd) (B, NULL, 0, Cmember, Perm, Common) ; } CHOLMOD(free_sparse) (&B, Common) ; if (!ok) { /* failed */ PRINT0 (("camd/csymamd failed\n")) ; return (EMPTY) ; } } else { /* ordering A*A' or A(:,f)*A(:,f)' */ /* workspace: Iwork (nrow if no fset; MAX(nrow,ncol) if fset) */ if (!CHOLMOD(ccolamd) (A, fset, fsize, Cmember, Perm, Common)) { /* ccolamd failed */ PRINT2 (("ccolamd failed\n")) ; return (EMPTY) ; } } } else { /* ------------------------------------------------------------------ */ /* natural ordering of each component */ /* ------------------------------------------------------------------ */ /* use Iwork [0..n-1] for Next [ */ Next = Iwork ; /* ------------------------------------------------------------------ */ /* place the nodes in link lists, one list per component */ /* ------------------------------------------------------------------ */ /* do so in reverse order, to preserve original ordering */ for (j = n-1 ; j >= 0 ; j--) { /* node j is in the cth component */ c = Cmember [j] ; ASSERT (c >= 0 && c < ncomponents) ; /* place node j in link list for component c */ Next [j] = Head [c] ; Head [c] = j ; } /* ------------------------------------------------------------------ */ /* order each node in each component */ /* ------------------------------------------------------------------ */ k = 0 ; for (c = 0 ; c < ncomponents ; c++) { for (j = Head [c] ; j != EMPTY ; j = Next [j]) { Perm [k++] = j ; } Head [c] = EMPTY ; } ASSERT (k == n) ; /* done using Iwork [0..n-1] for Next ] */ } /* ---------------------------------------------------------------------- */ /* clear workspace and return number of components */ /* ---------------------------------------------------------------------- */ ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; return (ncomponents) ; } /* ========================================================================== */ /* === cholmod_collapse_septree ============================================= */ /* ========================================================================== */ /* cholmod_nested_dissection returns the separator tree that was used in the * constrained minimum degree algorithm. Parameter settings (nd_small, * nd_oksep, etc) that give a good fill-reducing ordering may give too fine of * a separator tree for other uses (parallelism, multi-level LPDASA, etc). This * function takes as input the separator tree computed by * cholmod_nested_dissection, and collapses selected subtrees into single * nodes. A subtree is collapsed if its root node (the separator) is large * compared to the total number of nodes in the subtree, or if the subtree is * small. Note that the separator tree may actually be a forest. * * nd_oksep and nd_small act just like the ordering parameters in Common. * Returns the new number of nodes in the separator tree. */ SuiteSparse_long CHOLMOD(collapse_septree) ( /* ---- input ---- */ size_t n, /* # of nodes in the graph */ size_t ncomponents, /* # of nodes in the separator tree (must be <= n) */ double nd_oksep, /* collapse if #sep >= nd_oksep * #nodes in subtree */ size_t nd_small, /* collapse if #nodes in subtree < nd_small */ /* ---- in/out --- */ Int *CParent, /* size ncomponents; from cholmod_nested_dissection */ Int *Cmember, /* size n; from cholmod_nested_dissection */ /* --------------- */ cholmod_common *Common ) { Int *First, *Count, *Csubtree, *W, *Map ; Int c, j, k, nc, sepsize, total_weight, parent, nc_new, first ; int collapse = FALSE, ok = TRUE ; size_t s ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (EMPTY) ; RETURN_IF_NULL (CParent, EMPTY) ; RETURN_IF_NULL (Cmember, EMPTY) ; if (n < ncomponents) { ERROR (CHOLMOD_INVALID, "invalid separator tree") ; return (EMPTY) ; } Common->status = CHOLMOD_OK ; nc = ncomponents ; if (n <= 1 || ncomponents <= 1) { /* no change; tree is one node already */ return (nc) ; } nd_oksep = MAX (0, nd_oksep) ; nd_oksep = MIN (1, nd_oksep) ; nd_small = MAX (4, nd_small) ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ /* s = 3*ncomponents */ s = CHOLMOD(mult_size_t) (ncomponents, 3, &ok) ; if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (EMPTY) ; } CHOLMOD(allocate_work) (0, s, 0, Common) ; if (Common->status < CHOLMOD_OK) { return (EMPTY) ; } W = Common->Iwork ; Count = W ; W += ncomponents ; /* size ncomponents */ Csubtree = W ; W += ncomponents ; /* size ncomponents */ First = W ; W += ncomponents ; /* size ncomponents */ /* ---------------------------------------------------------------------- */ /* find the first descendant of each node of the separator tree */ /* ---------------------------------------------------------------------- */ for (c = 0 ; c < nc ; c++) { First [c] = EMPTY ; } for (k = 0 ; k < nc ; k++) { for (c = k ; c != EMPTY && First [c] == -1 ; c = CParent [c]) { ASSERT (c >= 0 && c < nc) ; First [c] = k ; } } /* ---------------------------------------------------------------------- */ /* find the number of nodes of the graph in each node of the tree */ /* ---------------------------------------------------------------------- */ for (c = 0 ; c < nc ; c++) { Count [c] = 0 ; } for (j = 0 ; j < (Int) n ; j++) { ASSERT (Cmember [j] >= 0 && Cmember [j] < nc) ; Count [Cmember [j]]++ ; } /* ---------------------------------------------------------------------- */ /* find the number of nodes in each subtree */ /* ---------------------------------------------------------------------- */ for (c = 0 ; c < nc ; c++) { /* each subtree includes its root */ Csubtree [c] = Count [c] ; PRINT1 ((ID" size "ID" parent "ID" first "ID"\n", c, Count [c], CParent [c], First [c])) ; } for (c = 0 ; c < nc ; c++) { /* add the subtree of the child, c, into the count of its parent */ parent = CParent [c] ; ASSERT (parent >= EMPTY && parent < nc) ; if (parent != EMPTY) { Csubtree [parent] += Csubtree [c] ; } } #ifndef NDEBUG /* the sum of the roots should be n */ j = 0 ; for (c = 0 ; c < nc ; c++) if (CParent [c] == EMPTY) j += Csubtree [c] ; ASSERT (j == (Int) n) ; #endif /* ---------------------------------------------------------------------- */ /* find subtrees to collapse */ /* ---------------------------------------------------------------------- */ /* consider all nodes in reverse post-order */ for (c = nc-1 ; c >= 0 ; c--) { /* consider the subtree rooted at node c */ sepsize = Count [c] ; total_weight = Csubtree [c] ; PRINT1 (("Node "ID" sepsize "ID" subtree "ID" ratio %g\n", c, sepsize, total_weight, ((double) sepsize)/((double) total_weight))) ; first = First [c] ; if (first < c && /* c must not be a leaf */ (sepsize > nd_oksep * total_weight || total_weight < (int) nd_small)) { /* this separator is too large, or the subtree is too small. * collapse the tree, by converting the entire subtree rooted at * c into a single node. The subtree consists of all nodes from * First[c] to the root c. Flag all nodes from First[c] to c-1 * as dead. */ collapse = TRUE ; for (k = first ; k < c ; k++) { CParent [k] = -2 ; PRINT1 ((" collapse node "ID"\n", k)) ; } /* continue at the next node, first-1 */ c = first ; } } PRINT1 (("collapse: %d\n", collapse)) ; /* ---------------------------------------------------------------------- */ /* compress the tree */ /* ---------------------------------------------------------------------- */ Map = Count ; /* Count no longer needed */ nc_new = nc ; if (collapse) { nc_new = 0 ; for (c = 0 ; c < nc ; c++) { Map [c] = nc_new ; if (CParent [c] >= EMPTY) { /* node c is alive, and becomes node Map[c] in the new tree. * Increment nc_new for the next node c. */ nc_new++ ; } } PRINT1 (("Collapse the tree from "ID" to "ID" nodes\n", nc, nc_new)) ; ASSERT (nc_new > 0) ; for (c = 0 ; c < nc ; c++) { parent = CParent [c] ; if (parent >= EMPTY) { /* node c is alive */ CParent [Map [c]] = (parent == EMPTY) ? EMPTY : Map [parent] ; } } for (j = 0 ; j < (Int) n ; j++) { PRINT1 (("j "ID" Cmember[j] "ID" Map[Cmember[j]] "ID"\n", j, Cmember [j], Map [Cmember [j]])) ; Cmember [j] = Map [Cmember [j]] ; } } /* ---------------------------------------------------------------------- */ /* return new size of separator tree */ /* ---------------------------------------------------------------------- */ return (nc_new) ; } #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Partition/cholmod_ccolamd.c������������������������������������������������������0000644�0001762�0000144�00000014472�13652535054�020636� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Partition/cholmod_ccolamd ============================================ */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Partition Module. * Copyright (C) 2005-2013, Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* CHOLMOD interface to the CCOLAMD ordering routine. Finds a permutation * p such that the Cholesky factorization of PAA'P' is sparser than AA'. * The column etree is found and postordered, and the ccolamd ordering is then * combined with its postordering. A must be unsymmetric. * * workspace: Iwork (MAX (nrow,ncol)) * Allocates a copy of its input matrix, which is * then used as CCOLAMD's workspace. * * Supports any xtype (pattern, real, complex, or zomplex). */ #ifndef NCAMD #include "cholmod_internal.h" #include "ccolamd.h" #include "cholmod_camd.h" #if (CCOLAMD_VERSION < CCOLAMD_VERSION_CODE (2,5)) #error "CCOLAMD v2.0 or later is required" #endif /* ========================================================================== */ /* === ccolamd_interface ==================================================== */ /* ========================================================================== */ /* Order with ccolamd */ static int ccolamd_interface ( cholmod_sparse *A, size_t alen, Int *Perm, Int *Cmember, Int *fset, Int fsize, cholmod_sparse *C, cholmod_common *Common ) { double knobs [CCOLAMD_KNOBS] ; Int *Cp = NULL ; Int ok, k, nrow, ncol, stats [CCOLAMD_STATS] ; nrow = A->nrow ; ncol = A->ncol ; /* ---------------------------------------------------------------------- */ /* copy (and transpose) the input matrix A into the ccolamd workspace */ /* ---------------------------------------------------------------------- */ /* C = A (:,f)', which also packs A if needed. */ /* workspace: Iwork (nrow if no fset; MAX (nrow,ncol) if fset non-NULL) */ ok = CHOLMOD(transpose_unsym) (A, 0, NULL, fset, fsize, C, Common) ; /* ---------------------------------------------------------------------- */ /* order the matrix (destroys the contents of C->i and C->p) */ /* ---------------------------------------------------------------------- */ /* get parameters */ #ifdef LONG ccolamd_l_set_defaults (knobs) ; #else ccolamd_set_defaults (knobs) ; #endif if (Common->current < 0 || Common->current >= CHOLMOD_MAXMETHODS) { /* this is the CHOLMOD default, not the CCOLAMD default */ knobs [CCOLAMD_DENSE_ROW] = -1 ; } else { /* get the knobs from the Common parameters */ knobs [CCOLAMD_DENSE_COL] =Common->method[Common->current].prune_dense ; knobs [CCOLAMD_DENSE_ROW] =Common->method[Common->current].prune_dense2; knobs [CCOLAMD_AGGRESSIVE]=Common->method[Common->current].aggressive ; knobs [CCOLAMD_LU] =Common->method[Common->current].order_for_lu; } if (ok) { #ifdef LONG ccolamd_l (ncol, nrow, alen, C->i, C->p, knobs, stats, Cmember) ; #else ccolamd (ncol, nrow, alen, C->i, C->p, knobs, stats, Cmember) ; #endif ok = stats [CCOLAMD_STATUS] ; ok = (ok == CCOLAMD_OK || ok == CCOLAMD_OK_BUT_JUMBLED) ; /* permutation returned in C->p, if the ordering succeeded */ Cp = C->p ; for (k = 0 ; k < nrow ; k++) { Perm [k] = Cp [k] ; } } return (ok) ; } /* ========================================================================== */ /* === cholmod_ccolamd ====================================================== */ /* ========================================================================== */ /* Order AA' or A(:,f)*A(:,f)' using CCOLAMD. */ int CHOLMOD(ccolamd) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to order */ Int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ Int *Cmember, /* size A->nrow. Cmember [i] = c if row i is in the * constraint set c. c must be >= 0. The # of * constraint sets is max (Cmember) + 1. If Cmember is * NULL, then it is interpretted as Cmember [i] = 0 for * all i */ /* ---- output --- */ Int *Perm, /* size A->nrow, output permutation */ /* --------------- */ cholmod_common *Common ) { cholmod_sparse *C ; Int ok, nrow, ncol ; size_t alen ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_NULL (Perm, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; if (A->stype != 0) { ERROR (CHOLMOD_INVALID, "matrix must be unsymmetric") ; return (FALSE) ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ nrow = A->nrow ; ncol = A->ncol ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ #ifdef LONG alen = ccolamd_l_recommended (A->nzmax, ncol, nrow) ; #else alen = ccolamd_recommended (A->nzmax, ncol, nrow) ; #endif if (alen == 0) { ERROR (CHOLMOD_TOO_LARGE, "matrix invalid or too large") ; return (FALSE) ; } CHOLMOD(allocate_work) (0, MAX (nrow,ncol), 0, Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; } C = CHOLMOD(allocate_sparse) (ncol, nrow, alen, TRUE, TRUE, 0, CHOLMOD_PATTERN, Common) ; /* ---------------------------------------------------------------------- */ /* order with ccolamd */ /* ---------------------------------------------------------------------- */ ok = ccolamd_interface (A, alen, Perm, Cmember, fset, fsize, C, Common) ; /* ---------------------------------------------------------------------- */ /* free the workspace and return result */ /* ---------------------------------------------------------------------- */ CHOLMOD(free_sparse) (&C, Common) ; return (ok) ; } #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Partition/cholmod_metis.c��������������������������������������������������������0000644�0001762�0000144�00000063044�13652535054�020354� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Partition/cholmod_metis ============================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Partition Module. * Copyright (C) 2005-2006, Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* CHOLMOD interface to the METIS package (Version 5.1.0): * * cholmod_metis_bisector: * * Wrapper for the METIS node separator function, * METIS_ComputeVertexSeparator (METIS 5.1). * * Finds a set of nodes that partitions the graph into two parts. METIS * 4.0 (the function METIS_ComputeVertexSeparator) allowed for edge * weights to be passed to the bisector. This feature is removed in METIS * 5.1. CHOLMOD itself does not rely on this feature (it calls the METIS * bisector with edge weights of all 1s). However, user code can call * cholmod_metis_bisector directly, and pass in edge weights. If you use * METIS 5.1, these edge weights are now ignored; if you pass a non-NULL * entry for edge weights, an error will be returned. * * cholmod_metis: * * Wrapper for METIS_NodeND, METIS's own nested dissection algorithm. * Typically faster than cholmod_nested_dissection, mostly because it * uses minimum degree on just the leaves of the separator tree, rather * than the whole matrix. * * Note that METIS does not return an error if it runs out of memory. Instead, * it terminates the program. This interface attempts to avoid that problem * by preallocating space that should be large enough for any memory allocations * within METIS, and then freeing that space, just before the call to METIS. * While this is not guaranteed to work, it is very unlikely to fail. If you * encounter this problem, increase Common->metis_memory. If you don't mind * having your program terminated, set Common->metis_memory to zero (a value of * 2.0 is usually safe). Several other METIS workarounds are made in the * routines in this file. See the description of metis_memory_ok, just below, * for more details. * * FUTURE WORK: interfaces to other partitioners (CHACO, SCOTCH, JOSTLE, ... ) * * workspace: several size-nz and size-n temporary arrays. Uses no workspace * in Common. * * Supports any xtype (pattern, real, complex, or zomplex). */ #ifndef NPARTITION #include "cholmod_internal.h" #include "metis.h" #include "cholmod_partition.h" #include "cholmod_cholesky.h" /* ========================================================================== */ /* === dumpgraph ============================================================ */ /* ========================================================================== */ /* For dumping the input graph to METIS_NodeND, to check with METIS's onmetis * and graphchk programs. For debugging only. To use, uncomment this #define: #define DUMP_GRAPH */ #ifdef DUMP_GRAPH #include /* After dumping the graph with this routine, run "onmetis metisgraph" */ static void dumpgraph (idx_t *Mp, idx_t *Mi, SuiteSparse_long n, cholmod_common *Common) { SuiteSparse_long i, j, p, nz ; FILE *f ; nz = Mp [n] ; printf ("Dumping METIS graph n %ld nz %ld\n", n, nz) ; /* DUMP_GRAPH */ f = fopen ("metisgraph", "w") ; if (f == NULL) { ERROR (-99, "cannot open metisgraph") ; return ; } fprintf (f, "%ld %ld\n", n, nz/2) ; /* DUMP_GRAPH */ for (j = 0 ; j < n ; j++) { for (p = Mp [j] ; p < Mp [j+1] ; p++) { i = Mi [p] ; fprintf (f, " %ld", i+1) ; /* DUMP_GRAPH */ } fprintf (f, "\n") ; /* DUMP_GRAPH */ } fclose (f) ; } #endif /* ========================================================================== */ /* === metis_memory_ok ====================================================== */ /* ========================================================================== */ /* METIS will terminate your program if * they run out of memory. In an attempt to workaround METIS' behavior, this * routine allocates a single block of memory of size equal to an observed * upper bound on METIS' memory usage. It then immediately deallocates the * block. If the allocation fails, METIS is not called. * * Median memory usage for a graph with n nodes and nz edges (counting each * edge twice, or both upper and lower triangular parts of a matrix) is * 4*nz + 40*n + 4096 integers. A "typical" upper bound is 10*nz + 50*n + 4096 * integers. Nearly all matrices tested fit within that upper bound, with the * exception two in the UF sparse matrix collection: Schenk_IBMNA/c-64 and * Gupta/gupta2. The latter exceeds the "upper bound" by a factor of just less * than 2. * * If you do not mind having your program terminated if it runs out of memory, * set Common->metis_memory to zero. Its default value is 2, which allows for * some memory fragmentation, and also accounts for the Gupta/gupta2 matrix. */ #define GUESS(nz,n) (10 * (nz) + 50 * (n) + 4096) static int metis_memory_ok ( Int n, Int nz, cholmod_common *Common ) { double s ; void *p ; size_t metis_guard ; if (Common->metis_memory <= 0) { /* do not prevent METIS from running out of memory */ return (TRUE) ; } n = MAX (1, n) ; nz = MAX (0, nz) ; /* compute in double, to avoid integer overflow */ s = GUESS ((double) nz, (double) n) ; s *= Common->metis_memory ; if (s * sizeof (idx_t) >= ((double) Size_max)) { /* don't even attempt to malloc such a large block */ return (FALSE) ; } /* recompute in size_t */ metis_guard = GUESS ((size_t) nz, (size_t) n) ; metis_guard *= Common->metis_memory ; /* attempt to malloc the block */ p = CHOLMOD(malloc) (metis_guard, sizeof (idx_t), Common) ; if (p == NULL) { /* failure - return out-of-memory condition */ return (FALSE) ; } /* success - free the block */ CHOLMOD(free) (metis_guard, sizeof (idx_t), p, Common) ; return (TRUE) ; } /* ========================================================================== */ /* === cholmod_metis_bisector =============================================== */ /* ========================================================================== */ /* Finds a set of nodes that bisects the graph of A or AA' (direct interface * to METIS_ComputeVertexSeparator. * * The input matrix A must be square, symmetric (with both upper and lower * parts present) and with no diagonal entries. These conditions are NOT * checked. */ SuiteSparse_long CHOLMOD(metis_bisector) /* returns separator size */ ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to bisect */ Int *Anw, /* size A->nrow, node weights, can be NULL, */ /* which means the graph is unweighted. */ Int *Aew, /* size nz, edge weights (silently ignored). */ /* This option was available with METIS 4, but not */ /* in METIS 5. This argument is now unused, but */ /* it remains for backward compatibilty, so as not */ /* to change the API for cholmod_metis_bisector. */ /* ---- output --- */ Int *Partition, /* size A->nrow */ /* --------------- */ cholmod_common *Common ) { Int *Ap, *Ai ; idx_t *Mp, *Mi, *Mnw, *Mpart ; Int n, nleft, nright, j, p, csep, total_weight, lightest, nz ; idx_t nn, csp ; size_t n1 ; int ok ; DEBUG (Int nsep) ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (EMPTY) ; RETURN_IF_NULL (A, EMPTY) ; /* RETURN_IF_NULL (Anw, EMPTY) ; */ /* RETURN_IF_NULL (Aew, EMPTY) ; */ RETURN_IF_NULL (Partition, EMPTY) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, EMPTY) ; if (A->stype || A->nrow != A->ncol) { /* A must be square, with both upper and lower parts present */ ERROR (CHOLMOD_INVALID, "matrix must be square, symmetric," " and with both upper/lower parts present") ; return (EMPTY) ; } Common->status = CHOLMOD_OK ; ASSERT (CHOLMOD(dump_sparse) (A, "A for bisector", Common) >= 0) ; /* ---------------------------------------------------------------------- */ /* quick return */ /* ---------------------------------------------------------------------- */ n = A->nrow ; if (n == 0) { return (0) ; } n1 = ((size_t) n) + 1 ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ Ap = A->p ; Ai = A->i ; nz = Ap [n] ; if (Anw != NULL) DEBUG (for (j = 0 ; j < n ; j++) ASSERT (Anw [j] > 0)) ; /* ---------------------------------------------------------------------- */ /* copy Int to METIS idx_t, if necessary */ /* ---------------------------------------------------------------------- */ if (sizeof (Int) == sizeof (idx_t)) { /* this is the typical case */ Mi = (idx_t *) Ai ; Mp = (idx_t *) Ap ; Mnw = (idx_t *) Anw ; Mpart = (idx_t *) Partition ; } else { /* idx_t and Int differ; copy the graph into the METIS idx_t */ Mi = CHOLMOD(malloc) (nz, sizeof (idx_t), Common) ; Mp = CHOLMOD(malloc) (n1, sizeof (idx_t), Common) ; Mnw = Anw ? (CHOLMOD(malloc) (n, sizeof (idx_t), Common)) : NULL ; Mpart = CHOLMOD(malloc) (n, sizeof (idx_t), Common) ; if (Common->status < CHOLMOD_OK) { CHOLMOD(free) (nz, sizeof (idx_t), Mi, Common) ; CHOLMOD(free) (n1, sizeof (idx_t), Mp, Common) ; CHOLMOD(free) (n, sizeof (idx_t), Mnw, Common) ; CHOLMOD(free) (n, sizeof (idx_t), Mpart, Common) ; return (EMPTY) ; } for (p = 0 ; p < nz ; p++) { Mi [p] = Ai [p] ; } for (j = 0 ; j <= n ; j++) { Mp [j] = Ap [j] ; } if (Anw != NULL) { for (j = 0 ; j < n ; j++) { Mnw [j] = Anw [j] ; } } } /* ---------------------------------------------------------------------- */ /* METIS workaround: try to ensure METIS doesn't run out of memory */ /* ---------------------------------------------------------------------- */ if (!metis_memory_ok (n, nz, Common)) { /* METIS might ask for too much memory and thus terminate the program */ if (sizeof (Int) != sizeof (idx_t)) { CHOLMOD(free) (nz, sizeof (idx_t), Mi, Common) ; CHOLMOD(free) (n1, sizeof (idx_t), Mp, Common) ; CHOLMOD(free) (n, sizeof (idx_t), Mnw, Common) ; CHOLMOD(free) (n, sizeof (idx_t), Mpart, Common) ; } return (EMPTY) ; } /* ---------------------------------------------------------------------- */ /* partition the graph */ /* ---------------------------------------------------------------------- */ #ifndef NDEBUG PRINT1 (("Metis graph, n = "ID"\n", n)) ; for (j = 0 ; j < n ; j++) { Int ppp, nodeweight = (Mnw ? Mnw [j] : 1) ; PRINT2 (("M(:,"ID") node weight "ID"\n", j, nodeweight)) ; ASSERT (nodeweight > 0) ; for (ppp = Mp [j] ; ppp < Mp [j+1] ; ppp++) { PRINT3 ((" "ID "\n", (Int) Mi [ppp])) ; ASSERT (Mi [ppp] != j) ; } } #endif /* METIS_ComputeVertexSeparator( idx_t *nvtxs, number of nodes idx_t *xadj, column pointers idx_t *adjncy, row indices idx_t *vwgt, vertex weights (NULL means unweighted) idx_t *options, options (NULL means defaults) idx_t *sepsize, separator size idx_t *part); partition. part [i] = 0,1,2, where: 0:left, 1:right, 2:separator */ nn = n ; ok = METIS_ComputeVertexSeparator (&nn, Mp, Mi, Mnw, NULL, &csp, Mpart) ; csep = csp ; PRINT1 (("METIS csep "ID"\n", csep)) ; /* ---------------------------------------------------------------------- */ /* copy the results back from idx_t, if required */ /* ---------------------------------------------------------------------- */ if (ok == METIS_OK && (sizeof (Int) != sizeof (idx_t))) { for (j = 0 ; j < n ; j++) { Partition [j] = Mpart [j] ; } } /* ---------------------------------------------------------------------- */ /* free the workspace for METIS, if allocated */ /* ---------------------------------------------------------------------- */ if (sizeof (Int) != sizeof (idx_t)) { CHOLMOD(free) (nz, sizeof (idx_t), Mi, Common) ; CHOLMOD(free) (n1, sizeof (idx_t), Mp, Common) ; CHOLMOD(free) (n, sizeof (idx_t), Mnw, Common) ; CHOLMOD(free) (n, sizeof (idx_t), Mpart, Common) ; } if (ok == METIS_ERROR_MEMORY) { ERROR (CHOLMOD_OUT_OF_MEMORY, "out of memory in METIS") ; return (EMPTY) ; } else if (ok == METIS_ERROR_INPUT) { ERROR (CHOLMOD_INVALID, "invalid input to METIS") ; return (EMPTY) ; } else if (ok == METIS_ERROR) { ERROR (CHOLMOD_INVALID, "unspecified METIS error") ; return (EMPTY) ; } /* ---------------------------------------------------------------------- */ /* ensure a reasonable separator */ /* ---------------------------------------------------------------------- */ /* METIS can return a valid separator with no nodes in (for example) the * left part. In this case, there really is no separator. CHOLMOD * prefers, in this case, for all nodes to be in the separator (and both * left and right parts to be empty). Also, if the graph is unconnected, * METIS can return a valid empty separator. CHOLMOD prefers at least one * node in the separator. Note that cholmod_nested_dissection only calls * this routine on connected components, but cholmod_bisect can call this * routine for any graph. */ if (csep == 0) { /* The separator is empty, select lightest node as separator. If * ties, select the highest numbered node. */ if (Anw == NULL) { lightest = n-1 ; } else { lightest = 0 ; for (j = 0 ; j < n ; j++) { if (Anw [j] <= Anw [lightest]) { lightest = j ; } } } PRINT1 (("Force "ID" as sep\n", lightest)) ; Partition [lightest] = 2 ; csep = (Anw ? (Anw [lightest]) : 1) ; } /* determine the node weights in the left and right part of the graph */ nleft = 0 ; nright = 0 ; DEBUG (nsep = 0) ; for (j = 0 ; j < n ; j++) { PRINT1 (("Partition ["ID"] = "ID"\n", j, Partition [j])) ; if (Partition [j] == 0) { nleft += (Anw ? (Anw [j]) : 1) ; } else if (Partition [j] == 1) { nright += (Anw ? (Anw [j]) : 1) ; } #ifndef NDEBUG else { ASSERT (Partition [j] == 2) ; nsep += (Anw ? (Anw [j]) : 1) ; } #endif } ASSERT (csep == nsep) ; total_weight = nleft + nright + csep ; if (csep < total_weight) { /* The separator is less than the whole graph. Make sure the left and * right parts are either both empty or both non-empty. */ PRINT1 (("nleft "ID" nright "ID" csep "ID" tot "ID"\n", nleft, nright, csep, total_weight)) ; ASSERT (nleft + nright + csep == total_weight) ; ASSERT (nleft > 0 || nright > 0) ; if ((nleft == 0 && nright > 0) || (nleft > 0 && nright == 0)) { /* left or right is empty; put all nodes in the separator */ PRINT1 (("Force all in sep\n")) ; csep = total_weight ; for (j = 0 ; j < n ; j++) { Partition [j] = 2 ; } } } ASSERT (CHOLMOD(dump_partition) (n, Ap, Ai, Anw, Partition, csep, Common)) ; /* ---------------------------------------------------------------------- */ /* return the sum of the weights of nodes in the separator */ /* ---------------------------------------------------------------------- */ return (csep) ; } /* ========================================================================== */ /* === cholmod_metis ======================================================== */ /* ========================================================================== */ /* CHOLMOD wrapper for the METIS_NodeND ordering routine. Creates A+A', * A*A' or A(:,f)*A(:,f)' and then calls METIS_NodeND on the resulting graph. * This routine is comparable to cholmod_nested_dissection, except that it * calls METIS_NodeND directly, and it does not return the separator tree. * * workspace: Flag (nrow), Iwork (4*n+uncol) * Allocates a temporary matrix B=A*A' or B=A. */ int CHOLMOD(metis) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to order */ Int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ int postorder, /* if TRUE, follow with etree or coletree postorder */ /* ---- output --- */ Int *Perm, /* size A->nrow, output permutation */ /* --------------- */ cholmod_common *Common ) { double d ; Int *Iperm, *Iwork, *Bp, *Bi ; idx_t *Mp, *Mi, *Mperm, *Miperm ; cholmod_sparse *B ; Int i, j, n, nz, p, identity, uncol ; idx_t nn, zero = 0 ; size_t n1, s ; int ok = TRUE ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_NULL (Perm, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* quick return */ /* ---------------------------------------------------------------------- */ n = A->nrow ; if (n == 0) { return (TRUE) ; } n1 = ((size_t) n) + 1 ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ /* s = 4*n + uncol */ uncol = (A->stype == 0) ? A->ncol : 0 ; s = CHOLMOD(mult_size_t) (n, 4, &ok) ; s = CHOLMOD(add_size_t) (s, uncol, &ok) ; if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (FALSE) ; } CHOLMOD(allocate_work) (n, s, 0, Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; /* ---------------------------------------------------------------------- */ /* convert the matrix to adjacency list form */ /* ---------------------------------------------------------------------- */ /* The input graph for METIS must be symmetric, with both upper and lower * parts present, and with no diagonal entries. The columns need not be * sorted. * B = A+A', A*A', or A(:,f)*A(:,f)', upper and lower parts present */ if (A->stype) { /* Add the upper/lower part to a symmetric lower/upper matrix by * converting to unsymmetric mode */ /* workspace: Iwork (nrow) */ B = CHOLMOD(copy) (A, 0, -1, Common) ; } else { /* B = A*A' or A(:,f)*A(:,f)', no diagonal */ /* workspace: Flag (nrow), Iwork (max (nrow,ncol)) */ B = CHOLMOD(aat) (A, fset, fsize, -1, Common) ; } ASSERT (CHOLMOD(dump_sparse) (B, "B for NodeND", Common) >= 0) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; } ASSERT (B->nrow == A->nrow) ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ Iwork = Common->Iwork ; Iperm = Iwork ; /* size n (i/i/l) */ Bp = B->p ; Bi = B->i ; nz = Bp [n] ; /* B does not include the diagonal, and both upper and lower parts. * Common->anz includes the diagonal, and just the lower part of B */ Common->anz = nz / 2 + n ; /* ---------------------------------------------------------------------- */ /* allocate the METIS input arrays, if needed */ /* ---------------------------------------------------------------------- */ if (sizeof (Int) == sizeof (idx_t)) { /* This is the typical case. */ Miperm = (idx_t *) Iperm ; Mperm = (idx_t *) Perm ; Mp = (idx_t *) Bp ; Mi = (idx_t *) Bi ; } else { /* allocate graph for METIS only if Int and idx_t differ */ Miperm = CHOLMOD(malloc) (n, sizeof (idx_t), Common) ; Mperm = CHOLMOD(malloc) (n, sizeof (idx_t), Common) ; Mp = CHOLMOD(malloc) (n1, sizeof (idx_t), Common) ; Mi = CHOLMOD(malloc) (nz, sizeof (idx_t), Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ CHOLMOD(free_sparse) (&B, Common) ; CHOLMOD(free) (n, sizeof (idx_t), Miperm, Common) ; CHOLMOD(free) (n, sizeof (idx_t), Mperm, Common) ; CHOLMOD(free) (n1, sizeof (idx_t), Mp, Common) ; CHOLMOD(free) (nz, sizeof (idx_t), Mi, Common) ; return (FALSE) ; } for (j = 0 ; j <= n ; j++) { Mp [j] = Bp [j] ; } for (p = 0 ; p < nz ; p++) { Mi [p] = Bi [p] ; } } /* ---------------------------------------------------------------------- */ /* METIS workarounds */ /* ---------------------------------------------------------------------- */ identity = FALSE ; if (nz == 0) { /* The matrix has no off-diagonal entries. METIS_NodeND fails in this * case, so avoid using it. The best permutation is identity anyway, * so this is an easy fix. */ identity = TRUE ; PRINT1 (("METIS:: no nz\n")) ; } else if (Common->metis_nswitch > 0) { /* METIS_NodeND in METIS 4.0.1 gives a seg fault with one matrix of * order n = 3005 and nz = 6,036,025, including the diagonal entries. * The workaround is to return the identity permutation instead of using * METIS for matrices of dimension 3000 or more and with density of 66% * or more - admittedly an uncertain fix, but such matrices are so dense * that any reasonable ordering will do, even identity (n^2 is only 50% * higher than nz in this case). CHOLMOD's nested dissection method * (cholmod_nested_dissection) has no problems with the same matrix, * even though it too uses METIS_ComputeVertexSeparator. The matrix is * derived from LPnetlib/lpi_cplex1 in the UF sparse matrix collection. * If C is the lpi_cplex matrix (of order 3005-by-5224), A = (C*C')^2 * results in the seg fault. The seg fault also occurs in the stand- * alone onmetis program that comes with METIS. If a future version of * METIS fixes this problem, then set Common->metis_nswitch to zero. */ d = ((double) nz) / (((double) n) * ((double) n)) ; if (n > (Int) (Common->metis_nswitch) && d > Common->metis_dswitch) { identity = TRUE ; PRINT1 (("METIS:: nswitch/dswitch activated\n")) ; } } if (!identity && !metis_memory_ok (n, nz, Common)) { /* METIS might ask for too much memory and thus terminate the program */ identity = TRUE ; } /* ---------------------------------------------------------------------- */ /* find the permutation */ /* ---------------------------------------------------------------------- */ if (identity) { /* no need to do the postorder */ postorder = FALSE ; for (i = 0 ; i < n ; i++) { Mperm [i] = i ; } } else { #ifdef DUMP_GRAPH /* DUMP_GRAPH */ printf ("Calling METIS_NodeND n "ID" nz "ID"" "density %g\n", n, nz, ((double) nz) / (((double) n) * ((double) n))); dumpgraph (Mp, Mi, n, Common) ; #endif /* int METIS_NodeND( idx_t *nvtxs, number of nodes idx_t *xadj, column pointers idx_t *adjncy, row indices idx_t *vwgt, vertex weights (NULL means unweighted) idx_t *options, options (NULL means defaults) idx_t *perm, fill-reducing ordering idx_t *iperm); inverse of perm */ nn = n ; METIS_NodeND (&nn, Mp, Mi, NULL, NULL, Mperm, Miperm) ; PRINT0 (("METIS_NodeND done\n")) ; } /* ---------------------------------------------------------------------- */ /* free the METIS input arrays */ /* ---------------------------------------------------------------------- */ if (sizeof (Int) != sizeof (idx_t)) { for (i = 0 ; i < n ; i++) { Perm [i] = (Int) (Mperm [i]) ; } CHOLMOD(free) (n, sizeof (idx_t), Miperm, Common) ; CHOLMOD(free) (n, sizeof (idx_t), Mperm, Common) ; CHOLMOD(free) (n+1, sizeof (idx_t), Mp, Common) ; CHOLMOD(free) (nz, sizeof (idx_t), Mi, Common) ; } CHOLMOD(free_sparse) (&B, Common) ; /* ---------------------------------------------------------------------- */ /* etree or column-etree postordering, using the Cholesky Module */ /* ---------------------------------------------------------------------- */ if (postorder) { Int *Parent, *Post, *NewPerm ; Int k ; Parent = Iwork + 2*((size_t) n) + uncol ; /* size n = nrow */ Post = Parent + n ; /* size n */ /* workspace: Iwork (2*nrow+uncol), Flag (nrow), Head (nrow+1) */ CHOLMOD(analyze_ordering) (A, CHOLMOD_METIS, Perm, fset, fsize, Parent, Post, NULL, NULL, NULL, Common) ; if (Common->status == CHOLMOD_OK) { /* combine the METIS permutation with its postordering */ NewPerm = Parent ; /* use Parent as workspace */ for (k = 0 ; k < n ; k++) { NewPerm [k] = Perm [Post [k]] ; } for (k = 0 ; k < n ; k++) { Perm [k] = NewPerm [k] ; } } } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; PRINT1 (("cholmod_metis done\n")) ; return (Common->status == CHOLMOD_OK) ; } #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Partition/cholmod_csymamd.c������������������������������������������������������0000644�0001762�0000144�00000010776�13652535054�020674� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Partition/cholmod_csymamd ============================================ */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Partition Module. * Copyright (C) 2005-2013, Univ. of Florida. Author: Timothy A. Davis * -------------------------------------------------------------------------- */ /* CHOLMOD interface to the CSYMAMD ordering routine. Finds a permutation * p such that the Cholesky factorization of PAP' is sparser than A. * The column etree is found and postordered, and the CSYMAMD * ordering is then combined with its postordering. If A is unsymmetric, * A+A' is ordered (A must be square). * * workspace: Head (nrow+1) * * Supports any xtype (pattern, real, complex, or zomplex). */ #ifndef NCAMD #include "cholmod_internal.h" #include "ccolamd.h" #include "cholmod_camd.h" #if (CCOLAMD_VERSION < CCOLAMD_VERSION_CODE (2,5)) #error "CCOLAMD v2.0 or later is required" #endif /* ========================================================================== */ /* === cholmod_csymamd ====================================================== */ /* ========================================================================== */ int CHOLMOD(csymamd) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to order */ /* ---- output --- */ Int *Cmember, /* size nrow. see cholmod_ccolamd.c for description */ Int *Perm, /* size A->nrow, output permutation */ /* --------------- */ cholmod_common *Common ) { double knobs [CCOLAMD_KNOBS] ; Int *perm, *Head ; Int ok, i, nrow, stats [CCOLAMD_STATS] ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_NULL (Perm, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; Common->status = CHOLMOD_OK ; if (A->nrow != A->ncol || !(A->packed)) { ERROR (CHOLMOD_INVALID, "matrix must be square and packed") ; return (FALSE) ; } /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ nrow = A->nrow ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ CHOLMOD(allocate_work) (nrow, 0, 0, Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; } /* ---------------------------------------------------------------------- */ /* order the matrix (does not affect A->p or A->i) */ /* ---------------------------------------------------------------------- */ perm = Common->Head ; /* size nrow+1 (i/l/l) */ /* get parameters */ #ifdef LONG ccolamd_l_set_defaults (knobs) ; #else ccolamd_set_defaults (knobs) ; #endif if (Common->current >= 0 && Common->current < CHOLMOD_MAXMETHODS) { /* get the knobs from the Common parameters */ knobs [CCOLAMD_DENSE_ROW] =Common->method[Common->current].prune_dense ; knobs [CCOLAMD_AGGRESSIVE]=Common->method[Common->current].aggressive ; } { #ifdef LONG csymamd_l (nrow, A->i, A->p, perm, knobs, stats, SuiteSparse_config.calloc_func, SuiteSparse_config.free_func, Cmember, A->stype) ; #else csymamd (nrow, A->i, A->p, perm, knobs, stats, SuiteSparse_config.calloc_func, SuiteSparse_config.free_func, Cmember, A->stype) ; #endif ok = stats [CCOLAMD_STATUS] ; } if (ok == CCOLAMD_ERROR_out_of_memory) { ERROR (CHOLMOD_OUT_OF_MEMORY, "out of memory") ; } ok = (ok == CCOLAMD_OK || ok == CCOLAMD_OK_BUT_JUMBLED) ; /* ---------------------------------------------------------------------- */ /* free the workspace and return result */ /* ---------------------------------------------------------------------- */ /* permutation returned in perm [0..n-1] */ for (i = 0 ; i < nrow ; i++) { Perm [i] = perm [i] ; } /* clear Head workspace (used for perm, in csymamd): */ Head = Common->Head ; for (i = 0 ; i <= nrow ; i++) { Head [i] = EMPTY ; } return (ok) ; } #endif ��Matrix/src/CHOLMOD/Partition/License.txt������������������������������������������������������������0000644�0001762�0000144�00000002104�11770402705�017466� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CHOLMOD/Partition Module. Copyright (C) 2005-2006, Univ. of Florida. Author: Timothy A. Davis CHOLMOD is also available under other licenses; contact authors for details. http://www.suitesparse.com Note that this license is for the CHOLMOD/Partition module only. All CHOLMOD modules are licensed separately. -------------------------------------------------------------------------------- This Module is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This Module 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this Module; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Partition/cholmod_camd.c���������������������������������������������������������0000644�0001762�0000144�00000016022�13652535054�020131� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Partition/cholmod_camd =============================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Partition Module. Copyright (C) 2005-2013, Timothy A. Davis * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* CHOLMOD interface to the CAMD ordering routine. Orders A if the matrix is * symmetric. On output, Perm [k] = i if row/column i of A is the kth * row/column of P*A*P'. This corresponds to A(p,p) in MATLAB notation. * * If A is unsymmetric, cholmod_camd orders A*A'. On output, Perm [k] = i if * row/column i of A*A' is the kth row/column of P*A*A'*P'. This corresponds to * A(p,:)*A(p,:)' in MATLAB notation. If f is present, A(p,f)*A(p,f)' is * ordered. * * Computes the flop count for a subsequent LL' factorization, the number * of nonzeros in L, and the number of nonzeros in the matrix ordered (A, * A*A' or A(:,f)*A(:,f)'). * * workspace: Iwork (4*nrow). Head (nrow). * * Allocates a temporary copy of A+A' or A*A' (with * both upper and lower triangular parts) as input to CAMD. * Also allocates 3*(n+1) additional integer workspace (not in Common). * * Supports any xtype (pattern, real, complex, or zomplex) */ #ifndef NCAMD #include "cholmod_internal.h" #include "camd.h" #include "cholmod_camd.h" #if (CAMD_VERSION < CAMD_VERSION_CODE (2,0)) #error "CAMD v2.0 or later is required" #endif /* ========================================================================== */ /* === cholmod_camd ========================================================= */ /* ========================================================================== */ int CHOLMOD(camd) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to order */ Int *fset, /* subset of 0:(A->ncol)-1 */ size_t fsize, /* size of fset */ Int *Cmember, /* size nrow. see cholmod_ccolamd.c for description.*/ /* ---- output ---- */ Int *Perm, /* size A->nrow, output permutation */ /* --------------- */ cholmod_common *Common ) { double Info [CAMD_INFO], Control2 [CAMD_CONTROL], *Control ; Int *Cp, *Len, *Nv, *Head, *Elen, *Degree, *Wi, *Next, *BucketSet, *Work3n, *p ; cholmod_sparse *C ; Int j, n, cnz ; size_t s ; int ok = TRUE ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; n = A->nrow ; /* s = 4*n */ s = CHOLMOD(mult_size_t) (n, 4, &ok) ; if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (FALSE) ; } RETURN_IF_NULL (Perm, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; Common->status = CHOLMOD_OK ; if (n == 0) { /* nothing to do */ Common->fl = 0 ; Common->lnz = 0 ; Common->anz = 0 ; return (TRUE) ; } /* ---------------------------------------------------------------------- */ /* get workspace */ /* ---------------------------------------------------------------------- */ /* cholmod_analyze has allocated Cmember at Common->Iwork + 5*n+uncol, and * CParent at Common->Iwork + 4*n+uncol, where uncol is 0 if A is symmetric * or A->ncol otherwise. Thus, only the first 4n integers in Common->Iwork * can be used here. */ CHOLMOD(allocate_work) (n, s, 0, Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; } p = Common->Iwork ; Degree = p ; p += n ; /* size n */ Elen = p ; p += n ; /* size n */ Len = p ; p += n ; /* size n */ Nv = p ; p += n ; /* size n */ Work3n = CHOLMOD(malloc) (n+1, 3*sizeof (Int), Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; } p = Work3n ; Next = p ; p += n ; /* size n */ Wi = p ; p += (n+1) ; /* size n+1 */ BucketSet = p ; /* size n */ Head = Common->Head ; /* size n+1 */ /* ---------------------------------------------------------------------- */ /* construct the input matrix for CAMD */ /* ---------------------------------------------------------------------- */ if (A->stype == 0) { /* C = A*A' or A(:,f)*A(:,f)', add extra space of nnz(C)/2+n to C */ C = CHOLMOD(aat) (A, fset, fsize, -2, Common) ; } else { /* C = A+A', but use only the upper triangular part of A if A->stype = 1 * and only the lower part of A if A->stype = -1. Add extra space of * nnz(C)/2+n to C. */ C = CHOLMOD(copy) (A, 0, -2, Common) ; } if (Common->status < CHOLMOD_OK) { /* out of memory, fset invalid, or other error */ CHOLMOD(free) (n+1, 3*sizeof (Int), Work3n, Common) ; return (FALSE) ; } Cp = C->p ; for (j = 0 ; j < n ; j++) { Len [j] = Cp [j+1] - Cp [j] ; } /* C does not include the diagonal, and both upper and lower parts. * Common->anz includes the diagonal, and just the lower part of C */ cnz = Cp [n] ; Common->anz = cnz / 2 + n ; /* ---------------------------------------------------------------------- */ /* order C using CAMD */ /* ---------------------------------------------------------------------- */ /* get parameters */ if (Common->current < 0 || Common->current >= CHOLMOD_MAXMETHODS) { /* use CAMD defaults */ Control = NULL ; } else { Control = Control2 ; Control [CAMD_DENSE] = Common->method [Common->current].prune_dense ; Control [CAMD_AGGRESSIVE] = Common->method [Common->current].aggressive; } #ifdef LONG /* DEBUG (camd_l_debug_init ("cholmod_l_camd")) ; */ camd_l2 (n, C->p, C->i, Len, C->nzmax, cnz, Nv, Next, Perm, Head, Elen, Degree, Wi, Control, Info, Cmember, BucketSet) ; #else /* DEBUG (camd_debug_init ("cholmod_camd")) ; */ camd_2 (n, C->p, C->i, Len, C->nzmax, cnz, Nv, Next, Perm, Head, Elen, Degree, Wi, Control, Info, Cmember, BucketSet) ; #endif /* LL' flop count. Need to subtract n for LL' flop count. Note that this * is a slight upper bound which is often exact (see CAMD/Source/camd_2.c * for details). cholmod_analyze computes an exact flop count and * fill-in. */ Common->fl = Info [CAMD_NDIV] + 2 * Info [CAMD_NMULTSUBS_LDL] + n ; /* Info [CAMD_LNZ] excludes the diagonal */ Common->lnz = n + Info [CAMD_LNZ] ; /* ---------------------------------------------------------------------- */ /* free the CAMD workspace and clear the persistent workspace in Common */ /* ---------------------------------------------------------------------- */ ASSERT (IMPLIES (Common->status == CHOLMOD_OK, CHOLMOD(dump_perm) (Perm, n, n, "CAMD2 perm", Common))) ; CHOLMOD(free_sparse) (&C, Common) ; for (j = 0 ; j <= n ; j++) { Head [j] = EMPTY ; } CHOLMOD(free) (n+1, 3*sizeof (Int), Work3n, Common) ; return (TRUE) ; } #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Modify/��������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14547723665�014644� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Modify/cholmod_rowadd.c����������������������������������������������������������0000644�0001762�0000144�00000046123�13652535054�017770� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Modify/cholmod_rowadd ================================================ */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Modify Module. * Copyright (C) 2005-2006, Timothy A. Davis and William W. Hager. * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* Adds a row and column to an LDL' factorization, and optionally updates the * solution to Lx=b. * * workspace: Flag (nrow), Head (nrow+1), W (2*nrow), Iwork (2*nrow) * * Only real matrices are supported. A symbolic L is converted into a * numeric identity matrix before the row is added. */ #ifndef NGPL #ifndef NMODIFY #include "cholmod_internal.h" #include "cholmod_modify.h" /* ========================================================================== */ /* === cholmod_rowadd ======================================================= */ /* ========================================================================== */ /* cholmod_rowadd adds a row to the LDL' factorization. It computes the kth * row and kth column of L, and then updates the submatrix L (k+1:n,k+1:n) * accordingly. The kth row and column of L should originally be equal to the * kth row and column of the identity matrix (they are treated as such, if they * are not). The kth row/column of L is computed as the factorization of the * kth row/column of the matrix to factorize, which is provided as a single * n-by-1 sparse matrix R. The sparse vector R need not be sorted. */ int CHOLMOD(rowadd) ( /* ---- input ---- */ size_t k, /* row/column index to add */ cholmod_sparse *R, /* row/column of matrix to factorize (n-by-1) */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ /* --------------- */ cholmod_common *Common ) { double bk [2] ; bk [0] = 0. ; bk [1] = 0. ; return (CHOLMOD(rowadd_mark) (k, R, bk, NULL, L, NULL, NULL, Common)) ; } /* ========================================================================== */ /* === cholmod_rowadd_solve ================================================= */ /* ========================================================================== */ /* Does the same as cholmod_rowadd, and also updates the solution to Lx=b * See cholmod_updown for a description of how Lx=b is updated. There is on * additional parameter: bk specifies the new kth entry of b. */ int CHOLMOD(rowadd_solve) ( /* ---- input ---- */ size_t k, /* row/column index to add */ cholmod_sparse *R, /* row/column of matrix to factorize (n-by-1) */ double bk [2], /* kth entry of the right-hand-side b */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ cholmod_dense *X, /* solution to Lx=b (size n-by-1) */ cholmod_dense *DeltaB, /* change in b, zero on output */ /* --------------- */ cholmod_common *Common ) { return (CHOLMOD(rowadd_mark) (k, R, bk, NULL, L, X, DeltaB, Common)) ; } /* ========================================================================== */ /* === icomp ================================================================ */ /* ========================================================================== */ /* for sorting by qsort */ static int icomp (Int *i, Int *j) { if (*i < *j) { return (-1) ; } else { return (1) ; } } /* ========================================================================== */ /* === cholmod_rowadd_mark ================================================== */ /* ========================================================================== */ /* Does the same as cholmod_rowadd_solve, except only part of L is used in * the update/downdate of the solution to Lx=b. This routine is an "expert" * routine. It is meant for use in LPDASA only. */ int CHOLMOD(rowadd_mark) ( /* ---- input ---- */ size_t kadd, /* row/column index to add */ cholmod_sparse *R, /* row/column of matrix to factorize (n-by-1) */ double bk [2], /* kth entry of the right hand side, b */ Int *colmark, /* Int array of size 1. See cholmod_updown.c */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ cholmod_dense *X, /* solution to Lx=b (size n-by-1) */ cholmod_dense *DeltaB, /* change in b, zero on output */ /* --------------- */ cholmod_common *Common ) { double dk, yj, l_kj, lx, l_ij, sqrt_dk, dj, xk, rnz, fl ; double *Lx, *W, *Cx, *Rx, *Xx, *Nx ; Int *Li, *Lp, *Lnz, *Flag, *Stack, *Ci, *Rj, *Rp, *Lnext, *Iwork, *Rnz ; cholmod_sparse *C, Cmatrix ; Int i, j, p, pend, top, len, kk, li, lnz, mark, k, n, parent, Cp [2], do_solve, do_update ; size_t s ; int ok = TRUE ; DEBUG (Int lastrow) ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (L, FALSE) ; RETURN_IF_NULL (R, FALSE) ; RETURN_IF_XTYPE_INVALID (L, CHOLMOD_PATTERN, CHOLMOD_REAL, FALSE) ; RETURN_IF_XTYPE_INVALID (R, CHOLMOD_REAL, CHOLMOD_REAL, FALSE) ; n = L->n ; k = kadd ; if (kadd >= L->n || k < 0) { ERROR (CHOLMOD_INVALID, "k invalid") ; return (FALSE) ; } if (R->ncol != 1 || R->nrow != L->n) { ERROR (CHOLMOD_INVALID, "R invalid") ; return (FALSE) ; } Rj = R->i ; Rx = R->x ; Rp = R->p ; Rnz = R->nz ; rnz = (R->packed) ? (Rp [1]) : (Rnz [0]) ; do_solve = (X != NULL) && (DeltaB != NULL) ; if (do_solve) { RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_REAL, FALSE) ; RETURN_IF_XTYPE_INVALID (DeltaB, CHOLMOD_REAL, CHOLMOD_REAL, FALSE) ; Xx = X->x ; Nx = DeltaB->x ; if (X->nrow != L->n || X->ncol != 1 || DeltaB->nrow != L->n || DeltaB->ncol != 1 || Xx == NULL || Nx == NULL) { ERROR (CHOLMOD_INVALID, "X and/or DeltaB invalid") ; return (FALSE) ; } } else { Xx = NULL ; Nx = NULL ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ /* s = 2*n */ s = CHOLMOD(mult_size_t) (n, 2, &ok) ; if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (FALSE) ; } CHOLMOD(allocate_work) (n, s, s, Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, s, Common)) ; /* ---------------------------------------------------------------------- */ /* convert to simplicial numeric LDL' factor, if not already */ /* ---------------------------------------------------------------------- */ if (L->xtype == CHOLMOD_PATTERN || L->is_super || L->is_ll) { /* can only update/downdate a simplicial LDL' factorization */ CHOLMOD(change_factor) (CHOLMOD_REAL, FALSE, FALSE, FALSE, FALSE, L, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory, L is returned unchanged */ return (FALSE) ; } } /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ /* inputs, not modified on output: */ Lp = L->p ; /* size n+1. input, not modified on output */ /* outputs, contents defined on input for incremental case only: */ Lnz = L->nz ; /* size n */ Li = L->i ; /* size L->nzmax. Can change in size. */ Lx = L->x ; /* size L->nzmax. Can change in size. */ Lnext = L->next ; /* size n+2 */ ASSERT (L->nz != NULL) ; PRINT1 (("rowadd:\n")) ; fl = 0 ; #if 0 #ifndef NDEBUG /* column k of L should be zero, except for the diagonal. This test is * overly cautious. */ for (p = Lp [k] + 1 ; p < Lp [k] + Lnz [k] ; p++) ASSERT (Lx [p] == 0) ; #endif #endif /* ---------------------------------------------------------------------- */ /* get workspace */ /* ---------------------------------------------------------------------- */ Flag = Common->Flag ; /* size n */ W = Common->Xwork ; /* size n */ Cx = W + n ; /* size n (use 2nd column of Xwork for C) */ Iwork = Common->Iwork ; Stack = Iwork ; /* size n (i/i/l), also in cholmod_updown */ Ci = Iwork + n ; /* size n (i/i/l) */ /* NOTE: cholmod_updown uses Iwork [0..n-1] (i/i/l) as Stack as well */ mark = Common->mark ; /* copy Rj/Rx into W/Ci */ for (p = 0 ; p < rnz ; p++) { i = Rj [p] ; ASSERT (i >= 0 && i < n) ; W [i] = Rx [p] ; Ci [p] = i ; } /* At this point, W [Ci [0..rnz-1]] holds the sparse vector to add */ /* The nonzero pattern of column W is held in Ci (it may be unsorted). */ /* ---------------------------------------------------------------------- */ /* symbolic factorization to get pattern of kth row of L */ /* ---------------------------------------------------------------------- */ DEBUG (for (p = 0 ; p < rnz ; p++) PRINT1 (("C ("ID",%g)\n", Ci [p], W [Ci [p]]))) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; /* flag the diagonal */ Flag [k] = mark ; /* find the union of all the paths */ top = n ; lnz = 0 ; /* # of nonzeros in column k of L, excluding diagonal */ for (p = 0 ; p < rnz ; p++) { i = Ci [p] ; if (i < k) { /* walk from i = entry in Ci to root (and stop if i marked)*/ PRINT2 (("\nwalk from i = "ID" towards k = "ID"\n", i, k)) ; len = 0 ; /* walk up tree, but stop if we go below the diagonal */ while (i < k && i != EMPTY && Flag [i] < mark) { PRINT2 ((" Add "ID" to path\n", i)) ; ASSERT (i >= 0 && i < k) ; Stack [len++] = i ; /* place i on the stack */ Flag [i] = mark ; /* mark i as visited */ /* parent is the first entry in the column after the diagonal */ ASSERT (Lnz [i] > 0) ; parent = (Lnz [i] > 1) ? (Li [Lp [i] + 1]) : EMPTY ; PRINT2 ((" parent: "ID"\n", parent)) ; i = parent ; /* go up the tree */ } ASSERT (len <= top) ; /* move the path down to the bottom of the stack */ /* this shifts Stack [0..len-1] down to [ ... oldtop-1] */ while (len > 0) { Stack [--top] = Stack [--len] ; } } else if (i > k) { /* prune the diagonal and upper triangular entries from Ci */ Ci [lnz++] = i ; Flag [i] = mark ; } } #ifndef NDEBUG PRINT1 (("length of S after prune: "ID"\n", lnz)) ; for (p = 0 ; p < lnz ; p++) { PRINT1 (("After prune Ci ["ID"] = "ID"\n", p, Ci [p])) ; ASSERT (Ci [p] > k) ; } #endif /* ---------------------------------------------------------------------- */ /* ensure each column of L has enough space to grow */ /* ---------------------------------------------------------------------- */ for (kk = top ; kk < n ; kk++) { /* could skip this if we knew column j already included row k */ j = Stack [kk] ; if (Lp [j] + Lnz [j] >= Lp [Lnext [j]]) { PRINT1 (("Col "ID" realloc, old Lnz "ID"\n", j, Lnz [j])) ; if (!CHOLMOD(reallocate_column) (j, Lnz [j] + 1, L, Common)) { /* out of memory, L is now simplicial symbolic */ /* CHOLMOD(clear_flag) (Common) ; */ CHOLMOD_CLEAR_FLAG (Common) ; for (i = 0 ; i < n ; i++) { W [i] = 0 ; } return (FALSE) ; } /* L->i and L->x may have moved */ Li = L->i ; Lx = L->x ; } ASSERT (Lp [j] + Lnz [j] < Lp [Lnext [j]] || (Lp [Lnext [j]] - Lp [j] == n-j)) ; } /* ---------------------------------------------------------------------- */ /* compute kth row of L and store in column form */ /* ---------------------------------------------------------------------- */ /* solve L (1:k-1, 1:k-1) * y (1:k-1) = b (1:k-1) */ /* where b (1:k) is in W and Ci */ /* L (k, 1:k-1) = y (1:k-1) ./ D (1:k-1) */ /* D (k) = B (k,k) - L (k, 1:k-1) * y (1:k-1) */ PRINT2 (("\nForward solve: "ID" to "ID"\n", top, n)) ; ASSERT (Lnz [k] >= 1 && Li [Lp [k]] == k) ; DEBUG (for (i = top ; i < n ; i++) PRINT2 ((" Path: "ID"\n", Stack [i]))) ; dk = W [k] ; W [k] = 0.0 ; /* if do_solve: compute x (k) = b (k) - L (k, 1:k-1) * x (1:k-1) */ xk = bk [0] ; PRINT2 (("B [k] = %g\n", xk)) ; for (kk = top ; kk < n ; kk++) { j = Stack [kk] ; i = j ; PRINT2 (("Forward solve col j = "ID":\n", j)) ; ASSERT (j >= 0 && j < k) ; /* forward solve using L (j+1:k-1,j) */ yj = W [j] ; W [j] = 0.0 ; p = Lp [j] ; pend = p + Lnz [j] ; ASSERT (Lnz [j] > 0) ; dj = Lx [p++] ; for ( ; p < pend ; p++) { i = Li [p] ; PRINT2 ((" row "ID"\n", i)) ; ASSERT (i > j) ; ASSERT (i < n) ; /* stop at row k */ if (i >= k) { break ; } W [i] -= Lx [p] * yj ; } /* each iteration of the above for loop did 2 flops, and 3 flops * are done below. so: fl += 2 * (Lp [j] - p - 1) + 3 becomes: */ fl += 2 * (Lp [j] - p) + 1 ; /* scale L (k,1:k-1) and compute dot product for D (k,k) */ l_kj = yj / dj ; dk -= l_kj * yj ; /* compute dot product for X(k) */ if (do_solve) { xk -= l_kj * Xx [j] ; } /* store l_kj in the jth column of L */ /* and shift the rest of the column down */ li = k ; lx = l_kj ; if (i == k) { /* no need to modify the nonzero pattern of L, since it already * contains row index k. */ ASSERT (Li [p] == k) ; Lx [p] = l_kj ; for (p++ ; p < pend ; p++) { i = Li [p] ; l_ij = Lx [p] ; ASSERT (i > k && i < n) ; PRINT2 ((" apply to row "ID" of column k of L\n", i)) ; /* add to the pattern of the kth column of L */ if (Flag [i] < mark) { PRINT2 ((" add Ci["ID"] = "ID"\n", lnz, i)) ; ASSERT (i > k) ; Ci [lnz++] = i ; Flag [i] = mark ; } /* apply the update to the kth column of L */ /* yj is equal to l_kj * d_j */ W [i] -= l_ij * yj ; } } else { PRINT2 (("Shift col j = "ID", apply saxpy to col k of L\n", j)) ; for ( ; p < pend ; p++) { /* swap (Li [p],Lx [p]) with (li,lx) */ i = Li [p] ; l_ij = Lx [p] ; Li [p] = li ; Lx [p] = lx ; li = i ; lx = l_ij ; ASSERT (i > k && i < n) ; PRINT2 ((" apply to row "ID" of column k of L\n", i)) ; /* add to the pattern of the kth column of L */ if (Flag [i] < mark) { PRINT2 ((" add Ci["ID"] = "ID"\n", lnz, i)) ; ASSERT (i > k) ; Ci [lnz++] = i ; Flag [i] = mark ; } /* apply the update to the kth column of L */ /* yj is equal to l_kj * d_j */ W [i] -= l_ij * yj ; } /* store the last value in the jth column of L */ Li [p] = li ; Lx [p] = lx ; Lnz [j]++ ; } } /* ---------------------------------------------------------------------- */ /* merge C with the pattern of the existing column of L */ /* ---------------------------------------------------------------------- */ /* This column should be zero, but it may contain explicit zero entries. * These entries should be kept, not dropped. */ p = Lp [k] ; pend = p + Lnz [k] ; for (p++ ; p < pend ; p++) { i = Li [p] ; /* add to the pattern of the kth column of L */ if (Flag [i] < mark) { PRINT2 ((" add Ci["ID"] = "ID" from existing col k\n", lnz, i)) ; ASSERT (i > k) ; Ci [lnz++] = i ; Flag [i] = mark ; } } /* ---------------------------------------------------------------------- */ if (do_solve) { Xx [k] = xk ; PRINT2 (("Xx [k] = %g\n", Xx [k])) ; } /* ---------------------------------------------------------------------- */ /* ensure abs (dk) >= dbound, if dbound is given */ /* ---------------------------------------------------------------------- */ dk = (IS_GT_ZERO (Common->dbound)) ? (CHOLMOD(dbound) (dk, Common)) : dk ; PRINT2 (("D [k = "ID"] = %g\n", k, dk)) ; /* ---------------------------------------------------------------------- */ /* store the kth column of L */ /* ---------------------------------------------------------------------- */ /* ensure the new column of L has enough space */ if (Lp [k] + lnz + 1 > Lp [Lnext [k]]) { PRINT1 (("New Col "ID" realloc, old Lnz "ID"\n", k, Lnz [k])) ; if (!CHOLMOD(reallocate_column) (k, lnz + 1, L, Common)) { /* out of memory, L is now simplicial symbolic */ CHOLMOD(clear_flag) (Common) ; for (i = 0 ; i < n ; i++) { W [i] = 0 ; } return (FALSE) ; } /* L->i and L->x may have moved */ Li = L->i ; Lx = L->x ; } ASSERT (Lp [k] + lnz + 1 <= Lp [Lnext [k]]) ; #ifndef NDEBUG PRINT2 (("\nPrior to sort: lnz "ID" (excluding diagonal)\n", lnz)) ; for (kk = 0 ; kk < lnz ; kk++) { i = Ci [kk] ; PRINT2 (("L ["ID"] kept: "ID" %e\n", kk, i, W [i] / dk)) ; } #endif /* sort Ci */ qsort (Ci, lnz, sizeof (Int), (int (*) (const void *, const void *)) icomp); /* store the kth column of L */ DEBUG (lastrow = k) ; p = Lp [k] ; Lx [p++] = dk ; Lnz [k] = lnz + 1 ; fl += lnz ; for (kk = 0 ; kk < lnz ; kk++, p++) { i = Ci [kk] ; PRINT2 (("L ["ID"] after sort: "ID", %e\n", kk, i, W [i] / dk)) ; ASSERT (i > lastrow) ; Li [p] = i ; Lx [p] = W [i] / dk ; W [i] = 0.0 ; DEBUG (lastrow = i) ; } /* compute DeltaB for updown (in DeltaB) */ if (do_solve) { p = Lp [k] ; pend = p + Lnz [k] ; for (p++ ; p < pend ; p++) { ASSERT (Li [p] > k) ; Nx [Li [p]] -= Lx [p] * xk ; } } /* clear the flag for the update */ mark = CHOLMOD(clear_flag) (Common) ; /* workspaces are now cleared */ ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 2*n, Common)) ; /* ---------------------------------------------------------------------- */ /* update/downdate */ /* ---------------------------------------------------------------------- */ /* update or downdate L (k+1:n, k+1:n) with the vector * C = L (:,k) * sqrt (abs (D [k])). * Do a numeric update if D[k] < 0, numeric downdate otherwise. */ ok = TRUE ; Common->modfl = 0 ; PRINT1 (("rowadd update lnz = "ID"\n", lnz)) ; if (lnz > 0) { do_update = IS_LT_ZERO (dk) ; if (do_update) { dk = -dk ; } sqrt_dk = sqrt (dk) ; p = Lp [k] + 1 ; for (kk = 0 ; kk < lnz ; kk++, p++) { Cx [kk] = Lx [p] * sqrt_dk ; } fl += lnz + 1 ; /* create a n-by-1 sparse matrix to hold the single column */ C = &Cmatrix ; C->nrow = n ; C->ncol = 1 ; C->nzmax = lnz ; C->sorted = TRUE ; C->packed = TRUE ; C->p = Cp ; C->i = Ci ; C->x = Cx ; C->nz = NULL ; C->itype = L->itype ; C->xtype = L->xtype ; C->dtype = L->dtype ; C->z = NULL ; C->stype = 0 ; Cp [0] = 0 ; Cp [1] = lnz ; /* numeric downdate if dk > 0, and optional Lx=b change */ /* workspace: Flag (nrow), Head (nrow+1), W (nrow), Iwork (2*nrow) */ ok = CHOLMOD(updown_mark) (do_update ? (1) : (0), C, colmark, L, X, DeltaB, Common) ; /* clear workspace */ for (kk = 0 ; kk < lnz ; kk++) { Cx [kk] = 0 ; } } Common->modfl += fl ; DEBUG (CHOLMOD(dump_factor) (L, "LDL factorization, L:", Common)) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 2*n, Common)) ; return (ok) ; } #endif #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Modify/t_cholmod_updown_numkr.c��������������������������������������������������0000644�0001762�0000144�00000051321�13652535054�021557� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Modify/t_cholmod_updown_numkr ======================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Modify Module. Copyright (C) 2005-2006, * Timothy A. Davis and William W. Hager. * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* Supernodal numerical update/downdate of rank K = RANK, along a single path. * This routine operates on a simplicial factor, but operates on adjacent * columns of L that would fit within a single supernode. "Adjacent" means * along a single path in the elimination tree; they may or may not be * adjacent in the matrix L. * * external defines: NUMERIC, WDIM, RANK. * * WDIM is 1, 2, 4, or 8. RANK can be 1 to WDIM. * * A simple method is included (#define SIMPLE). The code works, but is slow. * It is meant only to illustrate what this routine is doing. * * A rank-K update proceeds along a single path, using single-column, dual- * column, or quad-column updates of L. If a column j and the next column * in the path (its parent) do not have the same nonzero pattern, a single- * column update is used. If they do, but the 3rd and 4th column from j do * not have the same pattern, a dual-column update is used, in which the two * columns are treated as if they were a single supernode of two columns. If * there are 4 columns in the path that all have the same nonzero pattern, then * a quad-column update is used. All three kinds of updates can be used along * a single path, in a single call to this function. * * Single-column update: * * When updating a single column of L, each iteration of the for loop, * below, processes four rows of W (all columns involved) and one column * of L. Suppose we have a rank-5 update, and columns 2 through 6 of W * are involved. In this case, W in this routine is a pointer to column * 2 of the matrix W in the caller. W (in the caller, shown as 'W') is * held in row-major order, and is 8-by-n (a dense matrix storage format), * but shown below in column form to match the column of L. Suppose there * are 13 nonzero entries in column 27 of L, with row indices 27 (the * diagonal, D), 28, 30, 31, 42, 43, 44, 50, 51, 67, 81, 83, and 84. This * pattern is held in Li [Lp [27] ... Lp [27 + Lnz [27] - 1], where * Lnz [27] = 13. The modification of the current column j of L is done * in the following order. A dot (.) means the entry of W is not accessed. * * W0 points to row 27 of W, and G is a 1-by-8 temporary vector. * * G[0] G[4] * G x x x x x . . . * * W0 * | * v * 27 . . x x x x x . W0 points to W (27,2) * * * row 'W' W column j = 27 * | | | of L * v v v | * first iteration of for loop: v * * 28 . . 1 5 9 13 17 . x * 30 . . 2 6 10 14 18 . x * 31 . . 3 7 11 15 19 . x * 42 . . 4 8 12 16 20 . x * * second iteration of for loop: * * 43 . . 1 5 9 13 17 . x * 44 . . 2 6 10 14 18 . x * 50 . . 3 7 11 15 19 . x * 51 . . 4 8 12 16 20 . x * * third iteration of for loop: * * 67 . . 1 5 9 13 17 . x * 81 . . 2 6 10 14 18 . x * 83 . . 3 7 11 15 19 . x * 84 . . 4 8 12 16 20 . x * * If the number of offdiagonal nonzeros in column j of L is not divisible * by 4, then the switch-statement does the work for the first nz % 4 rows. * * Dual-column update: * * In this case, two columns of L that are adjacent in the path are being * updated, by 1 to 8 columns of W. Suppose columns j=27 and j=28 are * adjacent columns in the path (they need not be j and j+1). Two rows * of G and W are used as coefficients during the update: (G0, G1) and * (W0, W1). * * G0 x x x x x . . . * G1 x x x x x . . . * * 27 . . x x x x x . W0 points to W (27,2) * 28 . . x x x x x . W1 points to W (28,2) * * * row 'W' W0,W1 column j = 27 * | | | of L * v v v | * | |-- column j = 28 of L * v v * update L (j1,j): * * 28 . . 1 2 3 4 5 . x - ("-" is not stored in L) * * cleanup iteration since length is odd: * * 30 . . 1 2 3 4 5 . x x * * then each iteration does two rows of both columns of L: * * 31 . . 1 3 5 7 9 . x x * 42 . . 2 4 6 8 10 . x x * * 43 . . 1 3 5 7 9 . x x * 44 . . 2 4 6 8 10 . x x * * 50 . . 1 3 5 7 9 . x x * 51 . . 2 4 6 8 10 . x x * * 67 . . 1 3 5 7 9 . x x * 81 . . 2 4 6 8 10 . x x * * 83 . . 1 3 5 7 9 . x x * 84 . . 2 4 6 8 10 . x x * * If the number of offdiagonal nonzeros in column j of L is not even, * then the cleanup iteration does the work for the first row. * * Quad-column update: * * In this case, four columns of L that are adjacent in the path are being * updated, by 1 to 8 columns of W. Suppose columns j=27, 28, 30, and 31 * are adjacent columns in the path (they need not be j, j+1, ...). Four * rows of G and W are used as coefficients during the update: (G0 through * G3) and (W0 through W3). j=27, j1=28, j2=30, and j3=31. * * G0 x x x x x . . . * G1 x x x x x . . . * G3 x x x x x . . . * G4 x x x x x . . . * * 27 . . x x x x x . W0 points to W (27,2) * 28 . . x x x x x . W1 points to W (28,2) * 30 . . x x x x x . W2 points to W (30,2) * 31 . . x x x x x . W3 points to W (31,2) * * * row 'W' W0,W1,.. column j = 27 * | | | of L * v v v | * | |-- column j = 28 of L * | | |-- column j = 30 of L * | | | |-- column j = 31 of L * v v v v * update L (j1,j): * 28 . . 1 2 3 4 5 . x - - - * * update L (j2,j): * 30 . . 1 2 3 4 5 . # x - - (# denotes modified) * * update L (j2,j1) * 30 . . 1 2 3 4 5 . x # - - * * update L (j3,j) * 31 . . 1 2 3 4 5 . # x x - * * update L (j3,j1) * 31 . . 1 2 3 4 5 . x # x - * * update L (j3,j2) * 31 . . 1 2 3 4 5 . x x # - * * cleanup iteration since length is odd: * 42 . . 1 2 3 4 5 . x x x x * * * ----- CHOLMOD v1.1.1 did the following -------------------------------------- * then each iteration does two rows of all four colummns of L: * * 43 . . 1 3 5 7 9 . x x x x * 44 . . 2 4 6 8 10 . x x x x * * 50 . . 1 3 5 7 9 . x x x x * 51 . . 2 4 6 8 10 . x x x x * * 67 . . 1 3 5 7 9 . x x x x * 81 . . 2 4 6 8 10 . x x x x * * 83 . . 1 3 5 7 9 . x x x x * 84 . . 2 4 6 8 10 . x x x x * * ----- CHOLMOD v1.2.0 does the following ------------------------------------- * then each iteration does one rows of all four colummns of L: * * 43 . . 1 2 3 4 5 . x x x x * 44 . . 1 2 3 4 5 . x x x x * 50 . . 1 3 5 4 5 . x x x x * 51 . . 1 2 3 4 5 . x x x x * 67 . . 1 3 5 4 5 . x x x x * 81 . . 1 2 3 4 5 . x x x x * 83 . . 1 3 5 4 5 . x x x x * 84 . . 1 2 3 4 5 . x x x x * * This file is included in t_cholmod_updown.c, only. * It is not compiled separately. It contains no user-callable routines. * * workspace: Xwork (WDIM*nrow) */ /* ========================================================================== */ /* === loop unrolling macros ================================================ */ /* ========================================================================== */ #undef RANK1 #undef RANK2 #undef RANK3 #undef RANK4 #undef RANK5 #undef RANK6 #undef RANK7 #undef RANK8 #define RANK1(statement) statement #if RANK < 2 #define RANK2(statement) #else #define RANK2(statement) statement #endif #if RANK < 3 #define RANK3(statement) #else #define RANK3(statement) statement #endif #if RANK < 4 #define RANK4(statement) #else #define RANK4(statement) statement #endif #if RANK < 5 #define RANK5(statement) #else #define RANK5(statement) statement #endif #if RANK < 6 #define RANK6(statement) #else #define RANK6(statement) statement #endif #if RANK < 7 #define RANK7(statement) #else #define RANK7(statement) statement #endif #if RANK < 8 #define RANK8(statement) #else #define RANK8(statement) statement #endif #define FOR_ALL_K \ RANK1 (DO (0)) \ RANK2 (DO (1)) \ RANK3 (DO (2)) \ RANK4 (DO (3)) \ RANK5 (DO (4)) \ RANK6 (DO (5)) \ RANK7 (DO (6)) \ RANK8 (DO (7)) /* ========================================================================== */ /* === alpha/gamma ========================================================== */ /* ========================================================================== */ #undef ALPHA_GAMMA #define ALPHA_GAMMA(Dj,Alpha,Gamma,W) \ { \ double dj = Dj ; \ if (update) \ { \ for (k = 0 ; k < RANK ; k++) \ { \ double w = W [k] ; \ double alpha = Alpha [k] ; \ double a = alpha + (w * w) / dj ; \ dj *= a ; \ Alpha [k] = a ; \ Gamma [k] = (- w / dj) ; \ dj /= alpha ; \ } \ } \ else \ { \ for (k = 0 ; k < RANK ; k++) \ { \ double w = W [k] ; \ double alpha = Alpha [k] ; \ double a = alpha - (w * w) / dj ; \ dj *= a ; \ Alpha [k] = a ; \ Gamma [k] = w / dj ; \ dj /= alpha ; \ } \ } \ Dj = ((use_dbound) ? (CHOLMOD(dbound) (dj, Common)) : (dj)) ; \ } /* ========================================================================== */ /* === numeric update/downdate along one path =============================== */ /* ========================================================================== */ static void NUMERIC (WDIM, RANK) ( int update, /* TRUE for update, FALSE for downdate */ Int j, /* first column in the path */ Int e, /* last column in the path */ double Alpha [ ], /* alpha, for each column of W */ double W [ ], /* W is an n-by-WDIM array, stored in row-major order */ cholmod_factor *L, /* with unit diagonal (diagonal not stored) */ cholmod_common *Common ) { #ifdef SIMPLE #define w(row,col) W [WDIM*(row) + (col)] /* ---------------------------------------------------------------------- */ /* concise but slow version for illustration only */ /* ---------------------------------------------------------------------- */ double Gamma [WDIM] ; double *Lx ; Int *Li, *Lp, *Lnz ; Int p, k ; Int use_dbound = IS_GT_ZERO (Common->dbound) ; Li = L->i ; Lx = L->x ; Lp = L->p ; Lnz = L->nz ; /* walk up the etree from node j to its ancestor e */ for ( ; j <= e ; j = (Lnz [j] > 1) ? (Li [Lp [j] + 1]) : Int_max) { /* update the diagonal entry D (j,j) with each column of W */ ALPHA_GAMMA (Lx [Lp [j]], Alpha, Gamma, (&(w (j,0)))) ; /* update column j of L */ for (p = Lp [j] + 1 ; p < Lp [j] + Lnz [j] ; p++) { /* update row Li [p] of column j of L with each column of W */ Int i = Li [p] ; for (k = 0 ; k < RANK ; k++) { w (i,k) -= w (j,k) * Lx [p] ; Lx [p] -= Gamma [k] * w (i,k) ; } } /* clear workspace W */ for (k = 0 ; k < RANK ; k++) { w (j,k) = 0 ; } } #else /* ---------------------------------------------------------------------- */ /* dynamic supernodal version: supernodes detected dynamically */ /* ---------------------------------------------------------------------- */ double G0 [RANK], G1 [RANK], G2 [RANK], G3 [RANK] ; double Z0 [RANK], Z1 [RANK], Z2 [RANK], Z3 [RANK] ; double *W0, *W1, *W2, *W3, *Lx ; Int *Li, *Lp, *Lnz ; Int j1, j2, j3, p0, p1, p2, p3, parent, lnz, pend, k ; Int use_dbound = IS_GT_ZERO (Common->dbound) ; Li = L->i ; Lx = L->x ; Lp = L->p ; Lnz = L->nz ; /* walk up the etree from node j to its ancestor e */ for ( ; j <= e ; j = parent) { p0 = Lp [j] ; /* col j is Li,Lx [p0 ... p0+lnz-1] */ lnz = Lnz [j] ; W0 = W + WDIM * j ; /* pointer to row j of W */ pend = p0 + lnz ; /* for k = 0 to RANK-1 do: */ #define DO(k) Z0 [k] = W0 [k] ; FOR_ALL_K #undef DO /* for k = 0 to RANK-1 do: */ #define DO(k) W0 [k] = 0 ; FOR_ALL_K #undef DO /* update D (j,j) */ ALPHA_GAMMA (Lx [p0], Alpha, G0, Z0) ; p0++ ; /* determine how many columns of L to update at the same time */ parent = (lnz > 1) ? (Li [p0]) : Int_max ; if (parent <= e && lnz == Lnz [parent] + 1) { /* -------------------------------------------------------------- */ /* node j and its parent j1 can be updated at the same time */ /* -------------------------------------------------------------- */ j1 = parent ; j2 = (lnz > 2) ? (Li [p0+1]) : Int_max ; j3 = (lnz > 3) ? (Li [p0+2]) : Int_max ; W1 = W + WDIM * j1 ; /* pointer to row j1 of W */ p1 = Lp [j1] ; /* for k = 0 to RANK-1 do: */ #define DO(k) Z1 [k] = W1 [k] ; FOR_ALL_K #undef DO /* for k = 0 to RANK-1 do: */ #define DO(k) W1 [k] = 0 ; FOR_ALL_K #undef DO /* update L (j1,j) */ { double lx = Lx [p0] ; /* for k = 0 to RANK-1 do: */ #define DO(k) \ Z1 [k] -= Z0 [k] * lx ; \ lx -= G0 [k] * Z1 [k] ; FOR_ALL_K #undef DO Lx [p0++] = lx ; } /* update D (j1,j1) */ ALPHA_GAMMA (Lx [p1], Alpha, G1, Z1) ; p1++ ; /* -------------------------------------------------------------- */ /* update 2 or 4 columns of L */ /* -------------------------------------------------------------- */ if ((j2 <= e) && /* j2 in the current path */ (j3 <= e) && /* j3 in the current path */ (lnz == Lnz [j2] + 2) && /* column j2 matches */ (lnz == Lnz [j3] + 3)) /* column j3 matches */ { /* ---------------------------------------------------------- */ /* update 4 columns of L */ /* ---------------------------------------------------------- */ /* p0 and p1 currently point to row j2 in cols j and j1 of L */ parent = (lnz > 4) ? (Li [p0+2]) : Int_max ; W2 = W + WDIM * j2 ; /* pointer to row j2 of W */ W3 = W + WDIM * j3 ; /* pointer to row j3 of W */ p2 = Lp [j2] ; p3 = Lp [j3] ; /* for k = 0 to RANK-1 do: */ #define DO(k) Z2 [k] = W2 [k] ; FOR_ALL_K #undef DO /* for k = 0 to RANK-1 do: */ #define DO(k) Z3 [k] = W3 [k] ; FOR_ALL_K #undef DO /* for k = 0 to RANK-1 do: */ #define DO(k) W2 [k] = 0 ; FOR_ALL_K #undef DO /* for k = 0 to RANK-1 do: */ #define DO(k) W3 [k] = 0 ; FOR_ALL_K #undef DO /* update L (j2,j) and update L (j2,j1) */ { double lx [2] ; lx [0] = Lx [p0] ; lx [1] = Lx [p1] ; /* for k = 0 to RANK-1 do: */ #define DO(k) \ Z2 [k] -= Z0 [k] * lx [0] ; lx [0] -= G0 [k] * Z2 [k] ; \ Z2 [k] -= Z1 [k] * lx [1] ; lx [1] -= G1 [k] * Z2 [k] ; FOR_ALL_K #undef DO Lx [p0++] = lx [0] ; Lx [p1++] = lx [1] ; } /* update D (j2,j2) */ ALPHA_GAMMA (Lx [p2], Alpha, G2, Z2) ; p2++ ; /* update L (j3,j), L (j3,j1), and L (j3,j2) */ { double lx [3] ; lx [0] = Lx [p0] ; lx [1] = Lx [p1] ; lx [2] = Lx [p2] ; /* for k = 0 to RANK-1 do: */ #define DO(k) \ Z3 [k] -= Z0 [k] * lx [0] ; lx [0] -= G0 [k] * Z3 [k] ; \ Z3 [k] -= Z1 [k] * lx [1] ; lx [1] -= G1 [k] * Z3 [k] ; \ Z3 [k] -= Z2 [k] * lx [2] ; lx [2] -= G2 [k] * Z3 [k] ; FOR_ALL_K #undef DO Lx [p0++] = lx [0] ; Lx [p1++] = lx [1] ; Lx [p2++] = lx [2] ; } /* update D (j3,j3) */ ALPHA_GAMMA (Lx [p3], Alpha, G3, Z3) ; p3++ ; /* each iteration updates L (i, [j j1 j2 j3]) */ for ( ; p0 < pend ; p0++, p1++, p2++, p3++) { double lx [4], *w0 ; lx [0] = Lx [p0] ; lx [1] = Lx [p1] ; lx [2] = Lx [p2] ; lx [3] = Lx [p3] ; w0 = W + WDIM * Li [p0] ; /* for k = 0 to RANK-1 do: */ #define DO(k) \ w0 [k] -= Z0 [k] * lx [0] ; lx [0] -= G0 [k] * w0 [k] ; \ w0 [k] -= Z1 [k] * lx [1] ; lx [1] -= G1 [k] * w0 [k] ; \ w0 [k] -= Z2 [k] * lx [2] ; lx [2] -= G2 [k] * w0 [k] ; \ w0 [k] -= Z3 [k] * lx [3] ; lx [3] -= G3 [k] * w0 [k] ; FOR_ALL_K #undef DO Lx [p0] = lx [0] ; Lx [p1] = lx [1] ; Lx [p2] = lx [2] ; Lx [p3] = lx [3] ; } } else { /* ---------------------------------------------------------- */ /* update 2 columns of L */ /* ---------------------------------------------------------- */ parent = j2 ; /* cleanup iteration if length is odd */ if ((lnz - 2) % 2) { double lx [2] , *w0 ; lx [0] = Lx [p0] ; lx [1] = Lx [p1] ; w0 = W + WDIM * Li [p0] ; /* for k = 0 to RANK-1 do: */ #define DO(k) \ w0 [k] -= Z0 [k] * lx [0] ; lx [0] -= G0 [k] * w0 [k] ; \ w0 [k] -= Z1 [k] * lx [1] ; lx [1] -= G1 [k] * w0 [k] ; FOR_ALL_K #undef DO Lx [p0++] = lx [0] ; Lx [p1++] = lx [1] ; } for ( ; p0 < pend ; p0 += 2, p1 += 2) { double lx [2][2], w [2], *w0, *w1 ; lx [0][0] = Lx [p0 ] ; lx [1][0] = Lx [p0+1] ; lx [0][1] = Lx [p1 ] ; lx [1][1] = Lx [p1+1] ; w0 = W + WDIM * Li [p0 ] ; w1 = W + WDIM * Li [p0+1] ; /* for k = 0 to RANK-1 do: */ #define DO(k) \ w [0] = w0 [k] - Z0 [k] * lx [0][0] ; \ w [1] = w1 [k] - Z0 [k] * lx [1][0] ; \ lx [0][0] -= G0 [k] * w [0] ; \ lx [1][0] -= G0 [k] * w [1] ; \ w0 [k] = w [0] -= Z1 [k] * lx [0][1] ; \ w1 [k] = w [1] -= Z1 [k] * lx [1][1] ; \ lx [0][1] -= G1 [k] * w [0] ; \ lx [1][1] -= G1 [k] * w [1] ; FOR_ALL_K #undef DO Lx [p0 ] = lx [0][0] ; Lx [p0+1] = lx [1][0] ; Lx [p1 ] = lx [0][1] ; Lx [p1+1] = lx [1][1] ; } } } else { /* -------------------------------------------------------------- */ /* update one column of L */ /* -------------------------------------------------------------- */ /* cleanup iteration if length is not a multiple of 4 */ switch ((lnz - 1) % 4) { case 1: { double lx , *w0 ; lx = Lx [p0] ; w0 = W + WDIM * Li [p0] ; /* for k = 0 to RANK-1 do: */ #define DO(k) \ w0 [k] -= Z0 [k] * lx ; lx -= G0 [k] * w0 [k] ; FOR_ALL_K #undef DO Lx [p0++] = lx ; } break ; case 2: { double lx [2], *w0, *w1 ; lx [0] = Lx [p0 ] ; lx [1] = Lx [p0+1] ; w0 = W + WDIM * Li [p0 ] ; w1 = W + WDIM * Li [p0+1] ; /* for k = 0 to RANK-1 do: */ #define DO(k) \ w0 [k] -= Z0 [k] * lx [0] ; \ w1 [k] -= Z0 [k] * lx [1] ; \ lx [0] -= G0 [k] * w0 [k] ; \ lx [1] -= G0 [k] * w1 [k] ; FOR_ALL_K #undef DO Lx [p0++] = lx [0] ; Lx [p0++] = lx [1] ; } break ; case 3: { double lx [3], *w0, *w1, *w2 ; lx [0] = Lx [p0 ] ; lx [1] = Lx [p0+1] ; lx [2] = Lx [p0+2] ; w0 = W + WDIM * Li [p0 ] ; w1 = W + WDIM * Li [p0+1] ; w2 = W + WDIM * Li [p0+2] ; /* for k = 0 to RANK-1 do: */ #define DO(k) \ w0 [k] -= Z0 [k] * lx [0] ; \ w1 [k] -= Z0 [k] * lx [1] ; \ w2 [k] -= Z0 [k] * lx [2] ; \ lx [0] -= G0 [k] * w0 [k] ; \ lx [1] -= G0 [k] * w1 [k] ; \ lx [2] -= G0 [k] * w2 [k] ; FOR_ALL_K #undef DO Lx [p0++] = lx [0] ; Lx [p0++] = lx [1] ; Lx [p0++] = lx [2] ; } } for ( ; p0 < pend ; p0 += 4) { double lx [4], *w0, *w1, *w2, *w3 ; lx [0] = Lx [p0 ] ; lx [1] = Lx [p0+1] ; lx [2] = Lx [p0+2] ; lx [3] = Lx [p0+3] ; w0 = W + WDIM * Li [p0 ] ; w1 = W + WDIM * Li [p0+1] ; w2 = W + WDIM * Li [p0+2] ; w3 = W + WDIM * Li [p0+3] ; /* for k = 0 to RANK-1 do: */ #define DO(k) \ w0 [k] -= Z0 [k] * lx [0] ; \ w1 [k] -= Z0 [k] * lx [1] ; \ w2 [k] -= Z0 [k] * lx [2] ; \ w3 [k] -= Z0 [k] * lx [3] ; \ lx [0] -= G0 [k] * w0 [k] ; \ lx [1] -= G0 [k] * w1 [k] ; \ lx [2] -= G0 [k] * w2 [k] ; \ lx [3] -= G0 [k] * w3 [k] ; FOR_ALL_K #undef DO Lx [p0 ] = lx [0] ; Lx [p0+1] = lx [1] ; Lx [p0+2] = lx [2] ; Lx [p0+3] = lx [3] ; } } } #endif } /* prepare this file for another inclusion in t_cholmod_updown.c: */ #undef RANK ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Modify/cholmod_updown.c����������������������������������������������������������0000644�0001762�0000144�00000144753�13652535054�020034� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Modify/cholmod_updown ================================================ */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Modify Module. * Copyright (C) 2005-2006, Timothy A. Davis and William W. Hager. * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* Updates/downdates the LDL' factorization (symbolic, then numeric), by * computing a new factorization of * * Lnew * Dnew * Lnew' = Lold * Dold * Lold' +/- C*C' * * C must be sorted. It can be either packed or unpacked. As in all CHOLMOD * routines, the columns of L are sorted on input, and also on output. * * If the factor is not an unpacked LDL' or dynamic LDL', it is converted * to an LDL' dynamic factor. An unpacked LDL' factor may be updated, but if * any one column runs out of space, the factor is converted to an LDL' * dynamic one. If the initial conversion fails, the factor is returned * unchanged. * * If memory runs out during the update, the factor is returned as a simplicial * symbolic factor. That is, everything is freed except for the fill-reducing * ordering and its corresponding column counts (typically computed by * cholmod_analyze). * * Note that the fill-reducing permutation L->Perm is NOT used. The row * indices of C refer to the rows of L, not A. If your original system is * LDL' = PAP' (where P = L->Perm), and you want to compute the LDL' * factorization of A+CC', then you must permute C first. That is: * * PAP' = LDL' * P(A+CC')P' = PAP'+PCC'P' = LDL' + (PC)(PC)' = LDL' + Cnew*Cnew' * where Cnew = P*C. * * You can use the cholmod_submatrix routine in the MatrixOps module * to permute C, with: * * Cnew = cholmod_submatrix (C, L->Perm, L->n, NULL, -1, TRUE, TRUE, Common) ; * * Note that the sorted input parameter to cholmod_submatrix must be TRUE, * because cholmod_updown requires C with sorted columns. * * The system Lx=b can also be updated/downdated. The old system was Lold*x=b. * The new system is Lnew*xnew = b + deltab. The old solution x is overwritten * with xnew. Note that as in the update/downdate of L itself, the fill- * reducing permutation L->Perm is not used. x and b are in the permuted * ordering, not your original ordering. x and b are n-by-1; this routine * does not handle multiple right-hand-sides. * * workspace: Flag (nrow), Head (nrow+1), W (maxrank*nrow), Iwork (nrow), * where maxrank is 2, 4, or 8. * * Only real matrices are supported. A symbolic L is converted into a * numeric identity matrix. */ #ifndef NGPL #ifndef NMODIFY #include "cholmod_internal.h" #include "cholmod_modify.h" /* ========================================================================== */ /* === cholmod_updown ======================================================= */ /* ========================================================================== */ /* Compute the new LDL' factorization of LDL'+CC' (an update) or LDL'-CC' * (a downdate). The factor object L need not be an LDL' factorization; it * is converted to one if it isn't. */ int CHOLMOD(updown) ( /* ---- input ---- */ int update, /* TRUE for update, FALSE for downdate */ cholmod_sparse *C, /* the incoming sparse update */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ /* --------------- */ cholmod_common *Common ) { return (CHOLMOD(updown_mask2) (update, C, NULL, NULL, 0, L, NULL, NULL, Common)) ; } /* ========================================================================== */ /* === cholmod_updown_solve ================================================= */ /* ========================================================================== */ /* Does the same as cholmod_updown, except that it also updates/downdates the * solution to Lx=b+DeltaB. x and b must be n-by-1 dense matrices. b is not * need as input to this routine, but a sparse change to b is (DeltaB). Only * entries in DeltaB corresponding to columns modified in L are accessed; the * rest are ignored. */ int CHOLMOD(updown_solve) ( /* ---- input ---- */ int update, /* TRUE for update, FALSE for downdate */ cholmod_sparse *C, /* the incoming sparse update */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ cholmod_dense *X, /* solution to Lx=b (size n-by-1) */ cholmod_dense *DeltaB, /* change in b, zero on output */ /* --------------- */ cholmod_common *Common ) { return (CHOLMOD(updown_mask2) (update, C, NULL, NULL, 0, L, X, DeltaB, Common)) ; } /* ========================================================================== */ /* === Power2 =============================================================== */ /* ========================================================================== */ /* Power2 [i] is smallest power of 2 that is >= i (for i in range 0 to 8) */ static Int Power2 [ ] = { /* 0 1 2 3 4 5 6 7 8 */ 0, 1, 2, 4, 4, 8, 8, 8, 8 } ; /* ========================================================================== */ /* === debug routines ======================================================= */ /* ========================================================================== */ #ifndef NDEBUG static void dump_set (Int s, Int **Set_ps1, Int **Set_ps2, Int j, Int n, cholmod_common *Common) { Int *p, len, i, ilast ; if (CHOLMOD(dump) < -1) { /* no checks if debug level is -2 or less */ return ; } len = Set_ps2 [s] - Set_ps1 [s] ; PRINT2 (("Set s: "ID" len: "ID":", s, len)) ; ASSERT (len > 0) ; ilast = j ; for (p = Set_ps1 [s] ; p < Set_ps2 [s] ; p++) { i = *p ; PRINT3 ((" "ID"", i)) ; ASSERT (i > ilast && i < n) ; ilast = i ; } PRINT3 (("\n")) ; } static void dump_col ( char *w, Int j, Int p1, Int p2, Int *Li, double *Lx, Int n, cholmod_common *Common ) { Int p, row, lastrow ; if (CHOLMOD(dump) < -1) { /* no checks if debug level is -2 or less */ return ; } PRINT3 (("\n\nDUMP COL==== j = "ID" %s: p1="ID" p2="ID" \n", j, w, p1,p2)); lastrow = -1 ; for (p = p1 ; p < p2 ; p++) { PRINT3 ((" "ID": ", p)) ; row = Li [p] ; PRINT3 ((""ID" ", Li [p])) ; PRINT3 (("%g ", Lx [p])) ; PRINT3 (("\n")) ; ASSERT (row > lastrow && row < n) ; lastrow = row ; } ASSERT (p1 < p2) ; ASSERT (Li [p1] == j) ; PRINT3 (("\n")) ; } #endif /* ========================================================================== */ /* === a path =============================================================== */ /* ========================================================================== */ /* A path is a set of nodes of the etree which are all affected by the same * columns of C. */ typedef struct Path_struct { Int start ; /* column at which to start, or EMPTY if initial */ Int end ; /* column at which to end, or EMPTY if initial */ Int ccol ; /* column of C to which path refers */ Int parent ; /* parent path */ Int c ; /* child of j along this path */ Int next ; /* next path in link list */ Int rank ; /* number of rank-1 paths merged onto this path */ Int order ; /* dfs order of this path */ Int wfirst ; /* first column of W to affect this path */ Int pending ; /* column at which the path is pending */ Int botrow ; /* for partial update/downdate of solution to Lx=b */ } Path_type ; /* ========================================================================== */ /* === dfs ================================================================== */ /* ========================================================================== */ /* Compute the DFS order of the set of paths. This can be recursive because * there are at most 23 paths to sort: one for each column of C (8 at most), * and one for each node in a balanced binary tree with 8 leaves (15). * Stack overflow is thus not a problem. */ static void dfs ( Path_type *Path, /* the set of Paths */ Int k, /* the rank of the update/downdate */ Int path, /* which path to work on */ Int *path_order, /* the current path order */ Int *w_order, /* the current order of the columns of W */ Int depth, Int npaths /* total number of paths */ ) { Int c ; /* child path */ ASSERT (path >= 0 && path < npaths) ; if (path < k) { /* this is a leaf node, corresponding to column W (:,path) */ /* and column C (:, Path [path].ccol) */ ASSERT (Path [path].ccol >= 0) ; Path [path].wfirst = *w_order ; Path [path].order = *w_order ; (*w_order)++ ; } else { /* this is a non-leaf path, within the tree */ ASSERT (Path [path].c != EMPTY) ; ASSERT (Path [path].ccol == EMPTY) ; /* order each child path */ for (c = Path [path].c ; c != EMPTY ; c = Path [c].next) { dfs (Path, k, c, path_order, w_order, depth+1, npaths) ; if (Path [path].wfirst == EMPTY) { Path [path].wfirst = Path [c].wfirst ; } } /* order this path next */ Path [path].order = (*path_order)++ ; } } /* ========================================================================== */ /* === numeric update/downdate routines ===================================== */ /* ========================================================================== */ #define WDIM 1 #include "t_cholmod_updown.c" #define WDIM 2 #include "t_cholmod_updown.c" #define WDIM 4 #include "t_cholmod_updown.c" #define WDIM 8 #include "t_cholmod_updown.c" /* ========================================================================== */ /* === cholmod_updown_mark ================================================== */ /* ========================================================================== */ /* Update/downdate LDL' +/- C*C', and update/downdate selected portions of the * solution to Lx=b. * * The original system is L*x = b. The new system is Lnew*xnew = b + deltab. * deltab(i) can be nonzero only if column i of L is modified by the update/ * downdate. If column i is not modified, the deltab(i) is not accessed. * * The solution to Lx=b is not modified if either X or DeltaB are NULL. * * Rowmark and colmark: * -------------------- * * rowmark and colmark affect which portions of L take part in the update/ * downdate of the solution to Lx=b. They do not affect how L itself is * updated/downdated. They are both ignored if X or DeltaB are NULL. * * If not NULL, rowmark is an integer array of size n where L is n-by-n. * rowmark [j] defines the part of column j of L that takes part in the update/ * downdate of the forward solve, Lx=b. Specifically, if i = rowmark [j], * then L(j:i-1,j) is used, and L(i:end,j) is ignored. * * If not NULL, colmark is an integer array of size C->ncol. colmark [ccol] * for a column C(:,ccol) redefines those parts of L that take part in the * update/downdate of Lx=b. Each column of C affects a set of columns of L. * If column ccol of C affects column j of L, then the new rowmark [j] of * column j of L is defined as colmark [ccol]. In a multiple-rank update/ * downdate, if two or more columns of C affect column j, its new rowmark [j] * is the colmark of the least-numbered column of C. colmark is ignored if * it is NULL, in which case rowmark is not modified. If colmark [ccol] is * EMPTY (-1), then rowmark is not modified for that particular column of C. * colmark is ignored if it is NULL, or rowmark, X, or DeltaB are NULL. * * The algorithm for modifying the solution to Lx=b when rowmark and colmark * are NULL is as follows: * * for each column j of L that is modified: * deltab (j:end) += L (j:end,j) * x(j) * modify L * for each column j of L that is modified: * x (j) = deltab (j) * deltab (j) = 0 * deltab (j+1:end) -= L (j+1:end,j) * x(j) * * If rowmark is non-NULL but colmark is NULL: * * for each column j of L that is modified: * deltab (j:rowmark(j)-1) += L (j:rowmark(j)-1,j) * x(j) * modify L * for each column j of L that is modified: * x (j) = deltab (j) * deltab (j) = 0 * deltab (j+1:rowmark(j)-1) -= L (j+1:rowmark(j)-1,j) * x(j) * * If both rowmark and colmark are non-NULL: * * for each column j of L that is modified: * deltab (j:rowmark(j)-1) += L (j:rowmark(j)-1,j) * x(j) * modify L * for each column j of L that is modified: * modify rowmark (j) according to colmark * for each column j of L that is modified: * x (j) = deltab (j) * deltab (j) = 0 * deltab (j+1:rowmark(j)-1) -= L (j+1:rowmark(j)-1,j) * x(j) * * Note that if the rank of C exceeds k = Common->maxrank (which is 2, 4, or 8), * then the update/downdate is done as a series of rank-k updates. In this * case, the above algorithm is repeated for each block of k columns of C. * * Unless it leads to no changes in rowmark, colmark should be used only if * C->ncol <= Common->maxrank, because the update/downdate is done with maxrank * columns at a time. Otherwise, the results are undefined. * * This routine is an "expert" routine. It is meant for use in LPDASA only. */ int CHOLMOD(updown_mark) ( /* ---- input ---- */ int update, /* TRUE for update, FALSE for downdate */ cholmod_sparse *C, /* the incoming sparse update */ Int *colmark, /* Int array of size n. */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ cholmod_dense *X, /* solution to Lx=b (size n-by-1) */ cholmod_dense *DeltaB, /* change in b, zero on output */ /* --------------- */ cholmod_common *Common ) { return (CHOLMOD(updown_mask2) (update, C, colmark, NULL, 0, L, X, DeltaB, Common)) ; } /* ========================================================================== */ /* === cholmod_updown_mask ================================================== */ /* ========================================================================== */ int CHOLMOD(updown_mask) ( /* ---- input ---- */ int update, /* TRUE for update, FALSE for downdate */ cholmod_sparse *C, /* the incoming sparse update */ Int *colmark, /* Int array of size n. See cholmod_updown.c */ Int *mask, /* size n */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ cholmod_dense *X, /* solution to Lx=b (size n-by-1) */ cholmod_dense *DeltaB, /* change in b, zero on output */ /* --------------- */ cholmod_common *Common ) { Int maskmark = 0 ; return (CHOLMOD(updown_mask2) (update, C, colmark, mask, maskmark, L, X, DeltaB, Common)) ; } /* ========================================================================== */ /* === cholmod_updown_mask2 ================================================= */ /* ========================================================================== */ int CHOLMOD(updown_mask2) ( /* ---- input ---- */ int update, /* TRUE for update, FALSE for downdate */ cholmod_sparse *C, /* the incoming sparse update */ Int *colmark, /* Int array of size n. See cholmod_updown.c */ Int *mask, /* size n */ Int maskmark, /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ cholmod_dense *X, /* solution to Lx=b (size n-by-1) */ cholmod_dense *DeltaB, /* change in b, zero on output */ /* --------------- */ cholmod_common *Common ) { double xj, fl ; double *Lx, *W, *Xx, *Nx ; Int *Li, *Lp, *Lnz, *Cp, *Ci, *Cnz, *Head, *Flag, *Stack, *Lnext, *Iwork, *Set_ps1 [32], *Set_ps2 [32], *ps1, *ps2 ; size_t maxrank ; Path_type OrderedPath [32], Path [32] ; Int n, wdim, k1, k2, npaths, i, j, row, packed, ccol, p, cncol, do_solve, mark, jj, j2, kk, nextj, p1, p2, c, use_colmark, newlnz, k, newpath, path_order, w_order, scattered, path, newparent, pp1, pp2, smax, maxrow, row1, nsets, s, p3, newlnz1, Set [32], top, len, lnz, m, botrow ; size_t w ; int ok = TRUE ; DEBUG (Int oldparent) ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (C, FALSE) ; RETURN_IF_NULL (L, FALSE) ; RETURN_IF_XTYPE_INVALID (L, CHOLMOD_PATTERN, CHOLMOD_REAL, FALSE) ; RETURN_IF_XTYPE_INVALID (C, CHOLMOD_REAL, CHOLMOD_REAL, FALSE) ; n = L->n ; cncol = C->ncol ; if (!(C->sorted)) { ERROR (CHOLMOD_INVALID, "C must have sorted columns") ; return (FALSE) ; } if (n != (Int) (C->nrow)) { ERROR (CHOLMOD_INVALID, "C and L dimensions do not match") ; return (FALSE) ; } do_solve = (X != NULL) && (DeltaB != NULL) ; if (do_solve) { RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_REAL, FALSE) ; RETURN_IF_XTYPE_INVALID (DeltaB, CHOLMOD_REAL, CHOLMOD_REAL, FALSE) ; Xx = X->x ; Nx = DeltaB->x ; if (X->nrow != L->n || X->ncol != 1 || DeltaB->nrow != L->n || DeltaB->ncol != 1 || Xx == NULL || Nx == NULL) { ERROR (CHOLMOD_INVALID, "X and/or DeltaB invalid") ; return (FALSE) ; } } else { Xx = NULL ; Nx = NULL ; } Common->status = CHOLMOD_OK ; Common->modfl = 0 ; fl = 0 ; use_colmark = (colmark != NULL) ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ /* Note: cholmod_rowadd and cholmod_rowdel use the second n doubles in * Common->Xwork for Cx, and then perform a rank-1 update here, which uses * the first n doubles in Common->Xwork. Both the rowadd and rowdel * routines allocate enough workspace so that Common->Xwork isn't destroyed * below. Also, both cholmod_rowadd and cholmod_rowdel use the second n * ints in Common->Iwork for Ci. */ /* make sure maxrank is in the proper range */ maxrank = CHOLMOD(maxrank) (n, Common) ; k = MIN (cncol, (Int) maxrank) ; /* maximum k is wdim */ wdim = Power2 [k] ; /* number of columns needed in W */ ASSERT (wdim <= (Int) maxrank) ; PRINT1 (("updown wdim final "ID" k "ID"\n", wdim, k)) ; /* w = wdim * n */ w = CHOLMOD(mult_size_t) (n, wdim, &ok) ; if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (FALSE) ; } CHOLMOD(allocate_work) (n, n, w, Common) ; if (Common->status < CHOLMOD_OK || maxrank == 0) { /* out of memory, L is returned unchanged */ return (FALSE) ; } /* ---------------------------------------------------------------------- */ /* convert to simplicial numeric LDL' factor, if not already */ /* ---------------------------------------------------------------------- */ if (L->xtype == CHOLMOD_PATTERN || L->is_super || L->is_ll) { /* can only update/downdate a simplicial LDL' factorization */ CHOLMOD(change_factor) (CHOLMOD_REAL, FALSE, FALSE, FALSE, FALSE, L, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory, L is returned unchanged */ return (FALSE) ; } } /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ /* mark = CHOLMOD(clear_flag) (Common) ; */ CHOLMOD_CLEAR_FLAG (Common) ; mark = Common->mark ; PRINT1 (("updown, rank %g update %d\n", (double) C->ncol, update)) ; DEBUG (CHOLMOD(dump_factor) (L, "input L for updown", Common)) ; ASSERT (CHOLMOD(dump_sparse) (C, "input C for updown", Common) >= 0) ; Ci = C->i ; Cp = C->p ; Cnz = C->nz ; packed = C->packed ; ASSERT (IMPLIES (!packed, Cnz != NULL)) ; /* ---------------------------------------------------------------------- */ /* quick return */ /* ---------------------------------------------------------------------- */ if (cncol <= 0 || n == 0) { /* nothing to do */ return (TRUE) ; } /* ---------------------------------------------------------------------- */ /* get L */ /* ---------------------------------------------------------------------- */ Li = L->i ; Lx = L->x ; Lp = L->p ; Lnz = L->nz ; Lnext = L->next ; ASSERT (Lnz != NULL) ; /* ---------------------------------------------------------------------- */ /* get workspace */ /* ---------------------------------------------------------------------- */ Flag = Common->Flag ; /* size n, Flag [i] <= mark must hold */ Head = Common->Head ; /* size n, Head [i] == EMPTY must hold */ W = Common->Xwork ; /* size n-by-wdim, zero on input and output*/ /* note that Iwork [n .. 2*n-1] (i/i/l) may be in use in rowadd/rowdel: */ Iwork = Common->Iwork ; Stack = Iwork ; /* size n, uninitialized (i/i/l) */ /* ---------------------------------------------------------------------- */ /* entire rank-cncol update, done as a sequence of rank-k updates */ /* ---------------------------------------------------------------------- */ ps1 = NULL ; ps2 = NULL ; for (k1 = 0 ; k1 < cncol ; k1 += k) { /* ------------------------------------------------------------------ */ /* get the next k columns of C for the update/downdate */ /* ------------------------------------------------------------------ */ /* the last update/downdate might be less than rank-k */ if (k > cncol - k1) { k = cncol - k1 ; wdim = Power2 [k] ; } k2 = k1 + k - 1 ; /* workspaces are in the following state, on input and output */ ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, wdim, Common)) ; /* ------------------------------------------------------------------ */ /* create a zero-length path for each column of W */ /* ------------------------------------------------------------------ */ nextj = n ; path = 0 ; for (ccol = k1 ; ccol <= k2 ; ccol++) { PRINT1 (("Column ["ID"]: "ID"\n", path, ccol)) ; ASSERT (ccol >= 0 && ccol <= cncol) ; pp1 = Cp [ccol] ; pp2 = (packed) ? (Cp [ccol+1]) : (pp1 + Cnz [ccol]) ; /* get the row index j of the first entry in C (:,ccol) */ if (pp2 > pp1) { /* Column ccol of C has at least one entry. */ j = Ci [pp1] ; } else { /* Column ccol of C is empty. Pretend it has one entry in * the last column with numerical value of zero. */ j = n-1 ; } ASSERT (j >= 0 && j < n) ; /* find first column to work on */ nextj = MIN (nextj, j) ; Path [path].ccol = ccol ; /* which column of C this path is for */ Path [path].start = EMPTY ; /* paths for C have zero length */ Path [path].end = EMPTY ; Path [path].parent = EMPTY ; /* no parent yet */ Path [path].rank = 1 ; /* one column of W */ Path [path].c = EMPTY ; /* no child of this path (case A) */ Path [path].next = Head [j] ; /* this path is pending at col j */ Path [path].pending = j ; /* this path is pending at col j */ Head [j] = path ; /* this path is pending at col j */ PRINT1(("Path "ID" starts: start "ID" end "ID" parent "ID" c "ID"" "j "ID" ccol "ID"\n", path, Path [path].start, Path [path].end, Path [path].parent, Path [path].c, j, ccol)) ; /* initialize botrow for this path */ Path [path].botrow = (use_colmark) ? colmark [ccol] : n ; path++ ; } /* we start with paths 0 to k-1. Next one (now unused) is npaths */ npaths = k ; j = nextj ; ASSERT (j < n) ; scattered = FALSE ; /* ------------------------------------------------------------------ */ /* symbolic update of columns of L */ /* ------------------------------------------------------------------ */ while (j < n) { ASSERT (j >= 0 && j < n && Lnz [j] > 0) ; /* the old column, Li [p1..p2-1]. D (j,j) is stored in Lx [p1] */ p1 = Lp [j] ; newlnz = Lnz [j] ; p2 = p1 + newlnz ; #ifndef NDEBUG PRINT1 (("\n=========Column j="ID" p1 "ID" p2 "ID" lnz "ID" \n", j, p1, p2, newlnz)) ; dump_col ("Old", j, p1, p2, Li, Lx, n, Common) ; oldparent = (Lnz [j] > 1) ? (Li [p1 + 1]) : EMPTY ; ASSERT (CHOLMOD(dump_work) (TRUE, FALSE, 0, Common)) ; ASSERT (!scattered) ; PRINT1 (("Col "ID": Checking paths, npaths: "ID"\n", j, npaths)) ; for (kk = 0 ; kk < npaths ; kk++) { Int kk2, found, j3 = Path [kk].pending ; PRINT2 (("Path "ID" pending at "ID".\n", kk, j3)) ; if (j3 != EMPTY) { /* Path kk must be somewhere in link list for column j3 */ ASSERT (Head [j3] != EMPTY) ; PRINT3 ((" List at "ID": ", j3)) ; found = FALSE ; for (kk2 = Head [j3] ; kk2 != EMPTY ; kk2 = Path [kk2].next) { PRINT3 ((""ID" ", kk2)) ; ASSERT (Path [kk2].pending == j3) ; found = found || (kk2 == kk) ; } PRINT3 (("\n")) ; ASSERT (found) ; } } PRINT1 (("\nCol "ID": Paths at this column, head "ID"\n", j, Head [j])); ASSERT (Head [j] != EMPTY) ; for (kk = Head [j] ; kk != EMPTY ; kk = Path [kk].next) { PRINT1 (("path "ID": (c="ID" j="ID") npaths "ID"\n", kk, Path[kk].c, j, npaths)) ; ASSERT (kk >= 0 && kk < npaths) ; ASSERT (Path [kk].pending == j) ; } #endif /* -------------------------------------------------------------- */ /* determine the path we're on */ /* -------------------------------------------------------------- */ /* get the first old path at column j */ path = Head [j] ; /* -------------------------------------------------------------- */ /* update/downdate of forward solve, Lx=b */ /* -------------------------------------------------------------- */ if (do_solve) { xj = Xx [j] ; if (IS_NONZERO (xj)) { xj = Xx [j] ; /* This is first time column j has been seen for entire */ /* rank-k update/downdate. */ /* DeltaB += Lold (j:botrow-1,j) * X (j) */ Nx [j] += xj ; /* diagonal of L */ /* find the botrow for this column */ botrow = (use_colmark) ? Path [path].botrow : n ; for (p = p1 + 1 ; p < p2 ; p++) { i = Li [p] ; if (i >= botrow) { break ; } Nx [i] += Lx [p] * xj ; } /* clear X[j] to flag col j of Lold as having been seen. If * X (j) was initially zero, then the above code is never * executed for column j. This is safe, since if xj=0 the * code above does not do anything anyway. */ Xx [j] = 0.0 ; } } /* -------------------------------------------------------------- */ /* start a new path at this column if two or more paths merge */ /* -------------------------------------------------------------- */ newpath = /* start a new path if paths have merged */ (Path [path].next != EMPTY) /* or if j is the first node on a path (case A). */ || (Path [path].c == EMPTY) ; if (newpath) { /* get the botrow of the first path at column j */ botrow = (use_colmark) ? Path [path].botrow : n ; path = npaths++ ; ASSERT (npaths <= 3*k) ; Path [path].ccol = EMPTY ; /* no single col of C for this path*/ Path [path].start = j ; /* path starts at this column j */ Path [path].end = EMPTY ; /* don't know yet where it ends */ Path [path].parent = EMPTY ;/* don't know parent path yet */ Path [path].rank = 0 ; /* rank is sum of child path ranks */ PRINT1 (("Path "ID" starts: start "ID" end "ID" parent "ID"\n", path, Path [path].start, Path [path].end, Path [path].parent)) ; /* set the botrow of the new path */ Path [path].botrow = (use_colmark) ? botrow : n ; } /* -------------------------------------------------------------- */ /* for each path kk pending at column j */ /* -------------------------------------------------------------- */ /* make a list of the sets that need to be merged into column j */ nsets = 0 ; for (kk = Head [j] ; kk != EMPTY ; kk = Path [kk].next) { /* ---------------------------------------------------------- */ /* path kk is at (c,j) */ /* ---------------------------------------------------------- */ c = Path [kk].c ; ASSERT (c < j) ; PRINT1 (("TUPLE on path "ID" (c="ID" j="ID")\n", kk, c, j)) ; ASSERT (Path [kk].pending == j) ; if (newpath) { /* finalize path kk and find rank of this path */ Path [kk].end = c ; /* end of old path is previous node c */ Path [kk].parent = path ; /* parent is this path */ Path [path].rank += Path [kk].rank ; /* sum up ranks */ Path [kk].pending = EMPTY ; PRINT1 (("Path "ID" done:start "ID" end "ID" parent "ID"\n", kk, Path [kk].start, Path [kk].end, Path [kk].parent)) ; } if (c == EMPTY) { /* ------------------------------------------------------ */ /* CASE A: first node in path */ /* ------------------------------------------------------ */ /* update: add pattern of incoming column */ /* Column ccol of C is in Ci [pp1 ... pp2-1] */ ccol = Path [kk].ccol ; pp1 = Cp [ccol] ; pp2 = (packed) ? (Cp [ccol+1]) : (pp1 + Cnz [ccol]) ; PRINT1 (("Case A, ccol = "ID" len "ID"\n", ccol, pp2-pp1)) ; ASSERT (IMPLIES (pp2 > pp1, Ci [pp1] == j)) ; if (!scattered) { /* scatter the original pattern of column j of L */ for (p = p1 ; p < p2 ; p++) { Flag [Li [p]] = mark ; } scattered = TRUE ; } /* scatter column ccol of C (skip first entry, j) */ newlnz1 = newlnz ; for (p = pp1 + 1 ; p < pp2 ; p++) { row = Ci [p] ; if (Flag [row] < mark) { /* this is a new entry in Lj' */ Flag [row] = mark ; newlnz++ ; } } if (newlnz1 != newlnz) { /* column ccol of C adds something to column j of L */ Set [nsets++] = FLIP (ccol) ; } } else if (Head [c] == 1) { /* ------------------------------------------------------ */ /* CASE B: c is old, but changed, child of j */ /* CASE C: new child of j */ /* ------------------------------------------------------ */ /* Head [c] is 1 if col c of L has new entries, * EMPTY otherwise */ Flag [c] = 0 ; Head [c] = EMPTY ; /* update: add Lc' */ /* column c of L is in Li [pp1 .. pp2-1] */ pp1 = Lp [c] ; pp2 = pp1 + Lnz [c] ; PRINT1 (("Case B/C: c = "ID"\n", c)) ; DEBUG (dump_col ("Child", c, pp1, pp2, Li, Lx, n, Common)) ; ASSERT (j == Li [pp1 + 1]) ; /* j is new parent of c */ if (!scattered) { /* scatter the original pattern of column j of L */ for (p = p1 ; p < p2 ; p++) { Flag [Li [p]] = mark ; } scattered = TRUE ; } /* scatter column c of L (skip first two entries, c and j)*/ newlnz1 = newlnz ; for (p = pp1 + 2 ; p < pp2 ; p++) { row = Li [p] ; if (Flag [row] < mark) { /* this is a new entry in Lj' */ Flag [row] = mark ; newlnz++ ; } } PRINT2 (("\n")) ; if (newlnz1 != newlnz) { /* column c of L adds something to column j of L */ Set [nsets++] = c ; } } } /* -------------------------------------------------------------- */ /* update the pattern of column j of L */ /* -------------------------------------------------------------- */ /* Column j of L will be in Li/Lx [p1 .. p3-1] */ p3 = p1 + newlnz ; ASSERT (IMPLIES (nsets == 0, newlnz == Lnz [j])) ; PRINT1 (("p1 "ID" p2 "ID" p3 "ID" nsets "ID"\n", p1, p2, p3,nsets)); /* -------------------------------------------------------------- */ /* ensure we have enough space for the longer column */ /* -------------------------------------------------------------- */ if (nsets > 0 && p3 > Lp [Lnext [j]]) { PRINT1 (("Col realloc: j "ID" newlnz "ID"\n", j, newlnz)) ; if (!CHOLMOD(reallocate_column) (j, newlnz, L, Common)) { /* out of memory, L is now simplicial symbolic */ CHOLMOD(clear_flag) (Common) ; for (j = 0 ; j <= n ; j++) { Head [j] = EMPTY ; } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, wdim, Common)) ; return (FALSE) ; } /* L->i and L->x may have moved. Column j has moved too */ Li = L->i ; Lx = L->x ; p1 = Lp [j] ; p2 = p1 + Lnz [j] ; p3 = p1 + newlnz ; } /* -------------------------------------------------------------- */ /* create set pointers */ /* -------------------------------------------------------------- */ for (s = 0 ; s < nsets ; s++) { /* Pattern of Set s is *(Set_ps1 [s] ... Set_ps2 [s]-1) */ c = Set [s] ; if (c < EMPTY) { /* column ccol of C, skip first entry (j) */ ccol = FLIP (c) ; pp1 = Cp [ccol] ; pp2 = (packed) ? (Cp [ccol+1]) : (pp1 + Cnz [ccol]) ; ASSERT (pp2 - pp1 > 1) ; Set_ps1 [s] = &(Ci [pp1 + 1]) ; Set_ps2 [s] = &(Ci [pp2]) ; PRINT1 (("set "ID" is ccol "ID"\n", s, ccol)) ; } else { /* column c of L, skip first two entries (c and j) */ pp1 = Lp [c] ; pp2 = pp1 + Lnz [c] ; ASSERT (Lnz [c] > 2) ; Set_ps1 [s] = &(Li [pp1 + 2]) ; Set_ps2 [s] = &(Li [pp2]) ; PRINT1 (("set "ID" is L "ID"\n", s, c)) ; } DEBUG (dump_set (s, Set_ps1, Set_ps2, j, n, Common)) ; } /* -------------------------------------------------------------- */ /* multiset merge */ /* -------------------------------------------------------------- */ /* Merge the sets into a single sorted set, Lj'. Before the merge * starts, column j is located in Li/Lx [p1 ... p2-1] and the * space Li/Lx [p2 ... p3-1] is empty. p1 is Lp [j], p2 is * Lp [j] + Lnz [j] (the old length of the column), and p3 is * Lp [j] + newlnz (the new and longer length of the column). * * The sets 0 to nsets-1 are defined by the Set_ps1 and Set_ps2 * pointers. Set s is located in *(Set_ps1 [s] ... Set_ps2 [s]-1). * It may be a column of C, or a column of L. All row indices i in * the sets are in the range i > j and i < n. All sets are sorted. * * The merge into column j of L is done in place. * * During the merge, p2 and p3 are updated. Li/Lx [p1..p2-1] * reflects the indices of the old column j of L that are yet to * be merged into the new column. Entries in their proper place in * the new column j of L are located in Li/Lx [p3 ... p1+newlnz-1]. * The merge finishes when p2 == p3. * * During the merge, set s consumed as it is merged into column j of * L. Its unconsumed contents are *(Set_ps1 [s] ... Set_ps2 [s]-1). * When a set is completely consumed, it is removed from the set of * sets, and nsets is decremented. * * The multiset merge and 2-set merge finishes when p2 == p3. */ PRINT1 (("Multiset merge p3 "ID" p2 "ID" nsets "ID"\n", p3, p2, nsets)) ; while (p3 > p2 && nsets > 1) { #ifndef NDEBUG PRINT2 (("\nMultiset merge. nsets = "ID"\n", nsets)) ; PRINT2 (("Source col p1 = "ID", p2 = "ID", p3= "ID"\n", p1, p2, p3)) ; for (p = p1 + 1 ; p < p2 ; p++) { PRINT2 ((" p: "ID" source row "ID" %g\n", p, Li[p], Lx[p])) ; ASSERT (Li [p] > j && Li [p] < n) ; } PRINT2 (("---\n")) ; for (p = p3 ; p < p1 + newlnz ; p++) { PRINT2 ((" p: "ID" target row "ID" %g\n", p, Li[p], Lx[p])) ; ASSERT (Li [p] > j && Li [p] < n) ; } for (s = 0 ; s < nsets ; s++) { dump_set (s, Set_ps1, Set_ps2, j, n, Common) ; } #endif /* get the entry at the tail end of source column Lj */ row1 = Li [p2 - 1] ; ASSERT (row1 >= j && p2 >= p1) ; /* find the largest row in all the sets */ maxrow = row1 ; smax = EMPTY ; for (s = nsets-1 ; s >= 0 ; s--) { ASSERT (Set_ps1 [s] < Set_ps2 [s]) ; row = *(Set_ps2 [s] - 1) ; if (row == maxrow) { /* skip past this entry in set s (it is a duplicate) */ Set_ps2 [s]-- ; if (Set_ps1 [s] == Set_ps2 [s]) { /* nothing more in this set */ nsets-- ; Set_ps1 [s] = Set_ps1 [nsets] ; Set_ps2 [s] = Set_ps2 [nsets] ; if (smax == nsets) { /* Set smax redefined; it is now this set */ smax = s ; } } } else if (row > maxrow) { maxrow = row ; smax = s ; } } ASSERT (maxrow > j) ; /* move the row onto the stack of the target column */ if (maxrow == row1) { /* next entry is in Lj, move to the bottom of Lj' */ ASSERT (smax == EMPTY) ; p2-- ; p3-- ; Li [p3] = maxrow ; Lx [p3] = Lx [p2] ; } else { /* new entry in Lj' */ ASSERT (smax >= 0 && smax < nsets) ; Set_ps2 [smax]-- ; p3-- ; Li [p3] = maxrow ; Lx [p3] = 0.0 ; if (Set_ps1 [smax] == Set_ps2 [smax]) { /* nothing more in this set */ nsets-- ; Set_ps1 [smax] = Set_ps1 [nsets] ; Set_ps2 [smax] = Set_ps2 [nsets] ; PRINT1 (("Set "ID" now empty\n", smax)) ; } } } /* -------------------------------------------------------------- */ /* 2-set merge: */ /* -------------------------------------------------------------- */ /* This the same as the multi-set merge, except there is only one * set s = 0 left. The source column j and the set 0 are being * merged into the target column j. */ if (nsets > 0) { ps1 = Set_ps1 [0] ; ps2 = Set_ps2 [0] ; } while (p3 > p2) { #ifndef NDEBUG PRINT2 (("\n2-set merge.\n")) ; ASSERT (nsets == 1) ; PRINT2 (("Source col p1 = "ID", p2 = "ID", p3= "ID"\n", p1, p2, p3)) ; for (p = p1 + 1 ; p < p2 ; p++) { PRINT2 ((" p: "ID" source row "ID" %g\n", p, Li[p], Lx[p])) ; ASSERT (Li [p] > j && Li [p] < n) ; } PRINT2 (("---\n")) ; for (p = p3 ; p < p1 + newlnz ; p++) { PRINT2 ((" p: "ID" target row "ID" %g\n", p, Li[p], Lx[p])) ; ASSERT (Li [p] > j && Li [p] < n) ; } dump_set (0, Set_ps1, Set_ps2, j, n, Common) ; #endif if (p2 == p1 + 1) { /* the top of Lj is empty; copy the set and quit */ while (p3 > p2) { /* new entry in Lj' */ row = *(--ps2) ; p3-- ; Li [p3] = row ; Lx [p3] = 0.0 ; } } else { /* get the entry at the tail end of Lj */ row1 = Li [p2 - 1] ; ASSERT (row1 > j && row1 < n) ; /* get the entry at the tail end of the incoming set */ ASSERT (ps1 < ps2) ; row = *(ps2-1) ; ASSERT (row > j && row1 < n) ; /* move the larger of the two entries to the target set */ if (row1 >= row) { /* next entry is in Lj, move to the bottom */ if (row1 == row) { /* skip past this entry in the set */ ps2-- ; } p2-- ; p3-- ; Li [p3] = row1 ; Lx [p3] = Lx [p2] ; } else { /* new entry in Lj' */ ps2-- ; p3-- ; Li [p3] = row ; Lx [p3] = 0.0 ; } } } /* -------------------------------------------------------------- */ /* The new column j of L is now in Li/Lx [p1 ... p2-1] */ /* -------------------------------------------------------------- */ p2 = p1 + newlnz ; DEBUG (dump_col ("After merge: ", j, p1, p2, Li, Lx, n, Common)) ; fl += Path [path].rank * (6 + 4 * (double) newlnz) ; /* -------------------------------------------------------------- */ /* clear Flag; original pattern of column j L no longer marked */ /* -------------------------------------------------------------- */ mark = CHOLMOD(clear_flag) (Common) ; scattered = FALSE ; /* -------------------------------------------------------------- */ /* find the new parent */ /* -------------------------------------------------------------- */ newparent = (newlnz > 1) ? (Li [p1 + 1]) : EMPTY ; PRINT1 (("\nNew parent, Lnz: "ID": "ID" "ID"\n", j, newparent,newlnz)); ASSERT (oldparent == EMPTY || newparent <= oldparent) ; /* -------------------------------------------------------------- */ /* go to the next node in the path */ /* -------------------------------------------------------------- */ /* path moves to (j,nextj) unless j is a root */ nextj = (newparent == EMPTY) ? n : newparent ; /* place path at head of list for nextj, or terminate the path */ PRINT1 (("\n j = "ID" nextj = "ID"\n\n", j, nextj)) ; Path [path].c = j ; if (nextj < n) { /* put path on link list of pending paths at column nextj */ Path [path].next = Head [nextj] ; Path [path].pending = nextj ; Head [nextj] = path ; PRINT1 (("Path "ID" continues to ("ID","ID"). Rank "ID"\n", path, Path [path].c, nextj, Path [path].rank)) ; } else { /* path has ended here, at a root */ Path [path].next = EMPTY ; Path [path].pending = EMPTY ; Path [path].end = j ; PRINT1 (("Path "ID" ends at root ("ID"). Rank "ID"\n", path, Path [path].end, Path [path].rank)) ; } /* The link list Head [j] can now be emptied. Set Head [j] to 1 * if column j has changed (it is no longer used as a link list). */ PRINT1 (("column "ID", oldlnz = "ID"\n", j, Lnz [j])) ; Head [j] = (Lnz [j] != newlnz) ? 1 : EMPTY ; Lnz [j] = newlnz ; PRINT1 (("column "ID", newlnz = "ID"\n", j, newlnz)) ; DEBUG (dump_col ("New", j, p1, p2, Li, Lx, n, Common)) ; /* move to the next column */ if (k == Path [path].rank) { /* only one path left */ j = nextj ; } else { /* The current path is moving from column j to column nextj * (nextj is n if the path has ended). However, there may be * other paths pending in columns j+1 to nextj-1. There are * two methods for looking for the next column with a pending * update. The first one looks at all columns j+1 to nextj-1 * for a non-empty link list. This can be costly if j and * nextj differ by a large amount (it can be O(n), but this * entire routine may take Omega(1) time). The second method * looks at all paths and finds the smallest column at which any * path is pending. It takes O(# of paths), which is bounded * by 23: one for each column of C (up to 8), and then 15 for a * balanced binary tree with 8 leaves. However, if j and * nextj differ by a tiny amount (nextj is often j+1 near * the end of the matrix), looking at columns j+1 to nextj * would be faster. Both methods give the same answer. */ if (nextj - j < npaths) { /* there are fewer columns to search than paths */ PRINT1 (("check j="ID" to nextj="ID"\n", j, nextj)) ; for (j2 = j + 1 ; j2 < nextj ; j2++) { PRINT1 (("check j="ID" "ID"\n", j2, Head [j2])) ; if (Head [j2] != EMPTY) { PRINT1 (("found, j="ID"\n", j2)) ; ASSERT (Path [Head [j2]].pending == j2) ; break ; } } } else { /* there are fewer paths than columns to search */ j2 = nextj ; for (kk = 0 ; kk < npaths ; kk++) { jj = Path [kk].pending ; PRINT2 (("Path "ID" pending at "ID"\n", kk, jj)) ; if (jj != EMPTY) j2 = MIN (j2, jj) ; } } j = j2 ; } } /* ensure workspaces are back to the values required on input */ ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, TRUE, Common)) ; /* ------------------------------------------------------------------ */ /* depth-first-search of tree to order the paths */ /* ------------------------------------------------------------------ */ /* create lists of child paths */ PRINT1 (("\n\nDFS search:\n\n")) ; for (path = 0 ; path < npaths ; path++) { Path [path].c = EMPTY ; /* first child of path */ Path [path].next = EMPTY ; /* next sibling of path */ Path [path].order = EMPTY ; /* path is not ordered yet */ Path [path].wfirst = EMPTY ; /* 1st column of W not found yet */ #ifndef NDEBUG j = Path [path].start ; PRINT1 (("Path "ID" : start "ID" end "ID" parent "ID" ccol "ID"\n", path, j, Path [path].end, Path [path].parent, Path [path].ccol)) ; for ( ; ; ) { PRINT1 ((" column "ID"\n", j)) ; ASSERT (j == EMPTY || (j >= 0 && j < n)) ; if (j == Path [path].end) { break ; } ASSERT (j >= 0 && j < n) ; j = (Lnz [j] > 1) ? (Li [Lp [j] + 1]) : EMPTY ; } #endif } for (path = 0 ; path < npaths ; path++) { p = Path [path].parent ; /* add path to child list of parent */ if (p != EMPTY) { ASSERT (p < npaths) ; Path [path].next = Path [p].c ; Path [p].c = path ; } } path_order = k ; w_order = 0 ; for (path = npaths-1 ; path >= 0 ; path--) { if (Path [path].order == EMPTY) { /* this path is the root of a subtree of Tbar */ PRINT1 (("Root path "ID"\n", path)) ; ASSERT (path >= k) ; dfs (Path, k, path, &path_order, &w_order, 0, npaths) ; } } ASSERT (path_order == npaths) ; ASSERT (w_order == k) ; /* reorder the paths */ for (path = 0 ; path < npaths ; path++) { /* old order is path, new order is Path [path].order */ OrderedPath [Path [path].order] = Path [path] ; } #ifndef NDEBUG for (path = 0 ; path < npaths ; path++) { PRINT1 (("Ordered Path "ID": start "ID" end "ID" wfirst "ID" rank " ""ID" ccol "ID"\n", path, OrderedPath [path].start, OrderedPath [path].end, OrderedPath [path].wfirst, OrderedPath [path].rank, OrderedPath [path].ccol)) ; if (path < k) { ASSERT (OrderedPath [path].ccol >= 0) ; } else { ASSERT (OrderedPath [path].ccol == EMPTY) ; } } #endif /* ------------------------------------------------------------------ */ /* numeric update/downdate for all paths */ /* ------------------------------------------------------------------ */ ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, wdim, Common)) ; switch (wdim) { case 1: updown_1_r (update, C, k, L, W, OrderedPath, npaths, mask, maskmark, Common) ; break ; case 2: updown_2_r (update, C, k, L, W, OrderedPath, npaths, mask, maskmark, Common) ; break ; case 4: updown_4_r (update, C, k, L, W, OrderedPath, npaths, mask, maskmark, Common) ; break ; case 8: updown_8_r (update, C, k, L, W, OrderedPath, npaths, mask, maskmark, Common) ; break ; } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, wdim, Common)) ; } /* ---------------------------------------------------------------------- */ /* update/downdate the forward solve */ /* ---------------------------------------------------------------------- */ if (do_solve) { /* We now have DeltaB += Lold (:,j) * X (j) for all columns j in union * of all paths seen during the entire rank-cncol update/downdate. For * each j in path, do DeltaB -= Lnew (:,j)*DeltaB(j) * in topological order. */ #ifndef NDEBUG PRINT1 (("\ndo_solve, DeltaB + Lold(:,Path)*X(Path):\n")) ; for (i = 0 ; i < n ; i++) { PRINT1 (("do_solve: "ID" %30.20e\n", i, Nx [i])) ; } #endif /* Note that the downdate, if it deleted entries, would need to compute * the Stack prior to doing any downdates. */ /* find the union of all the paths in the new L */ top = n ; /* "top" is stack pointer, not a row or column index */ for (ccol = 0 ; ccol < cncol ; ccol++) { /* -------------------------------------------------------------- */ /* j = first row index of C (:,ccol) */ /* -------------------------------------------------------------- */ pp1 = Cp [ccol] ; pp2 = (packed) ? (Cp [ccol+1]) : (pp1 + Cnz [ccol]) ; if (pp2 > pp1) { /* Column ccol of C has at least one entry. */ j = Ci [pp1] ; } else { /* Column ccol of C is empty */ j = n-1 ; } PRINT1 (("\ndo_solve: ccol= "ID"\n", ccol)) ; ASSERT (j >= 0 && j < n) ; len = 0 ; /* -------------------------------------------------------------- */ /* find the new rowmark */ /* -------------------------------------------------------------- */ /* Each column of C can redefine the region of L that takes part in * the update/downdate of the triangular solve Lx=b. If * i = colmark [ccol] for column C(:,ccol), then i = rowmark [j] is * redefined for all columns along the path modified by C(:,ccol). * If more than one column modifies any given column j of L, then * the rowmark of j is determined by the colmark of the least- * numbered column that affects column j. That is, if both * C(:,ccol1) and C(:,ccol2) affect column j of L, then * rowmark [j] = colmark [MIN (ccol1, ccol2)]. * * rowmark [j] is not modified if rowmark or colmark are NULL, * or if colmark [ccol] is EMPTY. */ botrow = (use_colmark) ? (colmark [ccol]) : EMPTY ; /* -------------------------------------------------------------- */ /* traverse from j towards root, stopping if node already visited */ /* -------------------------------------------------------------- */ while (j != EMPTY && Flag [j] < mark) { PRINT1 (("do_solve: subpath j= "ID"\n", j)) ; ASSERT (j >= 0 && j < n) ; Stack [len++] = j ; /* place j on the stack */ Flag [j] = mark ; /* flag j as visited */ /* if using colmark, mark column j with botrow */ ASSERT (Li [Lp [j]] == j) ; /* diagonal is always present */ if (use_colmark) { Li [Lp [j]] = botrow ; /* use the space for botrow */ } /* go up the tree, to the parent of j */ j = (Lnz [j] > 1) ? (Li [Lp [j] + 1]) : EMPTY ; } /* -------------------------------------------------------------- */ /* move the path down to the bottom of the stack */ /* -------------------------------------------------------------- */ ASSERT (len <= top) ; while (len > 0) { Stack [--top] = Stack [--len] ; } } #ifndef NDEBUG /* Union of paths now in Stack [top..n-1] in topological order */ PRINT1 (("\nTopological order:\n")) ; for (i = top ; i < n ; i++) { PRINT1 (("column "ID" in full path\n", Stack [i])) ; } #endif /* Do the forward solve for the full path part of L */ for (m = top ; m < n ; m++) { j = Stack [m] ; ASSERT (j >= 0 && j < n) ; PRINT1 (("do_solve: path j= "ID"\n", j)) ; p1 = Lp [j] ; lnz = Lnz [j] ; p2 = p1 + lnz ; xj = Nx [j] ; /* copy new solution onto old one, for all cols in full path */ Xx [j] = xj ; Nx [j] = 0. ; /* DeltaB -= Lnew (j+1:botrow-1,j) * deltab(j) */ if (use_colmark) { botrow = Li [p1] ; /* get botrow */ Li [p1] = j ; /* restore diagonal entry */ for (p = p1 + 1 ; p < p2 ; p++) { i = Li [p] ; if (i >= botrow) break ; Nx [i] -= Lx [p] * xj ; } } else { for (p = p1 + 1 ; p < p2 ; p++) { Nx [Li [p]] -= Lx [p] * xj ; } } } /* clear the Flag */ mark = CHOLMOD(clear_flag) (Common) ; } /* ---------------------------------------------------------------------- */ /* successful update/downdate */ /* ---------------------------------------------------------------------- */ Common->modfl = fl ; DEBUG (for (j = 0 ; j < n ; j++) ASSERT (IMPLIES (do_solve, Nx[j] == 0.))) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, TRUE, Common)) ; DEBUG (CHOLMOD(dump_factor) (L, "output L for updown", Common)) ; return (TRUE) ; } #endif #endif ���������������������Matrix/src/CHOLMOD/Modify/License.txt���������������������������������������������������������������0000644�0001762�0000144�00000002046�11770402705�016751� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CHOLMOD/Modify Module. Copyright (C) 2005-2006, Timothy A. Davis and William W. Hager CHOLMOD is also available under other licenses; contact authors for details. http://www.suitesparse.com Note that this license is for the CHOLMOD/Modify module only. All CHOLMOD modules are licensed separately. -------------------------------------------------------------------------------- This Module 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 2 of the License, or (at your option) any later version. This Module 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 Module; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Modify/t_cholmod_updown.c��������������������������������������������������������0000644�0001762�0000144�00000014545�13652535054�020352� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Modify/t_cholmod_updown ============================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Modify Module. Copyright (C) 2005-2006, * Timothy A. Davis and William W. Hager. * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* Updates/downdates the LDL' factorization, by computing a new factorization of * * Lnew * Dnew * Lnew' = Lold * Dold * Lold' +/- C*C' * * This file is not compiled separately. It is included into * cholmod_updown.c. There are no user-callable routines in this file. * * The next include statements, below, create the numerical update/downdate * kernels from t_cholmod_updown_numkr.c. There are 4 compiled versions of this * file, one for each value of WDIM in the set 1, 2, 4, and 8. Each calls * multiple versions of t_cholmod_updown_numkr; the number of versions of each * is equal to WDIM. Each t_cholmod_updown_numkr version is included as a * static function within its t_cholmod_updown.c caller routine. Thus: * * t*_updown.c creates these versions of t_cholmod_updown_numkr.c: * --------- --------------------------------------------------- * * updown_1_r updown_1_1 * * updown_2_r updown_2_1 updown_2_2 * * updown_4_r updown_4_1 updown_4_2 updown_4_3 updown_4_4 * * updown_8_r updown_8_1 updown_8_2 updown_8_3 updown_8_4 * updown_8_5 updown_8_6 updown_8_7 updown_8_8 * * workspace: Xwork (nrow*wdim) */ /* ========================================================================== */ /* === routines for numeric update/downdate along one path ================== */ /* ========================================================================== */ #undef FORM_NAME #undef NUMERIC #define FORM_NAME(k,rank) updown_ ## k ## _ ## rank #define NUMERIC(k,rank) FORM_NAME(k,rank) #define RANK 1 #include "t_cholmod_updown_numkr.c" #if WDIM >= 2 #define RANK 2 #include "t_cholmod_updown_numkr.c" #endif #if WDIM >= 4 #define RANK 3 #include "t_cholmod_updown_numkr.c" #define RANK 4 #include "t_cholmod_updown_numkr.c" #endif #if WDIM == 8 #define RANK 5 #include "t_cholmod_updown_numkr.c" #define RANK 6 #include "t_cholmod_updown_numkr.c" #define RANK 7 #include "t_cholmod_updown_numkr.c" #define RANK 8 #include "t_cholmod_updown_numkr.c" #endif /* ========================================================================== */ /* === numeric update/downdate for all paths ================================ */ /* ========================================================================== */ static void NUMERIC (WDIM, r) ( int update, /* TRUE for update, FALSE for downdate */ cholmod_sparse *C, /* in packed or unpacked, and sorted form */ /* no empty columns */ Int rank, /* rank of the update/downdate */ cholmod_factor *L, /* with unit diagonal (diagonal not stored) */ /* temporary workspaces: */ double W [ ], /* n-by-WDIM dense matrix, initially zero */ Path_type Path [ ], Int npaths, Int mask [ ], /* size n */ Int maskmark, cholmod_common *Common ) { double Alpha [8] ; double *Cx, *Wpath, *W1, *a ; Int i, j, p, ccol, pend, wfirst, e, path, packed ; Int *Ci, *Cp, *Cnz ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ Ci = C->i ; Cx = C->x ; Cp = C->p ; Cnz = C->nz ; packed = C->packed ; ASSERT (IMPLIES (!packed, Cnz != NULL)) ; ASSERT (L->n == C->nrow) ; DEBUG (CHOLMOD(dump_real) ("num_d: in W:", W, WDIM, L->n, FALSE, 1,Common)); /* ---------------------------------------------------------------------- */ /* scatter C into W */ /* ---------------------------------------------------------------------- */ for (path = 0 ; path < rank ; path++) { /* W (:, path) = C (:, Path [path].col) */ ccol = Path [path].ccol ; Wpath = W + path ; PRINT1 (("Ordered Columns [path = "ID"] = "ID"\n", path, ccol)) ; p = Cp [ccol] ; pend = (packed) ? (Cp [ccol+1]) : (p + Cnz [ccol]) ; /* column C can be empty */ for ( ; p < pend ; p++) { i = Ci [p] ; ASSERT (i >= 0 && i < (Int) (C->nrow)) ; if (mask == NULL || mask [i] < maskmark) { Wpath [WDIM * i] = Cx [p] ; } PRINT1 ((" row "ID" : %g mask "ID"\n", i, Cx [p], (mask) ? mask [i] : 0)) ; } Alpha [path] = 1.0 ; } DEBUG (CHOLMOD(dump_real) ("num_d: W:", W, WDIM, L->n, FALSE, 1,Common)) ; /* ---------------------------------------------------------------------- */ /* numeric update/downdate of the paths */ /* ---------------------------------------------------------------------- */ /* for each disjoint subpath in Tbar in DFS order do */ for (path = rank ; path < npaths ; path++) { /* determine which columns of W to use */ wfirst = Path [path].wfirst ; e = Path [path].end ; j = Path [path].start ; ASSERT (e >= 0 && e < (Int) (L->n)) ; ASSERT (j >= 0 && j < (Int) (L->n)) ; W1 = W + wfirst ; /* pointer to row 0, column wfirst of W */ a = Alpha + wfirst ; /* pointer to Alpha [wfirst] */ PRINT1 (("Numerical update/downdate of path "ID"\n", path)) ; PRINT1 (("start "ID" end "ID" wfirst "ID" rank "ID" ccol "ID"\n", j, e, wfirst, Path [path].rank, Path [path].ccol)) ; #if WDIM == 1 NUMERIC (WDIM,1) (update, j, e, a, W1, L, Common) ; #else switch (Path [path].rank) { case 1: NUMERIC (WDIM,1) (update, j, e, a, W1, L, Common) ; break ; #if WDIM >= 2 case 2: NUMERIC (WDIM,2) (update, j, e, a, W1, L, Common) ; break ; #endif #if WDIM >= 4 case 3: NUMERIC (WDIM,3) (update, j, e, a, W1, L, Common) ; break ; case 4: NUMERIC (WDIM,4) (update, j, e, a, W1, L, Common) ; break ; #endif #if WDIM == 8 case 5: NUMERIC (WDIM,5) (update, j, e, a, W1, L, Common) ; break ; case 6: NUMERIC (WDIM,6) (update, j, e, a, W1, L, Common) ; break ; case 7: NUMERIC (WDIM,7) (update, j, e, a, W1, L, Common) ; break ; case 8: NUMERIC (WDIM,8) (update, j, e, a, W1, L, Common) ; break ; #endif } #endif } } /* prepare for the next inclusion of this file in cholmod_updown.c */ #undef WDIM �����������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Modify/cholmod_rowdel.c����������������������������������������������������������0000644�0001762�0000144�00000031423�13652535054�020001� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Modify/cholmod_rowdel ================================================ */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Modify Module. * Copyright (C) 2005-2006, Timothy A. Davis and William W. Hager. * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* Deletes a row and column from an LDL' factorization. The row and column k * is set to the kth row and column of the identity matrix. Optionally * downdates the solution to Lx=b. * * workspace: Flag (nrow), Head (nrow+1), W (nrow*2), Iwork (2*nrow) * * Only real matrices are supported (exception: since only the pattern of R * is used, it can have any valid xtype). */ #ifndef NGPL #ifndef NMODIFY #include "cholmod_internal.h" #include "cholmod_modify.h" /* ========================================================================== */ /* === cholmod_rowdel ======================================================= */ /* ========================================================================== */ /* Sets the kth row and column of L to be the kth row and column of the identity * matrix, and updates L(k+1:n,k+1:n) accordingly. To reduce the running time, * the caller can optionally provide the nonzero pattern (or an upper bound) of * kth row of L, as the sparse n-by-1 vector R. Provide R as NULL if you want * CHOLMOD to determine this itself, which is easier for the caller, but takes * a little more time. */ int CHOLMOD(rowdel) ( /* ---- input ---- */ size_t k, /* row/column index to delete */ cholmod_sparse *R, /* NULL, or the nonzero pattern of kth row of L */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ /* --------------- */ cholmod_common *Common ) { double yk [2] ; yk [0] = 0. ; yk [1] = 0. ; return (CHOLMOD(rowdel_mark) (k, R, yk, NULL, L, NULL, NULL, Common)) ; } /* ========================================================================== */ /* === cholmod_rowdel_solve ================================================= */ /* ========================================================================== */ /* Does the same as cholmod_rowdel, but also downdates the solution to Lx=b. * When row/column k of A is "deleted" from the system A*y=b, this can induce * a change to x, in addition to changes arising when L and b are modified. * If this is the case, the kth entry of y is required as input (yk) */ int CHOLMOD(rowdel_solve) ( /* ---- input ---- */ size_t k, /* row/column index to delete */ cholmod_sparse *R, /* NULL, or the nonzero pattern of kth row of L */ double yk [2], /* kth entry in the solution to A*y=b */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ cholmod_dense *X, /* solution to Lx=b (size n-by-1) */ cholmod_dense *DeltaB, /* change in b, zero on output */ /* --------------- */ cholmod_common *Common ) { return (CHOLMOD(rowdel_mark) (k, R, yk, NULL, L, X, DeltaB, Common)) ; } /* ========================================================================== */ /* === cholmod_rowdel_mark ================================================== */ /* ========================================================================== */ /* Does the same as cholmod_rowdel_solve, except only part of L is used in * the update/downdate of the solution to Lx=b. This routine is an "expert" * routine. It is meant for use in LPDASA only. * * if R == NULL then columns 0:k-1 of L are searched for row k. Otherwise, it * searches columns in the set defined by the pattern of the first column of R. * This is meant to be the pattern of row k of L (a superset of that pattern is * OK too). R must be a permutation of a subset of 0:k-1. */ int CHOLMOD(rowdel_mark) ( /* ---- input ---- */ size_t kdel, /* row/column index to delete */ cholmod_sparse *R, /* NULL, or the nonzero pattern of kth row of L */ double yk [2], /* kth entry in the solution to A*y=b */ Int *colmark, /* Int array of size 1. See cholmod_updown.c */ /* ---- in/out --- */ cholmod_factor *L, /* factor to modify */ cholmod_dense *X, /* solution to Lx=b (size n-by-1) */ cholmod_dense *DeltaB, /* change in b, zero on output */ /* --------------- */ cholmod_common *Common ) { double dk, sqrt_dk, xk, dj, fl ; double *Lx, *Cx, *W, *Xx, *Nx ; Int *Li, *Lp, *Lnz, *Ci, *Rj, *Rp, *Iwork ; cholmod_sparse *C, Cmatrix ; Int j, p, pend, kk, lnz, n, Cp [2], do_solve, do_update, left, k, right, middle, i, klast, given_row, rnz ; size_t s ; int ok = TRUE ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (L, FALSE) ; RETURN_IF_XTYPE_INVALID (L, CHOLMOD_PATTERN, CHOLMOD_REAL, FALSE) ; n = L->n ; k = kdel ; if (kdel >= L->n || k < 0) { ERROR (CHOLMOD_INVALID, "k invalid") ; return (FALSE) ; } if (R == NULL) { Rj = NULL ; rnz = EMPTY ; } else { RETURN_IF_XTYPE_INVALID (R, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; if (R->ncol != 1 || R->nrow != L->n) { ERROR (CHOLMOD_INVALID, "R invalid") ; return (FALSE) ; } Rj = R->i ; Rp = R->p ; rnz = Rp [1] ; } do_solve = (X != NULL) && (DeltaB != NULL) ; if (do_solve) { RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_REAL, FALSE) ; RETURN_IF_XTYPE_INVALID (DeltaB, CHOLMOD_REAL, CHOLMOD_REAL, FALSE) ; Xx = X->x ; Nx = DeltaB->x ; if (X->nrow != L->n || X->ncol != 1 || DeltaB->nrow != L->n || DeltaB->ncol != 1 || Xx == NULL || Nx == NULL) { ERROR (CHOLMOD_INVALID, "X and/or DeltaB invalid") ; return (FALSE) ; } } else { Xx = NULL ; Nx = NULL ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ /* s = 2*n */ s = CHOLMOD(mult_size_t) (n, 2, &ok) ; if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (FALSE) ; } CHOLMOD(allocate_work) (n, s, s, Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 2*n, Common)) ; /* ---------------------------------------------------------------------- */ /* convert to simplicial numeric LDL' factor, if not already */ /* ---------------------------------------------------------------------- */ if (L->xtype == CHOLMOD_PATTERN || L->is_super || L->is_ll) { /* can only update/downdate a simplicial LDL' factorization */ CHOLMOD(change_factor) (CHOLMOD_REAL, FALSE, FALSE, FALSE, FALSE, L, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory, L is returned unchanged */ return (FALSE) ; } } /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ /* inputs, not modified on output: */ Lp = L->p ; /* size n+1 */ /* outputs, contents defined on input for incremental case only: */ Lnz = L->nz ; /* size n */ Li = L->i ; /* size L->nzmax. Can change in size. */ Lx = L->x ; /* size L->nzmax. Can change in size. */ ASSERT (L->nz != NULL) ; /* ---------------------------------------------------------------------- */ /* get workspace */ /* ---------------------------------------------------------------------- */ W = Common->Xwork ; /* size n, used only in cholmod_updown */ Cx = W + n ; /* use 2nd column of Xwork for C (size n) */ Iwork = Common->Iwork ; Ci = Iwork + n ; /* size n (i/i/l) */ /* NOTE: cholmod_updown uses Iwork [0..n-1] (i/i/l) as Stack */ /* ---------------------------------------------------------------------- */ /* prune row k from all columns of L */ /* ---------------------------------------------------------------------- */ given_row = (rnz >= 0) ; klast = given_row ? rnz : k ; PRINT2 (("given_row "ID"\n", given_row)) ; for (kk = 0 ; kk < klast ; kk++) { /* either search j = 0:k-1 or j = Rj [0:rnz-1] */ j = given_row ? (Rj [kk]) : (kk) ; if (j < 0 || j >= k) { ERROR (CHOLMOD_INVALID, "R invalid") ; return (FALSE) ; } PRINT2 (("Prune col j = "ID":\n", j)) ; lnz = Lnz [j] ; dj = Lx [Lp [j]] ; ASSERT (Lnz [j] > 0 && Li [Lp [j]] == j) ; if (lnz > 1) { left = Lp [j] ; pend = left + lnz ; right = pend - 1 ; i = Li [right] ; if (i < k) { /* row k is not in column j */ continue ; } else if (i == k) { /* k is the last row index in this column (quick delete) */ if (do_solve) { Xx [j] -= yk [0] * dj * Lx [right] ; } Lx [right] = 0 ; } else { /* binary search for row k in column j */ PRINT2 (("\nBinary search: lnz "ID" k = "ID"\n", lnz, k)) ; while (left < right) { middle = (left + right) / 2 ; PRINT2 (("left "ID" right "ID" middle "ID": ["ID" "ID"" ""ID"]\n", left, right, middle, Li [left], Li [middle], Li [right])) ; if (k > Li [middle]) { left = middle + 1 ; } else { right = middle ; } } ASSERT (left >= Lp [j] && left < pend) ; #ifndef NDEBUG /* brute force, linear-time search */ { Int p3 = Lp [j] ; i = EMPTY ; PRINT2 (("Brute force:\n")) ; for ( ; p3 < pend ; p3++) { i = Li [p3] ; PRINT2 (("p "ID" ["ID"]\n", p3, i)) ; if (i >= k) { break ; } } if (i == k) { ASSERT (k == Li [p3]) ; ASSERT (p3 == left) ; } } #endif if (k == Li [left]) { if (do_solve) { Xx [j] -= yk [0] * dj * Lx [left] ; } /* found row k in column j. Prune it from the column.*/ Lx [left] = 0 ; } } } } #ifndef NDEBUG /* ensure that row k has been deleted from the matrix L */ for (j = 0 ; j < k ; j++) { Int lasti ; lasti = EMPTY ; p = Lp [j] ; pend = p + Lnz [j] ; /* look for row k in column j */ PRINT1 (("Pruned column "ID"\n", j)) ; for ( ; p < pend ; p++) { i = Li [p] ; PRINT2 ((" "ID"", i)) ; PRINT2 ((" %g\n", Lx [p])) ; ASSERT (IMPLIES (i == k, Lx [p] == 0)) ; ASSERT (i > lasti) ; lasti = i ; } PRINT1 (("\n")) ; } #endif /* ---------------------------------------------------------------------- */ /* set diagonal and clear column k of L */ /* ---------------------------------------------------------------------- */ lnz = Lnz [k] - 1 ; ASSERT (Lnz [k] > 0) ; /* ---------------------------------------------------------------------- */ /* update/downdate */ /* ---------------------------------------------------------------------- */ /* update or downdate L (k+1:n, k+1:n) with the vector * C = L (:,k) * sqrt (abs (D [k])) * Do a numeric update if D[k] > 0, numeric downdate otherwise. */ PRINT1 (("rowdel downdate lnz = "ID"\n", lnz)) ; /* store the new unit diagonal */ p = Lp [k] ; pend = p + lnz + 1 ; dk = Lx [p] ; Lx [p++] = 1 ; PRINT2 (("D [k = "ID"] = %g\n", k, dk)) ; ok = TRUE ; fl = 0 ; if (lnz > 0) { /* compute DeltaB for updown (in DeltaB) */ if (do_solve) { xk = Xx [k] - yk [0] * dk ; for ( ; p < pend ; p++) { Nx [Li [p]] += Lx [p] * xk ; } } do_update = IS_GT_ZERO (dk) ; if (!do_update) { dk = -dk ; } sqrt_dk = sqrt (dk) ; p = Lp [k] + 1 ; for (kk = 0 ; kk < lnz ; kk++, p++) { Ci [kk] = Li [p] ; Cx [kk] = Lx [p] * sqrt_dk ; Lx [p] = 0 ; /* clear column k */ } fl = lnz + 1 ; /* create a n-by-1 sparse matrix to hold the single column */ C = &Cmatrix ; C->nrow = n ; C->ncol = 1 ; C->nzmax = lnz ; C->sorted = TRUE ; C->packed = TRUE ; C->p = Cp ; C->i = Ci ; C->x = Cx ; C->nz = NULL ; C->itype = L->itype ; C->xtype = L->xtype ; C->dtype = L->dtype ; C->z = NULL ; C->stype = 0 ; Cp [0] = 0 ; Cp [1] = lnz ; /* numeric update if dk > 0, and with Lx=b change */ /* workspace: Flag (nrow), Head (nrow+1), W (nrow), Iwork (2*nrow) */ ok = CHOLMOD(updown_mark) (do_update ? (1) : (0), C, colmark, L, X, DeltaB, Common) ; /* clear workspace */ for (kk = 0 ; kk < lnz ; kk++) { Cx [kk] = 0 ; } } Common->modfl += fl ; if (do_solve) { /* kth equation becomes identity, so X(k) is now Y(k) */ Xx [k] = yk [0] ; } DEBUG (CHOLMOD(dump_factor) (L, "LDL factorization, L:", Common)) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 2*n, Common)) ; return (ok) ; } #endif #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Check/���������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14547723665�014432� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Check/cholmod_read.c�������������������������������������������������������������0000644�0001762�0000144�00000117037�13652535054�017214� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Check/cholmod_read =================================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Check Module. Copyright (C) 2005-2006, Timothy A. Davis. * -------------------------------------------------------------------------- */ /* Read a sparse matrix in triplet or dense form. A triplet matrix can be * returned as compressed-column sparse matrix. The file format is compatible * with all variations of the Matrix Market "coordinate" and "array" format * (http://www.nist.gov/MatrixMarket). The format supported by these routines * also allow other formats, where the Matrix Market header is optional. * * Although the Matrix Market header is optional, I recommend that users stick * with the strict Matrix Market format. The optional format appears here to * support the reading of symmetric matrices stored with just their upper * triangular parts present, for testing and development of the A->stype > 0 * format in CHOLMOD. That format is not included in the Matrix Market format. * * If the first line of the file starts with %%MatrixMarket, then it is * interpretted as a file in Matrix Market format. This line must have * the following format: * * %%MatrixMarket matrix * * is one of: coordinate or array. The former is a sparse matrix in * triplet form. The latter is a dense matrix in column-major form. * * is one of: real, complex, pattern, or integer. * The functions here convert the "integer" and "pattern" types to real. * * is one of: general, hermitian, symmetric, or skew-symmetric * * The strings are case-insensitive. Only the first character is * significant (or the first two for skew-symmetric). * * is ignored for all matrices; the actual type (real, complex, * or pattern) is inferred from the number of tokens in each line of the * file. For a "coordinate" matrix: 2: pattern, 3: real, 4: complex; for * a dense "array" matrix: 1: real, 2: complex. This is compatible with * the Matrix Market format, since pattern matrices must have two tokens * per line, real matrices must have 3, and complex matrices must have 4. * A storage of "general" implies an stype of zero (see below). * "symmetric" and "hermitian" imply an stype of -1. Skew-symmetric and * complex symmetric matrices are always returned with both upper and lower * triangular parts present, with an stype of zero, since CHOLMOD does not * have a method for representing skew-symmetric and complex symmetric * matrices. Real symmetric and complex Hermitian matrices may optionally * be returned with both parts present. * * Any other lines starting with "%" are treated as comments, and are ignored. * Blank lines are ignored. The Matrix Market header is optional in this * routine (it is not optional in the Matrix Market format). * * Note that complex matrices are always returned in CHOLMOD_COMPLEX format, * not CHOLMOD_ZOMPLEX. * * ----------------------------------------------------------------------------- * Triplet matrices: * ----------------------------------------------------------------------------- * * The first data line of a triplet matrix contains 3 or 4 integers: * * nrow ncol nnz stype * * where stype is optional (stype does not appear in the Matrix Market format). * The matrix is nrow-by-ncol. The following nnz lines (excluding comments * and blank lines) each contain a single entry. Duplicates are permitted, * and are summed in the output matrix. * * The stype is first derived from the Matrix Market header. If the stype * appears as the fourth integer in the first data line, it is determined from * that line. * * If stype is present, it denotes the storage format for the matrix. * stype = 0 denotes an unsymmetric matrix (same as Matrix Market "general"). * stype = -1 denotes a real symmetric or complex Hermitian matrix whose lower * triangular entries are stored. Entries may be present in the upper * triangular part, but these are ignored (same as Matrix Market * "real symmetric" and "complex Hermitian"). * stype = 1 denotes a real symmetric or complex Hermitian matrix whose upper * triangular entries are stored. Entries may be present in the lower * triangular part, but these are ignored. This option is not present * in the Matrix Market format. * * If stype is not present (no Matrix Market header and not in the first data * line) it is inferred from the rest of the data. If the matrix is * rectangular, or has entries in both the upper and lower triangular parts, * then it is assumed to be unsymmetric (stype=0). If only entries in the * lower triangular part are present, the matrix is assumed to have stype = -1. * If only entries in the upper triangular part are present, the matrix is * assumed to have stype = 1. * * After the first data line (with nrow, ncol, nnz, and optionally stype), * each nonzero consists of one line with 2, 3, or 4 entries. All lines must * have the same number of entries. The first two entries are the row and * column indices of the nonzero. If 3 entries are present, the 3rd entry is * the numerical value, and the matrix is real. If 4 entries are present, * the 3rd and 4th entries in the line are the real and imaginary parts of * a complex value. * * The matrix can be either 0-based or 1-based. It is first assumed to be * one-based (all matrices in the Matrix Market are one-based), with row indices * in the range 1 to ncol and column indices in the range 1 to nrow. If a row * or column index of zero is found, the matrix is assumed to be zero-based * (with row indices in the range 0 to ncol-1 and column indices in the range 0 * to nrow-1). * * If Common->prefer_binary is set to its default value of FALSE, then * for symmetric pattern-only matrices, the kth diagonal (if present) is set to * one plus the degree of the row/column k, and the off-diagonal entries are set * to -1. A symmetric pattern-only matrix with a zero-free diagonal is thus * converted into a symmetric positive definite matrix. All entries are set to * one for an unsymmetric pattern-only matrix. This differs from the * Matrix Market format (A = mmread ('file') returns a binary pattern for A for * symmetric pattern-only matrices). If Common->prefer_binary is TRUE, then * this function returns a binary matrix (just like mmread('file')). * * ----------------------------------------------------------------------------- * Dense matrices: * ----------------------------------------------------------------------------- * * A dense matrix is specified by the Matrix Market "array" format. The * Matrix Market header is optional; if not present, the matrix is assumed to * be in the Matrix Market "general" format. The first data line contains just * two integers: * * nrow ncol * * The can be real, integer, or complex (not pattern). These functions * convert an integer type to real. The entries in the matrix are stored in * column-major format, with one line per entry. Two entries are present in * each line for complex matrices, one for real and integer matrices. In * rectangular and unsymmetric matrices, all entries are present. For real * symmetric or complex Hermitian matrices, only entries in the lower triangular * part appear. For skew-symmetric matrices, only entries in the strictly * lower triangular part appear. * * Since CHOLMOD does not have a data structure for presenting dense symmetric/ * Hermitian matrices, these functions always return a dense matrix in its * general form, with both upper and lower parts present. */ #ifndef NCHECK #include "cholmod_internal.h" #include "cholmod_check.h" #include #include /* The MatrixMarket format specificies a maximum line length of 1024 */ #define MAXLINE 1030 /* ========================================================================== */ /* === get_line ============================================================= */ /* ========================================================================== */ /* Read one line of the file, return TRUE if successful, FALSE if EOF. */ static int get_line (FILE *f, char *buf) { buf [0] = '\0' ; buf [1] = '\0' ; buf [MAXLINE] = '\0' ; return (fgets (buf, MAXLINE, f) != NULL) ; } /* ========================================================================== */ /* === fix_inf ============================================================== */ /* ========================================================================== */ /* Replace huge values with +/- Inf's, since scanf and printf don't deal * with Inf's properly. */ static double fix_inf (double x) { if ((x >= HUGE_DOUBLE) || (x <= -HUGE_DOUBLE)) { /* treat this as +/- Inf (assume 2*x leads to overflow) */ x = 2*x ; } return (x) ; } /* ========================================================================== */ /* === is_blank_line ======================================================== */ /* ========================================================================== */ /* TRUE if s is a blank line or comment, FALSE otherwise */ static int is_blank_line ( char *s ) { int c, k ; if (s [0] == '%') { /* a comment line */ return (TRUE) ; } for (k = 0 ; k <= MAXLINE ; k++) { c = s [k] ; if (c == '\0') { /* end of line */ break ; } if (!isspace (c)) { /* non-space character */ return (FALSE) ; } } return (TRUE) ; } /* ========================================================================== */ /* === read_header ========================================================== */ /* ========================================================================== */ /* Read the header. This consists of zero or more comment lines (blank, or * starting with a "%" in the first column), followed by a single data line * containing up to four numerical values. * * The first line may optionally be a Matrix Market header line, of the form * * %%MatrixMarket matrix * * The first data line of a sparse matrix in triplet form consists of 3 or 4 * numerical values: * * nrow ncol nnz stype * * where stype is optional (it does not appear in the Matrix Market file * format). The first line of a dense matrix in column-major form consists of * two numerical values: * * nrow ncol * * The stype of the matrix is determine either from the Matrix Market header, * or (optionally) from the first data line. stypes of 0 to -3 directly * correlate with the Matrix Market format; stype = 1 is an extension to that * format. * * 999: unknown (will be inferred from the data) * 1: real symmetric or complex Hermitian with upper part stored * (not in the Matrix Market format) * 0: unsymmetric (same as Matrix Market "general") * -1: real symmetric or complex Hermitian, with lower part stored * (Matrix Market "real symmetric" or "complex hermitian") * -2: real or complex skew symmetric (lower part stored, can only be * specified by Matrix Market header) * -3: complex symmetric (lower part stored) * specified by Matrix Market header) * * The Matrix Market header is optional. If stype appears in the first data * line, it is determine by that data line. Otherwise, if the Matrix Market * header appears, stype is determined from that header. If stype does not * appear, it is set to "unknown" (999). */ #define STYPE_UNKNOWN 999 #define STYPE_SYMMETRIC_UPPER 1 #define STYPE_UNSYMMETRIC 0 #define STYPE_SYMMETRIC_LOWER -1 #define STYPE_SKEW_SYMMETRIC -2 #define STYPE_COMPLEX_SYMMETRIC_LOWER -3 static int read_header /* returns TRUE if successful, FALSE on error */ ( /* ---- input ---- */ FILE *f, /* file to read from */ /* ---- output --- */ char *buf, /* a character array of size MAXLINE+1 */ int *mtype, /* CHOLMOD_TRIPLET or CHOLMOD_DENSE */ size_t *nrow, /* number of rows in the matrix */ size_t *ncol, /* number of columns in the matrix */ size_t *nnz, /* number of entries in a triplet matrix (0 for dense)*/ int *stype /* stype (see above) */ ) { char *p ; int first = TRUE, got_mm_header = FALSE, c, c2, is_complex, nitems ; double l1, l2, l3, l4 ; *mtype = CHOLMOD_TRIPLET ; *nrow = 0 ; *ncol = 0 ; *nnz = 0 ; *stype = STYPE_UNKNOWN ; for ( ; ; ) { /* ------------------------------------------------------------------ */ /* get the next line */ /* ------------------------------------------------------------------ */ if (!get_line (f, buf)) { /* premature end of file */ return (FALSE) ; } if (first && (strncmp (buf, "%%MatrixMarket", 14) == 0)) { /* -------------------------------------------------------------- */ /* read a Matrix Market header */ /* -------------------------------------------------------------- */ got_mm_header = TRUE ; p = buf ; /* -------------------------------------------------------------- */ /* get "matrix" token */ /* -------------------------------------------------------------- */ while (*p && !isspace (*p)) p++ ; while (*p && isspace (*p)) p++ ; c = tolower (*p) ; if (c != 'm') { /* bad format */ return (FALSE) ; } /* -------------------------------------------------------------- */ /* get the fmt token ("coord" or "array") */ /* -------------------------------------------------------------- */ while (*p && !isspace (*p)) p++ ; while (*p && isspace (*p)) p++ ; c = tolower (*p) ; if (c == 'c') { *mtype = CHOLMOD_TRIPLET ; } else if (c == 'a') { *mtype = CHOLMOD_DENSE ; } else { /* bad format, neither "coordinate" nor "array" */ return (FALSE) ; } /* -------------------------------------------------------------- */ /* get type token (real, pattern, complex, integer) */ /* -------------------------------------------------------------- */ while (*p && !isspace (*p)) p++ ; while (*p && isspace (*p)) p++ ; c = tolower (*p) ; if (!(c == 'r' || c == 'p' || c == 'c' || c == 'i')) { /* bad format */ return (FALSE) ; } is_complex = (c == 'c') ; /* -------------------------------------------------------------- */ /* get storage token (general, hermitian, symmetric, skew) */ /* -------------------------------------------------------------- */ while (*p && !isspace (*p)) p++ ; while (*p && isspace (*p)) p++ ; c = tolower (*p) ; c2 = tolower (*(p+1)) ; if (c == 'g') { /* "general" storage (unsymmetric matrix), both parts present */ *stype = STYPE_UNSYMMETRIC ; } else if (c == 's' && c2 == 'y') { /* "symmetric" */ if (is_complex) { /* complex symmetric, lower triangular part present */ *stype = STYPE_COMPLEX_SYMMETRIC_LOWER ; } else { /* real symmetric, lower triangular part present */ *stype = STYPE_SYMMETRIC_LOWER ; } } else if (c == 'h') { /* "hermitian" matrix, lower triangular part present */ *stype = STYPE_SYMMETRIC_LOWER ; } else if (c == 's' && c2 == 'k') { /* "skew-symmetric" (real or complex), lower part present */ *stype = STYPE_SKEW_SYMMETRIC ; } else { /* bad format */ return (FALSE) ; } } else if (is_blank_line (buf)) { /* -------------------------------------------------------------- */ /* blank line or comment line */ /* -------------------------------------------------------------- */ continue ; } else { /* -------------------------------------------------------------- */ /* read the first data line and return */ /* -------------------------------------------------------------- */ /* format: nrow ncol nnz stype */ l1 = EMPTY ; l2 = EMPTY ; l3 = 0 ; l4 = 0 ; nitems = sscanf (buf, "%lg %lg %lg %lg\n", &l1, &l2, &l3, &l4) ; if (nitems < 2 || nitems > 4 || l1 > Int_max || l2 > Int_max) { /* invalid matrix */ return (FALSE) ; } *nrow = l1 ; *ncol = l2 ; if (nitems == 2) { /* a dense matrix */ if (!got_mm_header) { *mtype = CHOLMOD_DENSE ; *stype = STYPE_UNSYMMETRIC ; } } if (nitems == 3 || nitems == 4) { /* a sparse triplet matrix */ *nnz = l3 ; if (!got_mm_header) { *mtype = CHOLMOD_TRIPLET ; } } if (nitems == 4) { /* an stype specified here can only be 1, 0, or -1 */ if (l4 < 0) { *stype = STYPE_SYMMETRIC_LOWER ; } else if (l4 > 0) { *stype = STYPE_SYMMETRIC_UPPER ; } else { *stype = STYPE_UNSYMMETRIC ; } } if (*nrow != *ncol) { /* a rectangular matrix must be unsymmetric */ *stype = STYPE_UNSYMMETRIC ; } return (TRUE) ; } first = FALSE ; } } /* ========================================================================== */ /* === read_triplet ========================================================= */ /* ========================================================================== */ /* Header has already been read in, including first line (nrow ncol nnz stype). * Read the triplets. */ static cholmod_triplet *read_triplet ( /* ---- input ---- */ FILE *f, /* file to read from, must already be open */ size_t nrow, /* number of rows */ size_t ncol, /* number of columns */ size_t nnz, /* number of triplets in file to read */ int stype, /* stype from header, or "unknown" */ int prefer_unsym, /* if TRUE, always return T->stype of zero */ /* ---- workspace */ char *buf, /* of size MAXLINE+1 */ /* --------------- */ cholmod_common *Common ) { double x, z ; double *Tx ; Int *Ti, *Tj, *Rdeg, *Cdeg ; cholmod_triplet *T ; double l1, l2 ; Int nitems, xtype, unknown, k, nshould, is_lower, is_upper, one_based, i, j, imax, jmax, skew_symmetric, p, complex_symmetric ; size_t s, nnz2, extra ; int ok = TRUE ; /* ---------------------------------------------------------------------- */ /* quick return for empty matrix */ /* ---------------------------------------------------------------------- */ if (nrow == 0 || ncol == 0 || nnz == 0) { /* return an empty matrix */ return (CHOLMOD(allocate_triplet) (nrow, ncol, 0, 0, CHOLMOD_REAL, Common)) ; } /* ---------------------------------------------------------------------- */ /* special stype cases: unknown, skew symmetric, and complex symmetric */ /* ---------------------------------------------------------------------- */ unknown = (stype == STYPE_UNKNOWN) ; skew_symmetric = (stype == STYPE_SKEW_SYMMETRIC) ; complex_symmetric = (stype == STYPE_COMPLEX_SYMMETRIC_LOWER) ; extra = 0 ; if (stype < STYPE_SYMMETRIC_LOWER || (prefer_unsym && stype != STYPE_UNSYMMETRIC)) { /* 999: unknown might be converted to unsymmetric */ /* 1: symmetric upper converted to unsym. if prefer_unsym is TRUE */ /* -1: symmetric lower converted to unsym. if prefer_unsym is TRUE */ /* -2: real or complex skew symmetric converted to unsymmetric */ /* -3: complex symmetric converted to unsymmetric */ stype = STYPE_UNSYMMETRIC ; extra = nnz ; } nnz2 = CHOLMOD(add_size_t) (nnz, extra, &ok) ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ /* s = nrow + ncol */ s = CHOLMOD(add_size_t) (nrow, ncol, &ok) ; if (!ok || nrow > Int_max || ncol > Int_max || nnz > Int_max) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (NULL) ; } CHOLMOD(allocate_work) (0, s, 0, Common) ; Rdeg = Common->Iwork ; /* size nrow */ Cdeg = Rdeg + nrow ; /* size ncol */ /* ---------------------------------------------------------------------- */ /* read the triplets */ /* ---------------------------------------------------------------------- */ is_lower = TRUE ; is_upper = TRUE ; one_based = TRUE ; imax = 0 ; jmax = 0 ; Tx = NULL ; Ti = NULL ; Tj = NULL ; xtype = 999 ; nshould = 0 ; for (k = 0 ; k < (Int) nnz ; k++) { /* ------------------------------------------------------------------ */ /* get the next triplet, skipping blank lines and comment lines */ /* ------------------------------------------------------------------ */ l1 = EMPTY ; l2 = EMPTY ; x = 0 ; z = 0 ; for ( ; ; ) { if (!get_line (f, buf)) { /* premature end of file - not enough triplets read in */ ERROR (CHOLMOD_INVALID, "premature EOF") ; return (NULL) ; } if (is_blank_line (buf)) { /* blank line or comment */ continue ; } nitems = sscanf (buf, "%lg %lg %lg %lg\n", &l1, &l2, &x, &z) ; x = fix_inf (x) ; z = fix_inf (z) ; break ; } nitems = (nitems == EOF) ? 0 : nitems ; i = l1 ; j = l2 ; /* ------------------------------------------------------------------ */ /* for first triplet: determine type and allocate triplet matrix */ /* ------------------------------------------------------------------ */ if (k == 0) { if (nitems < 2 || nitems > 4) { /* invalid matrix */ ERROR (CHOLMOD_INVALID, "invalid format") ; return (NULL) ; } else if (nitems == 2) { /* this will be converted into a real matrix later */ xtype = CHOLMOD_PATTERN ; } else if (nitems == 3) { xtype = CHOLMOD_REAL ; } else if (nitems == 4) { xtype = CHOLMOD_COMPLEX ; } /* the rest of the lines should have the same number of entries */ nshould = nitems ; /* allocate triplet matrix */ T = CHOLMOD(allocate_triplet) (nrow, ncol, nnz2, stype, (xtype == CHOLMOD_PATTERN ? CHOLMOD_REAL : xtype), Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ return (NULL) ; } Ti = T->i ; Tj = T->j ; Tx = T->x ; T->nnz = nnz ; } /* ------------------------------------------------------------------ */ /* save the entry in the triplet matrix */ /* ------------------------------------------------------------------ */ if (nitems != nshould || i < 0 || j < 0) { /* wrong format, premature end-of-file, or negative indices */ CHOLMOD(free_triplet) (&T, Common) ; ERROR (CHOLMOD_INVALID, "invalid matrix file") ; return (NULL) ; } Ti [k] = i ; Tj [k] = j ; if (i < j) { /* this entry is in the upper triangular part */ is_lower = FALSE ; } if (i > j) { /* this entry is in the lower triangular part */ is_upper = FALSE ; } if (xtype == CHOLMOD_REAL) { Tx [k] = x ; } else if (xtype == CHOLMOD_COMPLEX) { Tx [2*k ] = x ; /* real part */ Tx [2*k+1] = z ; /* imaginary part */ } if (i == 0 || j == 0) { one_based = FALSE ; } imax = MAX (i, imax) ; jmax = MAX (j, jmax) ; } /* ---------------------------------------------------------------------- */ /* convert to zero-based */ /* ---------------------------------------------------------------------- */ if (one_based) { /* input matrix is one-based; convert matrix to zero-based */ for (k = 0 ; k < (Int) nnz ; k++) { Ti [k]-- ; Tj [k]-- ; } } if (one_based ? (imax > (Int) nrow || jmax > (Int) ncol) : (imax >= (Int) nrow || jmax >= (Int) ncol)) { /* indices out of range */ CHOLMOD(free_triplet) (&T, Common) ; ERROR (CHOLMOD_INVALID, "indices out of range") ; return (NULL) ; } /* ---------------------------------------------------------------------- */ /* determine the stype, if not yet known */ /* ---------------------------------------------------------------------- */ if (unknown) { if (is_lower && is_upper) { /* diagonal matrix, symmetric with upper part present */ stype = STYPE_SYMMETRIC_UPPER ; } else if (is_lower && !is_upper) { /* symmetric, lower triangular part present */ stype = STYPE_SYMMETRIC_LOWER ; } else if (!is_lower && is_upper) { /* symmetric, upper triangular part present */ stype = STYPE_SYMMETRIC_UPPER ; } else { /* unsymmetric */ stype = STYPE_UNSYMMETRIC ; extra = 0 ; } } /* ---------------------------------------------------------------------- */ /* add the remainder of symmetric, skew-symmetric or Hermitian matrices */ /* ---------------------------------------------------------------------- */ /* note that this step is not done for real symmetric or complex Hermitian * matrices, unless prefer_unsym is TRUE */ if (extra > 0) { p = nnz ; for (k = 0 ; k < (Int) nnz ; k++) { i = Ti [k] ; j = Tj [k] ; if (i != j) { Ti [p] = j ; Tj [p] = i ; if (xtype == CHOLMOD_REAL) { if (skew_symmetric) { Tx [p] = -Tx [k] ; } else { Tx [p] = Tx [k] ; } } else if (xtype == CHOLMOD_COMPLEX) { if (skew_symmetric) { Tx [2*p ] = -Tx [2*k ] ; Tx [2*p+1] = -Tx [2*k+1] ; } else if (complex_symmetric) { Tx [2*p ] = Tx [2*k ] ; Tx [2*p+1] = Tx [2*k+1] ; } else /* Hermitian */ { Tx [2*p ] = Tx [2*k ] ; Tx [2*p+1] = -Tx [2*k+1] ; } } p++ ; } } T->nnz = p ; nnz = p ; } T->stype = stype ; /* ---------------------------------------------------------------------- */ /* create values for a pattern-only matrix */ /* ---------------------------------------------------------------------- */ if (xtype == CHOLMOD_PATTERN) { if (stype == STYPE_UNSYMMETRIC || Common->prefer_binary) { /* unsymmetric case, or binary case */ for (k = 0 ; k < (Int) nnz ; k++) { Tx [k] = 1 ; } } else { /* compute the row and columm degrees (excluding the diagonal) */ for (i = 0 ; i < (Int) nrow ; i++) { Rdeg [i] = 0 ; } for (j = 0 ; j < (Int) ncol ; j++) { Cdeg [j] = 0 ; } for (k = 0 ; k < (Int) nnz ; k++) { i = Ti [k] ; j = Tj [k] ; if ((stype < 0 && i > j) || (stype > 0 && i < j)) { /* both a(i,j) and a(j,i) appear in the matrix */ Rdeg [i]++ ; Cdeg [j]++ ; Rdeg [j]++ ; Cdeg [i]++ ; } } /* assign the numerical values */ for (k = 0 ; k < (Int) nnz ; k++) { i = Ti [k] ; j = Tj [k] ; Tx [k] = (i == j) ? (1 + MAX (Rdeg [i], Cdeg [j])) : (-1) ; } } } /* ---------------------------------------------------------------------- */ /* return the new triplet matrix */ /* ---------------------------------------------------------------------- */ return (T) ; } /* ========================================================================== */ /* === read_dense =========================================================== */ /* ========================================================================== */ /* Header has already been read in, including first line (nrow ncol). * Read a dense matrix. */ static cholmod_dense *read_dense ( /* ---- input ---- */ FILE *f, /* file to read from, must already be open */ size_t nrow, /* number of rows */ size_t ncol, /* number of columns */ int stype, /* stype from header */ /* ---- workspace */ char *buf, /* of size MAXLINE+1 */ /* --------------- */ cholmod_common *Common ) { double x, z ; double *Xx = NULL ; cholmod_dense *X ; Int nitems, xtype = -1, nshould = 0, i, j, k, kup, first ; /* ---------------------------------------------------------------------- */ /* quick return for empty matrix */ /* ---------------------------------------------------------------------- */ if (nrow == 0 || ncol == 0) { /* return an empty dense matrix */ return (CHOLMOD(zeros) (nrow, ncol, CHOLMOD_REAL, Common)) ; } /* ---------------------------------------------------------------------- */ /* read the entries */ /* ---------------------------------------------------------------------- */ first = TRUE ; for (j = 0 ; j < (Int) ncol ; j++) { /* ------------------------------------------------------------------ */ /* get the row index of the first entry in the file for column j */ /* ------------------------------------------------------------------ */ if (stype == STYPE_UNSYMMETRIC) { i = 0 ; } else if (stype == STYPE_SKEW_SYMMETRIC) { i = j+1 ; } else /* real symmetric or complex Hermitian lower */ { i = j ; } /* ------------------------------------------------------------------ */ /* get column j */ /* ------------------------------------------------------------------ */ for ( ; i < (Int) nrow ; i++) { /* -------------------------------------------------------------- */ /* get the next entry, skipping blank lines and comment lines */ /* -------------------------------------------------------------- */ x = 0 ; z = 0 ; for ( ; ; ) { if (!get_line (f, buf)) { /* premature end of file - not enough entries read in */ ERROR (CHOLMOD_INVALID, "premature EOF") ; return (NULL) ; } if (is_blank_line (buf)) { /* blank line or comment */ continue ; } nitems = sscanf (buf, "%lg %lg\n", &x, &z) ; x = fix_inf (x) ; z = fix_inf (z) ; break ; } nitems = (nitems == EOF) ? 0 : nitems ; /* -------------------------------------------------------------- */ /* for first entry: determine type and allocate dense matrix */ /* -------------------------------------------------------------- */ if (first) { first = FALSE ; if (nitems < 1 || nitems > 2) { /* invalid matrix */ ERROR (CHOLMOD_INVALID, "invalid format") ; return (NULL) ; } else if (nitems == 1) { /* a real matrix */ xtype = CHOLMOD_REAL ; } else if (nitems == 2) { /* a complex matrix */ xtype = CHOLMOD_COMPLEX ; } /* the rest of the lines should have same number of entries */ nshould = nitems ; /* allocate the result */ X = CHOLMOD(zeros) (nrow, ncol, xtype, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ return (NULL) ; } Xx = X->x ; } /* -------------------------------------------------------------- */ /* save the entry in the dense matrix */ /* -------------------------------------------------------------- */ if (nitems != nshould) { /* wrong format or premature end-of-file */ CHOLMOD(free_dense) (&X, Common) ; ERROR (CHOLMOD_INVALID, "invalid matrix file") ; return (NULL) ; } k = i + j*nrow ; kup = j + i*nrow ; if (xtype == CHOLMOD_REAL) { /* real matrix */ Xx [k] = x ; if (k != kup) { if (stype == STYPE_SYMMETRIC_LOWER) { /* real symmetric matrix */ Xx [kup] = x ; } else if (stype == STYPE_SKEW_SYMMETRIC) { /* real skew symmetric matrix */ Xx [kup] = -x ; } } } else if (xtype == CHOLMOD_COMPLEX) { Xx [2*k ] = x ; /* real part */ Xx [2*k+1] = z ; /* imaginary part */ if (k != kup) { if (stype == STYPE_SYMMETRIC_LOWER) { /* complex Hermitian */ Xx [2*kup ] = x ; /* real part */ Xx [2*kup+1] = -z ; /* imaginary part */ } else if (stype == STYPE_SKEW_SYMMETRIC) { /* complex skew symmetric */ Xx [2*kup ] = -x ; /* real part */ Xx [2*kup+1] = -z ; /* imaginary part */ } if (stype == STYPE_COMPLEX_SYMMETRIC_LOWER) { /* complex symmetric */ Xx [2*kup ] = x ; /* real part */ Xx [2*kup+1] = z ; /* imaginary part */ } } } } } /* ---------------------------------------------------------------------- */ /* return the new dense matrix */ /* ---------------------------------------------------------------------- */ return (X) ; } /* ========================================================================== */ /* === cholmod_read_triplet ================================================= */ /* ========================================================================== */ /* Read in a triplet matrix from a file. */ cholmod_triplet *CHOLMOD(read_triplet) ( /* ---- input ---- */ FILE *f, /* file to read from, must already be open */ /* --------------- */ cholmod_common *Common ) { char buf [MAXLINE+1] ; size_t nrow, ncol, nnz ; int stype, mtype ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (f, NULL) ; Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* read the header and first data line */ /* ---------------------------------------------------------------------- */ if (!read_header (f, buf, &mtype, &nrow, &ncol, &nnz, &stype) || mtype != CHOLMOD_TRIPLET) { /* invalid matrix - this function can only read in a triplet matrix */ ERROR (CHOLMOD_INVALID, "invalid format") ; return (NULL) ; } /* ---------------------------------------------------------------------- */ /* read the triplet matrix */ /* ---------------------------------------------------------------------- */ return (read_triplet (f, nrow, ncol, nnz, stype, FALSE, buf, Common)) ; } /* ========================================================================== */ /* === cholmod_read_sparse ================================================== */ /* ========================================================================== */ /* Read a sparse matrix from a file. See cholmod_read_triplet for a discussion * of the file format. * * If Common->prefer_upper is TRUE (the default case), a symmetric matrix is * returned stored in upper-triangular form (A->stype == 1). */ cholmod_sparse *CHOLMOD(read_sparse) ( /* ---- input ---- */ FILE *f, /* file to read from, must already be open */ /* --------------- */ cholmod_common *Common ) { cholmod_sparse *A, *A2 ; cholmod_triplet *T ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (f, NULL) ; Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* convert to a sparse matrix in compressed-column form */ /* ---------------------------------------------------------------------- */ T = CHOLMOD(read_triplet) (f, Common) ; A = CHOLMOD(triplet_to_sparse) (T, 0, Common) ; CHOLMOD(free_triplet) (&T, Common) ; if (Common->prefer_upper && A != NULL && A->stype == -1) { /* A=A' */ A2 = CHOLMOD(transpose) (A, 2, Common) ; CHOLMOD(free_sparse) (&A, Common) ; A = A2 ; } return (A) ; } /* ========================================================================== */ /* === cholmod_read_dense =================================================== */ /* ========================================================================== */ /* Read a dense matrix from a file. */ cholmod_dense *CHOLMOD(read_dense) ( /* ---- input ---- */ FILE *f, /* file to read from, must already be open */ /* --------------- */ cholmod_common *Common ) { char buf [MAXLINE+1] ; size_t nrow, ncol, nnz ; int stype, mtype ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (f, NULL) ; Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* read the header and first data line */ /* ---------------------------------------------------------------------- */ if (!read_header (f, buf, &mtype, &nrow, &ncol, &nnz, &stype) || mtype != CHOLMOD_DENSE) { /* invalid matrix - this function can only read in a dense matrix */ ERROR (CHOLMOD_INVALID, "invalid format") ; return (NULL) ; } /* ---------------------------------------------------------------------- */ /* read the dense matrix */ /* ---------------------------------------------------------------------- */ return (read_dense (f, nrow, ncol, stype, buf, Common)) ; } /* ========================================================================== */ /* === cholmod_read_matrix ================================================== */ /* ========================================================================== */ /* Read a triplet matrix, sparse matrix or a dense matrix from a file. Returns * a void pointer to either a cholmod_triplet, cholmod_sparse, or cholmod_dense * object. The type of object is passed back to the caller as the mtype * argument. */ void *CHOLMOD(read_matrix) ( /* ---- input ---- */ FILE *f, /* file to read from, must already be open */ int prefer, /* If 0, a sparse matrix is always return as a * cholmod_triplet form. It can have any stype * (symmetric-lower, unsymmetric, or * symmetric-upper). * If 1, a sparse matrix is returned as an unsymmetric * cholmod_sparse form (A->stype == 0), with both * upper and lower triangular parts present. * This is what the MATLAB mread mexFunction does, * since MATLAB does not have an stype. * If 2, a sparse matrix is returned with an stype of 0 * or 1 (unsymmetric, or symmetric with upper part * stored). * This argument has no effect for dense matrices. */ /* ---- output---- */ int *mtype, /* CHOLMOD_TRIPLET, CHOLMOD_SPARSE or CHOLMOD_DENSE */ /* --------------- */ cholmod_common *Common ) { void *G = NULL ; cholmod_sparse *A, *A2 ; cholmod_triplet *T ; char buf [MAXLINE+1] ; size_t nrow, ncol, nnz ; int stype ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (NULL) ; RETURN_IF_NULL (f, NULL) ; RETURN_IF_NULL (mtype, NULL) ; Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* read the header to determine the mtype */ /* ---------------------------------------------------------------------- */ if (!read_header (f, buf, mtype, &nrow, &ncol, &nnz, &stype)) { /* invalid matrix */ ERROR (CHOLMOD_INVALID, "invalid format") ; return (NULL) ; } /* ---------------------------------------------------------------------- */ /* read a matrix */ /* ---------------------------------------------------------------------- */ if (*mtype == CHOLMOD_TRIPLET) { /* read in the triplet matrix, converting to unsymmetric format if * prefer == 1 */ T = read_triplet (f, nrow, ncol, nnz, stype, prefer == 1, buf, Common) ; if (prefer == 0) { /* return matrix in its original triplet form */ G = T ; } else { /* return matrix in a compressed-column form */ A = CHOLMOD(triplet_to_sparse) (T, 0, Common) ; CHOLMOD(free_triplet) (&T, Common) ; if (A != NULL && prefer == 2 && A->stype == -1) { /* convert A from symmetric-lower to symmetric-upper */ A2 = CHOLMOD(transpose) (A, 2, Common) ; CHOLMOD(free_sparse) (&A, Common) ; A = A2 ; } *mtype = CHOLMOD_SPARSE ; G = A ; } } else if (*mtype == CHOLMOD_DENSE) { /* return a dense matrix */ G = read_dense (f, nrow, ncol, stype, buf, Common) ; } return (G) ; } #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Check/cholmod_write.c������������������������������������������������������������0000644�0001762�0000144�00000051276�13652535054�017435� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Check/cholmod_write ================================================== */ /* ========================================================================== */ /* Write a matrix to a file in Matrix Market form. * * A can be sparse or full. * * If present and non-empty, A and Z must have the same dimension. Z contains * the explicit zero entries in the matrix (which MATLAB drops). The entries * of Z appear as explicit zeros in the output file. Z is optional. If it is * an empty matrix it is ignored. Z must be sparse or empty, if present. * It is ignored if A is full. * * filename is the name of the output file. comments is file whose * contents are include after the Matrix Market header and before the first * data line. Ignored if an empty string or not present. * * Except for the workspace used by cholmod_symmetry (ncol integers) for * the sparse case, these routines use no workspace at all. */ #ifndef NCHECK #include "cholmod_config.h" #include "cholmod_internal.h" #include "cholmod_check.h" #include "cholmod_matrixops.h" #include #include #define MMLEN 1024 #define MAXLINE MMLEN+6 /* ========================================================================== */ /* === include_comments ===================================================== */ /* ========================================================================== */ /* Read in the comments file, if it exists, and copy it to the Matrix Market * file. A "%" is prepended to each line. Returns TRUE if successful, FALSE * otherwise. */ static int include_comments (FILE *f, const char *comments) { FILE *cf = NULL ; char buffer [MAXLINE] ; int ok = TRUE ; if (comments != NULL && comments [0] != '\0') { cf = fopen (comments, "r") ; if (cf == NULL) { return (FALSE) ; } while (ok && fgets (buffer, MAXLINE, cf) != NULL) { /* ensure the line is not too long */ buffer [MMLEN-1] = '\0' ; buffer [MMLEN-2] = '\n' ; ok = ok && (fprintf (f, "%%%s", buffer) > 0) ; } fclose (cf) ; } return (ok) ; } /* ========================================================================== */ /* === get_value ============================================================ */ /* ========================================================================== */ /* Get the pth value in the matrix. */ static void get_value ( double *Ax, /* real values, or real/imag. for CHOLMOD_COMPLEX type */ double *Az, /* imaginary values for CHOLMOD_ZOMPLEX type */ Int p, /* get the pth entry */ Int xtype, /* A->xtype: pattern, real, complex, or zomplex */ double *x, /* the real part */ double *z /* the imaginary part */ ) { switch (xtype) { case CHOLMOD_PATTERN: *x = 1 ; *z = 0 ; break ; case CHOLMOD_REAL: *x = Ax [p] ; *z = 0 ; break ; case CHOLMOD_COMPLEX: *x = Ax [2*p] ; *z = Ax [2*p+1] ; break ; case CHOLMOD_ZOMPLEX: *x = Ax [p] ; *z = Az [p] ; break ; } } /* ========================================================================== */ /* === print_value ========================================================== */ /* ========================================================================== */ /* Print a numeric value to the file, using the shortest format that ensures * the value is written precisely. Returns TRUE if successful, FALSE otherwise. */ static int print_value ( FILE *f, /* file to print to */ double x, /* value to print */ Int is_integer /* TRUE if printing as an integer */ ) { double y ; char s [MAXLINE], *p ; Int i, dest = 0, src = 0 ; int width, ok ; if (is_integer) { i = (Int) x ; ok = (fprintf (f, ID, i) > 0) ; return (ok) ; } /* ---------------------------------------------------------------------- */ /* handle Inf and NaN */ /* ---------------------------------------------------------------------- */ /* change -inf to -HUGE_DOUBLE, and change +inf and nan to +HUGE_DOUBLE */ if (CHOLMOD_IS_NAN (x) || x >= HUGE_DOUBLE) { x = HUGE_DOUBLE ; } else if (x <= -HUGE_DOUBLE) { x = -HUGE_DOUBLE ; } /* ---------------------------------------------------------------------- */ /* find the smallest acceptable precision */ /* ---------------------------------------------------------------------- */ for (width = 6 ; width < 20 ; width++) { sprintf (s, "%.*g", width, x) ; sscanf (s, "%lg", &y) ; if (x == y) break ; } /* ---------------------------------------------------------------------- */ /* shorten the string */ /* ---------------------------------------------------------------------- */ /* change "e+0" to "e", change "e+" to "e", and change "e-0" to "e-" */ for (i = 0 ; i < MAXLINE && s [i] != '\0' ; i++) { if (s [i] == 'e') { if (s [i+1] == '+') { dest = i+1 ; if (s [i+2] == '0') { /* delete characters s[i+1] and s[i+2] */ src = i+3 ; } else { /* delete characters s[i+1] */ src = i+2 ; } } else if (s [i+1] == '-') { dest = i+2 ; if (s [i+2] == '0') { /* delete character s[i+2] */ src = i+3 ; } else { /* no change */ break ; } } while (s [src] != '\0') { s [dest++] = s [src++] ; } s [dest] = '\0' ; break ; } } /* delete the leading "0" if present and not necessary */ p = s ; s [MAXLINE-1] = '\0' ; i = strlen (s) ; if (i > 2 && s [0] == '0' && s [1] == '.') { /* change "0.x" to ".x" */ p = s + 1 ; } else if (i > 3 && s [0] == '-' && s [1] == '0' && s [2] == '.') { /* change "-0.x" to "-.x" */ s [1] = '-' ; p = s + 1 ; } #if 0 /* double-check */ i = sscanf (p, "%lg", &z) ; if (i != 1 || y != z) { /* oops! something went wrong in the "e+0" edit, above. */ /* this "cannot" happen */ sprintf (s, "%.*g", width, x) ; p = s ; } #endif /* ---------------------------------------------------------------------- */ /* print the value to the file */ /* ---------------------------------------------------------------------- */ ok = (fprintf (f, "%s", p) > 0) ; return (ok) ; } /* ========================================================================== */ /* === print_triplet ======================================================== */ /* ========================================================================== */ /* Print a triplet, converting it to one-based. Returns TRUE if successful, * FALSE otherwise. */ static int print_triplet ( FILE *f, /* file to print to */ Int is_binary, /* TRUE if file is "pattern" */ Int is_complex, /* TRUE if file is "complex" */ Int is_integer, /* TRUE if file is "integer" */ Int i, /* row index (zero-based) */ Int j, /* column index (zero-based) */ double x, /* real part */ double z /* imaginary part */ ) { int ok ; ok = (fprintf (f, ID " " ID, 1+i, 1+j) > 0) ; if (!is_binary) { fprintf (f, " ") ; ok = ok && print_value (f, x, is_integer) ; if (is_complex) { fprintf (f, " ") ; ok = ok && print_value (f, z, is_integer) ; } } ok = ok && (fprintf (f, "\n") > 0) ; return (ok) ; } /* ========================================================================== */ /* === ntriplets ============================================================ */ /* ========================================================================== */ /* Compute the number of triplets that will be printed to the file * from the matrix A. */ static Int ntriplets ( cholmod_sparse *A, /* matrix that will be printed */ Int is_sym /* TRUE if the file is symmetric (lower part only)*/ ) { Int *Ap, *Ai, *Anz, packed, i, j, p, pend, ncol, stype, nz = 0 ; if (A == NULL) { /* the Z matrix is NULL */ return (0) ; } stype = A->stype ; Ap = A->p ; Ai = A->i ; Anz = A->nz ; packed = A->packed ; ncol = A->ncol ; for (j = 0 ; j < ncol ; j++) { p = Ap [j] ; pend = (packed) ? Ap [j+1] : p + Anz [j] ; for ( ; p < pend ; p++) { i = Ai [p] ; if ((stype < 0 && i >= j) || (stype == 0 && (i >= j || !is_sym))) { /* CHOLMOD matrix is symmetric-lower (and so is the file); * or CHOLMOD matrix is unsymmetric and either A(i,j) is in * the lower part or the file is unsymmetric. */ nz++ ; } else if (stype > 0 && i <= j) { /* CHOLMOD matrix is symmetric-upper, but the file is * symmetric-lower. Need to transpose the entry. */ nz++ ; } } } return (nz) ; } /* ========================================================================== */ /* === cholmod_write_sparse ================================================= */ /* ========================================================================== */ /* Write a sparse matrix to a file in Matrix Market format. Optionally include * comments, and print explicit zero entries given by the pattern of the Z * matrix. If not NULL, the Z matrix must have the same dimensions and stype * as A. * * Returns the symmetry in which the matrix was printed (1 to 7, see the * CHOLMOD_MM_* codes in CHOLMOD/Include/cholmod_core.h), or -1 on failure. * * If A and Z are sorted on input, and either unsymmetric (stype = 0) or * symmetric-lower (stype < 0), and if A and Z do not overlap, then the triplets * are sorted, first by column and then by row index within each column, with * no duplicate entries. If all the above holds except stype > 0, then the * triplets are sorted by row first and then column. */ int CHOLMOD(write_sparse) ( /* ---- input ---- */ FILE *f, /* file to write to, must already be open */ cholmod_sparse *A, /* matrix to print */ cholmod_sparse *Z, /* optional matrix with pattern of explicit zeros */ const char *comments, /* optional filename of comments to include */ /* --------------- */ cholmod_common *Common ) { double x = 0, z = 0 ; double *Ax, *Az ; Int *Ap, *Ai, *Anz, *Zp, *Zi, *Znz ; Int nrow, ncol, is_complex, symmetry, i, j, q, iz, p, nz, is_binary, stype, is_integer, asym, is_sym, xtype, apacked, zpacked, pend, qend, zsym ; int ok ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (EMPTY) ; RETURN_IF_NULL (f, EMPTY) ; RETURN_IF_NULL (A, EMPTY) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, EMPTY) ; if (Z != NULL && (Z->nrow == 0 || Z->ncol == 0)) { /* Z is non-NULL but empty, so treat it as a NULL matrix */ Z = NULL ; } if (Z != NULL) { RETURN_IF_XTYPE_INVALID (Z, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, EMPTY) ; if (Z->nrow != A->nrow || Z->ncol != A->ncol || Z->stype != A->stype) { ERROR (CHOLMOD_INVALID, "dimension or type of A and Z mismatch") ; return (EMPTY) ; } } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* get the A matrix */ /* ---------------------------------------------------------------------- */ Ap = A->p ; Ai = A->i ; Ax = A->x ; Az = A->z ; Anz = A->nz ; nrow = A->nrow ; ncol = A->ncol ; xtype = A->xtype ; apacked = A->packed ; if (xtype == CHOLMOD_PATTERN) { /* a CHOLMOD pattern matrix is printed as "pattern" in the file */ is_binary = TRUE ; is_integer = FALSE ; is_complex = FALSE ; } else if (xtype == CHOLMOD_REAL) { /* determine if a real matrix is in fact binary or integer */ is_binary = TRUE ; is_integer = TRUE ; is_complex = FALSE ; for (j = 0 ; (is_binary || is_integer) && j < ncol ; j++) { p = Ap [j] ; pend = (apacked) ? Ap [j+1] : p + Anz [j] ; for ( ; (is_binary || is_integer) && p < pend ; p++) { x = Ax [p] ; if (x != 1) { is_binary = FALSE ; } /* convert to Int and then back to double */ i = (Int) x ; z = (double) i ; if (z != x) { is_integer = FALSE ; } } } } else { /* a CHOLMOD complex matrix is printed as "complex" in the file */ is_binary = FALSE ; is_integer = FALSE ; is_complex = TRUE ; } /* ---------------------------------------------------------------------- */ /* get the Z matrix (only consider the pattern) */ /* ---------------------------------------------------------------------- */ Zp = NULL ; Zi = NULL ; Znz = NULL ; zpacked = TRUE ; if (Z != NULL) { Zp = Z->p ; Zi = Z->i ; Znz = Z->nz ; zpacked = Z->packed ; } /* ---------------------------------------------------------------------- */ /* determine the symmetry of A and Z */ /* ---------------------------------------------------------------------- */ stype = A->stype ; if (A->nrow != A->ncol) { asym = CHOLMOD_MM_RECTANGULAR ; } else if (stype != 0) { /* CHOLMOD's A and Z matrices have a symmetric (and matching) stype. * Note that the diagonal is not checked. */ asym = is_complex ? CHOLMOD_MM_HERMITIAN : CHOLMOD_MM_SYMMETRIC ; } else if (!A->sorted) { /* A is in unsymmetric storage, but unsorted */ asym = CHOLMOD_MM_UNSYMMETRIC ; } else { /* CHOLMOD's stype is zero (stored in unsymmetric form) */ asym = EMPTY ; zsym = EMPTY ; #ifndef NMATRIXOPS /* determine if the matrices are in fact symmetric or Hermitian */ asym = CHOLMOD(symmetry) (A, 1, NULL, NULL, NULL, NULL, Common) ; zsym = (Z == NULL) ? 999 : CHOLMOD(symmetry) (Z, 1, NULL, NULL, NULL, NULL, Common) ; #endif if (asym == EMPTY || zsym <= CHOLMOD_MM_UNSYMMETRIC) { /* not computed, out of memory, or Z is unsymmetric */ asym = CHOLMOD_MM_UNSYMMETRIC ; } } /* ---------------------------------------------------------------------- */ /* write the Matrix Market header */ /* ---------------------------------------------------------------------- */ ok = fprintf (f, "%%%%MatrixMarket matrix coordinate") > 0 ; if (is_complex) { ok = ok && (fprintf (f, " complex") > 0) ; } else if (is_binary) { ok = ok && (fprintf (f, " pattern") > 0) ; } else if (is_integer) { ok = ok && (fprintf (f, " integer") > 0) ; } else { ok = ok && (fprintf (f, " real") > 0) ; } is_sym = FALSE ; switch (asym) { case CHOLMOD_MM_RECTANGULAR: case CHOLMOD_MM_UNSYMMETRIC: /* A is rectangular or unsymmetric */ ok = ok && (fprintf (f, " general\n") > 0) ; is_sym = FALSE ; symmetry = CHOLMOD_MM_UNSYMMETRIC ; break ; case CHOLMOD_MM_SYMMETRIC: case CHOLMOD_MM_SYMMETRIC_POSDIAG: /* A is symmetric */ ok = ok && (fprintf (f, " symmetric\n") > 0) ; is_sym = TRUE ; symmetry = CHOLMOD_MM_SYMMETRIC ; break ; case CHOLMOD_MM_HERMITIAN: case CHOLMOD_MM_HERMITIAN_POSDIAG: /* A is Hermitian */ ok = ok && (fprintf (f, " Hermitian\n") > 0) ; is_sym = TRUE ; symmetry = CHOLMOD_MM_HERMITIAN ; break ; case CHOLMOD_MM_SKEW_SYMMETRIC: /* A is skew symmetric */ ok = ok && (fprintf (f, " skew-symmetric\n") > 0) ; is_sym = TRUE ; symmetry = CHOLMOD_MM_SKEW_SYMMETRIC ; break ; } /* ---------------------------------------------------------------------- */ /* include the comments if present */ /* ---------------------------------------------------------------------- */ ok = ok && include_comments (f, comments) ; /* ---------------------------------------------------------------------- */ /* write a sparse matrix (A and Z) */ /* ---------------------------------------------------------------------- */ nz = ntriplets (A, is_sym) + ntriplets (Z, is_sym) ; /* write the first data line, with nrow, ncol, and # of triplets */ ok = ok && (fprintf (f, ID " " ID " " ID "\n", nrow, ncol, nz) > 0) ; for (j = 0 ; ok && j < ncol ; j++) { /* merge column of A and Z */ p = Ap [j] ; pend = (apacked) ? Ap [j+1] : p + Anz [j] ; q = (Z == NULL) ? 0 : Zp [j] ; qend = (Z == NULL) ? 0 : ((zpacked) ? Zp [j+1] : q + Znz [j]) ; while (ok) { /* get the next row index from A and Z */ i = (p < pend) ? Ai [p] : (nrow+1) ; iz = (q < qend) ? Zi [q] : (nrow+2) ; if (i <= iz) { /* get A(i,j), or quit if both A and Z are exhausted */ if (i == nrow+1) break ; get_value (Ax, Az, p, xtype, &x, &z) ; p++ ; } else { /* get Z(i,j) */ i = iz ; x = 0 ; z = 0 ; q++ ; } if ((stype < 0 && i >= j) || (stype == 0 && (i >= j || !is_sym))) { /* CHOLMOD matrix is symmetric-lower (and so is the file); * or CHOLMOD matrix is unsymmetric and either A(i,j) is in * the lower part or the file is unsymmetric. */ ok = ok && print_triplet (f, is_binary, is_complex, is_integer, i,j, x,z) ; } else if (stype > 0 && i <= j) { /* CHOLMOD matrix is symmetric-upper, but the file is * symmetric-lower. Need to transpose the entry. If the * matrix is real, the complex part is ignored. If the matrix * is complex, it Hermitian. */ ASSERT (IMPLIES (is_complex, asym == CHOLMOD_MM_HERMITIAN)) ; if (z != 0) { z = -z ; } ok = ok && print_triplet (f, is_binary, is_complex, is_integer, j,i, x,z) ; } } } if (!ok) { ERROR (CHOLMOD_INVALID, "error reading/writing file") ; return (EMPTY) ; } return (asym) ; } /* ========================================================================== */ /* === cholmod_write_dense ================================================== */ /* ========================================================================== */ /* Write a dense matrix to a file in Matrix Market format. Optionally include * comments. Returns > 0 if successful, -1 otherwise (1 if rectangular, 2 if * square). Future versions may return 1 to 7 on success (a CHOLMOD_MM_* code, * just as cholmod_write_sparse does). * * A dense matrix is written in "general" format; symmetric formats in the * Matrix Market standard are not exploited. */ int CHOLMOD(write_dense) ( /* ---- input ---- */ FILE *f, /* file to write to, must already be open */ cholmod_dense *X, /* matrix to print */ const char *comments, /* optional filename of comments to include */ /* --------------- */ cholmod_common *Common ) { double x = 0, z = 0 ; double *Xx, *Xz ; Int nrow, ncol, is_complex, i, j, xtype, p ; int ok ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (EMPTY) ; RETURN_IF_NULL (f, EMPTY) ; RETURN_IF_NULL (X, EMPTY) ; RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, EMPTY) ; Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* get the X matrix */ /* ---------------------------------------------------------------------- */ Xx = X->x ; Xz = X->z ; nrow = X->nrow ; ncol = X->ncol ; xtype = X->xtype ; is_complex = (xtype == CHOLMOD_COMPLEX) || (xtype == CHOLMOD_ZOMPLEX) ; /* ---------------------------------------------------------------------- */ /* write the Matrix Market header */ /* ---------------------------------------------------------------------- */ ok = (fprintf (f, "%%%%MatrixMarket matrix array") > 0) ; if (is_complex) { ok = ok && (fprintf (f, " complex general\n") > 0) ; } else { ok = ok && (fprintf (f, " real general\n") > 0) ; } /* ---------------------------------------------------------------------- */ /* include the comments if present */ /* ---------------------------------------------------------------------- */ ok = ok && include_comments (f, comments) ; /* ---------------------------------------------------------------------- */ /* write a dense matrix */ /* ---------------------------------------------------------------------- */ /* write the first data line, with nrow and ncol */ ok = ok && (fprintf (f, ID " " ID "\n", nrow, ncol) > 0) ; Xx = X->x ; Xz = X->z ; for (j = 0 ; ok && j < ncol ; j++) { for (i = 0 ; ok && i < nrow ; i++) { p = i + j*nrow ; get_value (Xx, Xz, p, xtype, &x, &z) ; ok = ok && print_value (f, x, FALSE) ; if (is_complex) { ok = ok && (fprintf (f, " ") > 0) ; ok = ok && print_value (f, z, FALSE) ; } ok = ok && (fprintf (f, "\n") > 0) ; } } if (!ok) { ERROR (CHOLMOD_INVALID, "error reading/writing file") ; return (EMPTY) ; } return ((nrow == ncol) ? CHOLMOD_MM_UNSYMMETRIC : CHOLMOD_MM_RECTANGULAR) ; } #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Check/License.txt����������������������������������������������������������������0000644�0001762�0000144�00000002042�11770402705�016533� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CHOLMOD/Check Module. Copyright (C) 2005-2006, Timothy A. Davis CHOLMOD is also available under other licenses; contact authors for details. http://www.suitesparse.com Note that this license is for the CHOLMOD/Check module only. All CHOLMOD modules are licensed separately. -------------------------------------------------------------------------------- This Module is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This Module 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this Module; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Check/cholmod_check.c������������������������������������������������������������0000644�0001762�0000144�00000202274�13652535054�017354� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Check/cholmod_check ================================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Check Module. Copyright (C) 2005-2013, Timothy A. Davis * -------------------------------------------------------------------------- */ /* Routines to check and print the contents of the 5 CHOLMOD objects: * * No CHOLMOD routine calls the check or print routines. If a user wants to * check CHOLMOD's input parameters, a separate call to the appropriate check * routine should be used before calling other CHOLMOD routines. * * cholmod_check_common check statistics and workspace in Common * cholmod_check_sparse check sparse matrix in compressed column form * cholmod_check_dense check dense matrix * cholmod_check_factor check factorization * cholmod_check_triplet check sparse matrix in triplet form * * cholmod_print_common print statistics in Common * cholmod_print_sparse print sparse matrix in compressed column form * cholmod_print_dense print dense matrix * cholmod_print_factor print factorization * cholmod_print_triplet print sparse matrix in triplet form * * In addition, this file contains routines to check and print three types of * integer vectors: * * cholmod_check_perm check a permutation of 0:n-1 (no duplicates) * cholmod_check_subset check a subset of 0:n-1 (duplicates OK) * cholmod_check_parent check an elimination tree * * cholmod_print_perm print a permutation * cholmod_print_subset print a subset * cholmod_print_parent print an elimination tree * * Each Common->print level prints the items at or below the given level: * * 0: print nothing; just check the data structures and return TRUE/FALSE * 1: error messages * 2: warning messages * 3: one-line summary of each object printed * 4: short summary of each object (first and last few entries) * 5: entire contents of the object * * No CHOLMOD routine calls these routines, so no printing occurs unless * the user specifically calls a cholmod_print_* routine. Thus, the default * print level is 3. * * Common->precise controls the # of digits printed for numerical entries * (5 if FALSE, 15 if TRUE). * * If SuiteSparse_config.printf_func is NULL, then no printing occurs. The * cholmod_check_* and cholmod_print_* routines still check their inputs and * return TRUE/FALSE if the object is valid or not. * * This file also includes debugging routines that are enabled only when * NDEBUG is defined in cholmod_internal.h (cholmod_dump_*). */ #ifndef NCHECK #include "cholmod_internal.h" #include "cholmod_check.h" /* ========================================================================== */ /* === printing definitions ================================================= */ /* ========================================================================== */ #ifdef LONG #define I8 "%8ld" #define I_8 "%-8ld" #else #define I8 "%8d" #define I_8 "%-8d" #endif #define PR(i,format,arg) \ { \ if (print >= i && SuiteSparse_config.printf_func != NULL) \ { \ SuiteSparse_config.printf_func (format, arg) ; \ } \ } #define P1(format,arg) PR(1,format,arg) #define P2(format,arg) PR(2,format,arg) #define P3(format,arg) PR(3,format,arg) #define P4(format,arg) PR(4,format,arg) #define ERR(msg) \ { \ P1 ("\nCHOLMOD ERROR: %s: ", type) ; \ if (name != NULL) \ { \ P1 ("%s", name) ; \ } \ P1 (": %s\n", msg) ; \ ERROR (CHOLMOD_INVALID, "invalid") ; \ return (FALSE) ; \ } /* print a numerical value */ #define PRINTVALUE(value) \ { \ if (Common->precise) \ { \ P4 (" %23.15e", value) ; \ } \ else \ { \ P4 (" %.5g", value) ; \ } \ } /* start printing */ #define ETC_START(count,limit) \ { \ count = (init_print == 4) ? (limit) : (-1) ; \ } /* re-enable printing if condition is met */ #define ETC_ENABLE(condition,count,limit) \ { \ if ((condition) && init_print == 4) \ { \ count = limit ; \ print = 4 ; \ } \ } /* turn off printing if limit is reached */ #define ETC_DISABLE(count) \ { \ if ((count >= 0) && (count-- == 0) && print == 4) \ { \ P4 ("%s", " ...\n") ; \ print = 3 ; \ } \ } /* re-enable printing, or turn if off after limit is reached */ #define ETC(condition,count,limit) \ { \ ETC_ENABLE (condition, count, limit) ; \ ETC_DISABLE (count) ; \ } #define BOOLSTR(x) ((x) ? "true " : "false") /* ========================================================================== */ /* === print_value ========================================================== */ /* ========================================================================== */ static void print_value ( Int print, Int xtype, double *Xx, double *Xz, Int p, cholmod_common *Common) { if (xtype == CHOLMOD_REAL) { PRINTVALUE (Xx [p]) ; } else if (xtype == CHOLMOD_COMPLEX) { P4 ("%s", "(") ; PRINTVALUE (Xx [2*p ]) ; P4 ("%s", " , ") ; PRINTVALUE (Xx [2*p+1]) ; P4 ("%s", ")") ; } else if (xtype == CHOLMOD_ZOMPLEX) { P4 ("%s", "(") ; PRINTVALUE (Xx [p]) ; P4 ("%s", " , ") ; PRINTVALUE (Xz [p]) ; P4 ("%s", ")") ; } } /* ========================================================================== */ /* === cholmod_check_common ================================================= */ /* ========================================================================== */ /* Print and verify the contents of Common */ static int check_common ( Int print, const char *name, cholmod_common *Common ) { double fl, lnz ; double *Xwork ; Int *Flag, *Head ; SuiteSparse_long mark ; Int i, nrow, nmethods, ordering, xworksize, amd_backup, init_print ; const char *type = "common" ; /* ---------------------------------------------------------------------- */ /* print control parameters and statistics */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; init_print = print ; P2 ("%s", "\n") ; P1 ("CHOLMOD version %d", CHOLMOD_MAIN_VERSION) ; P1 (".%d", CHOLMOD_SUB_VERSION) ; P1 (".%d", CHOLMOD_SUBSUB_VERSION) ; P1 (", %s: ", CHOLMOD_DATE) ; if (name != NULL) { P1 ("%s: ", name) ; } switch (Common->status) { case CHOLMOD_OK: P1 ("%s", "status: OK\n") ; break ; case CHOLMOD_OUT_OF_MEMORY: P1 ("%s", "status: ERROR, out of memory\n") ; break ; case CHOLMOD_INVALID: P1 ("%s", "status: ERROR, invalid parameter\n") ; break ; case CHOLMOD_TOO_LARGE: P1 ("%s", "status: ERROR, problem too large\n") ; break ; case CHOLMOD_NOT_INSTALLED: P1 ("%s", "status: ERROR, method not installed\n") ; break ; case CHOLMOD_GPU_PROBLEM: P1 ("%s", "status: ERROR, GPU had a fatal error\n") ; break ; case CHOLMOD_NOT_POSDEF: P1 ("%s", "status: warning, matrix not positive definite\n") ; break ; case CHOLMOD_DSMALL: P1 ("%s", "status: warning, diagonal entry has tiny abs. value\n") ; break ; default: ERR ("unknown status") ; } P2 (" Architecture: %s\n", CHOLMOD_ARCHITECTURE) ; P3 (" sizeof(int): %d\n", (int) sizeof (int)) ; P3 (" sizeof(SuiteSparse_long): %d\n", (int) sizeof (SuiteSparse_long)); P3 (" sizeof(void *): %d\n", (int) sizeof (void *)) ; P3 (" sizeof(double): %d\n", (int) sizeof (double)) ; P3 (" sizeof(Int): %d (CHOLMOD's basic integer)\n", (int) sizeof (Int)) ; P3 (" sizeof(BLAS_INT): %d (integer used in the BLAS)\n", (int) sizeof (BLAS_INT)) ; if (Common->fl != EMPTY) { P2 ("%s", " Results from most recent analysis:\n") ; P2 (" Cholesky flop count: %.5g\n", Common->fl) ; P2 (" Nonzeros in L: %.5g\n", Common->lnz) ; } if (Common->modfl != EMPTY) { P2 (" Update/downdate flop count: %.5g\n", Common->modfl) ; } P2 (" memory blocks in use: %8.0f\n", (double) (Common->malloc_count)) ; P2 (" memory in use (MB): %8.1f\n", (double) (Common->memory_inuse) / 1048576.) ; P2 (" peak memory usage (MB): %8.1f\n", (double) (Common->memory_usage) / 1048576.) ; /* ---------------------------------------------------------------------- */ /* primary control parameters and related ordering statistics */ /* ---------------------------------------------------------------------- */ P3 (" maxrank: update/downdate rank: "ID"\n", (Int) CHOLMOD(maxrank) (0, Common)) ; P3 (" supernodal control: %d", Common->supernodal) ; P3 (" %g ", Common->supernodal_switch) ; if (Common->supernodal <= CHOLMOD_SIMPLICIAL) { P3 ("%s", "(always do simplicial)\n") ; } else if (Common->supernodal == CHOLMOD_AUTO) { P3 ("(supernodal if flops/lnz >= %g)\n", Common->supernodal_switch) ; } else { P3 ("%s", "(always do supernodal)\n") ; } nmethods = MIN (Common->nmethods, CHOLMOD_MAXMETHODS) ; nmethods = MAX (0, nmethods) ; if (nmethods > 0) { P3 ("%s", " nmethods: number of ordering methods to try: ") ; P3 (""ID"\n", nmethods) ; amd_backup = (nmethods > 1) || (nmethods == 1 && (Common->method [0].ordering == CHOLMOD_METIS || Common->method [0].ordering == CHOLMOD_NESDIS)) ; } else { P3 ("%s", " nmethods=0: default strategy: Try user permutation if " "given. Try AMD.\n") ; #ifndef NPARTITION if (Common->default_nesdis) { P3 ("%s", " Try NESDIS if AMD reports flops/nnz(L) >= 500 and " "nnz(L)/nnz(A) >= 5.\n") ; } else { P3 ("%s", " Try METIS if AMD reports flops/nnz(L) >= 500 and " "nnz(L)/nnz(A) >= 5.\n") ; } #endif P3 ("%s", " Select best ordering tried.\n") ; Common->method [0].ordering = CHOLMOD_GIVEN ; Common->method [1].ordering = CHOLMOD_AMD ; Common->method [2].ordering = (Common->default_nesdis ? CHOLMOD_NESDIS : CHOLMOD_METIS) ; amd_backup = FALSE ; #ifndef NPARTITION nmethods = 3 ; #else nmethods = 2 ; #endif } for (i = 0 ; i < nmethods ; i++) { P3 (" method "ID": ", i) ; ordering = Common->method [i].ordering ; fl = Common->method [i].fl ; lnz = Common->method [i].lnz ; switch (ordering) { case CHOLMOD_NATURAL: P3 ("%s", "natural\n") ; break ; case CHOLMOD_GIVEN: P3 ("%s", "user permutation (if given)\n") ; break ; case CHOLMOD_AMD: P3 ("%s", "AMD (or COLAMD if factorizing AA')\n") ; amd_backup = FALSE ; break ; case CHOLMOD_COLAMD: P3 ("%s", "AMD if factorizing A, COLAMD if factorizing AA')\n"); amd_backup = FALSE ; break ; case CHOLMOD_METIS: P3 ("%s", "METIS_NodeND nested dissection\n") ; break ; case CHOLMOD_NESDIS: P3 ("%s", "CHOLMOD nested dissection\n") ; P3 (" nd_small: # nodes in uncut subgraph: "ID"\n", (Int) (Common->method [i].nd_small)) ; P3 (" nd_compress: compress the graph: %s\n", BOOLSTR (Common->method [i].nd_compress)) ; P3 (" nd_camd: use constrained min degree: %s\n", BOOLSTR (Common->method [i].nd_camd)) ; break ; default: P3 (ID, ordering) ; ERR ("unknown ordering method") ; break ; } if (!(ordering == CHOLMOD_NATURAL || ordering == CHOLMOD_GIVEN)) { if (Common->method [i].prune_dense < 0) { P3 (" prune_dense: for pruning dense nodes: %s\n", " none pruned") ; } else { P3 (" prune_dense: for pruning dense nodes: " "%.5g\n", Common->method [i].prune_dense) ; P3 (" a dense node has degree " ">= max(16,(%.5g)*sqrt(n))\n", Common->method [i].prune_dense) ; } } if (ordering == CHOLMOD_COLAMD || ordering == CHOLMOD_NESDIS) { if (Common->method [i].prune_dense2 < 0) { P3 (" prune_dense2: for pruning dense rows for AA':" " %s\n", " none pruned") ; } else { P3 (" prune_dense2: for pruning dense rows for AA':" " %.5g\n", Common->method [i].prune_dense2) ; P3 (" a dense row has degree " ">= max(16,(%.5g)*sqrt(ncol))\n", Common->method [i].prune_dense2) ; } } if (fl != EMPTY) P3 (" flop count: %.5g\n", fl) ; if (lnz != EMPTY) P3 (" nnz(L): %.5g\n", lnz) ; } /* backup AMD results, if any */ if (amd_backup) { P3 ("%s", " backup method: ") ; P3 ("%s", "AMD (or COLAMD if factorizing AA')\n") ; fl = Common->method [nmethods].fl ; lnz = Common->method [nmethods].lnz ; if (fl != EMPTY) P3 (" AMD flop count: %.5g\n", fl) ; if (lnz != EMPTY) P3 (" AMD nnz(L): %.5g\n", lnz) ; } /* ---------------------------------------------------------------------- */ /* arcane control parameters */ /* ---------------------------------------------------------------------- */ if (Common->final_asis) { P4 ("%s", " final_asis: TRUE, leave as is\n") ; } else { P4 ("%s", " final_asis: FALSE, convert when done\n") ; if (Common->final_super) { P4 ("%s", " final_super: TRUE, leave in supernodal form\n") ; } else { P4 ("%s", " final_super: FALSE, convert to simplicial form\n") ; } if (Common->final_ll) { P4 ("%s", " final_ll: TRUE, convert to LL' form\n") ; } else { P4 ("%s", " final_ll: FALSE, convert to LDL' form\n") ; } if (Common->final_pack) { P4 ("%s", " final_pack: TRUE, pack when done\n") ; } else { P4 ("%s", " final_pack: FALSE, do not pack when done\n") ; } if (Common->final_monotonic) { P4 ("%s", " final_monotonic: TRUE, ensure L is monotonic\n") ; } else { P4 ("%s", " final_monotonic: FALSE, do not ensure L is monotonic\n") ; } P4 (" final_resymbol: remove zeros from amalgamation: %s\n", BOOLSTR (Common->final_resymbol)) ; } P4 (" dbound: LDL' diagonal threshold: % .5g\n Entries with abs. value" " less than dbound are replaced with +/- dbound.\n", Common->dbound) ; P4 (" grow0: memory reallocation: % .5g\n", Common->grow0) ; P4 (" grow1: memory reallocation: % .5g\n", Common->grow1) ; P4 (" grow2: memory reallocation: %g\n", (double) (Common->grow2)) ; P4 ("%s", " nrelax, zrelax: supernodal amalgamation rule:\n") ; P4 ("%s", " s = # columns in two adjacent supernodes\n") ; P4 ("%s", " z = % of zeros in new supernode if they are merged.\n") ; P4 ("%s", " Two supernodes are merged if") ; P4 (" (s <= %g) or (no new zero entries) or\n", (double) (Common->nrelax [0])) ; P4 (" (s <= %g and ", (double) (Common->nrelax [1])) ; P4 ("z < %.5g%%) or", Common->zrelax [0] * 100) ; P4 (" (s <= %g and ", (double) (Common->nrelax [2])) ; P4 ("z < %.5g%%) or", Common->zrelax [1] * 100) ; P4 (" (z < %.5g%%)\n", Common->zrelax [2] * 100) ; /* ---------------------------------------------------------------------- */ /* check workspace */ /* ---------------------------------------------------------------------- */ mark = Common->mark ; nrow = Common->nrow ; Flag = Common->Flag ; Head = Common->Head ; if (nrow > 0) { if (mark < 0 || Flag == NULL || Head == NULL) { ERR ("workspace corrupted (Flag and/or Head missing)") ; } for (i = 0 ; i < nrow ; i++) { if (Flag [i] >= mark) { PRINT0 (("Flag ["ID"]="ID", mark = %ld\n", i, Flag [i], mark)) ; ERR ("workspace corrupted (Flag)") ; } } for (i = 0 ; i <= nrow ; i++) { if (Head [i] != EMPTY) { PRINT0 (("Head ["ID"] = "ID",\n", i, Head [i])) ; ERR ("workspace corrupted (Head)") ; } } } xworksize = Common->xworksize ; Xwork = Common->Xwork ; if (xworksize > 0) { if (Xwork == NULL) { ERR ("workspace corrupted (Xwork missing)") ; } for (i = 0 ; i < xworksize ; i++) { if (Xwork [i] != 0.) { PRINT0 (("Xwork ["ID"] = %g\n", i, Xwork [i])) ; ERR ("workspace corrupted (Xwork)") ; } } } /* workspace and parameters are valid */ P3 ("%s", " OK\n") ; P4 ("%s", "\n") ; return (TRUE) ; } int CHOLMOD(check_common) ( cholmod_common *Common ) { return (check_common (0, NULL, Common)) ; } int CHOLMOD(print_common) ( /* ---- input ---- */ const char *name, /* printed name of Common object */ /* --------------- */ cholmod_common *Common ) { Int print = (Common == NULL) ? 3 : (Common->print) ; return (check_common (print, name, Common)) ; } /* ========================================================================== */ /* === cholmod_gpu_stats ==================================================== */ /* ========================================================================== */ /* Print CPU / GPU statistics. If the timer is not installed, the times are reported as zero, but this function still works. Likewise, the function still works if the GPU BLAS is not installed. */ int CHOLMOD(gpu_stats) ( cholmod_common *Common /* input */ ) { double cpu_time, gpu_time ; int print ; RETURN_IF_NULL_COMMON (FALSE) ; print = Common->print ; P2 ("%s", "\nCHOLMOD GPU/CPU statistics:\n") ; P2 ("SYRK CPU calls %12.0f", (double) Common->CHOLMOD_CPU_SYRK_CALLS) ; P2 (" time %12.4e\n", Common->CHOLMOD_CPU_SYRK_TIME) ; P2 (" GPU calls %12.0f", (double) Common->CHOLMOD_GPU_SYRK_CALLS) ; P2 (" time %12.4e\n", Common->CHOLMOD_GPU_SYRK_TIME) ; P2 ("GEMM CPU calls %12.0f", (double) Common->CHOLMOD_CPU_GEMM_CALLS) ; P2 (" time %12.4e\n", Common->CHOLMOD_CPU_GEMM_TIME) ; P2 (" GPU calls %12.0f", (double) Common->CHOLMOD_GPU_GEMM_CALLS) ; P2 (" time %12.4e\n", Common->CHOLMOD_GPU_GEMM_TIME) ; P2 ("POTRF CPU calls %12.0f", (double) Common->CHOLMOD_CPU_POTRF_CALLS) ; P2 (" time %12.4e\n", Common->CHOLMOD_CPU_POTRF_TIME) ; P2 (" GPU calls %12.0f", (double) Common->CHOLMOD_GPU_POTRF_CALLS) ; P2 (" time %12.4e\n", Common->CHOLMOD_GPU_POTRF_TIME) ; P2 ("TRSM CPU calls %12.0f", (double) Common->CHOLMOD_CPU_TRSM_CALLS) ; P2 (" time %12.4e\n", Common->CHOLMOD_CPU_TRSM_TIME) ; P2 (" GPU calls %12.0f", (double) Common->CHOLMOD_GPU_TRSM_CALLS) ; P2 (" time %12.4e\n", Common->CHOLMOD_GPU_TRSM_TIME) ; cpu_time = Common->CHOLMOD_CPU_SYRK_TIME + Common->CHOLMOD_CPU_TRSM_TIME + Common->CHOLMOD_CPU_GEMM_TIME + Common->CHOLMOD_CPU_POTRF_TIME ; gpu_time = Common->CHOLMOD_GPU_SYRK_TIME + Common->CHOLMOD_GPU_TRSM_TIME + Common->CHOLMOD_GPU_GEMM_TIME + Common->CHOLMOD_GPU_POTRF_TIME ; P2 ("time in the BLAS: CPU %12.4e", cpu_time) ; P2 (" GPU %12.4e", gpu_time) ; P2 (" total: %12.4e\n", cpu_time + gpu_time) ; P2 ("assembly time %12.4e", Common->CHOLMOD_ASSEMBLE_TIME) ; P2 (" %12.4e\n", Common->CHOLMOD_ASSEMBLE_TIME2) ; return (TRUE) ; } /* ========================================================================== */ /* === cholmod_check_sparse ================================================= */ /* ========================================================================== */ /* Ensure that a sparse matrix in column-oriented form is valid, and optionally * print it. Returns the number of entries on the diagonal or -1 if error. * * workspace: Iwork (nrow) */ static SuiteSparse_long check_sparse ( Int *Wi, Int print, const char *name, cholmod_sparse *A, SuiteSparse_long *nnzdiag, cholmod_common *Common ) { double *Ax, *Az ; Int *Ap, *Ai, *Anz ; Int nrow, ncol, nzmax, sorted, packed, j, p, pend, i, nz, ilast, init_print, dnz, count, xtype ; const char *type = "sparse" ; /* ---------------------------------------------------------------------- */ /* print header information */ /* ---------------------------------------------------------------------- */ P4 ("%s", "\n") ; P3 ("%s", "CHOLMOD sparse: ") ; if (name != NULL) { P3 ("%s: ", name) ; } if (A == NULL) { ERR ("null") ; } nrow = A->nrow ; ncol = A->ncol ; nzmax = A->nzmax ; sorted = A->sorted ; packed = A->packed ; xtype = A->xtype ; Ap = A->p ; Ai = A->i ; Ax = A->x ; Az = A->z ; Anz = A->nz ; nz = CHOLMOD(nnz) (A, Common) ; P3 (" "ID"", nrow) ; P3 ("-by-"ID", ", ncol) ; P3 ("nz "ID",", nz) ; if (A->stype > 0) { P3 ("%s", " upper.") ; } else if (A->stype < 0) { P3 ("%s", " lower.") ; } else { P3 ("%s", " up/lo.") ; } P4 ("\n nzmax "ID", ", nzmax) ; if (nz > nzmax) { ERR ("nzmax too small") ; } if (!sorted) { P4 ("%s", "un") ; } P4 ("%s", "sorted, ") ; if (!packed) { P4 ("%s", "un") ; } P4 ("%s", "packed, ") ; switch (A->itype) { case CHOLMOD_INT: P4 ("%s", "\n scalar types: int, ") ; break ; case CHOLMOD_INTLONG: ERR ("mixed int/long type unsupported") ; case CHOLMOD_LONG: P4 ("%s", "\n scalar types: SuiteSparse_long, "); break ; default: ERR ("unknown itype") ; } switch (A->xtype) { case CHOLMOD_PATTERN: P4 ("%s", "pattern") ; break ; case CHOLMOD_REAL: P4 ("%s", "real") ; break ; case CHOLMOD_COMPLEX: P4 ("%s", "complex") ; break ; case CHOLMOD_ZOMPLEX: P4 ("%s", "zomplex") ; break ; default: ERR ("unknown xtype") ; } switch (A->dtype) { case CHOLMOD_DOUBLE: P4 ("%s", ", double\n") ; break ; case CHOLMOD_SINGLE: ERR ("float unsupported") ; default: ERR ("unknown dtype") ; } if (A->itype != ITYPE || A->dtype != DTYPE) { ERR ("integer and real type must match routine") ; } if (A->stype && nrow != ncol) { ERR ("symmetric but not square") ; } /* check for existence of Ap, Ai, Anz, Ax, and Az arrays */ if (Ap == NULL) { ERR ("p array not present") ; } if (Ai == NULL) { ERR ("i array not present") ; } if (!packed && Anz == NULL) { ERR ("nz array not present") ; } if (xtype != CHOLMOD_PATTERN && Ax == NULL) { ERR ("x array not present") ; } if (xtype == CHOLMOD_ZOMPLEX && Az == NULL) { ERR ("z array not present") ; } /* packed matrices must start at Ap [0] = 0 */ if (packed && Ap [0] != 0) { ERR ("p [0] must be zero") ; } if (packed && (Ap [ncol] < Ap [0] || Ap [ncol] > nzmax)) { ERR ("p [ncol] invalid") ; } /* ---------------------------------------------------------------------- */ /* allocate workspace if needed */ /* ---------------------------------------------------------------------- */ if (!sorted) { if (Wi == NULL) { CHOLMOD(allocate_work) (0, nrow, 0, Common) ; Wi = Common->Iwork ; /* size nrow, (i/i/l) */ } if (Common->status < CHOLMOD_OK) { return (FALSE) ; /* out of memory */ } for (i = 0 ; i < nrow ; i++) { Wi [i] = EMPTY ; } } /* ---------------------------------------------------------------------- */ /* check and print each column */ /* ---------------------------------------------------------------------- */ init_print = print ; dnz = 0 ; ETC_START (count, 8) ; for (j = 0 ; j < ncol ; j++) { ETC (j == ncol-1, count, 4) ; p = Ap [j] ; if (packed) { pend = Ap [j+1] ; nz = pend - p ; } else { /* Note that Anz [j] < 0 is treated as zero */ nz = MAX (0, Anz [j]) ; pend = p + nz ; } P4 (" col "ID":", j) ; P4 (" nz "ID"", nz) ; P4 (" start "ID"", p) ; P4 (" end "ID"", pend) ; P4 ("%s", ":\n") ; if (p < 0 || pend > nzmax) { ERR ("pointer invalid") ; } if (nz < 0 || nz > nrow) { ERR ("nz invalid") ; } ilast = EMPTY ; for ( ; p < pend ; p++) { ETC (j == ncol-1 && p >= pend-4, count, -1) ; i = Ai [p] ; P4 (" "I8":", i) ; print_value (print, xtype, Ax, Az, p, Common) ; if (i == j) { dnz++ ; } if (i < 0 || i >= nrow) { ERR ("row index out of range") ; } if (sorted && i <= ilast) { ERR ("row indices out of order") ; } if (!sorted && Wi [i] == j) { ERR ("duplicate row index") ; } P4 ("%s", "\n") ; ilast = i ; if (!sorted) { Wi [i] = j ; } } } /* matrix is valid */ P4 (" nnz on diagonal: "ID"\n", dnz) ; P3 ("%s", " OK\n") ; P4 ("%s", "\n") ; *nnzdiag = dnz ; return (TRUE) ; } int CHOLMOD(check_sparse) ( /* ---- input ---- */ cholmod_sparse *A, /* sparse matrix to check */ /* --------------- */ cholmod_common *Common ) { SuiteSparse_long nnzdiag ; RETURN_IF_NULL_COMMON (FALSE) ; Common->status = CHOLMOD_OK ; return (check_sparse (NULL, 0, NULL, A, &nnzdiag, Common)) ; } int CHOLMOD(print_sparse) ( /* ---- input ---- */ cholmod_sparse *A, /* sparse matrix to print */ const char *name, /* printed name of sparse matrix */ /* --------------- */ cholmod_common *Common ) { SuiteSparse_long nnzdiag ; RETURN_IF_NULL_COMMON (FALSE) ; Common->status = CHOLMOD_OK ; return (check_sparse (NULL, Common->print, name, A, &nnzdiag, Common)) ; } /* ========================================================================== */ /* === cholmod_check_dense ================================================== */ /* ========================================================================== */ /* Ensure a dense matrix is valid, and optionally print it. */ static int check_dense ( Int print, const char *name, cholmod_dense *X, cholmod_common *Common ) { double *Xx, *Xz ; Int i, j, d, nrow, ncol, nzmax, nz, init_print, count, xtype ; const char *type = "dense" ; /* ---------------------------------------------------------------------- */ /* print header information */ /* ---------------------------------------------------------------------- */ P4 ("%s", "\n") ; P3 ("%s", "CHOLMOD dense: ") ; if (name != NULL) { P3 ("%s: ", name) ; } if (X == NULL) { ERR ("null") ; } nrow = X->nrow ; ncol = X->ncol ; nzmax = X->nzmax ; d = X->d ; Xx = X->x ; Xz = X->z ; xtype = X->xtype ; P3 (" "ID"", nrow) ; P3 ("-by-"ID", ", ncol) ; P4 ("\n leading dimension "ID", ", d) ; P4 ("nzmax "ID", ", nzmax) ; if (d * ncol > nzmax) { ERR ("nzmax too small") ; } if (d < nrow) { ERR ("leading dimension must be >= # of rows") ; } if (Xx == NULL) { ERR ("null") ; } switch (X->xtype) { case CHOLMOD_PATTERN: ERR ("pattern unsupported") ; break ; case CHOLMOD_REAL: P4 ("%s", "real") ; break ; case CHOLMOD_COMPLEX: P4 ("%s", "complex") ; break ; case CHOLMOD_ZOMPLEX: P4 ("%s", "zomplex") ; break ; default: ERR ("unknown xtype") ; } switch (X->dtype) { case CHOLMOD_DOUBLE: P4 ("%s", ", double\n") ; break ; case CHOLMOD_SINGLE: ERR ("single unsupported") ; default: ERR ("unknown dtype") ; } /* ---------------------------------------------------------------------- */ /* check and print each entry */ /* ---------------------------------------------------------------------- */ if (print >= 4) { init_print = print ; ETC_START (count, 9) ; nz = nrow * ncol ; for (j = 0 ; j < ncol ; j++) { ETC (j == ncol-1, count, 5) ; P4 (" col "ID":\n", j) ; for (i = 0 ; i < nrow ; i++) { ETC (j == ncol-1 && i >= nrow-4, count, -1) ; P4 (" "I8":", i) ; print_value (print, xtype, Xx, Xz, i+j*d, Common) ; P4 ("%s", "\n") ; } } } /* dense is valid */ P3 ("%s", " OK\n") ; P4 ("%s", "\n") ; return (TRUE) ; } int CHOLMOD(check_dense) ( /* ---- input ---- */ cholmod_dense *X, /* dense matrix to check */ /* --------------- */ cholmod_common *Common ) { RETURN_IF_NULL_COMMON (FALSE) ; Common->status = CHOLMOD_OK ; return (check_dense (0, NULL, X, Common)) ; } int CHOLMOD(print_dense) ( /* ---- input ---- */ cholmod_dense *X, /* dense matrix to print */ const char *name, /* printed name of dense matrix */ /* --------------- */ cholmod_common *Common ) { RETURN_IF_NULL_COMMON (FALSE) ; Common->status = CHOLMOD_OK ; return (check_dense (Common->print, name, X, Common)) ; } /* ========================================================================== */ /* === cholmod_check_subset ================================================= */ /* ========================================================================== */ /* Ensure S (0:len-1) is a subset of 0:n-1. Duplicates are allowed. S may be * NULL. A negative len denotes the set 0:n-1. * * To check the rset and cset for A(rset,cset), where nc and nr are the length * of cset and rset respectively: * * cholmod_check_subset (cset, nc, A->ncol, Common) ; * cholmod_check_subset (rset, nr, A->nrow, Common) ; * * workspace: none */ static int check_subset ( Int *S, SuiteSparse_long len, size_t n, Int print, const char *name, cholmod_common *Common ) { Int i, k, init_print, count ; const char *type = "subset" ; init_print = print ; if (S == NULL) { /* zero len denotes S = [ ], negative len denotes S = 0:n-1 */ len = (len < 0) ? (-1) : 0 ; } P4 ("%s", "\n") ; P3 ("%s", "CHOLMOD subset: ") ; if (name != NULL) { P3 ("%s: ", name) ; } P3 (" len: %ld ", len) ; if (len < 0) { P3 ("%s", "(denotes 0:n-1) ") ; } P3 ("n: "ID"", (Int) n) ; P4 ("%s", "\n") ; if (len <= 0 || S == NULL) { P3 ("%s", " OK\n") ; P4 ("%s", "\n") ; return (TRUE) ; } if (print >= 4) { ETC_START (count, 8) ; for (k = 0 ; k < ((Int) len) ; k++) { ETC (k == ((Int) len) - 4, count, -1) ; i = S [k] ; P4 (" "I8":", k) ; P4 (" "ID"\n", i) ; if (i < 0 || i >= ((Int) n)) { ERR ("entry out range") ; } } } else { for (k = 0 ; k < ((Int) len) ; k++) { i = S [k] ; if (i < 0 || i >= ((Int) n)) { ERR ("entry out range") ; } } } P3 ("%s", " OK\n") ; P4 ("%s", "\n") ; return (TRUE) ; } int CHOLMOD(check_subset) ( /* ---- input ---- */ Int *Set, /* Set [0:len-1] is a subset of 0:n-1. Duplicates OK */ SuiteSparse_long len, /* size of Set (an integer array), or < 0 if 0:n-1 */ size_t n, /* 0:n-1 is valid range */ /* --------------- */ cholmod_common *Common ) { RETURN_IF_NULL_COMMON (FALSE) ; Common->status = CHOLMOD_OK ; return (check_subset (Set, len, n, 0, NULL, Common)) ; } int CHOLMOD(print_subset) ( /* ---- input ---- */ Int *Set, /* Set [0:len-1] is a subset of 0:n-1. Duplicates OK */ SuiteSparse_long len, /* size of Set (an integer array), or < 0 if 0:n-1 */ size_t n, /* 0:n-1 is valid range */ const char *name, /* printed name of Set */ /* --------------- */ cholmod_common *Common ) { RETURN_IF_NULL_COMMON (FALSE) ; Common->status = CHOLMOD_OK ; return (check_subset (Set, len, n, Common->print, name, Common)) ; } /* ========================================================================== */ /* === cholmod_check_perm =================================================== */ /* ========================================================================== */ /* Ensure that Perm [0..len-1] is a permutation of a subset of 0:n-1. Perm * may be NULL, which is interpreted as the identity permutation. There can * be no duplicate entries (len must be <= n). * * If n <= Common->nrow, then this routine takes O(len) time and does not * allocate any memory, by using Common->Flag. Otherwise, it takes O(n) time * and ensures that Common->Iwork is at least n*sizeof(Int) in size. * * To check the fset: cholmod_check_perm (fset, fsize, ncol, Common) ; * To check a permutation: cholmod_check_perm (Perm, n, n, Common) ; * * workspace: Flag (n) if n <= Common->nrow, Iwork (n) otherwise. */ static int check_perm ( Int *Wi, Int print, const char *name, Int *Perm, size_t len, size_t n, cholmod_common *Common ) { Int *Flag ; Int i, k, mark, init_print, count ; const char *type = "perm" ; /* ---------------------------------------------------------------------- */ /* checks that take O(1) time */ /* ---------------------------------------------------------------------- */ if (Perm == NULL || n == 0) { /* Perm is valid implicit identity, or empty */ return (TRUE) ; } /* ---------------------------------------------------------------------- */ /* checks that take O(n) time or require memory allocation */ /* ---------------------------------------------------------------------- */ init_print = print ; ETC_START (count, 8) ; if (Wi == NULL && n <= Common->nrow) { /* use the Common->Flag array if it's big enough */ mark = CHOLMOD(clear_flag) (Common) ; Flag = Common->Flag ; ASSERT (CHOLMOD(dump_work) (TRUE, FALSE, 0, Common)) ; if (print >= 4) { for (k = 0 ; k < ((Int) len) ; k++) { ETC (k >= ((Int) len) - 4, count, -1) ; i = Perm [k] ; P4 (" "I8":", k) ; P4 (""ID"\n", i) ; if (i < 0 || i >= ((Int) n) || Flag [i] == mark) { CHOLMOD(clear_flag) (Common) ; ERR ("invalid permutation") ; } Flag [i] = mark ; } } else { for (k = 0 ; k < ((Int) len) ; k++) { i = Perm [k] ; if (i < 0 || i >= ((Int) n) || Flag [i] == mark) { CHOLMOD(clear_flag) (Common) ; ERR ("invalid permutation") ; } Flag [i] = mark ; } } CHOLMOD(clear_flag) (Common) ; ASSERT (CHOLMOD(dump_work) (TRUE, FALSE, 0, Common)) ; } else { if (Wi == NULL) { /* use Common->Iwork instead, but initialize it first */ CHOLMOD(allocate_work) (0, n, 0, Common) ; Wi = Common->Iwork ; /* size n, (i/i/i) is OK */ } if (Common->status < CHOLMOD_OK) { return (FALSE) ; /* out of memory */ } for (i = 0 ; i < ((Int) n) ; i++) { Wi [i] = FALSE ; } if (print >= 4) { for (k = 0 ; k < ((Int) len) ; k++) { ETC (k >= ((Int) len) - 4, count, -1) ; i = Perm [k] ; P4 (" "I8":", k) ; P4 (""ID"\n", i) ; if (i < 0 || i >= ((Int) n) || Wi [i]) { ERR ("invalid permutation") ; } Wi [i] = TRUE ; } } else { for (k = 0 ; k < ((Int) len) ; k++) { i = Perm [k] ; if (i < 0 || i >= ((Int) n) || Wi [i]) { ERR ("invalid permutation") ; } Wi [i] = TRUE ; } } } /* perm is valid */ return (TRUE) ; } int CHOLMOD(check_perm) ( /* ---- input ---- */ Int *Perm, /* Perm [0:len-1] is a permutation of subset of 0:n-1 */ size_t len, /* size of Perm (an integer array) */ size_t n, /* 0:n-1 is valid range */ /* --------------- */ cholmod_common *Common ) { RETURN_IF_NULL_COMMON (FALSE) ; Common->status = CHOLMOD_OK ; return (check_perm (NULL, 0, NULL, Perm, len, n, Common)) ; } int CHOLMOD(print_perm) ( /* ---- input ---- */ Int *Perm, /* Perm [0:len-1] is a permutation of subset of 0:n-1 */ size_t len, /* size of Perm (an integer array) */ size_t n, /* 0:n-1 is valid range */ const char *name, /* printed name of Perm */ /* --------------- */ cholmod_common *Common ) { Int ok, print ; RETURN_IF_NULL_COMMON (FALSE) ; Common->status = CHOLMOD_OK ; print = Common->print ; P4 ("%s", "\n") ; P3 ("%s", "CHOLMOD perm: ") ; if (name != NULL) { P3 ("%s: ", name) ; } P3 (" len: "ID"", (Int) len) ; P3 (" n: "ID"", (Int) n) ; P4 ("%s", "\n") ; ok = check_perm (NULL, print, name, Perm, len, n, Common) ; if (ok) { P3 ("%s", " OK\n") ; P4 ("%s", "\n") ; } return (ok) ; } /* ========================================================================== */ /* === cholmod_check_parent ================================================= */ /* ========================================================================== */ /* Ensure that Parent is a valid elimination tree of nodes 0 to n-1. * If j is a root of the tree then Parent [j] is EMPTY (-1). * * NOTE: this check will fail if applied to the component tree (CParent) in * cholmod_nested_dissection, unless it has been postordered and renumbered. * * workspace: none */ static int check_parent ( Int *Parent, size_t n, Int print, const char *name, cholmod_common *Common ) { Int j, p, init_print, count ; const char *type = "parent" ; init_print = print ; P4 ("%s", "\n") ; P3 ("%s", "CHOLMOD parent: ") ; if (name != NULL) { P3 ("%s: ", name) ; } P3 (" n: "ID"", (Int) n) ; P4 ("%s", "\n") ; if (Parent == NULL) { ERR ("null") ; } /* ---------------------------------------------------------------------- */ /* checks that take O(n) time */ /* ---------------------------------------------------------------------- */ ETC_START (count, 8) ; for (j = 0 ; j < ((Int) n) ; j++) { ETC (j == ((Int) n) - 4, count, -1) ; p = Parent [j] ; P4 (" "I8":", j) ; P4 (" "ID"\n", p) ; if (!(p == EMPTY || p > j)) { ERR ("invalid") ; } } P3 ("%s", " OK\n") ; P4 ("%s", "\n") ; return (TRUE) ; } int CHOLMOD(check_parent) ( /* ---- input ---- */ Int *Parent, /* Parent [0:n-1] is an elimination tree */ size_t n, /* size of Parent */ /* --------------- */ cholmod_common *Common ) { RETURN_IF_NULL_COMMON (FALSE) ; Common->status = CHOLMOD_OK ; return (check_parent (Parent, n, 0, NULL, Common)) ; } int CHOLMOD(print_parent) ( /* ---- input ---- */ Int *Parent, /* Parent [0:n-1] is an elimination tree */ size_t n, /* size of Parent */ const char *name, /* printed name of Parent */ /* --------------- */ cholmod_common *Common ) { RETURN_IF_NULL_COMMON (FALSE) ; Common->status = CHOLMOD_OK ; return (check_parent (Parent, n, Common->print, name, Common)) ; } /* ========================================================================== */ /* === cholmod_check_factor ================================================= */ /* ========================================================================== */ static int check_factor ( Int *Wi, Int print, const char *name, cholmod_factor *L, cholmod_common *Common ) { double *Lx, *Lz ; Int *Lp, *Li, *Lnz, *Lnext, *Lprev, *Perm, *ColCount, *Lpi, *Lpx, *Super, *Ls ; Int n, nzmax, j, p, pend, i, nz, ordering, space, is_monotonic, minor, count, precise, init_print, ilast, lnz, head, tail, jprev, plast, jnext, examine_super, nsuper, s, k1, k2, psi, psend, psx, nsrow, nscol, ps2, psxend, ssize, xsize, maxcsize, maxesize, nsrow2, jj, ii, xtype ; Int check_Lpx ; const char *type = "factor" ; /* ---------------------------------------------------------------------- */ /* print header information */ /* ---------------------------------------------------------------------- */ P4 ("%s", "\n") ; P3 ("%s", "CHOLMOD factor: ") ; if (name != NULL) { P3 ("%s: ", name) ; } if (L == NULL) { ERR ("null") ; } n = L->n ; minor = L->minor ; ordering = L->ordering ; xtype = L->xtype ; Perm = L->Perm ; ColCount = L->ColCount ; lnz = 0 ; precise = Common->precise ; P3 (" "ID"", n) ; P3 ("-by-"ID"", n) ; if (minor < n) { P3 (" not positive definite (column "ID")", minor) ; } switch (L->itype) { case CHOLMOD_INT: P4 ("%s", "\n scalar types: int, ") ; break ; case CHOLMOD_INTLONG: ERR ("mixed int/long type unsupported") ; case CHOLMOD_LONG: P4 ("%s", "\n scalar types: SuiteSparse_long, "); break ; default: ERR ("unknown itype") ; } switch (L->xtype) { case CHOLMOD_PATTERN: P4 ("%s", "pattern") ; break ; case CHOLMOD_REAL: P4 ("%s", "real") ; break ; case CHOLMOD_COMPLEX: P4 ("%s", "complex") ; break ; case CHOLMOD_ZOMPLEX: P4 ("%s", "zomplex") ; break ; default: ERR ("unknown xtype") ; } switch (L->dtype) { case CHOLMOD_DOUBLE: P4 ("%s", ", double\n") ; break ; case CHOLMOD_SINGLE: ERR ("single unsupported") ; default: ERR ("unknown dtype") ; } if (L->itype != ITYPE || L->dtype != DTYPE) { ERR ("integer and real type must match routine") ; } if (L->is_super) { P3 ("%s", " supernodal") ; } else { P3 ("%s", " simplicial") ; } if (L->is_ll) { P3 ("%s", ", LL'.") ; } else { P3 ("%s", ", LDL'.") ; } P4 ("%s", "\n ordering method used: ") ; switch (L->ordering) { case CHOLMOD_POSTORDERED:P4 ("%s", "natural (postordered)") ; break ; case CHOLMOD_NATURAL: P4 ("%s", "natural") ; break ; case CHOLMOD_GIVEN: P4 ("%s", "user-provided") ; break ; case CHOLMOD_AMD: P4 ("%s", "AMD") ; break ; case CHOLMOD_COLAMD: P4 ("%s", "AMD for A, COLAMD for A*A'") ;break ; #ifndef NPARTITION case CHOLMOD_METIS: P4 ("%s", "METIS NodeND") ; break ; case CHOLMOD_NESDIS: P4 ("%s", "CHOLMOD nested dissection") ; break ; #endif default: ERR ("unknown ordering") ; } P4 ("%s", "\n") ; init_print = print ; if (L->is_super && L->xtype == CHOLMOD_ZOMPLEX) { ERR ("Supernodal zomplex L not supported") ; } /* ---------------------------------------------------------------------- */ /* check L->Perm */ /* ---------------------------------------------------------------------- */ if (!check_perm (Wi, print, name, Perm, n, n, Common)) { return (FALSE) ; } /* ---------------------------------------------------------------------- */ /* check L->ColCount */ /* ---------------------------------------------------------------------- */ if (ColCount == NULL) { ERR ("ColCount vector invalid") ; } ETC_START (count, 8) ; for (j = 0 ; j < n ; j++) { ETC (j >= n-4, count, -1) ; P4 (" col: "ID" ", j) ; nz = ColCount [j] ; P4 ("colcount: "ID"\n", nz) ; if (nz < 0 || nz > n-j) { ERR ("ColCount out of range") ; } } /* ---------------------------------------------------------------------- */ /* check factor */ /* ---------------------------------------------------------------------- */ if (L->xtype == CHOLMOD_PATTERN && !(L->is_super)) { /* ------------------------------------------------------------------ */ /* check simplicial symbolic factor */ /* ------------------------------------------------------------------ */ /* nothing else to do */ ; } else if (L->xtype != CHOLMOD_PATTERN && !(L->is_super)) { /* ------------------------------------------------------------------ */ /* check simplicial numerical factor */ /* ------------------------------------------------------------------ */ P4 ("monotonic: %d\n", L->is_monotonic) ; nzmax = L->nzmax ; P3 (" nzmax "ID".", nzmax) ; P4 ("%s", "\n") ; Lp = L->p ; Li = L->i ; Lx = L->x ; Lz = L->z ; Lnz = L->nz ; Lnext = L->next ; Lprev = L->prev ; /* check for existence of Lp, Li, Lnz, Lnext, Lprev, and Lx arrays */ if (Lp == NULL) { ERR ("p array not present") ; } if (Li == NULL) { ERR ("i array not present") ; } if (Lnz == NULL) { ERR ("nz array not present") ; } if (Lx == NULL) { ERR ("x array not present") ; } if (xtype == CHOLMOD_ZOMPLEX && Lz == NULL) { ERR ("z array not present") ; } if (Lnext == NULL) { ERR ("next array not present") ; } if (Lprev == NULL) { ERR ("prev array not present") ; } ETC_START (count, 8) ; /* check each column of L */ plast = 0 ; is_monotonic = TRUE ; for (j = 0 ; j < n ; j++) { ETC (j >= n-3, count, -1) ; p = Lp [j] ; nz = Lnz [j] ; pend = p + nz ; lnz += nz ; P4 (" col "ID":", j) ; P4 (" nz "ID"", nz) ; P4 (" start "ID"", p) ; P4 (" end "ID"", pend) ; if (Lnext [j] < 0 || Lnext [j] > n) { ERR ("invalid link list") ; } space = Lp [Lnext [j]] - p ; P4 (" space "ID"", space) ; P4 (" free "ID":\n", space - nz) ; if (p < 0 || pend > nzmax || space < 1) { ERR ("pointer invalid") ; } if (nz < 1 || nz > (n-j) || nz > space) { ERR ("nz invalid") ; } ilast = j-1 ; if (p < plast) { is_monotonic = FALSE ; } plast = p ; i = Li [p] ; P4 (" "I8":", i) ; if (i != j) { ERR ("diagonal missing") ; } print_value (print, xtype, Lx, Lz, p, Common) ; P4 ("%s", "\n") ; ilast = j ; for (p++ ; p < pend ; p++) { ETC_DISABLE (count) ; i = Li [p] ; P4 (" "I8":", i) ; if (i < j || i >= n) { ERR ("row index out of range") ; } if (i <= ilast) { ERR ("row indices out of order") ; } print_value (print, xtype, Lx, Lz, p, Common) ; P4 ("%s", "\n") ; ilast = i ; } } if (L->is_monotonic && !is_monotonic) { ERR ("columns not monotonic") ; } /* check the link list */ head = n+1 ; tail = n ; j = head ; jprev = EMPTY ; count = 0 ; for ( ; ; ) { if (j < 0 || j > n+1 || count > n+2) { ERR ("invalid link list") ; } jnext = Lnext [j] ; if (j >= 0 && j < n) { if (jprev != Lprev [j]) { ERR ("invalid link list") ; } } count++ ; if (j == tail) { break ; } jprev = j ; j = jnext ; } if (Lnext [tail] != EMPTY || count != n+2) { ERR ("invalid link list") ; } } else { /* ------------------------------------------------------------------ */ /* check supernodal numeric or symbolic factor */ /* ------------------------------------------------------------------ */ nsuper = L->nsuper ; ssize = L->ssize ; xsize = L->xsize ; maxcsize = L->maxcsize ; maxesize = L->maxesize ; Ls = L->s ; Lpi = L->pi ; Lpx = L->px ; Super = L->super ; Lx = L->x ; ETC_START (count, 8) ; P4 (" ssize "ID" ", ssize) ; P4 ("xsize "ID" ", xsize) ; P4 ("maxcsize "ID" ", maxcsize) ; P4 ("maxesize "ID"\n", maxesize) ; if (Ls == NULL) { ERR ("invalid: L->s missing") ; } if (Lpi == NULL) { ERR ("invalid: L->pi missing") ; } if (Lpx == NULL) { ERR ("invalid: L->px missing") ; } if (Super == NULL) { ERR ("invalid: L->super missing") ; } if (L->xtype != CHOLMOD_PATTERN) { /* numerical supernodal factor */ if (Lx == NULL) { ERR ("invalid: L->x missing") ; } if (Ls [0] == EMPTY) { ERR ("invalid: L->s not defined") ; } examine_super = TRUE ; } else { /* symbolic supernodal factor, but only if it has been computed */ examine_super = (Ls [0] != EMPTY) ; } if (examine_super) { if (Lpi [0] != 0 || MAX (1, Lpi [nsuper]) != ssize) { PRINT0 (("Lpi [0] "ID", Lpi [nsuper = "ID"] = "ID"\n", Lpi [0], nsuper, Lpi [nsuper])) ; ERR ("invalid: L->pi invalid") ; } /* If Lpx [0] is 123456, then supernodes are present but Lpx [0...nsuper] is not defined, so don't check it. This is used in the non-GPU accelerated SPQR */ check_Lpx = (Lpx [0] != 123456) ; if (check_Lpx && (Lpx [0] != 0 || MAX (1, Lpx[nsuper]) != xsize)) { ERR ("invalid: L->px invalid") ; } /* check and print each supernode */ for (s = 0 ; s < nsuper ; s++) { k1 = Super [s] ; k2 = Super [s+1] ; psi = Lpi [s] ; psend = Lpi [s+1] ; nsrow = psend - psi ; nscol = k2 - k1 ; nsrow2 = nsrow - nscol ; ps2 = psi + nscol ; if (check_Lpx) { psx = Lpx [s] ; psxend = Lpx [s+1] ; } ETC (s == nsuper-1, count, 4) ; P4 (" supernode "ID", ", s) ; P4 ("col "ID" ", k1) ; P4 ("to "ID". ", k2-1) ; P4 ("nz in first col: "ID".\n", nsrow) ; if (check_Lpx) { P4 (" values start "ID", ", psx) ; P4 ("end "ID"\n", psxend) ; } if (k1 > k2 || k1 < 0 || k2 > n || nsrow < nscol || nsrow2 < 0 || (check_Lpx && psxend - psx != nsrow * nscol)) { ERR ("invalid supernode") ; } lnz += nscol * nsrow - (nscol*nscol - nscol)/2 ; if (L->xtype != CHOLMOD_PATTERN) { /* print each column of the supernode */ for (jj = 0 ; jj < nscol ; jj++) { ETC_ENABLE (s == nsuper-1 && jj >= nscol-3, count, -1) ; j = k1 + jj ; P4 (" col "ID"\n", j) ; ilast = j ; i = Ls [psi + jj] ; P4 (" "I8":", i) ; if (i != j) { ERR ("row index invalid") ; } /* PRINTVALUE (Lx [psx + jj + jj*nsrow]) ; */ print_value (print, xtype, Lx, NULL, psx + jj + jj*nsrow, Common) ; P4 ("%s", "\n") ; for (ii = jj + 1 ; ii < nsrow ; ii++) { ETC_DISABLE (count) ; i = Ls [psi + ii] ; P4 (" "I8":", i) ; if (i <= ilast || i > n) { ERR ("row index out of range") ; } /* PRINTVALUE (Lx [psx + ii + jj*nsrow]) ; */ print_value (print, xtype, Lx, NULL, psx + ii + jj*nsrow, Common) ; P4 ("%s", "\n") ; ilast = i ; } } } else { /* just print the leading column of the supernode */ P4 (" col "ID"\n", k1) ; for (jj = 0 ; jj < nscol ; jj++) { ETC (s == nsuper-1 && jj >= nscol-3, count, -1) ; j = k1 + jj ; i = Ls [psi + jj] ; P4 (" "I8"", i) ; if (i != j) { ERR ("row index invalid") ; } P4 ("%s", "\n") ; } ilast = j ; for (ii = nscol ; ii < nsrow ; ii++) { ETC_DISABLE (count) ; i = Ls [psi + ii] ; P4 (" "I8"", i) ; if (i <= ilast || i > n) { ERR ("row index out of range") ; } P4 ("%s", "\n") ; ilast = i ; } } } } } /* factor is valid */ P3 (" nz "ID"", lnz) ; P3 ("%s", " OK\n") ; P4 ("%s", "\n") ; return (TRUE) ; } int CHOLMOD(check_factor) ( /* ---- input ---- */ cholmod_factor *L, /* factor to check */ /* --------------- */ cholmod_common *Common ) { RETURN_IF_NULL_COMMON (FALSE) ; Common->status = CHOLMOD_OK ; return (check_factor (NULL, 0, NULL, L, Common)) ; } int CHOLMOD(print_factor) ( /* ---- input ---- */ cholmod_factor *L, /* factor to print */ const char *name, /* printed name of factor */ /* --------------- */ cholmod_common *Common ) { RETURN_IF_NULL_COMMON (FALSE) ; Common->status = CHOLMOD_OK ; return (check_factor (NULL, Common->print, name, L, Common)) ; } /* ========================================================================== */ /* === cholmod_check_triplet ================================================ */ /* ========================================================================== */ /* Ensure a triplet matrix is valid, and optionally print it. */ static int check_triplet ( Int print, const char *name, cholmod_triplet *T, cholmod_common *Common ) { double *Tx, *Tz ; Int *Ti, *Tj ; Int i, j, p, nrow, ncol, nzmax, nz, xtype, init_print, count ; const char *type = "triplet" ; /* ---------------------------------------------------------------------- */ /* print header information */ /* ---------------------------------------------------------------------- */ P4 ("%s", "\n") ; P3 ("%s", "CHOLMOD triplet: ") ; if (name != NULL) { P3 ("%s: ", name) ; } if (T == NULL) { ERR ("null") ; } nrow = T->nrow ; ncol = T->ncol ; nzmax = T->nzmax ; nz = T->nnz ; Ti = T->i ; Tj = T->j ; Tx = T->x ; Tz = T->z ; xtype = T->xtype ; P3 (" "ID"", nrow) ; P3 ("-by-"ID", ", ncol) ; P3 ("nz "ID",", nz) ; if (T->stype > 0) { P3 ("%s", " upper.") ; } else if (T->stype < 0) { P3 ("%s", " lower.") ; } else { P3 ("%s", " up/lo.") ; } P4 ("\n nzmax "ID", ", nzmax) ; if (nz > nzmax) { ERR ("nzmax too small") ; } switch (T->itype) { case CHOLMOD_INT: P4 ("%s", "\n scalar types: int, ") ; break ; case CHOLMOD_INTLONG: ERR ("mixed int/long type unsupported") ; case CHOLMOD_LONG: P4 ("%s", "\n scalar types: SuiteSparse_long, "); break ; default: ERR ("unknown itype") ; } switch (T->xtype) { case CHOLMOD_PATTERN: P4 ("%s", "pattern") ; break ; case CHOLMOD_REAL: P4 ("%s", "real") ; break ; case CHOLMOD_COMPLEX: P4 ("%s", "complex") ; break ; case CHOLMOD_ZOMPLEX: P4 ("%s", "zomplex") ; break ; default: ERR ("unknown xtype") ; } switch (T->dtype) { case CHOLMOD_DOUBLE: P4 ("%s", ", double\n") ; break ; case CHOLMOD_SINGLE: ERR ("single unsupported") ; default: ERR ("unknown dtype") ; } if (T->itype != ITYPE || T->dtype != DTYPE) { ERR ("integer and real type must match routine") ; } if (T->stype && nrow != ncol) { ERR ("symmetric but not square") ; } /* check for existence of Ti, Tj, Tx arrays */ if (Tj == NULL) { ERR ("j array not present") ; } if (Ti == NULL) { ERR ("i array not present") ; } if (xtype != CHOLMOD_PATTERN && Tx == NULL) { ERR ("x array not present") ; } if (xtype == CHOLMOD_ZOMPLEX && Tz == NULL) { ERR ("z array not present") ; } /* ---------------------------------------------------------------------- */ /* check and print each entry */ /* ---------------------------------------------------------------------- */ init_print = print ; ETC_START (count, 8) ; for (p = 0 ; p < nz ; p++) { ETC (p >= nz-4, count, -1) ; i = Ti [p] ; P4 (" "I8":", p) ; P4 (" "I_8"", i) ; if (i < 0 || i >= nrow) { ERR ("row index out of range") ; } j = Tj [p] ; P4 (" "I_8"", j) ; if (j < 0 || j >= ncol) { ERR ("column index out of range") ; } print_value (print, xtype, Tx, Tz, p, Common) ; P4 ("%s", "\n") ; } /* triplet matrix is valid */ P3 ("%s", " OK\n") ; P4 ("%s", "\n") ; return (TRUE) ; } int CHOLMOD(check_triplet) ( /* ---- input ---- */ cholmod_triplet *T, /* triplet matrix to check */ /* --------------- */ cholmod_common *Common ) { RETURN_IF_NULL_COMMON (FALSE) ; Common->status = CHOLMOD_OK ; return (check_triplet (0, NULL, T, Common)) ; } int CHOLMOD(print_triplet) ( /* ---- input ---- */ cholmod_triplet *T, /* triplet matrix to print */ const char *name, /* printed name of triplet matrix */ /* --------------- */ cholmod_common *Common ) { RETURN_IF_NULL_COMMON (FALSE) ; Common->status = CHOLMOD_OK ; return (check_triplet (Common->print, name, T, Common)) ; } /* ========================================================================== */ /* === CHOLMOD debugging routines =========================================== */ /* ========================================================================== */ #ifndef NDEBUG /* The global variables present only when debugging enabled. */ int CHOLMOD(dump) = 0 ; int CHOLMOD(dump_malloc) = -1 ; /* workspace: no debug routines use workspace in Common */ /* ========================================================================== */ /* === cholmod_dump_init ==================================================== */ /* ========================================================================== */ void CHOLMOD(dump_init) (const char *s, cholmod_common *Common) { int i = 0 ; FILE *f ; f = fopen ("debug", "r") ; CHOLMOD(dump) = 0 ; if (f != NULL) { i = fscanf (f, "%d", &CHOLMOD(dump)) ; fclose (f) ; } PRINT1 (("%s: cholmod_dump_init, D = %d\n", s, CHOLMOD(dump))) ; } /* ========================================================================== */ /* === cholmod_dump_sparse ================================================== */ /* ========================================================================== */ /* returns nnz (diag (A)) or EMPTY if error */ SuiteSparse_long CHOLMOD(dump_sparse) ( cholmod_sparse *A, const char *name, cholmod_common *Common ) { Int *Wi ; SuiteSparse_long nnzdiag ; Int ok ; if (CHOLMOD(dump) < -1) { /* no checks if debug level is -2 or less */ return (0) ; } RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; Wi = malloc (MAX (1, A->nrow) * sizeof (Int)) ; ok = check_sparse (Wi, CHOLMOD(dump), name, A, &nnzdiag, Common) ; if (Wi != NULL) free (Wi) ; return (ok ? nnzdiag : EMPTY) ; } /* ========================================================================== */ /* === cholmod_dump_factor ================================================== */ /* ========================================================================== */ int CHOLMOD(dump_factor) ( cholmod_factor *L, const char *name, cholmod_common *Common ) { Int *Wi ; int ok ; if (CHOLMOD(dump) < -1) { /* no checks if debug level is -2 or less */ return (TRUE) ; } RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (L, FALSE) ; Wi = malloc (MAX (1, L->n) * sizeof (Int)) ; ok = check_factor (Wi, CHOLMOD(dump), name, L, Common) ; if (Wi != NULL) free (Wi) ; return (ok) ; } /* ========================================================================== */ /* === cholmod_dump_perm ==================================================== */ /* ========================================================================== */ int CHOLMOD(dump_perm) ( Int *Perm, size_t len, size_t n, const char *name, cholmod_common *Common ) { Int *Wi ; int ok ; if (CHOLMOD(dump) < -1) { /* no checks if debug level is -2 or less */ return (TRUE) ; } RETURN_IF_NULL_COMMON (FALSE) ; Wi = malloc (MAX (1, n) * sizeof (Int)) ; ok = check_perm (Wi, CHOLMOD(dump), name, Perm, len, n,Common) ; if (Wi != NULL) free (Wi) ; return (ok) ; } /* ========================================================================== */ /* === cholmod_dump_dense =================================================== */ /* ========================================================================== */ int CHOLMOD(dump_dense) ( cholmod_dense *X, const char *name, cholmod_common *Common ) { if (CHOLMOD(dump) < -1) { /* no checks if debug level is -2 or less */ return (TRUE) ; } RETURN_IF_NULL_COMMON (FALSE) ; return (check_dense (CHOLMOD(dump), name, X, Common)) ; } /* ========================================================================== */ /* === cholmod_dump_triplet ================================================= */ /* ========================================================================== */ int CHOLMOD(dump_triplet) ( cholmod_triplet *T, const char *name, cholmod_common *Common ) { if (CHOLMOD(dump) < -1) { /* no checks if debug level is -2 or less */ return (TRUE) ; } RETURN_IF_NULL_COMMON (FALSE) ; return (check_triplet (CHOLMOD(dump), name, T, Common)) ; } /* ========================================================================== */ /* === cholmod_dump_subset ================================================== */ /* ========================================================================== */ int CHOLMOD(dump_subset) ( Int *S, size_t len, size_t n, const char *name, cholmod_common *Common ) { if (CHOLMOD(dump) < -1) { /* no checks if debug level is -2 or less */ return (TRUE) ; } RETURN_IF_NULL_COMMON (FALSE) ; return (check_subset (S, len, n, CHOLMOD(dump), name, Common)) ; } /* ========================================================================== */ /* === cholmod_dump_parent ================================================== */ /* ========================================================================== */ int CHOLMOD(dump_parent) ( Int *Parent, size_t n, const char *name, cholmod_common *Common ) { if (CHOLMOD(dump) < -1) { /* no checks if debug level is -2 or less */ return (TRUE) ; } RETURN_IF_NULL_COMMON (FALSE) ; return (check_parent (Parent, n, CHOLMOD(dump), name, Common)) ; } /* ========================================================================== */ /* === cholmod_dump_real ==================================================== */ /* ========================================================================== */ void CHOLMOD(dump_real) ( const char *name, Real *X, SuiteSparse_long nrow, SuiteSparse_long ncol, int lower, int xentry, cholmod_common *Common ) { /* dump an nrow-by-ncol real dense matrix */ SuiteSparse_long i, j ; double x, z ; if (CHOLMOD(dump) < -1) { /* no checks if debug level is -2 or less */ return ; } PRINT1 (("%s: dump_real, nrow: %ld ncol: %ld lower: %d\n", name, nrow, ncol, lower)) ; for (j = 0 ; j < ncol ; j++) { PRINT2 ((" col %ld\n", j)) ; for (i = 0 ; i < nrow ; i++) { /* X is stored in column-major form */ if (lower && i < j) { PRINT2 ((" %5ld: -", i)) ; } else { x = *X ; PRINT2 ((" %5ld: %e", i, x)) ; if (xentry == 2) { z = *(X+1) ; PRINT2 ((", %e", z)) ; } } PRINT2 (("\n")) ; X += xentry ; } } } /* ========================================================================== */ /* === cholmod_dump_super =================================================== */ /* ========================================================================== */ void CHOLMOD(dump_super) ( SuiteSparse_long s, Int *Super, Int *Lpi, Int *Ls, Int *Lpx, double *Lx, int xentry, cholmod_common *Common ) { Int k1, k2, do_values, psi, psx, nsrow, nscol, psend, ilast, p, i ; if (CHOLMOD(dump) < -1) { /* no checks if debug level is -2 or less */ return ; } k1 = Super [s] ; k2 = Super [s+1] ; nscol = k2 - k1 ; do_values = (Lpx != NULL) && (Lx != NULL) ; psi = Lpi [s] ; psend = Lpi [s+1] ; nsrow = psend - psi ; PRINT1 (("\nSuper %ld, columns "ID" to "ID", "ID" rows "ID" cols\n", s, k1, k2-1, nsrow, nscol)) ; ilast = -1 ; for (p = psi ; p < psend ; p++) { i = Ls [p] ; PRINT2 ((" "ID" : p-psi "ID"\n", i, p-psi)) ; ASSERT (IMPLIES (p-psi < nscol, i == k1 + (p-psi))) ; if (p-psi == nscol-1) PRINT2 (("------\n")) ; ASSERT (i > ilast) ; ilast = i ; } if (do_values) { psx = Lpx [s] ; CHOLMOD(dump_real) ("Supernode", Lx + xentry*psx, nsrow, nscol, TRUE, xentry, Common) ; } } /* ========================================================================== */ /* === cholmod_dump_mem ===================================================== */ /* ========================================================================== */ int CHOLMOD(dump_mem) ( const char *where, SuiteSparse_long should, cholmod_common *Common ) { SuiteSparse_long diff = should - Common->memory_inuse ; if (diff != 0) { PRINT0 (("mem: %-15s peak %10g inuse %10g should %10g\n", where, (double) Common->memory_usage, (double) Common->memory_inuse, (double) should)) ; PRINT0 (("mem: %s diff %ld !\n", where, diff)) ; } return (diff == 0) ; } /* ========================================================================== */ /* === cholmod_dump_partition =============================================== */ /* ========================================================================== */ /* make sure we have a proper separator (for debugging only) * * workspace: none */ int CHOLMOD(dump_partition) ( SuiteSparse_long n, Int *Cp, Int *Ci, Int *Cnw, /* can be NULL */ Int *Part, SuiteSparse_long sepsize, cholmod_common *Common ) { Int chek [3], which, ok, i, j, p ; PRINT1 (("bisect sepsize %ld\n", sepsize)) ; ok = TRUE ; chek [0] = 0 ; chek [1] = 0 ; chek [2] = 0 ; for (j = 0 ; j < n ; j++) { PRINT2 (("--------j "ID" in part "ID" nw "ID"\n", j, Part [j], Cnw ? (Cnw[j]):1)); which = Part [j] ; for (p = Cp [j] ; p < Cp [j+1] ; p++) { i = Ci [p] ; PRINT3 (("i "ID", part "ID"\n", i, Part [i])) ; if (which == 0) { if (Part [i] == 1) { PRINT0 (("Error! "ID" "ID"\n", i, j)) ; ok = FALSE ; } } else if (which == 1) { if (Part [i] == 0) { PRINT0 (("Error! "ID" "ID"\n", i, j)) ; ok = FALSE ; } } } if (which < 0 || which > 2) { PRINT0 (("Part out of range\n")) ; ok = FALSE ; } chek [which] += (Cnw ? (Cnw [j]) : 1) ; } PRINT1 (("sepsize %ld check "ID" "ID" "ID"\n", sepsize, chek[0], chek[1],chek[2])); if (sepsize != chek[2]) { PRINT0 (("mismatch!\n")) ; ok = FALSE ; } return (ok) ; } /* ========================================================================== */ /* === cholmod_dump_work ==================================================== */ /* ========================================================================== */ int CHOLMOD(dump_work) (int flag, int head, SuiteSparse_long wsize, cholmod_common *Common) { double *W ; Int *Flag, *Head ; Int k, nrow, mark ; if (CHOLMOD(dump) < -1) { /* no checks if debug level is -2 or less */ return (TRUE) ; } RETURN_IF_NULL_COMMON (FALSE) ; nrow = Common->nrow ; Flag = Common->Flag ; Head = Common->Head ; W = Common->Xwork ; mark = Common->mark ; if (wsize < 0) { /* check all of Xwork */ wsize = Common->xworksize ; } else { /* check on the first wsize doubles in Xwork */ wsize = MIN (wsize, (Int) (Common->xworksize)) ; } if (flag) { for (k = 0 ; k < nrow ; k++) { if (Flag [k] >= mark) { PRINT0 (("Flag invalid, Flag ["ID"] = "ID", mark = "ID"\n", k, Flag [k], mark)) ; ASSERT (0) ; return (FALSE) ; } } } if (head) { for (k = 0 ; k < nrow ; k++) { if (Head [k] != EMPTY) { PRINT0 (("Head invalid, Head ["ID"] = "ID"\n", k, Head [k])) ; ASSERT (0) ; return (FALSE) ; } } } for (k = 0 ; k < wsize ; k++) { if (W [k] != 0.) { PRINT0 (("W invalid, W ["ID"] = %g\n", k, W [k])) ; ASSERT (0) ; return (FALSE) ; } } return (TRUE) ; } #endif #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Supernodal/����������������������������������������������������������������������0000755�0001762�0000144�00000000000�14547723665�015531� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Supernodal/cholmod_super_symbolic.c����������������������������������������������0000644�0001762�0000144�00000102332�13652535054�022427� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Supernodal/cholmod_super_symbolic ==================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Supernodal Module. Copyright (C) 2005-2006, Timothy A. Davis * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* Supernodal symbolic analysis of the LL' factorization of A, A*A', * A(:,f)*A(:,f)'. * * This routine must be preceded by a simplicial symbolic analysis * (cholmod_rowcolcounts). See cholmod_analyze.c for an example of how to use * this routine. * * The user need not call this directly; cholmod_analyze is a "simple" wrapper * for this routine. * * Symmetric case: * * A is stored in column form, with entries stored in the upper triangular * part. Entries in the lower triangular part are ignored. * * Unsymmetric case: * * A is stored in column form. If F is equal to the transpose of A, then * A*A' is analyzed. F can include a subset of the columns of A * (F=A(:,f)'), in which case F*F' is analyzed. * * Requires Parent and L->ColCount to be defined on input; these are the * simplicial Parent and ColCount arrays as computed by cholmod_rowcolcounts. * Does not use L->Perm; the input matrices A and F must already be properly * permuted. Allocates and computes the supernodal pattern of L (L->super, * L->pi, L->px, and L->s). Does not allocate the real part (L->x). * * Supports any xtype (pattern, real, complex, or zomplex). */ #ifndef NGPL #ifndef NSUPERNODAL #include "cholmod_internal.h" #include "cholmod_supernodal.h" #ifdef GPU_BLAS #include "cholmod_gpu.h" #endif /* ========================================================================== */ /* === subtree ============================================================== */ /* ========================================================================== */ /* In the symmetric case, traverse the kth row subtree from the nonzeros in * A (0:k1-1,k) and add the new entries found to the pattern of the kth row * of L. The current supernode s contains the diagonal block k1:k2-1, so it * can be skipped. * * In the unsymmetric case, the nonzero pattern of A*F is computed one column * at a time (thus, the total time spent in this function is bounded below by * the time taken to multiply A*F, which can be high if A is tall and thin). * The kth column is A*F(:,k), or the set union of all columns A(:,j) for which * F(j,k) is nonzero. This routine is called once for each entry j. Only the * upper triangular part is needed, so only A (0:k1-1,j) is accessed, where * k1:k2-1 are the columns of the current supernode s (k is in the range k1 to * k2-1). * * If A is sorted, then the total time taken by this function is proportional * to the number of nonzeros in the strictly block upper triangular part of A, * plus the number of entries in the strictly block lower triangular part of * the supernodal part of L. This excludes entries in the diagonal blocks * corresponding to the columns in each supernode. That is, if k1:k2-1 are * in a single supernode, then only A (0:k1-1,k1:k2-1) are accessed. * * For the unsymmetric case, only the strictly block upper triangular part * of A*F is constructed. * * Only adds column indices corresponding to the leading columns of each * relaxed supernode. */ static void subtree ( /* inputs, not modified: */ Int j, /* j = k for symmetric case */ Int k, Int Ap [ ], Int Ai [ ], Int Anz [ ], Int SuperMap [ ], Int Sparent [ ], Int mark, Int sorted, /* true if the columns of A are sorted */ Int k1, /* only consider A (0:k1-1,k) */ /* input/output: */ Int Flag [ ], Int Ls [ ], Int Lpi2 [ ] ) { Int p, pend, i, si ; p = Ap [j] ; pend = (Anz == NULL) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; if (i < k1) { /* (i,k) is an entry in the upper triangular part of A or A*F'. * symmetric case: A(i,k) is nonzero (j=k). * unsymmetric case: A(i,j) and F(j,k) are both nonzero. * * Column i is in supernode si = SuperMap [i]. Follow path from si * to root of supernodal etree, stopping at the first flagged * supernode. The root of the row subtree is supernode SuperMap[k], * which is flagged already. This traversal will stop there, or it * might stop earlier if supernodes have been flagged by previous * calls to this routine for the same k. */ for (si = SuperMap [i] ; Flag [si] < mark ; si = Sparent [si]) { ASSERT (si <= SuperMap [k]) ; Ls [Lpi2 [si]++] = k ; Flag [si] = mark ; } } else if (sorted) { break ; } } } /* clear workspace used by cholmod_super_symbolic */ #define FREE_WORKSPACE \ { \ /* CHOLMOD(clear_flag) (Common) ; */ \ CHOLMOD_CLEAR_FLAG (Common) ; \ for (k = 0 ; k <= nfsuper ; k++) \ { \ Head [k] = EMPTY ; \ } \ ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; \ } \ /* ========================================================================== */ /* === cholmod_super_symbolic2 ============================================== */ /* ========================================================================== */ /* Analyze for supernodal Cholesky or multifrontal QR. */ int CHOLMOD(super_symbolic2) ( /* ---- input ---- */ int for_whom, /* FOR_SPQR (0): for SPQR but not GPU-accelerated FOR_CHOLESKY (1): for Cholesky (GPU or not) FOR_SPQRGPU (2): for SPQR with GPU acceleration */ cholmod_sparse *A, /* matrix to analyze */ cholmod_sparse *F, /* F = A' or A(:,f)' */ Int *Parent, /* elimination tree */ /* ---- in/out --- */ cholmod_factor *L, /* simplicial symbolic on input, * supernodal symbolic on output */ /* --------------- */ cholmod_common *Common ) { double zrelax0, zrelax1, zrelax2, xxsize ; Int *Wi, *Wj, *Super, *Snz, *Ap, *Ai, *Flag, *Head, *Ls, *Lpi, *Lpx, *Fnz, *Sparent, *Anz, *SuperMap, *Merged, *Nscol, *Zeros, *Fp, *Fj, *ColCount, *Lpi2, *Lsuper, *Iwork ; Int nsuper, d, n, j, k, s, mark, parent, p, pend, k1, k2, packed, nscol, nsrow, ndrow1, ndrow2, stype, ssize, xsize, sparent, plast, slast, csize, maxcsize, ss, nscol0, nscol1, ns, nfsuper, newzeros, totzeros, merge, snext, esize, maxesize, nrelax0, nrelax1, nrelax2, Asorted ; size_t w ; int ok = TRUE, find_xsize ; const char* env_use_gpu; const char* env_max_bytes; size_t max_bytes; const char* env_max_fraction; double max_fraction; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_NULL (L, FALSE) ; RETURN_IF_NULL (Parent, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; RETURN_IF_XTYPE_INVALID (L, CHOLMOD_PATTERN, CHOLMOD_PATTERN, FALSE) ; stype = A->stype ; if (stype < 0) { /* invalid symmetry; symmetric lower form not supported */ ERROR (CHOLMOD_INVALID, "symmetric lower not supported") ; return (FALSE) ; } if (stype == 0) { /* F must be present in the unsymmetric case */ RETURN_IF_NULL (F, FALSE) ; } if (L->is_super) { /* L must be a simplicial symbolic factor */ ERROR (CHOLMOD_INVALID, "L must be symbolic on input") ; return (FALSE) ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ n = A->nrow ; /* w = 5*n */ w = CHOLMOD(mult_size_t) (n, 5, &ok) ; if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (FALSE) ; } CHOLMOD(allocate_work) (n, w, 0, Common) ; if (Common->status < CHOLMOD_OK) { /* out of memory */ return (FALSE) ; } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; /* ---------------------------------------------------------------------- */ /* allocate GPU workspace */ /* ---------------------------------------------------------------------- */ L->useGPU = 0 ; /* only used for Cholesky factorization, not QR */ #ifdef GPU_BLAS /* GPU module is installed */ if ( for_whom == CHOLMOD_ANALYZE_FOR_CHOLESKY ) { /* only allocate GPU workspace for supernodal Cholesky, and only when the GPU is requested and available. */ max_bytes = 0; max_fraction = 0; #ifdef DLONG if ( Common->useGPU == EMPTY ) { /* useGPU not explicity requested by the user, but not explicitly * prohibited either. Query OS environment variables for request.*/ env_use_gpu = getenv("CHOLMOD_USE_GPU"); if ( env_use_gpu ) { /* CHOLMOD_USE_GPU environment variable is set to something */ if ( atoi ( env_use_gpu ) == 0 ) { Common->useGPU = 0; /* don't use the gpu */ } else { Common->useGPU = 1; /* use the gpu */ env_max_bytes = getenv("CHOLMOD_GPU_MEM_BYTES"); env_max_fraction = getenv("CHOLMOD_GPU_MEM_FRACTION"); if ( env_max_bytes ) { max_bytes = atol(env_max_bytes); Common->maxGpuMemBytes = max_bytes; } if ( env_max_fraction ) { max_fraction = atof (env_max_fraction); if ( max_fraction < 0 ) max_fraction = 0; if ( max_fraction > 1 ) max_fraction = 1; Common->maxGpuMemFraction = max_fraction; } } } else { /* CHOLMOD_USE_GPU environment variable not set, so no GPU * acceleration will be used */ Common->useGPU = 0; } /* fprintf (stderr, "useGPU queried: %d\n", Common->useGPU) ; */ } /* Ensure that a GPU is present */ if ( Common->useGPU == 1 ) { /* fprintf (stderr, "\nprobe GPU:\n") ; */ Common->useGPU = CHOLMOD(gpu_probe) (Common); // Cholesky only, not SPQR /* fprintf (stderr, "\nprobe GPU: result %d\n", Common->useGPU) ; */ } if ( Common->useGPU == 1 ) { /* Cholesky + GPU, so allocate space */ /* fprintf (stderr, "allocate GPU:\n") ; */ CHOLMOD(gpu_allocate) ( Common ); // Cholesky only, not SPQR /* fprintf (stderr, "allocate GPU done\n") ; */ } #else /* GPU acceleration is only supported for long int version */ Common->useGPU = 0; #endif /* Cache the fact that the symbolic factorization supports * GPU acceleration */ L->useGPU = Common->useGPU; } #else /* GPU module is not installed */ Common->useGPU = 0 ; #endif /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ /* A is now either A or triu(A(p,p)) for the symmetric case. It is either * A or A(p,f) for the unsymmetric case (both in column form). It can be * either packed or unpacked, and either sorted or unsorted. Entries in * the lower triangular part may be present if A is symmetric, but these * are ignored. */ Ap = A->p ; Ai = A->i ; Anz = A->nz ; if (stype != 0) { /* F not accessed */ Fp = NULL ; Fj = NULL ; Fnz = NULL ; packed = TRUE ; } else { /* F = A(:,f) or A(p,f) in packed row form, either sorted or unsorted */ Fp = F->p ; Fj = F->i ; Fnz = F->nz ; packed = F->packed ; } ColCount = L->ColCount ; nrelax0 = Common->nrelax [0] ; nrelax1 = Common->nrelax [1] ; nrelax2 = Common->nrelax [2] ; zrelax0 = Common->zrelax [0] ; zrelax1 = Common->zrelax [1] ; zrelax2 = Common->zrelax [2] ; zrelax0 = IS_NAN (zrelax0) ? 0 : zrelax0 ; zrelax1 = IS_NAN (zrelax1) ? 0 : zrelax1 ; zrelax2 = IS_NAN (zrelax2) ? 0 : zrelax2 ; ASSERT (CHOLMOD(dump_parent) (Parent, n, "Parent", Common)) ; /* ---------------------------------------------------------------------- */ /* get workspace */ /* ---------------------------------------------------------------------- */ /* Sparent, Snz, and Merged could be allocated later, of size nfsuper */ Iwork = Common->Iwork ; Wi = Iwork ; /* size n (i/l/l). Lpi2 is i/l/l */ Wj = Iwork + n ; /* size n (i/l/l). Zeros is i/l/l */ Sparent = Iwork + 2*((size_t) n) ; /* size nfsuper <= n [ */ Snz = Iwork + 3*((size_t) n) ; /* size nfsuper <= n [ */ Merged = Iwork + 4*((size_t) n) ; /* size nfsuper <= n [ */ Flag = Common->Flag ; /* size n */ Head = Common->Head ; /* size n+1 */ /* ---------------------------------------------------------------------- */ /* find the fundamental supernodes */ /* ---------------------------------------------------------------------- */ /* count the number of children of each node, using Wi [ */ for (j = 0 ; j < n ; j++) { Wi [j] = 0 ; } for (j = 0 ; j < n ; j++) { parent = Parent [j] ; if (parent != EMPTY) { Wi [parent]++ ; } } Super = Head ; /* use Head [0..nfsuper] as workspace for Super list ( */ /* column 0 always starts a new supernode */ nfsuper = (n == 0) ? 0 : 1 ; /* number of fundamental supernodes */ Super [0] = 0 ; for (j = 1 ; j < n ; j++) { /* check if j starts new supernode, or in the same supernode as j-1 */ if (Parent [j-1] != j /* parent of j-1 is not j */ || (ColCount [j-1] != ColCount [j] + 1) /* j-1 not subset of j*/ || Wi [j] > 1 /* j has more than one child */ #ifdef GPU_BLAS /* Ensure that the supernode will fit in the GPU buffers */ /* Data size of 16 bytes must be assumed for case of PATTERN */ || (for_whom == CHOLMOD_ANALYZE_FOR_CHOLESKY && L->useGPU && (j-Super[nfsuper-1]+1) * ColCount[Super[nfsuper-1]] * sizeof(double) * 2 >= Common->devBuffSize) #endif ) { /* j is the leading node of a supernode */ Super [nfsuper++] = j ; } } Super [nfsuper] = n ; /* contents of Wi no longer needed for child count ] */ Nscol = Wi ; /* use Wi as size-nfsuper workspace for Nscol [ */ /* ---------------------------------------------------------------------- */ /* find the mapping of fundamental nodes to supernodes */ /* ---------------------------------------------------------------------- */ SuperMap = Wj ; /* use Wj as workspace for SuperMap [ */ /* SuperMap [k] = s if column k is contained in supernode s */ for (s = 0 ; s < nfsuper ; s++) { for (k = Super [s] ; k < Super [s+1] ; k++) { SuperMap [k] = s ; } } /* ---------------------------------------------------------------------- */ /* construct the fundamental supernodal etree */ /* ---------------------------------------------------------------------- */ for (s = 0 ; s < nfsuper ; s++) { j = Super [s+1] - 1 ; /* last node in supernode s */ parent = Parent [j] ; /* parent of last node */ Sparent [s] = (parent == EMPTY) ? EMPTY : SuperMap [parent] ; PRINT1 (("Sparent ["ID"] = "ID"\n", s, Sparent [s])) ; } /* contents of Wj no longer needed as workspace for SuperMap ] * SuperMap will be recomputed below, for the relaxed supernodes. */ Zeros = Wj ; /* use Wj for Zeros, workspace of size nfsuper [ */ /* ---------------------------------------------------------------------- */ /* relaxed amalgamation */ /* ---------------------------------------------------------------------- */ for (s = 0 ; s < nfsuper ; s++) { Merged [s] = EMPTY ; /* s not merged into another */ Nscol [s] = Super [s+1] - Super [s] ; /* # of columns in s */ Zeros [s] = 0 ; /* # of zero entries in s */ ASSERT (s <= Super [s]) ; Snz [s] = ColCount [Super [s]] ; /* # of entries in leading col of s */ PRINT2 (("lnz ["ID"] "ID"\n", s, Snz [s])) ; } for (s = nfsuper-2 ; s >= 0 ; s--) { double lnz1 ; /* should supernodes s and s+1 merge into a new node s? */ PRINT1 (("\n========= Check relax of s "ID" and s+1 "ID"\n", s, s+1)) ; ss = Sparent [s] ; if (ss == EMPTY) { PRINT1 (("s "ID" is a root, no merge with s+1 = "ID"\n", s, s+1)) ; continue ; } /* find the current parent of s (perform path compression as needed) */ for (ss = Sparent [s] ; Merged [ss] != EMPTY ; ss = Merged [ss]) ; sparent = ss ; PRINT2 (("Current sparent of s "ID" is "ID"\n", s, sparent)) ; /* ss is the current parent of s */ for (ss = Sparent [s] ; Merged [ss] != EMPTY ; ss = snext) { snext = Merged [ss] ; PRINT2 (("ss "ID" is dead, merged into snext "ID"\n", ss, snext)) ; Merged [ss] = sparent ; } /* if s+1 is not the current parent of s, do not merge */ if (sparent != s+1) { continue ; } nscol0 = Nscol [s] ; /* # of columns in s */ nscol1 = Nscol [s+1] ; /* # of columns in s+1 */ ns = nscol0 + nscol1 ; PRINT2 (("ns "ID" nscol0 "ID" nscol1 "ID"\n", ns, nscol0, nscol1)) ; totzeros = Zeros [s+1] ; /* current # of zeros in s+1 */ lnz1 = (double) (Snz [s+1]) ; /* # entries in leading column of s+1 */ /* determine if supernodes s and s+1 should merge */ if (ns <= nrelax0) { PRINT2 (("ns is tiny ("ID"), so go ahead and merge\n", ns)) ; merge = TRUE ; } else { /* use double to avoid integer overflow */ double lnz0 = Snz [s] ; /* # entries in leading column of s */ double xnewzeros = nscol0 * (lnz1 + nscol0 - lnz0) ; /* use Int for the final update of Zeros [s] below */ newzeros = nscol0 * (Snz [s+1] + nscol0 - Snz [s]) ; ASSERT (newzeros == xnewzeros) ; PRINT2 (("lnz0 %g lnz1 %g xnewzeros %g\n", lnz0, lnz1, xnewzeros)) ; if (xnewzeros == 0) { /* no new zeros, so go ahead and merge */ PRINT2 (("no new fillin, so go ahead and merge\n")) ; merge = TRUE ; } else { /* # of zeros if merged */ double xtotzeros = ((double) totzeros) + xnewzeros ; /* xtotsize: total size of merged supernode, if merged: */ double xns = (double) ns ; double xtotsize = (xns * (xns+1) / 2) + xns * (lnz1 - nscol1) ; double z = xtotzeros / xtotsize ; Int totsize ; totsize = (ns * (ns+1) / 2) + ns * (Snz [s+1] - nscol1) ; PRINT2 (("oldzeros "ID" newzeros "ID" xtotsize %g z %g\n", Zeros [s+1], newzeros, xtotsize, z)) ; /* use Int for the final update of Zeros [s] below */ totzeros += newzeros ; /* do not merge if supernode would become too big * (Int overflow). Continue computing; not (yet) an error. */ /* fl.pt. compare, but no NaN's can occur here */ merge = ((ns <= nrelax1 && z < zrelax0) || (ns <= nrelax2 && z < zrelax1) || (z < zrelax2)) && (xtotsize < Int_max / sizeof (double)) ; } } #ifdef GPU_BLAS if ( for_whom == CHOLMOD_ANALYZE_FOR_CHOLESKY && L->useGPU ) { /* Ensure that the aggregated supernode fits in the device supernode buffers */ double xns = (double) ns; if ( ((xns * xns) + xns * (lnz1 - nscol1))*sizeof(double)*2 >= Common->devBuffSize ) { merge = FALSE; } } #endif if (merge) { PRINT1 (("Merge node s ("ID") and s+1 ("ID")\n", s, s+1)) ; Zeros [s] = totzeros ; Merged [s+1] = s ; Snz [s] = nscol0 + Snz [s+1] ; Nscol [s] += Nscol [s+1] ; } } /* contents of Wj no longer needed for Zeros ] */ /* contents of Wi no longer needed for Nscol ] */ /* contents of Sparent no longer needed (recomputed below) */ /* ---------------------------------------------------------------------- */ /* construct the relaxed supernode list */ /* ---------------------------------------------------------------------- */ nsuper = 0 ; for (s = 0 ; s < nfsuper ; s++) { if (Merged [s] == EMPTY) { PRINT1 (("live supernode: "ID" snz "ID"\n", s, Snz [s])) ; Super [nsuper] = Super [s] ; Snz [nsuper] = Snz [s] ; nsuper++ ; } } Super [nsuper] = n ; PRINT1 (("Fundamental supernodes: "ID" relaxed "ID"\n", nfsuper, nsuper)) ; /* Merged no longer needed ] */ /* ---------------------------------------------------------------------- */ /* find the mapping of relaxed nodes to supernodes */ /* ---------------------------------------------------------------------- */ /* use Wj as workspace for SuperMap { */ /* SuperMap [k] = s if column k is contained in supernode s */ for (s = 0 ; s < nsuper ; s++) { for (k = Super [s] ; k < Super [s+1] ; k++) { SuperMap [k] = s ; } } /* ---------------------------------------------------------------------- */ /* construct the relaxed supernodal etree */ /* ---------------------------------------------------------------------- */ for (s = 0 ; s < nsuper ; s++) { j = Super [s+1] - 1 ; /* last node in supernode s */ parent = Parent [j] ; /* parent of last node */ Sparent [s] = (parent == EMPTY) ? EMPTY : SuperMap [parent] ; PRINT1 (("new Sparent ["ID"] = "ID"\n", s, Sparent [s])) ; } /* ---------------------------------------------------------------------- */ /* determine the size of L->s and L->x */ /* ---------------------------------------------------------------------- */ ssize = 0 ; xsize = 0 ; xxsize = 0 ; find_xsize = for_whom == CHOLMOD_ANALYZE_FOR_CHOLESKY || for_whom == CHOLMOD_ANALYZE_FOR_SPQRGPU ; for (s = 0 ; s < nsuper ; s++) { nscol = Super [s+1] - Super [s] ; nsrow = Snz [s] ; ASSERT (nscol > 0) ; ssize += nsrow ; if (find_xsize) { xsize += nscol * nsrow ; /* also compute xsize in double to guard against Int overflow */ xxsize += ((double) nscol) * ((double) nsrow) ; } if (ssize < 0 ||(find_xsize && xxsize > Int_max)) { /* Int overflow, clear workspace and return. QR factorization will not use xxsize, so that error is ignored. For Cholesky factorization, however, memory of space xxsize will be allocated, so this is a failure. Both QR and Cholesky fail if ssize overflows. */ ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; FREE_WORKSPACE ; return (FALSE) ; } ASSERT (ssize > 0) ; ASSERT (IMPLIES (find_xsize, xsize > 0)) ; } xsize = MAX (1, xsize) ; ssize = MAX (1, ssize) ; PRINT1 (("ix sizes: "ID" "ID" nsuper "ID"\n", ssize, xsize, nsuper)) ; /* ---------------------------------------------------------------------- */ /* allocate L (all except real part L->x) */ /* ---------------------------------------------------------------------- */ L->ssize = ssize ; L->xsize = xsize ; L->nsuper = nsuper ; CHOLMOD(change_factor) (CHOLMOD_PATTERN, TRUE, TRUE, TRUE, TRUE, L, Common); if (Common->status < CHOLMOD_OK) { /* out of memory; L is still a valid simplicial symbolic factor */ FREE_WORKSPACE ; return (FALSE) ; } DEBUG (CHOLMOD(dump_factor) (L, "L to symbolic super", Common)) ; ASSERT (L->is_ll && L->xtype == CHOLMOD_PATTERN && L->is_super) ; Lpi = L->pi ; Lpx = L->px ; Ls = L->s ; Ls [0] = 0 ; /* flag for cholmod_check_factor; supernodes are defined */ Lsuper = L->super ; /* copy the list of relaxed supernodes into the final list in L */ for (s = 0 ; s <= nsuper ; s++) { Lsuper [s] = Super [s] ; } /* Head no longer needed as workspace for fundamental Super list ) */ Super = Lsuper ; /* Super is now the list of relaxed supernodes */ /* ---------------------------------------------------------------------- */ /* construct column pointers of relaxed supernodal pattern (L->pi) */ /* ---------------------------------------------------------------------- */ p = 0 ; for (s = 0 ; s < nsuper ; s++) { Lpi [s] = p ; p += Snz [s] ; PRINT1 (("Snz ["ID"] = "ID", Super ["ID"] = "ID"\n", s, Snz [s], s, Super[s])) ; } Lpi [nsuper] = p ; ASSERT ((Int) (L->ssize) == MAX (1,p)) ; /* ---------------------------------------------------------------------- */ /* construct pointers for supernodal values (L->px) */ /* ---------------------------------------------------------------------- */ if (for_whom == CHOLMOD_ANALYZE_FOR_CHOLESKY || for_whom == CHOLMOD_ANALYZE_FOR_SPQRGPU) { Lpx [0] = 0 ; p = 0 ; for (s = 0 ; s < nsuper ; s++) { nscol = Super [s+1] - Super [s] ; /* number of columns in s */ nsrow = Snz [s] ; /* # of rows, incl triangular part*/ Lpx [s] = p ; /* pointer to numerical part of s */ p += nscol * nsrow ; } Lpx [s] = p ; ASSERT ((Int) (L->xsize) == MAX (1,p)) ; } else { /* L->px is not needed for non-GPU accelerated QR factorization (it may * lead to Int overflow, anyway, if xsize caused Int overflow above). * Use a magic number to tell cholmod_check_factor to ignore Lpx. */ Lpx [0] = 123456 ; } /* Snz no longer needed ] */ /* ---------------------------------------------------------------------- */ /* symbolic analysis to construct the relaxed supernodal pattern (L->s) */ /* ---------------------------------------------------------------------- */ Lpi2 = Wi ; /* copy Lpi into Lpi2, using Wi as workspace for Lpi2 [ */ for (s = 0 ; s < nsuper ; s++) { Lpi2 [s] = Lpi [s] ; } Asorted = A->sorted ; for (s = 0 ; s < nsuper ; s++) { /* sth supernode is in columns k1 to k2-1. * compute nonzero pattern of L (k1:k2-1,:). */ /* place rows k1 to k2-1 in leading column of supernode s */ k1 = Super [s] ; k2 = Super [s+1] ; PRINT1 (("=========>>> Supernode "ID" k1 "ID" k2-1 "ID"\n", s, k1, k2-1)) ; for (k = k1 ; k < k2 ; k++) { Ls [Lpi2 [s]++] = k ; } /* compute nonzero pattern each row k1 to k2-1 */ for (k = k1 ; k < k2 ; k++) { /* compute row k of L. In the symmetric case, the pattern of L(k,:) * is the set of nodes reachable in the supernodal etree from any * row i in the nonzero pattern of A(0:k,k). In the unsymmetric * case, the pattern of the kth column of A*A' is the set union * of all columns A(0:k,j) for each nonzero F(j,k). */ /* clear the Flag array and mark the current supernode */ /* mark = CHOLMOD(clear_flag) (Common) ; */ CHOLMOD_CLEAR_FLAG (Common) ; mark = Common->mark ; Flag [s] = mark ; ASSERT (s == SuperMap [k]) ; /* traverse the row subtree for each nonzero in A or AA' */ if (stype != 0) { subtree (k, k, Ap, Ai, Anz, SuperMap, Sparent, mark, Asorted, k1, Flag, Ls, Lpi2) ; } else { /* for each j nonzero in F (:,k) do */ p = Fp [k] ; pend = (packed) ? (Fp [k+1]) : (p + Fnz [k]) ; for ( ; p < pend ; p++) { subtree (Fj [p], k, Ap, Ai, Anz, SuperMap, Sparent, mark, Asorted, k1, Flag, Ls, Lpi2) ; } } } } #ifndef NDEBUG for (s = 0 ; s < nsuper ; s++) { PRINT1 (("Lpi2[s] "ID" Lpi[s+1] "ID"\n", Lpi2 [s], Lpi [s+1])) ; ASSERT (Lpi2 [s] == Lpi [s+1]) ; CHOLMOD(dump_super) (s, Super, Lpi, Ls, NULL, NULL, 0, Common) ; } #endif /* contents of Wi no longer needed for Lpi2 ] */ /* Sparent no longer needed ] */ /* ---------------------------------------------------------------------- */ /* determine the largest update matrix (L->maxcsize) */ /* ---------------------------------------------------------------------- */ /* maxcsize could be determined before L->s is allocated and defined, which * would mean that all memory requirements for both the symbolic and numeric * factorizations could be computed using O(nnz(A)+O(n)) space. However, it * would require a lot of extra work. The analysis phase, above, would need * to be duplicated, but with Ls not kept; instead, the algorithm would keep * track of the current s and slast for each supernode d, and update them * when a new row index appears in supernode d. An alternative would be to * do this computation only if the allocation of L->s failed, in which case * the following code would be skipped. * * The csize for a supernode is the size of its largest contribution to * a subsequent ancestor supernode. For example, suppose the rows of #'s * in the figure below correspond to the columns of a subsequent supernode, * and the dots are the entries in that ancestore. * * c * c c * c c c * x x x * x x x * # # # . * # # # . . * * * * . . * * * * . . * * * * . . * . . * * Then for this update, the csize is 3-by-2, or 6, because there are 3 * rows of *'s which is the number of rows in the update, and there are * 2 rows of #'s, which is the number columns in the update. The csize * of a supernode is the largest such contribution for any ancestor * supernode. maxcsize, for the whole matrix, has a rough upper bound of * the maximum size of any supernode. This bound is loose, because the * the contribution must be less than the size of the ancestor supernodal * that it's updating. maxcsize of a completely dense matrix, with one * supernode, is zero. * * maxesize is the column dimension for the workspace E needed for the * solve. E is of size nrhs-by-maxesize, where the nrhs is the number of * columns in the right-hand-side. The maxesize is the largest esize of * any supernode. The esize of a supernode is the number of row indices * it contains, excluding the column indices of the supernode itself. * For the following example, esize is 4: * * c * c c * c c c * x x x * x x x * x x x * x x x * * maxesize can be no bigger than n. */ maxcsize = 1 ; maxesize = 1 ; /* Do not need to guard csize against Int overflow since xsize is OK. */ if (for_whom == CHOLMOD_ANALYZE_FOR_CHOLESKY || for_whom == CHOLMOD_ANALYZE_FOR_SPQRGPU) { /* this is not needed for non-GPU accelerated QR factorization */ for (d = 0 ; d < nsuper ; d++) { nscol = Super [d+1] - Super [d] ; p = Lpi [d] + nscol ; plast = p ; pend = Lpi [d+1] ; esize = pend - p ; maxesize = MAX (maxesize, esize) ; slast = (p == pend) ? (EMPTY) : (SuperMap [Ls [p]]) ; for ( ; p <= pend ; p++) { s = (p == pend) ? (EMPTY) : (SuperMap [Ls [p]]) ; if (s != slast) { /* row i is the start of a new supernode */ ndrow1 = p - plast ; ndrow2 = pend - plast ; csize = ndrow2 * ndrow1 ; PRINT1 (("Supernode "ID" ancestor "ID" C: "ID"-by-"ID " csize "ID"\n", d, slast, ndrow1, ndrow2, csize)) ; maxcsize = MAX (maxcsize, csize) ; plast = p ; slast = s ; } } } PRINT1 (("max csize "ID"\n", maxcsize)) ; } /* Wj no longer needed for SuperMap } */ L->maxcsize = maxcsize ; L->maxesize = maxesize ; L->is_super = TRUE ; ASSERT (L->xtype == CHOLMOD_PATTERN && L->is_ll) ; /* ---------------------------------------------------------------------- */ /* supernodal symbolic factorization is complete */ /* ---------------------------------------------------------------------- */ FREE_WORKSPACE ; return (TRUE) ; } /* ========================================================================== */ /* === cholmod_super_symbolic =============================================== */ /* ========================================================================== */ /* Analyzes A, AA', or A(:,f)*A(:,f)' in preparation for a supernodal numeric * factorization. The user need not call this directly; cholmod_analyze is * a "simple" wrapper for this routine. * * This function does all the analysis for a supernodal Cholesky factorization. * * workspace: Flag (nrow), Head (nrow), Iwork (2*nrow), * and temporary space of size 3*nfsuper*sizeof(Int), where nfsuper <= n * is the number of fundamental supernodes. */ int CHOLMOD(super_symbolic) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to analyze */ cholmod_sparse *F, /* F = A' or A(:,f)' */ Int *Parent, /* elimination tree */ /* ---- in/out --- */ cholmod_factor *L, /* simplicial symbolic on input, * supernodal symbolic on output */ /* --------------- */ cholmod_common *Common ) { return (CHOLMOD(super_symbolic2) (CHOLMOD_ANALYZE_FOR_CHOLESKY, A, F, Parent, L, Common)) ; } #endif #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Supernodal/t_cholmod_super_numeric.c���������������������������������������������0000644�0001762�0000144�00000122766�13652535054�022610� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Supernodal/t_cholmod_super_numeric =================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Supernodal Module. Copyright (C) 2005-2012, Timothy A. Davis * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* Template routine for cholmod_super_numeric. All xtypes supported, except * that a zomplex A and F result in a complex L (there is no supernodal * zomplex L). */ /* ========================================================================== */ /* === complex arithmetic =================================================== */ /* ========================================================================== */ #include "cholmod_template.h" #undef L_ENTRY #undef L_CLEAR #undef L_ASSIGN #undef L_MULTADD #undef L_ASSEMBLE #undef L_ASSEMBLESUB #ifdef REAL /* -------------------------------------------------------------------------- */ /* A, F, and L are all real */ /* -------------------------------------------------------------------------- */ #define L_ENTRY 1 #define L_CLEAR(Lx,p) Lx [p] = 0 #define L_ASSIGN(Lx,q, Ax,Az,p) Lx [q] = Ax [p] #define L_MULTADD(Lx,q, Ax,Az,p, f) Lx [q] += Ax [p] * f [0] #define L_ASSEMBLE(Lx,q,b) Lx [q] += b [0] #define L_ASSEMBLESUB(Lx,q,C,p) Lx [q] -= C [p] #else /* -------------------------------------------------------------------------- */ /* A and F are complex or zomplex, L and C are complex */ /* -------------------------------------------------------------------------- */ #define L_ENTRY 2 #define L_CLEAR(Lx,p) Lx [2*(p)] = 0 ; Lx [2*(p)+1] = 0 #define L_ASSEMBLE(Lx,q,b) Lx [2*(q)] += b [0] ; #define L_ASSEMBLESUB(Lx,q,C,p) \ Lx [2*(q) ] -= C [2*(p) ] ; \ Lx [2*(q)+1] -= C [2*(p)+1] ; #ifdef COMPLEX /* -------------------------------------------------------------------------- */ /* A, F, L, and C are all complex */ /* -------------------------------------------------------------------------- */ #define L_ASSIGN(Lx,q, Ax,Az,p) \ Lx [2*(q) ] = Ax [2*(p) ] ; \ Lx [2*(q)+1] = Ax [2*(p)+1] #define L_MULTADD(Lx,q, Ax,Az,p, f) \ Lx [2*(q) ] += Ax [2*(p) ] * f [0] - Ax [2*(p)+1] * f [1] ; \ Lx [2*(q)+1] += Ax [2*(p)+1] * f [0] + Ax [2*(p) ] * f [1] #else /* -------------------------------------------------------------------------- */ /* A and F are zomplex, L and C is complex */ /* -------------------------------------------------------------------------- */ #define L_ASSIGN(Lx,q, Ax,Az,p) \ Lx [2*(q) ] = Ax [p] ; \ Lx [2*(q)+1] = Az [p] ; #define L_MULTADD(Lx,q, Ax,Az,p, f) \ Lx [2*(q) ] += Ax [p] * f [0] - Az [p] * f [1] ; \ Lx [2*(q)+1] += Az [p] * f [0] + Ax [p] * f [1] #endif #endif /* ========================================================================== */ /* === t_cholmod_super_numeric ============================================== */ /* ========================================================================== */ /* This function returns FALSE only if integer overflow occurs in the BLAS. * It returns TRUE otherwise whether or not the matrix is positive definite. */ static int TEMPLATE (cholmod_super_numeric) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to factorize */ cholmod_sparse *F, /* F = A' or A(:,f)' */ double beta [2], /* beta*I is added to diagonal of matrix to factorize */ /* ---- in/out --- */ cholmod_factor *L, /* factorization */ /* -- workspace -- */ cholmod_dense *Cwork, /* size (L->maxcsize)-by-1 */ /* --------------- */ cholmod_common *Common ) { double one [2], zero [2], tstart ; double *Lx, *Ax, *Fx, *Az, *Fz, *C ; Int *Super, *Head, *Ls, *Lpi, *Lpx, *Map, *SuperMap, *RelativeMap, *Next, *Lpos, *Fp, *Fi, *Fnz, *Ap, *Ai, *Anz, *Iwork, *Next_save, *Lpos_save, *Previous; Int nsuper, n, j, i, k, s, p, pend, k1, k2, nscol, psi, psx, psend, nsrow, pj, d, kd1, kd2, info, ndcol, ndrow, pdi, pdx, pdend, pdi1, pdi2, pdx1, ndrow1, ndrow2, px, dancestor, sparent, dnext, nsrow2, ndrow3, pk, pf, pfend, stype, Apacked, Fpacked, q, imap, repeat_supernode, nscol2, ss, tail, nscol_new = 0; /* ---------------------------------------------------------------------- */ /* declarations for the GPU */ /* ---------------------------------------------------------------------- */ /* these variables are not used if the GPU module is not installed */ #ifdef GPU_BLAS Int ndescendants, mapCreatedOnGpu, supernodeUsedGPU, idescendant, dlarge, dsmall, skips ; int iHostBuff, iDevBuff, useGPU, GPUavailable ; cholmod_gpu_pointers *gpu_p, gpu_pointer_struct ; gpu_p = &gpu_pointer_struct ; #endif /* ---------------------------------------------------------------------- */ /* guard against integer overflow in the BLAS */ /* ---------------------------------------------------------------------- */ /* If integer overflow occurs in the BLAS, Common->status is set to * CHOLMOD_TOO_LARGE, and the contents of Lx are undefined. */ Common->blas_ok = TRUE ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ nsuper = L->nsuper ; n = L->n ; C = Cwork->x ; /* workspace of size L->maxcsize */ one [0] = 1.0 ; /* ALPHA for *syrk, *herk, *gemm, and *trsm */ one [1] = 0. ; zero [0] = 0. ; /* BETA for *syrk, *herk, and *gemm */ zero [1] = 0. ; /* Iwork must be of size 2n + 5*nsuper, allocated in the caller, * cholmod_super_numeric. The memory cannot be allocated here because the * cholmod_super_numeric initializes SuperMap, and cholmod_allocate_work * does not preserve existing workspace if the space needs to be increase * in size. */ /* allocate integer workspace */ Iwork = Common->Iwork ; SuperMap = Iwork ; /* size n (i/i/l) */ RelativeMap = Iwork + n ; /* size n (i/i/l) */ Next = Iwork + 2*((size_t) n) ; /* size nsuper*/ Lpos = Iwork + 2*((size_t) n) + nsuper ; /* size nsuper*/ Next_save = Iwork + 2*((size_t) n) + 2*((size_t) nsuper) ;/* size nsuper*/ Lpos_save = Iwork + 2*((size_t) n) + 3*((size_t) nsuper) ;/* size nsuper*/ Previous = Iwork + 2*((size_t) n) + 4*((size_t) nsuper) ;/* size nsuper*/ Map = Common->Flag ; /* size n, use Flag as workspace for Map array */ Head = Common->Head ; /* size n+1, only Head [0..nsuper-1] used */ Ls = L->s ; Lpi = L->pi ; Lpx = L->px ; Super = L->super ; Lx = L->x ; #ifdef GPU_BLAS /* local copy of useGPU */ if ( (Common->useGPU == 1) && L->useGPU) { /* Initialize the GPU. If not found, don't use it. */ useGPU = TEMPLATE2 (CHOLMOD (gpu_init)) (C, L, Common, nsuper, n, Lpi[nsuper]-Lpi[0], gpu_p) ; } else { useGPU = 0; } /* fprintf (stderr, "local useGPU %d\n", useGPU) ; */ #endif #ifndef NTIMER /* clear GPU / CPU statistics */ Common->CHOLMOD_CPU_GEMM_CALLS = 0 ; Common->CHOLMOD_CPU_SYRK_CALLS = 0 ; Common->CHOLMOD_CPU_TRSM_CALLS = 0 ; Common->CHOLMOD_CPU_POTRF_CALLS = 0 ; Common->CHOLMOD_GPU_GEMM_CALLS = 0 ; Common->CHOLMOD_GPU_SYRK_CALLS = 0 ; Common->CHOLMOD_GPU_TRSM_CALLS = 0 ; Common->CHOLMOD_GPU_POTRF_CALLS = 0 ; Common->CHOLMOD_CPU_GEMM_TIME = 0 ; Common->CHOLMOD_CPU_SYRK_TIME = 0 ; Common->CHOLMOD_CPU_TRSM_TIME = 0 ; Common->CHOLMOD_CPU_POTRF_TIME = 0 ; Common->CHOLMOD_GPU_GEMM_TIME = 0 ; Common->CHOLMOD_GPU_SYRK_TIME = 0 ; Common->CHOLMOD_GPU_TRSM_TIME = 0 ; Common->CHOLMOD_GPU_POTRF_TIME = 0 ; Common->CHOLMOD_ASSEMBLE_TIME = 0 ; Common->CHOLMOD_ASSEMBLE_TIME2 = 0 ; #endif stype = A->stype ; if (stype != 0) { /* F not accessed */ Fp = NULL ; Fi = NULL ; Fx = NULL ; Fz = NULL ; Fnz = NULL ; Fpacked = TRUE ; } else { Fp = F->p ; Fi = F->i ; Fx = F->x ; Fz = F->z ; Fnz = F->nz ; Fpacked = F->packed ; } Ap = A->p ; Ai = A->i ; Ax = A->x ; Az = A->z ; Anz = A->nz ; Apacked = A->packed ; /* clear the Map so that changes in the pattern of A can be detected */ #pragma omp parallel for num_threads(CHOLMOD_OMP_NUM_THREADS) \ if ( n > 128 ) schedule (static) for (i = 0 ; i < n ; i++) { Map [i] = EMPTY ; } /* If the matrix is not positive definite, the supernode s containing the * first zero or negative diagonal entry of L is repeated (but factorized * only up to just before the problematic diagonal entry). The purpose is * to provide MATLAB with [R,p]=chol(A); columns 1 to p-1 of L=R' are * required, where L(p,p) is the problematic diagonal entry. The * repeat_supernode flag tells us whether this is the repeated supernode. * Once supernode s is repeated, the factorization is terminated. */ repeat_supernode = FALSE ; #ifdef GPU_BLAS if ( useGPU ) { /* Case of GPU, zero all supernodes at one time for better performance*/ TEMPLATE2 (CHOLMOD (gpu_clear_memory))(Lx, L->xsize, CHOLMOD_OMP_NUM_THREADS); } #endif /* ---------------------------------------------------------------------- */ /* supernodal numerical factorization */ /* ---------------------------------------------------------------------- */ for (s = 0 ; s < nsuper ; s++) { /* ------------------------------------------------------------------ */ /* get the size of supernode s */ /* ------------------------------------------------------------------ */ k1 = Super [s] ; /* s contains columns k1 to k2-1 of L */ k2 = Super [s+1] ; nscol = k2 - k1 ; /* # of columns in all of s */ psi = Lpi [s] ; /* pointer to first row of s in Ls */ psx = Lpx [s] ; /* pointer to first row of s in Lx */ psend = Lpi [s+1] ; /* pointer just past last row of s in Ls */ nsrow = psend - psi ; /* # of rows in all of s */ PRINT1 (("====================================================\n" "S "ID" k1 "ID" k2 "ID" nsrow "ID" nscol "ID" psi "ID" psend " ""ID" psx "ID"\n", s, k1, k2, nsrow, nscol, psi, psend, psx)) ; /* ------------------------------------------------------------------ */ /* zero the supernode s */ /* ------------------------------------------------------------------ */ ASSERT ((size_t) (psx + nsrow*nscol) <= L->xsize) ; pend = psx + nsrow * nscol ; /* s is nsrow-by-nscol */ #ifdef GPU_BLAS if ( !useGPU ) #endif { /* Case of no GPU, zero individual supernodes */ #pragma omp parallel for num_threads(CHOLMOD_OMP_NUM_THREADS) \ schedule (static) if ( pend - psx > 1024 ) for (p = psx ; p < pend ; p++) { L_CLEAR (Lx,p); } } /* ------------------------------------------------------------------ */ /* construct the scattered Map for supernode s */ /* ------------------------------------------------------------------ */ /* If row i is the kth row in s, then Map [i] = k. Similarly, if * column j is the kth column in s, then Map [j] = k. */ #pragma omp parallel for num_threads(CHOLMOD_OMP_NUM_THREADS) \ if ( nsrow > 128 ) for (k = 0 ; k < nsrow ; k++) { PRINT1 ((" "ID" map "ID"\n", Ls [psi+k], k)) ; Map [Ls [psi + k]] = k ; } /* ------------------------------------------------------------------ */ /* when using GPU, reorder supernodes by levels.*/ /* (all supernodes in a level are independent) */ /* ------------------------------------------------------------------ */ #ifdef GPU_BLAS if ( useGPU ) { TEMPLATE2 (CHOLMOD (gpu_reorder_descendants)) ( Common, Super, &s, Lpi, Lpos, Head, Next, Previous, &ndescendants, &tail, &mapCreatedOnGpu, gpu_p ) ; } #endif /* ------------------------------------------------------------------ */ /* copy matrix into supernode s (lower triangular part only) */ /* ------------------------------------------------------------------ */ pk = psx ; #pragma omp parallel for private ( p, pend, pfend, pf, i, j, imap, q ) \ num_threads(CHOLMOD_OMP_NUM_THREADS) if ( k2-k1 > 64 ) for (k = k1 ; k < k2 ; k++) { if (stype != 0) { /* copy the kth column of A into the supernode */ p = Ap [k] ; pend = (Apacked) ? (Ap [k+1]) : (p + Anz [k]) ; for ( ; p < pend ; p++) { /* row i of L is located in row Map [i] of s */ i = Ai [p] ; if (i >= k) { /* This test is here simply to avoid a segfault. If * the test is false, the numeric factorization of A * is undefined. It does not detect all invalid * entries, only some of them (when debugging is * enabled, and Map is cleared after each step, then * all entries not in the pattern of L are detected). */ imap = Map [i] ; if (imap >= 0 && imap < nsrow) { /* Lx [Map [i] + pk] = Ax [p] ; */ L_ASSIGN (Lx,(imap+(psx+(k-k1)*nsrow)), Ax,Az,p) ; } } } } else { double fjk[2]; /* copy the kth column of A*F into the supernode */ pf = Fp [k] ; pfend = (Fpacked) ? (Fp [k+1]) : (p + Fnz [k]) ; for ( ; pf < pfend ; pf++) { j = Fi [pf] ; /* fjk = Fx [pf] ; */ L_ASSIGN (fjk,0, Fx,Fz,pf) ; p = Ap [j] ; pend = (Apacked) ? (Ap [j+1]) : (p + Anz [j]) ; for ( ; p < pend ; p++) { i = Ai [p] ; if (i >= k) { /* See the discussion of imap above. */ imap = Map [i] ; if (imap >= 0 && imap < nsrow) { /* Lx [Map [i] + pk] += Ax [p] * fjk ; */ L_MULTADD (Lx,(imap+(psx+(k-k1)*nsrow)), Ax,Az,p, fjk) ; } } } } } } /* add beta to the diagonal of the supernode, if nonzero */ if (beta [0] != 0.0) { /* note that only the real part of beta is used */ pk = psx ; for (k = k1 ; k < k2 ; k++) { /* Lx [pk] += beta [0] ; */ L_ASSEMBLE (Lx,pk, beta) ; pk += nsrow + 1 ; /* advance to the next diagonal entry */ } } PRINT1 (("Supernode with just A: repeat: "ID"\n", repeat_supernode)) ; DEBUG (CHOLMOD(dump_super) (s, Super, Lpi, Ls, Lpx, Lx, L_ENTRY, Common)) ; PRINT1 (("\n\n")) ; /* ------------------------------------------------------------------ */ /* save/restore the list of supernodes */ /* ------------------------------------------------------------------ */ if (!repeat_supernode) { /* Save the list of pending descendants in case s is not positive * definite. Also save Lpos for each descendant d, so that we can * find which part of d is used to update s. */ for (d = Head [s] ; d != EMPTY ; d = Next [d]) { Lpos_save [d] = Lpos [d] ; Next_save [d] = Next [d] ; } } else { for (d = Head [s] ; d != EMPTY ; d = Next [d]) { Lpos [d] = Lpos_save [d] ; Next [d] = Next_save [d] ; } } /* ------------------------------------------------------------------ */ /* update supernode s with each pending descendant d */ /* ------------------------------------------------------------------ */ #ifndef NDEBUG for (d = Head [s] ; d != EMPTY ; d = Next [d]) { PRINT1 (("\nWill update "ID" with Child: "ID"\n", s, d)) ; DEBUG (CHOLMOD(dump_super) (d, Super, Lpi, Ls, Lpx, Lx, L_ENTRY, Common)) ; } PRINT1 (("\nNow factorizing supernode "ID":\n", s)) ; #endif #ifdef GPU_BLAS /* initialize the buffer counter */ if ( useGPU ) { Common->ibuffer = 0; supernodeUsedGPU = 0; idescendant = 0; d = Head[s]; dnext = d; dlarge = Next[d]; dsmall = tail; GPUavailable = 1; skips = 0; } else { dnext = Head[s]; } #else /* GPU module not installed */ dnext = Head[s]; #endif while #ifdef GPU_BLAS ( (!useGPU && (dnext != EMPTY)) || (useGPU && (idescendant < ndescendants))) #else ( dnext != EMPTY ) #endif { #ifdef GPU_BLAS if ( useGPU ) { /* Conditionally select the next descendant supernode to * assemble. * + first, select the largest descendant * + subsequently, if gpu host buffers are available, select * the largest remaining descendant for assembly on the GPU * + otherwise select the smallest remaining descendant for * assembly on the CPU * * The objective is to keep the GPU busy assembling the largest * descendants, and simultaneously keep the CPU busy assembling * the smallest descendants. * * As this is called for every descendent supernode, moving * this code to t_cholmod_gpu incurs substantial overhead - * ~20 GF/s on audikw_1 - so it is being left here. */ iHostBuff = (Common->ibuffer) % CHOLMOD_HOST_SUPERNODE_BUFFERS; cudaError_t cuErr; if ( idescendant > 0 ) { if ( GPUavailable == -1 || skips > 0) { d = dsmall; dsmall = Previous[dsmall]; skips--; } else { cuErr = cudaEventQuery ( Common->updateCBuffersFree[iHostBuff] ); if ( cuErr == cudaSuccess ) { /* buffers are available, so assemble a large * descendant (anticipating that this will be * assembled on the GPU) */ d = dlarge; dlarge = Next[dlarge]; GPUavailable = 1; skips = 0; } else { /* buffers are not available, so the GPU is busy, * so assemble a small descendant (anticipating * that it will be assembled on the host) */ d = dsmall; dsmall = Previous[dsmall]; GPUavailable = 0; /* if the GPUs are busy, then do this many * supernodes on the CPU before querying GPUs * again. */ skips = CHOLMOD_GPU_SKIP; } } } idescendant++; } else { d = dnext; } #else /* GPU module not installed at compile time */ d = dnext ; #endif /* -------------------------------------------------------------- */ /* get the size of supernode d */ /* -------------------------------------------------------------- */ kd1 = Super [d] ; /* d contains cols kd1 to kd2-1 of L */ kd2 = Super [d+1] ; ndcol = kd2 - kd1 ; /* # of columns in all of d */ pdi = Lpi [d] ; /* pointer to first row of d in Ls */ pdx = Lpx [d] ; /* pointer to first row of d in Lx */ pdend = Lpi [d+1] ; /* pointer just past last row of d in Ls */ ndrow = pdend - pdi ; /* # rows in all of d */ PRINT1 (("Child: ")) ; DEBUG (CHOLMOD(dump_super) (d, Super, Lpi, Ls, Lpx, Lx, L_ENTRY, Common)) ; /* -------------------------------------------------------------- */ /* find the range of rows of d that affect rows k1 to k2-1 of s */ /* -------------------------------------------------------------- */ p = Lpos [d] ; /* offset of 1st row of d affecting s */ pdi1 = pdi + p ; /* ptr to 1st row of d affecting s in Ls */ pdx1 = pdx + p ; /* ptr to 1st row of d affecting s in Lx */ /* there must be at least one row remaining in d to update s */ ASSERT (pdi1 < pdend) ; PRINT1 (("Lpos[d] "ID" pdi1 "ID" Ls[pdi1] "ID"\n", Lpos[d], pdi1, Ls [pdi1])) ; ASSERT (Ls [pdi1] >= k1 && Ls [pdi1] < k2) ; for (pdi2 = pdi1 ; pdi2 < pdend && Ls [pdi2] < k2 ; pdi2++) ; ndrow1 = pdi2 - pdi1 ; /* # rows in first part of d */ ndrow2 = pdend - pdi1 ; /* # rows in remaining d */ /* rows Ls [pdi1 ... pdi2-1] are in the range k1 to k2-1. Since d * affects s, this set cannot be empty. */ ASSERT (pdi1 < pdi2 && pdi2 <= pdend) ; PRINT1 (("ndrow1 "ID" ndrow2 "ID"\n", ndrow1, ndrow2)) ; DEBUG (for (p = pdi1 ; p < pdi2 ; p++) PRINT1 (("Ls["ID"] "ID"\n", p, Ls[p]))) ; /* -------------------------------------------------------------- */ /* construct the update matrix C for this supernode d */ /* -------------------------------------------------------------- */ /* C = L (k1:n-1, kd1:kd2-1) * L (k1:k2-1, kd1:kd2-1)', except * that k1:n-1 refers to all of the rows in L, but many of the * rows are all zero. Supernode d holds columns kd1 to kd2-1 of L. * Nonzero rows in the range k1:k2-1 are in the list * Ls [pdi1 ... pdi2-1], of size ndrow1. Nonzero rows in the range * k2:n-1 are in the list Ls [pdi2 ... pdend], of size ndrow2. Let * L1 = L (Ls [pdi1 ... pdi2-1], kd1:kd2-1), and let * L2 = L (Ls [pdi2 ... pdend], kd1:kd2-1). C is ndrow2-by-ndrow1. * Let C1 be the first ndrow1 rows of C and let C2 be the last * ndrow2-ndrow1 rows of C. Only the lower triangular part of C1 * needs to be computed since C1 is symmetric. */ /* maxcsize is the largest size of C for all pairs (d,s) */ ASSERT (ndrow2 * ndrow1 <= ((Int) L->maxcsize)) ; /* compute leading ndrow1-by-ndrow1 lower triangular block of C, * C1 = L1*L1' */ ndrow3 = ndrow2 - ndrow1 ; /* number of rows of C2 */ ASSERT (ndrow3 >= 0) ; #ifdef GPU_BLAS if ( useGPU ) { /* set up GPU to assemble new supernode */ if ( GPUavailable == 1) { if ( ndrow2 * L_ENTRY >= CHOLMOD_ND_ROW_LIMIT && ndcol * L_ENTRY >= CHOLMOD_ND_COL_LIMIT ) { if ( ! mapCreatedOnGpu ) { TEMPLATE2 ( CHOLMOD (gpu_initialize_supernode)) ( Common, nscol, nsrow, psi, gpu_p ); mapCreatedOnGpu = 1; } } else { /* we've reached the limit of GPU-eligible descendants * flag to stop stop performing cudaEventQueries */ GPUavailable = -1; } } } #endif #ifdef GPU_BLAS if ( !useGPU || GPUavailable!=1 || !TEMPLATE2 (CHOLMOD (gpu_updateC)) (ndrow1, ndrow2, ndrow, ndcol, nsrow, pdx1, pdi1, Lx, C, Common, gpu_p)) #endif { /* GPU not installed, or not used */ #ifndef NTIMER Common->CHOLMOD_CPU_SYRK_CALLS++ ; tstart = SuiteSparse_time () ; #endif #ifdef REAL BLAS_dsyrk ("L", "N", ndrow1, ndcol, /* N, K: L1 is ndrow1-by-ndcol*/ one, /* ALPHA: 1 */ Lx + L_ENTRY*pdx1, ndrow, /* A, LDA: L1, ndrow */ zero, /* BETA: 0 */ C, ndrow2) ; /* C, LDC: C1 */ #else BLAS_zherk ("L", "N", ndrow1, ndcol, /* N, K: L1 is ndrow1-by-ndcol*/ one, /* ALPHA: 1 */ Lx + L_ENTRY*pdx1, ndrow, /* A, LDA: L1, ndrow */ zero, /* BETA: 0 */ C, ndrow2) ; /* C, LDC: C1 */ #endif #ifndef NTIMER Common->CHOLMOD_CPU_SYRK_TIME += SuiteSparse_time () - tstart ; #endif /* compute remaining (ndrow2-ndrow1)-by-ndrow1 block of C, * C2 = L2*L1' */ if (ndrow3 > 0) { #ifndef NTIMER Common->CHOLMOD_CPU_GEMM_CALLS++ ; tstart = SuiteSparse_time () ; #endif #ifdef REAL BLAS_dgemm ("N", "C", ndrow3, ndrow1, ndcol, /* M, N, K */ one, /* ALPHA: 1 */ Lx + L_ENTRY*(pdx1 + ndrow1), /* A, LDA: L2 */ ndrow, /* ndrow */ Lx + L_ENTRY*pdx1, /* B, LDB: L1 */ ndrow, /* ndrow */ zero, /* BETA: 0 */ C + L_ENTRY*ndrow1, /* C, LDC: C2 */ ndrow2) ; #else BLAS_zgemm ("N", "C", ndrow3, ndrow1, ndcol, /* M, N, K */ one, /* ALPHA: 1 */ Lx + L_ENTRY*(pdx1 + ndrow1), /* A, LDA: L2 */ ndrow, /* ndrow */ Lx + L_ENTRY*pdx1, /* B, LDB: L1, ndrow */ ndrow, zero, /* BETA: 0 */ C + L_ENTRY*ndrow1, /* C, LDC: C2 */ ndrow2) ; #endif #ifndef NTIMER Common->CHOLMOD_CPU_GEMM_TIME += SuiteSparse_time () - tstart ; #endif } /* ---------------------------------------------------------- */ /* construct relative map to assemble d into s */ /* ---------------------------------------------------------- */ DEBUG (CHOLMOD(dump_real) ("C", C, ndrow2, ndrow1, TRUE, L_ENTRY, Common)) ; #pragma omp parallel for num_threads(CHOLMOD_OMP_NUM_THREADS) \ if ( ndrow2 > 64 ) for (i = 0 ; i < ndrow2 ; i++) { RelativeMap [i] = Map [Ls [pdi1 + i]] ; ASSERT (RelativeMap [i] >= 0 && RelativeMap [i] < nsrow) ; } /* ---------------------------------------------------------- */ /* assemble C into supernode s using the relative map */ /* ---------------------------------------------------------- */ #pragma omp parallel for private ( j, i, px, q ) \ num_threads(CHOLMOD_OMP_NUM_THREADS) if (ndrow1 > 64 ) for (j = 0 ; j < ndrow1 ; j++) /* cols k1:k2-1 */ { ASSERT (RelativeMap [j] == Map [Ls [pdi1 + j]]) ; ASSERT (RelativeMap [j] >= 0 && RelativeMap [j] < nscol) ; px = psx + RelativeMap [j] * nsrow ; for (i = j ; i < ndrow2 ; i++) /* rows k1:n-1 */ { ASSERT (RelativeMap [i] == Map [Ls [pdi1 + i]]) ; ASSERT (RelativeMap [i] >= j && RelativeMap[i] < nsrow); /* Lx [px + RelativeMap [i]] -= C [i + pj] ; */ q = px + RelativeMap [i] ; L_ASSEMBLESUB (Lx,q, C, i+ndrow2*j) ; } } } #ifdef GPU_BLAS else { supernodeUsedGPU = 1; /* GPU was used for this supernode*/ Common->ibuffer++; /* gpu_updateC is asynchronous, so use * the next host buffer for the next * supernode */ Common->ibuffer = Common->ibuffer% (CHOLMOD_HOST_SUPERNODE_BUFFERS*CHOLMOD_DEVICE_STREAMS); } #endif /* -------------------------------------------------------------- */ /* prepare this supernode d for its next ancestor */ /* -------------------------------------------------------------- */ dnext = Next [d] ; if (!repeat_supernode) { /* If node s is being repeated, Head [dancestor] has already * been cleared (set to EMPTY). It must remain EMPTY. The * dancestor will not be factorized since the factorization * terminates at node s. */ Lpos [d] = pdi2 - pdi ; if (Lpos [d] < ndrow) { dancestor = SuperMap [Ls [pdi2]] ; ASSERT (dancestor > s && dancestor < nsuper) ; /* place d in the link list of its next ancestor */ Next [d] = Head [dancestor] ; Head [dancestor] = d ; } } } /* end of descendant supernode loop */ #ifdef GPU_BLAS if ( useGPU ) { iHostBuff = (Common->ibuffer)%CHOLMOD_HOST_SUPERNODE_BUFFERS; iDevBuff = (Common->ibuffer)%CHOLMOD_DEVICE_STREAMS; /* combine updates assembled on the GPU with updates * assembled on the CPU */ TEMPLATE2 ( CHOLMOD (gpu_final_assembly )) ( Common, Lx, psx, nscol, nsrow, supernodeUsedGPU, &iHostBuff, &iDevBuff, gpu_p ); } #endif PRINT1 (("\nSupernode with contributions A: repeat: "ID"\n", repeat_supernode)) ; DEBUG (CHOLMOD(dump_super) (s, Super, Lpi, Ls, Lpx, Lx, L_ENTRY, Common)) ; PRINT1 (("\n\n")) ; /* ------------------------------------------------------------------ */ /* factorize diagonal block of supernode s in LL' */ /* ------------------------------------------------------------------ */ /* The current supernode s is ready to factorize. It has been updated * by all descendant supernodes. Let S = the current supernode, which * holds rows k1:n-1 and columns k1:k2-1 of the updated matrix. It * splits into two parts: the square diagonal block S1, and the * rectangular part S2. Here, S1 is factorized into L1*L1' and * overwritten by L1. * * If supernode s is being repeated, only factorize it up to but not * including the column containing the problematic entry. */ nscol2 = (repeat_supernode) ? (nscol_new) : (nscol) ; #ifdef GPU_BLAS if ( !useGPU || !supernodeUsedGPU || !TEMPLATE2 (CHOLMOD (gpu_lower_potrf))(nscol2, nsrow, psx, Lx, &info, Common, gpu_p)) #endif { /* Note that the GPU will not be used for the triangular solve */ #ifdef GPU_BLAS supernodeUsedGPU = 0; #endif #ifndef NTIMER Common->CHOLMOD_CPU_POTRF_CALLS++ ; tstart = SuiteSparse_time () ; #endif #ifdef REAL LAPACK_dpotrf ("L", nscol2, /* N: nscol2 */ Lx + L_ENTRY*psx, nsrow, /* A, LDA: S1, nsrow */ info) ; /* INFO */ #else LAPACK_zpotrf ("L", nscol2, /* N: nscol2 */ Lx + L_ENTRY*psx, nsrow, /* A, LDA: S1, nsrow */ info) ; /* INFO */ #endif #ifndef NTIMER Common->CHOLMOD_CPU_POTRF_TIME += SuiteSparse_time ()- tstart ; #endif } /* ------------------------------------------------------------------ */ /* check if the matrix is not positive definite */ /* ------------------------------------------------------------------ */ if (repeat_supernode) { /* the leading part has been refactorized; it must have succeeded */ info = 0 ; /* zero out the rest of this supernode */ p = psx + nsrow * nscol_new ; pend = psx + nsrow * nscol ; /* s is nsrow-by-nscol */ for ( ; p < pend ; p++) { /* Lx [p] = 0 ; */ L_CLEAR (Lx,p) ; } } /* info is set to one in LAPACK_*potrf if blas_ok is FALSE. It is * set to zero in dpotrf/zpotrf if the factorization was successful. */ if (CHECK_BLAS_INT && !Common->blas_ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large for the BLAS") ; } if (info != 0) { /* Matrix is not positive definite. dpotrf/zpotrf do NOT report an * error if the diagonal of L has NaN's, only if it has a zero. */ if (Common->status == CHOLMOD_OK) { ERROR (CHOLMOD_NOT_POSDEF, "matrix not positive definite") ; } /* L->minor is the column of L that contains a zero or negative * diagonal term. */ L->minor = k1 + info - 1 ; /* clear the link lists of all subsequent supernodes */ for (ss = s+1 ; ss < nsuper ; ss++) { Head [ss] = EMPTY ; } /* zero this supernode, and all remaining supernodes */ pend = L->xsize ; for (p = psx ; p < pend ; p++) { /* Lx [p] = 0. ; */ L_CLEAR (Lx,p) ; } /* If L is indefinite, it still contains useful information. * Supernodes 0 to s-1 are valid, similar to MATLAB [R,p]=chol(A), * where the 1-based p is identical to the 0-based L->minor. Since * L->minor is in the current supernode s, it and any columns to the * left of it in supernode s are also all zero. This differs from * [R,p]=chol(A), which contains nonzero rows 1 to p-1. Fix this * by setting repeat_supernode to TRUE, and repeating supernode s. * * If Common->quick_return_if_not_posdef is true, then the entire * supernode s is not factorized; it is left as all zero. */ if (info == 1 || Common->quick_return_if_not_posdef) { /* If the first column of supernode s contains a zero or * negative diagonal entry, then it is already properly set to * zero. Also, info will be 1 if integer overflow occured in * the BLAS. */ Head [s] = EMPTY ; #ifdef GPU_BLAS if ( useGPU ) { CHOLMOD (gpu_end) (Common) ; } #endif return (Common->status >= CHOLMOD_OK) ; } else { /* Repeat supernode s, but only factorize it up to but not * including the column containing the problematic diagonal * entry. */ repeat_supernode = TRUE ; s-- ; nscol_new = info - 1 ; continue ; } } /* ------------------------------------------------------------------ */ /* compute the subdiagonal block and prepare supernode for its parent */ /* ------------------------------------------------------------------ */ nsrow2 = nsrow - nscol2 ; if (nsrow2 > 0) { /* The current supernode is columns k1 to k2-1 of L. Let L1 be the * diagonal block (factorized by dpotrf/zpotrf above; rows/cols * k1:k2-1), and L2 be rows k2:n-1 and columns k1:k2-1 of L. The * triangular system to solve is L2*L1' = S2, where S2 is * overwritten with L2. More precisely, L2 = S2 / L1' in MATLAB * notation. */ #ifdef GPU_BLAS if ( !useGPU || !supernodeUsedGPU || !TEMPLATE2 (CHOLMOD(gpu_triangular_solve)) (nsrow2, nscol2, nsrow, psx, Lx, Common, gpu_p)) #endif { #ifndef NTIMER Common->CHOLMOD_CPU_TRSM_CALLS++ ; tstart = SuiteSparse_time () ; #endif #ifdef REAL BLAS_dtrsm ("R", "L", "C", "N", nsrow2, nscol2, /* M, N */ one, /* ALPHA: 1 */ Lx + L_ENTRY*psx, nsrow, /* A, LDA: L1, nsrow */ Lx + L_ENTRY*(psx + nscol2), /* B, LDB, L2, nsrow */ nsrow) ; #else BLAS_ztrsm ("R", "L", "C", "N", nsrow2, nscol2, /* M, N */ one, /* ALPHA: 1 */ Lx + L_ENTRY*psx, nsrow, /* A, LDA: L1, nsrow */ Lx + L_ENTRY*(psx + nscol2), /* B, LDB, L2, nsrow */ nsrow) ; #endif #ifndef NTIMER Common->CHOLMOD_CPU_TRSM_TIME += SuiteSparse_time () - tstart ; #endif } if (CHECK_BLAS_INT && !Common->blas_ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large for the BLAS") ; } if (!repeat_supernode) { /* Lpos [s] is offset of first row of s affecting its parent */ Lpos [s] = nscol ; sparent = SuperMap [Ls [psi + nscol]] ; ASSERT (sparent != EMPTY) ; ASSERT (Ls [psi + nscol] >= Super [sparent]) ; ASSERT (Ls [psi + nscol] < Super [sparent+1]) ; ASSERT (SuperMap [Ls [psi + nscol]] == sparent) ; ASSERT (sparent > s && sparent < nsuper) ; /* place s in link list of its parent */ Next [s] = Head [sparent] ; Head [sparent] = s ; } } else { #ifdef GPU_BLAS TEMPLATE2 ( CHOLMOD (gpu_copy_supernode) ) ( Common, Lx, psx, nscol, nscol2, nsrow, supernodeUsedGPU, iHostBuff, gpu_p); #endif } Head [s] = EMPTY ; /* link list for supernode s no longer needed */ /* clear the Map (debugging only, to detect changes in pattern of A) */ DEBUG (for (k = 0 ; k < nsrow ; k++) Map [Ls [psi + k]] = EMPTY) ; DEBUG (CHOLMOD(dump_super) (s, Super, Lpi, Ls, Lpx, Lx, L_ENTRY, Common)) ; if (repeat_supernode) { /* matrix is not positive definite; finished clean-up for supernode * containing negative diagonal */ #ifdef GPU_BLAS if ( useGPU ) { CHOLMOD (gpu_end) (Common) ; } #endif return (Common->status >= CHOLMOD_OK) ; } } /* success; matrix is positive definite */ L->minor = n ; #ifdef GPU_BLAS if ( useGPU ) { CHOLMOD (gpu_end) (Common) ; } #endif return (Common->status >= CHOLMOD_OK) ; } #undef PATTERN #undef REAL #undef COMPLEX #undef ZOMPLEX ����������Matrix/src/CHOLMOD/Supernodal/License.txt�����������������������������������������������������������0000644�0001762�0000144�00000002031�11770402705�017630� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CHOLMOD/Supernodal Module. Copyright (C) 2005-2006, Timothy A. Davis CHOLMOD is also available under other licenses; contact authors for details. http://www.suitesparse.com Note that this license is for the CHOLMOD/Supernodal module only. All CHOLMOD modules are licensed separately. -------------------------------------------------------------------------------- This Module 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 2 of the License, or (at your option) any later version. This Module 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 Module; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Supernodal/cholmod_super_solve.c�������������������������������������������������0000644�0001762�0000144�00000015371�13652535054�021744� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Supernodal/cholmod_super_solve ======================================= */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Supernodal Module. Copyright (C) 2005-2006, Timothy A. Davis * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* Solve Lx=b or L'x=b for a supernodal factorization. These routines do not * apply the permutation L->Perm. See cholmod_solve for a more general * interface that performs that operation. */ #ifndef NGPL #ifndef NSUPERNODAL #include "cholmod_internal.h" #include "cholmod_supernodal.h" /* ========================================================================== */ /* === TEMPLATE ============================================================= */ /* ========================================================================== */ #define REAL #include "t_cholmod_super_solve.c" #define COMPLEX #include "t_cholmod_super_solve.c" /* ========================================================================== */ /* === cholmod_super_lsolve ================================================= */ /* ========================================================================== */ /* Solve Lx=b where x and b are of size n-by-nrhs. b is overwritten by the * solution x. On input, b is stored in col-major order with leading dimension * of d, and on output x is stored in the same manner. * * The contents of the workspace E are undefined on both input and output. * * workspace: none */ int CHOLMOD(super_lsolve) /* TRUE if OK, FALSE if BLAS overflow occured */ ( /* ---- input ---- */ cholmod_factor *L, /* factor to use for the forward solve */ /* ---- output ---- */ cholmod_dense *X, /* b on input, solution to Lx=b on output */ /* ---- workspace ---- */ cholmod_dense *E, /* workspace of size nrhs*(L->maxesize) */ /* --------------- */ cholmod_common *Common ) { /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (L, FALSE) ; RETURN_IF_NULL (X, FALSE) ; RETURN_IF_NULL (E, FALSE) ; RETURN_IF_XTYPE_INVALID (L, CHOLMOD_REAL, CHOLMOD_COMPLEX, FALSE) ; RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_COMPLEX, FALSE) ; RETURN_IF_XTYPE_INVALID (E, CHOLMOD_REAL, CHOLMOD_COMPLEX, FALSE) ; if (L->xtype != X->xtype) { ERROR (CHOLMOD_INVALID, "L and X must have the same xtype") ; return (FALSE) ; } if (L->xtype != E->xtype) { ERROR (CHOLMOD_INVALID, "L and E must have the same xtype") ; return (FALSE) ; } if (X->d < X->nrow || L->n != X->nrow) { ERROR (CHOLMOD_INVALID, "X and L dimensions must match") ; return (FALSE) ; } if (E->nzmax < X->ncol * (L->maxesize)) { ERROR (CHOLMOD_INVALID, "workspace E not large enough") ; return (FALSE) ; } if (!(L->is_ll) || !(L->is_super)) { ERROR (CHOLMOD_INVALID, "L not supernodal") ; return (FALSE) ; } Common->status = CHOLMOD_OK ; ASSERT (IMPLIES (L->n == 0, L->nsuper == 0)) ; if (L->n == 0 || X->ncol == 0) { /* nothing to do */ return (TRUE) ; } /* ---------------------------------------------------------------------- */ /* solve Lx=b using template routine */ /* ---------------------------------------------------------------------- */ switch (L->xtype) { case CHOLMOD_REAL: r_cholmod_super_lsolve (L, X, E, Common) ; break ; case CHOLMOD_COMPLEX: c_cholmod_super_lsolve (L, X, E, Common) ; break ; } if (CHECK_BLAS_INT && !Common->blas_ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large for the BLAS") ; } return (Common->blas_ok) ; } /* ========================================================================== */ /* === cholmod_super_ltsolve ================================================ */ /* ========================================================================== */ /* Solve L'x=b where x and b are of size n-by-nrhs. b is overwritten by the * solution x. On input, b is stored in col-major order with leading dimension * of d, and on output x is stored in the same manner. * * The contents of the workspace E are undefined on both input and output. * * workspace: none */ int CHOLMOD(super_ltsolve) /* TRUE if OK, FALSE if BLAS overflow occured */ ( /* ---- input ---- */ cholmod_factor *L, /* factor to use for the backsolve */ /* ---- output ---- */ cholmod_dense *X, /* b on input, solution to L'x=b on output */ /* ---- workspace ---- */ cholmod_dense *E, /* workspace of size nrhs*(L->maxesize) */ /* --------------- */ cholmod_common *Common ) { /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (L, FALSE) ; RETURN_IF_NULL (X, FALSE) ; RETURN_IF_NULL (E, FALSE) ; RETURN_IF_XTYPE_INVALID (L, CHOLMOD_REAL, CHOLMOD_COMPLEX, FALSE) ; RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_COMPLEX, FALSE) ; RETURN_IF_XTYPE_INVALID (E, CHOLMOD_REAL, CHOLMOD_COMPLEX, FALSE) ; if (L->xtype != X->xtype) { ERROR (CHOLMOD_INVALID, "L and X must have the same xtype") ; return (FALSE) ; } if (L->xtype != E->xtype) { ERROR (CHOLMOD_INVALID, "L and E must have the same xtype") ; return (FALSE) ; } if (X->d < X->nrow || L->n != X->nrow) { ERROR (CHOLMOD_INVALID, "X and L dimensions must match") ; return (FALSE) ; } if (E->nzmax < X->ncol * (L->maxesize)) { ERROR (CHOLMOD_INVALID, "workspace E not large enough") ; return (FALSE) ; } if (!(L->is_ll) || !(L->is_super)) { ERROR (CHOLMOD_INVALID, "L not supernodal") ; return (FALSE) ; } Common->status = CHOLMOD_OK ; ASSERT (IMPLIES (L->n == 0, L->nsuper == 0)) ; if (L->n == 0 || X->ncol == 0) { /* nothing to do */ return (TRUE) ; } /* ---------------------------------------------------------------------- */ /* solve Lx=b using template routine */ /* ---------------------------------------------------------------------- */ switch (L->xtype) { case CHOLMOD_REAL: r_cholmod_super_ltsolve (L, X, E, Common) ; break ; case CHOLMOD_COMPLEX: c_cholmod_super_ltsolve (L, X, E, Common) ; break ; } if (CHECK_BLAS_INT && !Common->blas_ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large for the BLAS") ; } return (Common->blas_ok) ; } #endif #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Supernodal/t_cholmod_gpu.c�������������������������������������������������������0000644�0001762�0000144�00000103746�12215610421�020502� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Supernodal/t_cholmod_gpu ============================================= */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Supernodal Module. Copyright (C) 2005-2012, Timothy A. Davis * The CHOLMOD/Supernodal Module is licensed under Version 2.0 of the GNU * General Public License. See gpl.txt for a text of the license. * CHOLMOD is also available under other licenses; contact authors for details. * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* GPU BLAS template routine for cholmod_super_numeric. */ /* ========================================================================== */ /* === include files and definitions ======================================== */ /* ========================================================================== */ #include "cholmod_template.h" #undef L_ENTRY #ifdef REAL #define L_ENTRY 1 #else #define L_ENTRY 2 #endif /* #define GPU_Printf printf */ #define GPU_Printf #define PAGE_SIZE (4*1024) #define OK(cuda_operation) ((cuda_operation) == cudaSuccess) /* ========================================================================== */ /* === gpu_init ============================================================= */ /* ========================================================================== */ void TEMPLATE (CHOLMOD (gpu_init)) ( void *Cwork, Int maxSize, cholmod_common *Common ) { Int i ; cublasStatus_t cublasError ; cudaError_t cudaErr ; size_t maxBytesSize, HostPinnedSize ; Common->GemmUsed = 0 ; GPU_Printf ("gpu_init : %p\n", (void *) ((size_t) Cwork & ~(PAGE_SIZE-1))) ; if (!(Common->cublasHandle)) { /* ------------------------------------------------------------------ */ /* create the CUDA BLAS handle */ /* ------------------------------------------------------------------ */ cublasError = cublasCreate (&(Common->cublasHandle)) ; if (cublasError != CUBLAS_STATUS_SUCCESS) { ERROR (CHOLMOD_GPU_PROBLEM, "CUBLAS initialization") ; return ; } /* ------------------------------------------------------------------ */ /* create each CUDA stream */ /* ------------------------------------------------------------------ */ cudaErr = cudaStreamCreate (&(Common->cudaStreamSyrk)) ; if (cudaErr != cudaSuccess) { ERROR (CHOLMOD_GPU_PROBLEM, "CUDA stream initialization") ; return ; } cudaErr = cudaStreamCreate (&(Common->cudaStreamGemm)) ; if (cudaErr != cudaSuccess) { ERROR (CHOLMOD_GPU_PROBLEM, "CUDA stream initialization") ; return ; } cudaErr = cudaStreamCreate (&(Common->cudaStreamTrsm)) ; if (cudaErr != cudaSuccess) { ERROR (CHOLMOD_GPU_PROBLEM, "CUDA stream initialization") ; return ; } for (i = 0 ; i < 3 ; i++) { cudaErr = cudaStreamCreate (&(Common->cudaStreamPotrf [i])) ; if (cudaErr != cudaSuccess) { ERROR (CHOLMOD_GPU_PROBLEM, "CUDA stream initialization") ; return ; } } /* ------------------------------------------------------------------ */ /* create each CUDA event */ /* ------------------------------------------------------------------ */ for (i = 0 ; i < 2 ; i++) { cudaErr = cudaEventCreateWithFlags (&(Common->cublasEventPotrf [i]), cudaEventDisableTiming) ; if (cudaErr != cudaSuccess) { ERROR (CHOLMOD_GPU_PROBLEM, "CUDA event") ; return ; } } } /* ---------------------------------------------------------------------- */ /* pin the Host memory */ /* ---------------------------------------------------------------------- */ Common->HostPinnedMemory = (void *) ((size_t) Cwork & ~(PAGE_SIZE-1)) ; maxBytesSize = sizeof (double)*L_ENTRY*maxSize ; /* Align on a 4K page boundary (it is no more necessary in 4.1 */ HostPinnedSize = (((size_t) Cwork + maxBytesSize + PAGE_SIZE-1) & ~(PAGE_SIZE-1)) - (size_t) (Common->HostPinnedMemory) ; GPU_Printf ("gpu HostPinnedSize: %g %p\n", (double) HostPinnedSize, Common->HostPinnedMemory) ; cudaErr = cudaHostRegister (Common->HostPinnedMemory, HostPinnedSize, 0) ; if (cudaErr != cudaSuccess) { ERROR (CHOLMOD_GPU_PROBLEM, "CUDA Pinning Memory") ; Common->HostPinnedMemory = NULL ; } } /* ========================================================================== */ /* === gpu_end ============================================================== */ /* ========================================================================== */ void TEMPLATE (CHOLMOD (gpu_end)) ( cholmod_common *Common ) { int i; /* unpin the Host memory */ GPU_Printf ("gpu_end %p\n", Common->HostPinnedMemory) ; cudaError_t cudaErr = cudaHostUnregister (Common->HostPinnedMemory) ; if (cudaErr != cudaSuccess) { ERROR (CHOLMOD_GPU_PROBLEM, "CUDA Unpinning Memory") ; Common->HostPinnedMemory = NULL ; } /* ------------------------------------------------------------------ */ /* destroy Cublas Handle */ /* ------------------------------------------------------------------ */ if (Common->cublasHandle) { cublasDestroy(Common->cublasHandle); Common->cublasHandle = NULL ; } /* ------------------------------------------------------------------ */ /* destroy each CUDA stream */ /* ------------------------------------------------------------------ */ if (Common->cudaStreamSyrk) { cudaStreamDestroy (Common->cudaStreamSyrk) ; Common->cudaStreamSyrk = NULL ; } if (Common->cudaStreamGemm) { cudaStreamDestroy (Common->cudaStreamGemm) ; } if (Common->cudaStreamTrsm) { cudaStreamDestroy (Common->cudaStreamTrsm) ; Common->cudaStreamTrsm = NULL ; } for (i = 0 ; i < 3 ; i++) { if (Common->cudaStreamPotrf [i]) { cudaStreamDestroy(Common->cudaStreamPotrf [i]) ; Common->cudaStreamPotrf [i] = NULL ; } } /* ------------------------------------------------------------------ */ /* destroy each CUDA event */ /* ------------------------------------------------------------------ */ for (i = 0 ; i < 2 ; i++) { if (Common->cublasEventPotrf [i]) { cudaEventDestroy( Common->cublasEventPotrf [i] ) ; Common->cublasEventPotrf [i] = NULL ; } } } /* ========================================================================== */ /* === gpu_updateC ========================================================== */ /* ========================================================================== */ /* C = L (k1:n-1, kd1:kd2-1) * L (k1:k2-1, kd1:kd2-1)', except that k1:n-1 * refers to all of the rows in L, but many of the rows are all zero. * Supernode d holds columns kd1 to kd2-1 of L. Nonzero rows in the range * k1:k2-1 are in the list Ls [pdi1 ... pdi2-1], of size ndrow1. Nonzero rows * in the range k2:n-1 are in the list Ls [pdi2 ... pdend], of size ndrow2. * Let L1 = L (Ls [pdi1 ... pdi2-1], kd1:kd2-1), and let L2 = L (Ls [pdi2 ... * pdend], kd1:kd2-1). C is ndrow2-by-ndrow1. Let C1 be the first ndrow1 * rows of C and let C2 be the last ndrow2-ndrow1 rows of C. Only the lower * triangular part of C1 needs to be computed since C1 is symmetric. */ int TEMPLATE (CHOLMOD (gpu_updateC)) ( Int ndrow1, /* C is ndrow2-by-ndrow2 */ Int ndrow2, Int ndrow, /* leading dimension of Lx */ Int ndcol, /* L1 is ndrow1-by-ndcol */ Int pdx1, /* L1 starts at Lx + L_ENTRY*pdx1 */ /* L2 starts at Lx + L_ENTRY*(pdx1 + ndrow1) */ double *Lx, double *C, cholmod_common *Common ) { double *devPtrLx, *devPtrC ; double alpha, beta ; cublasStatus_t cublasStatus ; cudaError_t cudaStat [2] ; Int ndrow3 ; Common->SyrkUsed = 0 ; Common->GemmUsed = 0 ; if ((ndrow2 < 512) || (ndcol < 128)) { /* too small for the CUDA BLAS; use the CPU instead */ return (0) ; } ndrow3 = ndrow2 - ndrow1 ; #ifndef NTIMER Common->syrkStart = SuiteSparse_time ( ) ; #endif /* ---------------------------------------------------------------------- */ /* allocate workspace on the GPU */ /* ---------------------------------------------------------------------- */ cudaStat [0] = cudaMalloc ((void **) &devPtrLx, ndrow2 * ndcol * L_ENTRY * sizeof (devPtrLx [0])) ; cudaStat [1] = cudaMalloc ((void **) &devPtrC, ndrow2 * ndrow1 * L_ENTRY * sizeof (devPtrC [0])) ; Common->devSyrkGemmPtrLx = devPtrLx ; Common->devSyrkGemmPtrC = devPtrC ; if (cudaStat [0] || cudaStat [1]) { /* one or both cudaMalloc's failed */ if (devPtrLx) cudaFree (devPtrLx) ; if (devPtrC) cudaFree (devPtrC) ; GPU_Printf ("gpu malloc failed =%d,%d ndrow1=%d ndrow2=%d ndcol=%d\n", cudaStat [0], cudaStat [1], (int) ndrow1, (int) ndrow2, (int) ndcol) ; /* cudaMalloc failure is not an error, just bypass the GPU */ return (0) ; } Common->SyrkUsed = 1 ; #ifndef NTIMER Common->CHOLMOD_GPU_SYRK_CALLS++ ; #endif /* ---------------------------------------------------------------------- */ /* copy Lx to the GPU */ /* ---------------------------------------------------------------------- */ /* copy Lx in two steps on different streams. * (ldLx is shortened from ndrow to ndrow2) */ cudaStat [0] = cudaMemcpy2DAsync (devPtrLx, ndrow2 * L_ENTRY * sizeof (devPtrLx [0]), Lx + L_ENTRY * pdx1, ndrow * L_ENTRY * sizeof (Lx [0]), ndrow1 * L_ENTRY * sizeof (devPtrLx [0]), ndcol, cudaMemcpyHostToDevice, Common->cudaStreamSyrk) ; if (cudaStat [0]) { ERROR (CHOLMOD_GPU_PROBLEM, "GPU memcopy to device") ; } if (ndrow3 > 0) { Common->GemmUsed = 1 ; cudaStat [1] = cudaMemcpy2DAsync (devPtrLx + L_ENTRY*ndrow1, ndrow2 * L_ENTRY * sizeof (devPtrLx [0]), Lx + L_ENTRY * (pdx1 + ndrow1), ndrow * L_ENTRY * sizeof (Lx [0]), ndrow3 * L_ENTRY * sizeof (devPtrLx [0]), ndcol, cudaMemcpyHostToDevice, Common->cudaStreamGemm) ; if (cudaStat [1]) { ERROR (CHOLMOD_GPU_PROBLEM, "GPU memcopy to device") ; } } /* ---------------------------------------------------------------------- */ /* do the CUDA SYRK */ /* ---------------------------------------------------------------------- */ cublasStatus = cublasSetStream (Common->cublasHandle, Common->cudaStreamSyrk) ; if (cublasStatus != CUBLAS_STATUS_SUCCESS) { ERROR (CHOLMOD_GPU_PROBLEM, "GPU CUBLAS stream") ; } alpha = 1.0 ; beta = 0.0 ; #ifdef REAL cublasStatus = cublasDsyrk (Common->cublasHandle, CUBLAS_FILL_MODE_LOWER, CUBLAS_OP_N, (int) ndrow1, (int) ndcol, /* N, K: L1 is ndrow1-by-ndcol */ &alpha, /* ALPHA: 1 */ devPtrLx, ndrow2, /* A, LDA: L1, ndrow2 */ &beta, /* BETA: 0 */ devPtrC, ndrow2) ; /* C, LDC: C1 */ #else cublasStatus = cublasZherk (Common->cublasHandle, CUBLAS_FILL_MODE_LOWER, CUBLAS_OP_N, (int) ndrow1, (int) ndcol, /* N, K: L1 is ndrow1-by-ndcol*/ &alpha, /* ALPHA: 1 */ (const cuDoubleComplex *) devPtrLx, ndrow2, /* A, LDA: L1, ndrow2 */ &beta, /* BETA: 0 */ (cuDoubleComplex *) devPtrC, ndrow2) ; /* C, LDC: C1 */ #endif if (cublasStatus != CUBLAS_STATUS_SUCCESS) { ERROR (CHOLMOD_GPU_PROBLEM, "GPU CUBLAS routine failure") ; } /* ---------------------------------------------------------------------- */ /* partial copy of C to the GPU */ /* ---------------------------------------------------------------------- */ cudaStat [0] = cudaMemcpy2DAsync (C, ndrow2 * L_ENTRY * sizeof (C [0]), devPtrC, ndrow2 * L_ENTRY * sizeof (devPtrC [0]), ndrow1 * L_ENTRY * sizeof (devPtrC [0]), ndrow1, cudaMemcpyDeviceToHost, Common->cudaStreamSyrk) ; if (cudaStat [0]) { ERROR (CHOLMOD_GPU_PROBLEM, "GPU memcopy from device") ; } /* ---------------------------------------------------------------------- */ /* compute remaining (ndrow2-ndrow1)-by-ndrow1 block of C, C2 = L2*L1' */ /* ---------------------------------------------------------------------- */ if (ndrow3 > 0) { #ifndef REAL cuDoubleComplex calpha = {1.0,0.0} ; cuDoubleComplex cbeta = {0.0,0.0} ; #endif #ifndef NTIMER Common->CHOLMOD_GPU_GEMM_CALLS++ ; #endif cublasStatus = cublasSetStream (Common->cublasHandle, Common->cudaStreamGemm) ; if (cublasStatus != CUBLAS_STATUS_SUCCESS) { ERROR (CHOLMOD_GPU_PROBLEM, "GPU CUBLAS stream") ; } /* ------------------------------------------------------------------ */ /* do the CUDA BLAS dgemm */ /* ------------------------------------------------------------------ */ #ifdef REAL alpha = 1.0 ; beta = 0.0 ; cublasStatus = cublasDgemm (Common->cublasHandle, CUBLAS_OP_N, CUBLAS_OP_T, ndrow3, ndrow1, ndcol, /* M, N, K */ &alpha, /* ALPHA: 1 */ devPtrLx + L_ENTRY*(ndrow1), /* A, LDA: L2, ndrow */ ndrow2, devPtrLx, /* B, LDB: L1, ndrow */ ndrow2, &beta, /* BETA: 0 */ devPtrC + L_ENTRY*ndrow1, /* C, LDC: C2 */ ndrow2) ; #else cublasStatus = cublasZgemm (Common->cublasHandle, CUBLAS_OP_N, CUBLAS_OP_C, ndrow3, ndrow1, ndcol, /* M, N, K */ &calpha, /* ALPHA: 1 */ (const cuDoubleComplex *) devPtrLx + ndrow1, /* A, LDA: L2, ndrow */ ndrow2, (const cuDoubleComplex *) devPtrLx, /* B, LDB: L1, ndrow */ ndrow2, &cbeta, /* BETA: 0 */ (cuDoubleComplex *)devPtrC + ndrow1, /* C, LDC: C2 */ ndrow2) ; #endif if (cublasStatus != CUBLAS_STATUS_SUCCESS) { ERROR (CHOLMOD_GPU_PROBLEM, "GPU CUBLAS routine failure") ; } /* ------------------------------------------------------------------ */ /* finish copy of C */ /* ------------------------------------------------------------------ */ cudaStat [0] = cudaMemcpy2DAsync (C + L_ENTRY*ndrow1, ndrow2 * L_ENTRY * sizeof (C [0]), devPtrC+ L_ENTRY*ndrow1, ndrow2 * L_ENTRY * sizeof (devPtrC [0]), ndrow3 * L_ENTRY * sizeof (devPtrC [0]), ndrow1, cudaMemcpyDeviceToHost, Common->cudaStreamGemm) ; if (cudaStat [0]) { ERROR (CHOLMOD_GPU_PROBLEM, "GPU memcopy from device") ; } } return (1) ; } /* ========================================================================== */ /* === gpu_syncSyrk ========================================================= */ /* ========================================================================== */ /* synchronize with the CUDA BLAS dsyrk stream */ void TEMPLATE (CHOLMOD (gpu_syncSyrk)) ( cholmod_common *Common ) { if (Common->SyrkUsed) { cudaStreamSynchronize (Common->cudaStreamSyrk) ; if (!Common->GemmUsed) { cudaFree (Common->devSyrkGemmPtrLx) ; cudaFree (Common->devSyrkGemmPtrC) ; Common->devSyrkGemmPtrLx = NULL ; Common->devSyrkGemmPtrC = NULL ; #ifndef NTIMER /* this actually sums time spend on Syrk and Gemm */ Common->CHOLMOD_GPU_SYRK_TIME += SuiteSparse_time ( ) - Common->syrkStart ; #endif } } } /* ========================================================================== */ /* === gpu_syncGemm ========================================================= */ /* ========================================================================== */ /* synchronize with the CUDA BLAS dgemm stream */ void TEMPLATE (CHOLMOD (gpu_syncGemm)) ( cholmod_common *Common ) { if (Common->GemmUsed) { cudaStreamSynchronize (Common->cudaStreamGemm) ; cudaFree (Common->devSyrkGemmPtrLx) ; cudaFree (Common->devSyrkGemmPtrC) ; Common->devSyrkGemmPtrLx = NULL ; Common->devSyrkGemmPtrC = NULL ; #ifndef NTIMER /* this actually sums time spend on Syrk and Gemm */ Common->CHOLMOD_GPU_SYRK_TIME += SuiteSparse_time ( ) - Common->syrkStart ; #endif } } /* ========================================================================== */ /* === gpu_lower_potrf ====================================================== */ /* ========================================================================== */ /* Cholesky factorzation (dpotrf) of a matrix S, operating on the lower * triangular part only. S is nscol2-by-nscol2 with leading dimension nsrow. * * S is the top part of the supernode (the lower triangular matrx). * This function also copies the bottom rectangular part of the supernode (B) * onto the GPU, in preparation for gpu_triangular_solve. */ int TEMPLATE (CHOLMOD (gpu_lower_potrf)) ( Int nscol2, /* S is nscol2-by-nscol2 */ Int nsrow, /* leading dimension of S */ Int psx, /* S is located at Lx + L_Entry*psx */ double *Lx, /* contains S; overwritten with Cholesky factor */ Int *info, /* BLAS info return value */ cholmod_common *Common ) { double *devPtrA, *devPtrB, *A ; double alpha, beta ; cudaError_t cudaStat ; cublasStatus_t cublasStatus ; Int j, nsrow2, nb, n, gpu_lda, lda, gpu_ldb ; int ilda, ijb, iinfo ; #ifndef NTIMER double tstart = SuiteSparse_time ( ) ; #endif if (nscol2 < 256) { /* too small for the CUDA BLAS; use the CPU instead */ return (0) ; } nsrow2 = nsrow - nscol2 ; /* ---------------------------------------------------------------------- */ /* heuristic to get the block size depending of the problem size */ /* ---------------------------------------------------------------------- */ nb = 128 ; if (nscol2 > 4096) nb = 256 ; if (nscol2 > 8192) nb = 384 ; n = nscol2 ; gpu_lda = ((nscol2+31)/32)*32 ; lda = nsrow ; A = Lx + L_ENTRY*psx ; /* ---------------------------------------------------------------------- */ /* free the dpotrf workspace, if allocated */ /* ---------------------------------------------------------------------- */ if (Common->devPotrfWork) { cudaFree (Common->devPotrfWork) ; Common->devPotrfWork = NULL ; } /* ---------------------------------------------------------------------- */ /* determine the GPU leading dimension of B */ /* ---------------------------------------------------------------------- */ gpu_ldb = 0 ; if (nsrow2 > 0) { gpu_ldb = ((nsrow2+31)/32)*32 ; } /* ---------------------------------------------------------------------- */ /* allocate device memory for the factorization and for potential solve */ /* ---------------------------------------------------------------------- */ cudaStat = cudaMalloc ((void **) &devPtrA, gpu_lda * (gpu_lda + gpu_ldb) * L_ENTRY * sizeof (devPtrA [0])) ; if (cudaStat) { GPU_Printf ("@@gpu_lower_potrf cudaMalloc failed =%d gpu_lda=%d\n", cudaStat, (int) (gpu_lda)) ; /* cudaMalloc failure not fatal, GPU bypassed */ return (0) ; } #ifndef NTIMER Common->CHOLMOD_GPU_POTRF_CALLS++ ; #endif /* ---------------------------------------------------------------------- */ /* remember where device memory is, to be used by triangular solve later */ /* ---------------------------------------------------------------------- */ Common->devPotrfWork = devPtrA ; devPtrB = devPtrA + gpu_lda * gpu_lda * L_ENTRY ; /* ---------------------------------------------------------------------- */ /* copy B in advance, for gpu_triangular_solve */ /* ---------------------------------------------------------------------- */ if (nsrow2 > 0) { cudaStat = cudaMemcpy2DAsync (devPtrB, gpu_ldb * L_ENTRY * sizeof (devPtrB [0]), Lx + L_ENTRY * (psx + nscol2), nsrow * L_ENTRY * sizeof (Lx [0]), nsrow2 * L_ENTRY * sizeof (devPtrB [0]), nscol2, cudaMemcpyHostToDevice, Common->cudaStreamTrsm) ; if (cudaStat) { ERROR (CHOLMOD_GPU_PROBLEM, "GPU memcopy to device") ; } } /* ---------------------------------------------------------------------- */ /* block Cholesky factorization of S */ /* ---------------------------------------------------------------------- */ for (j = 0 ; j < n ; j += nb) { Int jb = nb < (n-j) ? nb : (n-j) ; /* ------------------------------------------------------------------ */ /* copy jb columns starting at the diagonal to the GPU */ /* ------------------------------------------------------------------ */ cudaStat = cudaMemcpy2DAsync (devPtrA + (j + j*gpu_lda)*L_ENTRY, gpu_lda * L_ENTRY * sizeof (devPtrA [0]), A + L_ENTRY*(j + j*lda), lda * L_ENTRY * sizeof (A [0]), (n-j) * L_ENTRY * sizeof (devPtrA [0]), jb, cudaMemcpyHostToDevice, Common->cudaStreamPotrf [0]) ; if (cudaStat) { ERROR (CHOLMOD_GPU_PROBLEM, "GPU memcopy to device") ; } /* ------------------------------------------------------------------ */ /* define the dpotrf stream */ /* ------------------------------------------------------------------ */ cublasStatus = cublasSetStream (Common->cublasHandle, Common->cudaStreamPotrf [0]) ; if (cublasStatus != CUBLAS_STATUS_SUCCESS) { ERROR (CHOLMOD_GPU_PROBLEM, "GPU CUBLAS stream") ; } /* ------------------------------------------------------------------ */ /* record the end of the copy of block L22 | L32 */ /* ------------------------------------------------------------------ */ cudaStat = cudaEventRecord (Common->cublasEventPotrf [0], Common->cudaStreamPotrf [0]) ; if (cudaStat) { ERROR (CHOLMOD_GPU_PROBLEM, "CUDA event failure") ; } /* ------------------------------------------------------------------ */ /* do the CUDA BLAS dsyrk */ /* ------------------------------------------------------------------ */ alpha = -1.0 ; beta = 1.0 ; #ifdef REAL cublasStatus = cublasDsyrk (Common->cublasHandle, CUBLAS_FILL_MODE_LOWER, CUBLAS_OP_N, jb, j, &alpha, devPtrA + j, gpu_lda, &beta, devPtrA + j + j*gpu_lda, gpu_lda) ; #else cublasStatus = cublasZherk (Common->cublasHandle, CUBLAS_FILL_MODE_LOWER, CUBLAS_OP_N, jb, j, &alpha, (cuDoubleComplex*)devPtrA + j, gpu_lda, &beta, (cuDoubleComplex*)devPtrA + j + j*gpu_lda, gpu_lda) ; #endif if (cublasStatus != CUBLAS_STATUS_SUCCESS) { ERROR (CHOLMOD_GPU_PROBLEM, "GPU CUBLAS routine failure") ; } /* ------------------------------------------------------------------ */ cudaStat = cudaEventRecord (Common->cublasEventPotrf [1], Common->cudaStreamPotrf [0]) ; if (cudaStat) { ERROR (CHOLMOD_GPU_PROBLEM, "CUDA event failure") ; } cudaStat = cudaStreamWaitEvent (Common->cudaStreamPotrf [1], Common->cublasEventPotrf [1], 0) ; if (cudaStat) { ERROR (CHOLMOD_GPU_PROBLEM, "CUDA event failure") ; } /* ------------------------------------------------------------------ */ /* copy back the jb columns on two different streams */ /* ------------------------------------------------------------------ */ cudaStat = cudaMemcpy2DAsync (A + L_ENTRY*(j + j*lda), lda * L_ENTRY * sizeof (double), devPtrA + L_ENTRY*(j + j*gpu_lda), gpu_lda * L_ENTRY * sizeof (double), L_ENTRY * sizeof (double)*jb, jb, cudaMemcpyDeviceToHost, Common->cudaStreamPotrf [1]) ; if (cudaStat) { ERROR (CHOLMOD_GPU_PROBLEM, "GPU memcopy from device") ; } cudaStat = cudaMemcpy2DAsync (A + L_ENTRY*j, lda * L_ENTRY * sizeof (double), devPtrA + L_ENTRY*j, gpu_lda * L_ENTRY * sizeof (double), L_ENTRY * sizeof (double)*jb, j, cudaMemcpyDeviceToHost, Common->cudaStreamPotrf [0]) ; if (cudaStat) { ERROR (CHOLMOD_GPU_PROBLEM, "GPU memcopy to device") ; } /* ------------------------------------------------------------------ */ /* do the CUDA BLAS dgemm */ /* ------------------------------------------------------------------ */ if ((j+jb) < n) { #ifdef REAL alpha = -1.0 ; beta = 1.0 ; cublasStatus = cublasDgemm (Common->cublasHandle, CUBLAS_OP_N, CUBLAS_OP_T, (n-j-jb), jb, j, &alpha, devPtrA + (j+jb), gpu_lda, devPtrA + (j) , gpu_lda, &beta, devPtrA + (j+jb + j*gpu_lda), gpu_lda) ; #else cuDoubleComplex calpha = {-1.0,0.0} ; cuDoubleComplex cbeta = { 1.0,0.0} ; cublasStatus = cublasZgemm (Common->cublasHandle, CUBLAS_OP_N, CUBLAS_OP_C, (n-j-jb), jb, j, &calpha, (cuDoubleComplex*)devPtrA + (j+jb), gpu_lda, (cuDoubleComplex*)devPtrA + (j) , gpu_lda, &cbeta, (cuDoubleComplex*)devPtrA + (j+jb + j*gpu_lda), gpu_lda) ; #endif if (cublasStatus != CUBLAS_STATUS_SUCCESS) { ERROR (CHOLMOD_GPU_PROBLEM, "GPU CUBLAS routine failure") ; } } cudaStat = cudaStreamSynchronize (Common->cudaStreamPotrf [1]) ; if (cudaStat) { ERROR (CHOLMOD_GPU_PROBLEM, "GPU memcopy to device") ; } /* ------------------------------------------------------------------ */ /* compute the Cholesky factorization of the jbxjb block on the CPU */ /* ------------------------------------------------------------------ */ ilda = (int) lda ; ijb = jb ; #ifdef REAL LAPACK_DPOTRF ("L", &ijb, A + L_ENTRY * (j + j*lda), &ilda, &iinfo) ; #else LAPACK_ZPOTRF ("L", &ijb, A + L_ENTRY * (j + j*lda), &ilda, &iinfo) ; #endif *info = iinfo ; if (*info != 0) { *info = *info + j ; break ; } /* ------------------------------------------------------------------ */ /* copy the result back to the GPU */ /* ------------------------------------------------------------------ */ cudaStat = cudaMemcpy2DAsync (devPtrA + L_ENTRY*(j + j*gpu_lda), gpu_lda * L_ENTRY * sizeof (double), A + L_ENTRY * (j + j*lda), lda * L_ENTRY * sizeof (double), L_ENTRY * sizeof (double) * jb, jb, cudaMemcpyHostToDevice, Common->cudaStreamPotrf [0]) ; if (cudaStat) { ERROR (CHOLMOD_GPU_PROBLEM, "GPU memcopy to device") ; } /* ------------------------------------------------------------------ */ /* do the CUDA BLAS dtrsm */ /* ------------------------------------------------------------------ */ if ((j+jb) < n) { #ifdef REAL alpha = 1.0 ; cublasStatus = cublasDtrsm (Common->cublasHandle, CUBLAS_SIDE_RIGHT, CUBLAS_FILL_MODE_LOWER, CUBLAS_OP_T, CUBLAS_DIAG_NON_UNIT, (n-j-jb), jb, &alpha, devPtrA + (j + j*gpu_lda), gpu_lda, devPtrA + (j+jb + j*gpu_lda), gpu_lda) ; #else cuDoubleComplex calpha = {1.0,0.0}; cublasStatus = cublasZtrsm (Common->cublasHandle, CUBLAS_SIDE_RIGHT, CUBLAS_FILL_MODE_LOWER, CUBLAS_OP_C, CUBLAS_DIAG_NON_UNIT, (n-j-jb), jb, &calpha, (cuDoubleComplex *)devPtrA + (j + j*gpu_lda), gpu_lda, (cuDoubleComplex *)devPtrA + (j+jb + j*gpu_lda), gpu_lda) ; #endif if (cublasStatus != CUBLAS_STATUS_SUCCESS) { ERROR (CHOLMOD_GPU_PROBLEM, "GPU CUBLAS routine failure") ; } } } if (nsrow2 <= 0) { /* No TRSM necessary */ cudaFree (Common->devPotrfWork) ; Common->devPotrfWork = NULL ; } #ifndef NTIMER Common->CHOLMOD_GPU_POTRF_TIME += SuiteSparse_time ( ) - tstart ; #endif return (1) ; } /* ========================================================================== */ /* === gpu_triangular_solve ================================================= */ /* ========================================================================== */ /* The current supernode is columns k1 to k2-1 of L. Let L1 be the diagonal * block (factorized by dpotrf/zpotrf above; rows/cols k1:k2-1), and L2 be rows * k2:n-1 and columns k1:k2-1 of L. The triangular system to solve is L2*L1' = * S2, where S2 is overwritten with L2. More precisely, L2 = S2 / L1' in * MATLAB notation. */ /* Version with pre-allocation in POTRF */ int TEMPLATE (CHOLMOD (gpu_triangular_solve)) ( Int nsrow2, /* L1 and S2 are nsrow2-by-nscol2 */ Int nscol2, /* L1 is nscol2-by-nscol2 */ Int nsrow, /* leading dimension of L1, L2, and S2 */ Int psx, /* L1 is at Lx+L_ENTRY*psx; L2 at Lx+L_ENTRY*(psx+nscol2)*/ double *Lx, /* holds L1, L2, and S2 */ cholmod_common *Common ) { double *devPtrA, *devPtrB ; cudaError_t cudaStat ; cublasStatus_t cublasStatus ; Int gpu_lda, gpu_ldb ; #ifdef REAL double alpha = 1.0 ; #else cuDoubleComplex calpha = {1.0,0.0} ; #endif if (!Common->devPotrfWork) { /* no workspace for triangular solve */ return (0) ; } #ifndef NTIMER double tstart = SuiteSparse_time ( ) ; Common->CHOLMOD_GPU_TRSM_CALLS++ ; #endif gpu_lda = ((nscol2+31)/32)*32 ; gpu_ldb = ((nsrow2+31)/32)*32 ; devPtrA = Common->devPotrfWork ; devPtrB = devPtrA + gpu_lda * gpu_lda * L_ENTRY ; /* ---------------------------------------------------------------------- */ /* start the trsm stream */ /* ---------------------------------------------------------------------- */ cublasStatus = cublasSetStream (Common->cublasHandle, Common->cudaStreamTrsm) ; if (cublasStatus != CUBLAS_STATUS_SUCCESS) { ERROR (CHOLMOD_GPU_PROBLEM, "GPU CUBLAS stream") ; } /* ---------------------------------------------------------------------- */ /* do the CUDA BLAS dtrsm */ /* ---------------------------------------------------------------------- */ #ifdef REAL cublasStatus = cublasDtrsm (Common->cublasHandle, CUBLAS_SIDE_RIGHT, CUBLAS_FILL_MODE_LOWER, CUBLAS_OP_T, CUBLAS_DIAG_NON_UNIT, nsrow2, nscol2, /* M, N */ &alpha, /* ALPHA: 1 */ devPtrA, gpu_lda, /* A, LDA */ devPtrB, gpu_ldb) ; /* B, LDB */ #else cublasStatus = cublasZtrsm (Common->cublasHandle, CUBLAS_SIDE_RIGHT, CUBLAS_FILL_MODE_LOWER, CUBLAS_OP_C, CUBLAS_DIAG_NON_UNIT, nsrow2, nscol2, /* M, N */ &calpha, /* ALPHA: 1 */ (const cuDoubleComplex *) devPtrA, gpu_lda, /* A, LDA */ (cuDoubleComplex *) devPtrB, gpu_ldb) ; /* B, LDB: nsrow2 */ #endif if (cublasStatus != CUBLAS_STATUS_SUCCESS) { ERROR (CHOLMOD_GPU_PROBLEM, "GPU CUBLAS routine failure") ; } /* ---------------------------------------------------------------------- */ /* copy result back to the CPU */ /* ---------------------------------------------------------------------- */ cudaStat = cudaMemcpy2DAsync (Lx + L_ENTRY*(psx + nscol2), nsrow * L_ENTRY * sizeof (Lx [0]), devPtrB, gpu_ldb * L_ENTRY * sizeof (devPtrB [0]), nsrow2 * L_ENTRY * sizeof (devPtrB [0]), nscol2, cudaMemcpyDeviceToHost, Common->cudaStreamTrsm) ; if (cudaStat) { ERROR (CHOLMOD_GPU_PROBLEM, "GPU memcopy from device") ; } /* ---------------------------------------------------------------------- */ /* synchronize with the GPU */ /* ---------------------------------------------------------------------- */ cudaStat = cudaThreadSynchronize ( ) ; if (cudaStat) { ERROR (CHOLMOD_GPU_PROBLEM, "GPU synchronization failure") ; } /* ---------------------------------------------------------------------- */ /* free workspace and return */ /* ---------------------------------------------------------------------- */ cudaFree (Common->devPotrfWork) ; Common->devPotrfWork = NULL ; #ifndef NTIMER Common->CHOLMOD_GPU_TRSM_TIME += SuiteSparse_time ( ) - tstart ; #endif return (1) ; } #undef REAL #undef COMPLEX #undef ZOMPLEX ��������������������������Matrix/src/CHOLMOD/Supernodal/cholmod_super_numeric.c�����������������������������������������������0000644�0001762�0000144�00000025275�13652535054�022262� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Supernodal/cholmod_super_numeric ===================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Supernodal Module. Copyright (C) 2005-2006, Timothy A. Davis * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* Computes the Cholesky factorization of A+beta*I or A*F+beta*I. Only the * the lower triangular part of A+beta*I or A*F+beta*I is accessed. The * matrices A and F must already be permuted according to the fill-reduction * permutation L->Perm. cholmod_factorize is an "easy" wrapper for this code * which applies that permutation. beta is real. * * Symmetric case: A is a symmetric (lower) matrix. F is not accessed. * With a fill-reducing permutation, A(p,p) should be passed instead, where is * p is L->Perm. * * Unsymmetric case: A is unsymmetric, and F must be present. Normally, F=A'. * With a fill-reducing permutation, A(p,f) and A(p,f)' should be passed as A * and F, respectively, where f is a list of the subset of the columns of A. * * The input factorization L must be supernodal (L->is_super is TRUE). It can * either be symbolic or numeric. In the first case, L has been analyzed by * cholmod_analyze or cholmod_super_symbolic, but the matrix has not yet been * numerically factorized. The numerical values are allocated here and the * factorization is computed. In the second case, a prior matrix has been * analyzed and numerically factorized, and a new matrix is being factorized. * The numerical values of L are replaced with the new numerical factorization. * * L->is_ll is ignored, and set to TRUE. This routine always computes an LL' * factorization. Supernodal LDL' factorization is not (yet) supported. * FUTURE WORK: perform a supernodal LDL' factorization if L->is_ll is FALSE. * * Uses BLAS routines dsyrk, dgemm, dtrsm, and the LAPACK routine dpotrf. * The supernodal solver uses BLAS routines dtrsv, dgemv, dtrsm, and dgemm. * * If the matrix is not positive definite the routine returns TRUE, but sets * Common->status to CHOLMOD_NOT_POSDEF and L->minor is set to the column at * which the failure occurred. The supernode containing the non-positive * diagonal entry is set to zero (this includes columns to the left of L->minor * in the same supernode), as are all subsequent supernodes. * * workspace: Flag (nrow), Head (nrow+1), Iwork (2*nrow + 5*nsuper). * Allocates temporary space of size L->maxcsize * sizeof(double) * (twice that for the complex/zomplex case). * * If L is supernodal symbolic on input, it is converted to a supernodal numeric * factor on output, with an xtype of real if A is real, or complex if A is * complex or zomplex. If L is supernodal numeric on input, its xtype must * match A (except that L can be complex and A zomplex). The xtype of A and F * must match. */ #ifndef NGPL #ifndef NSUPERNODAL #include "cholmod_internal.h" #include "cholmod_supernodal.h" #ifdef GPU_BLAS #include "cholmod_gpu.h" #endif /* ========================================================================== */ /* === TEMPLATE codes for GPU and regular numeric factorization ============= */ /* ========================================================================== */ #ifdef DLONG #ifdef GPU_BLAS #define REAL #include "../GPU/t_cholmod_gpu.c" #define COMPLEX #include "../GPU/t_cholmod_gpu.c" #define ZOMPLEX /* no #include of "../GPU/t_cholmod_gpu.c". Zomplex case relies on complex */ #endif #endif #define REAL #include "t_cholmod_super_numeric.c" #define COMPLEX #include "t_cholmod_super_numeric.c" #define ZOMPLEX #include "t_cholmod_super_numeric.c" /* ========================================================================== */ /* === cholmod_super_numeric ================================================ */ /* ========================================================================== */ /* Returns TRUE if successful, or if the matrix is not positive definite. * Returns FALSE if out of memory, inputs are invalid, or other fatal error * occurs. */ int CHOLMOD(super_numeric) ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to factorize */ cholmod_sparse *F, /* F = A' or A(:,f)' */ double beta [2], /* beta*I is added to diagonal of matrix to factorize */ /* ---- in/out --- */ cholmod_factor *L, /* factorization */ /* --------------- */ cholmod_common *Common ) { cholmod_dense *C ; Int *Super, *Map, *SuperMap ; size_t maxcsize ; Int nsuper, n, i, k, s, stype, nrow ; int ok = TRUE, symbolic ; size_t t, w ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (L, FALSE) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; RETURN_IF_XTYPE_INVALID (L, CHOLMOD_PATTERN, CHOLMOD_COMPLEX, FALSE) ; stype = A->stype ; if (stype < 0) { if (A->nrow != A->ncol || A->nrow != L->n) { ERROR (CHOLMOD_INVALID, "invalid dimensions") ; return (FALSE) ; } } else if (stype == 0) { if (A->nrow != L->n) { ERROR (CHOLMOD_INVALID, "invalid dimensions") ; return (FALSE) ; } RETURN_IF_NULL (F, FALSE) ; RETURN_IF_XTYPE_INVALID (F, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; if (A->nrow != F->ncol || A->ncol != F->nrow || F->stype != 0) { ERROR (CHOLMOD_INVALID, "F invalid") ; return (FALSE) ; } if (A->xtype != F->xtype) { ERROR (CHOLMOD_INVALID, "A and F must have same xtype") ; return (FALSE) ; } } else { /* symmetric upper case not suppored */ ERROR (CHOLMOD_INVALID, "symmetric upper case not supported") ; return (FALSE) ; } if (!(L->is_super)) { ERROR (CHOLMOD_INVALID, "L not supernodal") ; return (FALSE) ; } if (L->xtype != CHOLMOD_PATTERN) { if (! ((A->xtype == CHOLMOD_REAL && L->xtype == CHOLMOD_REAL) || (A->xtype == CHOLMOD_COMPLEX && L->xtype == CHOLMOD_COMPLEX) || (A->xtype == CHOLMOD_ZOMPLEX && L->xtype == CHOLMOD_COMPLEX))) { ERROR (CHOLMOD_INVALID, "complex type mismatch") ; return (FALSE) ; } } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate workspace in Common */ /* ---------------------------------------------------------------------- */ nsuper = L->nsuper ; maxcsize = L->maxcsize ; nrow = A->nrow ; n = nrow ; PRINT1 (("nsuper "ID" maxcsize %g\n", nsuper, (double) maxcsize)) ; ASSERT (nsuper >= 0 && maxcsize > 0) ; /* w = 2*n + 5*nsuper */ w = CHOLMOD(mult_size_t) (n, 2, &ok) ; t = CHOLMOD(mult_size_t) (nsuper, 5, &ok) ; w = CHOLMOD(add_size_t) (w, t, &ok) ; if (!ok) { ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; return (FALSE) ; } CHOLMOD(allocate_work) (n, w, 0, Common) ; if (Common->status < CHOLMOD_OK) { return (FALSE) ; } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; /* ---------------------------------------------------------------------- */ /* get the current factor L and allocate numerical part, if needed */ /* ---------------------------------------------------------------------- */ Super = L->super ; symbolic = (L->xtype == CHOLMOD_PATTERN) ; if (symbolic) { /* convert to supernodal numeric by allocating L->x */ CHOLMOD(change_factor) ( (A->xtype == CHOLMOD_REAL) ? CHOLMOD_REAL : CHOLMOD_COMPLEX, TRUE, TRUE, TRUE, TRUE, L, Common) ; if (Common->status < CHOLMOD_OK) { /* the factor L remains in symbolic supernodal form */ return (FALSE) ; } } ASSERT (L->dtype == DTYPE) ; ASSERT (L->xtype == CHOLMOD_REAL || L->xtype == CHOLMOD_COMPLEX) ; /* supernodal LDL' is not supported */ L->is_ll = TRUE ; /* ---------------------------------------------------------------------- */ /* get more workspace */ /* ---------------------------------------------------------------------- */ C = CHOLMOD(allocate_dense) (maxcsize, 1, maxcsize, L->xtype, Common) ; if (Common->status < CHOLMOD_OK) { int status = Common->status ; if (symbolic) { /* Change L back to symbolic, since the numeric values are not * initialized. This cannot fail. */ CHOLMOD(change_factor) (CHOLMOD_PATTERN, TRUE, TRUE, TRUE, TRUE, L, Common) ; } /* the factor L is now back to the form it had on input */ Common->status = status ; return (FALSE) ; } /* ---------------------------------------------------------------------- */ /* get workspace */ /* ---------------------------------------------------------------------- */ SuperMap = Common->Iwork ; /* size n (i/i/l) */ Map = Common->Flag ; /* size n, use Flag as workspace for Map array */ for (i = 0 ; i < n ; i++) { Map [i] = EMPTY ; } /* ---------------------------------------------------------------------- */ /* find the mapping of nodes to relaxed supernodes */ /* ---------------------------------------------------------------------- */ /* SuperMap [k] = s if column k is contained in supernode s */ for (s = 0 ; s < nsuper ; s++) { PRINT1 (("Super ["ID"] "ID" ncols "ID"\n", s, Super[s], Super[s+1]-Super[s])); for (k = Super [s] ; k < Super [s+1] ; k++) { SuperMap [k] = s ; PRINT2 (("relaxed SuperMap ["ID"] = "ID"\n", k, SuperMap [k])) ; } } /* ---------------------------------------------------------------------- */ /* supernodal numerical factorization, using template routine */ /* ---------------------------------------------------------------------- */ switch (A->xtype) { case CHOLMOD_REAL: ok = r_cholmod_super_numeric (A, F, beta, L, C, Common) ; break ; case CHOLMOD_COMPLEX: ok = c_cholmod_super_numeric (A, F, beta, L, C, Common) ; break ; case CHOLMOD_ZOMPLEX: /* This operates on complex L, not zomplex */ ok = z_cholmod_super_numeric (A, F, beta, L, C, Common) ; break ; } /* ---------------------------------------------------------------------- */ /* clear Common workspace, free temp workspace C, and return */ /* ---------------------------------------------------------------------- */ /* Flag array was used as workspace, clear it */ Common->mark = EMPTY ; /* CHOLMOD(clear_flag) (Common) ; */ CHOLMOD_CLEAR_FLAG (Common) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; CHOLMOD(free_dense) (&C, Common) ; return (ok) ; } #endif #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/CHOLMOD/Supernodal/t_cholmod_super_solve.c�����������������������������������������������0000644�0001762�0000144�00000025230�13652535054�022262� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === Supernodal/t_cholmod_super_solve ===================================== */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/Supernodal Module. Copyright (C) 2005-2006, Timothy A. Davis * http://www.suitesparse.com * -------------------------------------------------------------------------- */ /* Template routine for cholmod_super_solve. Supports real or complex L. */ #include "cholmod_template.h" static void TEMPLATE (cholmod_super_lsolve) ( /* ---- input ---- */ cholmod_factor *L, /* factor to use for the forward solve */ /* ---- output ---- */ cholmod_dense *X, /* b on input, solution to Lx=b on output */ /* ---- workspace ---- */ cholmod_dense *E, /* workspace of size nrhs*(L->maxesize) */ /* --------------- */ cholmod_common *Common ) { double *Lx, *Xx, *Ex ; double minus_one [2], one [2] ; Int *Lpi, *Lpx, *Ls, *Super ; Int nsuper, k1, k2, psi, psend, psx, nsrow, nscol, ii, s, nsrow2, n, ps2, j, i, d, nrhs ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ nrhs = X->ncol ; Ex = E->x ; Xx = X->x ; n = L->n ; d = X->d ; nsuper = L->nsuper ; Lpi = L->pi ; Lpx = L->px ; Ls = L->s ; Super = L->super ; Lx = L->x ; minus_one [0] = -1.0 ; minus_one [1] = 0 ; one [0] = 1.0 ; one [1] = 0 ; /* ---------------------------------------------------------------------- */ /* solve Lx=b */ /* ---------------------------------------------------------------------- */ if (nrhs == 1) { for (s = 0 ; s < nsuper ; s++) { k1 = Super [s] ; k2 = Super [s+1] ; psi = Lpi [s] ; psend = Lpi [s+1] ; psx = Lpx [s] ; nsrow = psend - psi ; nscol = k2 - k1 ; nsrow2 = nsrow - nscol ; ps2 = psi + nscol ; ASSERT ((size_t) nsrow2 <= L->maxesize) ; /* L1 is nscol-by-nscol, lower triangular with non-unit diagonal. * L2 is nsrow2-by-nscol. L1 and L2 have leading dimension of * nsrow. x1 is nscol-by-nsrow, with leading dimension n. * E is nsrow2-by-1, with leading dimension nsrow2. */ /* gather X into E */ for (ii = 0 ; ii < nsrow2 ; ii++) { /* Ex [ii] = Xx [Ls [ps2 + ii]] ; */ ASSIGN (Ex,-,ii, Xx,-,Ls [ps2 + ii]) ; } #ifdef REAL /* solve L1*x1 (that is, x1 = L1\x1) */ BLAS_dtrsv ("L", "N", "N", nscol, /* N: L1 is nscol-by-nscol */ Lx + ENTRY_SIZE*psx, nsrow, /* A, LDA: L1 */ Xx + ENTRY_SIZE*k1, 1) ; /* X, INCX: x1 */ /* E = E - L2*x1 */ BLAS_dgemv ("N", nsrow2, nscol, /* M, N: L2 is nsrow2-by-nscol */ minus_one, /* ALPHA: -1 */ Lx + ENTRY_SIZE*(psx + nscol), /* A, LDA: L2 */ nsrow, Xx + ENTRY_SIZE*k1, 1, /* X, INCX: x1 */ one, /* BETA: 1 */ Ex, 1) ; /* Y, INCY: E */ #else /* solve L1*x1 (that is, x1 = L1\x1) */ BLAS_ztrsv ("L", "N", "N", nscol, /* N: L1 is nscol-by-nscol */ Lx + ENTRY_SIZE*psx, nsrow, /* A, LDA: L1 */ Xx + ENTRY_SIZE*k1, 1) ; /* X, INCX: x1 */ /* E = E - L2*x1 */ BLAS_zgemv ("N", nsrow2, nscol, /* M, N: L2 is nsrow2-by-nscol */ minus_one, /* ALPHA: -1 */ Lx + ENTRY_SIZE*(psx + nscol), /* A, LDA: L2 */ nsrow, Xx + ENTRY_SIZE*k1, 1, /* X, INCX: x1 */ one, /* BETA: 1 */ Ex, 1) ; /* Y, INCY: E */ #endif /* scatter E back into X */ for (ii = 0 ; ii < nsrow2 ; ii++) { /* Xx [Ls [ps2 + ii]] = Ex [ii] ; */ ASSIGN (Xx,-,Ls [ps2 + ii], Ex,-,ii) ; } } } else { for (s = 0 ; s < nsuper ; s++) { k1 = Super [s] ; k2 = Super [s+1] ; psi = Lpi [s] ; psend = Lpi [s+1] ; psx = Lpx [s] ; nsrow = psend - psi ; nscol = k2 - k1 ; nsrow2 = nsrow - nscol ; ps2 = psi + nscol ; ASSERT ((size_t) nsrow2 <= L->maxesize) ; /* E is nsrow2-by-nrhs, with leading dimension nsrow2. */ /* gather X into E */ for (ii = 0 ; ii < nsrow2 ; ii++) { i = Ls [ps2 + ii] ; for (j = 0 ; j < nrhs ; j++) { /* Ex [ii + j*nsrow2] = Xx [i + j*d] ; */ ASSIGN (Ex,-,ii+j*nsrow2, Xx,-,i+j*d) ; } } #ifdef REAL /* solve L1*x1 */ BLAS_dtrsm ("L", "L", "N", "N", nscol, nrhs, /* M, N: x1 is nscol-by-nrhs */ one, /* ALPHA: 1 */ Lx + ENTRY_SIZE*psx, nsrow, /* A, LDA: L1 */ Xx + ENTRY_SIZE*k1, d) ; /* B, LDB: x1 */ /* E = E - L2*x1 */ if (nsrow2 > 0) { BLAS_dgemm ("N", "N", nsrow2, nrhs, nscol, /* M, N, K */ minus_one, /* ALPHA: -1 */ Lx + ENTRY_SIZE*(psx + nscol), /* A, LDA: L2 */ nsrow, Xx + ENTRY_SIZE*k1, d, /* B, LDB: X1 */ one, /* BETA: 1 */ Ex, nsrow2) ; /* C, LDC: E */ } #else /* solve L1*x1 */ BLAS_ztrsm ("L", "L", "N", "N", nscol, nrhs, /* M, N: x1 is nscol-by-nrhs */ one, /* ALPHA: 1 */ Lx + ENTRY_SIZE*psx, nsrow, /* A, LDA: L1 */ Xx + ENTRY_SIZE*k1, d) ; /* B, LDB: x1 */ /* E = E - L2*x1 */ if (nsrow2 > 0) { BLAS_zgemm ("N", "N", nsrow2, nrhs, nscol, /* M, N, K */ minus_one, /* ALPHA: -1 */ Lx + ENTRY_SIZE*(psx + nscol), /* A, LDA: L2 */ nsrow, Xx + ENTRY_SIZE*k1, d, /* B, LDB: X1 */ one, /* BETA: 1 */ Ex, nsrow2) ; /* C, LDC: E */ } #endif /* scatter E back into X */ for (ii = 0 ; ii < nsrow2 ; ii++) { i = Ls [ps2 + ii] ; for (j = 0 ; j < nrhs ; j++) { /* Xx [i + j*d] = Ex [ii + j*nsrow2] ; */ ASSIGN (Xx,-,i+j*d, Ex,-,ii+j*nsrow2) ; } } } } } static void TEMPLATE (cholmod_super_ltsolve) ( /* ---- input ---- */ cholmod_factor *L, /* factor to use for the forward solve */ /* ---- output ---- */ cholmod_dense *X, /* b on input, solution to Lx=b on output */ /* ---- workspace ---- */ cholmod_dense *E, /* workspace of size nrhs*(L->maxesize) */ /* --------------- */ cholmod_common *Common ) { double *Lx, *Xx, *Ex ; double minus_one [2], one [2] ; Int *Lpi, *Lpx, *Ls, *Super ; Int nsuper, k1, k2, psi, psend, psx, nsrow, nscol, ii, s, nsrow2, n, ps2, j, i, d, nrhs ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ nrhs = X->ncol ; Ex = E->x ; Xx = X->x ; n = L->n ; d = X->d ; nsuper = L->nsuper ; Lpi = L->pi ; Lpx = L->px ; Ls = L->s ; Super = L->super ; Lx = L->x ; minus_one [0] = -1.0 ; minus_one [1] = 0 ; one [0] = 1.0 ; one [1] = 0 ; /* ---------------------------------------------------------------------- */ /* solve L'x=b */ /* ---------------------------------------------------------------------- */ if (nrhs == 1) { for (s = nsuper-1 ; s >= 0 ; s--) { k1 = Super [s] ; k2 = Super [s+1] ; psi = Lpi [s] ; psend = Lpi [s+1] ; psx = Lpx [s] ; nsrow = psend - psi ; nscol = k2 - k1 ; nsrow2 = nsrow - nscol ; ps2 = psi + nscol ; ASSERT ((size_t) nsrow2 <= L->maxesize) ; /* L1 is nscol-by-nscol, lower triangular with non-unit diagonal. * L2 is nsrow2-by-nscol. L1 and L2 have leading dimension of * nsrow. x1 is nscol-by-nsrow, with leading dimension n. * E is nsrow2-by-1, with leading dimension nsrow2. */ /* gather X into E */ for (ii = 0 ; ii < nsrow2 ; ii++) { /* Ex [ii] = Xx [Ls [ps2 + ii]] ; */ ASSIGN (Ex,-,ii, Xx,-,Ls [ps2 + ii]) ; } #ifdef REAL /* x1 = x1 - L2'*E */ BLAS_dgemv ("C", nsrow2, nscol, /* M, N: L2 is nsrow2-by-nscol */ minus_one, /* ALPHA: -1 */ Lx + ENTRY_SIZE*(psx + nscol), /* A, LDA: L2 */ nsrow, Ex, 1, /* X, INCX: Ex */ one, /* BETA: 1 */ Xx + ENTRY_SIZE*k1, 1) ; /* Y, INCY: x1 */ /* solve L1'*x1 */ BLAS_dtrsv ("L", "C", "N", nscol, /* N: L1 is nscol-by-nscol */ Lx + ENTRY_SIZE*psx, nsrow, /* A, LDA: L1 */ Xx + ENTRY_SIZE*k1, 1) ; /* X, INCX: x1 */ #else /* x1 = x1 - L2'*E */ BLAS_zgemv ("C", nsrow2, nscol, /* M, N: L2 is nsrow2-by-nscol */ minus_one, /* ALPHA: -1 */ Lx + ENTRY_SIZE*(psx + nscol), /* A, LDA: L2 */ nsrow, Ex, 1, /* X, INCX: Ex */ one, /* BETA: 1 */ Xx + ENTRY_SIZE*k1, 1) ; /* Y, INCY: x1 */ /* solve L1'*x1 */ BLAS_ztrsv ("L", "C", "N", nscol, /* N: L1 is nscol-by-nscol */ Lx + ENTRY_SIZE*psx, nsrow, /* A, LDA: L1 */ Xx + ENTRY_SIZE*k1, 1) ; /* X, INCX: x1 */ #endif } } else { for (s = nsuper-1 ; s >= 0 ; s--) { k1 = Super [s] ; k2 = Super [s+1] ; psi = Lpi [s] ; psend = Lpi [s+1] ; psx = Lpx [s] ; nsrow = psend - psi ; nscol = k2 - k1 ; nsrow2 = nsrow - nscol ; ps2 = psi + nscol ; ASSERT ((size_t) nsrow2 <= L->maxesize) ; /* E is nsrow2-by-nrhs, with leading dimension nsrow2. */ /* gather X into E */ for (ii = 0 ; ii < nsrow2 ; ii++) { i = Ls [ps2 + ii] ; for (j = 0 ; j < nrhs ; j++) { /* Ex [ii + j*nsrow2] = Xx [i + j*d] ; */ ASSIGN (Ex,-,ii+j*nsrow2, Xx,-,i+j*d) ; } } #ifdef REAL /* x1 = x1 - L2'*E */ if (nsrow2 > 0) { BLAS_dgemm ("C", "N", nscol, nrhs, nsrow2, /* M, N, K */ minus_one, /* ALPHA: -1 */ Lx + ENTRY_SIZE*(psx + nscol), /* A, LDA: L2 */ nsrow, Ex, nsrow2, /* B, LDB: E */ one, /* BETA: 1 */ Xx + ENTRY_SIZE*k1, d) ; /* C, LDC: x1 */ } /* solve L1'*x1 */ BLAS_dtrsm ("L", "L", "C", "N", nscol, nrhs, /* M, N: x1 is nscol-by-nrhs */ one, /* ALPHA: 1 */ Lx + ENTRY_SIZE*psx, nsrow, /* A, LDA: L1 */ Xx + ENTRY_SIZE*k1, d) ; /* B, LDB: x1 */ #else /* x1 = x1 - L2'*E */ if (nsrow2 > 0) { BLAS_zgemm ("C", "N", nscol, nrhs, nsrow2, /* M, N, K */ minus_one, /* ALPHA: -1 */ Lx + ENTRY_SIZE*(psx + nscol), /* A, LDA: L2 */ nsrow, Ex, nsrow2, /* B, LDB: E */ one, /* BETA: 1 */ Xx + ENTRY_SIZE*k1, d) ; /* C, LDC: x1 */ } /* solve L1'*x1 */ BLAS_ztrsm ("L", "L", "C", "N", nscol, nrhs, /* M, N: x1 is nscol-by-nrhs */ one, /* ALPHA: 1 */ Lx + ENTRY_SIZE*psx, nsrow, /* A, LDA: L1 */ Xx + ENTRY_SIZE*k1, d) ; /* B, LDB: x1 */ #endif } } } #undef PATTERN #undef REAL #undef COMPLEX #undef ZOMPLEX ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/utils-R.c��������������������������������������������������������������������������������0000644�0001762�0000144�00000037125�14531352033�014017� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "Mdefines.h" #include "utils-R.h" SEXP R_Matrix_version(void) { SEXP ans, nms; PROTECT(ans = allocVector(INTSXP, 3)); INTEGER(ans)[0] = MATRIX_PACKAGE_VERSION; INTEGER(ans)[1] = MATRIX_ABI_VERSION; INTEGER(ans)[2] = MATRIX_SUITESPARSE_VERSION; PROTECT(nms = allocVector(STRSXP, 3)); SET_STRING_ELT(nms, 0, mkChar("package")); SET_STRING_ELT(nms, 1, mkChar("abi")); SET_STRING_ELT(nms, 2, mkChar("suitesparse")); setAttrib(ans, R_NamesSymbol, nms); UNPROTECT(2); return ans; } SEXP R_index_triangle(SEXP n, SEXP packed, SEXP upper, SEXP diag) { SEXP r; int i, j, n_ = asInteger(n), packed_ = asLogical(packed), upper_ = asLogical(upper), diag_ = asLogical(diag); Matrix_int_fast64_t nn = (Matrix_int_fast64_t) n_ * n_, nx = (packed_) ? n_ + (nn - n_) / 2 : nn, nr = (diag_) ? n_ + (nn - n_) / 2 : (nn - n_) / 2; if (nx > 0x1.0p+53) error(_("indices would exceed %s"), "2^53"); if (nr > R_XLEN_T_MAX) error(_("attempt to allocate vector of length exceeding %s"), "R_XLEN_T_MAX"); #define DO_INDEX \ do { \ if (packed_) { \ if (diag_) { \ while (k <= nr_) \ *(pr++) = k++; \ } else if (upper_) { \ for (j = 0; j < n_; ++j) { \ for (i = 0; i < j; ++i) \ *(pr++) = k++; \ k++; \ } \ } else { \ for (j = 0; j < n_; ++j) { \ k++; \ for (i = j+1; i < n_; ++i) \ *(pr++) = k++; \ } \ } \ } else if (diag_) { \ if (upper_) { \ for (j = 0; j < n_; ++j) { \ for (i = 0; i <= j; ++i) \ *(pr++) = k++; \ k += n_-j-1; \ } \ } else { \ for (j = 0; j < n_; ++j) { \ k += j; \ for (i = j; i < n_; ++i) \ *(pr++) = k++; \ } \ } \ } else { \ if (upper_) { \ for (j = 0; j < n_; ++j) { \ for (i = 0; i < j; ++i) \ *(pr++) = k++; \ k += n_-j; \ } \ } else { \ for (j = 0; j < n_; ++j) { \ k += j+1; \ for (i = j+1; i < n_; ++i) \ *(pr++) = k++; \ } \ } \ } \ } while (0) if (nx > INT_MAX) { PROTECT(r = allocVector(REALSXP, (R_xlen_t) nr)); double k = 1.0, nr_ = (double) nr, *pr = REAL(r); DO_INDEX; } else { PROTECT(r = allocVector(INTSXP, (R_xlen_t) nr)); int k = 1, nr_ = (int) nr, *pr = INTEGER(r); DO_INDEX; } #undef DO_INDEX UNPROTECT(1); return r; } SEXP R_index_diagonal(SEXP n, SEXP packed, SEXP upper) { SEXP r; int j, n_ = asInteger(n), packed_ = asLogical(packed), upper_ = asLogical(upper); Matrix_int_fast64_t nn = (Matrix_int_fast64_t) n_ * n_, nx = (packed_) ? n_ + (nn - n_) / 2 : nn; if (nx > 0x1.0p+53) error(_("indices would exceed %s"), "2^53"); #define DO_INDEX \ do { \ if (!packed_) { \ for (j = 0; j < n_; ++j) { \ *(pr++) = k++; \ k += n_; \ } \ } else if (upper_) { \ for (j = 0; j < n_; ++j) { \ *(pr++) = k; \ k += j+2; \ } \ } else { \ for (j = 0; j < n_; ++j) { \ *(pr++) = k; \ k += n_-j; \ } \ } \ } while (0) if (nx > INT_MAX) { PROTECT(r = allocVector(REALSXP, n_)); double k = 1.0, *pr = REAL(r); DO_INDEX; } else { PROTECT(r = allocVector(INTSXP, n_)); int k = 1, *pr = INTEGER(r); DO_INDEX; } #undef DO_INDEX UNPROTECT(1); return r; } SEXP R_nnz(SEXP x, SEXP countNA, SEXP nnzmax) { int do_countNA = asLogical(countNA); R_xlen_t n = XLENGTH(x), nnz = 0; double n_ = asReal(nnzmax); if (!ISNAN(n_) && n_ >= 0.0 && n_ < (double) n) n = (R_xlen_t) n_; #define DO_NNZ(_CTYPE_, _PTR_, _ISNA_, _ISNZ_, _STRICTLY_ISNZ_) \ do { \ _CTYPE_ *px = _PTR_(x); \ if (do_countNA == NA_LOGICAL) { \ while (n-- > 0) { \ if (_ISNA_(*px)) \ return ScalarInteger(NA_INTEGER); \ if (_ISNZ_(*px)) \ ++nnz; \ ++px; \ } \ } else if (do_countNA != 0) { \ while (n-- > 0) { \ if (_ISNZ_(*px)) \ ++nnz; \ ++px; \ } \ } else { \ while (n-- > 0) { \ if (_STRICTLY_ISNZ_(*px)) \ ++nnz; \ ++px; \ } \ } \ } while (0) switch (TYPEOF(x)) { case LGLSXP: DO_NNZ(int, LOGICAL, ISNA_LOGICAL, ISNZ_LOGICAL, STRICTLY_ISNZ_LOGICAL); break; case INTSXP: DO_NNZ(int, INTEGER, ISNA_INTEGER, ISNZ_INTEGER, STRICTLY_ISNZ_INTEGER); break; case REALSXP: DO_NNZ(double, REAL, ISNA_REAL, ISNZ_REAL, STRICTLY_ISNZ_REAL); break; case CPLXSXP: DO_NNZ(Rcomplex, COMPLEX, ISNA_COMPLEX, ISNZ_COMPLEX, STRICTLY_ISNZ_COMPLEX); break; default: ERROR_INVALID_TYPE(x, __func__); } #undef DO_NNZ return (nnz <= INT_MAX) ? ScalarInteger((int) nnz) : ScalarReal((double) nnz); } /* ================================================================== */ /* ================================================================== */ #define TRUE_ ScalarLogical(1) #define FALSE_ ScalarLogical(0) // Fast implementation of [ originally in ../R/Auxiliaries.R ] // all0 <- function(x) !any(is.na(x)) && all(!x) ## ~= allFalse // allFalse <- function(x) !any(x) && !any(is.na(x)) ## ~= all0 SEXP R_all0(SEXP x) { if (!isVectorAtomic(x)) { if (length(x) == 0) return TRUE_; // Typically S4. TODO: Call the R code above, instead! error(_("Argument must be numeric-like atomic vector")); } R_xlen_t i, n = XLENGTH(x); if (n == 0) return TRUE_; switch (TYPEOF(x)) { case LGLSXP: { int *xx = LOGICAL(x); for (i = 0; i < n; i++) if (xx[i] == NA_LOGICAL || xx[i] != 0) return FALSE_; return TRUE_; } case INTSXP: { int *xx = INTEGER(x); for (i = 0; i < n; i++) if (xx[i] == NA_INTEGER || xx[i] != 0) return FALSE_; return TRUE_; } case REALSXP: { double *xx = REAL(x); for (i = 0; i < n; i++) if (ISNAN(xx[i]) || xx[i] != 0.) return FALSE_; return TRUE_; } case RAWSXP: { unsigned char *xx = RAW(x); for (i = 0; i < n; i++) if (xx[i] != 0) return FALSE_; return TRUE_; } } error(_("Argument must be numeric-like atomic vector")); return R_NilValue; // -Wall } // Fast implementation of [ originally in ../R/Auxiliaries.R ] // any0 <- function(x) isTRUE(any(x == 0)) ## ~= anyFalse // anyFalse <- function(x) isTRUE(any(!x)) ## ~= any0 SEXP R_any0(SEXP x) { if (!isVectorAtomic(x)) { if (length(x) == 0) return FALSE_; // Typically S4. TODO: Call the R code above, instead! error(_("Argument must be numeric-like atomic vector")); } R_xlen_t i, n = XLENGTH(x); if (n == 0) return FALSE_; switch (TYPEOF(x)) { case LGLSXP: { int *xx = LOGICAL(x); for (i = 0; i < n; i++) if (xx[i] == 0) return TRUE_; return FALSE_; } case INTSXP: { int *xx = INTEGER(x); for (i = 0; i < n; i++) if (xx[i] == 0) return TRUE_; return FALSE_; } case REALSXP: { double *xx = REAL(x); for (i = 0; i < n; i++) if (xx[i] == 0.) return TRUE_; return FALSE_; } case RAWSXP: { unsigned char *xx = RAW(x); for (i = 0; i < n; i++) if (xx[i] == 0) return TRUE_; return FALSE_; } } error(_("Argument must be numeric-like atomic vector")); return R_NilValue; // -Wall } #undef TRUE_ #undef FALSE_ // Almost "Cut n Paste" from ...R../src/main/array.c do_matrix() : // used in ../R/Matrix.R as // // .External(Mmatrix, // data, nrow, ncol, byrow, dimnames, // missing(nrow), missing(ncol)) SEXP Mmatrix(SEXP args) { SEXP vals, ans, snr, snc, dimnames; int nr = 1, nc = 1, byrow, miss_nr, miss_nc; R_xlen_t lendat; args = CDR(args); /* skip 'name' */ vals = CAR(args); args = CDR(args); /* Supposedly as.vector() gave a vector type, but we check */ switch (TYPEOF(vals)) { case LGLSXP: case INTSXP: case REALSXP: case CPLXSXP: case STRSXP: case RAWSXP: case EXPRSXP: case VECSXP: break; default: error(_("'data' must be of a vector type")); } lendat = XLENGTH(vals); snr = CAR(args); args = CDR(args); snc = CAR(args); args = CDR(args); byrow = asLogical(CAR(args)); args = CDR(args); if (byrow == NA_INTEGER) error(_("invalid '%s' argument"), "byrow"); dimnames = CAR(args); args = CDR(args); miss_nr = asLogical(CAR(args)); args = CDR(args); miss_nc = asLogical(CAR(args)); if (!miss_nr) { if (!isNumeric(snr)) error(_("non-numeric matrix extent")); nr = asInteger(snr); if (nr == NA_INTEGER) error(_("invalid 'nrow' value (too large or NA)")); if (nr < 0) error(_("invalid 'nrow' value (< 0)")); } if (!miss_nc) { if (!isNumeric(snc)) error(_("non-numeric matrix extent")); nc = asInteger(snc); if (nc == NA_INTEGER) error(_("invalid 'ncol' value (too large or NA)")); if (nc < 0) error(_("invalid 'ncol' value (< 0)")); } if (miss_nr && miss_nc) { if (lendat > INT_MAX) error("data is too long"); nr = (int) lendat; } else if (miss_nr) { if (lendat > (double) nc * INT_MAX) error("data is too long"); nr = (int) ceil((double) lendat / (double) nc); } else if (miss_nc) { if (lendat > (double) nr * INT_MAX) error("data is too long"); nc = (int) ceil((double) lendat / (double) nr); } if (lendat > 0) { R_xlen_t nrc = (R_xlen_t) nr * nc; if (lendat > 1 && nrc % lendat != 0) { if ((lendat > nr && (lendat / nr) * nr != lendat) || (lendat < nr && (nr / lendat) * lendat != nr)) warning(_("data length [%lld] is not a sub-multiple " "or multiple of the number of rows [%d]"), (long long)lendat, nr); else if ((lendat > nc && (lendat / nc) * nc != lendat) || (lendat < nc && (nc / lendat) * lendat != nc)) warning(_("data length [%lld] is not a sub-multiple " "or multiple of the number of columns [%d]"), (long long)lendat, nc); } else if (lendat > 1 && nrc == 0) warning(_("data length exceeds size of matrix")); } #ifndef LONG_VECTOR_SUPPORT if ((double) nr * (double) nc > INT_MAX) error(_("too many elements specified")); #endif PROTECT(ans = allocMatrix(TYPEOF(vals), nr, nc)); if (lendat) { if (isVector(vals)) copyMatrix(ans, vals, byrow); else copyListMatrix(ans, vals, byrow); } else if (isVector(vals)) { /* fill with NAs */ R_xlen_t N = (R_xlen_t) nr * nc, i; switch (TYPEOF(vals)) { case STRSXP: for (i = 0; i < N; i++) SET_STRING_ELT(ans, i, NA_STRING); break; case LGLSXP: for (i = 0; i < N; i++) LOGICAL(ans)[i] = NA_LOGICAL; break; case INTSXP: for (i = 0; i < N; i++) INTEGER(ans)[i] = NA_INTEGER; break; case REALSXP: for (i = 0; i < N; i++) REAL(ans)[i] = NA_REAL; break; case CPLXSXP: { /* Initialization must work whether Rcomplex is typedef-ed to a struct { R < 4.3.0 } or to a union { R >= 4.3.0 } */ Rcomplex zna = { .r = NA_REAL, .i = 0.0 }; for (i = 0; i < N; i++) COMPLEX(ans)[i] = zna; break; } case RAWSXP: // FIXME: N may overflow size_t !! memset(RAW(ans), 0, N); break; default: /* don't fill with anything */ ; } } if (!isNull(dimnames)&& length(dimnames) > 0) ans = dimnamesgets(ans, dimnames); UNPROTECT(1); return ans; } /** * Expand compressed pointers in the array mp into a full set of indices * in the array mj. * * @param ncol number of columns (or rows) * @param mp column pointer vector of length ncol + 1 * @param mj vector of length mp[ncol] to hold the result * * @return mj */ static int *expand_cmprPt(int ncol, const int mp[], int mj[]) { int j; for (j = 0; j < ncol; j++) { int j2 = mp[j+1], jj; for (jj = mp[j]; jj < j2; jj++) mj[jj] = j; } return mj; } /** Return a 2 column matrix '' cbind(i, j) '' of 0-origin index vectors (i,j) * which entirely correspond to the (i,j) slots of * as(x, "TsparseMatrix") : */ SEXP compressed_non_0_ij(SEXP x, SEXP colP) { int col = asLogical(colP); /* 1 if "C"olumn compressed; 0 if "R"ow */ SEXP ans, indSym = col ? Matrix_iSym : Matrix_jSym; SEXP indP = PROTECT(GET_SLOT(x, indSym)), pP = PROTECT(GET_SLOT(x, Matrix_pSym)); int i, *ij; int nouter = INTEGER(GET_SLOT(x, Matrix_DimSym))[col ? 1 : 0], n_el = INTEGER(pP)[nouter]; /* is only == length(indP), if the inner slot is not over-allocated */ ij = INTEGER(ans = PROTECT(allocMatrix(INTSXP, n_el, 2))); /* expand the compressed margin to 'i' or 'j' : */ expand_cmprPt(nouter, INTEGER(pP), &ij[col ? n_el : 0]); /* and copy the other one: */ if (col) for(i = 0; i < n_el; i++) ij[i] = INTEGER(indP)[i]; else /* row compressed */ for(i = 0; i < n_el; i++) ij[i + n_el] = INTEGER(indP)[i]; UNPROTECT(3); return ans; } SEXP Matrix_expand_pointers(SEXP pP) { int n = length(pP) - 1; int *p = INTEGER(pP); SEXP ans = PROTECT(allocVector(INTSXP, p[n])); expand_cmprPt(n, p, INTEGER(ans)); UNPROTECT(1); return ans; } /** * Encode Matrix index (i,j) |--> i + j * nrow {i,j : 0-origin} * * @param ij: 2-column integer matrix * @param di: dim(.), i.e. length 2 integer vector * @param chk_bnds: logical indicating 0 <= ij[,k] < di[k] need to be checked. * * @return encoded index; integer if prod(dim) is small; double otherwise */ SEXP m_encodeInd(SEXP ij, SEXP di, SEXP orig_1, SEXP chk_bnds) { SEXP ans; int *ij_di = NULL, n, nprot=1; Rboolean check_bounds = asLogical(chk_bnds), one_ind = asLogical(orig_1); if (TYPEOF(di) != INTSXP) { di = PROTECT(coerceVector(di, INTSXP)); nprot++; } if (TYPEOF(ij) != INTSXP) { ij = PROTECT(coerceVector(ij, INTSXP)); nprot++; } if (!isMatrix(ij) || (ij_di = INTEGER(getAttrib(ij, R_DimSymbol)))[1] != 2) error(_("Argument ij must be 2-column integer matrix")); n = ij_di[0]; int *Di = INTEGER(di), *IJ = INTEGER(ij), *j_ = IJ+n;/* pointer offset! */ if ((Di[0] * (double) Di[1]) >= 1 + (double)INT_MAX) { /* need double */ ans = PROTECT(allocVector(REALSXP, n)); double *ii = REAL(ans), nr = (double) Di[0]; #define do_ii_FILL(_i_, _j_) \ int i; \ if (check_bounds) { \ for (i = 0; i < n; i++) { \ if (_i_[i] == NA_INTEGER || _j_[i] == NA_INTEGER) \ ii[i] = NA_INTEGER; \ else { \ register int i_i, j_i; \ if (one_ind) { \ i_i = _i_[i]-1; \ j_i = _j_[i]-1; \ } else { \ i_i = _i_[i]; \ j_i = _j_[i]; \ } \ if (i_i < 0 || i_i >= Di[0]) \ error(_("subscript 'i' out of bounds in M[ij]")); \ if (j_i < 0 || j_i >= Di[1]) \ error(_("subscript 'j' out of bounds in M[ij]")); \ ii[i] = i_i + j_i * nr; \ } \ } \ } else { \ for (i = 0; i < n; i++) \ ii[i] = (_i_[i] == NA_INTEGER || _j_[i] == NA_INTEGER) \ ? NA_INTEGER \ : ((one_ind) \ ? ((_i_[i]-1) + (_j_[i]-1) * nr) \ : _i_[i] + _j_[i] * nr); \ } do_ii_FILL(IJ, j_); } else { ans = PROTECT(allocVector(INTSXP, n)); int *ii = INTEGER(ans), nr = Di[0]; do_ii_FILL(IJ, j_); } UNPROTECT(nprot); return ans; } /** * Encode Matrix index (i,j) |--> i + j * nrow {i,j : 0-origin} * * @param i: integer vector * @param j: integer vector of same length as 'i' * @param orig_1: logical: if TRUE, "1-origin" otherwise "0-origin" * @param di: dim(.), i.e. length 2 integer vector * @param chk_bnds: logical indicating 0 <= ij[,k] < di[k] need to be checked. * * @return encoded index; integer if prod(dim) is small; double otherwise */ SEXP m_encodeInd2(SEXP i, SEXP j, SEXP di, SEXP orig_1, SEXP chk_bnds) { SEXP ans; int n = LENGTH(i), nprot = 1; Rboolean check_bounds = asLogical(chk_bnds), one_ind = asLogical(orig_1); if (TYPEOF(di)!= INTSXP) { di = PROTECT(coerceVector(di,INTSXP)); nprot++; } if (TYPEOF(i) != INTSXP) { i = PROTECT(coerceVector(i, INTSXP)); nprot++; } if (TYPEOF(j) != INTSXP) { j = PROTECT(coerceVector(j, INTSXP)); nprot++; } if (LENGTH(j) != n) error(_("i and j must be integer vectors of the same length")); int *Di = INTEGER(di), *i_ = INTEGER(i), *j_ = INTEGER(j); if ((Di[0] * (double) Di[1]) >= 1 + (double) INT_MAX) { /* need double */ ans = PROTECT(allocVector(REALSXP, n)); double *ii = REAL(ans), nr = (double) Di[0]; do_ii_FILL(i_, j_); } else { ans = PROTECT(allocVector(INTSXP, n)); int *ii = INTEGER(ans), nr = Di[0]; do_ii_FILL(i_, j_); } UNPROTECT(nprot); return ans; } #undef do_ii_FILL �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/products.c�������������������������������������������������������������������������������0000644�0001762�0000144�00000126751�14513776604�014345� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "Lapack-etc.h" #include "cholmod-etc.h" #include "Mdefines.h" #include "idz.h" #include "coerce.h" #include "dense.h" #include "sparse.h" #include "products.h" static void matmultDim(SEXP x, SEXP y, int *xtrans, int *ytrans, int *ztrans, int *m, int *n, int *v) { *xtrans = (*xtrans) ? 1 : 0; *ytrans = (*ytrans) ? 1 : 0; *ztrans = (*ztrans) ? 1 : 0; if (y == R_NilValue) { SEXP xdim = (TYPEOF(x) == S4SXP) ? GET_SLOT(x, Matrix_DimSym) : getAttrib(x, R_DimSymbol); if (TYPEOF(xdim) == INTSXP && LENGTH(xdim) == 2) { *v = 0; *m = *n = INTEGER(xdim)[(*xtrans) ? 1 : 0]; } else if (XLENGTH(x) <= INT_MAX) { *v = 1; *m = *n = (*xtrans) ? 1 : LENGTH(x); } else error(_("dimensions cannot exceed %s"), "2^31-1"); *ytrans = (*xtrans) ? 0 : 1; } else { /* MJ: So that I don't lose my mind ... : */ if (*ztrans) { int tmp = !(*xtrans); *xtrans = !(*ytrans); *ytrans = tmp; SEXP s = x; x = y; y = s; } SEXP xdim = (TYPEOF(x) == S4SXP) ? GET_SLOT(x, Matrix_DimSym) : getAttrib(x, R_DimSymbol), ydim = (TYPEOF(y) == S4SXP) ? GET_SLOT(y, Matrix_DimSym) : getAttrib(y, R_DimSymbol); int xm, xn, ym, yn, x2, y2; xm = xn = ym = yn = -1; x2 = TYPEOF(xdim) == INTSXP && LENGTH(xdim) == 2; y2 = TYPEOF(ydim) == INTSXP && LENGTH(ydim) == 2; if (x2) { int *pxdim = INTEGER(xdim); xm = pxdim[0]; xn = pxdim[1]; } else if (XLENGTH(x) > INT_MAX) error(_("dimensions cannot exceed %s"), "2^31-1"); if (y2) { int *pydim = INTEGER(ydim); ym = pydim[0]; yn = pydim[1]; } else if (XLENGTH(y) > INT_MAX) error(_("dimensions cannot exceed %s"), "2^31-1"); /* MJ: R's do_matprod behaves quite asymmetrically ... what a pain */ if (x2 && y2) *v = 0; else if (y2) { *v = (*ztrans) ? 2 : 1; int k = (*ytrans) ? yn : ym, xl = LENGTH(x); if (k == xl || (k == 1 && !(*xtrans))) { xm = (int) xl; xn = 1; *xtrans = (k == xl) ? 1 : 0; } } else if (x2) { *v = (*ztrans) ? 1 : 2; int k = (*xtrans) ? xm : xn, yl = LENGTH(y); if (*ytrans) { if (xm == 1 || xn == 1) { ym = (int) yl; yn = 1; *ytrans = (((*xtrans) ? xn : xm) == 1) ? 0 : 1; } } else { if (k == yl || k == 1) { ym = (int) yl; yn = 1; *ytrans = (k == yl) ? 0 : 1; } } } else { *v = 3; int xl = LENGTH(x), yl = LENGTH(y); if (*xtrans) { xm = xl; xn = 1; ym = yl; yn = 1; *ytrans = xl == 1; } else if (*ytrans) { xm = xl; xn = 1; ym = yl; yn = 1; /* *xtrans = 0; */ } else { xm = 1; xn = xl; ym = (xl == 1) ? 1 : yl; yn = (xl == 1) ? yl : 1; } } if (((*xtrans) ? xm : xn) != ((*ytrans) ? yn : ym)) error(_("non-conformable arguments")); *m = (*xtrans) ? xn : xm; *n = (*ytrans) ? ym : yn; if (*ztrans) { int tmp = !(*xtrans); *xtrans = !(*ytrans); *ytrans = tmp; tmp = *m; *m = *n; *n = tmp; } } return; } static void matmultDN(SEXP dest, SEXP asrc, int ai, SEXP bsrc, int bi) { SEXP s; if (!isNull(s = VECTOR_ELT(asrc, ai))) SET_VECTOR_ELT(dest, 0, s); if (!isNull(s = VECTOR_ELT(bsrc, bi))) SET_VECTOR_ELT(dest, 1, s); PROTECT(asrc = getAttrib(asrc, R_NamesSymbol)); PROTECT(bsrc = getAttrib(bsrc, R_NamesSymbol)); if (!isNull(asrc) || !isNull(bsrc)) { SEXP destnms = PROTECT(allocVector(STRSXP, 2)); if (!isNull(asrc) && *CHAR(s = STRING_ELT(asrc, ai)) != '\0') SET_STRING_ELT(destnms, 0, s); if (!isNull(bsrc) && *CHAR(s = STRING_ELT(bsrc, bi)) != '\0') SET_STRING_ELT(destnms, 1, s); setAttrib(dest, R_NamesSymbol, destnms); UNPROTECT(1); } UNPROTECT(2); return; } /* op() * op() */ static SEXP dgeMatrix_matmult(SEXP a, SEXP b, int atrans, int btrans) { SEXP adim = GET_SLOT(a, Matrix_DimSym); int *padim = INTEGER(adim), am = padim[0], an = padim[1], rm = (atrans) ? an : am, rk = (atrans) ? am : an; if (b == R_NilValue) { if ((Matrix_int_fast64_t) rm * rm > R_XLEN_T_MAX) error(_("attempt to allocate vector of length exceeding %s"), "R_XLEN_T_MAX"); SEXP ax = PROTECT(GET_SLOT(a, Matrix_xSym)); char rcl[] = ".poMatrix"; rcl[0] = (TYPEOF(ax) == CPLXSXP) ? 'z' : 'd'; SEXP r = PROTECT(newObject(rcl)); SEXP rdim = GET_SLOT(r, Matrix_DimSym); int *prdim = INTEGER(rdim); prdim[0] = prdim[1] = rm; SEXP adimnames = PROTECT(GET_SLOT(a, Matrix_DimNamesSym)), rdimnames = PROTECT(GET_SLOT(r, Matrix_DimNamesSym)); symDN(rdimnames, adimnames, (atrans) ? 1 : 0); UNPROTECT(2); /* rdimnames, adimnames */ if (rm > 0) { SEXP rx = PROTECT(allocVector(TYPEOF(ax), (R_xlen_t) rm * rm)); #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(ax) == CPLXSXP) { Rcomplex *prx = COMPLEX(rx); Matrix_memset(prx, 0, (R_xlen_t) rm * rm, sizeof(Rcomplex)); if (rk > 0) { Rcomplex *pax = COMPLEX(ax), zero = Matrix_zzero, one = Matrix_zone; F77_CALL(zsyrk)( "U", (atrans) ? "T" : "N", &rm, &rk, &one, pax, &am, &zero, prx, &rm FCONE FCONE); } } else { #endif double *prx = REAL(rx); Matrix_memset(prx, 0, (R_xlen_t) rm * rm, sizeof(double)); if (rk > 0) { double *pax = REAL(ax), zero = 0.0, one = 1.0; F77_CALL(dsyrk)( "U", (atrans) ? "T" : "N", &rm, &rk, &one, pax, &am, &zero, prx, &rm FCONE FCONE); } #ifdef MATRIX_ENABLE_ZMATRIX } #endif SET_SLOT(r, Matrix_xSym, rx); UNPROTECT(1); /* rx */ } UNPROTECT(2); /* r, ax */ return r; } else { SEXP bdim = GET_SLOT(b, Matrix_DimSym); int *pbdim = INTEGER(bdim), bm = pbdim[0], bn = pbdim[1], rn = (btrans) ? bm : bn; if (rk != ((btrans) ? bn : bm)) error(_("non-conformable arguments")); if ((Matrix_int_fast64_t) rm * rn > R_XLEN_T_MAX) error(_("attempt to allocate vector of length exceeding %s"), "R_XLEN_T_MAX"); SEXP ax = PROTECT(GET_SLOT(a, Matrix_xSym)); char rcl[] = ".geMatrix"; rcl[0] = (TYPEOF(ax) == CPLXSXP) ? 'z' : 'd'; SEXP r = PROTECT(newObject(rcl)); SEXP rdim = GET_SLOT(r, Matrix_DimSym); int *prdim = INTEGER(rdim); prdim[0] = rm; prdim[1] = rn; SEXP adimnames = PROTECT(GET_SLOT(a, Matrix_DimNamesSym)), bdimnames = PROTECT(GET_SLOT(b, Matrix_DimNamesSym)), rdimnames = PROTECT(GET_SLOT(r, Matrix_DimNamesSym)); matmultDN(rdimnames, adimnames, (atrans) ? 1 : 0, bdimnames, (btrans) ? 0 : 1); UNPROTECT(3); /* rdimnames, bdimnames, adimnames */ if (rm > 0 && rn > 0) { SEXP rx = PROTECT(allocVector(TYPEOF(ax), (R_xlen_t) rm * rn)); #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(ax) == CPLXSXP) { Rcomplex *prx = COMPLEX(rx); if (rk == 0) Matrix_memset(prx, 0, (R_xlen_t) rm * rn, sizeof(Rcomplex)); else { SEXP bx = PROTECT(GET_SLOT(b, Matrix_xSym)); Rcomplex *pax = COMPLEX(ax), *pbx = COMPLEX(bx), zero = Matrix_zzero, one = Matrix_zone; F77_CALL(zgemm)( (atrans) ? "T" : "N", (btrans) ? "T" : "N", &rm, &rn, &rk, &one, pax, &am, pbx, &bm, &zero, prx, &rm FCONE FCONE); UNPROTECT(1); /* bx */ } } else { #endif double *prx = REAL(rx); if (rk == 0) Matrix_memset(prx, 0, (R_xlen_t) rm * rn, sizeof(double)); else { SEXP bx = PROTECT(GET_SLOT(b, Matrix_xSym)); double *pax = REAL(ax), *pbx = REAL(bx), zero = 0.0, one = 1.0; F77_CALL(dgemm)( (atrans) ? "T" : "N", (btrans) ? "T" : "N", &rm, &rn, &rk, &one, pax, &am, pbx, &bm, &zero, prx, &rm FCONE FCONE); UNPROTECT(1); /* bx */ } #ifdef MATRIX_ENABLE_ZMATRIX } #endif SET_SLOT(r, Matrix_xSym, rx); UNPROTECT(1); /* rx */ } UNPROTECT(2); /* r, ax */ return r; } } /* * op() or op() * */ static SEXP dsyMatrix_matmult(SEXP a, SEXP b, int aleft, int btrans) { SEXP adim = GET_SLOT(a, Matrix_DimSym); int rk = INTEGER(adim)[0]; SEXP bdim = GET_SLOT(b, Matrix_DimSym); int *pbdim = INTEGER(bdim), bm = pbdim[0], bn = pbdim[1], rm = (btrans) ? bn : bm, rn = (btrans) ? bm : bn; if (rk != ((aleft == btrans) ? bn : bm)) error(_("non-conformable arguments")); if ((Matrix_int_fast64_t) rm * rn > R_XLEN_T_MAX) error(_("attempt to allocate vector of length exceeding %s"), "R_XLEN_T_MAX"); SEXP ax = PROTECT(GET_SLOT(a, Matrix_xSym)); char rcl[] = ".geMatrix"; rcl[0] = (TYPEOF(ax) == CPLXSXP) ? 'z' : 'd'; SEXP r = PROTECT(newObject(rcl)); SEXP rdim = GET_SLOT(r, Matrix_DimSym); int *prdim = INTEGER(rdim); prdim[0] = rm; prdim[1] = rn; SEXP adimnames = PROTECT(get_symmetrized_DimNames(a, -1)), bdimnames = PROTECT(GET_SLOT(b, Matrix_DimNamesSym)), rdimnames = PROTECT(GET_SLOT(r, Matrix_DimNamesSym)); if (aleft) matmultDN(rdimnames, adimnames, 0, bdimnames, !btrans); else matmultDN(rdimnames, bdimnames, btrans, adimnames, 1); UNPROTECT(3); /* rdimnames, bdimnames, adimnames */ if (rm > 0 && rn > 0) { SEXP auplo = PROTECT(GET_SLOT(a, Matrix_uploSym)), bx = PROTECT(GET_SLOT(b, Matrix_xSym)), rx = PROTECT(allocVector(TYPEOF(ax), (R_xlen_t) rm * rn)); char aul = *CHAR(STRING_ELT(auplo, 0)); int i, d = (aleft) ? rn : rm, binc = (aleft) ? bm : 1, bincp = (aleft) ? 1 : bm, rinc = (aleft) ? 1 : rm, rincp = (aleft) ? rm : 1; #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(ax) == CPLXSXP) { Rcomplex *pax = COMPLEX(ax), *pbx = COMPLEX(bx), *prx = COMPLEX(rx), zero = Matrix_zero, one = Matrix_zone; if (!btrans) F77_CALL(zsymm)( (aleft) ? "L" : "R", &aul, &rm, &rn, &one, pax, &rk, pbx, &bm, &zero, prx, &rm FCONE FCONE); else { for (i = 0; i < d; ++i) { F77_CALL(zsymv)( &aul, &rk, &one, pax, &rk, pbx, &binc, &zero, prx, &rinc FCONE); pbx += bincp; prx += rincp; } } } else { #endif double *pax = REAL(ax), *pbx = REAL(bx), *prx = REAL(rx), zero = 0.0, one = 1.0; if (!btrans) F77_CALL(dsymm)( (aleft) ? "L" : "R", &aul, &rm, &rn, &one, pax, &rk, pbx, &bm, &zero, prx, &rm FCONE FCONE); else { for (i = 0; i < d; ++i) { F77_CALL(dsymv)( &aul, &rk, &one, pax, &rk, pbx, &binc, &zero, prx, &rinc FCONE); pbx += bincp; prx += rincp; } } #ifdef MATRIX_ENABLE_ZMATRIX } #endif SET_SLOT(r, Matrix_xSym, rx); UNPROTECT(3); /* rx, bx, auplo */ } UNPROTECT(2); /* r, ax */ return r; } /* * op() or op() * */ static SEXP dspMatrix_matmult(SEXP a, SEXP b, int aleft, int btrans) { SEXP adim = GET_SLOT(a, Matrix_DimSym); int rk = INTEGER(adim)[0]; SEXP bdim = GET_SLOT(b, Matrix_DimSym); int *pbdim = INTEGER(bdim), bm = pbdim[0], bn = pbdim[1], rm = (btrans) ? bn : bm, rn = (btrans) ? bm : bn; if (rk != ((aleft == btrans) ? bn : bm)) error(_("non-conformable arguments")); if ((Matrix_int_fast64_t) rm * rn > R_XLEN_T_MAX) error(_("attempt to allocate vector of length exceeding %s"), "R_XLEN_T_MAX"); SEXP ax = PROTECT(GET_SLOT(a, Matrix_xSym)); char rcl[] = ".geMatrix"; rcl[0] = (TYPEOF(ax) == CPLXSXP) ? 'z' : 'd'; SEXP r = PROTECT(newObject(rcl)); SEXP rdim = GET_SLOT(r, Matrix_DimSym); int *prdim = INTEGER(rdim); prdim[0] = rm; prdim[1] = rn; SEXP adimnames = PROTECT(get_symmetrized_DimNames(a, -1)), bdimnames = PROTECT(GET_SLOT(b, Matrix_DimNamesSym)), rdimnames = PROTECT(GET_SLOT(r, Matrix_DimNamesSym)); if (aleft) matmultDN(rdimnames, adimnames, 0, bdimnames, !btrans); else matmultDN(rdimnames, bdimnames, btrans, adimnames, 1); UNPROTECT(3); /* rdimnames, bdimnames, adimnames */ if (rm > 0 && rn > 0) { SEXP auplo = PROTECT(GET_SLOT(a, Matrix_uploSym)), bx = PROTECT(GET_SLOT(b, Matrix_xSym)), rx = PROTECT(allocVector(REALSXP, (R_xlen_t) rm * rn)); char aul = *CHAR(STRING_ELT(auplo, 0)); int i, d = (aleft) ? rn : rm, binc = (aleft == btrans) ? bm : 1, bincp = (aleft == btrans) ? 1 : bm, rinc = (aleft ) ? 1 : rm, rincp = (aleft ) ? rm : 1; #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(ax) == CPLXSXP) { Rcomplex *pax = COMPLEX(ax), *pbx = COMPLEX(bx), *prx = COMPLEX(rx), zero = Matrix_zzero, one = Matrix_zone; for (i = 0; i < d; ++i) { F77_CALL(zspmv)( &aul, &rk, &one, pax, pbx, &binc, &zero, prx, &rinc FCONE); pbx += bincp; prx += rincp; } } else { #endif double *pax = REAL(ax), *pbx = REAL(bx), *prx = REAL(rx), zero = 0.0, one = 1.0; for (i = 0; i < d; ++i) { F77_CALL(dspmv)( &aul, &rk, &one, pax, pbx, &binc, &zero, prx, &rinc FCONE); pbx += bincp; prx += rincp; } #ifdef MATRIX_ENABLE_ZMATRIX } #endif SET_SLOT(r, Matrix_xSym, rx); UNPROTECT(3); /* rx, bx, auplo */ } UNPROTECT(2); /* r, ax */ return r; } /* op() * op() or op() * op() */ static SEXP dtrMatrix_matmult(SEXP a, SEXP b, int aleft, int atrans, int btrans, int triangular) { SEXP adim = GET_SLOT(a, Matrix_DimSym); int rk = INTEGER(adim)[0]; SEXP bdim = GET_SLOT(b, Matrix_DimSym); int *pbdim = INTEGER(bdim), bm = pbdim[0], bn = pbdim[1], rm = (btrans) ? bn : bm, rn = (btrans) ? bm : bn; if (rk != ((aleft == btrans) ? bn : bm)) error(_("non-conformable arguments")); if ((Matrix_int_fast64_t) rm * rn > R_XLEN_T_MAX) error(_("attempt to allocate vector of length exceeding %s"), "R_XLEN_T_MAX"); SEXP ax = PROTECT(GET_SLOT(a, Matrix_xSym)); char rcl[] = "...Matrix"; rcl[0] = (TYPEOF(ax) == CPLXSXP) ? 'z' : 'd'; rcl[1] = (triangular > 0) ? 't' : 'g'; rcl[2] = (triangular > 0) ? 'r' : 'e'; SEXP r = PROTECT(newObject(rcl)); SEXP rdim = GET_SLOT(r, Matrix_DimSym); int *prdim = INTEGER(rdim); prdim[0] = rm; prdim[1] = rn; SEXP adimnames = PROTECT(GET_SLOT(a, Matrix_DimNamesSym)), bdimnames = PROTECT(GET_SLOT(b, Matrix_DimNamesSym)), rdimnames = PROTECT(GET_SLOT(r, Matrix_DimNamesSym)); if (aleft) matmultDN(rdimnames, adimnames, atrans, bdimnames, !btrans); else matmultDN(rdimnames, bdimnames, btrans, adimnames, !atrans); UNPROTECT(3); /* rdimnames, bdimnames, adimnames */ SEXP auplo = GET_SLOT(a, Matrix_uploSym); char aul = *CHAR(STRING_ELT(auplo, 0)); if (triangular > 0 && ((atrans) ? aul == 'U' : aul != 'U')) { if (atrans) auplo = mkString("L"); PROTECT(auplo); SET_SLOT(r, Matrix_uploSym, auplo); UNPROTECT(1); /* auplo */ } SEXP adiag = GET_SLOT(a, Matrix_diagSym); char adi = *CHAR(STRING_ELT(adiag, 0)); if (triangular > 1 && adi != 'N') { PROTECT(adiag); SET_SLOT(r, Matrix_diagSym, adiag); UNPROTECT(1); /* adiag */ } if (rm > 0 && rn > 0) { SEXP bx = PROTECT(GET_SLOT(b, Matrix_xSym)), rx = PROTECT(allocVector(TYPEOF(ax), (R_xlen_t) rm * rn)); #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(ax) == CPLXSXP) { Rcomplex *pax = COMPLEX(ax), *pbx = COMPLEX(bx), *prx = COMPLEX(rx), one = Matrix_zone; if (!btrans) Matrix_memcpy(prx, pbx, (R_xlen_t) bm * bn, sizeof(Rcomplex)); else ztranspose2(prx, pbx, bm, bn); F77_CALL(ztrmm)( (aleft) ? "L" : "R", &aul, (atrans) ? "T" : "N", &adi, &rm, &rn, &one, pax, &rk, prx, &rm FCONE FCONE FCONE FCONE); } else { #endif double *pax = REAL(ax), *pbx = REAL(bx), *prx = REAL(rx), one = 1.0; if (!btrans) Matrix_memcpy(prx, pbx, (R_xlen_t) bm * bn, sizeof(double)); else dtranspose2(prx, pbx, bm, bn); F77_CALL(dtrmm)( (aleft) ? "L" : "R", &aul, (atrans) ? "T" : "N", &adi, &rm, &rn, &one, pax, &rk, prx, &rm FCONE FCONE FCONE FCONE); #ifdef MATRIX_ENABLE_ZMATRIX } #endif SET_SLOT(r, Matrix_xSym, rx); UNPROTECT(2); /* rx, bx */ } UNPROTECT(2); /* r, ax */ return r; } /* op() * op() or op() * op() */ static SEXP dtpMatrix_matmult(SEXP a, SEXP b, int aleft, int atrans, int btrans, int triangular) { SEXP adim = GET_SLOT(a, Matrix_DimSym); int rk = INTEGER(adim)[0]; SEXP bdim = GET_SLOT(b, Matrix_DimSym); int *pbdim = INTEGER(bdim), bm = pbdim[0], bn = pbdim[1], rm = (btrans) ? bn : bm, rn = (btrans) ? bm : bn; if (rk != ((aleft == btrans) ? bn : bm)) error(_("non-conformable arguments")); if ((Matrix_int_fast64_t) rm * rn > R_XLEN_T_MAX) error(_("attempt to allocate vector of length exceeding %s"), "R_XLEN_T_MAX"); SEXP ax = PROTECT(GET_SLOT(a, Matrix_xSym)); char rcl[] = "...Matrix"; rcl[0] = (TYPEOF(ax) == CPLXSXP) ? 'z' : 'd'; rcl[1] = (triangular > 0) ? 't' : 'g'; rcl[2] = (triangular > 0) ? 'r' : 'e'; SEXP r = PROTECT(newObject(rcl)); SEXP rdim = GET_SLOT(r, Matrix_DimSym); int *prdim = INTEGER(rdim); prdim[0] = rm; prdim[1] = rn; SEXP adimnames = PROTECT(GET_SLOT(a, Matrix_DimNamesSym)), bdimnames = PROTECT(GET_SLOT(b, Matrix_DimNamesSym)), rdimnames = PROTECT(GET_SLOT(r, Matrix_DimNamesSym)); if (aleft) matmultDN(rdimnames, adimnames, atrans, bdimnames, !btrans); else matmultDN(rdimnames, bdimnames, btrans, adimnames, !atrans); UNPROTECT(3); /* rdimnames, bdimnames, adimnames */ SEXP auplo = GET_SLOT(a, Matrix_uploSym); char aul = *CHAR(STRING_ELT(auplo, 0)); if (triangular > 0 && ((atrans) ? aul == 'U' : aul != 'U')) { if (atrans) auplo = mkString("L"); PROTECT(auplo); SET_SLOT(r, Matrix_uploSym, auplo); UNPROTECT(1); /* auplo */ } SEXP adiag = GET_SLOT(a, Matrix_diagSym); char adi = *CHAR(STRING_ELT(adiag, 0)); if (triangular > 1 && adi != 'N') { PROTECT(adiag); SET_SLOT(r, Matrix_diagSym, adiag); UNPROTECT(1); /* adiag */ } if (rm > 0 && rn > 0) { SEXP bx = PROTECT(GET_SLOT(b, Matrix_xSym)), rx = PROTECT(allocVector(REALSXP, (R_xlen_t) rm * rn)); int i, rinc = (aleft) ? 1 : rm, rincp = (aleft) ? rm : 1; #ifdef MATRIX_ENABLE_ZMATRIX if (TYPEOF(ax) == CPLXSXP) { Rcomplex *pax = COMPLEX(ax), *pbx = COMPLEX(bx), *prx = COMPLEX(rx); if (!btrans) Matrix_memcpy(prx, pbx, (R_xlen_t) bm * bn, sizeof(Rcomplex)); else ztranspose2(prx, pbx, bm, bn); for (i = 0; i < rn; ++i) { F77_CALL(ztpmv)( &aul, (aleft == atrans) ? "T" : "N", &adi, &rk, pax, prx, &rinc FCONE FCONE FCONE); prx += rincp; } } else { #endif double *pax = REAL(ax), *pbx = REAL(bx), *prx = REAL(rx); if (!btrans) Matrix_memcpy(prx, pbx, (R_xlen_t) bm * bn, sizeof(double)); else dtranspose2(prx, pbx, bm, bn); for (i = 0; i < rn; ++i) { F77_CALL(dtpmv)( &aul, (aleft == atrans) ? "T" : "N", &adi, &rk, pax, prx, &rinc FCONE FCONE FCONE); prx += rincp; } #ifdef MATRIX_ENABLE_ZMATRIX } #endif SET_SLOT(r, Matrix_xSym, rx); UNPROTECT(2); /* rx, bx */ } UNPROTECT(2); /* r, ax */ return r; } SEXP R_dense_matmult(SEXP x, SEXP y, SEXP xtrans, SEXP ytrans) { int xtrans_ = LOGICAL(xtrans)[0], ytrans_ = LOGICAL(ytrans)[0], ztrans_ = 0, m, n, v; matmultDim(x, y, &xtrans_, &ytrans_, &ztrans_, &m, &n, &v); PROTECT_INDEX xpid, ypid; PROTECT_WITH_INDEX(x, &xpid); PROTECT_WITH_INDEX(y, &ypid); if (TYPEOF(x) != S4SXP) { REPROTECT(x = matrix_as_dense(x, ",ge", '\0', '\0', xtrans_, 0), xpid); if (v == 1) { /* Vector: discard names and don't transpose again */ SET_VECTOR_ELT(GET_SLOT(x, Matrix_DimNamesSym), (xtrans_) ? 1 : 0, R_NilValue); xtrans_ = 0; } } if (TYPEOF(y) != S4SXP && y != R_NilValue) { REPROTECT(y = matrix_as_dense(y, ",ge", '\0', '\0', ytrans_, 0), ypid); if (v == 2) { /* Vector: discard names and don't transpose again */ SET_VECTOR_ELT(GET_SLOT(y, Matrix_DimNamesSym), (ytrans_) ? 1 : 0, R_NilValue); ytrans_ = 0; } } static const char *valid[] = { VALID_DENSE, "" }; const char *xcl = NULL, *ycl = NULL; int ivalid; ivalid = R_check_class_etc(x, valid); if (ivalid < 0) ERROR_INVALID_CLASS(x, __func__); xcl = valid[ivalid]; if (y != R_NilValue) { ivalid = R_check_class_etc(y, valid); if (ivalid < 0) ERROR_INVALID_CLASS(y, __func__); ycl = valid[ivalid]; } char kind = (xcl[0] == 'z' || (y != R_NilValue && ycl[0] == 'z')) ? 'z' : 'd'; if (xcl[0] != kind) { REPROTECT(x = dense_as_kind(x, xcl, kind, 0), xpid); xcl = valid[R_check_class_etc(x, valid)]; } if (y != R_NilValue) { if (ycl[0] != kind) { REPROTECT(y = dense_as_kind(y, ycl, kind, 0), ypid); ycl = valid[R_check_class_etc(y, valid)]; } } if (y == R_NilValue) { REPROTECT(x = dense_as_general(x, xcl, 1), xpid); x = dgeMatrix_matmult(x, y, xtrans_, !xtrans_); } else if (xcl[1] == 'g' && ycl[1] == 'g') { x = dgeMatrix_matmult(x, y, xtrans_, ytrans_); } else if (xcl[1] == 'g' || ycl[1] == 'g') { x = (xcl[1] == 'g') ? ((ycl[1] == 's') ? ((ycl[2] != 'p') ? dsyMatrix_matmult(y, x, 0, xtrans_) : dspMatrix_matmult(y, x, 0, xtrans_)) : ((ycl[2] != 'p') ? dtrMatrix_matmult(y, x, 0, ytrans_, xtrans_, 0) : dtpMatrix_matmult(y, x, 0, ytrans_, xtrans_, 0))) : ((xcl[1] == 's') ? ((xcl[2] != 'p') ? dsyMatrix_matmult(x, y, 1, ytrans_) : dspMatrix_matmult(x, y, 1, ytrans_)) : ((xcl[2] != 'p') ? dtrMatrix_matmult(x, y, 1, xtrans_, ytrans_, 0) : dtpMatrix_matmult(x, y, 1, xtrans_, ytrans_, 0))); } else if (xcl[1] == 's' && ycl[1] == 's') { if (xcl[2] == 'p' && ycl[2] == 'p') { REPROTECT(y = dense_as_general(y, ycl, 1), ypid); x = dspMatrix_matmult(x, y, 1, ytrans_); } else if (xcl[2] == 'p') { REPROTECT(x = dense_as_general(x, xcl, 1), xpid); x = dsyMatrix_matmult(y, x, 0, xtrans_); } else { REPROTECT(y = dense_as_general(y, ycl, 1), ypid); x = dsyMatrix_matmult(x, y, 1, ytrans_); } } else if (xcl[1] == 's' || ycl[1] == 's') { if (xcl[1] == 's') { REPROTECT(x = dense_as_general(x, xcl, 1), xpid); x = (ycl[2] != 'p') ? dtrMatrix_matmult(y, x, 0, ytrans_, 0, 0) : dtpMatrix_matmult(y, x, 0, ytrans_, 0, 0); } else { REPROTECT(y = dense_as_general(y, ycl, 1), ypid); x = (xcl[2] != 'p') ? dtrMatrix_matmult(x, y, 1, xtrans_, 0, 0) : dtpMatrix_matmult(x, y, 1, xtrans_, 0, 0); } } else { SEXP xuplo = PROTECT(GET_SLOT(x, Matrix_uploSym)), yuplo = PROTECT(GET_SLOT(y, Matrix_uploSym)), xdiag = PROTECT(GET_SLOT(x, Matrix_diagSym)), ydiag = PROTECT(GET_SLOT(y, Matrix_diagSym)); char xul = *CHAR(STRING_ELT(xuplo, 0)), yul = *CHAR(STRING_ELT(yuplo, 0)), xdi = *CHAR(STRING_ELT(xdiag, 0)), ydi = *CHAR(STRING_ELT(ydiag, 0)); if (xtrans_) xul = (xul == 'U') ? 'L' : 'U'; if (ytrans_) yul = (yul == 'U') ? 'L' : 'U'; int triangular = (xul != yul) ? 0 : ((xdi != ydi || xdi == 'N') ? 1 : 2); UNPROTECT(4); /* ydiag, xdiag, yuplo, xuplo */ if (xcl[2] == 'p' && ycl[2] == 'p') { REPROTECT(y = dense_as_general(y, ycl, 1), ypid); x = dtpMatrix_matmult(x, y, 1, xtrans_, ytrans_, triangular); } else if (xcl[2] == 'p') { REPROTECT(x = dense_as_general(x, xcl, 1), xpid); x = dtrMatrix_matmult(y, x, 0, ytrans_, xtrans_, triangular); } else { REPROTECT(y = dense_as_general(y, ycl, 1), ypid); x = dtrMatrix_matmult(x, y, 1, xtrans_, ytrans_, triangular); } } UNPROTECT(2); /* y, x */ return x; } /* boolean: op(op(<.gC>) & op(<.gC>)) */ /* numeric: op(op() * op()) */ static SEXP dgCMatrix_dgCMatrix_matmult(SEXP x, SEXP y, int xtrans, int ytrans, int ztrans, int triangular, int boolean) { PROTECT_INDEX zpid; SEXP z; char zcl[] = "..CMatrix"; zcl[0] = (boolean) ? 'n' : 'd'; if (y == R_NilValue) { zcl[1] = 's'; cholmod_sparse *X = M2CHS(x, !boolean); if (X->xtype == CHOLMOD_COMPLEX) error(_("'%s' does not support complex matrices"), "cholmod_aat"); if (xtrans) X = cholmod_transpose(X, !boolean, &c); cholmod_sparse *Z = cholmod_aat(X, (int *) NULL, 0, !boolean, &c); if (xtrans) cholmod_free_sparse(&X, &c); Z->stype = (ztrans) ? -1 : 1; cholmod_sort(Z, &c); PROTECT_WITH_INDEX(z = CHS2M(Z, !boolean, zcl[1]), &zpid); cholmod_free_sparse(&Z, &c); SEXP xdimnames = PROTECT(GET_SLOT(x, Matrix_DimNamesSym)), zdimnames = PROTECT(GET_SLOT(z, Matrix_DimNamesSym)); symDN(zdimnames, xdimnames, (xtrans) ? 1 : 0); UNPROTECT(2); /* zdimnames, xdimnames */ if (ztrans) { SEXP uplo = PROTECT(mkString("L")); SET_SLOT(z, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ } } else { zcl[1] = (triangular != 0) ? 't' : 'g'; cholmod_sparse *X = M2CHS(x, !boolean), *Y = M2CHS(y, !boolean); if (X->xtype == CHOLMOD_COMPLEX || Y->xtype == CHOLMOD_COMPLEX) error(_("'%s' does not support complex matrices"), "cholmod_ssmult"); if (((xtrans) ? X->nrow : X->ncol) != ((ytrans) ? Y->ncol : Y->nrow)) error(_("non-conformable arguments")); if (xtrans) X = cholmod_transpose(X, !boolean, &c); if (ytrans) Y = cholmod_transpose(Y, !boolean, &c); cholmod_sparse *Z = cholmod_ssmult(X, Y, 0, !boolean, 1, &c); if (xtrans) cholmod_free_sparse(&X, &c); if (ytrans) cholmod_free_sparse(&Y, &c); PROTECT_WITH_INDEX(z = CHS2M(Z, !boolean, zcl[1]), &zpid); cholmod_free_sparse(&Z, &c); SEXP xdimnames = PROTECT(GET_SLOT(x, Matrix_DimNamesSym)), ydimnames = PROTECT(GET_SLOT(y, Matrix_DimNamesSym)), zdimnames = PROTECT(GET_SLOT(z, Matrix_DimNamesSym)); matmultDN(zdimnames, xdimnames, (xtrans) ? 1 : 0, ydimnames, (ytrans) ? 0 : 1); UNPROTECT(3); /* zdimnames, ydimnames, xdimnames */ if (triangular < 0) { SEXP uplo = PROTECT(mkString("L")); SET_SLOT(z, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ } if (triangular < -1 || triangular > 1) REPROTECT(z = sparse_diag_N2U(z, zcl), zpid); } if (ztrans) REPROTECT(z = sparse_transpose(z, zcl, 1), zpid); UNPROTECT(1); /* z */ return z; } /* op(op() * op()) */ static SEXP dgCMatrix_dgeMatrix_matmult(SEXP x, SEXP y, int xtrans, int ytrans, int ztrans, int triangular, int symmetric) { SEXP z; char zcl[] = "...Matrix"; cholmod_sparse *X = M2CHS(x, 1); cholmod_dense *Y = M2CHD(y, ytrans); zcl[0] = (X->xtype == CHOLMOD_COMPLEX || Y->xtype == CHOLMOD_COMPLEX) ? 'z' : 'd'; zcl[1] = (triangular) ? 't' : 'g'; zcl[2] = (triangular) ? 'r' : 'e'; X->stype = symmetric; if (((xtrans) ? X->nrow : X->ncol) != Y->nrow) { if (ytrans) R_Free(Y->x); error(_("non-conformable arguments")); } int m = (int) ((xtrans) ? X->ncol : X->nrow), n = (int) Y->ncol; if ((Matrix_int_fast64_t) m * n > R_XLEN_T_MAX) { if (ytrans) R_Free(Y->x); error(_("attempt to allocate vector of length exceeding %s"), "R_XLEN_T_MAX"); } cholmod_dense *Z = (cholmod_dense *) R_alloc(1, sizeof(cholmod_dense)); memset(Z, 0, sizeof(cholmod_dense)); Z->nrow = (size_t) m; Z->ncol = (size_t) n; Z->d = Z->nrow; Z->nzmax = Z->nrow * Z->ncol; Z->xtype = Y->xtype; Z->dtype = Y->dtype; double alpha[2] = { 1.0, 0.0 }, beta[2] = { 0.0, 0.0 }; if (ztrans) { if (Z->xtype == CHOLMOD_COMPLEX) Z->x = R_Calloc(Z->nzmax, Rcomplex); else Z->x = R_Calloc(Z->nzmax, double); cholmod_sdmult(X, xtrans, alpha, beta, Y, Z, &c); PROTECT(z = CHD2M(Z, ztrans, zcl[1])); R_Free(Z->x); } else { PROTECT(z = newObject(zcl)); SEXP zdim = GET_SLOT(z, Matrix_DimSym); INTEGER(zdim)[0] = m; INTEGER(zdim)[1] = n; SEXP zx; if (Z->xtype == CHOLMOD_COMPLEX) { PROTECT(zx = allocVector(CPLXSXP, (R_xlen_t) m * n)); Z->x = COMPLEX(zx); } else { PROTECT(zx = allocVector(REALSXP, (R_xlen_t) m * n)); Z->x = REAL(zx); } cholmod_sdmult(X, xtrans, alpha, beta, Y, Z, &c); SET_SLOT(z, Matrix_xSym, zx); UNPROTECT(1); /* zx */ } if (ytrans) R_Free(Y->x); SEXP xdimnames = (symmetric) ? PROTECT(get_symmetrized_DimNames(x, -1)) : PROTECT(GET_SLOT(x, Matrix_DimNamesSym)), ydimnames = PROTECT(GET_SLOT(y, Matrix_DimNamesSym)), zdimnames = PROTECT(GET_SLOT(z, Matrix_DimNamesSym)); if (ztrans) matmultDN(zdimnames, ydimnames, (ytrans) ? 0 : 1, xdimnames, (xtrans) ? 1 : 0); else matmultDN(zdimnames, xdimnames, (xtrans) ? 1 : 0, ydimnames, (ytrans) ? 0 : 1); UNPROTECT(3); /* zdimnames, ydimnames, xdimnames */ if (triangular != 0 && ztrans == (triangular > 0)) { SEXP uplo = PROTECT(mkString("L")); SET_SLOT(z, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ } if (triangular < -1 || triangular > 1) { SEXP diag = PROTECT(mkString("U")); SET_SLOT(z, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ } UNPROTECT(1); /* z */ return z; } SEXP R_sparse_matmult(SEXP x, SEXP y, SEXP xtrans, SEXP ytrans, SEXP ztrans, SEXP boolean) { if (TYPEOF(boolean) != LGLSXP || LENGTH(boolean) < 1) error(_("invalid '%s' to '%s'"), "boolean", __func__); int boolean_ = LOGICAL(boolean)[0]; int xtrans_ = LOGICAL(xtrans)[0], ytrans_ = LOGICAL(ytrans)[0], ztrans_ = LOGICAL(ztrans)[0], m, n, v; matmultDim(x, y, &xtrans_, &ytrans_, &ztrans_, &m, &n, &v); PROTECT_INDEX xpid, ypid; PROTECT_WITH_INDEX(x, &xpid); PROTECT_WITH_INDEX(y, &ypid); if (TYPEOF(x) != S4SXP) { if (boolean_ == NA_LOGICAL || !boolean_) REPROTECT(x = matrix_as_dense( x, ",ge", '\0', '\0', xtrans_, 0), xpid); else if (!xtrans_) REPROTECT(x = matrix_as_sparse(x, "ngC", '\0', '\0', xtrans_ ), xpid); else REPROTECT(x = matrix_as_sparse(x, "ngR", '\0', '\0', xtrans_ ), xpid); if (v == 1) { /* Discard names and don't transpose again */ SET_VECTOR_ELT(GET_SLOT(x, Matrix_DimNamesSym), (xtrans_) ? 1 : 0, R_NilValue); xtrans_ = 0; } } if (TYPEOF(y) != S4SXP && y != R_NilValue) { if (boolean_ == NA_LOGICAL || !boolean_) REPROTECT(y = matrix_as_dense( y, ",ge", '\0', '\0', ytrans_, 0), ypid); else if (!ytrans_) REPROTECT(y = matrix_as_sparse(y, "ngC", '\0', '\0', ytrans_ ), ypid); else REPROTECT(y = matrix_as_sparse(y, "ngR", '\0', '\0', ytrans_ ), ypid); if (v == 2) { /* Discard names and don't transpose again */ SET_VECTOR_ELT(GET_SLOT(y, Matrix_DimNamesSym), (ytrans_) ? 1 : 0, R_NilValue); ytrans_ = 0; } } static const char *valid[] = { VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, VALID_DENSE, "" }; const char *xcl = NULL, *ycl = NULL; int ivalid; ivalid = R_check_class_etc(x, valid); if (ivalid < 0) ERROR_INVALID_CLASS(x, __func__); xcl = valid[ivalid]; if (y != R_NilValue) { ivalid = R_check_class_etc(y, valid); if (ivalid < 0) ERROR_INVALID_CLASS(y, __func__); ycl = valid[ivalid]; } if (boolean_ == NA_LOGICAL) boolean_ = xcl[0] == 'n' && (y == R_NilValue || ycl[0] == 'n'); char kind = (boolean_) ? 'n' : ((xcl[0] == 'z' || (y != R_NilValue && ycl[0] == 'z')) ? 'z' : 'd'); if (xcl[2] != 'C' && xtrans_) { if (xcl[2] != 'R' && xcl[2] != 'T') { REPROTECT(x = dense_as_sparse(x, xcl, 'R'), xpid); xcl = valid[R_check_class_etc(x, valid)]; } if (xcl[1] != 's' || xcl[1] != 'T') { REPROTECT(x = sparse_transpose(x, xcl, 1), xpid); xcl = valid[R_check_class_etc(x, valid)]; } xtrans_ = 0; } if (xcl[2] != 'C') { if (xcl[2] != 'R' && xcl[2] != 'T') REPROTECT(x = dense_as_sparse(x, xcl, 'C'), xpid); else REPROTECT(x = sparse_as_Csparse(x, xcl), xpid); xcl = valid[R_check_class_etc(x, valid)]; } if (xcl[1] == 's') xtrans_ = 0; if (xcl[0] != kind) { if (boolean_) REPROTECT(x = sparse_drop0(x, xcl, 0.0), xpid); else { REPROTECT(x = sparse_as_kind(x, xcl, kind), xpid); xcl = valid[R_check_class_etc(x, valid)]; } } if (y == R_NilValue) { REPROTECT(x = sparse_as_general(x, xcl), xpid); x = dgCMatrix_dgCMatrix_matmult( x, y, xtrans_, !xtrans_, ztrans_, 0, boolean_); UNPROTECT(2); /* y, x */ return x; } int triangular = 0; if (xcl[1] == 't' && ycl[1] == 't') { SEXP xuplo = PROTECT(GET_SLOT(x, Matrix_uploSym)), yuplo = PROTECT(GET_SLOT(y, Matrix_uploSym)), xdiag = PROTECT(GET_SLOT(x, Matrix_diagSym)), ydiag = PROTECT(GET_SLOT(y, Matrix_diagSym)); char xul = *CHAR(STRING_ELT(xuplo, 0)), yul = *CHAR(STRING_ELT(yuplo, 0)), xdi = *CHAR(STRING_ELT(xdiag, 0)), ydi = *CHAR(STRING_ELT(ydiag, 0)); if (xtrans_) xul = (xul == 'U') ? 'L' : 'U'; if (ytrans_) yul = (yul == 'U') ? 'L' : 'U'; triangular = (xul != yul) ? 0 : ((xdi != ydi || xdi == 'N') ? 1 : 2); if (xul != 'U') triangular = -triangular; UNPROTECT(4); /* ydiag, xdiag, yuplo, xuplo */ } if (!boolean_ && ycl[2] != 'C' && ycl[2] != 'R' && ycl[2] != 'T') { int symmetric = xcl[1] == 's'; if (symmetric) { SEXP xuplo = PROTECT(GET_SLOT(x, Matrix_uploSym)); char xul = *CHAR(STRING_ELT(xuplo, 0)); if (xul != 'U') symmetric = -1; UNPROTECT(1); /* xuplo */ } if (ycl[0] != kind) { REPROTECT(y = dense_as_kind(y, ycl, kind, 0), ypid); ycl = valid[R_check_class_etc(y, valid)]; } REPROTECT(y = dense_as_general(y, ycl, 1), ypid); if (xcl[1] == 't') REPROTECT(x = sparse_diag_U2N(x, xcl), xpid); x = dgCMatrix_dgeMatrix_matmult( x, y, xtrans_, ytrans_, ztrans_, triangular, symmetric); UNPROTECT(2); /* y, x */ return x; } if (ycl[2] != 'C' && ytrans_) { if (ycl[2] != 'R' && ycl[2] != 'T') { REPROTECT(y = dense_as_sparse(y, ycl, 'R'), ypid); ycl = valid[R_check_class_etc(y, valid)]; } if (ycl[1] != 's' || ycl[1] != 'T') { REPROTECT(y = sparse_transpose(y, ycl, 1), ypid); ycl = valid[R_check_class_etc(y, valid)]; } ytrans_ = 0; } if (ycl[2] != 'C') { if (ycl[2] != 'R' && ycl[2] != 'T') REPROTECT(y = dense_as_sparse(y, ycl, 'C'), ypid); else REPROTECT(y = sparse_as_Csparse(y, ycl), ypid); ycl = valid[R_check_class_etc(y, valid)]; } if (ycl[1] == 's') ytrans_ = 0; if (ycl[0] != kind) { if (boolean_) REPROTECT(y = sparse_drop0(y, ycl, 0.0), ypid); else { REPROTECT(y = sparse_as_kind(y, ycl, kind), ypid); ycl = valid[R_check_class_etc(y, valid)]; } } REPROTECT(x = sparse_as_general(x, xcl), xpid); REPROTECT(y = sparse_as_general(y, ycl), ypid); x = dgCMatrix_dgCMatrix_matmult( x, y, xtrans_, ytrans_, ztrans_, triangular, boolean_); UNPROTECT(2); /* y, x */ return x; } #define MULTIPLY_COMPLEX(_X_, _D_) \ do { \ tmp = (_X_); \ (_X_).r = tmp.r * (_D_).r - tmp.i * (_D_).i; \ (_X_).i = tmp.r * (_D_).i + tmp.i * (_D_).r; \ } while (0) #define MULTIPLY_REAL(_X_, _D_) \ (_X_) = (_X_) * (_D_) #define MULTIPLY_LOGICAL(_X_, _D_) \ (_X_) = (_X_) && (_D_) #define SCALE_CASES(_J_) \ do { \ switch (TYPEOF(d)) { \ case CPLXSXP: \ { \ Rcomplex tmp; \ SCALE(Rcomplex, COMPLEX, MULTIPLY_COMPLEX, _J_); \ break; \ } \ case REALSXP: \ SCALE(double, REAL, MULTIPLY_REAL, _J_); \ break; \ default: \ SCALE(int, LOGICAL, MULTIPLY_LOGICAL, _J_); \ break; \ } \ } while (0) static void dense_colscale(SEXP obj, SEXP d, int m, int n, char uplo, char diag) { SEXP x = GET_SLOT(obj, Matrix_xSym); int i, j, packed = XLENGTH(x) < (R_xlen_t) m * n; #define SCALE(_CTYPE_, _PTR_, _OP_, _J_) \ do { \ _CTYPE_ *px = _PTR_(x), *pd = _PTR_(d); \ if (uplo == '\0') { \ for (j = 0; j < n; ++j) { \ for (i = 0; i < m; ++i) { \ _OP_(*px, pd[_J_]); \ ++px; \ } \ } \ } else if (uplo == 'U') { \ for (j = 0; j < n; ++j) { \ for (i = 0; i <= j; ++i) { \ _OP_(*px, pd[_J_]); \ ++px; \ } \ if (!packed) \ px += m - j - 1; \ } \ } else { \ for (j = 0; j < n; ++j) { \ if (!packed) \ px += j; \ for (i = j; i < m; ++i) { \ _OP_(*px, pd[_J_]); \ ++px; \ } \ } \ } \ if (diag != '\0' && diag != 'N') { \ px = _PTR_(x); \ if (!packed) { \ R_xlen_t m1a = (R_xlen_t) m + 1; \ for (j = 0; j < n; ++j, px += m1a, pd += 1) \ *px = *pd; \ } else if (uplo == 'U') { \ for (j = 0; j < n; px += (++j)+1, pd += 1) \ *px = *pd; \ } else { \ for (j = 0; j < n; px += m-(j++), pd += 1) \ *px = *pd; \ } \ } \ } while (0) SCALE_CASES(j); return; } static void dense_rowscale(SEXP obj, SEXP d, int m, int n, char uplo, char diag) { SEXP x = GET_SLOT(obj, Matrix_xSym); int i, j, packed = XLENGTH(x) < (R_xlen_t) m * n; SCALE_CASES(i); #undef SCALE return; } /* boolean: & or & */ /* numeric: * or * */ static void Csparse_colscale(SEXP obj, SEXP d) { SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)), p = PROTECT(GET_SLOT(obj, Matrix_pSym)); int *pp = INTEGER(p) + 1, n = (int) (XLENGTH(p) - 1), j, k = 0, kend; UNPROTECT(2); /* p, x */ #define SCALE(_CTYPE_, _PTR_, _OP_, _J_) \ do { \ _CTYPE_ *px = _PTR_(x), *pd = _PTR_(d); \ for (j = 0; j < n; ++j) { \ kend = pp[j]; \ while (k < kend) { \ _OP_(*px, *pd); \ ++px; \ ++k; \ } \ ++pd; \ } \ } while (0) SCALE_CASES(); #undef SCALE return; } /* boolean: & or & */ /* numeric: * or * */ static void Csparse_rowscale(SEXP obj, SEXP d, SEXP iSym) { SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)), p = PROTECT(GET_SLOT(obj, Matrix_pSym)), i = PROTECT(GET_SLOT(obj, iSym)); int *pi = INTEGER(i), k, nnz = INTEGER(p)[XLENGTH(p) - 1]; UNPROTECT(3); /* i, p, x */ #define SCALE(_CTYPE_, _PTR_, _OP_, _J_) \ do { \ _CTYPE_ *px = _PTR_(x), *pd = _PTR_(d); \ for (k = 0; k < nnz; ++k) { \ _OP_(*px, pd[*pi]); \ ++px; \ ++pi; \ } \ } while (0) SCALE_CASES(); return; } /* boolean: & or & */ /* numeric: * or * */ static void Tsparse_rowscale(SEXP obj, SEXP d, SEXP iSym) { SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)), i = PROTECT(GET_SLOT(obj, iSym)); int *pi = INTEGER(i); R_xlen_t k, nnz = XLENGTH(i); UNPROTECT(2); /* i, x */ SCALE_CASES(); #undef SCALE return; } SEXP R_diagonal_matmult(SEXP x, SEXP y, SEXP xtrans, SEXP ytrans, SEXP boolean) { SEXP x_ = x, y_ = y; /* for later pointer comparison */ if (TYPEOF(boolean) != LGLSXP || LENGTH(boolean) < 1) error(_("invalid '%s' to '%s'"), "boolean", __func__); int boolean_ = LOGICAL(boolean)[0]; int xtrans_ = LOGICAL(xtrans)[0], ytrans_ = LOGICAL(ytrans)[0], ztrans_ = 0, m, n, v; matmultDim(x, y, &xtrans_, &ytrans_, &ztrans_, &m, &n, &v); PROTECT_INDEX xpid, ypid; PROTECT_WITH_INDEX(x, &xpid); PROTECT_WITH_INDEX(y, &ypid); if (TYPEOF(x) != S4SXP) { if (boolean_ == NA_LOGICAL || !boolean_) REPROTECT(x = matrix_as_dense(x, ",ge", '\0', '\0', xtrans_, 2), xpid); else REPROTECT(x = matrix_as_dense(x, "nge", '\0', '\0', xtrans_, 2), xpid); if (v == 1) { /* Vector: discard names and don't transpose again */ SET_VECTOR_ELT(GET_SLOT(x, Matrix_DimNamesSym), (xtrans_) ? 1 : 0, R_NilValue); xtrans_ = 0; } } if (TYPEOF(y) != S4SXP) { if (boolean_ == NA_LOGICAL || !boolean_) REPROTECT(y = matrix_as_dense(y, ",ge", '\0', '\0', ytrans_, 2), ypid); else REPROTECT(y = matrix_as_dense(y, "nge", '\0', '\0', ytrans_, 2), ypid); if (v == 2) { /* Vector: discard names and don't transpose again */ SET_VECTOR_ELT(GET_SLOT(y, Matrix_DimNamesSym), (ytrans_) ? 1 : 0, R_NilValue); ytrans_ = 0; } } static const char *valid[] = { VALID_DIAGONAL, VALID_CSPARSE, VALID_RSPARSE, VALID_TSPARSE, VALID_DENSE, "" }; const char *xcl = NULL, *ycl = NULL; int ivalid; ivalid = R_check_class_etc(x, valid); if (ivalid < 0) ERROR_INVALID_CLASS(x, __func__); xcl = valid[ivalid]; if (xcl[1] == 's') xtrans_ = 0; ivalid = R_check_class_etc(y, valid); if (ivalid < 0) ERROR_INVALID_CLASS(y, __func__); ycl = valid[ivalid]; if (ycl[1] == 's') ytrans_ = 0; if (boolean_ == NA_LOGICAL) boolean_ = xcl[0] == 'n' && ycl[0] == 'n'; char kind = (boolean_) ? 'n' : ((xcl[0] == 'z' || ycl[0] == 'z') ? 'z' : 'd'); int margin = -1, unit = -1; if (xcl[2] == 'i') { margin = 0; unit = *CHAR(STRING_ELT(GET_SLOT(x, Matrix_diagSym), 0)) != 'N'; } else if (ycl[2] == 'i') { margin = 1; unit = *CHAR(STRING_ELT(GET_SLOT(y, Matrix_diagSym), 0)) != 'N'; } else error(_("should never happen ...")); char ks = (boolean_) ? 'l' : kind, kd = kind; switch (xcl[2]) { case 'i': if (!unit && xcl[0] != ks) { REPROTECT(x = diagonal_as_kind(x, xcl, ks), xpid); xcl = valid[R_check_class_etc(x, valid)]; } break; case 'C': case 'R': case 'T': if (xcl[0] != ks) { REPROTECT(x = sparse_as_kind(x, xcl, ks), xpid); xcl = valid[R_check_class_etc(x, valid)]; } if (!unit && xcl[1] == 's') { REPROTECT(x = sparse_as_general(x, xcl), xpid); xcl = valid[R_check_class_etc(x, valid)]; } else if (!unit && xcl[1] == 't') REPROTECT(x = sparse_diag_U2N(x, xcl), xpid); if (xtrans_) { REPROTECT(x = sparse_transpose(x, xcl, 0), xpid); xtrans_ = 0; } break; default: if (xcl[0] != kd) { REPROTECT(x = dense_as_kind(x, xcl, kd, 1), xpid); xcl = valid[R_check_class_etc(x, valid)]; } if (!unit && xcl[1] == 's') { REPROTECT(x = dense_as_general(x, xcl, x == x_), xpid); xcl = valid[R_check_class_etc(x, valid)]; } if (xtrans_) { REPROTECT(x = dense_transpose(x, xcl), xpid); xtrans_ = 0; } break; } switch (ycl[2]) { case 'i': if (!unit && ycl[0] != ks) { REPROTECT(y = diagonal_as_kind(y, ycl, ks), ypid); ycl = valid[R_check_class_etc(y, valid)]; } break; case 'C': case 'R': case 'T': if (ycl[0] != ks) { REPROTECT(y = sparse_as_kind(y, ycl, ks), ypid); ycl = valid[R_check_class_etc(y, valid)]; } if (!unit && ycl[1] == 's') { REPROTECT(y = sparse_as_general(y, ycl), ypid); ycl = valid[R_check_class_etc(y, valid)]; } else if (!unit && ycl[1] == 't') REPROTECT(y = sparse_diag_U2N(y, ycl), ypid); if (ytrans_) { REPROTECT(y = sparse_transpose(y, ycl, 0), ypid); ytrans_ = 0; } break; default: if (ycl[0] != kd) { REPROTECT(y = dense_as_kind(y, ycl, kd, 1), ypid); ycl = valid[R_check_class_etc(y, valid)]; } if (!unit && ycl[1] == 's') { REPROTECT(y = dense_as_general(y, ycl, y == y_), ypid); ycl = valid[R_check_class_etc(y, valid)]; } if (ytrans_) { REPROTECT(y = dense_transpose(y, ycl), ypid); ytrans_ = 0; } break; } SEXP z; PROTECT_INDEX zpid; const char *zcl = (margin == 0) ? ycl : xcl; PROTECT_WITH_INDEX(z = newObject(zcl), &zpid); SEXP zdim = PROTECT(GET_SLOT(z, Matrix_DimSym)); int *pzdim = INTEGER(zdim); pzdim[0] = m; pzdim[1] = n; UNPROTECT(1); /* zdim */ SEXP xdimnames = PROTECT(GET_SLOT(x, Matrix_DimNamesSym)), ydimnames = PROTECT(GET_SLOT(y, Matrix_DimNamesSym)), zdimnames = PROTECT(GET_SLOT(z, Matrix_DimNamesSym)); matmultDN(zdimnames, xdimnames, (xtrans_) ? 1 : 0, ydimnames, (ytrans_) ? 0 : 1); UNPROTECT(3); /* zdimnames, ydimnames, xdimnames */ char ul = '\0', di = '\0'; if (zcl[1] != 'g') { SEXP uplo = PROTECT(GET_SLOT((margin == 0) ? y : x, Matrix_uploSym)); ul = *CHAR(STRING_ELT(uplo, 0)); if (ul != 'U') SET_SLOT(z, Matrix_uploSym, uplo); UNPROTECT(1); /* uplo */ if (zcl[1] == 't') { SEXP diag = PROTECT(GET_SLOT((margin == 0) ? y : x, Matrix_diagSym)); di = *CHAR(STRING_ELT(diag, 0)); if (di != 'N' && unit) SET_SLOT(z, Matrix_diagSym, diag); UNPROTECT(1); /* diag */ } } if (zcl[2] == 'C' || zcl[2] == 'R' || zcl[2] == 'T') { if (zcl[2] != 'T') { SEXP p = PROTECT(GET_SLOT((margin == 0) ? y : x, Matrix_pSym)); SET_SLOT(z, Matrix_pSym, p); UNPROTECT(1); /* p */ } if (zcl[2] != 'R') { SEXP i = PROTECT(GET_SLOT((margin == 0) ? y : x, Matrix_iSym)); SET_SLOT(z, Matrix_iSym, i); UNPROTECT(1); /* i */ } if (zcl[2] != 'C') { SEXP j = PROTECT(GET_SLOT((margin == 0) ? y : x, Matrix_jSym)); SET_SLOT(z, Matrix_jSym, j); UNPROTECT(1); /* j */ } } SEXP x0 = PROTECT(GET_SLOT((margin == 0) ? y : x, Matrix_xSym)); if (unit || ((margin == 0) ? y != y_ : x != x_)) SET_SLOT(z, Matrix_xSym, x0); else { SEXP x1 = PROTECT(allocVector(TYPEOF(x0), XLENGTH(x0))); switch (kind) { case 'z': Matrix_memcpy(COMPLEX(x1), COMPLEX(x0), XLENGTH(x0), sizeof(Rcomplex)); break; case 'd': Matrix_memcpy( REAL(x1), REAL(x0), XLENGTH(x0), sizeof( double)); break; default: Matrix_memcpy(LOGICAL(x1), LOGICAL(x0), XLENGTH(x0), sizeof( int)); break; } SET_SLOT(z, Matrix_xSym, x1); UNPROTECT(1); /* x1 */ } UNPROTECT(1); /* x0 */ if (!unit) { SEXP d = PROTECT(GET_SLOT((margin == 0) ? x : y, Matrix_xSym)); switch (zcl[2]) { case 'C': if (margin == 0) Csparse_rowscale(z, d, Matrix_iSym); else Csparse_colscale(z, d); break; case 'R': if (margin == 0) Csparse_colscale(z, d); else Csparse_rowscale(z, d, Matrix_jSym); break; case 'T': if (margin == 0) Tsparse_rowscale(z, d, Matrix_iSym); else Tsparse_rowscale(z, d, Matrix_jSym); break; default: if (margin == 0) dense_rowscale(z, d, m, n, ul, di); else dense_colscale(z, d, m, n, ul, di); break; } UNPROTECT(1); /* d */ } if (boolean_ && (zcl[2] == 'C' || zcl[2] == 'R' || zcl[2] == 'T')) { REPROTECT(z = sparse_drop0(z, zcl, 0.0), zpid); REPROTECT(z = sparse_as_kind(z, zcl, 'n'), zpid); } UNPROTECT(3); /* z, y, x */ return z; } �����������������������Matrix/src/SuiteSparse_config/����������������������������������������������������������������������0000755�0001762�0000144�00000000000�14547724215�016114� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/SuiteSparse_config/SuiteSparse_config.h��������������������������������������������������0000644�0001762�0000144�00000020462�14212074443�022053� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === SuiteSparse_config =================================================== */ /* ========================================================================== */ /* Configuration file for SuiteSparse: a Suite of Sparse matrix packages * (AMD, COLAMD, CCOLAMD, CAMD, CHOLMOD, UMFPACK, CXSparse, and others). * * SuiteSparse_config.h provides the definition of the long integer. On most * systems, a C program can be compiled in LP64 mode, in which long's and * pointers are both 64-bits, and int's are 32-bits. Windows 64, however, uses * the LLP64 model, in which int's and long's are 32-bits, and long long's and * pointers are 64-bits. * * SuiteSparse packages that include long integer versions are * intended for the LP64 mode. However, as a workaround for Windows 64 * (and perhaps other systems), the long integer can be redefined. * * If _WIN64 is defined, then the __int64 type is used instead of long. * * The long integer can also be defined at compile time. For example, this * could be added to SuiteSparse_config.mk: * * CFLAGS = -O -D'SuiteSparse_long=long long' \ * -D'SuiteSparse_long_max=9223372036854775801' -D'SuiteSparse_long_idd="lld"' * * This file defines SuiteSparse_long as either long (on all but _WIN64) or * __int64 on Windows 64. The intent is that a SuiteSparse_long is always a * 64-bit integer in a 64-bit code. ptrdiff_t might be a better choice than * long; it is always the same size as a pointer. * * This file also defines the SUITESPARSE_VERSION and related definitions. * * Copyright (c) 2012, Timothy A. Davis. No licensing restrictions apply * to this file or to the SuiteSparse_config directory. * Author: Timothy A. Davis. */ #ifndef SUITESPARSE_CONFIG_H #define SUITESPARSE_CONFIG_H #ifdef __cplusplus extern "C" { #endif #include #include /* ========================================================================== */ /* === SuiteSparse_long ===================================================== */ /* ========================================================================== */ // Rather use C99 -- which we require in R anyway #include #ifndef SuiteSparse_long // -----> for Matrix in R -- replace these by the SuiteSparse_long* defs below : /* PROBLEM: 1) ../COLAMD/Source/colamd.c ifdef DLONG has `#define Int SuiteSparse_long` * and then declares ` unsigned Int hash ; ` which gives a compilation error * on Windows for int64_t * 2) PRId64 seems wrong on current R-devel Windows _UCRT */ #if !defined(_WIN64) || defined(_UCRT) #define SuiteSparse_long long #define SuiteSparse_long_max LONG_MAX #define SuiteSparse_long_idd "ld" #else // _WIN64 but not _UCRT #define SuiteSparse_long __int64 #define SuiteSparse_long_max _I64_MAX #define SuiteSparse_long_idd PRId64 #endif /* #define SuiteSparse_long int64_t */ /* // typically long (but on WIN64) */ /* #define SuiteSparse_long_max 9223372036854775801 */ /* // typically LONG_MAX (but ..) */ /* #define SuiteSparse_long_idd PRId64 */ // typically "ld" //--------------------------------- end of changes for Matrix in R --- #define SuiteSparse_long_id "%" SuiteSparse_long_idd #endif /* ========================================================================== */ /* === SuiteSparse_config parameters and functions ========================== */ /* ========================================================================== */ /* SuiteSparse-wide parameters are placed in this struct. It is meant to be an extern, globally-accessible struct. It is not meant to be updated frequently by multiple threads. Rather, if an application needs to modify SuiteSparse_config, it should do it once at the beginning of the application, before multiple threads are launched. The intent of these function pointers is that they not be used in your application directly, except to assign them to the desired user-provided functions. Rather, you should use the */ struct SuiteSparse_config_struct { void *(*malloc_func) (size_t) ; /* pointer to malloc */ void *(*calloc_func) (size_t, size_t) ; /* pointer to calloc */ void *(*realloc_func) (void *, size_t) ; /* pointer to realloc */ void (*free_func) (void *) ; /* pointer to free */ int (*printf_func) (const char *, ...) ; /* pointer to printf */ double (*hypot_func) (double, double) ; /* pointer to hypot */ int (*divcomplex_func) (double, double, double, double, double *, double *); } ; extern struct SuiteSparse_config_struct SuiteSparse_config ; void SuiteSparse_start ( void ) ; /* called to start SuiteSparse */ void SuiteSparse_finish ( void ) ; /* called to finish SuiteSparse */ void *SuiteSparse_malloc /* pointer to allocated block of memory */ ( size_t nitems, /* number of items to malloc (>=1 is enforced) */ size_t size_of_item /* sizeof each item */ ) ; void *SuiteSparse_calloc /* pointer to allocated block of memory */ ( size_t nitems, /* number of items to calloc (>=1 is enforced) */ size_t size_of_item /* sizeof each item */ ) ; void *SuiteSparse_realloc /* pointer to reallocated block of memory, or to original block if the realloc failed. */ ( size_t nitems_new, /* new number of items in the object */ size_t nitems_old, /* old number of items in the object */ size_t size_of_item, /* sizeof each item */ void *p, /* old object to reallocate */ int *ok /* 1 if successful, 0 otherwise */ ) ; void *SuiteSparse_free /* always returns NULL */ ( void *p /* block to free */ ) ; void SuiteSparse_tic /* start the timer */ ( double tic [2] /* output, contents undefined on input */ ) ; double SuiteSparse_toc /* return time in seconds since last tic */ ( double tic [2] /* input: from last call to SuiteSparse_tic */ ) ; double SuiteSparse_time /* returns current wall clock time in seconds */ ( void ) ; /* returns sqrt (x^2 + y^2), computed reliably */ double SuiteSparse_hypot (double x, double y) ; /* complex division of c = a/b */ int SuiteSparse_divcomplex ( double ar, double ai, /* real and imaginary parts of a */ double br, double bi, /* real and imaginary parts of b */ double *cr, double *ci /* real and imaginary parts of c */ ) ; /* determine which timer to use, if any */ #ifndef NTIMER #ifdef _POSIX_C_SOURCE #if _POSIX_C_SOURCE >= 199309L #define SUITESPARSE_TIMER_ENABLED #endif #endif #endif /* SuiteSparse printf macro */ #define SUITESPARSE_PRINTF(params) \ { \ if (SuiteSparse_config.printf_func != NULL) \ { \ (void) (SuiteSparse_config.printf_func) params ; \ } \ } /* ========================================================================== */ /* === SuiteSparse version ================================================== */ /* ========================================================================== */ /* SuiteSparse is not a package itself, but a collection of packages, some of * which must be used together (UMFPACK requires AMD, CHOLMOD requires AMD, * COLAMD, CAMD, and CCOLAMD, etc). A version number is provided here for the * collection itself, which is also the version number of SuiteSparse_config. */ int SuiteSparse_version /* returns SUITESPARSE_VERSION */ ( /* output, not defined on input. Not used if NULL. Returns the three version codes in version [0..2]: version [0] is SUITESPARSE_MAIN_VERSION version [1] is SUITESPARSE_SUB_VERSION version [2] is SUITESPARSE_SUBSUB_VERSION */ int version [3] ) ; /* Versions prior to 4.2.0 do not have the above function. The following code fragment will work with any version of SuiteSparse: #ifdef SUITESPARSE_HAS_VERSION_FUNCTION v = SuiteSparse_version (NULL) ; #else v = SUITESPARSE_VERSION ; #endif */ #define SUITESPARSE_HAS_VERSION_FUNCTION #define SUITESPARSE_DATE "May 17, 2021" #define SUITESPARSE_VER_CODE(main,sub) ((main) * 1000 + (sub)) #define SUITESPARSE_MAIN_VERSION 5 #define SUITESPARSE_SUB_VERSION 10 #define SUITESPARSE_SUBSUB_VERSION 1 #define SUITESPARSE_VERSION \ SUITESPARSE_VER_CODE(SUITESPARSE_MAIN_VERSION,SUITESPARSE_SUB_VERSION) #ifdef __cplusplus } #endif #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/SuiteSparse_config/Makefile��������������������������������������������������������������0000644�0001762�0000144�00000000650�14547724215�017555� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#------------------------------------------------------------------------------- # SuiteSparse_config Makefile #------------------------------------------------------------------------------- VERSION = 4.2.1 PKG_CPPFLAGS = -DNTIMER LIB = ../SuiteSparse_config.a library: $(LIB) $(LIB): SuiteSparse_config.o $(AR) -rucs $(LIB) SuiteSparse_config.o mostlyclean: clean clean: @-rm -rf .libs _libs $(LIB) @-rm -f *.o ����������������������������������������������������������������������������������������Matrix/src/SuiteSparse_config/SuiteSparse_config.mk�������������������������������������������������0000644�0001762�0000144�00000000000�11770402705�022217� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/SuiteSparse_config/SuiteSparse_config.c��������������������������������������������������0000644�0001762�0000144�00000040333�13652535054�022054� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ========================================================================== */ /* === SuiteSparse_config =================================================== */ /* ========================================================================== */ /* SuiteSparse configuration : memory manager and printf functions. */ /* Copyright (c) 2013-2018, Timothy A. Davis. No licensing restrictions * apply to this file or to the SuiteSparse_config directory. * Author: Timothy A. Davis. */ #include #include // For use with R package 'Matrix': #define NPRINT #ifndef NPRINT #include #endif #ifdef MATLAB_MEX_FILE #include "mex.h" #include "matrix.h" #endif #ifndef NULL #define NULL ((void *) 0) #endif #include "SuiteSparse_config.h" /* -------------------------------------------------------------------------- */ /* SuiteSparse_config : a global extern struct */ /* -------------------------------------------------------------------------- */ /* The SuiteSparse_config struct is available to all SuiteSparse functions and to all applications that use those functions. It must be modified with care, particularly in a multithreaded context. Normally, the application will initialize this object once, via SuiteSparse_start, possibily followed by application-specific modifications if the applications wants to use alternative memory manager functions. The user can redefine these global pointers at run-time to change the memory manager and printf function used by SuiteSparse. If -DNMALLOC is defined at compile-time, then no memory-manager is specified. You must define them at run-time, after calling SuiteSparse_start. If -DPRINT is defined a compile time, then printf is disabled, and SuiteSparse will not use printf. */ struct SuiteSparse_config_struct SuiteSparse_config = { /* memory management functions */ #ifndef NMALLOC #ifdef MATLAB_MEX_FILE /* MATLAB mexFunction: */ mxMalloc, mxCalloc, mxRealloc, mxFree, #else /* standard ANSI C: */ malloc, calloc, realloc, free, #endif #else /* no memory manager defined; you must define one at run-time: */ NULL, NULL, NULL, NULL, #endif /* printf function */ #ifndef NPRINT #ifdef MATLAB_MEX_FILE /* MATLAB mexFunction: */ mexPrintf, #else // /* standard ANSI C: */ // printf, // For use with R package 'Matrix': #include Rprintf, #endif #else /* printf is disabled */ NULL, #endif SuiteSparse_hypot, SuiteSparse_divcomplex } ; /* -------------------------------------------------------------------------- */ /* SuiteSparse_start */ /* -------------------------------------------------------------------------- */ /* All applications that use SuiteSparse should call SuiteSparse_start prior to using any SuiteSparse function. Only a single thread should call this function, in a multithreaded application. Currently, this function is optional, since all this function currently does is to set the four memory function pointers to NULL (which tells SuiteSparse to use the default functions). In a multi- threaded application, only a single thread should call this function. Future releases of SuiteSparse might enforce a requirement that SuiteSparse_start be called prior to calling any SuiteSparse function. */ void SuiteSparse_start ( void ) { /* memory management functions */ #ifndef NMALLOC #ifdef MATLAB_MEX_FILE /* MATLAB mexFunction: */ SuiteSparse_config.malloc_func = mxMalloc ; SuiteSparse_config.calloc_func = mxCalloc ; SuiteSparse_config.realloc_func = mxRealloc ; SuiteSparse_config.free_func = mxFree ; #else /* standard ANSI C: */ SuiteSparse_config.malloc_func = malloc ; SuiteSparse_config.calloc_func = calloc ; SuiteSparse_config.realloc_func = realloc ; SuiteSparse_config.free_func = free ; #endif #else /* no memory manager defined; you must define one after calling SuiteSparse_start */ SuiteSparse_config.malloc_func = NULL ; SuiteSparse_config.calloc_func = NULL ; SuiteSparse_config.realloc_func = NULL ; SuiteSparse_config.free_func = NULL ; #endif /* printf function */ #ifndef NPRINT #ifdef MATLAB_MEX_FILE /* MATLAB mexFunction: */ SuiteSparse_config.printf_func = mexPrintf ; #else /* standard ANSI C: */ SuiteSparse_config.printf_func = printf ; #endif #else /* printf is disabled */ SuiteSparse_config.printf_func = NULL ; #endif /* math functions */ SuiteSparse_config.hypot_func = SuiteSparse_hypot ; SuiteSparse_config.divcomplex_func = SuiteSparse_divcomplex ; } /* -------------------------------------------------------------------------- */ /* SuiteSparse_finish */ /* -------------------------------------------------------------------------- */ /* This currently does nothing, but in the future, applications should call SuiteSparse_start before calling any SuiteSparse function, and then SuiteSparse_finish after calling the last SuiteSparse function, just before exiting. In a multithreaded application, only a single thread should call this function. Future releases of SuiteSparse might use this function for any SuiteSparse-wide cleanup operations or finalization of statistics. */ void SuiteSparse_finish ( void ) { /* do nothing */ ; } /* -------------------------------------------------------------------------- */ /* SuiteSparse_malloc: malloc wrapper */ /* -------------------------------------------------------------------------- */ void *SuiteSparse_malloc /* pointer to allocated block of memory */ ( size_t nitems, /* number of items to malloc */ size_t size_of_item /* sizeof each item */ ) { void *p ; size_t size ; if (nitems < 1) nitems = 1 ; if (size_of_item < 1) size_of_item = 1 ; size = nitems * size_of_item ; if (size != ((double) nitems) * size_of_item) { /* size_t overflow */ p = NULL ; } else { p = (void *) (SuiteSparse_config.malloc_func) (size) ; } return (p) ; } /* -------------------------------------------------------------------------- */ /* SuiteSparse_calloc: calloc wrapper */ /* -------------------------------------------------------------------------- */ void *SuiteSparse_calloc /* pointer to allocated block of memory */ ( size_t nitems, /* number of items to calloc */ size_t size_of_item /* sizeof each item */ ) { void *p ; size_t size ; if (nitems < 1) nitems = 1 ; if (size_of_item < 1) size_of_item = 1 ; size = nitems * size_of_item ; if (size != ((double) nitems) * size_of_item) { /* size_t overflow */ p = NULL ; } else { p = (void *) (SuiteSparse_config.calloc_func) (nitems, size_of_item) ; } return (p) ; } /* -------------------------------------------------------------------------- */ /* SuiteSparse_realloc: realloc wrapper */ /* -------------------------------------------------------------------------- */ /* If p is non-NULL on input, it points to a previously allocated object of size nitems_old * size_of_item. The object is reallocated to be of size nitems_new * size_of_item. If p is NULL on input, then a new object of that size is allocated. On success, a pointer to the new object is returned, and ok is returned as 1. If the allocation fails, ok is set to 0 and a pointer to the old (unmodified) object is returned. */ void *SuiteSparse_realloc /* pointer to reallocated block of memory, or to original block if the realloc failed. */ ( size_t nitems_new, /* new number of items in the object */ size_t nitems_old, /* old number of items in the object */ size_t size_of_item, /* sizeof each item */ void *p, /* old object to reallocate */ int *ok /* 1 if successful, 0 otherwise */ ) { size_t size ; if (nitems_old < 1) nitems_old = 1 ; if (nitems_new < 1) nitems_new = 1 ; if (size_of_item < 1) size_of_item = 1 ; size = nitems_new * size_of_item ; if (size != ((double) nitems_new) * size_of_item) { /* size_t overflow */ (*ok) = 0 ; } else if (p == NULL) { /* a fresh object is being allocated */ p = SuiteSparse_malloc (nitems_new, size_of_item) ; (*ok) = (p != NULL) ; } else if (nitems_old == nitems_new) { /* the object does not change; do nothing */ (*ok) = 1 ; } else { /* change the size of the object from nitems_old to nitems_new */ void *pnew ; pnew = (void *) (SuiteSparse_config.realloc_func) (p, size) ; if (pnew == NULL) { if (nitems_new < nitems_old) { /* the attempt to reduce the size of the block failed, but the old block is unchanged. So pretend to succeed. */ (*ok) = 1 ; } else { /* out of memory */ (*ok) = 0 ; } } else { /* success */ p = pnew ; (*ok) = 1 ; } } return (p) ; } /* -------------------------------------------------------------------------- */ /* SuiteSparse_free: free wrapper */ /* -------------------------------------------------------------------------- */ void *SuiteSparse_free /* always returns NULL */ ( void *p /* block to free */ ) { if (p) { (SuiteSparse_config.free_func) (p) ; } return (NULL) ; } /* -------------------------------------------------------------------------- */ /* SuiteSparse_tic: return current wall clock time */ /* -------------------------------------------------------------------------- */ /* Returns the number of seconds (tic [0]) and nanoseconds (tic [1]) since some * unspecified but fixed time in the past. If no timer is installed, zero is * returned. A scalar double precision value for 'tic' could be used, but this * might cause loss of precision because clock_getttime returns the time from * some distant time in the past. Thus, an array of size 2 is used. * * The timer is enabled by default. To disable the timer, compile with * -DNTIMER. If enabled on a POSIX C 1993 system, the timer requires linking * with the -lrt library. * * example: * * double tic [2], r, s, t ; * SuiteSparse_tic (tic) ; // start the timer * // do some work A * t = SuiteSparse_toc (tic) ; // t is time for work A, in seconds * // do some work B * s = SuiteSparse_toc (tic) ; // s is time for work A and B, in seconds * SuiteSparse_tic (tic) ; // restart the timer * // do some work C * r = SuiteSparse_toc (tic) ; // s is time for work C, in seconds * * A double array of size 2 is used so that this routine can be more easily * ported to non-POSIX systems. The caller does not rely on the POSIX * include file. */ #ifdef SUITESPARSE_TIMER_ENABLED #include void SuiteSparse_tic ( double tic [2] /* output, contents undefined on input */ ) { /* POSIX C 1993 timer, requires -librt */ struct timespec t ; clock_gettime (CLOCK_MONOTONIC, &t) ; tic [0] = (double) (t.tv_sec) ; tic [1] = (double) (t.tv_nsec) ; } #else void SuiteSparse_tic ( double tic [2] /* output, contents undefined on input */ ) { /* no timer installed */ tic [0] = 0 ; tic [1] = 0 ; } #endif /* -------------------------------------------------------------------------- */ /* SuiteSparse_toc: return time since last tic */ /* -------------------------------------------------------------------------- */ /* Assuming SuiteSparse_tic is accurate to the nanosecond, this function is * accurate down to the nanosecond for 2^53 nanoseconds since the last call to * SuiteSparse_tic, which is sufficient for SuiteSparse (about 104 days). If * additional accuracy is required, the caller can use two calls to * SuiteSparse_tic and do the calculations differently. */ double SuiteSparse_toc /* returns time in seconds since last tic */ ( double tic [2] /* input, not modified from last call to SuiteSparse_tic */ ) { double toc [2] ; SuiteSparse_tic (toc) ; return ((toc [0] - tic [0]) + 1e-9 * (toc [1] - tic [1])) ; } /* -------------------------------------------------------------------------- */ /* SuiteSparse_time: return current wallclock time in seconds */ /* -------------------------------------------------------------------------- */ /* This function might not be accurate down to the nanosecond. */ double SuiteSparse_time /* returns current wall clock time in seconds */ ( void ) { double toc [2] ; SuiteSparse_tic (toc) ; return (toc [0] + 1e-9 * toc [1]) ; } /* -------------------------------------------------------------------------- */ /* SuiteSparse_version: return the current version of SuiteSparse */ /* -------------------------------------------------------------------------- */ int SuiteSparse_version ( int version [3] ) { if (version != NULL) { version [0] = SUITESPARSE_MAIN_VERSION ; version [1] = SUITESPARSE_SUB_VERSION ; version [2] = SUITESPARSE_SUBSUB_VERSION ; } return (SUITESPARSE_VERSION) ; } /* -------------------------------------------------------------------------- */ /* SuiteSparse_hypot */ /* -------------------------------------------------------------------------- */ /* There is an equivalent routine called hypot in , which conforms * to ANSI C99. However, SuiteSparse does not assume that ANSI C99 is * available. You can use the ANSI C99 hypot routine with: * * #include *i SuiteSparse_config.hypot_func = hypot ; * * Default value of the SuiteSparse_config.hypot_func pointer is * SuiteSparse_hypot, defined below. * * s = hypot (x,y) computes s = sqrt (x*x + y*y) but does so more accurately. * The NaN cases for the double relops x >= y and x+y == x are safely ignored. * * Source: Algorithm 312, "Absolute value and square root of a complex number," * P. Friedland, Comm. ACM, vol 10, no 10, October 1967, page 665. */ double SuiteSparse_hypot (double x, double y) { double s, r ; x = fabs (x) ; y = fabs (y) ; if (x >= y) { if (x + y == x) { s = x ; } else { r = y / x ; s = x * sqrt (1.0 + r*r) ; } } else { if (y + x == y) { s = y ; } else { r = x / y ; s = y * sqrt (1.0 + r*r) ; } } return (s) ; } /* -------------------------------------------------------------------------- */ /* SuiteSparse_divcomplex */ /* -------------------------------------------------------------------------- */ /* c = a/b where c, a, and b are complex. The real and imaginary parts are * passed as separate arguments to this routine. The NaN case is ignored * for the double relop br >= bi. Returns 1 if the denominator is zero, * 0 otherwise. * * This uses ACM Algo 116, by R. L. Smith, 1962, which tries to avoid * underflow and overflow. * * c can be the same variable as a or b. * * Default value of the SuiteSparse_config.divcomplex_func pointer is * SuiteSparse_divcomplex. */ int SuiteSparse_divcomplex ( double ar, double ai, /* real and imaginary parts of a */ double br, double bi, /* real and imaginary parts of b */ double *cr, double *ci /* real and imaginary parts of c */ ) { double tr, ti, r, den ; if (fabs (br) >= fabs (bi)) { r = bi / br ; den = br + r * bi ; tr = (ar + ai * r) / den ; ti = (ai - ar * r) / den ; } else { r = br / bi ; den = r * br + bi ; tr = (ar * r + ai) / den ; ti = (ai * r - ar) / den ; } *cr = tr ; *ci = ti ; return (den == 0.) ; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/src/validity.c�������������������������������������������������������������������������������0000644�0001762�0000144�00000155310�14545337734�014322� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include /* trunc */ #include "Mdefines.h" #include "validity.h" #define MK(_FORMAT_ ) mkString(_FORMAT_ ) #define MS(_FORMAT_, ...) Matrix_sprintf(_FORMAT_, __VA_ARGS__) #define RMK(_FORMAT_ ) \ return MK( _FORMAT_ ) #define RMS(_FORMAT_, ...) \ return MS(_FORMAT_, __VA_ARGS__) #define RMKMS(_FORMAT_, ...) \ return MK(MS(_FORMAT_, __VA_ARGS__)) #define FRMKMS(_FORMAT_, ...) \ do { \ Matrix_Free(work, lwork); \ RMKMS(_FORMAT_, __VA_ARGS__); \ } while (0) /* Slot validity methods =============================================== Called by various class validity methods (see below). */ /** * Test that `dim` is a length-2, non-negative integer vector. * * @param dim A `SEXP`, * typically the `Dim` slot of a (to be validated) `Matrix`. * * @return A string containing an error message, empty if `dim` * is valid. */ char *Dim_validate(SEXP dim) { if (TYPEOF(dim) != INTSXP) RMS(_("'%s' slot is not of type \"%s\""), "Dim", "integer"); if (XLENGTH(dim) != 2) RMS(_("'%s' slot does not have length %d"), "Dim", 2); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; if (m == NA_INTEGER || n == NA_INTEGER) RMS(_("'%s' slot contains NA"), "Dim"); if (m < 0 || n < 0) RMS(_("'%s' slot has negative elements"), "Dim"); return NULL; } SEXP R_Dim_validate(SEXP dim) { char *msg = Dim_validate(dim); return (msg) ? mkString(msg) : ScalarLogical(1); } /** * Test that `dimnames` is a valid length-2 list. * * @param dimnames A `SEXP`, * typically the `Dimnames` slot of a (to be validated) `Matrix`. * @param pdim Pointer to a length-2, non-negative `int` array, * typically from the `Dim` slot of a (to be validated) `Matrix`. * Array validity _must_ be checked by the caller. * * @return A string containing an error message, empty if `dimnames` * is valid. */ char *DimNames_validate(SEXP dimnames, int *pdim) { if (TYPEOF(dimnames) != VECSXP) RMS(_("'%s' slot is not a list"), "Dimnames"); if (XLENGTH(dimnames) != 2) RMS(_("'%s' slot does not have length %d"), "Dimnames", 2); /* Behave as do_matrix() from src/main/array.c: Dimnames[[i]] must be NULL or _coercible to_ character of length Dim[i] or 0 ... see R_Dimnames_fixup() below */ SEXP s; int i; R_xlen_t ns; for (i = 0; i < 2; ++i) { s = VECTOR_ELT(dimnames, i); if (s == R_NilValue) continue; if (!isVector(s)) RMS(_("%s[[%d]] is not NULL or a vector"), "Dimnames", i + 1); ns = XLENGTH(s); if (ns != pdim[i] && ns != 0) RMS(_("length of %s[[%d]] (%lld) is not equal to %s[%d] (%d)"), "Dimnames", i + 1, (long long) ns, "Dim" , i + 1, pdim[i]); } return NULL; } SEXP R_DimNames_validate(SEXP dimnames, SEXP dim) { char *msg = DimNames_validate(dimnames, INTEGER(dim)); return (msg) ? mkString(msg) : ScalarLogical(1); } /** * @brief Sanitize user-supplied `[dD]imnames`. * * Replaces length-0 vectors with `NULL` and non-character vectors * with the result of coercing to character. Intended to emulate the * behaviour of `do_matrix()` from `src/main/array.c`. * * @param dn A list of length 2 passing `DimNames_validate()`. * * @return A modified copy of `dn`, or `dn` if no modification is * necessary. */ SEXP R_DimNames_fixup(SEXP dn) { SEXP s; int i, fixup = 0; for (i = 0; i < 2 && !fixup; ++i) fixup = (s = VECTOR_ELT(dn, i)) != R_NilValue && (LENGTH(s) == 0 || TYPEOF(s) != STRSXP); if (!fixup) return dn; SEXP dn_ = PROTECT(allocVector(VECSXP, 2)); for (i = 0; i < 2; ++i) { if ((s = VECTOR_ELT(dn, i)) == R_NilValue || LENGTH(s) == 0) continue; if (TYPEOF(s) == STRSXP) PROTECT(s); else if (TYPEOF(s) == INTSXP && inherits(s, "factor")) PROTECT(s = asCharacterFactor(s)); else { PROTECT(s = coerceVector(s, STRSXP)); SET_ATTRIB(s, R_NilValue); SET_OBJECT(s, 0); } SET_VECTOR_ELT(dn_, i, s); UNPROTECT(1); /* s */ } s = getAttrib(dn, R_NamesSymbol); if (s != R_NilValue) { PROTECT(s); setAttrib(dn_, R_NamesSymbol, s); UNPROTECT(1); /* s */ } UNPROTECT(1); /* dn_ */ return dn_; } /* Class validity methods ============================================== NB: These assume that validity methods for superclasses have already been called via validObject() ... */ SEXP Matrix_validate(SEXP obj) { SEXP dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)); char *msg = Dim_validate(dim); if (!msg) { SEXP dimnames = PROTECT(GET_SLOT(obj, Matrix_DimNamesSym)); msg = DimNames_validate(dimnames, INTEGER(dim)); UNPROTECT(1); /* dimnames */ } UNPROTECT(1); /* dim */ return (msg) ? mkString(msg) : ScalarLogical(1); } SEXP MatrixFactorization_validate(SEXP obj) { return Matrix_validate(obj); } #define KINDMATRIX_VALIDATE(_PREFIX_, _SEXPTYPE_) \ SEXP _PREFIX_ ## Matrix_validate(SEXP obj) \ { \ SEXP x = GET_SLOT(obj, Matrix_xSym); \ if (TYPEOF(x) != _SEXPTYPE_) \ RMKMS(_("'%s' slot is not of type \"%s\""), "x", type2char(_SEXPTYPE_)); \ return ScalarLogical(1); \ } KINDMATRIX_VALIDATE(n, LGLSXP) KINDMATRIX_VALIDATE(l, LGLSXP) KINDMATRIX_VALIDATE(i, INTSXP) KINDMATRIX_VALIDATE(d, REALSXP) KINDMATRIX_VALIDATE(z, CPLXSXP) #undef KINDMATRIX_VALIDATE SEXP compMatrix_validate(SEXP obj) { SEXP factors = GET_SLOT(obj, Matrix_factorsSym); if (TYPEOF(factors) != VECSXP) RMKMS(_("'%s' slot is not a list"), "factors"); if (XLENGTH(factors) > 0) { PROTECT(factors); SEXP nms = getAttrib(factors, R_NamesSymbol); UNPROTECT(1); /* factors */ if (nms == R_NilValue) RMKMS(_("'%s' slot has no '%s' attribute"), "factors", "names"); } return ScalarLogical(1); } SEXP symmetricMatrix_validate(SEXP obj) { SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), n = pdim[0]; if (pdim[1] != n) RMKMS(_("%s[1] != %s[2] (matrix is not square)"), "Dim", "Dim"); #ifdef ENFORCE_SYMMETRIC_DIMNAMES /* This check can be expensive when both rownames and colnames have nonzero length, and even more so when coercions to character are required ... Users can avoid the expense by setting at least one of rownames and colnames to NULL or by ensuring that they are the same object, as testing for pointer equality is fast ... */ # define ANY_TO_STRING(x) \ ((TYPEOF(x) == INTSXP && inherits(x, "factor")) \ ? asCharacterFactor(x) \ : coerceVector(x, STRSXP)) SEXP dn = PROTECT(GET_SLOT(obj, Matrix_DimNamesSym)), ndn = getAttrib(dn, R_NamesSymbol); UNPROTECT(1); /* dn */ const char *ndn0, *ndn1; if (ndn != R_NilValue && *(ndn0 = CHAR(STRING_ELT(ndn, 0))) != '\0' && *(ndn1 = CHAR(STRING_ELT(ndn, 1))) != '\0' && strcmp(ndn0, ndn1) != 0) RMKMS(_("%s[1] differs from %s[2]"), "Dimnames", "Dimnames"); if (n > 0) { /* NB: It is already known that the length of 'dn[[i]]' is 0 or 'n' */ SEXP rn, cn; if ((rn = VECTOR_ELT(dn, 0)) != R_NilValue && (cn = VECTOR_ELT(dn, 1)) != R_NilValue && LENGTH(rn) == n && LENGTH(cn) == n && rn != cn) { PROTECT(rn); PROTECT(cn); PROTECT(rn = ANY_TO_STRING(rn)); PROTECT(cn = ANY_TO_STRING(cn)); UNPROTECT(4); /* cn, rn */ if (!equal_character_vectors(rn, cn, n)) RMKMS(_("%s[1] differs from %s[2]"), "Dimnames", "Dimnames"); } } # undef ANY_TO_STRING #endif SEXP uplo = GET_SLOT(obj, Matrix_uploSym); if (TYPEOF(uplo) != STRSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "uplo", "character"); if (XLENGTH(uplo) != 1) RMKMS(_("'%s' slot does not have length %d"), "uplo", 1); const char *ul = CHAR(STRING_ELT(uplo, 0)); if (ul[0] == '\0' || ul[1] != '\0' || (ul[0] != 'U' && ul[0] != 'L')) RMKMS(_("'%s' slot is not \"%s\" or \"%s\""), "uplo", "U", "L"); return ScalarLogical(1); } SEXP triangularMatrix_validate(SEXP obj) { SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), n = pdim[0]; if (pdim[1] != n) RMKMS(_("%s[1] != %s[2] (matrix is not square)"), "Dim", "Dim"); SEXP uplo = GET_SLOT(obj, Matrix_uploSym); if (TYPEOF(uplo) != STRSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "uplo", "character"); if (XLENGTH(uplo) != 1) RMKMS(_("'%s' slot does not have length %d"), "uplo", 1); const char *ul = CHAR(STRING_ELT(uplo, 0)); if (ul[0] == '\0' || ul[1] != '\0' || (ul[0] != 'U' && ul[0] != 'L')) RMKMS(_("'%s' slot is not \"%s\" or \"%s\""), "uplo", "U", "L"); SEXP diag = GET_SLOT(obj, Matrix_diagSym); if (TYPEOF(diag) != STRSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "diag", "character"); if (XLENGTH(diag) != 1) RMKMS(_("'%s' slot does not have length %d"), "diag", 1); const char *di = CHAR(STRING_ELT(diag, 0)); if (di[0] == '\0' || di[1] != '\0' || (di[0] != 'N' && di[0] != 'U')) RMKMS(_("'%s' slot is not \"%s\" or \"%s\""), "diag", "N", "U"); return ScalarLogical(1); } SEXP diagonalMatrix_validate(SEXP obj) { SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), n = pdim[0]; if (pdim[1] != n) RMKMS(_("%s[1] != %s[2] (matrix is not square)"), "Dim", "Dim"); SEXP diag = GET_SLOT(obj, Matrix_diagSym); if (TYPEOF(diag) != STRSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "diag", "character"); if (XLENGTH(diag) != 1) RMKMS(_("'%s' slot does not have length %d"), "diag", 1); const char *di = CHAR(STRING_ELT(diag, 0)); if (di[0] == '\0' || di[1] != '\0' || (di[0] != 'N' && di[0] != 'U')) RMKMS(_("'%s' slot is not \"%s\" or \"%s\""), "diag", "N", "U"); int nonunit = di[0] == 'N'; SEXP x = GET_SLOT(obj, Matrix_xSym); if (nonunit) { if (XLENGTH(x) != n) RMKMS(_("'%s' slot is \"%s\" but '%s' slot does not have length %s"), "diag", "N", "x", "Dim[1]"); } else { if (XLENGTH(x) != 0) RMKMS(_("'%s' slot is \"%s\" but '%s' slot does not have length %s"), "diag", "U", "x", "0"); } return ScalarLogical(1); } SEXP indMatrix_validate(SEXP obj) { SEXP margin = GET_SLOT(obj, Matrix_marginSym); if (TYPEOF(margin) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "margin", "integer"); if (XLENGTH(margin) != 1) RMKMS(_("'%s' slot does not have length %d"), "margin", 1); int mg = INTEGER(margin)[0] - 1; if (mg != 0 && mg != 1) RMKMS(_("'%s' slot is not %d or %d"), "margin", 1, 2); SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), m = pdim[mg], n = pdim[!mg]; if (m > 0 && n == 0) { if (mg == 0) RMKMS(_("%s-by-%s %s invalid for positive '%s' when %s=%d"), "m", "0", "indMatrix", "m", "margin", 1); else RMKMS(_("%s-by-%s %s invalid for positive '%s' when %s=%d"), "0", "n", "indMatrix", "n", "margin", 2); } SEXP perm = GET_SLOT(obj, Matrix_permSym); if (TYPEOF(perm) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "perm", "integer"); if (XLENGTH(perm) != m) RMKMS(_("'%s' slot does not have length %s"), "perm", "Dim[margin]"); int *pperm = INTEGER(perm); while (m--) { if (*pperm == NA_INTEGER) RMKMS(_("'%s' slot contains NA"), "perm"); if (*pperm < 1 || *pperm > n) RMKMS(_("'%s' slot has elements not in {%s}"), "perm", "1,...,Dim[1+margin%%2]"); ++pperm; } return ScalarLogical(1); } SEXP pMatrix_validate(SEXP obj) { SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), n = pdim[0]; if (pdim[1] != n) RMKMS(_("%s[1] != %s[2] (matrix is not square)"), "Dim", "Dim"); if (n > 1) { SEXP perm = GET_SLOT(obj, Matrix_permSym); char *work; int lwork = n; Matrix_Calloc(work, lwork, char); int j, *pperm = INTEGER(perm); for (j = 0; j < n; ++j) { if (work[*pperm - 1]) FRMKMS(_("'%s' slot contains duplicates"), "perm"); work[*(pperm++) - 1] = 1; } Matrix_Free(work, lwork); } return ScalarLogical(1); } SEXP CsparseMatrix_validate(SEXP obj) { SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; SEXP p = PROTECT(GET_SLOT(obj, Matrix_pSym)), i = PROTECT(GET_SLOT(obj, Matrix_iSym)); UNPROTECT(2); /* i, p */ if (TYPEOF(p) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "p", "integer"); if (XLENGTH(p) - 1 != n) RMKMS(_("'%s' slot does not have length %s"), "p", "Dim[2]+1"); int *pp = INTEGER(p); if (pp[0] != 0) RMKMS(_("first element of '%s' slot is not 0"), "p"); int j; for (j = 1; j <= n; ++j) { if (pp[j] == NA_INTEGER) RMKMS(_("'%s' slot contains NA"), "p"); if (pp[j] < pp[j - 1]) RMKMS(_("'%s' slot is not nondecreasing"), "p"); if (pp[j] - pp[j - 1] > m) RMKMS(_("first differences of '%s' slot exceed %s"), "p", "Dim[1]"); } if (TYPEOF(i) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "i", "integer"); if (XLENGTH(i) < pp[n]) RMKMS(_("'%s' slot has length less than %s"), "i", "p[length(p)]"); int *pi = INTEGER(i), k, kend, ik, i0; for (j = 1, k = 0; j <= n; ++j) { kend = pp[j]; i0 = -1; while (k < kend) { ik = pi[k]; if (ik == NA_INTEGER) RMKMS(_("'%s' slot contains NA"), "i"); if (ik < 0 || ik >= m) RMKMS(_("'%s' slot has elements not in {%s}"), "i", "0,...,Dim[1]-1"); if (ik <= i0) RMKMS(_("'%s' slot is not increasing within columns"), "i"); i0 = ik; ++k; } } return ScalarLogical(1); } SEXP RsparseMatrix_validate(SEXP obj) { SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; SEXP p = PROTECT(GET_SLOT(obj, Matrix_pSym)), j = PROTECT(GET_SLOT(obj, Matrix_jSym)); UNPROTECT(2); /* j, p */ if (TYPEOF(p) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "p", "integer"); if (XLENGTH(p) - 1 != m) RMKMS(_("'%s' slot does not have length %s"), "p", "Dim[1]+1"); int *pp = INTEGER(p); if (pp[0] != 0) RMKMS(_("first element of '%s' slot is not 0"), "p"); int i; for (i = 1; i <= m; ++i) { if (pp[i] == NA_INTEGER) RMKMS(_("'%s' slot contains NA"), "p"); if (pp[i] < pp[i - 1]) RMKMS(_("'%s' slot is not nondecreasing"), "p"); if (pp[i] - pp[i - 1] > n) RMKMS(_("first differences of '%s' slot exceed %s"), "p", "Dim[2]"); } if (TYPEOF(j) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "j", "integer"); if (XLENGTH(j) < pp[m]) RMKMS(_("'%s' slot has length less than %s"), "j", "p[length(p)]"); int *pj = INTEGER(j), k, kend, jk, j0; for (i = 1, k = 0; i <= m; ++i) { kend = pp[i]; j0 = -1; while (k < kend) { jk = pj[k]; if (jk == NA_INTEGER) RMKMS(_("'%s' slot contains NA"), "j"); if (jk < 0 || jk >= n) RMKMS(_("'%s' slot has elements not in {%s}"), "j", "0,...,Dim[2]-1"); if (jk <= j0) RMKMS(_("'%s' slot is not increasing within rows"), "j"); j0 = jk; ++k; } } return ScalarLogical(1); } SEXP TsparseMatrix_validate(SEXP obj) { SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; SEXP i = PROTECT(GET_SLOT(obj, Matrix_iSym)), j = PROTECT(GET_SLOT(obj, Matrix_jSym)); UNPROTECT(2); /* j, i */ if (TYPEOF(i) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "i", "integer"); if (TYPEOF(j) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "j", "integer"); R_xlen_t nnz = XLENGTH(i); if (XLENGTH(j) != nnz) RMKMS(_("'%s' and '%s' slots do not have equal length"), "i", "j"); if (nnz > 0) { if (m == 0 || n == 0) RMKMS(_("'%s' slot has nonzero length but %s is 0"), "i", "prod(Dim)"); int *pi = INTEGER(i), *pj = INTEGER(j); while (nnz--) { if (*pi == NA_LOGICAL) RMKMS(_("'%s' slot contains NA"), "i"); if (*pj == NA_LOGICAL) RMKMS(_("'%s' slot contains NA"), "j"); if (*pi < 0 || *pi >= m) RMKMS(_("'%s' slot has elements not in {%s}"), "i", "0,...,Dim[1]-1"); if (*pj < 0 || *pj >= n) RMKMS(_("'%s' slot has elements not in {%s}"), "j", "0,...,Dim[2]-1"); ++pi; ++pj; } } return ScalarLogical(1); } SEXP sCMatrix_validate(SEXP obj) { SEXP p = GET_SLOT(obj, Matrix_pSym); int *pp = INTEGER(p), n = (int) (XLENGTH(p) - 1); if (pp[n] > 0) { PROTECT(p); SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = *CHAR(STRING_ELT(uplo, 0)); SEXP i = GET_SLOT(obj, Matrix_iSym); int *pi = INTEGER(i), j, k, kend; UNPROTECT(1); /* p */ if (ul == 'U') { for (j = 0, k = 0; j < n; ++j) { kend = pp[j + 1]; while (k < kend) { if (pi[k] > j) RMKMS(_("%s=\"%s\" but there are entries below the diagonal"), "uplo", "U"); ++k; } } } else { for (j = 0, k = 0; j < n; ++j) { kend = pp[j + 1]; while (k < kend) { if (pi[k] < j) RMKMS(_("%s=\"%s\" but there are entries above the diagonal"), "uplo", "L"); ++k; } } } } return ScalarLogical(1); } SEXP tCMatrix_validate(SEXP obj) { SEXP diag = GET_SLOT(obj, Matrix_diagSym); char di = *CHAR(STRING_ELT(diag, 0)); if (di == 'N') return sCMatrix_validate(obj); SEXP p = GET_SLOT(obj, Matrix_pSym); int *pp = INTEGER(p), n = (int) (XLENGTH(p) - 1); if (pp[n] > 0) { PROTECT(p); SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = *CHAR(STRING_ELT(uplo, 0)); SEXP i = GET_SLOT(obj, Matrix_iSym); int *pi = INTEGER(i), j, k, kend; UNPROTECT(1); /* p */ if (ul == 'U') { for (j = 0, k = 0; j < n; ++j) { kend = pp[j + 1]; while (k < kend) { if (pi[k] > j) RMKMS(_("%s=\"%s\" but there are entries below the diagonal"), "uplo", "U"); if (pi[k] == j) RMKMS(_("%s=\"%s\" but there are entries on the diagonal"), "diag", "U"); ++k; } } } else { for (j = 0, k = 0; j < n; ++j) { kend = pp[j + 1]; while (k < kend) { if (pi[k] < j) RMKMS(_("%s=\"%s\" but there are entries above the diagonal"), "uplo", "L"); if (pi[k] == j) RMKMS(_("%s=\"%s\" but there are entries on the diagonal"), "diag", "U"); ++k; } } } } return ScalarLogical(1); } SEXP sRMatrix_validate(SEXP obj) { SEXP p = GET_SLOT(obj, Matrix_pSym); int *pp = INTEGER(p), m = (int) (XLENGTH(p) - 1); if (pp[m] > 0) { PROTECT(p); SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = *CHAR(STRING_ELT(uplo, 0)); SEXP j = GET_SLOT(obj, Matrix_jSym); int *pj = INTEGER(j), i, k, kend; UNPROTECT(1); /* p */ if (ul == 'U') { for (i = 0, k = 0; i < m; ++i) { kend = pp[i + 1]; while (k < kend) { if (pj[k] < i) RMKMS(_("%s=\"%s\" but there are entries below the diagonal"), "uplo", "U"); ++k; } } } else { for (i = 0, k = 0; i < m; ++i) { kend = pp[i + 1]; while (k < kend) { if (pj[k] > i) RMKMS(_("%s=\"%s\" but there are entries above the diagonal"), "uplo", "L"); ++k; } } } } return ScalarLogical(1); } SEXP tRMatrix_validate(SEXP obj) { SEXP diag = GET_SLOT(obj, Matrix_diagSym); char di = *CHAR(STRING_ELT(diag, 0)); if (di == 'N') return sRMatrix_validate(obj); SEXP p = GET_SLOT(obj, Matrix_pSym); int *pp = INTEGER(p), m = (int) (XLENGTH(p) - 1); if (pp[m] > 0) { PROTECT(p); SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = *CHAR(STRING_ELT(uplo, 0)); SEXP j = GET_SLOT(obj, Matrix_jSym); int *pj = INTEGER(j), i, k, kend; UNPROTECT(1); /* p */ if (ul == 'U') { for (i = 0, k = 0; i < m; ++i) { kend = pp[i + 1]; while (k < kend) { if (pj[k] < i) RMKMS(_("%s=\"%s\" but there are entries below the diagonal"), "uplo", "U"); if (pj[k] == i) RMKMS(_("%s=\"%s\" but there are entries on the diagonal"), "diag", "U"); ++k; } } } else { for (i = 0, k = 0; i < m; ++i) { kend = pp[i + 1]; while (k < kend) { if (pj[k] > i) RMKMS(_("%s=\"%s\" but there are entries above the diagonal"), "uplo", "L"); if (pj[k] == i) RMKMS(_("%s=\"%s\" but there are entries on the diagonal"), "diag", "U"); ++k; } } } } return ScalarLogical(1); } SEXP sTMatrix_validate(SEXP obj) { SEXP i = GET_SLOT(obj, Matrix_iSym); R_xlen_t nnz = XLENGTH(i); if (nnz > 0) { PROTECT(i); SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = *CHAR(STRING_ELT(uplo, 0)); SEXP j = GET_SLOT(obj, Matrix_jSym); int *pi = INTEGER(i), *pj = INTEGER(j); UNPROTECT(1); /* i */ if (ul == 'U') { while (nnz--) if (*(pi++) > *(pj++)) RMKMS(_("%s=\"%s\" but there are entries below the diagonal"), "uplo", "U"); } else { while (nnz--) if (*(pi++) < *(pj++)) RMKMS(_("%s=\"%s\" but there are entries above the diagonal"), "uplo", "L"); } } return ScalarLogical(1); } SEXP tTMatrix_validate(SEXP obj) { SEXP diag = GET_SLOT(obj, Matrix_diagSym); char di = *CHAR(STRING_ELT(diag, 0)); if (di == 'N') return sTMatrix_validate(obj); SEXP i = GET_SLOT(obj, Matrix_iSym); R_xlen_t nnz = XLENGTH(i); if (nnz > 0) { PROTECT(i); SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = *CHAR(STRING_ELT(uplo, 0)); SEXP j = GET_SLOT(obj, Matrix_jSym); int *pi = INTEGER(i), *pj = INTEGER(j); UNPROTECT(1); /* i */ if (ul == 'U') { while (nnz--) { if (*pi > *pj) RMKMS(_("%s=\"%s\" but there are entries below the diagonal"), "uplo", "U"); if (*pi == *pj) RMKMS(_("%s=\"%s\" but there are entries on the diagonal"), "diag", "U"); ++pi; ++pj; } } else { while (nnz--) { if (*pi < *pj) RMKMS(_("%s=\"%s\" but there are entries above the diagonal"), "uplo", "L"); if (*pi == *pj) RMKMS(_("%s=\"%s\" but there are entries on the diagonal"), "diag", "U"); ++pi; ++pj; } } } return ScalarLogical(1); } SEXP xgCMatrix_validate(SEXP obj) { SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)), i = PROTECT(GET_SLOT(obj, Matrix_iSym)); UNPROTECT(2); /* i, x */ if (XLENGTH(x) != XLENGTH(i)) RMKMS(_("'%s' and '%s' slots do not have equal length"), "i", "x"); return ScalarLogical(1); } SEXP xsCMatrix_validate(SEXP obj) { SEXP val = xgCMatrix_validate(obj); if (TYPEOF(val) != STRSXP) val = sCMatrix_validate(obj); return val; } SEXP xtCMatrix_validate(SEXP obj) { SEXP val = xgCMatrix_validate(obj); if (TYPEOF(val) != STRSXP) val = tCMatrix_validate(obj); return val; } SEXP xgRMatrix_validate(SEXP obj) { SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)), j = PROTECT(GET_SLOT(obj, Matrix_jSym)); UNPROTECT(2); /* j, x */ if (XLENGTH(x) != XLENGTH(j)) RMKMS(_("'%s' and '%s' slots do not have equal length"), "j", "x"); return ScalarLogical(1); } SEXP xsRMatrix_validate(SEXP obj) { SEXP val = xgRMatrix_validate(obj); if (TYPEOF(val) != STRSXP) val = sRMatrix_validate(obj); return val; } SEXP xtRMatrix_validate(SEXP obj) { SEXP val = xgRMatrix_validate(obj); if (TYPEOF(val) != STRSXP) val = tRMatrix_validate(obj); return val; } SEXP xgTMatrix_validate(SEXP obj) { SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)), i = PROTECT(GET_SLOT(obj, Matrix_iSym)); UNPROTECT(2); /* i, x */ if (XLENGTH(x) != XLENGTH(i)) RMKMS(_("'%s' and '%s' slots do not have equal length"), "i", "x"); return ScalarLogical(1); } SEXP xsTMatrix_validate(SEXP obj) { SEXP val = xgTMatrix_validate(obj); if (TYPEOF(val) != STRSXP) val = sTMatrix_validate(obj); return val; } SEXP xtTMatrix_validate(SEXP obj) { SEXP val = xgTMatrix_validate(obj); if (TYPEOF(val) != STRSXP) val = tTMatrix_validate(obj); return val; } SEXP unpackedMatrix_validate(SEXP obj) { SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)), dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)); UNPROTECT(2); /* dim, x */ int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; if (XLENGTH(x) != (Matrix_int_fast64_t) m * n) RMKMS(_("'%s' slot does not have length %s"), "x", "prod(Dim)"); return ScalarLogical(1); } SEXP packedMatrix_validate(SEXP obj) { SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)), dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)); UNPROTECT(2); /* dim, x */ int n = INTEGER(dim)[0]; if (XLENGTH(x) != n + ((Matrix_int_fast64_t) n * (n - 1)) / 2) RMKMS(_("'%s' slot does not have length %s"), "x", "Dim[1]*(Dim[1]+1)/2"); return ScalarLogical(1); } SEXP dpoMatrix_validate(SEXP obj) { /* NB: Non-finite entries are "valid" because we consider crossprod(x) and tcrossprod(x) to be positive semidefinite even if 'x' contains non-finite entries (for speed) ... */ SEXP dim = GET_SLOT(obj, Matrix_DimSym); int j, n = INTEGER(dim)[0]; R_xlen_t n1a = (R_xlen_t) n + 1; /* Non-negative diagonal elements are necessary but _not_ sufficient */ SEXP x = GET_SLOT(obj, Matrix_xSym); double *px = REAL(x); for (j = 0; j < n; ++j, px += n1a) if (!ISNAN(*px) && *px < 0.0) RMK(_("matrix has negative diagonal elements")); return ScalarLogical(1); } SEXP dppMatrix_validate(SEXP obj) { /* NB: Non-finite entries are "valid" because we consider crossprod(x) and tcrossprod(x) to be positive semidefinite even if 'x' contains non-finite entries (for speed) ... */ SEXP dim = GET_SLOT(obj, Matrix_DimSym); int j, n = INTEGER(dim)[0]; SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = *CHAR(STRING_ELT(uplo, 0)); /* Non-negative diagonal elements are necessary but _not_ sufficient */ SEXP x = GET_SLOT(obj, Matrix_xSym); double *px = REAL(x); if (ul == 'U') { for (j = 0; j < n; px += (++j)+1) if (!ISNAN(*px) && *px < 0.0) RMK(_("matrix has negative diagonal elements")); } else { for (j = 0; j < n; px += n-(j++)) if (!ISNAN(*px) && *px < 0.0) RMK(_("matrix has negative diagonal elements")); } return ScalarLogical(1); } SEXP corMatrix_validate(SEXP obj) { SEXP dim = GET_SLOT(obj, Matrix_DimSym); int j, n = INTEGER(dim)[0]; R_xlen_t n1a = (R_xlen_t) n + 1; SEXP x = GET_SLOT(obj, Matrix_xSym); double *px = REAL(x); for (j = 0; j < n; ++j, px += n1a) if (ISNAN(*px) || *px != 1.0) RMK(_("matrix has nonunit diagonal elements")); SEXP sd = GET_SLOT(obj, Matrix_sdSym); if (TYPEOF(sd) != REALSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "sd", "double"); if (XLENGTH(sd) != n) RMKMS(_("'%s' slot does not have length %s"), "sd", "Dim[1]"); double *psd = REAL(sd); for (j = 0; j < n; ++j) if (!ISNAN(psd[j]) && psd[j] < 0.0) RMKMS(_("'%s' slot has negative elements"), "sd"); return ScalarLogical(1); } SEXP pcorMatrix_validate(SEXP obj) { SEXP dim = GET_SLOT(obj, Matrix_DimSym); int j, n = INTEGER(dim)[0]; SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = *CHAR(STRING_ELT(uplo, 0)); SEXP x = GET_SLOT(obj, Matrix_xSym); double *px = REAL(x); if (ul == 'U') { for (j = 0; j < n; px += (++j)+1) if (ISNAN(*px) || *px != 1.0) RMK(_("matrix has nonunit diagonal elements")); } else { for (j = 0; j < n; px += n-(j++)) if (ISNAN(*px) || *px != 1.0) RMK(_("matrix has nonunit diagonal elements")); } SEXP sd = GET_SLOT(obj, Matrix_sdSym); if (TYPEOF(sd) != REALSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "sd", "double"); if (XLENGTH(sd) != n) RMKMS(_("'%s' slot does not have length %s"), "sd", "Dim[1]"); double *psd = REAL(sd); for (j = 0; j < n; ++j) if (!ISNAN(psd[j]) && psd[j] < 0.0) RMKMS(_("'%s' slot has negative elements"), "sd"); return ScalarLogical(1); } SEXP sparseVector_validate(SEXP obj) { SEXP length = GET_SLOT(obj, Matrix_lengthSym); if (TYPEOF(length) != INTSXP && TYPEOF(length) != REALSXP) RMKMS(_("'%s' slot is not of type \"%s\" or \"%s\""), "length", "integer", "double"); if (XLENGTH(length) != 1) RMKMS(_("'%s' slot does not have length %d"), "length", 1); Matrix_int_fast64_t n; if (TYPEOF(length) == INTSXP) { int n_ = INTEGER(length)[0]; if (n_ == NA_INTEGER) RMKMS(_("'%s' slot is NA"), "length"); if (n_ < 0) RMKMS(_("'%s' slot is negative"), "length"); n = (Matrix_int_fast64_t) n_; } else { double n_ = REAL(length)[0]; if (ISNAN(n_)) RMKMS(_("'%s' slot is NA"), "length"); if (n_ < 0.0) RMKMS(_("'%s' slot is negative"), "length"); if (n_ > 0x1.0p+53) RMKMS(_("'%s' slot exceeds %s"), "length", "2^53"); n = (Matrix_int_fast64_t) n_; } SEXP i = GET_SLOT(obj, Matrix_iSym); if (TYPEOF(i) != INTSXP && TYPEOF(i) != REALSXP) RMKMS(_("'%s' slot is not of type \"%s\" or \"%s\""), "i", "integer", "double"); R_xlen_t nnz = XLENGTH(i); if (nnz > n) RMKMS(_("'%s' slot has length greater than '%s' slot"), "i", "length"); if (TYPEOF(i) == INTSXP) { int *pi = INTEGER(i), max = (n > INT_MAX) ? INT_MAX : (int) n, last = 0; while (nnz--) { if (*pi == NA_INTEGER) RMKMS(_("'%s' slot contains NA"), "i"); if (*pi < 1 || *pi > max) RMKMS(_("'%s' slot has elements not in {%s}"), "i", "1,...,length"); if (*pi <= last) RMKMS(_("'%s' slot is not increasing"), "i"); last = *(pi++); } } else { double *pi = REAL(i), max = (double) n, last = 0.0, tmp; while (nnz--) { if (ISNAN(*pi)) RMKMS(_("'%s' slot contains NA"), "i"); tmp = trunc(*(pi++)); if (tmp < 1.0 || tmp > max) RMKMS(_("'%s' slot has elements not in {%s} after truncation towards zero"), "i", "1,...,length"); if (tmp <= last) RMKMS(_("'%s' slot is not increasing after truncation towards zero"), "i"); last = tmp; } } return ScalarLogical(1); } #define KINDVECTOR_VALIDATE(_PREFIX_, _SEXPTYPE_) \ SEXP _PREFIX_ ## sparseVector_validate(SEXP obj) \ { \ SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)), \ i = PROTECT(GET_SLOT(obj, Matrix_iSym)); \ UNPROTECT(2); /* i, x */ \ if (TYPEOF(x) != _SEXPTYPE_) \ RMKMS(_("'%s' slot is not of type \"%s\""), "x", type2char(_SEXPTYPE_)); \ if (XLENGTH(x) != XLENGTH(i)) \ RMKMS(_("'%s' and '%s' slots do not have equal length"), "i", "x"); \ return ScalarLogical(1); \ } KINDVECTOR_VALIDATE(l, LGLSXP) KINDVECTOR_VALIDATE(i, INTSXP) KINDVECTOR_VALIDATE(d, REALSXP) KINDVECTOR_VALIDATE(z, CPLXSXP) #undef KINDVECTOR_VALIDATE SEXP denseLU_validate(SEXP obj) { /* In R, we start by checking that 'obj' would be a valid dgeMatrix */ SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1], r = (m < n) ? m : n; SEXP perm = GET_SLOT(obj, Matrix_permSym); if (TYPEOF(perm) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "perm", "integer"); if (XLENGTH(perm) != r) RMKMS(_("'%s' slot does not have length %s"), "perm", "min(Dim)"); int *pperm = INTEGER(perm); while (r--) { if (*pperm == NA_INTEGER) RMKMS(_("'%s' slot contains NA"), "perm"); if (*pperm < 1 || *pperm > m) RMKMS(_("'%s' slot has elements not in {%s}"), "perm", "1,...,Dim[1]"); ++pperm; } return ScalarLogical(1); } SEXP sparseLU_validate(SEXP obj) { SEXP dim = GET_SLOT(obj, Matrix_DimSym), uplo, diag; int *pdim = INTEGER(dim), n = pdim[0]; if (pdim[1] != n) RMKMS(_("%s[1] != %s[2] (matrix is not square)"), "Dim", "Dim"); SEXP L = PROTECT(GET_SLOT(obj, Matrix_LSym)); PROTECT(dim = GET_SLOT(L, Matrix_DimSym)); PROTECT(uplo = GET_SLOT(L, Matrix_uploSym)); PROTECT(diag = GET_SLOT(L, Matrix_diagSym)); UNPROTECT(4); /* diag, uplo, dim, L */ pdim = INTEGER(dim); if (pdim[0] != n || pdim[1] != n) RMKMS(_("dimensions of '%s' slot are not identical to '%s'"), "L", "Dim"); if (*CHAR(STRING_ELT(uplo, 0)) == 'U') RMKMS(_("'%s' slot is upper (not lower) triangular"), "L"); if (*CHAR(STRING_ELT(diag, 0)) == 'N') { PROTECT(L); SEXP p = PROTECT(GET_SLOT(L, Matrix_pSym)), i = PROTECT(GET_SLOT(L, Matrix_iSym)), x = PROTECT(GET_SLOT(L, Matrix_xSym)); UNPROTECT(4); /* x, i, p, L */ int *pp = INTEGER(p), *pi = INTEGER(i), j, k, kend; double *px = REAL(x); for (j = 0, k = 0; j < n; ++j) { kend = pp[j + 1]; if (kend == k || pi[k] != j || px[k] != 1.0) RMKMS(_("'%s' slot has nonunit diagonal elements"), "L"); k = kend; } } SEXP U = PROTECT(GET_SLOT(obj, Matrix_USym)); PROTECT(dim = GET_SLOT(U, Matrix_DimSym)); PROTECT(uplo = GET_SLOT(U, Matrix_uploSym)); UNPROTECT(3); /* uplo, dim, U */ pdim = INTEGER(dim); if (pdim[0] != n || pdim[1] != n) RMKMS(_("dimensions of '%s' slot are not identical to '%s'"), "U", "Dim"); if (*CHAR(STRING_ELT(uplo, 0)) != 'U') RMKMS(_("'%s' slot is lower (not upper) triangular"), "U"); SEXP p = PROTECT(GET_SLOT(obj, Matrix_pSym)), q = PROTECT(GET_SLOT(obj, Matrix_qSym)); UNPROTECT(2); /* q, p */ if (TYPEOF(p) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "p", "integer"); if (TYPEOF(q) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "q", "integer"); if (XLENGTH(p) != n) RMKMS(_("'%s' slot does not have length %s"), "p", "Dim[1]"); if (XLENGTH(q) != n && XLENGTH(q) != 0) RMKMS(_("'%s' slot does not have length %s or length %s"), "q", "Dim[2]", "0"); char *work; int lwork = n; Matrix_Calloc(work, lwork, char); int j, *pp = INTEGER(p); for (j = 0; j < n; ++j) { if (*pp == NA_INTEGER) FRMKMS(_("'%s' slot contains NA"), "p"); if (*pp < 0 || *pp >= n) FRMKMS(_("'%s' slot has elements not in {%s}"), "p", "0,...,Dim[1]-1"); if (work[*pp]) FRMKMS(_("'%s' slot contains duplicates"), "p"); work[*(pp++)] = 1; } if (LENGTH(q) == n) { int *pq = INTEGER(q); for (j = 0; j < n; ++j) { if (*pq == NA_INTEGER) FRMKMS(_("'%s' slot contains NA"), "q"); if (*pq < 0 || *pq >= n) FRMKMS(_("'%s' slot has elements not in {%s}"), "q", "0,...,Dim[2]-1"); if (!work[*pq]) FRMKMS(_("'%s' slot contains duplicates"), "q"); work[*(pq++)] = 0; } } Matrix_Free(work, lwork); return ScalarLogical(1); } SEXP sparseQR_validate(SEXP obj) { /* MJ: assuming for simplicity that 'V' and 'R' slots are formally valid */ SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; if (m < n) RMK(_("matrix has more columns than rows")); SEXP beta = GET_SLOT(obj, Matrix_betaSym); if (TYPEOF(beta) != REALSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "beta", "double"); if (XLENGTH(beta) != n) RMKMS(_("'%s' slot does not have length %s"), "beta", "Dim[2]"); SEXP p, i, q; int *pp, *pi, *pq, j, k, kend; SEXP V = PROTECT(GET_SLOT(obj, Matrix_VSym)); PROTECT(dim = GET_SLOT(V, Matrix_DimSym)); PROTECT(p = GET_SLOT(V, Matrix_pSym)); PROTECT(i = GET_SLOT(V, Matrix_iSym)); UNPROTECT(4); /* i, p, dim, V */ pdim = INTEGER(dim); int m0 = pdim[0]; if (m0 < m) RMKMS(_("'%s' slot has fewer than %s rows"), "V", "Dim[1]"); if (m0 > m + n) RMKMS(_("'%s' slot has more than %s rows"), "V", "Dim[1]+Dim[2]"); if (pdim[1] != n) RMKMS(_("'%s' slot does not have %s columns"), "V", "Dim[2]"); pp = INTEGER(p); pi = INTEGER(i); for (j = 0, k = 0; j < n; ++j) { kend = pp[j + 1]; if (k < kend) { if (pi[k] < j) RMKMS(_("'%s' slot must be lower trapezoidal but has entries above the diagonal"), "V"); } k = kend; } SEXP R = PROTECT(GET_SLOT(obj, Matrix_RSym)); PROTECT(dim = GET_SLOT(R, Matrix_DimSym)); PROTECT(p = GET_SLOT(R, Matrix_pSym)); PROTECT(i = GET_SLOT(R, Matrix_iSym)); UNPROTECT(4); /* i, p, dim, R */ pdim = INTEGER(dim); if (pdim[0] != m0) RMKMS(_("'%s' slot does not have %s row"), "R", "nrow(V)"); if (pdim[1] != n) RMKMS(_("'%s' slot does not have %s columns"), "R", "Dim[2]"); pp = INTEGER(p); pi = INTEGER(i); for (j = 0, k = 0; j < n; ++j) { kend = pp[j + 1]; if (k < kend) { if (pi[kend - 1] > j) RMKMS(_("'%s' slot must be upper trapezoidal but has entries below the diagonal"), "R"); #if 0 /* cs_house imposes diag(R) >= 0 in CSparse but not in CXSparse */ if (pi[kend - 1] == j && !ISNAN(px[kend - 1]) && px[kend - 1] < 0.0) RMKMS(_("'%s' slot has negative diagonal elements"), "R"); #endif } k = kend; } PROTECT(p = GET_SLOT(obj, Matrix_pSym)); PROTECT(q = GET_SLOT(obj, Matrix_qSym)); UNPROTECT(2); /* q, p */ if (TYPEOF(p) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "p", "integer"); if (TYPEOF(q) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "q", "integer"); if (XLENGTH(p) != m0) RMKMS(_("'%s' slot does not have length %s"), "p", "nrow(V)"); if (XLENGTH(q) != n && XLENGTH(q) != 0) RMKMS(_("'%s' slot does not have length %s or length %s"), "q", "Dim[2]", "0"); char *work; int lwork = m0; /* n <= m <= m0 */ Matrix_Calloc(work, lwork, char); pp = INTEGER(p); for (j = 0; j < m0; ++j) { if (*pp == NA_INTEGER) FRMKMS(_("'%s' slot contains NA"), "p"); if (*pp < 0 || *pp >= m0) FRMKMS(_("'%s' slot has elements not in {%s}"), "p", "0,...,nrow(V)-1"); if (work[*pp]) FRMKMS(_("'%s' slot contains duplicates"), "p"); work[*(pp++)] = 1; } if (LENGTH(q) == n) { pq = INTEGER(q); for (j = 0; j < n; ++j) { if (*pq == NA_INTEGER) FRMKMS(_("'%s' slot contains NA"), "q"); if (*pq < 0 || *pq >= n) FRMKMS(_("'%s' slot has elements not in {%s}"), "q", "0,...,Dim[2]-1"); if (!work[*pq]) FRMKMS(_("'%s' slot contains duplicates"), "q"); work[*(pq++)] = 0; } } Matrix_Free(work, lwork); return ScalarLogical(1); } SEXP BunchKaufman_validate(SEXP obj) { /* In R, we start by checking that 'obj' would be a valid dtrMatrix */ SEXP dim = GET_SLOT(obj, Matrix_DimSym); int n = INTEGER(dim)[0]; SEXP perm = GET_SLOT(obj, Matrix_permSym); if (TYPEOF(perm) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "perm", "integer"); if (XLENGTH(perm) != n) RMKMS(_("'%s' slot does not have length %s"), "perm", "Dim[1]"); int n_ = n, *pperm = INTEGER(perm); while (n_) { if (*pperm == NA_INTEGER) RMKMS(_("'%s' slot contains NA"), "perm"); if (*pperm < -n || *pperm == 0 || *pperm > n) RMKMS(_("'%s' slot has elements not in {%s}\\{%s}"), "perm", "-Dim[1],...,Dim[1]", "0"); if (*pperm > 0) { pperm += 1; n_ -= 1; } else if (n_ > 1 && *(pperm + 1) == *pperm) { pperm += 2; n_ -= 2; } else RMKMS(_("'%s' slot has unpaired negative elements"), "perm"); } return ScalarLogical(1); } SEXP pBunchKaufman_validate(SEXP obj) { /* In R, we start by checking that 'obj' would be a valid dtpMatrix */ return BunchKaufman_validate(obj); } SEXP Cholesky_validate(SEXP obj) { /* In R, we start by checking that 'obj' would be a valid dtrMatrix */ SEXP dim = GET_SLOT(obj, Matrix_DimSym); int j, n = INTEGER(dim)[0]; R_xlen_t n1a = (R_xlen_t) n + 1; /* Non-negative diagonal elements are necessary _and_ sufficient */ SEXP x = GET_SLOT(obj, Matrix_xSym); double *px = REAL(x); for (j = 0; j < n; ++j, px += n1a) if (!ISNAN(*px) && *px < 0.0) RMK(_("Cholesky factor has negative diagonal elements")); SEXP perm = GET_SLOT(obj, Matrix_permSym); if (TYPEOF(perm) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "perm", "integer"); if (XLENGTH(perm) != n && XLENGTH(perm) != 0) RMKMS(_("'%s' slot does not have length %s or length %s"), "perm", "Dim[1]", "0"); if (LENGTH(perm) == n) { char *work; int lwork = n; Matrix_Calloc(work, lwork, char); int *pperm = INTEGER(perm); for (j = 0; j < n; ++j) { if (*pperm == NA_INTEGER) FRMKMS(_("'%s' slot contains NA"), "perm"); if (*pperm < 0 || *pperm >= n) FRMKMS(_("'%s' slot has elements not in {%s}"), "perm", "0,...,Dim[1]-1"); if (work[*pperm]) FRMKMS(_("'%s' slot contains duplicates"), "perm"); work[*(pperm++)] = 1; } Matrix_Free(work, lwork); } return ScalarLogical(1); } SEXP pCholesky_validate(SEXP obj) { /* In R, we start by checking that 'obj' would be a valid dtpMatrix */ SEXP dim = GET_SLOT(obj, Matrix_DimSym); int j, n = INTEGER(dim)[0]; SEXP uplo = GET_SLOT(obj, Matrix_uploSym); char ul = *CHAR(STRING_ELT(uplo, 0)); /* Non-negative diagonal elements are necessary _and_ sufficient */ SEXP x = GET_SLOT(obj, Matrix_xSym); double *px = REAL(x); if (ul == 'U') { for (j = 0; j < n; px += (++j)+1) if (!ISNAN(*px) && *px < 0.0) RMK(_("Cholesky factor has negative diagonal elements")); } else { for (j = 0; j < n; px += n-(j++)) if (!ISNAN(*px) && *px < 0.0) RMK(_("Cholesky factor has negative diagonal elements")); } SEXP perm = GET_SLOT(obj, Matrix_permSym); if (TYPEOF(perm) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "perm", "integer"); if (XLENGTH(perm) != n && XLENGTH(perm) != 0) RMKMS(_("'%s' slot does not have length %s or length %s"), "perm", "Dim[1]", "0"); if (LENGTH(perm) == n) { char *work; int lwork = n; Matrix_Calloc(work, lwork, char); int *pperm = INTEGER(perm); for (j = 0; j < n; ++j) { if (*pperm == NA_INTEGER) FRMKMS(_("'%s' slot contains NA"), "perm"); if (*pperm < 0 || *pperm >= n) FRMKMS(_("'%s' slot has elements not in {%s}"), "perm", "0,...,Dim[1]-1"); if (work[*pperm]) FRMKMS(_("'%s' slot contains duplicates"), "perm"); work[*(pperm++)] = 1; } Matrix_Free(work, lwork); } return ScalarLogical(1); } SEXP CHMfactor_validate(SEXP obj) { SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), n = pdim[0]; if (pdim[1] != n) RMKMS(_("%s[1] != %s[2] (matrix is not square)"), "Dim", "Dim"); SEXP type = GET_SLOT(obj, install("type")); if (TYPEOF(type) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "type", "integer"); if (XLENGTH(type) != 6) RMKMS(_("'%s' slot does not have length %d"), "type", 6); int order = INTEGER(type)[0]; if (order < 0 || order > 4) RMKMS(_("%s[%d] (%s) is not in %s"), "type", 1, "cholmod_factor.ordering", "0:4"); SEXP colcount = GET_SLOT(obj, install("colcount")); if (TYPEOF(colcount) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "colcount", "integer"); if (XLENGTH(colcount) != n) RMKMS(_("'%s' slot does not have length %s"), "colcount", "Dim[2]"); int j, *pcolcount = INTEGER(colcount); for (j = 0; j < n; ++j) { if (pcolcount[j] == NA_INTEGER) RMKMS(_("'%s' slot contains NA"), "colcount"); if (pcolcount[j] < 0 || pcolcount[j] > n - j) RMKMS(_("%s is not in {%s}"), "colcount[j]", "0,...,Dim[1]-j+1"); } SEXP perm = GET_SLOT(obj, Matrix_permSym); if (TYPEOF(perm) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "perm", "integer"); if (order == 0) { if (XLENGTH(perm) != 0) RMKMS(_("'%s' slot does not have length %d"), "perm", 0); } else { if (XLENGTH(perm) != n) RMKMS(_("'%s' slot does not have length %s"), "perm", "Dim[1]"); char *work; int lwork = n; Matrix_Calloc(work, lwork, char); int *pperm = INTEGER(perm); for (j = 0; j < n; ++j) { if (*pperm == NA_INTEGER) FRMKMS(_("'%s' slot contains NA"), "perm"); if (*pperm < 0 || *pperm >= n) FRMKMS(_("'%s' slot has elements not in {%s}"), "perm", "0,...,Dim[1]-1"); if (work[*pperm]) FRMKMS(_("'%s' slot contains duplicates"), "perm"); work[*(pperm++)] = 1; } Matrix_Free(work, lwork); } return ScalarLogical(1); } SEXP CHMsimpl_validate(SEXP obj) { SEXP dim = GET_SLOT(obj, Matrix_DimSym); int n = INTEGER(dim)[0]; if (n == INT_MAX) RMKMS(_("%s is not representable as \"%s\""), "Dim[1]+1", "integer"); SEXP type = GET_SLOT(obj, install("type")); int *ptype = INTEGER(type), mono = ptype[3]; if (ptype[1] != 0 && ptype[1] != 1) RMKMS(_("%s[%d] (%s) is not %d or %d"), "type", 2, "cholmod_factor.is_ll", 0, 1); if (ptype[2] != 0) RMKMS(_("%s[%d] (%s) is not %d"), "type", 3, "cholmod_factor.is_super", 0); if (ptype[3] != 0 && ptype[3] != 1) RMKMS(_("%s[%d] (%s) is not %d or %d"), "type", 4, "cholmod_factor.is_monotonic", 0, 1); SEXP nxt = PROTECT(GET_SLOT(obj, install("nxt"))), prv = PROTECT(GET_SLOT(obj, install("prv"))), nz = PROTECT(GET_SLOT(obj, install("nz"))), p = PROTECT(GET_SLOT(obj, Matrix_pSym)), i = PROTECT(GET_SLOT(obj, Matrix_iSym)); UNPROTECT(5); /* i, p, nz, prv, nxt */ if (TYPEOF(nxt) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "nxt", "integer"); if (TYPEOF(prv) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "prv", "integer"); if (XLENGTH(nxt) - 2 != n) RMKMS(_("'%s' slot does not have length %s"), "nxt", "Dim[2]+2"); if (XLENGTH(prv) - 2 != n) RMKMS(_("'%s' slot does not have length %s"), "prv", "Dim[2]+2"); int *pnxt = INTEGER(nxt), *pprv = INTEGER(prv), j1 = pnxt[n + 1], j2 = pprv[n], count = n + 1; while (count--) { if (j1 < 0 || j1 > n) RMKMS(_("%s has elements not in {%s}"), "nxt[-(Dim[2]+1)]", "0,...,Dim[2]"); if (j2 < 0 || j2 > n + 1 || j2 == n) RMKMS(_("%s has elements not in {%s}\\{%s}"), "prv[-(Dim[2]+2)]", "0,...,Dim[2]+1", "Dim[2]"); if ((count > 1) && mono && (pnxt[j1] != j1 + 1 || pprv[j2] != j2 - 1)) RMKMS(_("%s is %d but columns are not stored in increasing order"), "type[4]", 1); if ((count >= 1) ? j1 == n : j1 != n) RMKMS(_("traversal of '%s' slot does not complete in exactly %s steps"), "nxt", "length(nxt)"); if ((count >= 1) ? j2 == n + 1 : j2 != n + 1) RMKMS(_("traversal of '%s' slot does not complete in exactly %s steps"), "prv", "length(prv)"); j1 = pnxt[j1]; j2 = pprv[j2]; } if (j1 != -1) RMKMS(_("%s is not %d"), "nxt[Dim[2]+1]", -1); if (j2 != -1) RMKMS(_("%s is not %d"), "prv[Dim[2]+2]", -1); if (TYPEOF(nz) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "nz", "integer"); if (XLENGTH(nz) != n) RMKMS(_("'%s' slot does not have length %s"), "nz", "Dim[2]"); int j, *pnz = INTEGER(nz); for (j = 0; j < n; ++j) { if (pnz[j] == NA_INTEGER) RMKMS(_("'%s' slot contains NA"), "nz"); if (pnz[j] < 1 || pnz[j] > n - j) RMKMS(_("%s is not in {%s}"), "nz[j]", "1,...,Dim[1]-j+1"); } if (TYPEOF(p) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "p", "integer"); if (XLENGTH(p) - 1 != n) RMKMS(_("'%s' slot does not have length %s"), "p", "Dim[2]+1"); j1 = pnxt[n + 1]; int *pp = INTEGER(p); if (pp[j1] != 0) RMKMS(_("column '%s' is stored first but %s is not 0"), "j", "p[j]"); for (j = 0; j < n; ++j) { j2 = pnxt[j1]; if (pp[j2] == NA_INTEGER) RMKMS(_("'%s' slot contains NA"), "p"); if (pp[j2] < pp[j1]) RMKMS(_("'%s' slot is not increasing when traversed in stored column order"), "p"); if (pp[j2] - pp[j1] < pnz[j1]) RMKMS(_("'%s' slot allocates fewer than %s elements for column '%s'"), "i", "nz[j]", "j"); if (pp[j2] - pp[j1] > n - j1) RMKMS(_("'%s' slot allocates more than %s elements for column '%s'"), "i", "Dim[2]-j+1", "j"); j1 = j2; } if (TYPEOF(i) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "i", "integer"); if (XLENGTH(i) != pp[n]) RMKMS(_("'%s' slot does not have length %s"), "i", "p[length(p)]"); int *pi = INTEGER(i), *pi_, k; j1 = pnxt[n + 1]; for (j = 0; j < n; ++j) { pi_ = pi + pp[j1]; if (pi_[0] != j1) RMKMS(_("first entry in column '%s' does not have row index '%s'"), "j", "j"); for (k = 1; k < pnz[j1]; ++k) { if (pi_[k] == NA_INTEGER) RMKMS(_("'%s' slot contains NA"), "i"); if (pi_[k] < 0 || pi_[k] >= n) RMKMS(_("'%s' slot has elements not in {%s}"), "i", "0,...,Dim[1]-1"); if (pi_[k] <= pi_[k - 1]) RMKMS(_("'%s' slot is not increasing within columns"), "i"); } j1 = pnxt[j1]; } return ScalarLogical(1); } SEXP CHMsuper_validate(SEXP obj) { SEXP dim = GET_SLOT(obj, Matrix_DimSym); int n = INTEGER(dim)[0]; SEXP type = GET_SLOT(obj, install("type")); int *ptype = INTEGER(type); if (ptype[1] != 1) RMKMS(_("%s[%d] (%s) is not %d"), "type", 2, "cholmod_factor.is_ll", 1); if (ptype[2] != 1) RMKMS(_("%s[%d] (%s) is not %d"), "type", 3, "cholmod_factor.is_super", 1); if (ptype[3] != 1) RMKMS(_("%s[%d] (%s) is not %d"), "type", 4, "cholmod_factor.is_monotonic", 1); if (ptype[4] < 0) RMKMS(_("%s[%d] (%s) is negative"), "type", 5, "cholmod_factor.maxcsize"); if (ptype[5] < 0) RMKMS(_("%s[%d] (%s) is negative"), "type", 6, "cholmod_factor.maxesize"); if (n > 0 && ptype[5] >= n) RMKMS(_("%s[%d] (%s) is not less than %s"), "type", 6, "cholmod_factor.maxesize", "Dim[1]"); /* FIXME: maxcsize and maxesize are well-defined properties of the factorization, so we should also test that the values are _correct_ ... see CHOLMOD/Supernodal/cholmod_super_symbolic.c */ SEXP super = PROTECT(GET_SLOT(obj, install("super"))), pi = PROTECT(GET_SLOT(obj, install("pi"))), px = PROTECT(GET_SLOT(obj, install("px"))), s = PROTECT(GET_SLOT(obj, install("s"))); UNPROTECT(4); /* s, px, pi, super */ if (TYPEOF(super) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "super", "integer"); R_xlen_t nsuper1a = XLENGTH(super); if (nsuper1a - 1 < ((n > 0) ? 1 : 0)) RMKMS(_("'%s' slot has length less than %d"), "super", 2); if (nsuper1a - 1 > n) RMKMS(_("'%s' slot has length greater than %s"), "super", "Dim[2]+1"); int k, nsuper = (int) (nsuper1a - 1), *psuper = INTEGER(super); if (psuper[0] != 0) RMKMS(_("first element of '%s' slot is not 0"), "super"); if (psuper[nsuper] != n) RMKMS(_("last element of '%s' slot is not %s"), "super", "Dim[2]"); for (k = 1; k <= nsuper; ++k) { if (psuper[k] == NA_INTEGER) RMKMS(_("'%s' slot contains NA"), "super"); if (psuper[k] <= psuper[k - 1]) RMKMS(_("'%s' slot is not increasing"), "super"); } if (TYPEOF(pi) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "pi", "integer"); if (TYPEOF(px) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "px", "integer"); if (XLENGTH(pi) != nsuper1a) RMKMS(_("'%s' and '%s' slots do not have equal length"), "pi", "super"); if (XLENGTH(px) != nsuper1a) RMKMS(_("'%s' and '%s' slots do not have equal length"), "px", "super"); int *ppi = INTEGER(pi), *ppx = INTEGER(px), nr, nc; if (ppi[0] != 0) RMKMS(_("first element of '%s' slot is not 0"), "pi"); if (ppx[0] != 0) RMKMS(_("first element of '%s' slot is not 0"), "px"); for (k = 1; k <= nsuper; ++k) { if (ppi[k] == NA_INTEGER) RMKMS(_("'%s' slot contains NA"), "pi"); if (ppx[k] == NA_INTEGER) RMKMS(_("'%s' slot contains NA"), "px"); if (ppi[k] <= ppi[k - 1]) RMKMS(_("'%s' slot is not increasing"), "pi"); if (ppx[k] <= ppx[k - 1]) RMKMS(_("'%s' slot is not increasing"), "px"); nr = ppi[k] - ppi[k - 1]; nc = psuper[k] - psuper[k - 1]; if (nr < nc) RMKMS(_("first differences of '%s' slot are less than those of '%s' slot"), "pi", "super"); if ((Matrix_int_fast64_t) nr * nc > INT_MAX) RMKMS(_("supernode lengths exceed %s"), "2^31-1"); if (ppx[k] - ppx[k - 1] != nr * nc) RMKMS(_("first differences of '%s' slot are not equal to supernode lengths"), "px"); } if (TYPEOF(s) != INTSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "s", "integer"); if (XLENGTH(s) != ppi[nsuper]) RMKMS(_("'%s' slot does not have length %s"), "s", "pi[length(pi)]"); int i, j, *ps = INTEGER(s); for (k = 1; k <= nsuper; ++k) { nr = ppi[k] - ppi[k-1]; nc = psuper[k] - (j = psuper[k-1]); for (i = 0; i < nr; ++i) { if (ps[i] == NA_INTEGER) RMKMS(_("'%s' slot contains NA"), "s"); if (ps[i] < 0 || ps[i] >= n) RMKMS(_("'%s' slot has elements not in {%s}"), "s", "0,...,Dim[1]-1"); if (i < nc) { if (ps[i] != j + i) RMKMS(_("'%s' slot is wrong within diagonal blocks (row and column indices do not coincide)"), "s"); } else { if (ps[i] <= ps[i-1]) RMKMS(_("'%s' slot is not increasing within supernodes"), "s"); } } ps += nr; } return ScalarLogical(1); } SEXP dCHMsimpl_validate(SEXP obj) { SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)), p = PROTECT(GET_SLOT(obj, Matrix_pSym)), type = PROTECT(GET_SLOT(obj, install("type"))); UNPROTECT(3); /* type, p, x */ if (TYPEOF(x) != REALSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "x", "double"); int *pp = INTEGER(p), n = (int) (XLENGTH(p) - 1); if (XLENGTH(x) != pp[n]) RMKMS(_("'%s' slot does not have length %s"), "x", "p[length(p)]"); if (INTEGER(type)[1]) { int j; double *px = REAL(x); /* Non-negative diagonal elements are necessary _and_ sufficient */ for (j = 0; j < n; ++j) if (!ISNAN(px[pp[j]]) && px[pp[j]] < 0.0) RMK(_("Cholesky factor has negative diagonal elements")); } return ScalarLogical(1); } SEXP dCHMsuper_validate(SEXP obj) { SEXP x = PROTECT(GET_SLOT(obj, Matrix_xSym)), px = PROTECT(GET_SLOT(obj, install("px"))), pi = PROTECT(GET_SLOT(obj, install("pi"))), super = PROTECT(GET_SLOT(obj, install("super"))); UNPROTECT(4); /* super, pi, px, x */ if (TYPEOF(x) != REALSXP) RMKMS(_("'%s' slot is not of type \"%s\""), "x", "double"); int *ppx = INTEGER(px), nsuper = (int) (XLENGTH(px) - 1); if (XLENGTH(x) != ppx[nsuper]) RMKMS(_("'%s' slot does not have length %s"), "x", "px[length(px)]"); int *ppi = INTEGER(pi), *psuper = INTEGER(super), k, j, nc; double *pu = REAL(x), *pv; R_xlen_t nr1a; /* Non-negative diagonal elements are necessary _and_ sufficient */ for (k = 0; k < nsuper; ++k) { nc = psuper[k+1] - psuper[k]; nr1a = (R_xlen_t) (ppi[k+1] - ppi[k]) + 1; pv = pu + ppx[k]; for (j = 0; j < nc; ++j) { if (!ISNAN(*pv) && *pv < 0.0) RMK(_("Cholesky factor has negative diagonal elements")); pv += nr1a; } } return ScalarLogical(1); } SEXP Schur_validate(SEXP obj) { /* MJ: assuming for simplicity that 'Q' and 'T' slots are formally valid */ SEXP dim = GET_SLOT(obj, Matrix_DimSym); int *pdim = INTEGER(dim), n = pdim[0]; if (pdim[1] != n) RMKMS(_("%s[1] != %s[2] (matrix is not square)"), "Dim", "Dim"); SEXP Q = PROTECT(GET_SLOT(obj, Matrix_QSym)); dim = GET_SLOT(Q, Matrix_DimSym); pdim = INTEGER(dim); UNPROTECT(1); /* Q */ if (pdim[0] != n || pdim[1] != n) RMKMS(_("dimensions of '%s' slot are not identical to '%s'"), "Q", "Dim"); SEXP T = PROTECT(GET_SLOT(obj, Matrix_TSym)); dim = GET_SLOT(T, Matrix_DimSym); pdim = INTEGER(dim); UNPROTECT(1); /* T */ if (pdim[0] != n || pdim[1] != n) RMKMS(_("dimensions of '%s' slot are not identical to '%s'"), "T", "Dim"); SEXP v = GET_SLOT(obj, install("EValues")); SEXPTYPE tv = TYPEOF(v); if (tv != REALSXP && tv != CPLXSXP) RMKMS(_("'%s' slot is not of type \"%s\" or \"%s\""), "EValues", "double", "complex"); if (XLENGTH(v) != n) RMKMS(_("'%s' slot does not have length %s"), "EValues", "Dim[1]"); return ScalarLogical(1); } /* where 'cl' must be an element of VALID_NONVIRTUAL_MATRIX */ void validObject(SEXP obj, const char *cl) { #ifndef MATRIX_DISABLE_VALIDITY SEXP status; # define IS_VALID(_CLASS_) \ do { \ status = _CLASS_ ## _validate(obj); \ if (TYPEOF(status) == STRSXP) \ error(_("invalid class \"%s\" object: %s"), \ cl, CHAR(STRING_ELT(status, 0))); \ } while (0) #define IS_VALID_SPARSE(_C_) \ do { \ IS_VALID(_C_ ## sparseMatrix); \ if (cl[0] == 'n') { \ if (cl[1] == 's') \ IS_VALID(s ## _C_ ## Matrix); \ else if (cl[1] == 't') \ IS_VALID(t ## _C_ ## Matrix); \ } else { \ if (cl[1] == 'g') \ IS_VALID(xg ## _C_ ## Matrix); \ else if (cl[1] == 's') \ IS_VALID(xs ## _C_ ## Matrix); \ else if (cl[1] == 't') \ IS_VALID(xt ## _C_ ## Matrix); \ } \ } while (0) IS_VALID(Matrix); if ((cl[0] == 'i' && cl[1] == 'n' && cl[2] == 'd') || (cl[0] == 'p' && cl[1] != 'c')) { IS_VALID(indMatrix); if (cl[0] == 'p') IS_VALID(pMatrix); return; } const char *cl_ = cl; if (cl[0] == 'c') cl = "dpoMatrix"; else if (cl[0] == 'p' && cl[1] == 'c') cl = "dppMatrix"; if (cl[0] == 'n' && cl[2] != 'C' && cl[2] != 'R' && cl[2] != 'T') IS_VALID(nMatrix); else if (cl[0] == 'l') IS_VALID(lMatrix); else if (cl[0] == 'i') IS_VALID(iMatrix); else if (cl[0] == 'd') IS_VALID(dMatrix); else if (cl[0] == 'z') IS_VALID(zMatrix); if (cl[1] == 's' || cl[1] == 'p') IS_VALID(symmetricMatrix); else if (cl[1] == 't') IS_VALID(triangularMatrix); else if (cl[1] == 'd') { IS_VALID(diagonalMatrix); return; } if (cl[2] == 'C') IS_VALID_SPARSE(C); else if (cl[2] == 'R') IS_VALID_SPARSE(R); else if (cl[2] == 'T') IS_VALID_SPARSE(T); else if (cl[2] != 'p') { IS_VALID(unpackedMatrix); if (cl[1] == 'p') { IS_VALID(dpoMatrix); if (cl_[0] == 'c') IS_VALID(corMatrix); } } else { IS_VALID(packedMatrix); if (cl[1] == 'p') { IS_VALID(dppMatrix); if (cl_[0] == 'p' && cl_[1] == 'c') IS_VALID(pcorMatrix); } } # undef IS_VALID_SPARSE # undef IS_VALID #endif return; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/vignettes/�����������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14547724214�013540� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/vignettes/Comparisons.Rnw��������������������������������������������������������������������0000644�0001762�0000144�00000021663�14444514070�016526� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������\documentclass{article} \usepackage{myVignette} \usepackage[authoryear,round]{natbib} \bibliographystyle{plainnat} %%\VignetteIndexEntry{Comparisons of Least Squares calculation speeds} %%\VignetteDepends{Matrix,datasets,stats,utils} \begin{document} \SweaveOpts{engine=R,eps=FALSE,pdf=TRUE,width=5,height=3,strip.white=true,keep.source=TRUE} \setkeys{Gin}{width=\textwidth} \title{Comparing Least Squares Calculations} \author{Douglas Bates\\R Development Core Team\\\email{Douglas.Bates@R-project.org}} \date{\today} \maketitle \begin{abstract} Many statistics methods require one or more least squares problems to be solved. There are several ways to perform this calculation, using objects from the base R system and using objects in the classes defined in the \code{Matrix} package. We compare the speed of some of these methods on a very small example and on a example for which the model matrix is large and sparse. \end{abstract} <>= options(width=75) library(stats) # for R_DEFAULT_PACKAGES=NULL library(utils) # ditto @ \section{Linear least squares calculations} \label{sec:LeastSquares} Many statistical techniques require least squares solutions \begin{equation} \label{eq:LeastSquares} \widehat{\bm{\beta}}= \arg\min_{\bm{\beta}}\left\|\bm{y}-\bX\bm{\beta}\right\|^2 \end{equation} where $\bX$ is an $n\times p$ model matrix ($p\leq n$), $\bm{y}$ is $n$-dimensional and $\bm{\beta}$ is $p$ dimensional. Most statistics texts state that the solution to (\ref{eq:LeastSquares}) is \begin{equation} \label{eq:XPX} \widehat{\bm{\beta}}=\left(\bX\trans\bX\right)^{-1}\bX\trans\bm{y} \end{equation} when $\bX$ has full column rank (i.e. the columns of $\bX$ are linearly independent) and all too frequently it is calculated in exactly this way. \subsection{A small example} \label{sec:smallLSQ} As an example, let's create a model matrix, \code{mm}, and corresponding response vector, \code{y}, for a simple linear regression model using the \code{Formaldehyde} data. <>= data(Formaldehyde, package = "datasets") str(Formaldehyde) (m <- cbind(1, Formaldehyde$carb)) (yo <- Formaldehyde$optden) @ Using \code{t} to evaluate the transpose, \code{solve} to take an inverse, and the \code{\%*\%} operator for matrix multiplication, we can translate \ref{eq:XPX} into the \Slang{} as <>= solve(t(m) %*% m) %*% t(m) %*% yo @ On modern computers this calculation is performed so quickly that it cannot be timed accurately in \RR{} \footnote{From R version 2.2.0, \code{system.time()} has default argument \code{gcFirst = TRUE} which is assumed and relevant for all subsequent timings} <>= system.time(solve(t(m) %*% m) %*% t(m) %*% yo) @ and it provides essentially the same results as the standard \code{lm.fit} function that is called by \code{lm}. <>= dput(c(solve(t(m) %*% m) %*% t(m) %*% yo)) dput(unname(lm.fit(m, yo)$coefficients)) @ %$ \subsection{A large example} \label{sec:largeLSQ} For a large, ill-conditioned least squares problem, such as that described in \citet{koen:ng:2003}, the literal translation of (\ref{eq:XPX}) does not perform well. <>= library(Matrix) data(KNex, package = "Matrix") y <- KNex$y mm <- as(KNex$mm, "matrix") # full traditional matrix dim(mm) system.time(naive.sol <- solve(t(mm) %*% mm) %*% t(mm) %*% y) @ Because the calculation of a ``cross-product'' matrix, such as $\bX\trans\bX$ or $\bX\trans\bm{y}$, is a common operation in statistics, the \code{crossprod} function has been provided to do this efficiently. In the single argument form \code{crossprod(mm)} calculates $\bX\trans\bX$, taking advantage of the symmetry of the product. That is, instead of calculating the $712^2=506944$ elements of $\bX\trans\bX$ separately, it only calculates the $(712\cdot 713)/2=253828$ elements in the upper triangle and replicates them in the lower triangle. Furthermore, there is no need to calculate the inverse of a matrix explicitly when solving a linear system of equations. When the two argument form of the \code{solve} function is used the linear system \begin{equation} \label{eq:LSQsol} \left(\bX\trans\bX\right) \widehat{\bm{\beta}} = \bX\trans\by \end{equation} is solved directly. Combining these optimizations we obtain <>= system.time(cpod.sol <- solve(crossprod(mm), crossprod(mm,y))) all.equal(naive.sol, cpod.sol) @ On this computer (2.0 GHz Pentium-4, 1 GB Memory, Goto's BLAS, in Spring 2004) the crossprod form of the calculation is about four times as fast as the naive calculation. In fact, the entire crossprod solution is faster than simply calculating $\bX\trans\bX$ the naive way. <>= system.time(t(mm) %*% mm) @ Note that in newer versions of \RR{} and the BLAS library (as of summer 2007), \RR's \code{\%*\%} is able to detect the many zeros in \code{mm} and shortcut many operations, and is hence much faster for such a sparse matrix than \code{crossprod} which currently does not make use of such optimizations. This is not the case when \RR{} is linked against an optimized BLAS library such as GOTO or ATLAS. %% Also, for fully dense matrices, \code{crossprod()} indeed remains faster (by a factor of two, typically) independently of the BLAS library: <>= fm <- mm set.seed(11) fm[] <- rnorm(length(fm)) system.time(c1 <- t(fm) %*% fm) system.time(c2 <- crossprod(fm)) stopifnot(all.equal(c1, c2, tol = 1e-12)) @ % using stopifnot(.) to save output \subsection{Least squares calculations with Matrix classes} \label{sec:MatrixLSQ} The \code{crossprod} function applied to a single matrix takes advantage of symmetry when calculating the product but does not retain the information that the product is symmetric (and positive semidefinite). As a result the solution of (\ref{eq:LSQsol}) is performed using general linear system solver based on an LU decomposition when it would be faster, and more stable numerically, to use a Cholesky decomposition. The Cholesky decomposition could be used but it is rather awkward <>= system.time(ch <- chol(crossprod(mm))) system.time(chol.sol <- backsolve(ch, forwardsolve(ch, crossprod(mm, y), upper = TRUE, trans = TRUE))) stopifnot(all.equal(chol.sol, naive.sol)) @ The \code{Matrix} package uses the S4 class system \citep{R:Chambers:1998} to retain information on the structure of matrices from the intermediate calculations. A general matrix in dense storage, created by the \code{Matrix} function, has class \code{"dgeMatrix"} but its cross-product has class \code{"dpoMatrix"}. The \code{solve} methods for the \code{"dpoMatrix"} class use the Cholesky decomposition. <>= mm <- as(KNex$mm, "denseMatrix") class(crossprod(mm)) system.time(Mat.sol <- solve(crossprod(mm), crossprod(mm, y))) stopifnot(all.equal(naive.sol, unname(as(Mat.sol,"matrix")))) @ Furthermore, any method that calculates a decomposition or factorization stores the resulting factorization with the original object so that it can be reused without recalculation. <>= xpx <- crossprod(mm) xpy <- crossprod(mm, y) system.time(solve(xpx, xpy)) system.time(solve(xpx, xpy)) # reusing factorization @ The model matrix \code{mm} is sparse; that is, most of the elements of \code{mm} are zero. The \code{Matrix} package incorporates special methods for sparse matrices, which produce the fastest results of all. <>= mm <- KNex$mm class(mm) system.time(sparse.sol <- solve(crossprod(mm), crossprod(mm, y))) stopifnot(all.equal(naive.sol, unname(as(sparse.sol, "matrix")))) @ As with other classes in the \code{Matrix} package, the \code{dsCMatrix} retains any factorization that has been calculated although, in this case, the decomposition is so fast that it is difficult to determine the difference in the solution times. <>= xpx <- crossprod(mm) xpy <- crossprod(mm, y) system.time(solve(xpx, xpy)) system.time(solve(xpx, xpy)) @ \subsection*{Session Info} <>= toLatex(sessionInfo()) @ <>= if(identical(1L, grep("linux", R.version[["os"]]))) { ##----- Linux - only ---- Sys.procinfo <- function(procfile) { l2 <- strsplit(readLines(procfile),"[ \t]*:[ \t]*") r <- sapply(l2[sapply(l2, length) == 2], function(c2)structure(c2[2], names= c2[1])) attr(r,"Name") <- procfile class(r) <- "simple.list" r } Scpu <- Sys.procinfo("/proc/cpuinfo") Smem <- Sys.procinfo("/proc/meminfo") } # Linux only @ <>= if(identical(1L, grep("linux", R.version[["os"]]))) { ## Linux - only --- Scpu <- sfsmisc::Sys.procinfo("/proc/cpuinfo") Smem <- sfsmisc::Sys.procinfo("/proc/meminfo") print(Scpu[c("model name", "cpu MHz", "cache size", "bogomips")]) print(Smem[c("MemTotal", "SwapTotal")]) } @ <>= if(identical(1L, grep("linux", R.version[["os"]]))) { ## Linux - only --- print(Scpu[c("model name", "cpu MHz", "cache size", "bogomips")]) print(Smem[c("MemTotal", "SwapTotal")]) } @ \bibliography{Matrix} \end{document} �����������������������������������������������������������������������������Matrix/vignettes/Matrix.bib�������������������������������������������������������������������������0000644�0001762�0000144�00000034104�12764547531�015470� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@BOOK{R:Venables+Ripley:2000, AUTHOR = {William N. Venables and Brian D. Ripley}, TITLE = {S Programming}, PUBLISHER = {Springer}, YEAR = 2000, NOTE = {ISBN 0-387-98966-8}, URL = {http://www.stats.ox.ac.uk/pub/MASS3/Sprog/}, ABSTRACT = {This provides an in-depth guide to writing software in the S language which forms the basis of both the commercial S-PLUS and the Open Source R data analysis software systems.} } @BOOK{R:Chambers+Hastie:1992, AUTHOR = {John M. Chambers and Trevor J. Hastie}, TITLE = {Statistical Models in {S}}, PUBLISHER = {Chapman \& Hall}, YEAR = 1992, ADDRESS = {London}, ISBN = {0-412-83040-X}, ABSTRACT = {This is also called the ``\emph{White Book}'', and introduced S version 3, which added structures to facilitate statistical modeling in S. } } @Article{Rnews:Gentleman+Carey:2002, author = {Robert Gentleman and Vincent Carey}, title = {Bioconductor}, journal = {R News}, year = 2002, volume = 2, number = 1, pages = {11--16}, month = {March}, url = {https://CRAN.R-project.org/doc/Rnews/} } @article{Ke:Wang:2001, author = {Ke, Chunlei and Wang, Yuedong}, title = {Semiparametric nonlinear mixed-effects models and their applications}, year = {2001}, journal = {Journal of the American Statistical Association}, volume = {96}, number = {456}, pages = {1272--1298}, keywords = {NONLINEAR MIXED EFFECTS MODEL; Penalized likelihood; Repeated measures; SELF-MODELING NONLINEAR REGRESSION; Smoothing spline} } @Article{Lind:Bate:1988, author = {Lindstrom, Mary J. and Bates, Douglas M.}, title = {Newton-{R}aphson and {EM} algorithms for linear mixed-effects models for repeated-measures data ({C}orr: 94{V}89 p1572)}, year = {1988}, journal = {Journal of the American Statistical Association}, volume = {83}, pages = {1014--1022}, keywords = {Growth curve; Longitudinal data} } @ARTICLE{Atlas, AUTHOR = "R. Clint Whaley and Antoine Petitet and Jack J. Dongarra", TITLE = "Automated Empirical Optimization of Software and the {ATLAS} Project", JOURNAL = "Parallel Computing", VOLUME = "27", NUMBER = "1--2", PAGES = "3--35", YEAR = 2001, NOTE = "Also available as University of Tennessee LAPACK Working Note \#147, UT-CS-00-448, 2000 ({\tt www.netlib.org/lapack/lawns/lawn147.ps})" } @TechReport{GotosBLAS, author = {Kazushige Goto and Robert van de Geijn}, title = {On Reducing TLB Misses in Matrix Multiplication}, institution = {Department of Computer Sciences, U. of Texas at Austin}, year = 2002, number = {TR02-55} } @Misc{Taucs, author = {Sivan Toledo}, title = {Taucs: A Library of Sparse Linear Solvers}, howpublished = {http://www.tau.ac.il/~stoledo/taucs/}, year = 2003 } @Misc{Umfpack, author = {Tim Davis}, title = {UMFPACK: Unified Multifrontal Package}, howpublished = {http://www.cise.ufl.edu/research/sparse/umfpack}, year = 2003 } @misc{Cholmod, author = {Tim Davis}, title = {{CHOLMOD}: sparse supernodal {Cholesky} factorization and update/downdate}, howpublished = {http://www.cise.ufl.edu/research/sparse/cholmod}, year = 2005 } @Misc{CSparse, author = {Tim Davis}, title = {{CSparse}: a concise sparse matrix package}, howpublished = {http://www.cise.ufl.edu/research/sparse/CSparse}, year = 2005 } @Book{davis06:csparse_book, author = {Timothy A. Davis }, title = {Direct Methods for Sparse Linear Systems}, publisher = {SIAM}, year = 2006, series = {Fundamentals of Algorithms} } @Misc{Metis, author = {George Karapis}, title = {Metis: Family of Multilevel Partioning Algorithms}, howpublished = {http://www-users.cs.umn.edu/~karypis/metis/}, year = 2003 } @Book{Linpack, author = {Jack Dongarra and Cleve Moler and Bunch and G.W. Stewart}, title = {Linpack Users' Guide}, publisher = {SIAM}, year = 1979 } @Book{Lapack, author = {E. Anderson and Z. Bai and C. Bischof and S. Blackford and J. Demmel and J. Dongarra and J. Du Croz and A. Greenbaum and S. Hammarling and A. McKenney and D. Sorensen}, title = {LAPACK Users' Guide}, chapter = {}, publisher = {SIAM}, year = 1999, address = {Philadelphia, PA}, edition = {3rd} } @Book{bryk00:_hlm, author = {A. S. Bryk and S. W. Raudenbush and R. Congdon}, title = {{HLM} version 5}, publisher = {Scientific Software International, Inc.}, year = 2000, address = {Chicago} } @Article{demp:lair:rubi:1977, Journal = JRSSB, Volume = 39, Pages = {1--22}, Keywords = {Posterior mode}, Author = {A. P. Dempster and N. M. Laird and D. B. Rubin}, Title = {Maximum Likelihood From Incomplete Data Via the {EM} Algorithm}, Year = 1977 } @Book{denn:schn:1983, author = {J. E. Dennis and R. B. Schnabel}, title = {Numerical Methods for Unconstrained Optimization and Nonlinear Equations}, publisher = {Prentice-Hall}, year = 1983, address = {Englewood Cliffs, NJ} } @Book{dong:bunc:mole:stew:1979, publisher = "SIAM", address = "Philadelphia", author = "J. J. Dongarra and J. R. Bunch and C. B. Moler and G. W. Stewart", title = "Linpack Users' Guide", year = 1979 } @Book{goldstein98:_mlwin, author = {H. Goldstein and J. Rasbash and I. Plewis and D. Draper and W. Browne and M. Wang}, title = {A user's guide to {MLwiN}}, publisher = {University of London, Institute of Education}, year = 1998, address = {London} } @Book{golu:vanl:1996, author = {Golub, Gene H. and van Loan, Charles F.}, title = {Matrix Computations}, publisher = {Johns Hopkins}, year = 1996, edition = {3rd} } @Article{ harv:1974, author = {Harville, David A.}, title = {Bayesian Inference for Variance Components Using Only Error Contrasts}, journal = {Biometrika}, year = 1974, volume = 61, pages = {383--385}, keywords = {Maximum likelihood} } @Article{ lair:ware:1982, author = {Laird, Nan M. and Ware, James H.}, title = {Random-effects Models for Longitudinal Data}, journal = {Biometrics}, year = 1982, volume = 38, pages = {963--974}, keywords = {Variance components; Repeated measurements; Empirical Bayes; EM algorithm} } @Book{lapack:1992, publisher = "SIAM", address = "Philadelphia", author = "E. Anderson and Z. Bai and C. Bischof and J. Demmel and J. Dongarra and J. Du Croz and A. Greenbaum and S. Hammaring and A. McKenney and S. Ostrouchov and D. Sorensen", title = "Lapack Users' Guide", year = 1992 } @Article{liu:rubi:1994, author = {Liu, Chuanhai and Rubin, Donald B.}, title = {The {ECME} algorithm: {A} simple extension of {EM} and {ECM} with faster monotone convergence}, year = {1994}, journal = {Biometrika}, volume = {81}, pages = {633--648}, keywords = {Markov chain monte carlo; Incomplete data} } @article{patt:thom:1971, Author = {Patterson, H. D. and Thompson, R.}, Title = {Recovery of Interblock Information When Block Sizes Are Unequal}, Year = 1971, Journal = {Biometrika}, Volume = 58, Pages = {545--554}, Keywords = {Incomplete block design; Components of variance; Maximum likelihood; Design of experiments} } @phdthesis{pinh:1994, author = {Jos\'{e} C. Pinheiro}, title = {Topics in Mixed-Effects Models}, school = {University of Wisconsin}, year = 1994, address = {Madison, WI} } @Article{pinh:bate:1995, author = "Jos\'{e} C. Pinheiro and Douglas M. Bates", title = "Approximations to the Log-Likelihood Function in the Nonlinear Mixed-Effects Model", year = 1995, journal = "Journal of Computational and Graphical Statistics", volume = 4, number = 1, pages = "12--35" } @Article{ pinh:bate:1996, author = {Jos\'{e} C. Pinheiro and Douglas M. Bates}, title = {Unconstrained Parameterizations for Variance-Covariance Matrices}, journal = {Statistics and Computing}, year = 1996, volume = 6, pages = {289--296} } @Book{pinh:bate:2000, author = {Jos\'{e} C. Pinheiro and Douglas M. Bates}, title = {Mixed-Effects Models in {S} and {S-PLUS}}, year = 2000, pages = {528}, ISBN = {0-387-98957-9}, publisher = {Springer} } @Article{schn:koon:1985, Journal = {ACM Trans. Math. Software}, Volume = 11, Pages = {419--440}, Author = {R. B. Schnabel and J. E. Koontz and B. E. Weiss}, Title = {A modular system of algorithms for unconstrained minimization}, Year = 1985 } @book{snijders99:_multil_analy, author = {Tom Snijders and Roel Bosker}, title = {Multilevel Analysis: An introduction to basic and advanced multilevel analysis}, publisher = {Sage}, year = 1999, address = {London} } @book{this:1988, Author = {Thisted, R. A.}, Title = {Elements of Statistical Computing}, Year = 1988, Publisher = {Chapman \& Hall}, address = {London} } @Article{van:2000, author = {van Dyk, David A.}, title = {Fitting mixed-effects models using efficient {EM}-type algorithms}, year = {2000}, journal = {Journal of Computational and Graphical Statistics}, volume = {9}, number = {1}, pages = {78--98}, keywords = {EM algorithm; ECME algorithm; Gaussian hierarchical models; Posterior inference; PXEM algorithm; random-effects models; Reml; variance-component models; working parameters} } @misc{jfox:2002, author = {Fox, John}, title = {Linear Mixed Models -- Appendix to {An R and S-PLUS Companion to Applied Regression}}, year = 2002, month= {May}, url = {http://www.socsci.mcmaster.ca/jfox/Books/companion/appendix-mixed-models.pdf} } @book{roge:1980, Author = {Rogers, Gerald S.}, Title = {Matrix Derivatives}, Year = 1980, Publisher = {Marcell Dekker, Inc.}, address = {New York and Basel} } @TechReport{DebRoy:Bates:2003a, author = {Saikat DebRoy and Douglas M. Bates}, title = {Computational Methods for Single Level Linear Mixed-effects Models}, institution = {Department of Statistics, University of Wisconsin-Madison}, number = {1073}, year = 2003 } @TechReport{DebRoy:Bates:2003b, author = {Saikat DebRoy and Douglas M. Bates}, title = {Computational Methods for Multiple Level Linear Mixed-effects Models}, institution = {Department of Statistics, University of Wisconsin-Madison}, number = {1076}, year = 2003 } @Article{RaudenbushYangYosef:2000, author = {Stephen W. Raudenbush and Meng-Li Yang and Matheos Yosef}, title = {Maximum Likelihood for Generalized Linear Models With Nested Random Effects via High-Order, Multivariate {L}aplace Approximation}, journal = {J. Comput. Graph. Statist.}, year = 2000, volume = 9, number = 1, pages = {141--157} } @Book{goldstein87:_multil, author = {Goldstein, Harvey}, title = {Multilevel models in education and social research}, publisher = {Oxford University Press}, year = 1987 } @Book{raudenbush02:_hierar_linear_model, author = {Stephen W. Raudenbush and Anthony S. Bryk}, title = {Hierarchical Linear Models: Applications and Data Analysis Methods}, publisher = {Sage}, year = 2002, edition = {second}, ISBN = {0-7619-1904-X} } @BOOK{R:Chambers:1998, AUTHOR = {John M. Chambers}, TITLE = {Programming with Data}, PUBLISHER = {Springer}, YEAR = 1998, ADDRESS = {New York}, ISBN = {0-387-98503-4}, ABSTRACT = {This ``\emph{Green Book}'' describes version 4 of S, a major revision of S designed by John Chambers to improve its usefulness at every stage of the programming process.} } @article{Rodriguez:Goldman:1995, author = {Germ\'an Rodriguez and Noreen Goldman}, title = {An assessment of estimation procedures for multilevel models with binary responses}, year = {1995}, journal = {Journal of the Royal Statistical Society, Series A, General}, volume = {158}, pages = {73--89}, keywords = {Logistic regression; Random effects model; Software; Variance component} } @Article{koen:ng:2003, author = {Roger Koenker and Pin Ng}, title = {{SparseM}: A Sparse Matrix Package for {R}}, journal = {J. of Statistical Software}, year = 2003, volume = 8, number = 6 } @Book{Eispack, author = {Smith, B. T. and Boyle, J. M. and Dongarra, J. J. and Garbow, B. S. and Ikebe, Y. and Klema, V. C. and Moler, C. B.}, title = {Matrix Eigensystem Routines. EISPACK Guide}, publisher = {Springer-Verlag}, year = 1976, volume = 6, series = {Lecture Notes in Computer Science}, address = {New York} } @Article{bate:debr:2004, author = {Douglas M. Bates and Saikat DebRoy}, title = {Linear Mixed Models and Penalized Least Squares}, journal = {J. of Multivariate Analysis}, year = 2004, note = {to appear} } @Article{Rnews:Lockwood+Doran+Mccaffrey:2003, author = {J.R. Lockwood and Harold Doran and Daniel F. McCaffrey}, title = {Using R for Estimating Longitudinal Student Achievement Models}, journal = {R News}, year = 2003, volume = 3, number = 3, pages = {17--23}, month = {December}, url = {https://CRAN.R-project.org/doc/Rnews/} } @Article{Paterson:1991, author = {L. Paterson}, title = {Socio economic status and educational attainment: a multidimensional and multilevel study}, journal = {Evaluation and Research in Education}, year = 1991, volume = 5, pages = {97--121} } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/vignettes/Design-issues.Rnw������������������������������������������������������������������0000644�0001762�0000144�00000020746�14444514070�016754� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������\documentclass{article} % \usepackage{myVignette} \usepackage[authoryear,round]{natbib} \bibliographystyle{plainnat} \newcommand{\noFootnote}[1]{{\small (\textit{#1})}} \newcommand{\myOp}[1]{{$\left\langle\ensuremath{#1}\right\rangle$}} %% vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv %%\VignetteIndexEntry{Design Issues in Matrix package Development} %%\VignetteDepends{Matrix,utils} \SweaveOpts{engine=R,eps=FALSE,pdf=TRUE,width=5,height=3,strip.white=true,keep.source=TRUE} % ^^^^^^^^^^^^^^^^ \title{Design Issues in Matrix package Development} \author{Martin Maechler and Douglas Bates\\R Core Development Team \\\email{maechler@stat.math.ethz.ch}, \email{bates@r-project.org}} \date{Spring 2008; Aug~2022 ({\tiny typeset on \tiny\today})} % \begin{document} \maketitle \begin{abstract} This is a (\textbf{currently very incomplete}) write-up of the many smaller and larger design decisions we have made in organizing functionalities in the Matrix package. Classes: There's a rich hierarchy of matrix classes, which you can visualize as a set of trees whose inner (and ``upper'') nodes are \emph{virtual} classes and only the leaves are non-virtual ``actual'' classes. Functions and Methods: - setAs() - others \end{abstract} %% Note: These are explained in '?RweaveLatex' : <>= options(width=75) library(utils) # for R_DEFAULT_PACKAGES=NULL library(Matrix) @ \section{The Matrix class structures} \label{sec:classes} Take Martin's DSC 2007 talk to depict the Matrix class hierarchy; available from {\small \url{https://stat.ethz.ch/~maechler/R/DSC-2007_MatrixClassHierarchies.pdf}} . % ~/R/Meetings-Kurse-etc/2007-DSC/talk.tex Matrix-classes.Rnw --- --- --- %% \hrule[1pt]{\textwidth} From far, there are \textbf{three} separate class hierarchies, and every \pkg{Matrix} package matrix has an actual (or ``factual'') class inside these three hierarchies: % ~/R/Meetings-Kurse-etc/2007-DSC/Matrix-classes.Rnw More formally, we have three (\ 3 \ ) main ``class classifications'' for our Matrices, i.e.,\\ three ``orthogonal'' partitions of ``Matrix space'', and every Matrix object's class corresponds to an \emph{intersection} of these three partitions; i.e., in R's S4 class system: We have three independent inheritance schemes for every Matrix, and each such Matrix class is simply defined to \texttt{contain} three \emph{virtual} classes (one from each partitioning scheme), e.g, The three partioning schemes are \begin{enumerate} \item Content \texttt{type}: Classes \code{dMatrix}, \code{lMatrix}, \code{nMatrix}, (\code{iMatrix}, \code{zMatrix}) for entries of type \textbf{d}ouble, \textbf{l}ogical, patter\textbf{n} (and not yet \textbf{i}nteger and complex) Matrices. \code{nMatrix} only stores the \emph{location} of non-zero matrix entries (where as logical Matrices can also have \code{NA} entries!) \item structure: general, triangular, symmetric, diagonal Matrices \item sparsity: \code{denseMatrix}, \code{sparseMatrix} \end{enumerate} For example in the most used sparseMatrix class, \code{"dgCMatrix"}, the three initial letters \code{dgC} each codes for one of the three hierarchies: \begin{description} \item{d: } \textbf{d}ouble \item{g: } \textbf{g}eneral \item{C: } \textbf{C}sparseMatrix, where \textbf{C} is for \textbf{C}olumn-compressed. \end{description} Part of this is visible from printing \code{getClass("\emph{}")}: <>= getClass("dgCMatrix") @ Another example is the \code{"nsTMatrix"} class, where \code{nsT} stands for \begin{description} \item{n: } \textbf{n} is for ``patter\textbf{n}'', boolean content where only the \emph{locations} of the non-zeros need to be stored. \item{t: } \textbf{t}riangular matrix; either \textbf{U}pper, or \textbf{L}ower. \item{T: } \textbf{T}sparseMatrix, where \textbf{T} is for \textbf{T}riplet, the simplest but least efficient way to store a sparse matrix. \end{description} From R itself, via \code{getClass(.)}: <>= getClass("ntTMatrix") @ \subsection{Diagonal Matrices} \label{ssec:diagMat} The class of diagonal matrices is worth mentioning for several reasons. First, we have wanted such a class, because \emph{multiplication} methods are particularly simple with diagonal matrices. The typical constructor is \Rfun{Diagonal} whereas the accessor (as for traditional matrices), \Rfun{diag} simply returns the \emph{vector} of diagonal entries: <>= (D4 <- Diagonal(4, 10*(1:4))) str(D4) diag(D4) @ We can \emph{modify} the diagonal in the traditional way (via method definition for \Rfun{diag<-}): <>= diag(D4) <- diag(D4) + 1:4 D4 @ Note that \textbf{unit-diagonal} matrices (the identity matrices of linear algebra) with slot \code{diag = "U"} can have an empty \code{x} slot, very analogously to the unit-diagonal triangular matrices: <>= str(I3 <- Diagonal(3)) ## empty 'x' slot getClass("diagonalMatrix") ## extending "sparseMatrix" @ Originally, we had implemented diagonal matrices as \emph{dense} rather than sparse matrices. After several years it became clear that this had not been helpful really both from a user and programmer point of view. So now, indeed the \code{"diagonalMatrix"} class does also extend \code{"sparseMatrix"}, i.e., is a subclass of it. However, we do \emph{not} store explicitly where the non-zero entries are, and the class does \emph{not} extend any of the typical sparse matrix classes, \code{"CsparseMatrix"}, \code{"TsparseMatrix"}, or \code{"RsparseMatrix"}. Rather, the \code{diag()}onal (vector) is the basic part of such a matrix, and this is simply the \code{x} slot unless the \code{diag} slot is \code{"U"}, the unit-diagonal case, which is the identity matrix. Further note, e.g., from the \code{?$\,$Diagonal} help page, that we provide (low level) utility function \code{.sparseDiagonal()} with wrappers \code{.symDiagonal()} and \code{.trDiagonal()} which will provide diagonal matrices inheriting from \code{"CsparseMatrix"} which may be advantageous in \emph{some cases}, but less efficient in others, see the help page. \section{Matrix Transformations} \label{sec:trafos} \subsection{Coercions between Matrix classes} \label{ssec:coerce} You may need to transform Matrix objects into specific shape (triangular, symmetric), content type (double, logical, \dots) or storage structure (dense or sparse). Every useR should use \code{as(x, )} to this end, where \code{} is a \emph{virtual} Matrix super class, such as \code{"triangularMatrix"} \code{"dMatrix"}, or \code{"sparseMatrix"}. In other words, the user should \emph{not} coerce directly to a specific desired class such as \code{"dtCMatrix"}, even though that may occasionally work as well. Here is a set of rules to which the Matrix developers and the users should typically adhere: \begin{description} \item[Rule~1]: \code{as(M, "matrix")} should work for \textbf{all} Matrix objects \code{M}. \item[Rule~2]: \code{Matrix(x)} should also work for matrix like objects \code{x} and always return a ``classed'' Matrix. Applied to a \code{"matrix"} object \code{m}, \code{M. <- Matrix(m)} can be considered a kind of inverse of \code{m <- as(M, "matrix")}. For sparse matrices however, \code{M.} well be a \code{CsparseMatrix}, and it is often ``more structured'' than \code{M}, e.g., <>= (M <- spMatrix(4,4, i=1:4, j=c(3:1,4), x=c(4,1,4,8))) # dgTMatrix m <- as(M, "matrix") (M. <- Matrix(m)) # dsCMatrix (i.e. *symmetric*) @ \item[Rule~3]: All the following coercions to \emph{virtual} matrix classes should work:\\ \begin{enumerate} \item \code{as(m, "dMatrix")} \item \code{as(m, "lMatrix")} \item \code{as(m, "nMatrix")} \item \code{as(m, "denseMatrix")} \item \code{as(m, "sparseMatrix")} \item \code{as(m, "generalMatrix")} \end{enumerate} whereas the next ones should work under some assumptions: \begin{enumerate} \item \code{as(m1, "triangularMatrix")} \\ should work when \code{m1} is a triangular matrix, i.e. the upper or lower triangle of \code{m1} contains only zeros. \item \code{as(m2, "symmetricMatrix")} should work when \code{m2} is a symmetric matrix in the sense of \code{isSymmetric(m2)} returning \code{TRUE}. Note that this is typically equivalent to something like \code{isTRUE(all.equal(m2, t(m2)))}, i.e., the lower and upper triangle of the matrix have to be equal \emph{up to small numeric fuzz}. \end{enumerate} \end{description} \section{Session Info} <>= toLatex(sessionInfo()) @ %not yet %\bibliography{Matrix} \end{document} ��������������������������Matrix/vignettes/myVignette.sty���������������������������������������������������������������������0000644�0001762�0000144�00000006665�12070321331�016427� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������\RequirePackage{hyperref} \RequirePackage{url} \RequirePackage{amsmath} \RequirePackage{bm}%-> \bm (= bold math) \newcommand{\Slang}{\textsf{S} language} \newcommand{\RR}{\textsf{R}} \newcommand{\email}[1]{\href{mailto:#1}{\normalfont\texttt{#1}}} %- R programming markup \newcommand\code{\bgroup\@codex} \def\@codex#1{{\normalfont\ttfamily\hyphenchar\font=-1 #1}\egroup} \let\env=\code \let\command=\code \newcommand*{\Rfun}[1]{\code{#1()}\index{\RR~function #1}} \newcommand*{\class}[1]{\code{#1}\index{class #1}}% \newcommand*{\pkg}[1]{\code{#1}\index{\RR~package #1}} % \newcommand{\kbd}[1]{{\normalfont\texttt{#1}}} \newcommand{\key}[1]{{\normalfont\texttt{\uppercase{#1}}}} \newcommand\samp{`\bgroup\@noligs\@sampx} \def\@sampx#1{{\normalfont\texttt{#1}}\egroup'} \let\option=\samp \newcommand{\var}[1]{{\normalfont\textsl{#1}}} \newcommand{\file}[1]{{`\normalfont\textsf{#1}'}} \newcommand{\dfn}[1]{{\normalfont\textsl{#1}}} \newcommand{\acronym}[1]{{\normalfont\textsc{\lowercase{#1}}}} \newcommand{\strong}[1]{{\normalfont\fontseries{b}\selectfont #1}} \let\pkg=\strong % \RequirePackage{alltt} \newenvironment{example}{\begin{alltt}}{\end{alltt}} \newenvironment{smallexample}{\begin{alltt}\small}{\end{alltt}} \newenvironment{display}{\list{}{}\item\relax}{\endlist} \newenvironment{smallverbatim}{\small\verbatim}{\endverbatim} % This is already in ``Sweave'' -- but withOUT the fontsize=\small part !! %% \RequirePackage{fancyvrb} %% \DefineVerbatimEnvironment{Sinput}{Verbatim}{fontsize=\small,fontshape=sl} %% \DefineVerbatimEnvironment{Soutput}{Verbatim}{fontsize=\small} %% \DefineVerbatimEnvironment{Scode}{Verbatim}{fontsize=\small,fontshape=sl} % \newcommand{\FIXME}[1]{\marginpar{ \dots FIXME \emph{#1} \dots}} \newcommand{\TODO}[1]{\par\noindent\textsc{Todo:} \textit{#1}\par} % %% Matrix stuff : % \newcommand{\trans}{\ensuremath{^\mathsf{T}}} \newcommand{\bA}{\ensuremath{\bm{A}}} \newcommand{\bD}{\ensuremath{\bm{D}}} \newcommand{\bDelta}{\ensuremath{\bm{\Delta}}} \newcommand{\bI}{\ensuremath{\bm{I}}} \newcommand{\bL}{\ensuremath{\bm{L}}} \newcommand{\LXXi}[1]{\ensuremath{\bL_{\mathit{XX}({#1})}}} \newcommand{\LXX}{\ensuremath{\bL_\mathit{XX}}} \newcommand{\LXZi}[1]{\ensuremath{\bL_{\mathit{XZ}({#1})}}} \newcommand{\LXZ}{\ensuremath{\bL_\mathit{XZ}}} \newcommand{\LZZi}[1]{\ensuremath{\bL_{\mathit{ZZ}({#1})}}} \newcommand{\LZZ}{\ensuremath{\bL_\mathit{ZZ}}} \newcommand{\LZZoo}{\ensuremath{\bL_{\mathit{ZZ}11}}} \newcommand{\LZZot}{\ensuremath{\bL_{\mathit{ZZ}12}}} \newcommand{\LZZtt}{\ensuremath{\bL_{\mathit{ZZ}22}}} \newcommand{\bOmega}{\ensuremath{\bm{\Omega}}} \newcommand{\bPhi}{\ensuremath{\bm{\Phi}}} \newcommand{\bR}{\ensuremath{\bm{R}}} \newcommand{\bX}{\ensuremath{\bm{X}}} \newcommand{\bZ}{\ensuremath{\bm{Z}}} \newcommand{\bbeta}{\ensuremath{\bm{\beta}}} \newcommand{\bb}{\ensuremath{\bm{b}}} \newcommand{\beps}{\ensuremath{\bm{\epsilon}}} \newcommand{\dX}{\ensuremath{\bm{d}_{\mathit{X}}}} \newcommand{\dZ}{\ensuremath{\bm{d}_{\mathit{Z}}}} \newcommand{\dy}{\ensuremath{d_{\mathit{y}}}} \newcommand{\lyXi}[1]{\ensuremath{\bm{\ell}_{\mathit{yX}(#1)}}} \newcommand{\lyX}{\ensuremath{\bm{\ell}_\mathit{yX}}} \newcommand{\lyZi}[1]{\ensuremath{\bm{\ell}_{\mathit{yZ}(#1)}}} \newcommand{\lyZ}{\ensuremath{\bm{\ell}_\mathit{yZ}}} \newcommand{\lyyi}[1]{\ensuremath{\bm{\ell}_{\mathit{yy}(#1)}}} \newcommand{\lyy}{\ensuremath{\ell_\mathit{yy}}} \newcommand{\btheta}{\ensuremath{\bm{\theta}}} \newcommand{\by}{\ensuremath{\bm{y}}} \newcommand{\bzer}{\ensuremath{\bm{0}}} ���������������������������������������������������������������������������Matrix/vignettes/Intro2Matrix.Rnw�������������������������������������������������������������������0000644�0001762�0000144�00000044616�14444514070�016576� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������\documentclass{article} % \usepackage{myVignette} \usepackage{fullpage}% save trees ;-) \usepackage[authoryear,round]{natbib} \bibliographystyle{plainnat} \newcommand{\noFootnote}[1]{{\small (\textit{#1})}} \newcommand{\myOp}[1]{{$\left\langle\ensuremath{#1}\right\rangle$}} % %%\VignetteIndexEntry{2nd Introduction to the Matrix Package} %%\VignetteDepends{Matrix,utils} \SweaveOpts{engine=R,eps=FALSE,pdf=TRUE,width=7,height=4,strip.white=true,keep.source=TRUE} % ^^^^^^^^^^^^^^^^ \title{2nd Introduction to the Matrix package} \author{Martin Maechler and Douglas Bates\\ R Core Development Team \\\email{maechler@stat.math.ethz.ch}, \email{bates@r-project.org}} \date{September 2006 ({\tiny typeset on \tiny\today})} % \begin{document} \maketitle \begin{abstract} % \emph{\Large Why should you want to work with this package and what % does it do for you?} Linear algebra is at the core of many areas of statistical computing and from its inception the \Slang{} has supported numerical linear algebra via a matrix data type and several functions and operators, such as \code{\%*\%}, \code{qr}, \code{chol}, and \code{solve}. However, these data types and functions do not provide direct access to all of the facilities for efficient manipulation of dense matrices, as provided by the Lapack subroutines, and they do not provide for manipulation of sparse matrices. The \pkg{Matrix} package provides a set of S4 classes for dense and sparse matrices that extend the basic matrix data type. Methods for a wide variety of functions and operators applied to objects from these classes provide efficient access to BLAS (Basic Linear Algebra Subroutines), Lapack (dense matrix), CHOLMOD including AMD and COLAMD and \code{Csparse} (sparse matrix) routines. One notable characteristic of the package is that whenever a matrix is factored, the factorization is stored as part of the original matrix so that further operations on the matrix can reuse this factorization. \end{abstract} %% Note: These are explained in '?RweaveLatex' : <>= options(width=75) library(utils) # for R_DEFAULT_PACKAGES=NULL @ \section{Introduction} \label{sec:Intro} The most automatic way to use the \pkg{Matrix} package is via the \Rfun{Matrix} function which is very similar to the standard \RR\ function \Rfun{matrix}, @ <>= library(Matrix) M <- Matrix(10 + 1:28, 4, 7) M tM <- t(M) @ %def Such a matrix can be appended to (using \Rfun{cbind} or \Rfun{rbind}) or indexed, <>= (M2 <- cbind(-1, M)) M[2, 1] M[4, ] @ where the last two statements show customary matrix indexing, returning a simple numeric vector each\footnote{because there's an additional default argument to indexing, \code{drop = TRUE}. If you add \hbox{``\code{\ ,\ drop = FALSE}\ ''} you will get submatrices instead of simple vectors.}. We assign 0 to some columns and rows to ``sparsify'' it, and some \code{NA}s (typically ``missing values'' in data analysis) in order to demonstrate how they are dealt with; note how we can \emph{``subassign''} as usual, for classical \RR{} matrices (i.e., single entries or whole slices at once), @ <>= M2[, c(2,4:6)] <- 0 M2[2, ] <- 0 M2 <- rbind(0, M2, 0) M2[1:2,2] <- M2[3,4:5] <- NA @ and then coerce it to a sparse matrix, @ <>= sM <- as(M2, "sparseMatrix") 10 * sM identical(sM * 2, sM + sM) is(sM / 10 + M2 %/% 2, "sparseMatrix") @ %def where the last three calls show that multiplication by a scalar keeps sparcity, as does other arithmetic, but addition to a ``dense'' object does not, as you might have expected after some thought about ``sensible'' behavior: @ <>= sM + 10 @ %def Operations on our classed matrices include (componentwise) arithmetic ($+$, $-$, $*$, $/$, etc) as partly seen above, comparison ($>$, $\le$, etc), e.g., <>= Mg2 <- (sM > 2) Mg2 @ returning a logical sparse matrix. When interested in the internal \textbf{str}ucture, \Rfun{str} comes handy, and we have been using it ourselves more regulary than \Rfun{print}ing (or \Rfun{show}ing as it happens) our matrices; alternatively, \Rfun{summary} gives output similar to Matlab's printing of sparse matrices. @ <>= str(Mg2) summary(Mg2) @ As you see from both of these, \code{Mg2} contains ``extra zero'' (here \code{FALSE}) entries; such sparse matrices may be created for different reasons, and you can use \Rfun{drop0} to remove (``drop'') these extra zeros. This should \emph{never} matter for functionality, and does not even show differently for logical sparse matrices, but the internal structure is more compact: <>= Mg2 <- drop0(Mg2) str(Mg2@x) # length 13, was 16 @ For large sparse matrices, visualization (of the sparsity pattern) is important, and we provide \Rfun{image} methods for that, e.g., <>= data(CAex, package = "Matrix") print(image(CAex, main = "image(CAex)")) # print(.) needed for Sweave @ \smallskip Further, i.e., in addition to the above implicitly mentioned \code{"Ops"} operators (\code{+}, \code{*},\dots, \code{<=},\code{>},\dots, \code{\&} which all work with our matrices, notably in conjunction with scalars and traditional matrices), the \code{"Math"}-operations (such as \Rfun{exp}, \Rfun{sin} or \Rfun{gamma}) and \code{"Math2"} (\Rfun{round} etc) and the \code{"Summary"} group of functions, \Rfun{min}, \Rfun{range}, \Rfun{sum}, all work on our matrices as they should. Note that all these are implemented via so called \emph{group methods}, see e.g., \code{?Arith} in \RR. The intention is that sparse matrices remain sparse whenever sensible, given the matrix \emph{classes} and operators involved, but not content specifically. E.g., + gives even for the rare cases where it would be advantageous to get a result. These classed matrices can be ``indexed'' (more technically ``subset'') as traditional \Slang{} (and hence \RR) matrices, as partly seen above. This also includes the idiom \code{M [ M \myOp{\mathit{op}} \myOp{\mathrm{num}}~]} which returns simple vectors, @ <>= sM[sM > 2] sml <- sM[sM <= 2] sml @ %def and \emph{``subassign''}ment similarly works in the same generality as for traditional \Slang{} matrices. %% We have seen that already above! %% This was the 2005 - Introduction vignette's first section: \subsection{\pkg{Matrix} package for numerical linear algebra} \label{ssec:intro-linalg} Linear algebra is at the core of many statistical computing techniques and, from its inception, the \Slang{} has supported numerical linear algebra via a matrix data type and several functions and operators, such as \code{\%*\%}, \code{qr}, \code{chol}, and \code{solve}. %% Initially the numerical linear algebra functions in \RR{} called underlying Fortran routines from the Linpack~\citep{Linpack} and Eispack~\citep{Eispack} libraries but over the years most of these functions have been switched to use routines from the Lapack~\citep{Lapack} library which is the state-of-the-art implementation of numerical dense linear algebra. %% Furthermore, \RR{} can be configured to use accelerated BLAS (Basic Linear Algebra Subroutines), such as those from the Atlas~\citep{Atlas} project or other ones, see the \RR~manual ``Installation and Administration''. Lapack provides routines for operating on several special forms of matrices, such as triangular matrices and symmetric matrices. Furthermore, matrix decompositions like the QR decompositions produce multiple output components that should be regarded as parts of a single object. There is some support in \RR{} for operations on special forms of matrices (e.g. the \code{backsolve}, \code{forwardsolve} and \code{chol2inv} functions) and for special structures (e.g. a QR structure is implicitly defined as a list by the \code{qr}, \code{qr.qy}, \code{qr.qty}, and related functions) but it is not as fully developed as it could be. Also there is no direct support for sparse matrices in \RR{} although \citet{koen:ng:2003} have developed the \pkg{SparseM} package for sparse matrices based on SparseKit. The \pkg{Matrix} package provides S4 classes and methods for dense and sparse matrices. The methods for dense matrices use Lapack and BLAS. The sparse matrix methods use CHOLMOD~\citep{Cholmod}, CSparse~\citep{Csparse} and other parts (AMD, COLAMD) of Tim Davis' ``SuiteSparse'' collection of sparse matrix libraries, many of which also use BLAS. \TODO{\Rfun{triu}, \Rfun{tril}, \Rfun{diag}, ... and \command{as(.,.)} , but of course only when they've seen a few different ones.} \TODO{matrix operators include \code{\%*\%}, \Rfun{crossprod}, \Rfun{tcrossprod}, \Rfun{solve}} \TODO{\Rfun{expm} is the matrix exponential ... ...} \TODO{\Rfun{symmpart} and \Rfun{skewpart} compute the symmetric part, \code{(x + t(x))/2} and the skew-symmetric part, \code{(x - t(x))/2} of a matrix \code{x}.} \TODO{factorizations include \Rfun{Cholesky} (or \Rfun{chol}), \Rfun{lu}, \Rfun{qr} (not yet for dense)} \TODO{Although generally the result of an operation on dense matrices is a dgeMatrix, certain operations return matrices of special types.} \TODO{E.g. show the distinction between \code{t(mm) \%*\% mm} and \code{crossprod(mm)}.} % \bigskip % ... ... ... The following is the old \file{Introduction.Rnw} ... FIXME ... ... \bigskip \section{Matrix Classes} The \pkg{Matrix} package provides classes for real (stored as double precision), logical and so-called ``pattern'' (binary) dense and sparse matrices. There are provisions to also provide integer and complex (stored as double precision complex) matrices. Note that in \RR, \code{logical} means entries \code{TRUE}, \code{FALSE}, or \code{NA}. To store just the non-zero pattern for typical sparse matrix algorithms, the pattern matrices are \emph{binary}, i.e., conceptually just \code{TRUE} or \code{FALSE}. In \pkg{Matrix}, the pattern matrices all have class names starting with \code{"n"} (patter\textbf{n}). \subsection{Classes for dense matrices} \label{ssec:DenseClasses} For the sake of brevity, we restrict ourselves to the \emph{real} (\textbf{d}ouble) classes, but they are paralleled by \textbf{l}ogical and patter\textbf{n} matrices for all but the positive definite ones. \begin{description} \item[dgeMatrix] Real matrices in general storage mode \item[dsyMatrix] Symmetric real matrices in non-packed storage \item[dspMatrix] Symmetric real matrices in packed storage (one triangle only) \item[dtrMatrix] Triangular real matrices in non-packed storage \item[dtpMatrix] Triangular real matrices in packed storage (triangle only) \item[dpoMatrix] Positive semi-definite symmetric real matrices in non-packed storage \item[dppMatrix] \ \ ditto \ \ in packed storage \end{description} Methods for these classes include coercion between these classes, when appropriate, and coercion to the \code{matrix} class; methods for matrix multiplication (\code{\%*\%}); cross products (\code{crossprod}), matrix norm (\code{norm}); reciprocal condition number (\code{rcond}); LU factorization (\code{lu}) or, for the \code{poMatrix} class, the Cholesky decomposition (\code{chol}); and solutions of linear systems of equations (\code{solve}). %-- mentioned above already: % Further, group methods have been defined for the \code{Arith} (basic % arithmetic, including with scalar numbers) and the \code{Math} (basic % mathematical functions) group.. Whenever a factorization or a decomposition is calculated it is preserved as a (list) element in the \code{factors} slot of the original object. In this way a sequence of operations, such as determining the condition number of a matrix then solving a linear system based on the matrix, do not require multiple factorizations of the same matrix nor do they require the user to store the intermediate results. \subsection{Classes for sparse matrices} \label{sec:SparseClasses} Used for large matrices in which most of the elements are known to be zero (or \code{FALSE} for logical and binary (``pattern'') matrices). Sparse matrices are automatically built from \Rfun{Matrix} whenever the majority of entries is zero (or \code{FALSE} respectively). Alternatively, \Rfun{sparseMatrix} builds sparse matrices from their non-zero entries and is typically recommended to construct large sparse matrices, rather than direct calls of \Rfun{new}. \TODO{E.g. model matrices created from factors with a large number of levels} \TODO{ or from spline basis functions (e.g. COBS, package \pkg{cobs}), etc.} \TODO{Other uses include representations of graphs. indeed; good you mentioned it! particularly since we still have the interface to the \pkg{graph} package. I think I'd like to draw one graph in that article --- maybe the undirected graph corresponding to a crossprod() result of dimension ca. $50^2$} \TODO{Specialized algorithms can give substantial savings in amount of storage used and execution time of operations.} \TODO{Our implementation is based on the CHOLMOD and CSparse libraries by Tim Davis.} \subsection{Representations of sparse matrices} \label{ssec:SparseReps} \subsubsection{Triplet representation (\class{TsparseMatrix})} Conceptually, the simplest representation of a sparse matrix is as a triplet of an integer vector \code{i} giving the row numbers, an integer vector \code{j} giving the column numbers, and a numeric vector \code{x} giving the non-zero values in the matrix.\footnote{For efficiency reasons, we use ``zero-based'' indexing in the \pkg{Matrix} package, i.e., the row indices \code{i} are in \code{0:(nrow(.)-1)} and the column indices \code{j} accordingly.} In \pkg{Matrix}, the \class{TsparseMatrix} class is the virtual class of all sparse matrices in triplet representation. Its main use is for easy input or transfer to other classes. As for the dense matrices, the class of the \code{x} slot may vary, and the subclasses may be triangular, symmetric or unspecified (``general''), such that the \class{TsparseMatrix} class has several\footnote{the $3 \times 3$ actual subclasses of \class{TsparseMatrix} are the three structural kinds, namely \textbf{t}riangular, \textbf{s}ymmetric and \textbf{g}eneral, times three entry classes, \textbf{d}ouble, \textbf{l}ogical, and patter\textbf{n}.} `actual'' subclasses, the most typical (numeric, general) is \class{dgTMatrix}: <>= getClass("TsparseMatrix") # (i,j, Dim, Dimnames) slots are common to all getClass("dgTMatrix") @ Note that the \emph{order} of the entries in the \code{(i,j,x)} vectors does not matter; consequently, such matrices are not unique in their representation. \footnote{ Furthermore, there can be \emph{repeated} \code{(i,j)} entries with the customary convention that the corresponding \code{x} entries are \emph{added} to form the matrix element $m_{ij}$. } %% The triplet representation is row-oriented if elements in the same row %% were adjacent and column-oriented if elements in the same column were %% adjacent. \subsubsection{Compressed representations: \class{CsparseMatrix} and \class{RsparseMatrix}} For most sparse operations we use the compressed column-oriented representation (virtual class \class{CsparseMatrix}) (also known as ``csc'', ``compressed sparse column''). Here, instead of storing all column indices \code{j}, only the \emph{start} index of every column is stored. Analogously, there is also a compressed sparse row (csr) representation, which e.g. is used in in the \pkg{SparseM} package, and we provide the \class{RsparseMatrix} for compatibility and completeness purposes, in addition to basic coercion (\code({as(., \textit{})} between the classes. %% (column-oriented triplet) except that \code{i} (\code{j}) just stores %% the index of the first element in the row (column). (There are a %% couple of other details but that is the gist of it.) These compressed representations remove the redundant row (column) indices and provide faster access to a given location in the matrix because you only need to check one row (column). There are certain advantages \footnote{routines can make use of high-level (``level-3'') BLAS in certain sparse matrix computations} to csc in systems like \RR{}, Octave and Matlab where dense matrices are stored in column-major order, therefore it is used in sparse matrix libraries such as CHOLMOD or CSparse of which we make use. For this reason, the \class{CsparseMatrix} class and subclasses are the principal classes for sparse matrices in the \pkg{Matrix} package. The Matrix package provides the following classes for sparse matrices \FIXME{many more --- maybe explain naming scheme?} \begin{description} \item[dgTMatrix] general, numeric, sparse matrices in (a possibly redundant) triplet form. This can be a convenient form in which to construct sparse matrices. \item[dgCMatrix] general, numeric, sparse matrices in the (sorted) compressed sparse column format. \item[dsCMatrix] symmetric, real, sparse matrices in the (sorted) compressed sparse column format. Only the upper or the lower triangle is stored. Although there is provision for both forms, the lower triangle form works best with TAUCS. \item[dtCMatrix] triangular, real, sparse matrices in the (sorted) compressed sparse column format. \end{description} \TODO{Can also read and write the Matrix Market and read the Harwell-Boeing representations.} \TODO{Can convert from a dense matrix to a sparse matrix (or use the Matrix function) but going through an intermediate dense matrix may cause problems with the amount of memory required.} \TODO{similar range of operations as for the dense matrix classes.} \section{More detailed examples of ``Matrix'' operations} Have seen \texttt{drop0()} above, %(p.3); only with logical showe a nice double example (where you see ``.'' and ``0''). Show the use of \code{dim<-} for \emph{resizing} a (sparse) matrix. Maybe mention \Rfun{nearPD}. \TODO{Solve a sparse least squares problem and demonstrate memory / speed gain} \TODO{mention \code{lme4} and \Rfun{lmer}, maybe use one example to show the matrix sizes.} \section{Notes about S4 classes and methods implementation} Maybe we could % even here (for R News, not only for JSS) give some glimpses of implementations at least on the \RR{} level ones? \TODO{The class hierarchy: a non-trivial tree where only the leaves are ``actual'' classes.} \TODO{The main advantage of the multi-level hierarchy is that methods can often be defined on a higher (virtual class) level which ensures consistency [and saves from ``cut \& paste'' and forgetting things]} \TODO{Using Group Methods} \section{Session Info} <>= toLatex(sessionInfo()) @ \bibliography{Matrix} \end{document} ������������������������������������������������������������������������������������������������������������������Matrix/vignettes/Introduction.Rnw�������������������������������������������������������������������0000644�0001762�0000144�00000017534�12070262574�016716� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������\documentclass{article} \usepackage{myVignette} \usepackage[authoryear,round]{natbib} \bibliographystyle{plainnat} %%\VignetteIndexEntry{Introduction to the Matrix Package} %%\VignetteDepends{Matrix} \SweaveOpts{engine=R,eps=FALSE,pdf=TRUE,width=5,height=3,strip.white=true,keep.source=TRUE} \title{Introduction to the Matrix package --- as of Feb.~2005\footnote{ There's an unfinished ``2nd Introduction to the Matrix package'' which contains partly newer information, but is not at all self-contained. Eventually that will replace this one.}} \author{Douglas Bates\\R Core Development Group\\\email{bates@r-project.org}} \date{\today} \begin{document} \maketitle \begin{abstract} Linear algebra is at the core of many areas of statistical computing and from its inception the \Slang{} has supported numerical linear algebra via a matrix data type and several functions and operators, such as \code{\%*\%}, \code{qr}, \code{chol}, and \code{solve}. However, these data types and functions do not provide direct access to all of the facilities for efficient manipulation of dense matrices, as provided by the Lapack subroutines, and they do not provide for manipulation of sparse matrices. The \code{Matrix} package provides a set of S4 classes for dense and sparse matrices that extend the basic matrix data type. Methods for a wide variety of functions and operators applied to objects from these classes provide efficient access to BLAS (Basic Linear Algebra Subroutines), Lapack (dense matrix), TAUCS (sparse matrix) and UMFPACK (sparse matrix) routines. One notable characteristic of the package is that whenever a matrix is factored, the factorization is stored as part of the original matrix so that further operations on the matrix can reuse this factorization. \end{abstract} <>= options(width=75) @ \section{Introduction} \label{sec:Intro} Linear algebra is at the core of many statistical computing techniques and, from its inception, the \Slang{} has supported numerical linear algebra via a matrix data type and several functions and operators, such as \code{\%*\%}, \code{qr}, \code{chol}, and \code{solve}. Initially the numerical linear algebra functions in \RR{} called underlying Fortran routines from the Linpack~\citep{Linpack} and Eispack~\cite{Eispack} libraries but over the years most of these functions have been switched to use routines from the Lapack~\cite{Lapack} library. Furthermore, \RR{} can be configured to use accelerated BLAS (Basic Linear Algebra Subroutines), such as those from the Atlas~\cite{Atlas} project or Goto's BLAS~\cite{GotosBLAS}. Lapack provides routines for operating on several special forms of matrices, such as triangular matrices and symmetric matrices. Furthermore,matrix decompositions like the QR decompositions produce multiple output components that should be regarded as parts of a single object. There is some support in R for operations on special forms of matrices (e.g. the \code{backsolve}, \code{forwardsolve} and \code{chol2inv} functions) and for special structures (e.g. a QR structure is implicitly defined as a list by the \code{qr}, \code{qr.qy}, \code{qr.qty}, and related functions) but it is not as fully developed as it could be. Also there is no direct support for sparse matrices in R although \citet{koen:ng:2003} have developed a contributed package for sparse matrices based on SparseKit. The \code{Matrix} package provides S4 classes and methods for dense and sparse matrices. The methods for dense matrices use Lapack and BLAS. The sparse matrix methods use TAUCS~\citep{Taucs}, UMFPACK~\citep{Umfpack}, and Metis~\citep{Metis}. \section{Classes for dense matrices} \label{sec:DenseClasses} The \code{Matrix} package will provide classes for real (stored as double precision) and complex (stored as double precision complex) dense matrices. At present only the real classes have been implemented. These classes are \begin{description} \item[dgeMatrix] Real matrices in general storage mode \item[dsyMatrix] Symmetric real matrices in non-packed storage \item[dspMatrix] Symmetric real matrices in packed storage (one triangle only) \item[dtrMatrix] Triangular real matrices in non-packed storage \item[dtpMatrix] Triangular real matrices in packed storage (triangle only) \item[dpoMatrix] Positive semi-definite symmetric real matrices in non-packed storage \item[dppMatrix] \ \ ditto \ \ in packed storage \end{description} Methods for these classes include coercion between these classes, when appropriate, and coercion to the \code{matrix} class; methods for matrix multiplication (\code{\%*\%}); cross products (\code{crossprod}), matrix norm (\code{norm}); reciprocal condition number (\code{rcond}); LU factorization (\code{lu}) or, for the \code{poMatrix} class, the Cholesky decomposition (\code{chol}); and solutions of linear systems of equations (\code{solve}). Further, group methods have been defined for the \code{Arith} (basic arithmetic, including with scalar numbers) and the \code{Math} (basic mathematical functions) group.. Whenever a factorization or a decomposition is calculated it is preserved as a (list) element in the \code{factors} slot of the original object. In this way a sequence of operations, such as determining the condition number of a matrix then solving a linear system based on the matrix, do not require multiple factorizations of the same matrix nor do they require the user to store the intermediate results. \section{Classes for sparse matrices} \label{sec:SparseClasses} \subsection{Representations of sparse matrices} \label{ssec:SparseReps} Conceptually, the simplest representation of a sparse matrix is as a triplet of an integer vector \code{i} giving the row numbers, an integer vector \code{j} giving the column numbers, and a numeric vector \code{x} giving the non-zero values in the matrix. An S4 class definition might be \begin{Schunk} \begin{Sinput} setClass("dgTMatrix", representation(i = "integer", j = "integer", x = "numeric", Dim = "integer")) \end{Sinput} \end{Schunk} The triplet representation is row-oriented if elements in the same row were adjacent and column-oriented if elements in the same column were adjacent. The compressed sparse row (csr) (or compressed sparse column - csc) representation is similar to row-oriented triplet (column-oriented triplet) except that \code{i} (\code{j}) just stores the index of the first element in the row (column). (There are a couple of other details but that is the gist of it.) These compressed representations remove the redundant row (column) indices and provide faster access to a given location in the matrix because you only need to check one row (column). The preferred representation of sparse matrices in the SparseM package is csr. Matlab uses csc. We hope that Octave will also use this representation. There are certain advantages to csc in systems like R and Matlab where dense matrices are stored in column-major order. For example, Sivan Toledo's TAUCS~\cite{Taucs} library and Tim Davis's UMFPACK~\cite{Umfpack} library are both based on csc and can both use level-3 BLAS in certain sparse matrix computations. The Matrix package provides the following classes for sparse matrices \begin{description} \item[dgTMatrix] general, numeric, sparse matrices in (a possibly redundant) triplet form. This can be a convenient form in which to construct sparse matrices. \item[dgCMatrix] general, numeric, sparse matrices in the (sorted) compressed sparse column format. \item[dsCMatrix] symmetric, real, sparse matrices in the (sorted) compressed sparse column format. Only the upper or the lower triangle is stored. Although there is provision for both forms, the lower triangle form works best with TAUCS. \item[dtCMatrix] triangular, real, sparse matrices in the (sorted) compressed sparse column format. \end{description} \bibliography{Matrix} \end{document} ��������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/vignettes/sparseModels.Rnw�������������������������������������������������������������������0000644�0001762�0000144�00000025534�14444514070�016673� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������\documentclass{article} % \usepackage{fullpage} \usepackage{myVignette} \usepackage[authoryear,round]{natbib} \bibliographystyle{plainnat} \newcommand{\noFootnote}[1]{{\small (\textit{#1})}} \newcommand{\myOp}[1]{{$\left\langle\ensuremath{#1}\right\rangle$}} %%\VignetteIndexEntry{Sparse Model Matrices} %%\VignetteDepends{Matrix,MASS,datasets,grDevices,stats,utils} \title{Sparse Model Matrices} \author{Martin Maechler\\ R Core Development Team \\\email{maechler@R-project.org}} \date{July 2007, 2008 ({\tiny typeset on \tiny\today})} % \begin{document} \maketitle \SweaveOpts{engine=R, keep.source=TRUE} \SweaveOpts{eps=FALSE, pdf=TRUE, width=8, height=5.5, strip.white=true} \setkeys{Gin}{width=\textwidth} % \begin{abstract} % ............................ FIXME % \end{abstract} %% Note: These are explained in '?RweaveLatex' : <>= options(width=75) library(grDevices) # for R_DEFAULT_PACKAGES=NULL library(stats) # ditto library(utils) # ditto @ \section*{Introduction} Model matrices in the very widely used (generalized) linear models of statistics, (typically fit via \Rfun{lm} or \Rfun{glm} in \RR) are often practically sparse --- whenever categorical predictors, \code{factor}s in \RR, are used. %% FIXME: Introduce lm.fit.sparse() or not ? We show for a few classes of such linear models how to construct sparse model matrices using sparse matrix (S4) objects from the \pkg{Matrix} package, and typically \emph{without} using dense matrices in intermediate steps. %% only the latter is really novel, since "SparseM" (and others) %% have used the equivalent of %% as( model.matrix(.....), "sparseMatrix") \section{One factor: \texttt{y $\sim$ f1}} Let's start with an artifical small example: <>= (ff <- factor(strsplit("statistics_is_a_task", "")[[1]], levels=c("_",letters))) factor(ff) # drops the levels that do not occur f1 <- ff[, drop=TRUE] # the same, more transparently @ and now assume a model $$y_i = \mu + \alpha_{j(i)} + E_i,$$ for $i=1,\dots,n =$~\code{length(f1)}$= 20$, and $\alpha_{j(i)}$ with a constraint such as $\sum_j \alpha_j = 0$ (``sum'') or $\alpha_1 = 0$ (``treatment'') and $j(i) =$\code{as.numeric(f1[i])} being the level number of the $i$-th observation. For such a ``design'', the model is only estimable if the levels \code{c} and \code{k} are merged, and <>= levels(f1)[match(c("c","k"), levels(f1))] <- "ck" library(Matrix) Matrix(contrasts(f1)) # "treatment" contrasts by default -- level "_" = baseline Matrix(contrasts(C(f1, sum))) Matrix(contrasts(C(f1, helmert)), sparse=TRUE) # S-plus default; much less sparse @ where \Rfun{contrasts} is (conceptually) just one major ingredient in the well-known \Rfun{model.matrix} function to build the linear model matrix $\mathbf{X}$ of so-called ``dummy variables''. %% Since 2007, the \pkg{Matrix} package has been providing coercion from a \code{factor} object to a \code{sparseMatrix} one to produce the transpose of the model matrix corresponding to a model with that factor as predictor (and no intercept): <>= as(f1, "sparseMatrix") @ which is really almost the transpose of using the above sparsification of \Rfun{contrasts} (and arranging for nice printing), <>= printSpMatrix( t( Matrix(contrasts(f1))[as.character(f1) ,] ), col.names=TRUE) @ and that is the same as the ``sparsification'' of \Rfun{model.matrix}, apart from the column names (here transposed), <>= t( Matrix(model.matrix(~ 0+ f1))) # model with*OUT* intercept @ A more realistic small example is the \code{chickwts} data set, <>= data(chickwts, package = "datasets") str(chickwts)# a standard R data set, 71 x 2 x.feed <- as(chickwts$feed, "sparseMatrix") x.feed[ , (1:72)[c(TRUE,FALSE,FALSE)]] ## every 3rd column: @ % FIXME: Move this to ../../../MatrixModels/inst/doc/ ??? % ## Provisional (hence unexported) sparse lm.fit(): % Matrix:::lm.fit.sparse(x = t(x.feed), y = chickwts[,1]) %- for emacs: $ \section{One factor, one continuous: \texttt{y $\sim$ f1 + x}} To create the model matrix for the case of one factor and one continuous predictor---called ``analysis of covariance'' in the historical literature--- we can adopt the following simple scheme. %% Possible examples: %% - Puromycin %% - ToothGrowth %--- FIXME --- The final model matrix is the concatenation of: 1) create the sparse 0-1 matrix \code{m1} from the f1 main-effect 2) the single row/column 'x' == 'x' main-effect 3) replacing the values 1 in \code{m1@x} (the x-slot of the factor model matrix), by the values of \code{x} (our continuous predictor). \section{Two (or more) factors, main effects only: \texttt{y $\sim$ f1 + f2}} %% FIXME: 'warpbreaks' is smaller and more natural as fixed effect model! Let us consider the \code{warpbreaks} data set of 54 observations, <>= data(warpbreaks, package = "datasets") # a standard R data set str(warpbreaks) # 2 x 3 (x 9) balanced two-way with 9 replicates: xtabs(~ wool + tension, data = warpbreaks) @ %It is \emph{not} statistically sensible to assume that \code{Run} is a %fixed effect, however the example is handy to depict how a model matrix This example depicts how a model matrix would be built for the model \code{breaks ~ wool + tension}. Since this is a main effects model (no interactions), the desired model matrix is simply the concatenation of the model matrices of the main effects. There are two here, but the principle applies to general main effects of factors. The most sparse matrix is reached by \emph{not} using an intercept, (which would give an all-1-column) but rather have one factor fully coded (aka ``swallow'' the intercept), and all others being at \code{"treatment"} contrast, i.e., here, the \emph{transposed} model matrix, \code{tmm}, is <>= tmm <- with(warpbreaks, rbind(as(tension, "sparseMatrix"), as(wool, "sparseMatrix")[-1,,drop=FALSE])) print( image(tmm) ) # print(.) the lattice object @ \\ The matrices are even sparser when the factors have more than just two or three levels, e.g., for the morley data set, <>= data(morley, package = "datasets") # a standard R data set morley$Expt <- factor(morley$Expt) morley$Run <- factor(morley$Run) str(morley) t.mm <- with(morley, rbind(as(Expt, "sparseMatrix"), as(Run, "sparseMatrix")[-1,])) print( image(t.mm) ) # print(.) the lattice object @ %% Also see Doug's E-mail to R-help % From: "Douglas Bates" % Subject: Re: [R] Large number of dummy variables % Date: Mon, 21 Jul 2008 18:07:26 -0500 \section{Interactions of two (or more) factors,.....} %% Of course, this is *the* interesting part %% To form interactions, we would have to ``outer-multiply'' %% the single-factor model-matrices (after "[, -1]") In situations with more than one factor, particularly with interactions, the model matrix is currently not directly available via \pkg{Matrix} functions --- but we still show to build them carefully. The easiest---but not at memory resources efficient---way is to go via the dense \Rfun{model.matrix} result: <>= data(npk, package = "MASS") npk.mf <- model.frame(yield ~ block + N*P*K, data = npk) ## str(npk.mf) # the data frame + "terms" attribute m.npk <- model.matrix(attr(npk.mf, "terms"), data = npk) class(M.npk <- Matrix(m.npk)) dim(M.npk)# 24 x 13 sparse Matrix t(M.npk) # easier to display, column names readably displayed as row.names(t(.)) @ %% printSpMatrix(M.npk, col.names = "abb1") Another example was reported by a user on R-help (July 15, 2008, {\small \url{https://stat.ethz.ch/pipermail/r-help/2008-July/167772.html}}) about an ``aov error with large data set''. \begin{citation} % RAS: in my PDF, I don't see the first character I I'm looking to analyze a large data set: a within-Ss 2*2*1500 design with 20 Ss. However, aov() gives me an error. %, reproducible as follows: \end{citation} And gave the following code example (slightly edited): <>= id <- factor(1:20) a <- factor(1:2) b <- factor(1:2) d <- factor(1:1500) aDat <- expand.grid(id=id, a=a, b=b, d=d) aDat$y <- rnorm(length(aDat[, 1])) # generate some random DV data dim(aDat) # 120'000 x 5 (120'000 = 2*2*1500 * 20 = 6000 * 20) @ %% ^^^^^^^ MM: "fix" and generate much more interesting data and then continued with \begin{Sinput} m.aov <- aov(y ~ a*b*d + Error(id/(a*b*d)), data=aDat) \end{Sinput} \begin{citation}\sffamily which yields the following error:\\ \ttfamily Error in model.matrix.default(mt, mf, contrasts) :\\ allocMatrix: too many elements specified\\ \end{citation} to which he got the explanation by Peter Dalgaard that the formal model matrix involved was much too large in this case, and that PD assumed, \pkg{lme4} would be able to solve the problem. However, currently there would still be a big problem with using \pkg{lme4}, because of the many levels of \emph{fixed} effects: Specifically\footnote{the following is not run in \RR\ on purpose, rather just displayed here}, \begin{Sinput} dim(model.matrix( ~ a*b*d, data = aDat)) # 120'000 x 6000 \end{Sinput} where we note that $120'000 \times 6000 = 720 \textrm{mio}$, which is $720'000'000 * 8 / 2^{20} \approx 5500$ Megabytes. \emph{Unfortunately} \pkg{lme4} does \emph{not} use a sparse $X$-matrix for the fixed effects (yet), it just uses sparse matrices for the $Z$-matrix of random effects and sparse matrix operations for computations related to $Z$. Let us use a smaller factor \code{d} in order to investigate how sparse the $X$ matrix would be: <>= d2 <- factor(1:150) # 10 times smaller tmp2 <- expand.grid(id=id, a=a, b=b, d=d2) dim(tmp2) dim(mm <- model.matrix( ~ a*b*d, data=tmp2)) ## is 100 times smaller than original example class(smm <- Matrix(mm)) # automatically coerced to sparse round(object.size(mm) / object.size(smm), 1) @ shows that even for the small \code{d} here, the memory reduction would be more than an order of magnitude. \\ %% Reasons to fake here: %% 1) print() is needed for lattice -- but looks ugly, %% 2) the resulting pdf file is too large -- use png instead: <>= image(t(smm), aspect = 1/3, lwd=0, col.regions = "red") <>= png("sparseModels-X-sparse-image.png", width=6, height=3, units='in', res=150) print( <> ) dev.off() @ %%--NB: 'keep.source=FALSE' above is workaround-a-bug-in-R-devel-(2.13.x)--- \par\vspace*{-1ex} \centerline{% \includegraphics[width=1.1\textwidth]{sparseModels-X-sparse-image.png}} and working with the sparse instead of the dense model matrix is considerably faster as well, <>= x <- 1:600 system.time(y <- smm %*% x) ## sparse is much faster system.time(y. <- mm %*% x) ## than dense identical(as.matrix(y), y.) ## TRUE @ <>= toLatex(sessionInfo()) @ \end{document} ��������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/R/�������������������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14547724215�011732� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/R/AllClass.R���������������������������������������������������������������������������������0000644�0001762�0000144�00000103553�14500446564�013557� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## README: ## ## Validity methods should assume that methods for superclasses have passed, ## following validObject(). We should _not_ be testing, e.g., length(Dim), ## typeof(Dimnames), etc. repeatedly ... ## ## When checking whether a class is validated correctly, take care to follow ## the 'contains' recursively!! ## initialize() method for Matrix and MatrixFactorization, which both ## allow Dimnames[[i]] to be a vector of type other than "character" ## and furthermore to be a vector of length zero rather than NULL ... .initialize <- function(.Object, ...) { .Object <- callNextMethod() ## Suboptimal if ...names() is NULL but that will "never" ## happen if ...length() is nonzero: if(...length() && any(...names() == "Dimnames")) .Object@Dimnames <- fixupDN(.Object@Dimnames) .Object } ## new() does not work at build time because native symbols such as ## 'Matrix_validate' needed for validity checking are not available ... .new <- function(cl, ...) { def <- getClassDef(cl) structure(def@prototype, class = def@className, ...) } ######################################################################## ## 1. Matrix ######################################################################## ## ====== Virtual Subclasses =========================================== ## ------ The Mother Class 'Matrix' ------------------------------------ ## Virtual class of all Matrix objects setClass("Matrix", contains = "VIRTUAL", slots = c(Dim = "integer", Dimnames = "list"), prototype = list(Dim = integer(2L), Dimnames = list(NULL, NULL)), validity = function(object) .Call(Matrix_validate, object)) setMethod("initialize", "Matrix", .initialize) ## ------ Virtual by structure ----------------------------------------- ## Virtual class of composite matrices, ## i.e., those for which it makes sense to define a factorization setClass("compMatrix", contains = c("Matrix", "VIRTUAL"), slots = c(factors = "list"), validity = function(object) .Call(compMatrix_validate, object)) ## Virtual class of matrices that are not symmetric, triangular, _or diagonal_ setClass("generalMatrix", contains = c("compMatrix", "VIRTUAL")) ## Virtual class of triangular matrices setClass("triangularMatrix", contains = c("Matrix", "VIRTUAL"), slots = c(uplo = "character", diag = "character"), prototype = list(uplo = "U", diag = "N"), validity = function(object) .Call(triangularMatrix_validate, object)) ## Virtual class of symmetric matrices setClass("symmetricMatrix", contains = c("compMatrix", "VIRTUAL"), slots = c(uplo = "character"), prototype = list(uplo = "U"), validity = function(object) .Call(symmetricMatrix_validate, object)) ## ------ Virtual by kind ---------------------------------------------- ## Virtual class of _n_onzero pattern matrices ## NB: only subclass ndenseMatrix requires an 'x' slot setClass("nMatrix", contains = c("Matrix", "VIRTUAL")) ## Virtual class of logical matrices, ## * typically the result of comparisons, e.g., , ## hence NA are allowed and distinct from TRUE, in contrast with nMatrix setClass("lMatrix", contains = c("Matrix", "VIRTUAL"), slots = c(x = "logical"), validity = function(object) .Call(lMatrix_validate, object)) ## Virtual class of integer matrices setClass("iMatrix", contains = c("Matrix", "VIRTUAL"), slots = c(x = "integer"), validity = function(object) .Call(iMatrix_validate, object)) ## Virtual class of double matrices setClass("dMatrix", contains = c("Matrix", "VIRTUAL"), slots = c(x = "numeric"), validity = function(object) .Call(dMatrix_validate, object)) ## Virtual class of complex matrices ## * initial 'z' is derived from the names of LAPACK routines setClass("zMatrix", contains = c("Matrix", "VIRTUAL"), slots = c(x = "complex"), validity = function(object) .Call(zMatrix_validate, object)) ## ------ Virtual Dense ------------------------------------------------ ## Virtual class of dense matrices ## * includes "unpacked" _and_ "packed" matrices ## * included diagonal matrices until 0.999375-11 (2008-07) setClass("denseMatrix", contains = c("Matrix", "VIRTUAL")) ## ...... Virtual Dense ... by storage ................................. ## Virtual class of dense, "unpacked" matrices, s.t. length(.@x) == m*n setClass("unpackedMatrix", contains = c("denseMatrix", "VIRTUAL"), validity = function(object) .Call(unpackedMatrix_validate, object)) ## Virtual class of dense, "packed" matrices, s.t. length(.@x) == n*(n+1)/2 setClass("packedMatrix", contains = c("denseMatrix", "VIRTUAL"), slots = c(uplo = "character"), prototype = list(uplo = "U"), validity = function(object) .Call(packedMatrix_validate, object)) ## ...... Virtual Dense ... by kind .................................... ## Virtual class of dense, _n_onzero pattern matrices setClass("ndenseMatrix", contains = c("nMatrix", "denseMatrix", "VIRTUAL"), slots = c(x = "logical"), validity = function(object) .Call(nMatrix_validate, object)) ## Virtual class of dense, logical matrices setClass("ldenseMatrix", contains = c("lMatrix", "denseMatrix", "VIRTUAL")) if(FALSE) { # --NOT YET-- ## Virtual class of dense, integer matrices setClass("idenseMatrix", contains = c("iMatrix", "denseMatrix", "VIRTUAL")) } # --NOT YET-- ## Virtual class of dense, double matrices setClass("ddenseMatrix", contains = c("dMatrix", "denseMatrix", "VIRTUAL")) if(FALSE) { # --NOT YET-- ## Virtual class of dense, complex matrices setClass("zdenseMatrix", contains = c("zMatrix", "denseMatrix", "VIRTUAL")) } # --NOT YET-- ## ------ Virtual Sparse ----------------------------------------------- ## Virtual class of sparse matrices ## * includes diagonal matrices since 0.999375-11 (2008-07) setClass("sparseMatrix", contains = c("Matrix", "VIRTUAL")) ## ...... Virtual Sparse ... by storage ................................ ## Virtual class of sparse matrices in compressed sparse column (CSC) format setClass("CsparseMatrix", contains = c("sparseMatrix", "VIRTUAL"), slots = c(i = "integer", p = "integer"), prototype = list(p = 0L), # to be valid validity = function(object) .Call(CsparseMatrix_validate, object)) ## Virtual class of sparse matrices in compressed sparse row (CSR) format setClass("RsparseMatrix", contains = c("sparseMatrix", "VIRTUAL"), slots = c(p = "integer", j = "integer"), prototype = list(p = 0L), # to be valid validity = function(object) .Call(RsparseMatrix_validate, object)) ## Virtual class of sparse matrices in triplet format setClass("TsparseMatrix", contains = c("sparseMatrix", "VIRTUAL"), slots = c(i = "integer", j = "integer"), validity = function(object) .Call(TsparseMatrix_validate, object)) ## Virtual class of diagonal matrices setClass("diagonalMatrix", contains = c("sparseMatrix", "VIRTUAL"), slots = c(diag = "character"), prototype = list(diag = "N"), validity = function(object) .Call(diagonalMatrix_validate, object)) if(FALSE) { # --NOT YET-- ## These methods would allow initialization of zero matrices _without_ 'p', ## as in the call new("dgCMatrix", Dim = c(6L, 6L)). However, they would ## also incur a small performance penalty on all other new("..[CR]Matrix") ## calls. setMethod("initialize", "CsparseMatrix", function(.Object, ...) { ## Suboptimal if ...names() is NULL or if 'Dim' is missing ## but that will "never" happen if ...length() is nonzero: if(...length() && all((nms <- ...names()) != "p") && length(w <- which(nms == "Dim")) && !is.character(validDim(d <- ...elt(w[1L])))) callNextMethod(.Object, ..., p = integer(d[2L] + 1)) else callNextMethod() }) setMethod("initialize", "RsparseMatrix", function(.Object, ...) { ## Suboptimal if ...names() is NULL or if 'Dim' is missing ## but that will "never" happen if ...length() is nonzero: if(...length() && all((nms <- ...names()) != "p") && length(w <- which(nms == "Dim")) && !is.character(validDim(d <- ...elt(w[1L])))) callNextMethod(.Object, ..., p = integer(d[1L] + 1)) else callNextMethod() }) } # --NOT YET-- ## ...... Virtual Sparse ... by kind ................................... ## Virtual class of sparse, _n_onzero pattern matrices ## * these are the "pattern" matrices from "symbolic analysis" of sparse OPs setClass("nsparseMatrix", contains = c("nMatrix", "sparseMatrix", "VIRTUAL")) ## Virtual class of sparse, logical matrices setClass("lsparseMatrix", contains = c("lMatrix", "sparseMatrix", "VIRTUAL")) if(FALSE) { # --NOT YET-- ## Virtual class of sparse, integer matrices setClass("isparseMatrix", contains = c("iMatrix", "sparseMatrix", "VIRTUAL")) } # --NOT YET-- ## Virtual class of sparse, double matrices setClass("dsparseMatrix", contains = c("dMatrix", "sparseMatrix", "VIRTUAL")) if(FALSE) { # --NOT YET-- ## Virtual class of sparse, complex matrices setClass("zsparseMatrix", contains = c("zMatrix", "sparseMatrix", "VIRTUAL")) } # --NOT YET-- ## ====== Non-Virtual Subclasses ======================================= ## ------ Non-Virtual Dense -------------------------------------------- ## ...... Dense, _n_onzero pattern ..................................... ## Unpacked, general setClass("ngeMatrix", contains = c("unpackedMatrix", "ndenseMatrix", "generalMatrix")) ## Unpacked, triangular setClass("ntrMatrix", contains = c("unpackedMatrix", "ndenseMatrix", "triangularMatrix")) ## Unpacked, symmetric setClass("nsyMatrix", contains = c("unpackedMatrix", "ndenseMatrix", "symmetricMatrix")) ## Packed, triangular setClass("ntpMatrix", contains = c("packedMatrix", "ndenseMatrix", "triangularMatrix")) ## Packed, symmetric setClass("nspMatrix", contains = c("packedMatrix", "ndenseMatrix", "symmetricMatrix")) ## ...... Dense, logical ............................................... ## Unpacked, general setClass("lgeMatrix", contains = c("unpackedMatrix", "ldenseMatrix", "generalMatrix")) ## Unpacked, triangular setClass("ltrMatrix", contains = c("unpackedMatrix", "ldenseMatrix", "triangularMatrix")) ## Unpacked, symmetric setClass("lsyMatrix", contains = c("unpackedMatrix", "ldenseMatrix", "symmetricMatrix")) ## Packed, triangular setClass("ltpMatrix", contains = c("packedMatrix", "ldenseMatrix", "triangularMatrix")) ## Packed, symmetric setClass("lspMatrix", contains = c("packedMatrix", "ldenseMatrix", "symmetricMatrix")) ## ...... Dense, double ................................................ ## Unpacked, general setClass("dgeMatrix", contains = c("unpackedMatrix", "ddenseMatrix", "generalMatrix")) ## Unpacked, triangular setClass("dtrMatrix", contains = c("unpackedMatrix", "ddenseMatrix", "triangularMatrix")) ## Unpacked, symmetric setClass("dsyMatrix", contains = c("unpackedMatrix", "ddenseMatrix", "symmetricMatrix")) ## Unpacked, symmetric, positive semidefinite setClass("dpoMatrix", contains = "dsyMatrix", validity = function(object) .Call(dpoMatrix_validate, object)) ## Unpacked, symmetric, positive semidefinite, correlation setClass("corMatrix", contains = "dpoMatrix", slots = c(sd = "numeric"), validity = function(object) .Call(corMatrix_validate, object)) ## Packed, triangular setClass("dtpMatrix", contains = c("packedMatrix", "ddenseMatrix", "triangularMatrix")) ## Packed, symmetric setClass("dspMatrix", contains = c("packedMatrix", "ddenseMatrix", "symmetricMatrix")) ## Packed, symmetric, positive semidefinite setClass("dppMatrix", contains = "dspMatrix", validity = function(object) .Call(dppMatrix_validate, object)) ## Packed, symmetric, positive semidefinite, correlation setClass("pcorMatrix", contains = "dppMatrix", slots = c(sd = "numeric"), validity = function(object) .Call(pcorMatrix_validate, object)) ## ------ Non-Virtual Sparse ------------------------------------------- ## ...... Sparse, nonzero pattern ...................................... ## NB: Unlike [^n]sparseMatrix (below), there is no 'x' slot to validate here. ## CSC, general setClass("ngCMatrix", contains = c("CsparseMatrix", "nsparseMatrix", "generalMatrix")) ## CSC, triangular setClass("ntCMatrix", contains = c("CsparseMatrix", "nsparseMatrix", "triangularMatrix"), validity = function(object) .Call(tCMatrix_validate, object)) ## CSC, symmetric setClass("nsCMatrix", contains = c("CsparseMatrix", "nsparseMatrix", "symmetricMatrix"), validity = function(object) .Call(sCMatrix_validate, object)) ## CSR, general setClass("ngRMatrix", contains = c("RsparseMatrix", "nsparseMatrix", "generalMatrix")) ## CSR, triangular setClass("ntRMatrix", contains = c("RsparseMatrix", "nsparseMatrix", "triangularMatrix"), validity = function(object) .Call(tRMatrix_validate, object)) ## CSR, symmetric setClass("nsRMatrix", contains = c("RsparseMatrix", "nsparseMatrix", "symmetricMatrix"), validity = function(object) .Call(sRMatrix_validate, object)) ## Triplet general setClass("ngTMatrix", contains = c("TsparseMatrix", "nsparseMatrix", "generalMatrix")) ## Triplet, triangular setClass("ntTMatrix", contains = c("TsparseMatrix", "nsparseMatrix", "triangularMatrix"), validity = function(object) .Call(tTMatrix_validate, object)) ## Triplet, symmetric setClass("nsTMatrix", contains = c("TsparseMatrix", "nsparseMatrix", "symmetricMatrix"), validity = function(object) .Call(sTMatrix_validate, object)) ## Diagonal setClass("ndiMatrix", contains = c("diagonalMatrix", "nMatrix"), slots = c(x = "logical"), validity = function(object) .Call(nMatrix_validate, object)) ## ...... Sparse, logical .............................................. ## CSC, general setClass("lgCMatrix", contains = c("CsparseMatrix", "lsparseMatrix", "generalMatrix"), validity = function(object) .Call(xgCMatrix_validate, object)) ## CSC, triangular setClass("ltCMatrix", contains = c("CsparseMatrix", "lsparseMatrix", "triangularMatrix"), validity = function(object) .Call(xtCMatrix_validate, object)) ## CSC, symmetric setClass("lsCMatrix", contains = c("CsparseMatrix", "lsparseMatrix", "symmetricMatrix"), validity = function(object) .Call(xsCMatrix_validate, object)) ## CSR, general setClass("lgRMatrix", contains = c("RsparseMatrix", "lsparseMatrix", "generalMatrix"), validity = function(object) .Call(xgRMatrix_validate, object)) ## CSR, triangular setClass("ltRMatrix", contains = c("RsparseMatrix", "lsparseMatrix", "triangularMatrix"), validity = function(object) .Call(xtRMatrix_validate, object)) ## CSR, symmetric setClass("lsRMatrix", contains = c("RsparseMatrix", "lsparseMatrix", "symmetricMatrix"), validity = function(object) .Call(xsRMatrix_validate, object)) ## Triplet, general setClass("lgTMatrix", contains = c("TsparseMatrix", "lsparseMatrix", "generalMatrix"), validity = function(object) .Call(xgTMatrix_validate, object)) ## Triplet, triangular setClass("ltTMatrix", contains = c("TsparseMatrix", "lsparseMatrix", "triangularMatrix"), validity = function(object) .Call(xtTMatrix_validate, object)) ## Triplet, symmetric setClass("lsTMatrix", contains = c("TsparseMatrix", "lsparseMatrix", "symmetricMatrix"), validity = function(object) .Call(xsTMatrix_validate, object)) ## Diagonal setClass("ldiMatrix", contains = c("diagonalMatrix", "lMatrix")) ## ...... Sparse, double ............................................... ## CSC, general setClass("dgCMatrix", contains = c("CsparseMatrix", "dsparseMatrix", "generalMatrix"), validity = function(object) .Call(xgCMatrix_validate, object)) ## CSC, triangular setClass("dtCMatrix", contains = c("CsparseMatrix", "dsparseMatrix", "triangularMatrix"), validity = function(object) .Call(xtCMatrix_validate, object)) ## CSC, symmetric setClass("dsCMatrix", contains = c("CsparseMatrix", "dsparseMatrix", "symmetricMatrix"), validity = function(object) .Call(xsCMatrix_validate, object)) ## CSR, general setClass("dgRMatrix", contains = c("RsparseMatrix", "dsparseMatrix", "generalMatrix"), validity = function(object) .Call(xgRMatrix_validate, object)) ## CSR, triangular setClass("dtRMatrix", contains = c("RsparseMatrix", "dsparseMatrix", "triangularMatrix"), validity = function(object) .Call(xtRMatrix_validate, object)) ## CSR, symmetric setClass("dsRMatrix", contains = c("RsparseMatrix", "dsparseMatrix", "symmetricMatrix"), validity = function(object) .Call(xsRMatrix_validate, object)) ## Triplet, general setClass("dgTMatrix", contains = c("TsparseMatrix", "dsparseMatrix", "generalMatrix"), validity = function(object) .Call(xgTMatrix_validate, object)) ## Triplet, triangular setClass("dtTMatrix", contains = c("TsparseMatrix", "dsparseMatrix", "triangularMatrix"), validity = function(object) .Call(xtTMatrix_validate, object)) ## Triplet, symmetric setClass("dsTMatrix", contains = c("TsparseMatrix", "dsparseMatrix", "symmetricMatrix"), validity = function(object) .Call(xsTMatrix_validate, object)) ## Diagonal setClass("ddiMatrix", contains = c("diagonalMatrix", "dMatrix")) if(FALSE) { # TODO ## CSC, symmetic, positive semidefinite setClass("dpCMatrix", contains = "dsCMatrix", validity = function(object) TODO("test positive semidefiniteness")) ## CSR, symmetic, positive semidefinite setClass("dpRMatrix", contains = "dsRMatrix", validity = function(object) TODO("test positive semidefiniteness")) ## Triplet, symmetic, positive semidefinite setClass("dpTMatrix", contains = "dsTMatrix", validity = function(object) TODO("test positive semidefiniteness")) } # TODO ## ...... Sparse, index ................................................ ## Row or column index setClass("indMatrix", contains = c("sparseMatrix", "generalMatrix"), slots = c(perm = "integer", margin = "integer"), prototype = list(margin = 1L), # to be valid validity = function(object) .Call(indMatrix_validate, object)) ## Row or column permutation setClass("pMatrix", contains = c("indMatrix"), validity = function(object) .Call(pMatrix_validate, object)) ######################################################################## ## 2. MatrixFactorization ######################################################################## ## ------ The Mother Class "MatrixFactorization" ----------------------- setClass("MatrixFactorization", contains = "VIRTUAL", slots = c(Dim = "integer", Dimnames = "list"), prototype = list(Dim = integer(2L), Dimnames = list(NULL, NULL)), validity = function(object).Call(MatrixFactorization_validate, object)) setMethod("initialize", "MatrixFactorization", .initialize) ## ------ LU ----------------------------------------------------------- setClass("LU", contains = c("MatrixFactorization", "VIRTUAL")) ## Inherit most aspects of dgeMatrix without extending it setClass("denseLU", contains = "LU", slots = c(x = "numeric", perm = "integer"), validity = function(object) { object. <- new("dgeMatrix") object.@Dim <- object@Dim object.@Dimnames <- object@Dimnames object.@x <- object@x if(is.character(valid <- validObject(object., test = TRUE))) valid else .Call(denseLU_validate, object) }) setClass("sparseLU", contains = "LU", slots = c(L = "dtCMatrix", U = "dtCMatrix", p = "integer", q = "integer"), prototype = list(L = .new("dtCMatrix", uplo = "L")), validity = function(object) .Call(sparseLU_validate, object)) ## ------ QR ----------------------------------------------------------- setClass("QR", contains = c("MatrixFactorization", "VIRTUAL")) if(FALSE) { ## MJ: It would nice to have symmetry with LU, but then we would need ## to define methods already available for S3 class 'qr'. Still ... setClass("denseQR", contains = "QR", ## based on S3 class 'qr': slots = c(qr = "numeric", qraux = "numeric", rank = "integer", pivot = "integer", useLAPACK = "logical"), validity = function(object) .Call(denseQR_validate, object)) } setClass("sparseQR", contains = "QR", slots = c(beta = "numeric", V = "dgCMatrix", R = "dgCMatrix", p = "integer", q = "integer"), validity = function(object) .Call(sparseQR_validate, object)) ## ------ Bunch-Kaufman ------------------------------------------------ setClass("BunchKaufmanFactorization", contains = c("MatrixFactorization", "VIRTUAL")) ## Inherit most aspects of dt[rp]Matrix without extending them setClass("BunchKaufman", contains = "BunchKaufmanFactorization", slots = c(uplo = "character", x = "numeric", perm = "integer"), prototype = list(uplo = "U"), validity = function(object) { object. <- new("dtrMatrix") object.@Dim <- object@Dim object.@Dimnames <- object@Dimnames object.@uplo <- object@uplo object.@x <- object@x if(is.character(valid <- validObject(object., test = TRUE))) valid else .Call(BunchKaufman_validate, object) }) setClass("pBunchKaufman", contains = "BunchKaufmanFactorization", slots = c(uplo = "character", x = "numeric", perm = "integer"), prototype = list(uplo = "U"), validity = function(object) { object. <- new("dtpMatrix") object.@Dim <- object@Dim object.@Dimnames <- object@Dimnames object.@uplo <- object@uplo object.@x <- object@x if(is.character(valid <- validObject(object., test = TRUE))) valid else .Call(pBunchKaufman_validate, object) }) ## ------ Cholesky ----------------------------------------------------- setClass("CholeskyFactorization", contains = c("MatrixFactorization", "VIRTUAL")) ## ...... Dense ........................................................ ## Inherit most aspects of dt[rp]Matrix without extending them setClass("Cholesky", contains = "CholeskyFactorization", slots = c(uplo = "character", x = "numeric", perm = "integer"), prototype = list(uplo = "U"), validity = function(object) { object. <- new("dtrMatrix") object.@Dim <- object@Dim object.@Dimnames <- object@Dimnames object.@uplo <- object@uplo object.@x <- object@x if(is.character(valid <- validObject(object., test = TRUE))) valid else .Call(Cholesky_validate, object) }) setClass("pCholesky", contains = "CholeskyFactorization", slots = c(uplo = "character", x = "numeric", perm = "integer"), prototype = list(uplo = "U"), validity = function(object) { object. <- new("dtpMatrix") object.@Dim <- object@Dim object.@Dimnames <- object@Dimnames object.@uplo <- object@uplo object.@x <- object@x if(is.character(valid <- validObject(object., test = TRUE))) valid else .Call(pCholesky_validate, object) }) ## ...... Sparse ....................................................... ## FIXME? simplicial symbolic factorization is specified entirely by ## 'colcount' and 'perm' ... ## should 'p', 'i', 'nz', 'nxt', 'prv' slots all be emtpy ?? ## see comments in ../src/CHOLMOD/Core/cholmod_change_factor.c ## S4 representation of C struct 'cholmod_factor', ## from header ../src/CHOLMOD/Include/cholmod_core.h setClass("CHMfactor", contains = c("CholeskyFactorization", "VIRTUAL"), slots = c(type = "integer", colcount = "integer", perm = "integer"), validity = function(object) .Call(CHMfactor_validate, object)) ## Simplicial factorization setClass("CHMsimpl", contains = c("CHMfactor", "VIRTUAL"), slots = c(p = "integer", i = "integer", nz = "integer", nxt = "integer", prv = "integer"), prototype = list(type = c(0L, 1L, 0L, 1L, 0L, 0L), p = 0L, nxt = c(-1L, 0L), prv = c(1L, -1L)), validity = function(object) .Call(CHMsimpl_validate, object)) setClass("nCHMsimpl", contains = "CHMsimpl") # symbolic factorization setClass("dCHMsimpl", contains = "CHMsimpl", slots = c(x = "numeric"), validity = function(object) .Call(dCHMsimpl_validate, object)) ## Supernodal factorization setClass("CHMsuper", contains = c("CHMfactor", "VIRTUAL"), slots = c(super = "integer", pi = "integer", px = "integer", s = "integer"), prototype = list(type = c(0L, 1L, 1L, 1L, 0L, 0L), super = 0L, pi = 0L, px = 0L), validity = function(object) .Call(CHMsuper_validate, object)) setClass("nCHMsuper", contains = "CHMsuper") # symbolic factorization setClass("dCHMsuper", contains = "CHMsuper", slots = c(x = "numeric"), validity = function(object) .Call(dCHMsuper_validate, object)) ## ------ Schur -------------------------------------------------------- ## For eigenvalues: setClassUnion("number", members = c("numeric", "complex")) setClass("SchurFactorization", contains = c("MatrixFactorization", "VIRTUAL")) setClass("Schur", contains = "SchurFactorization", slots = c(Q = "Matrix", T = "Matrix", EValues = "number"), prototype = list(Q = .new("dgeMatrix"), T = .new("dgeMatrix")), validity = function(object) .Call(Schur_validate, object)) ######################################################################## ## 3. sparseVector ######################################################################## ## ------ The Mother Class 'sparseVector' ------------------------------ setClass("sparseVector", contains = "VIRTUAL", slots = c(length = "numeric", i = "numeric"), # 1-based index! prototype = list(length = 0), validity = function(object) .Call(sparseVector_validate, object)) ## Allow users to do new("[nlidz]sparseVector", i=, x=) with unsorted 'i' setMethod("initialize", "sparseVector", function(.Object, i, x, ...) { if(has.x <- !missing(x)) x <- x # MJ: why is this necessary? if(!missing(i)) { i.uns <- is.unsorted(i, strictly = TRUE) i <- if(is.na(i.uns) || !i.uns) i else { ## we know that there are no NA, and the order of ## ties does not matter (since ties are an error), ## hence it is safe to use "quick" here m <- if(is.integer(length(i))) "radix" else "quick" if(.hasSlot(.Object, "x") && has.x) { s <- sort.int(i, method = m, index.return = TRUE) x <- x[s$ix] s$x } else sort.int(i, method = m) } } callNextMethod() }) ## ------ Non-Virtual Subclasses --------------------------------------- setClass("nsparseVector", contains = "sparseVector") setClass("lsparseVector", contains = "sparseVector", slots = c(x = "logical"), validity = function(object) .Call(lsparseVector_validate, object)) setClass("isparseVector", contains = "sparseVector", slots = c(x = "integer"), validity = function(object) .Call(isparseVector_validate, object)) setClass("dsparseVector", contains = "sparseVector", slots = c(x = "numeric"), validity = function(object) .Call(dsparseVector_validate, object)) setClass("zsparseVector", contains = "sparseVector", slots = c(x = "complex"), validity = function(object) .Call(zsparseVector_validate, object)) ######################################################################## ## 4. Index and more "miscellaneous" classes, but _not_ class unions ######################################################################## ## Idea: represent x = c(seq(from1, to1, by1), seq(from2, to2, by2), ...) ## as list(first = x[1L], rle = rle(diff(x))) setOldClass("rle") setClass("rleDiff", ## MJ: simpler would be slots = c(first=, lengths=, values=) ... slots = c(first = "numeric", rle = "rle"), prototype = list(first = integer(0L), rle = rle(integer(0L))), validity = function(object) { if(length(object@first) != 1L) "'first' slot does not have length 1" else if(!is.list(rle <- object@rle)) "'rle' slot is not a list" else if(length(rle) != 2L) "'rle' slot does not have length 2" else if(is.null(nms <- names(rle)) || anyNA(match(nms, c("lengths", "values")))) "'rle' slot does not have names \"lengths\", \"values\"" else if(!is.numeric(lens <- rle$lengths)) "'lengths' is not numeric" else if(!is.numeric(vals <- rle$values)) "'values' is not numeric" else if(length(lens) != length(vals)) "'lengths' and 'values' do not have equal length" else if(length(lens) == 0L) TRUE else if(anyNA(lens)) "'lengths' contains NA" else if(is.double(lens)) { if(!(all(is.finite(r <- range(lens))) && all(lens == trunc(lens)))) "'lengths' is not integer-valued" else if(r[1L] < 1) "'lengths' is not positive" else TRUE } else { if(min(lens) < 1L) "'lengths' is not positive" else TRUE } }) ## Idea: represent x = c(seq(from1, to1, by1), seq(from2, to2, by2), ...) ## as rbind(c(from1, from2, ...), c(to1, to2, ...), c(by1, by2, ...)) ## MM: (2010-03-04) more efficient than "rleDiff" [TODO: write rleDiff<->seqMat] ## MJ: (2022-09-06) data.frame(from, to, by) could be _handled_ more efficiently setClass("seqMat", contains = "matrix", prototype = matrix(integer(0L), nrow = 3L, ncol = 0L), validity = function(object) { if(!is.numeric(object)) "matrix is not numeric" else if(nrow(object) != 3L) "matrix does not have 3 rows" else if(anyNA(object)) "matrix contains NA" else if(is.double(object) && !(all(is.finite(range(object))) && all(object == trunc(object)))) "matrix is not integer-valued" else { from <- object[1L, ] to <- object[2L, ] by <- object[3L, ] if(any((from < to & by <= 0) | (from > to & by >= 0))) "degenerate sequence(s): sign(to - from) != sign(by)" else TRUE } }) ## Idea: _ab_stract index ## MJ: (2022-09-06) why not just ## setClassUnion("abIndex", members = c("numeric", "rleDiff", "seqMat")) ? setClass("abIndex", slots = c(kind = "character", x = "numeric", rleD = "rleDiff"), prototype = list(kind = "int32", x = integer(0L)), validity = function(object) { ## MJ: should 'rleD' be "empty" if kind != "rleDiff" ? if(length(kind <- object@kind) != 1L) "'kind' slot does not have length 1" else switch(kind, "int32" = if(is.integer(object@x)) TRUE else "kind=\"int32\" but 'x' slot is not of type \"integer\"", "double" = if(is.double(object@x)) TRUE else "kind=\"double\" but 'x' slot is not of type \"double\"", "rleDiff" = if(length(object@x) == 0L) TRUE else "kind=\"rleDiff\" but 'x' slot is nonempty", ## otherwise: "'kind' is not \"int32\", \"double\", or \"rleDiff\"") }) ######################################################################## ## 5. Class unions ######################################################################## ## NB: these exist mainly to reduce duplication of methods ## NB: numeric = { double, integer } ## Atomic vectors: ## * note that is(, "atomicVector") is FALSE ## even though is.atomic() is TRUE setClassUnion("atomicVector", members = c("logical", "numeric", "complex", "raw", "character")) ## Numeric-like vectors: ## * for methods handling logical and integer as double setClassUnion("numLike", members = c("logical", "numeric")) ## Index vectors: ## * for 'i' in x[i], x[i, ], x[, i], etc. ## * TODO: include rleDiff setClassUnion("index", members = c("logical", "numeric", "character")) ## Subassignment values: ## * for 'value' in x[i, j] <- value setClassUnion("replValue", members = c("logical", "numeric", "complex", "raw")) setClassUnion("replValueSp", members = c("replValue", "sparseVector", "matrix", "Matrix")) rm(.new, .initialize) �����������������������������������������������������������������������������������������������������������������������������������������������������Matrix/R/show.R�������������������������������������������������������������������������������������0000644�0001762�0000144�00000055712�14467103523�013041� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������prMatrix <- function(x, digits = getOption("digits"), maxp = getOption("max.print")) { d <- dim(x) cl <- class(x) ## cld <- getClassDef(cl) tri <- extends(cl, "triangularMatrix") xtra <- if(tri && x@diag == "U") " (unitriangular)" else "" cat(sprintf('%d x %d Matrix of class "%s"%s\n', d[1], d[2], cl, xtra)) if(prod(d) <= maxp) { if(tri) prTriang(x, digits = digits, maxp = maxp) else print(as(x, "matrix"), digits = digits, max = maxp) } else { ## d[1] > maxp / d[2] >= nr : m <- as(x, "matrix") nr <- maxp %/% d[2] n2 <- ceiling(nr / 2) print(head(m, max(1, n2))) cat("\n ..........\n\n") print(tail(m, max(1, nr - n2))) cat("\n ..........\n\n") } ## DEBUG: cat("str(.):\n") ; str(x) invisible(x)# as print() S3 methods do } prTriang <- function(x, digits = getOption("digits"), maxp = getOption("max.print"), justify = "none", right = TRUE) { ## modeled along stats:::print.dist upper <- x@uplo == "U" m <- as(x, "matrix") cf <- format(m, digits = digits, justify = justify) cf[if(upper) row(cf) > col(cf) else row(cf) < col(cf)] <- "." print(cf, quote = FALSE, right = right, max = maxp) invisible(x) } prDiag <- function(x, digits = getOption("digits"), justify = "none", right = TRUE) { cf <- array(".", dim = x@Dim, dimnames = x@Dimnames) cf[row(cf) == col(cf)] <- vapply(diag(x), format, "", digits = digits, justify = justify) print(cf, quote = FALSE, right = right) invisible(x) } emptyColnames <- function(x, msg.if.not.empty = FALSE) { ## Useful for compact printing of (parts) of sparse matrices ## possibly dimnames(x) "==" NULL : if((nd <- length(d <- dim(x))) < 2L) return(x) nc <- d[2L] if(is.null(dn <- dimnames(x))) dn <- vector("list", nd) else if(msg.if.not.empty && is.character(cn <- dn[[2L]]) && any(nzchar(cn))) message(gettextf(" [[ suppressing %d column name%s %s ... ]]", nc, if(nc == 1L) "" else "s", paste0(sQuote(if(nc <= 3L) cn else cn[1:3]), collapse = ", ")), domain = NA) dn[[2L]] <- character(nc) dimnames(x) <- dn x } .formatSparseSimple <- function(m, asLogical = FALSE, digits = NULL, col.names, note.dropping.colnames = TRUE, dn = dimnames(m)) { stopifnot(is.logical(asLogical)) if(asLogical) cx <- array("N", dim(m), dimnames=dn) else { ## numeric (or --not yet implemented-- complex): cx <- apply(m, 2, format, digits=digits) if(is.null(dim(cx))) {# e.g. in 1 x 1 case dim(cx) <- dim(m) dimnames(cx) <- dn } } if (missing(col.names)) col.names <- { if(!is.null(cc <- getOption("sparse.colnames"))) cc else if(is.null(dn[[2]])) FALSE else { # has column names == dn[[2]] ncol(m) < 10 } } if(identical(col.names, FALSE)) cx <- emptyColnames(cx, msg.if.not.empty = note.dropping.colnames) else if(is.character(col.names)) { stopifnot(length(col.names) == 1) cn <- col.names switch(substr(cn, 1,3), "abb" = { iarg <- as.integer(sub("^[^0-9]*", '', cn)) colnames(cx) <- abbreviate(colnames(cx), minlength = iarg) }, "sub" = { iarg <- as.integer(sub("^[^0-9]*", '', cn)) colnames(cx) <- substr(colnames(cx), 1, iarg) }, stop(gettextf("invalid 'col.names' string: %s", cn), domain=NA)) } ## else: nothing to do for col.names == TRUE cx } ## NB: Want this to work also for logical or numeric traditional matrix 'x': formatSparseM <- function(x, zero.print = ".", align = c("fancy", "right"), m = as(x, "matrix"), asLogical = NULL, uniDiag = NULL, digits = NULL, cx, iN0, dn = dimnames(m)) { cld <- getClassDef(class(x)) if(is.null(asLogical)) { asLogical <- extends1of(cld, c("nsparseMatrix", "indMatrix", "lsparseMatrix")) || # simple TRUE/FALSE (extends(cld, "matrix") && is.logical(x)) # has NA and (non-)structural FALSE } if(missing(cx)) cx <- .formatSparseSimple(m, asLogical=asLogical, digits=digits, dn=dn) if(is.null(d <- dim(cx))) {# e.g. in 1 x 1 case d <- dim(cx) <- dim(m) dimnames(cx) <- dn } if(missing(iN0)) iN0 <- 1L + .Call(m_encodeInd, non0ind(x, cld), di = d, FALSE, FALSE) ## ne <- length(iN0) if(asLogical) { cx[m] <- "|" if(!extends(cld, "sparseMatrix")) x <- as(x,"sparseMatrix") if(anyFalse(x@x)) { ## any (x@x == FALSE) ## Careful for *non-sorted* Tsparse, e.g. from U-diag if(extends(cld, "TsparseMatrix")) { ## have no "fast uniqTsparse(): x <- as(x, "CsparseMatrix") cld <- getClassDef(class(x)) } F. <- is0(x@x) # the 'FALSE' ones ### FIXME: have iN0 already above -- *really* need the following ??? --FIXME-- ij <- non0.i(x, cld, uniqT=FALSE) if(extends(cld, "symmetricMatrix")) { ## also get "other" triangle notdiag <- ij[,1] != ij[,2] # but not the diagonals again ij <- rbind(ij, ij[notdiag, 2:1], deparse.level=0) F. <- c(F., F.[notdiag]) } iN0 <- 1L + .Call(m_encodeInd, ij, di = d, FALSE, FALSE) cx[iN0[F.]] <- ":" # non-structural FALSE (or "o", "," , "-" or "f")? } } else if(match.arg(align) == "fancy" && !is.integer(m)) { fi <- apply(m, 2, format.info) ## fi[3,] == 0 <==> not expo. ## now 'format' the zero.print by padding it with ' ' on the right: ## case 1: non-exponent: fi[2,] + as.logical(fi[2,] > 0) ## the column numbers of all 'zero' entries -- (*large*) cols <- 1L + (0:(prod(d)-1L))[-iN0] %/% d[1] pad <- ifelse(fi[3,] == 0, fi[2,] + as.logical(fi[2,] > 0), ## exponential: fi[2,] + fi[3,] + 4) ## now be efficient ; sprintf() is relatively slow ## and pad is much smaller than 'cols'; instead of "simply" ## zero.print <- sprintf("%-*s", pad[cols] + 1, zero.print) if(any(doP <- pad > 0)) { # ## only pad those that need padding - *before* expanding z.p.pad <- rep.int(zero.print, length(pad)) z.p.pad[doP] <- sprintf("%-*s", pad[doP] + 1, zero.print) zero.print <- z.p.pad[cols] } else zero.print <- rep.int(zero.print, length(cols)) } ## else "right" : nothing to do if(!asLogical && isTRUE(uniDiag)) { ## use "I" in diagonal -- pad correctly if(any(diag(x) != 1)) stop("uniDiag=TRUE, but not all diagonal entries are 1") D <- diag(cx) # use if(any((ir <- regexpr("1", D)) < 0)) { warning("uniDiag=TRUE, not all entries in diagonal coded as 1") } else { ir <- as.vector(ir) nD <- nchar(D, "bytes") ## replace "1..." by "I " (I plus blanks) substr(D, ir, nD) <- sprintf("I%*s", nD - ir, "") diag(cx) <- D } } cx[-iN0] <- zero.print cx } ## The `format()` method for sparse Matrices; ## also used inside sparseMatrix print()ing, ## exported as it might be useful directly. formatSpMatrix <- function(x, digits = NULL, maxp = 1e+09, # ~ 0.5 * .Machine$integer.max cld = getClassDef(class(x)), zero.print = ".", col.names, note.dropping.colnames = TRUE, uniDiag = TRUE, align = c("fancy", "right")) { stopifnot(extends(cld, "sparseMatrix")) validObject(x) # have seen seg.faults for invalid objects d <- dim(x) unitD <- extends(cld, "triangularMatrix") && x@diag == "U" ## Will note it is *unit*-diagonal by using "I" instead of "1" if(unitD) x <- .Call(R_sparse_diag_U2N, x) if(maxp < 100) maxp <- 100L # "stop gap" if(prod(d) > maxp) { # "Large" => will be "cut" ## only coerce to dense that part which won't be cut : nr <- maxp %/% d[2] m <- as(x[1:max(1, nr), ,drop=FALSE], "matrix") } else { m <- as(x, "matrix") } dn <- dimnames(m) ## will be === dimnames(cx) binary <- extends(cld,"nsparseMatrix") || extends(cld, "indMatrix") # -> simple T / F logi <- binary || extends(cld,"lsparseMatrix") # has NA and (non-)structural FALSE cx <- .formatSparseSimple(m, asLogical = logi, digits=digits, col.names=col.names, note.dropping.colnames=note.dropping.colnames, dn=dn) if(is.logical(zero.print)) zero.print <- if(zero.print) "0" else " " if(binary) { cx[!m] <- zero.print cx[m] <- "|" } else { # non-binary ==> has 'x' slot ## show only "structural" zeros as 'zero.print', not all of them.. ## -> cannot use 'm' alone d <- dim(cx) ne <- length(iN0 <- 1L + .Call(m_encodeInd, non0ind(x, cld), di = d, FALSE, FALSE)) if(0 < ne && (logi || ne < prod(d))) { cx <- formatSparseM(x, zero.print, align, m=m, asLogical = logi, uniDiag = unitD & uniDiag, digits=digits, cx=cx, iN0=iN0, dn=dn) } else if (ne == 0)# all zeroes cx[] <- zero.print } cx } ## FIXME(?) -- ``merge this'' (at least ``synchronize'') with ## - - - prMatrix() from ./Auxiliaries.R ## FIXME: prTriang() in ./Auxiliaries.R should also get align = "fancy" printSpMatrix <- function(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")) { stopifnot(extends(cld, "sparseMatrix")) cx <- formatSpMatrix(x, digits=digits, maxp=maxp, cld=cld, zero.print=zero.print, col.names=col.names, note.dropping.colnames=note.dropping.colnames, uniDiag=uniDiag, align=align) if(col.trailer != '') cx <- cbind(cx, col.trailer, deparse.level = 0) ## right = TRUE : cheap attempt to get better "." alignment print(cx, quote = FALSE, right = TRUE, max = maxp) invisible(x) } ##' The "real" show() / print() method, calling the above printSpMatrix(): printSpMatrix2 <- function(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) { d <- dim(x) cl <- class(x) cld <- getClassDef(cl) xtra <- if(extends(cld, "triangularMatrix") && x@diag == "U") " (unitriangular)" else "" cat(sprintf('%d x %d sparse Matrix of class "%s"%s\n', d[1], d[2], cl, xtra)) setW <- !missing(width) && width > getOption("width") if(setW) { op <- options(width = width) ; on.exit( options(op) ) } if((isFALSE(suppRows) && isFALSE(suppCols)) || (!isTRUE(suppRows) && !isTRUE(suppCols) && prod(d) <= maxp)) { ## "small matrix" and supp* not TRUE : no rows or columns are suppressed if(missing(col.trailer) && is.null(suppCols)) suppCols <- FALSE # for default 'col.trailer' printSpMatrix(x, cld=cld, digits=digits, maxp=maxp, zero.print=zero.print, col.names=col.names, note.dropping.colnames=note.dropping.colnames, uniDiag=uniDiag, col.trailer=col.trailer, align=align) } else { ## d[1] > maxp / d[2] >= nr : -- this needs [,] working: validObject(x) sTxt <- c(" ", gettext("in show(); maybe adjust options(max.print=, width=)"), "\n ..............................\n") useW <- width - (format.info(d[1], digits=digits)[1] + 3+1) ## == width - space for the largest row label : "[,] " ## Suppress rows and/or columns in printing ... ## ---------------------------------------- but which exactly depends on format ## Determining number of columns - first assuming all zeros : ". . "..: 2 chars/column ## i.e., we get the *maximal* numbers of columns to keep, nc : if(is.null(suppCols)) # i.e., "it depends" .. suppCols <- (d[2] * 2 > useW) # used in 'col.trailer' default nCc <- 1 + nchar(col.trailer, "width") if(suppCols) { nc <- (useW - nCc) %/% 2 x <- x[ , 1:nc, drop = FALSE] } else nc <- d[2] nr <- maxp %/% nc # if nc becomes smaller, nr will become larger (!) if(is.null(suppRows)) suppRows <- (nr < d[1]) if(suppRows) { n2 <- ceiling(nr / 2) nr1 <- min(d[1], max(1L, n2)) #{rows} in 1st part nr2 <- max(1L, nr-n2) #{rows} in 2nd part nr <- nr1+nr2 # total #{rows} to be printed if(fitWidth) { ## one iteration of improving the width, by "fake printing" : cM <- formatSpMatrix(x[seq_len(nr1), , drop = FALSE], digits=digits, maxp=maxp, zero.print=zero.print, col.names=col.names, align=align, note.dropping.colnames=note.dropping.colnames, uniDiag=FALSE) ## width needed (without the 'col.trailer's 'nCc'): matW <- nchar(capture.output(print(cM, quote=FALSE, right=FALSE))[[1]]) needW <- matW + (if(suppCols) nCc else 0) if(needW > useW) { ## need more width op <- options(width = width+(needW-useW)) if(!setW) on.exit( options(op) ) } } printSpMatrix(x[seq_len(nr1), , drop=FALSE], digits=digits, maxp=maxp, zero.print=zero.print, col.names=col.names, note.dropping.colnames=note.dropping.colnames, uniDiag=uniDiag, col.trailer = col.trailer, align=align) suppTxt <- if(suppCols) gettextf("suppressing %d columns and %d rows", d[2]-nc , d[1]-nr) else gettextf("suppressing %d rows", d[1]-nr) cat("\n ..............................", "\n ........", suppTxt, sTxt, sep='') ## tail() automagically uses "[..,]" rownames: printSpMatrix(tail(x, nr2), digits=digits, maxp=maxp, zero.print=zero.print, col.names=col.names, note.dropping.colnames=note.dropping.colnames, uniDiag=FALSE, col.trailer = col.trailer, align=align) } else if(suppCols) { printSpMatrix(x[ , 1:nc , drop = FALSE], digits=digits, maxp=maxp, zero.print=zero.print, col.names=col.names, note.dropping.colnames=note.dropping.colnames, uniDiag=uniDiag, col.trailer = col.trailer, align=align) cat("\n .....", gettextf("suppressing %d columns", d[2]-nc), sTxt, sep='') } else stop("logic programming error in printSpMatrix2(), please report") invisible(x) } } prSpVector <- function(x, digits = getOption("digits"), maxp = getOption("max.print"), zero.print = ".") { cld <- getClassDef(class(x)) stopifnot(extends(cld, "sparseVector"), maxp >= 1) if(is.logical(zero.print)) zero.print <- if(zero.print) "0" else " " ## kind <- .M.kindC(cld) ## has.x <- kind != "n" n <- x@length if(n > 0) { if(n > maxp) { ## n > maxp =: nn : will cut length of what we'll display : x <- head(x, maxp) n <- maxp } xi <- x@i is.n <- extends(cld, "nsparseVector") logi <- is.n || extends(cld, "lsparseVector") cx <- if(logi) rep.int("N", n) else character(n) cx[if(length(xi)) -xi else TRUE] <- zero.print cx[xi] <- if(is.n) "|" else if(logi) c(":", "|")[x@x + 1L] else ## numeric (or --not yet-- complex): 'has.x' in any cases format(x@x, digits = digits) ## right = TRUE : cheap attempt to get better "." alignment print(cx, quote = FALSE, right = TRUE, max = maxp) } invisible(x) # TODO? in case of n > maxp, "should" return original x } ## METHODS FOR GENERIC: show ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("show", signature(object = "denseMatrix"), function(object) prMatrix(object)) setMethod("show", signature(object = "sparseMatrix"), function(object) printSpMatrix2(object)) setMethod("show", signature(object = "diagonalMatrix"), function(object) { d <- dim(object) cl <- class(object) cat(sprintf('%d x %d diagonal matrix of class "%s"', d[1L], d[2L], cl)) if(d[1L] < 50) { cat("\n") prDiag(object) } else { cat(", with diagonal entries\n") show(diag(object)) invisible(object) } }) setMethod("show", "MatrixFactorization", function(object) { cat("matrix factorization of ") str(object) }) setMethod("show", "CholeskyFactorization", function(object) { cat("Cholesky factorization of ") str(object) }) setMethod("show", "BunchKaufmanFactorization", function(object) { cat("Bunch-Kaufman factorization of ") str(object) }) setMethod("show", "SchurFactorization", function(object) { cat("Schur factorization of ") str(object) }) setMethod("show", "LU", function(object) { cat("LU factorization of ") str(object) }) setMethod("show", "QR", function(object) { cat("QR factorization of ") str(object) }) setMethod("show", signature(object = "sparseVector"), function(object) { n <- object@length cl <- class(object) cat(sprintf("sparse vector (nnz/length = %d/%.0f) of class \"%s\"\n", length(object@i), as.double(n), cl)) maxp <- max(1, getOption("max.print")) if(n <= maxp) prSpVector(object, maxp = maxp) else { ## n > maxp : will cut length of what we'll display : ## cannot easily show head(.) & tail(.) because of ## "[1] .." printing of tail prSpVector(head(object, maxp), maxp = maxp) cat(" ............................\n", " ........suppressing ", n - maxp, " entries in show(); maybe adjust options(max.print=)\n", " ............................\n\n", sep = "") } invisible(object) }) ## METHODS FOR GENERIC: print ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("print", signature(x = "sparseMatrix"), printSpMatrix2) setMethod("print", signature(x = "diagonalMatrix"), prDiag) ## METHODS FOR GENERIC: format ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("format", signature(x = "sparseMatrix"), formatSpMatrix) ## METHODS FOR GENERIC: summary ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("summary", signature(object = "sparseMatrix"), function(object, uniqT = FALSE, ...) { d <- object@Dim ## return a data frame (int, int, {double|logical}) : r <- as.data.frame(mat2triplet(object, uniqT = uniqT)) attr(r, "header") <- sprintf("%d x %d sparse Matrix of class \"%s\", with %d entries", d[1L], d[2L], class(object), nrow(r)) class(r) <- c("sparseSummary", oldClass(r)) r }) setMethod("summary", signature(object = "diagonalMatrix"), function(object, ...) { d <- object@Dim r <- summary(object@x, ...) attr(r, "header") <- sprintf("%d x %d diagonal Matrix of class \"%s\"", d[1L], d[2L], class(object)) class(r) <- c("diagSummary", class(r)) r }) print.sparseSummary <- print.diagSummary <- function (x, ...) { cat(attr(x, "header"), "\n", sep = "") NextMethod() invisible(x) } ������������������������������������������������������Matrix/R/bind2.R������������������������������������������������������������������������������������0000644�0001762�0000144�00000006465�14534140574�013062� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## METHODS FOR GENERIC: c ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ c.Matrix <- function(...) { if(nargs() == 0L) return(NULL) args <- lapply(list(...), as.vector) unlist(args, FALSE, TRUE) } c.sparseVector <- function(...) { N <- nargs() if(N == 0L) return(NULL) args <- lapply(list(...), as, "sparseVector") args.length <- vapply(args, slot, 0, "length") args.i <- lapply(args, slot, "i") args.nnz <- lengths(args.i, FALSE) s <- c("n", "l", "i", "d", "z") i <- match(vapply(args, .M.kind, ""), s) k <- range(i) n <- sum(args.length) a <- if(n - 1 <= .Machine$integer.max) as.integer else as.double r <- new(paste0(s[k[2L]], "sparseVector")) r@length <- a(n) r@i <- a(unlist(args.i, FALSE, FALSE)) + rep.int(cumsum(c(0L, a(args.length)[-N])), args.nnz) if(k[2L] > 1L) { if(k[1L] > 1L) args.x <- lapply(args, slot, "x") else { pattern <- i == 1L args.x <- vector("list", N) args.x[!pattern] <- lapply(args [!pattern], slot, "x") args.x[ pattern] <- lapply(args.nnz[ pattern], rep.int, x = TRUE) } r@x <- unlist(args.x, FALSE, FALSE) } r } ## These are insufficient as dispatch only consides the first argument, ## which need not be a Matrix or sparseVector: if(FALSE) { setMethod("c", "Matrix", function(x, ...) c.Matrix (x, ...)) setMethod("c", "sparseVector", function(x, ...) c.sparseVector(x, ...)) } ## METHODS FOR GENERIC: cbind, rbind ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## MJ: not yet registered or exported cbind.Matrix <- function(..., deparse.level = 1) .External(R_bind, deparse.level, 1L, substitute(list(...)), ...) rbind.Matrix <- function(..., deparse.level = 1) .External(R_bind, deparse.level, 0L, substitute(list(...)), ...) ## METHODS FOR GENERIC: cbind2, rbind2 ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .cbind2 <- function(x, y, ...) cbind.Matrix(x, y, deparse.level = 0L) .rbind2 <- function(x, y, ...) rbind.Matrix(x, y, deparse.level = 0L) setMethod("cbind2", signature(x = "Matrix", y = "missing"), function(x, y, ...) x) setMethod("rbind2", signature(x = "Matrix", y = "missing"), function(x, y, ...) x) setMethod("cbind2", signature(x = "Matrix", y = "NULL"), .cbind2) setMethod("cbind2", signature(x = "NULL", y = "Matrix"), .cbind2) setMethod("rbind2", signature(x = "Matrix", y = "NULL"), .rbind2) setMethod("rbind2", signature(x = "NULL", y = "Matrix"), .rbind2) setMethod("cbind2", signature(x = "Matrix", y = "vector"), .cbind2) setMethod("cbind2", signature(x = "vector", y = "Matrix"), .cbind2) setMethod("rbind2", signature(x = "Matrix", y = "vector"), .rbind2) setMethod("rbind2", signature(x = "vector", y = "Matrix"), .rbind2) setMethod("cbind2", signature(x = "Matrix", y = "matrix"), .cbind2) setMethod("cbind2", signature(x = "matrix", y = "Matrix"), .cbind2) setMethod("rbind2", signature(x = "Matrix", y = "matrix"), .rbind2) setMethod("rbind2", signature(x = "matrix", y = "Matrix"), .rbind2) setMethod("cbind2", signature(x = "Matrix", y = "Matrix"), .cbind2) setMethod("rbind2", signature(x = "Matrix", y = "Matrix"), .rbind2) rm(.cbind2, .rbind2) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/R/image.R������������������������������������������������������������������������������������0000644�0001762�0000144�00000013743�14503364553�013144� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## METHODS FOR GENERIC: image ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## NB: currently going via dgTMatrix in all cases, ## which is not so inefficient, as levelplot() ## needs 'i' and 'j' anyway .image.dgT <- function(x, xlim = c(1, di[2L]), ylim = c(di[1L], 1), aspect = "iso", sub = sprintf("Dimensions: %d x %d", di[1L], di[2L]), xlab = "Column", ylab = "Row", cuts = 15, useRaster = FALSE, useAbs = NULL, colorkey = !useAbs, col.regions = NULL, lwd = NULL, border.col = NULL, ...) { ## 'at' can remain missing and be passed to levelplot di <- x@Dim xx <- x@x empty.x <- length(xx) == 0L && length(x) > 0L if(empty.x) { # workaround having "empty" matrix xx <- 0 x@i <- x@j <- 0L } if(missing(useAbs)) ## use abs() when all values are non-neg useAbs <- if(empty.x) FALSE else min(xx, na.rm = TRUE) >= 0 else if(useAbs) xx <- abs(xx) ## rx <- range(xx, finite = TRUE) ## FIXME: make use of 'cuts' now ## and call levelplot() with 'at = ', ## making sure 0 is included and matching ## *exactly* - rather than approximately if(is.null(col.regions)) { l.col <- empty.x || diff(rx <- range(xx, finite = TRUE)) == 0 col.regions <- if(useAbs) { grey(if(l.col) 0.9 else seq(from = 0.7, to = 0, length.out = 100L)) } else if(l.col) "gray90" else { ## no abs(.), rx[1] < 0 typically nn <- 100 n0 <- min(nn, max(0, round((0 - rx[1L])/(rx[2L]-rx[1L]) * nn))) col.regions <- c(colorRampPalette(c("blue3", "gray80"))(n0), colorRampPalette(c("gray75","red3"))(nn - n0)) } } if(!is.null(lwd) && !(is.numeric(lwd) && all(lwd >= 0))) # allow lwd=0 stop("'lwd' must be NULL or non-negative numeric") stopifnot(length(xlim) == 2L, length(ylim) == 2L) ## ylim: the rows count from top to bottom: ylim <- sort(ylim, decreasing = TRUE) if(all(xlim == round(xlim))) xlim <- xlim + c(-0.5, +0.5) if(all(ylim == round(ylim))) ylim <- ylim + c(+0.5, -0.5) # decreasing! panel <- if(useRaster) panel.levelplot.raster else { function(x, y, z, subscripts, at, ..., col.regions) { x <- as.numeric(x[subscripts]) y <- as.numeric(y[subscripts]) ## ## FIXME: use level.colors() here and 'at' from above -- ## ----- look at 'zcol' in panel.levelplot() numcol <- length(at) - 1L num.r <- length(col.regions) col.regions <- if(num.r <= numcol) rep_len(col.regions, numcol) else col.regions[1 + ((1:numcol-1)*(num.r-1)) %/% (numcol-1)] zcol <- rep.int(NA_integer_, length(z)) for(i in seq_along(col.regions)) zcol[!is.na(x) & !is.na(y) & !is.na(z) & at[i] <= z & z < at[i+1L]] <- i zcol <- zcol[subscripts] if(any(subscripts)) { ## the line-width used in grid.rect() inside ## levelplot()'s panel for the *border* of the ## rectangles: levelplot()panel has lwd= 0.01: ## Here: use "smart" default ! if(is.null(lwd)) { wh <- current.viewport()[c("width", "height")] ## wh : current viewport dimension in pixel wh <- (par("cra") / par("cin")) * c(convertWidth(wh$width, "inches", valueOnly = TRUE), convertHeight(wh$height, "inches", valueOnly = TRUE)) pSize <- wh/di ## size of one matrix-entry in pixels pA <- prod(pSize) # the "area" p1 <- min(pSize) lwd <- ## crude for now if(p1 < 2 || pA < 6) 0.01 # effectively 0 else if(p1 >= 4) 1 else if(p1 > 3) 0.5 else 0.2 ## browser() Matrix.message("rectangle size ", paste(round(pSize, 1L), collapse = " x "), " [pixels]; --> lwd :", formatC(lwd)) } else stopifnot(is.numeric(lwd), all(lwd >= 0)) # allow 0 if(is.null(border.col) && lwd < 0.01) # no border border.col <- NA grid.rect(x = x, y = y, width = 1, height = 1, default.units = "native", ## FIXME?: allow 'gp' to be passed via '...' !! gp = gpar(fill = col.regions[zcol], lwd = lwd, col = border.col)) } } } # panel <- if(useRaster) ... levelplot(xx ~ (x@j + 1L) * (x@i + 1L), # no 'data' sub = sub, xlab = xlab, ylab = ylab, xlim = xlim, ylim = ylim, aspect = aspect, colorkey = colorkey, col.regions = col.regions, cuts = cuts, par.settings = list(background = list(col = "transparent")), panel = panel, ...) } setMethod("image", "dgTMatrix", .image.dgT) setMethod("image", "Matrix", function(x, ...) { if(.M.kind(x) == "z") stop(gettextf("%s(<%s>) is not yet implemented", "image", "zMatrix"), domain = NA) image(.M2kind(.M2gen(.M2T(x)), "d"), ...) }) setMethod("image", "CHMfactor", function(x, ...) image(.M2gen(.M2T(expand1(x, "L"))), ...)) rm(.image.dgT) �����������������������������Matrix/R/nnzero.R�����������������������������������������������������������������������������������0000644�0001762�0000144�00000006314�14500446564�013371� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## METHODS FOR GENERIC: nnzero ## * used to retrieve number of nonzero elements, ## i.e., number of elements excl. both structural and non-structural zeros ## * like MATLAB's nnz() but more sophisticated due to handling of NA ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## na.counted: ## FALSE ... NA is treated as zero and so excluded from count ## TRUE ... NA is treated as nonzero and so included in count ## NA ... NA is indeterminate (could be zero or nonzero) hence count is NA sparseDefault <- function(x) length(x) > 2 * nnzero(x, na.counted = TRUE) .sparseDefault <- function(x) length(x) > 2 * .nnzero(x, na.counted = TRUE) ## For logical, integer, double, and complex vectors .nnzero <- function(x, na.counted = NA, nnzmax = length(x)) .Call(R_nnz, x, na.counted, nnzmax) ## For any class with methods for 'is.na' and '!=' .nnzero.fallback <- function(x, na.counted = NA) sum(if(is.na(na.counted)) x != 0 else if(na.counted) is.na(x) | x != 0 else !is.na(x) & x != 0) .nnzero.dispatching <- function(x, na.counted = NA) switch(typeof(x), logical =, integer =, double =, complex = .nnzero, .nnzero.fallback)(x, na.counted) setMethod("nnzero", "ANY", .nnzero.fallback) setMethod("nnzero", "vector", .nnzero.dispatching) setMethod("nnzero", "denseMatrix", function(x, na.counted = NA) { d <- x@Dim if(any(d == 0L)) return(0L) if(.M.kind(x) == "n") na.counted <- TRUE if((shape <- .M.shape(x)) != "g") x <- .M2packed(x) N <- .nnzero(x@x, na.counted) switch(shape, "g" = N, "s" = N + N - .nnzero(diag(x, names = FALSE), na.counted), "t" = if(x@diag == "N") N else N + d[1L] - .nnzero(x@x[indDiag(d[1L], upper = x@uplo == "U", packed = TRUE)], na.counted)) }) setMethod("nnzero", "sparseMatrix", function(x, na.counted = NA) { d <- x@Dim if(any(d == 0L)) return(0L) N <- switch(.M.repr(x), "C" = x@p[d[2L]+1L], "R" = x@p[d[1L]+1L], "T" = length((x <- aggregateT(x))@i)) if(.M.kind(x) != "n") N <- .nnzero(x@x, na.counted, N) switch(.M.shape(x), "g" = N, "s" = N + N - .nnzero(diag(x, names = FALSE), na.counted), "t" = if(x@diag == "N") N else N + d[1L]) }) setMethod("nnzero", "diagonalMatrix", function(x, na.counted = NA) { if(x@diag != "N") x@Dim[1L] else { y <- x@x if(.M.kind(x) == "n" && anyNA(y)) y <- y | is.na(y) .nnzero(y, na.counted) } }) setMethod("nnzero", "indMatrix", function(x, na.counted = NA) length(x@perm)) setMethod("nnzero", "CHMfactor", function(x, na.counted = NA) nnzero(as(x, "CsparseMatrix"), na.counted)) rm(.nnzero.dispatching) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/R/objects.R����������������������������������������������������������������������������������0000644�0001762�0000144�00000006237�14511521056�013503� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## if strict=FALSE then gives "...Matrix" or ".sparseVector" or "" ## if strict= TRUE then may also give one of these: ## "pMatrix", "dpoMatrix", "dppMatrix", "corMatrix", "pcorMatrix" .M.nonvirtual <- function(x, strict = FALSE) .Call(R_Matrix_nonvirtual, x, strict) ## "[nlidz]" for Matrix, sparseVector, logical, integer, double, complex 'x'; ## otherwise "" .M.kind <- function(x) .Call(R_Matrix_kind, x) ## "[gstd]" for Matrix, sparseVector 'x'; ## otherwise "" .M.shape <- function(x) .Call(R_Matrix_shape, x) ## "[CRTdiup]" for [CRT]sparseMatrix, diagonalMatrix, indMatrix ## unpackedMatrix, packedMatrix 'x' {resp.}; ## otherwise "" .M.repr <- function(x) .Call(R_Matrix_repr, x) .isMatrix <- function(x) nzchar(cl <- .M.nonvirtual(x)) && substr(cl, 4L, 4L) == "M" .isVector <- function(x) nzchar(cl <- .M.nonvirtual(x)) && substr(cl, 8L, 8L) == "V" .isDense <- function(x) any(.M.repr(x) == c("u", "p")) .isUnpacked <- function(x) .M.repr(x) == "u" .isPacked <- function(x) .M.repr(x) == "p" .isSparse <- function(x) any(.M.repr(x) == c("C", "R", "T", "d", "i")) .isCRT <- function(x) any(.M.repr(x) == c("C", "R", "T")) .isC <- function(x) .M.repr(x) == "C" .isR <- function(x) .M.repr(x) == "R" .isT <- function(x) .M.repr(x) == "T" .isDiagonal <- function(x) .M.repr(x) == "d" .isInd <- function(x) .M.repr(x) == "i" ## for .type.kind[.M.kind(x)]: .type.kind <- c("n" = "logical", "l" = "logical", "i" = "integer", "d" = "double", "z" = "complex") ## for .kind.type[ typeof(x)]: .kind.type <- c("logical" = "l", "integer" = "i", "double" = "d", "complex" = "z") extends1of <- function(class, classes, ...) { if(is.character(class)) class <- getClassDef(class[[1L]]) for(cl in classes) if(extends(class, cl, ...)) return(TRUE) FALSE } MatrixClass <- function(cl, cld = getClassDef(cl), ...Matrix = TRUE, dropVirtual = TRUE, ...) { if(!is.character(cl) || length(cl) != 1L || is.na(cl)) stop("'cl' is not a character string") if(is.null(pkg <- cld@package) && is.null(pkg <- attr(cl, "package"))) return(character(0L)) if(identical(pkg, "Matrix") && (!...Matrix || grepl("^[nlidz](ge|sy|sp|tr|tp|di|[gst][CRT])Matrix$", cl))) return(cl) r <- .selectSuperClasses(cld@contains, dropVirtual = dropVirtual, namesOnly = TRUE, ...) if(length(r) == 0L) return(character(0L)) while({ r1 <- Recall(r[1L], ...Matrix = ...Matrix, dropVirtual = dropVirtual, ...) length(r1) == 0L && length(r) > 1L }) r <- r[-1L] r1 } class2 <- function(cl, kind = "l") sub("^[nlidz]", kind, MatrixClass(cl)) copyClass <- function(from, to.class, sNames = intersect(slotNames(to.class), slotNames(from)), check = TRUE) { to <- new(to.class) if(check) for(nm in sNames) slot(to, nm) <- slot(from, nm) else for(nm in sNames) attr(to, nm) <- attr(from, nm) to } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/R/zzz.R��������������������������������������������������������������������������������������0000644�0001762�0000144�00000055724�14533700334�012716� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## ~~~~ VERSION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Matrix.Version <- function() { n <- .Call(R_Matrix_version) v <- .mapply(function(n, p, b, class) { r <- integer(p) while (p > 0L) { r[p] <- tmp <- n %% b n <- (n - tmp) %/% b p <- p - 1L } v <- list(r) class(v) <- c(class, "numeric_version") v }, list(n = n, p = c(3L, 1L, 3L), b = c(256L, 10L, 256L), class = list("package_version", NULL, NULL)), NULL) names(v) <- names(n) v } ## ~~~~ PACKAGE ENVIRONMENTS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## Recording default values of Matrix.* options .MatrixEnv <- new.env(parent = emptyenv(), hash = FALSE) ## Storing settings from 'cholmod_common' .CholmodCommonEnv <- new.env(parent = emptyenv()) ## ~~~~ NAMESPACE HOOKS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .onLoad <- function(libname, pkgname) { ## For backwards compatibility with earlier versions of R, ## at least until x.y.z if we have Depends: R (>= x.y.z) Mns <- parent.env(environment()) if(!environmentIsLocked(Mns)) { ## Namespace not locked yet, but being defensive here Rv <- getRversion() if(Rv < "4.4.0") { assign("%||%", envir = Mns, inherits = FALSE, function(x, y) if(is.null(x)) y else x) if(Rv < "4.1.3") { assign("...names", envir = Mns, inherits = FALSE, function() eval(quote(names(list(...))), sys.frame(-1L))) if(Rv < "4.0.0") { assign("deparse1", envir = Mns, inherits = FALSE, function(expr, collapse = " ", width.cutoff = 500L, ...) paste(deparse(expr, width.cutoff, ...), collapse = collapse)) assign("sequence.default", envir = Mns, inherits = FALSE, function(nvec, from = 1L, by = 1L, ...) { if(length(nvec) == 0L) return(integer(0L)) else if(length(from) == 0L || length(by) == 0L) stop(gettextf("'%s' has length 0 but '%s' does not", if(length(from) == 0L) "from" else "by", "nvec"), domain = NA) unlist(.mapply(seq.int, list(from = as.integer(from), by = as.integer(by), length.out = as.integer(nvec)), NULL), recursive = FALSE, use.names = FALSE) }) assign("tryInvokeRestart", envir = Mns, inherits = FALSE, function(r, ...) tryCatch(invokeRestart(r, ...), error = function(e) invisible(NULL))) } # Rv < "4.0.0" } # Rv < "4.1.3" } # Rv < "4.4.0" } ## verbose: ## logical/integer (but often supplied as double), ## deciding _if_ conditions are signaled v <- as.integer(Sys.getenv("R_MATRIX_VERBOSE", "0")) assign("verbose", if(is.na(v)) 0L else v, envir = .MatrixEnv) ## warn: ## logical/integer (but often supplied as double), ## deciding _what_ conditions are signaled ## (0=message, 1=warning, 2=error) w <- as.integer(Sys.getenv("R_MATRIX_WARN", "0")) assign("warn", if(is.na(w)) 0L else w, envir = .MatrixEnv) ## ambiguityNotes: ## show S4 method dispatch ambiguity notes if TRUE aN <- as.logical(Sys.getenv("R_MATRIX_AMBIGUITY_NOTES", "false")) aN <- (!is.na(aN) && aN) || !is.null(getOption("ambiguousMethodSelection")) assign("ambiguityNotes", aN, envir = .MatrixEnv) if(!aN) options(ambiguousMethodSelection = # ?methods::testInheritedMethods `environment<-`(function(cond) NULL, emptyenv())) ## warnDeprecatedCoerce: ## <=0 ... no conditions signaled ## 1 ... persistent warning ## >=2 ... persistent error ## NA ... one-time message { d(g.|.C)Matrix } or warning { others } wDC <- as.integer(Sys.getenv("R_MATRIX_WARN_DEPRECATED_COERCE", NA)) assign("warnDeprecatedCoerce", wDC, envir = .MatrixEnv) ## warnSqrtDefault: ## <=0 ... no conditions signaled ## 1 ... persistent warning ## >=2 ... persistent error ## NA ... one-time warning wSD <- as.integer(Sys.getenv("R_MATRIX_WARN_SQRT_DEFAULT", NA)) assign("warnSqrtDefault", wSD, envir = .MatrixEnv) .Call(R_cholmod_common_envini, .CholmodCommonEnv) NULL } .onUnload <- function(libpath) { library.dynam.unload("Matrix", libpath) if(!.MatrixEnv[["ambiguityNotes"]]) options(ambiguousMethodSelection = NULL) NULL } ## ~~~~ DEPRECATED ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ..2dge <- function(from) { .Deprecated(new = ".M2gen(*, \"d\") or .m2dense(*, \"dge\")", package = "Matrix") if(isS4(from)) .M2gen(from, "d") else .m2dense(from, "dge") } .C2nC <- function(from, isTri) { .Deprecated(new = ".M2kind", package = "Matrix") .M2kind(from, "n") } .T2Cmat <- function(from, isTri) { .Deprecated(new = ".M2C", package = "Matrix") .M2C(from) } .asmatrix <- function(x) { .Deprecated(new = "as(., \"matrix\")", package = "Matrix") as(x, "matrix") } .dense2sy <- function(from, ...) { .Deprecated(new = ".M2sym", package = "Matrix") .M2sym(from, ...) } .diag2mat <- function(from) { .Deprecated(new = ".M2m", package = "Matrix") .M2m(from) } .diag2sT <- function(from, uplo = "U", kind = ".", drop0 = TRUE) { .Deprecated(new = ".diag2sparse", package = "Matrix") r <- .diag2sparse(from, kind, "s", "T", uplo) if(drop0) r <- .drop0(r) r } .diag2tT <- function(from, uplo = "U", kind = ".", drop0 = TRUE) { .Deprecated(new = ".diag2sparse", package = "Matrix") to <- .diag2sparse(from, kind, "t", "T", uplo) if(drop0) to <- .drop0(to) to } .dsy2dsp <- function(from) { .Deprecated(new = ".M2packed", package = "Matrix") .M2packed(from) } .dsy2mat <- function(from, keep.dimnames = TRUE) { .Deprecated(new = ".M2m", package = "Matrix") to <- .M2m(from) if(!keep.dimnames) dimnames(to) <- NULL to } .dxC2mat <- function(from, chkUdiag) { .Deprecated(new = ".M2m", package = "Matrix") .M2m(from) } .m2dgC <- function(from) { .Deprecated(new = ".m2sparse", package = "Matrix") .m2sparse(from, "dgC") } .m2lgC <- function(from) { .Deprecated(new = ".m2sparse", package = "Matrix") .m2sparse(from, "lgC") } .m2ngC <- function(from) { .Deprecated(new = ".m2sparse", package = "Matrix") if(anyNA(from)) stop(gettextf("attempt to coerce matrix with NA to %s", "ngCMatrix"), domain = NA) .m2sparse(from, "ngC") } .m2ngCn <- function(from, na.is.not.0 = FALSE) { .Deprecated(new = ".m2sparse", package = "Matrix") if(!na.is.not.0 && anyNA(from)) stop(gettextf("attempt to coerce matrix with NA to %s", "ngCMatrix"), domain = NA) .m2sparse(from, "ngC") } .m2ngTn <- function(from, na.is.not.0 = FALSE) { .Deprecated(new = ".m2sparse", package = "Matrix") if(!na.is.not.0 && anyNA(from)) stop(gettextf("attempt to coerce matrix with NA to %s", "ngTMatrix"), domain = NA) .m2sparse(from, "ngT") } .n2dgT <- function(from) { .Deprecated(new = ".M2kind", package = "Matrix") .M2kind(from, "d") } .nC2d <- function(from) { .Deprecated(new = ".M2kind", package = "Matrix") .M2kind(from, "d") } .nC2l <- function(from) { .Deprecated(new = ".M2kind", package = "Matrix") .M2kind(from, "l") } .dense2m <- .sparse2m <- function(from) { if(FALSE) { .Deprecated(new = ".M2m", package = "Matrix") } .M2m(from) } .dense2v <- .sparse2v <- function(from) { if(FALSE) { .Deprecated(new = ".M2v", package = "Matrix") } .M2v(from) } .dense2kind <- function(from, kind) { if(FALSE) { .Deprecated(new = ".M2kind", package = "Matrix") } .M2kind(from, kind) } .sparse2kind <- function(from, kind, drop0 = FALSE) { if(FALSE) { .Deprecated(new = ".M2kind", package = "Matrix") } .M2kind(if(drop0) .drop0(from) else from, kind) } .dense2g <- .sparse2g <- function(from, kind = ".") { if(FALSE) { .Deprecated(new = ".M2gen", package = "Matrix") } .M2gen(from, kind) } .CR2RC <- function(from) { if(.M.repr(from) != "C") { if(FALSE) { .Deprecated(new = ".M2C", package = "Matrix") } .M2C(from) } else { if(FALSE) { .Deprecated(new = ".M2R", package = "Matrix") } .M2R(from) } } .CR2T <- function(from) { if(FALSE) { .Deprecated(new = ".M2T", package = "Matrix") } .M2T(from) } .T2CR <- function(from, Csparse = TRUE) { if(Csparse) { if(FALSE) { .Deprecated(new = ".M2C", package = "Matrix") } .M2C(from) } else { if(FALSE) { .Deprecated(new = ".M2R", package = "Matrix") } .M2R(from) } } .tCR2RC <- function(from) { if(FALSE) { .Deprecated(new = ".tCRT", package = "Matrix") } .tCRT(from) } uniqTsparse <- function(x, class.x = class(x)) { if(FALSE) { .Deprecated(new = "asUniqueT", package = "Matrix") } asUniqueT(x, isT = extends(class.x, "TsparseMatrix")) } .SuiteSparse_version <- function() { if(FALSE) { .Deprecated(new = "Matrix.Version", package = "Matrix") } Matrix.Version()[["suitesparse"]] } ## Utility for Matrix.DeprecatedCoerce(); see below .as.via.virtual <- function(Class1, Class2, from = quote(from)) { if(!isClassDef(Class1)) Class1 <- getClassDef(Class1) if(!isClassDef(Class2)) Class2 <- getClassDef(Class2) if(!grepl("^[dln](di|ge|tr|sy|tp|sp|[gts][CRT])Matrix$", Class2@className)) stop("invalid 'Class2'") contains1 <- names(Class1@contains) contains2 <- names(Class2@contains) virtual <- list(c("dMatrix", "lMatrix", "nMatrix"), c("generalMatrix", "triangularMatrix", "symmetricMatrix"), c("CsparseMatrix", "RsparseMatrix", "TsparseMatrix", "diagonalMatrix", "unpackedMatrix", "packedMatrix")) to <- from for(v in virtual) { if(any(m <- match(v, contains2, 0L) > 0L)) { v1 <- v[m][1L] if(match(v1, contains1, 0L) == 0L) to <- call("as", to, v1) } } to } Matrix.DeprecatedCoerce <- function(Class1, Class2) { if(!isClassDef(Class1)) Class1 <- getClassDef(Class1) if(!isClassDef(Class2)) Class2 <- getClassDef(Class2) w <- getOption("Matrix.warnDeprecatedCoerce", .MatrixEnv[["warnDeprecatedCoerce"]]) if(is.atomic(w) && length(w) == 1L && ((w.na <- is.na(w <- as.integer(w))) || w > 0L)) { cln1 <- Class1@className cln2 <- Class2@className old <- sprintf("as(<%s>, \"%s\")", cln1, cln2) new <- deparse1(.as.via.virtual(Class1, Class2, quote(.))) if(w.na) on.exit(options(Matrix.warnDeprecatedCoerce = 0L)) if(w.na && grepl("d(g.|.C)Matrix", cln2)) { cond <- tryCatch(.Deprecated(old = old, new = new, package = "Matrix"), deprecatedWarning = identity) message(conditionMessage(cond), domain = NA) } else { if(!w.na && w > 1L) { oop <- options(warn = 2L) on.exit(options(oop)) } .Deprecated(old = old, new = new, package = "Matrix") } } invisible(NULL) } ## "Granular" coercions available in Matrix 1.4-1, ## all candidates for deprecation in Matrix 1.5-0: if(FALSE) { stopifnot(packageVersion("Matrix") == "1.4.1") dput(lapply(grep("to=\"[dln](di|ge|tr|sy|tp|sp|[gts][CRT])Matrix\"", capture.output(showMethods("coerce")), value = TRUE), function(s) unname(eval(str2lang(paste0("c(", s, ")")))))) } ## Note: Allow as(*, "dpoMatrix") to check for pos.(semi)definite-ness .from.to <- list(c("ddenseMatrix", "dgeMatrix"), c("ddiMatrix", "dgCMatrix"), c("ddiMatrix", "dgeMatrix"), c("ddiMatrix", "dtCMatrix"), c("dgCMatrix", "dgeMatrix"), c("dgCMatrix", "dgTMatrix"), c("dgCMatrix", "dsCMatrix"), c("dgCMatrix", "dtCMatrix"), c("dgCMatrix", "lgCMatrix"), c("dgCMatrix", "ngCMatrix"), c("dgeMatrix", "dgCMatrix"), c("dgeMatrix", "dgTMatrix"), c("dgeMatrix", "dspMatrix"), c("dgeMatrix", "dsTMatrix"), c("dgeMatrix", "dsyMatrix"), c("dgeMatrix", "dtrMatrix"), c("dgeMatrix", "lgeMatrix"), c("dgTMatrix", "dgCMatrix"), c("dgTMatrix", "dgeMatrix"), c("dgTMatrix", "dsTMatrix"), c("dgTMatrix", "dtCMatrix"), c("dgTMatrix", "dtTMatrix"), c("dsCMatrix", "dgCMatrix"), c("dsCMatrix", "dgeMatrix"), c("dsCMatrix", "dgTMatrix"), c("dsCMatrix", "dsRMatrix"), c("dsCMatrix", "dsTMatrix"), c("dsCMatrix", "dsyMatrix"), c("dsCMatrix", "lsCMatrix"), c("dsCMatrix", "nsCMatrix"), c("dspMatrix", "dsyMatrix"), c("dspMatrix", "lspMatrix"), c("dsTMatrix", "dgeMatrix"), c("dsTMatrix", "dgTMatrix"), c("dsTMatrix", "dsCMatrix"), c("dsTMatrix", "dsyMatrix"), c("dsTMatrix", "lsTMatrix"), c("dsyMatrix", "dsCMatrix"), c("dsyMatrix", "dspMatrix"), c("dsyMatrix", "dsTMatrix"), c("dsyMatrix", "lsyMatrix"), c("dtCMatrix", "dgCMatrix"), c("dtCMatrix", "dgeMatrix"), c("dtCMatrix", "dgTMatrix"), c("dtCMatrix", "dsCMatrix"), c("dtCMatrix", "dtrMatrix"), c("dtCMatrix", "dtTMatrix"), c("dtCMatrix", "ltCMatrix"), c("dtCMatrix", "ntCMatrix"), c("dtpMatrix", "dtrMatrix"), c("dtpMatrix", "dtTMatrix"), c("dtpMatrix", "ltpMatrix"), c("dtrMatrix", "dtpMatrix"), c("dtrMatrix", "ltrMatrix"), c("dtTMatrix", "dgeMatrix"), c("dtTMatrix", "dgTMatrix"), c("dtTMatrix", "dtCMatrix"), c("dtTMatrix", "dtrMatrix"), c("indMatrix", "ngeMatrix"), c("indMatrix", "ngTMatrix"), c("lgCMatrix", "dgCMatrix"), c("lgCMatrix", "lgeMatrix"), c("lgCMatrix", "lgTMatrix"), c("lgCMatrix", "ltCMatrix"), c("lgeMatrix", "dgeMatrix"), c("lgeMatrix", "lgCMatrix"), c("lgeMatrix", "lgTMatrix"), c("lgeMatrix", "lspMatrix"), c("lgeMatrix", "lsyMatrix"), c("lgeMatrix", "ltpMatrix"), c("lgeMatrix", "ltrMatrix"), c("lgTMatrix", "dgTMatrix"), c("lgTMatrix", "lgCMatrix"), c("lgTMatrix", "lgeMatrix"), c("lgTMatrix", "lsCMatrix"), c("lgTMatrix", "ltTMatrix"), c("lMatrix", "dgCMatrix"), c("lsCMatrix", "dsCMatrix"), c("lsCMatrix", "lgCMatrix"), c("lsCMatrix", "lgTMatrix"), c("lsCMatrix", "lsTMatrix"), c("lspMatrix", "dspMatrix"), c("lspMatrix", "lgeMatrix"), c("lspMatrix", "lsyMatrix"), c("lsTMatrix", "lgCMatrix"), c("lsTMatrix", "lgTMatrix"), c("lsTMatrix", "lsCMatrix"), c("lsTMatrix", "lsyMatrix"), c("lsyMatrix", "dsyMatrix"), c("lsyMatrix", "lgeMatrix"), c("lsyMatrix", "lspMatrix"), c("ltCMatrix", "lgCMatrix"), c("ltCMatrix", "ltTMatrix"), c("ltpMatrix", "dtpMatrix"), c("ltpMatrix", "lgeMatrix"), c("ltpMatrix", "ltrMatrix"), c("ltrMatrix", "dtrMatrix"), c("ltrMatrix", "lgeMatrix"), c("ltrMatrix", "ltpMatrix"), c("ltTMatrix", "dtTMatrix"), c("ltTMatrix", "lgCMatrix"), c("ltTMatrix", "lgTMatrix"), c("ltTMatrix", "ltCMatrix"), c("ltTMatrix", "ltrMatrix"), ## c("matrix.coo", "dgCMatrix"), c("matrix.coo", "dgTMatrix"), ## c("matrix.csc", "dgCMatrix"), c("matrix.csr", "dgCMatrix"), ## c("matrix.csr", "dgRMatrix"), ## c("matrix", "dgCMatrix"), c("matrix", "dgeMatrix"), c("matrix", "dgRMatrix"), c("matrix", "dgTMatrix"), c("matrix", "dsCMatrix"), c("matrix", "dspMatrix"), c("matrix", "dsTMatrix"), c("matrix", "dsyMatrix"), c("matrix", "dtCMatrix"), c("matrix", "dtpMatrix"), c("matrix", "dtrMatrix"), c("matrix", "dtTMatrix"), c("matrix", "lgCMatrix"), c("matrix", "lgeMatrix"), c("matrix", "lgTMatrix"), c("matrix", "lsCMatrix"), c("matrix", "lspMatrix"), c("matrix", "lsyMatrix"), c("matrix", "ltCMatrix"), c("matrix", "ltpMatrix"), c("matrix", "ltrMatrix"), c("matrix", "ltTMatrix"), c("matrix", "ngCMatrix"), c("matrix", "ngeMatrix"), c("matrix", "ngTMatrix"), c("matrix", "nspMatrix"), c("matrix", "nsyMatrix"), c("matrix", "ntCMatrix"), c("matrix", "ntpMatrix"), c("matrix", "ntrMatrix"), c("matrix", "ntTMatrix"), c("ngCMatrix", "dgCMatrix"), c("ngCMatrix", "lgCMatrix"), c("ngCMatrix", "ntCMatrix"), c("ngeMatrix", "dgeMatrix"), c("ngeMatrix", "lgeMatrix"), c("ngeMatrix", "ngCMatrix"), c("ngeMatrix", "ngTMatrix"), c("ngeMatrix", "nspMatrix"), c("ngeMatrix", "nsyMatrix"), c("ngeMatrix", "ntpMatrix"), c("ngeMatrix", "ntrMatrix"), c("ngTMatrix", "dgTMatrix"), c("ngTMatrix", "lgeMatrix"), c("ngTMatrix", "lgTMatrix"), c("ngTMatrix", "ngCMatrix"), c("ngTMatrix", "ngeMatrix"), c("ngTMatrix", "ntTMatrix"), c("nsCMatrix", "dsCMatrix"), c("nsCMatrix", "lsCMatrix"), c("nsCMatrix", "ngCMatrix"), c("nsCMatrix", "nsTMatrix"), c("nspMatrix", "dspMatrix"), c("nspMatrix", "lspMatrix"), c("nspMatrix", "ngeMatrix"), c("nspMatrix", "nsyMatrix"), c("nsTMatrix", "dsTMatrix"), c("nsTMatrix", "ngCMatrix"), c("nsTMatrix", "ngTMatrix"), c("nsTMatrix", "nsCMatrix"), c("nsTMatrix", "nsyMatrix"), c("nsyMatrix", "dsyMatrix"), c("nsyMatrix", "lsyMatrix"), c("nsyMatrix", "ngeMatrix"), c("nsyMatrix", "nspMatrix"), c("ntCMatrix", "dtCMatrix"), c("ntCMatrix", "ltCMatrix"), c("ntCMatrix", "ngCMatrix"), c("ntpMatrix", "dtpMatrix"), c("ntpMatrix", "ltpMatrix"), c("ntpMatrix", "ngeMatrix"), c("ntpMatrix", "ntrMatrix"), c("ntrMatrix", "dtrMatrix"), c("ntrMatrix", "ltrMatrix"), c("ntrMatrix", "ngeMatrix"), c("ntrMatrix", "ntpMatrix"), c("ntTMatrix", "dtTMatrix"), c("ntTMatrix", "ngCMatrix"), c("ntTMatrix", "ngTMatrix"), c("ntTMatrix", "ntCMatrix"), c("ntTMatrix", "ntrMatrix"), c("numLike", "dgeMatrix"), c("RsparseMatrix", "dgeMatrix")) .def.template <- function(from) { cd1 <- getClassDef(.FROM) cd2 <- getClassDef(.TO) Matrix.DeprecatedCoerce(cd1, cd2); to <- .CALL if(identical(as.character(class(to)), .TO)) return(to) ## Coercion via virtual generated a _subclass_ of the target class to.strict <- new(.TO) for (nm in slotNames(cd2)) slot(to.strict, nm) <- slot(to, nm) to.strict } for (.f.t in .from.to) { .f <- .f.t[1L] .t <- .f.t[2L] .def <- .def.template .env <- list(.FROM = .f, .TO = .t, .CALL = .as.via.virtual(.f, .t)) body(.def) <- do.call(substitute, list(body(.def), .env)) setAs(.f, .t, .def) } rm(.from.to, .f.t, .f, .t, .def.template, .def, .env) setAs("CHMfactor", "Matrix", function(from) { if(FALSE) { .Deprecated(old = "as(, \"Matrix\")", new = "expand1(., \"L\")", package = "Matrix") } expand1(from, "L") }) setAs("CHMfactor", "dMatrix", function(from) { if(FALSE) { .Deprecated(old = "as(, \"dMatrix\")", new = "expand1(., \"L\")", package = "Matrix") } expand1(from, "L") }) setAs("CHMfactor", "dsparseMatrix", function(from) { if(FALSE) { .Deprecated(old = "as(, \"dsparseMatrix\")", new = "expand1(., \"L\")", package = "Matrix") } expand1(from, "L") }) setAs("CHMfactor", "sparseMatrix", function(from) { if(FALSE) { .Deprecated(old = "as(, \"sparseMatrix\")", new = "expand1(., \"L\")", package = "Matrix") } expand1(from, "L") }) setAs("CHMfactor", "CsparseMatrix", function(from) { if(FALSE) { .Deprecated(old = "as(, \"CsparseMatrix\")", new = "expand1(., \"L\")", package = "Matrix") } expand1(from, "L") }) setAs("CHMfactor", "RsparseMatrix", function(from) { if(FALSE) { .Deprecated(old = "as(, \"RsparseMatrix\")", new = "as(expand1(., \"L\"), \"RsparseMatrix\")", package = "Matrix") } as(expand1(from, "L"), "RsparseMatrix") }) setAs("CHMfactor", "TsparseMatrix", function(from) { if(FALSE) { .Deprecated(old = "as(, \"TsparseMatrix\")", new = "as(expand1(., \"L\"), \"TsparseMatrix\")", package = "Matrix") } as(expand1(from, "L"), "TsparseMatrix") }) setAs("CHMfactor", "triangularMatrix", function(from) { if(FALSE) { .Deprecated(old = "as(, \"triangularMatrix\")", new = "as(expand1(., \"L\"), \"triangularMatrix\")", package = "Matrix") } as(expand1(from, "L"), "triangularMatrix") }) setAs("CHMfactor", "pMatrix", function(from) { if(FALSE) { .Deprecated(old = "as(, \"pMatrix\")", new = "expand1(., \"P1\")", package = "Matrix") } expand1(from, "P1") }) setMethod("chol2inv", signature(x = "CHMfactor"), function(x, ...) { if(FALSE) { .Deprecated(old = "chol2inv()", new = "solve(.)", package = "Matrix") } solve(x) }) ## ~~~~ DEFUNCT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cBind <- function(..., deparse.level = 1) .Defunct(new = "cbind", package = "Matrix") rBind <- function(..., deparse.level = 1) .Defunct(msg = "rbind", package = "Matrix") ��������������������������������������������Matrix/R/indMatrix.R��������������������������������������������������������������������������������0000644�0001762�0000144�00000020143�14535465023�014010� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## METHODS FOR CLASS: indMatrix ## index matrices, i.e., matrices with standard unit vectors ## for all rows _or_ all columns ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .perm2ind <- function(perm, n, margin = 1L, check.p = 0L) { if(mode(perm) != "numeric") stop(gettextf("'%s' is not of type \"%s\" or \"%s\"", "perm", "integer", "double"), domain = NA) else if((m <- length(perm)) == 0L) perm <- integer(0L) else if(anyNA(r <- range(perm))) stop(gettextf("'%s' contains NA", "perm"), domain = NA) else if(r[1L] < 1L) stop(gettextf("'%s' has elements less than %d", "perm", 1L), domain = NA) else if(m > .Machine$integer.max || (is.double(perm) && trunc(r[2L]) > .Machine$integer.max)) stop(gettextf("dimensions cannot exceed %s", "2^31-1"), domain = NA) else { perm <- as.integer(perm); r <- as.integer(r) } if(m.n <- missing(n)) n <- if(m == 0L) 0L else r[2L] else if(mode(n) != "numeric" || length(n) != 1L || is.na(n) || n < 0L) stop(gettextf("'%s' is not a non-negative number", "n"), domain = NA) else if(is.double(n) && trunc(n) > .Machine$integer.max) stop(gettextf("dimensions cannot exceed %s", "2^31-1"), domain = NA) else if(r[2L] > as.integer(n)) stop(gettextf("'%s' has elements exceeding '%s'", "perm", "n"), domain = NA) else n <- as.integer(n) if(mode(margin) != "numeric" || length(margin) != 1L || is.na(margin) || (margin != 1L && margin != 2L)) stop(gettextf("'%s' is not %d or %d", "margin", 1L, 2L), domain = NA) give.p <- check.p >= 1L && m == n && (m == 0L || (all(r == c(1L, m)) && !anyDuplicated.default(perm))) if(check.p >= 2L && !give.p) stop(gettextf("'%s' is not a permutation of seq_len(%s)", "perm", if(m.n) "max(perm, 0)" else "n"), domain = NA) J <- new(if(give.p) "pMatrix" else "indMatrix") nms <- names(perm) if(margin == 1L) { J@Dim <- c(m, n) J@Dimnames = list(nms, if(give.p) nms) } else { J@Dim <- c(n, m) J@Dimnames = list(if(give.p) nms, nms) J@margin <- 2L } J@perm <- perm J } setAs("numeric", "indMatrix", function(from) .perm2ind(from)) ## FIXME: deprecate this method and export more general function .perm2ind setAs("list", "indMatrix", function(from) do.call(.perm2ind, unname(from))) setAs("nsparseMatrix", "indMatrix", function(from) { from <- .M2gen(from) J <- new("indMatrix") J@Dim <- from@Dim J@Dimnames <- from@Dimnames from. <- .M2R(from) p <- from.@p m <- length(p) - 1L if(all(p == 0:m)) { J@perm <- from.@j + 1L return(J) } from. <- .M2C(from) p <- from.@p n <- length(p) - 1L if(all(p == 0:n)) { J@perm <- from.@i + 1L J@margin <- 2L return(J) } stop("matrix must have exactly one entry in each row or column") }) setMethod("band", signature(x = "indMatrix"), function(x, k1, k2, ...) band(.M2kind(x, "n"), k1, k2, ...)) setMethod("triu", signature(x = "indMatrix"), function(x, k = 0L, ...) triu(.M2kind(x, "n"), k, ...)) setMethod("tril", signature(x = "indMatrix"), function(x, k = 0L, ...) tril(.M2kind(x, "n"), k, ...)) setMethod("diag", signature(x = "indMatrix"), function(x, nrow, ncol, names = TRUE) { if((m <- min(x@Dim)) == 0L) return(logical(0L)) i <- seq_len(m) r <- x@perm[i] == i if(names && !any(vapply(dn <- x@Dimnames, is.null, NA)) && identical(nms <- dn[[1L]][i], dn[[2L]][i])) names(r) <- nms r }) setMethod("diag<-", signature(x = "indMatrix"), function(x, value) `diag<-`(.M2kind(x, "n"), value)) setMethod("t", signature(x = "indMatrix"), function(x) { r <- new("indMatrix") r@Dim <- x@Dim[2:1] r@Dimnames = x@Dimnames[2:1] r@perm <- x@perm if(x@margin == 1L) r@margin <- 2L r }) setMethod("forceSymmetric", signature(x = "indMatrix", uplo = "missing"), function(x, uplo) forceSymmetric(.M2kind(x, "n"))) setMethod("forceSymmetric", signature(x = "indMatrix", uplo = "character"), function(x, uplo) forceSymmetric(.M2kind(x, "n"), uplo)) setMethod("symmpart", signature(x = "indMatrix"), function(x) symmpart(.M2kind(x, "d"))) setMethod("skewpart", signature(x = "indMatrix"), function(x) skewpart(.M2kind(x, "d"))) setMethod("isDiagonal", signature(object = "indMatrix"), function(object) { d <- object@Dim if((n <- d[2L]) != d[1L]) return(FALSE) all(object@perm == seq_len(n)) }) setMethod("isTriangular", signature(object = "indMatrix"), function(object, upper = NA, ...) { d <- object@Dim if((n <- d[2L]) != d[1L]) return(FALSE) if(object@margin == 1L) { i <- seq_len(n) j <- object@perm } else { i <- object@perm j <- seq_len(n) } if(is.na(upper)) { if(all(j >= i)) return(`attr<-`(TRUE, "kind", "U")) if(all(i <= j)) return(`attr<-`(TRUE, "kind", "L")) FALSE } else if(upper) { all(j >= i) } else { all(i <= j) } }) setMethod("isSymmetric", signature(object = "indMatrix"), function(object, checkDN = TRUE, ...) { d <- object@Dim if((n <- d[2L]) != d[1L]) return(FALSE) if(checkDN) { ca <- function(check.attributes = TRUE, ...) check.attributes if(ca(...) && !isSymmetricDN(object@Dimnames)) return(FALSE) } perm <- object@perm all(perm[perm] == seq_len(n)) }) ## METHODS FOR CLASS: pMatrix ## permutation matrices, i.e., matrices with standard unit vectors ## for all rows _and_ all columns ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## MJ: could export without dot .changeMargin <- function(x) { x@margin <- if(x@margin == 1L) 2L else 1L x@perm <- invertPerm(x@perm) x } setAs("numeric", "pMatrix", function(from) .perm2ind(from, check.p = 2L)) setAs("nsparseMatrix", "pMatrix", function(from) { d <- from@Dim if((n <- d[1L]) != d[2L]) stop(gettextf("attempt to coerce non-square matrix to %s", "pMatrix"), domain = NA) from <- .M2gen(from) J <- new("pMatrix") J@Dim <- d J@Dimnames <- from@Dimnames from. <- .M2R(from) p <- from.@p m <- length(p) - 1L if(all(p == 0:m) && !anyDuplicated.default(j <- from.@j)) { J@perm <- j + 1L return(J) } from. <- .M2C(from) p <- from.@p n <- length(p) - 1L if(all(p == 0:n) && !anyDuplicated.default(i <- from.@i)) { J@perm <- i + 1L J@margin <- 2L return(J) } stop("matrix must have exactly one entry in each row and column") }) setAs("indMatrix", "pMatrix", function(from) new("pMatrix", from)) setMethod("t", signature(x = "pMatrix"), function(x) { r <- new("pMatrix") r@Dim <- x@Dim r@Dimnames = x@Dimnames[2:1] r@perm <- x@perm if(x@margin == 1L) r@margin <- 2L r }) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/R/sparseVector.R�����������������������������������������������������������������������������0000644�0001762�0000144�00000021403�14534140574�014531� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## METHODS FOR CLASS: sparseVector (virtual) ## sparse vectors ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("diff", signature(x = "sparseVector"), ## Mostly cut and paste of base::diff.default : function(x, lag = 1L, differences = 1L, ...) { if(length(lag) != 1L || length(differences) != 1L || lag < 1L || differences < 1L) stop(gettextf("'%s' and '%s' must be positive integers", "lag", "differences"), domain = NA) if(lag * differences >= length(x)) return(x[0L]) i1 <- -seq_len(lag) for(i in seq_len(differences)) x <- x[i1] - x[-length(x):-(length(x) - lag + 1L)] x }) setMethod("mean", signature(x = "sparseVector"), function(x, trim = 0, na.rm = FALSE, ...) { kind <- .M.kind(x) if(kind == "z" && trim > 0) stop("trimmed means are not defined for complex data") n <- length(x) if(kind != "n" && n > 0L && anyNA(x@x)) { if(!na.rm) return(NA_real_) n <- n - sum(is.na(x@x)) } if(n == 0L) return(if(kind == "z") NaN * 0i else NaN) if(kind == "n") { nnz <- length(x@i) if(trim <= 0) return(nnz / n) ntrim <- trunc(n * min(trim, 0.5)) if(nnz < ntrim) 0 else if(nnz == ntrim) { if(n - 2 * ntrim > 0) 0 else 0.5 } else { if(n - 2 * ntrim > 0) (nnz - ntrim - max(ntrim - (n - nnz), 0)) / (n - 2 * ntrim) else 1 } } else { if(trim <= 0) return(sum(x@x, na.rm = na.rm) / n) ntrim <- trunc(n * min(trim, 0.5)) x <- .V.sort(x, na.last = NA)[(ntrim + 1):(n - ntrim)] sum(x@x) / length(x) } }) .V.rep.each <- function(x, each) { each <- as.double(each) if(length(each) != 1L) { warning(gettextf("first element used of '%s' argument", "each"), domain = NA) each <- each[1L] } if(!is.finite(each) || each <= -1) stop(gettextf("invalid '%s' argument", "each"), domain = NA) if(each < 1) return(x[0L]) if(each < 2) return(x) n <- length(x) each <- trunc(each) if(n * each > 0x1p+53) stop(gettextf("%s length cannot exceed %s", "sparseVector", "2^53"), domain = NA) else if(n * each > .Machine$integer.max) { a <- as.double one <- 1 } else { each <- as.integer(each) a <- as.integer one <- 1L } x@length <- n * each x@i <- rep(each * (a(x@i) - one), each = each) + seq_len(each) if(.M.kind(x) != "n") x@x <- rep(x@x, each = each) x } .V.rep.int <- function(x, times) { times <- as.double(times) if(length(times) != 1L) { ## FIXME: support length(times) == length(x) warning(gettextf("first element used of '%s' argument", "times"), domain = NA) times <- times[1L] } if(!is.finite(times) || times <= -1) stop(gettextf("invalid '%s' argument", "times"), domain = NA) if(times < 1) return(x[0L]) if(times < 2) return(x) n <- length(x) times <- trunc(times) if(n * times > 0x1p+53) stop(gettextf("%s length cannot exceed %s", "sparseVector", "2^53"), domain = NA) else if(n * times > .Machine$integer.max) { a <- as.double zero <- 0 } else { times <- as.integer(times) a <- as.integer zero <- 0L } x@length <- n * times x@i <- rep(a(seq.int(from = zero, by = n, length.out = times)), each = length(x@i)) + x@i if(.M.kind(x) != "n") x@x <- rep.int(x@x, times) x } .V.rep.len <- function(x, length.out) { length.out <- as.double(length.out) if(length(length.out) != 1L) { warning(gettextf("first element used of '%s' argument", "length.out"), domain = NA) length.out <- length.out[1L] } if(!is.finite(length.out) || length.out <= -1) stop(gettextf("invalid '%s' argument", "length.out"), domain = NA) if(length.out > 0x1p+53) stop(gettextf("%s length cannot exceed %s", "sparseVector", "2^53"), domain = NA) n <- length(x) length.out <- if(length.out - 1 < .Machine$integer.max) as.integer(length.out) else trunc(length.out) if(length.out > n && n > 0L) { x <- .V.rep.int(x, ceiling(length.out / n)) n <- length(x) } x@length <- length.out if(length.out < n) { head <- x@i <= length.out x@i <- x@i[head] if(.M.kind(x) != "n") x@x <- x@x[head] } else if(length.out > n && n == 0L) { x@i <- seq_len(length.out) if(.M.kind(x) != "n") x@x <- rep.int(x@x[NA_integer_], length.out) } x } setMethod("rep", signature(x = "sparseVector"), function(x, times, length.out, each, ...) { if(!missing(each)) x <- .V.rep.each(x, each) if(!missing(length.out)) x <- .V.rep.len (x, length.out) else if(!missing(times)) x <- .V.rep.int (x, times) x }) .V.sort <- function(x, decreasing = FALSE, na.last = NA, ...) { nnz <- length(x@i) if(nnz == 0L) return(x) n <- length(x) kind <- .M.kind(x) if(kind == "n") { x@i <- if(decreasing) seq_len(nnz) else seq.int(to = n, length.out = nnz) return(x) } x@x <- y <- sort.int(x@x, na.last = na.last, decreasing = decreasing, ...) if(!is.na(na.last)) nna <- if(anyNA(y)) sum(is.na(y)) else 0L else { x@length <- n <- n - (nnz - length(y)) nna <- 0L nnz <- length(y) } nnn <- switch(kind, "l" = nnz - nna, "i" = sum(y >= 0L, na.rm = TRUE), "d" = sum(y >= 0 , na.rm = TRUE), "z" = { arg <- Arg(y) hpi <- 0.5 * pi sum(arg > -hpi & arg <= hpi, na.rm = TRUE) }, stop("should never happen ...")) if(nna > 0L && decreasing != na.last) nnn <- nnn + nna x@i <- if(nnn < nnz) { if(decreasing) c(seq_len(nnn), seq.int(to = n, length.out = nnz - nnn)) else c(seq_len(nnz - nnn), seq.int(to = n, length.out = nnn)) } else { if(decreasing) seq_len(nnn) else seq.int(to = n, length.out = nnn) } x } if(FALSE) { ## MJ: once 'sort' becomes implicit generic in package 'methods' : setMethod("sort", signature(x = "sparseVector"), .V.sort) ## TODO: parallel method for internal generic 'xtfrm' } setMethod("t", signature(x = "sparseVector"), function(x) .tCRT(.V2C(x))) setMethod("toeplitz", signature(x = "sparseVector"), function(x, symmetric = TRUE, repr = c("C", "R", "T"), giveCsparse, ...) { n <- length(x) if(n > .Machine$integer.max) stop(gettextf("dimensions cannot exceed %s", "2^31-1"), domain = NA) nn <- c(n, n) r <- spV2M(x[as.integer(abs(.col(nn) - .row(nn))) + 1L], nrow = n, ncol = n, symmetric = symmetric, check = FALSE) repr <- # keep in sync with sparseMatrix if(missing(giveCsparse)) match.arg(repr) else if(!missing(repr)) { warning(gettextf("'%s' is deprecated; using '%s' instead", "giveCsparse", "repr"), domain = NA) match.arg(repr) } else if(giveCsparse) { "C" } else { warning(gettextf("'%s' is deprecated; setting %s=\"%s\"", "giveCsparse", "repr", "T"), domain = NA) "T" } switch(repr, "C" = .M2C(r), "R" = .M2R(r), "T" = r) }) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/R/posdef.R�����������������������������������������������������������������������������������0000644�0001762�0000144�00000012434�14503364553�013336� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## METHODS FOR CLASS: dpoMatrix, dppMatrix ## dense symmetric positive semidefinite matrices ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## Operations such as rounding can lose positive semidefiniteness ## but not symmetry, hence: .indefinite <- function(x) { cl <- .M.nonvirtual(x, TRUE) if(any(cl == c("dpoMatrix", "corMatrix"))) as(x, "dsyMatrix") else if(any(cl == c("dppMatrix", "pcorMatrix"))) as(x, "dspMatrix") else x } .dsy2dpo <- .dsp2dpp <- function(from) { if(is.null(tryCatch(Cholesky(from, perm = FALSE), error = function(e) NULL))) stop("not a positive definite matrix (and positive semidefiniteness is not checked)") to <- new(.CLASS) to@Dim <- from@Dim to@Dimnames <- from@Dimnames to@uplo <- from@uplo to@x <- from@x to@factors <- from@factors to } body(.dsy2dpo)[[3L]][[3L]][[2L]] <- "dpoMatrix" body(.dsp2dpp)[[3L]][[3L]][[2L]] <- "dppMatrix" setAs("dppMatrix", "dpoMatrix", function(from) unpack(from)) setAs("dpoMatrix", "dppMatrix", function(from) pack(from)) setAs("dsyMatrix", "dpoMatrix", .dsy2dpo) setAs("dspMatrix", "dppMatrix", .dsp2dpp) setAs("Matrix", "dpoMatrix", function(from) .dsy2dpo(.M2unpacked(.M2sym(.M2kind(from, "d"))))) setAs("Matrix", "dppMatrix", function(from) .dsp2dpp(.M2packed (.M2sym(.M2kind(from, "d"))))) setAs("matrix", "dpoMatrix", function(from) { storage.mode(from) <- "double" .dsy2dpo(.M2sym(from)) }) setAs("matrix", "dppMatrix", function(from) { storage.mode(from) <- "double" .dsp2dpp(pack(from, symmetric = TRUE)) }) ## METHODS FOR CLASS: corMatrix, pcorMatrix ## dense correlation matrices ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .dpo2cor <- function(from) { if(!is.null(to <- from@factors$correlation)) return(to) sd <- sqrt(diag(from, names = FALSE)) to <- new("corMatrix") to@Dim <- d <- from@Dim to@Dimnames <- from@Dimnames to@uplo <- from@uplo to@sd <- sd n <- d[1L] x <- from@x / sd / rep(sd, each = n) x[indDiag(n)] <- 1 to@x <- x .set.factor(from, "correlation", to) } .dpp2pcor <- function(from) { if(!is.null(to <- from@factors$correlation)) return(to) sd <- sqrt(diag(from, names = FALSE)) to <- new("pcorMatrix") to@Dim <- d <- from@Dim to@Dimnames <- from@Dimnames to@uplo <- uplo <- from@uplo to@sd <- sd n <- d[1L] u <- uplo == "U" if(u) { r <- seq_len(n) s <- 1L } else { r <- seq.int(to = 1L, by = -1L, length.out = n) s <- seq_len(n) } x <- from@x / rep.int(sd, r) / sd[sequence.default(r, s)] x[indDiag(n, upper = u, packed = TRUE)] <- 1 to@x <- x .set.factor(from, "correlation", to) } setAs("pcorMatrix", "corMatrix", function(from) unpack(from)) setAs( "corMatrix", "pcorMatrix", function(from) pack(from)) setAs("dpoMatrix", "corMatrix", .dpo2cor) setAs("dppMatrix", "pcorMatrix", .dpp2pcor) setAs("dsyMatrix", "corMatrix", function(from) .dpo2cor (.dsy2dpo(from))) setAs("dspMatrix", "pcorMatrix", function(from) .dpp2pcor(.dsp2dpp(from))) setAs("Matrix", "corMatrix", function(from) .dpo2cor (.dsy2dpo(.M2unpacked(.M2sym(.M2kind(from, "d")))))) setAs("Matrix", "pcorMatrix", function(from) .dpp2pcor(.dsp2dpp(.M2packed (.M2sym(.M2kind(from, "d")))))) setAs("matrix", "corMatrix", function(from) { storage.mode(from) <- "double" .dpo2cor (.dsy2dpo(.M2sym(from))) }) setAs("matrix", "pcorMatrix", function(from) { storage.mode(from) <- "double" .dpp2pcor(.dsp2dpp(pack(from, symmetric = TRUE))) }) ## METHODS FOR GENERIC: cov2cor ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("cov2cor", signature(V = "unpackedMatrix"), function(V) { d <- V@Dim if(d[1L] != d[2L] || .M.kind(V) == "z") stop(gettextf("'%s' is not a square numeric matrix", "V"), domain = NA) as(forceSymmetric(V), "corMatrix") }) setMethod("cov2cor", signature(V = "packedMatrix"), function(V) { d <- V@Dim if(d[1L] != d[2L] || .M.kind(V) == "z") stop(gettextf("'%s' is not a square numeric matrix", "V"), domain = NA) as(forceSymmetric(V), "pcorMatrix") }) setMethod("cov2cor", signature(V = "sparseMatrix"), function(V) { d <- V@Dim if(d[1L] != d[2L] || .M.kind(V) == "z") stop(gettextf("'%s' is not a square numeric matrix", "V"), domain = NA) dn <- symDN(V@Dimnames) V <- .M2kind(V, "d") V.ii <- diag(V, names = FALSE) if(length(V.ii) > 0L && is.na(m <- min(V.ii)) || m <= 0) warning(gettextf("diag(%s) has non-positive or non-finite entries; finite result is doubtful", "V"), domain = NA) D <- Diagonal(x = sqrt(1/V.ii)) r <- forceSymmetric(D %*% V %*% D) diag(r) <- 1 r@Dimnames <- dn r }) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/R/subassign.R��������������������������������������������������������������������������������0000644�0001762�0000144�00000173563�14542726437�014075� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## METHODS FOR GENERIC: [<- ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## GOAL: automate method definitions and eventually replace the ones ## collected below ... ## ## need to write C-level functions ## ## *_subassign_1ary (x, i, value) ## *_subassign_1ary_mat(x, i, value) ## *_subassign_2ary (x, i, j, value) ## ## for * = unpackedMatrix,packedMatrix, ## CsparseMatrix,RsparseMatrix,TsparseMatrix, ## diagonalMatrix,indMatrix if(FALSE) { # TODO .subassign.invalid <- function(value) { if(is.object(i)) gettextf("invalid subassignment value class \"%s\"", class(i)[1L]) else gettextf("invalid subassignment value type \"%s\"", typeof(i)) } .subassign.1ary <- function(x, i, value) { } ..subassign.1ary <- function(x, i, value) { } .subassign.1ary.mat <- function(x, i, value) { } ..subassign.1ary.mat <- function(x, i, value) { } .subassign.2ary <- function(x, i, j, value) { } ..subassign.2ary <- function(x, i, j, value) { } setMethod("[<-", signature(x = "Matrix", i = "missing", j = "missing", value = "ANY"), function(x, i, j, ..., value) { if(missing(value)) stop("missing subassignment value") na <- nargs() if(na <= 4L) ## x[], x[, ] <- value .subassign.1ary(x, , value) else ## x[, , ], etc. <- value stop("incorrect number of dimensions") }) setMethod("[<-", signature(x = "Matrix", i = "index", j = "missing", value = "ANY"), function(x, i, j, ..., value) { if(missing(value)) stop("missing subassignment value") na <- nargs() if(na == 3L) ## x[i=] <- value .subassign.1ary(x, i, value) else if(na == 4L) ## x[i=, ], x[, i=] <- value .subassign.2ary(x, i, , value) else ## x[i=, , ], etc. <- value stop("incorrect number of dimensions") }) setMethod("[<-", signature(x = "Matrix", i = "missing", j = "index", value = "ANY"), function(x, i, j, ..., value) { if(missing(value)) stop("missing subassignment value") na <- nargs() if(na == 3L) ## x[j=] <- value .subassign.1ary(x, j, value) else if(na == 4L) ## x[j=, ], x[, j=] <- value .subassign.2ary(x, , j, value) else ## x[, j=, ], etc. <- value stop("incorrect number of dimensions") }) setMethod("[<-", signature(x = "Matrix", i = "index", j = "index", value = "ANY"), function(x, i, j, ..., value) { if(missing(value)) stop("missing subassignment value") na <- nargs() if(na == 4L) ## x[i=, j=], x[j=, i=] <- value .subassign.2ary(x, i, j, value) else ## x[i=, j=, ], etc. <- value stop("incorrect number of dimensions") }) for(.cl in c("matrix", "nMatrix", "lMatrix")) setMethod("[<-", signature(x = "Matrix", i = .cl, j = "missing", value = "ANY"), function(x, i, j, ..., value) { if(missing(value)) stop("missing subassignment value") na <- nargs() if(na == 3L) ## x[i=] <- value .subassign.1ary.mat(x, i, value) else if(na == 4L) ## x[i=, ], x[, i=] <- value .subassign.2ary(x, i, , value) else ## x[i=, , ], etc. <- value stop("incorrect number of dimensions") }) rm(.cl) setMethod("[<-", signature(x = "Matrix", i = "NULL", j = "ANY", value = "ANY"), function(x, i, j, ..., value) { i <- integer(0L) callGeneric() }) setMethod("[<-", signature(x = "Matrix", i = "ANY", j = "NULL", value = "ANY"), function(x, i, j, ..., value) { j <- integer(0L) callGeneric() }) setMethod("[<-", signature(x = "Matrix", i = "NULL", j = "NULL", value = "ANY"), function(x, i, j, ..., value) { i <- integer(0L) j <- integer(0L) callGeneric() }) setMethod("[<-", signature(x = "sparseVector", i = "missing", j = "missing", value = "ANY"), function(x, i, j, ..., value) { if(missing(value)) stop("missing subassignment value") if(nargs() > 3L) stop("incorrect number of dimensions") if(isS4(value)) { if(!.isVector(value)) stop(.subassign.invalid(value), domain = NA) } else value <- switch(typeof(value), "logical" =, "integer" =, "double" =, "complex" = .m2V(value), stop(.subassign.invalid(value), domain = NA)) n.x <- length(x) n.value <- length(value) if(n.x > 0L && n.value == 0L) stop("replacement has length zero") k.x <- .M2kind(x) k.value <- .M2kind(value) if(k.x != k.value) { map <- `names<-`(1:5, c("n", "l", "i", "d", "z")) if(map[[k.value]] < map[[k.x]]) value <- .V2kind(value, k.x) } if(n.value == 0L) return(value) if(n.x %% n.value != 0L) warning("number of items to replace is not a multiple of replacement length") .V.rep.len(value, n.x) }) setMethod("[<-", signature(x = "sparseVector", i = "index", j = "missing", value = "ANY"), function(x, i, j, ..., value) { if(missing(value)) stop("missing subassignment value") if(nargs() > 3L) stop("incorrect number of dimensions") if(isS4(value)) { if(!.isVector(value)) stop(.subassign.invalid(value), domain = NA) } else value <- switch(typeof(value), "logical" =, "integer" =, "double" =, "complex" = .m2V(value), stop(.subassign.invalid(value), domain = NA)) switch(typeof(i), "logical" = {}, "integer" = {}, "double" = {}, stop(.subscript.invalid(value), domain = NA)) k.x <- .M2kind(x) k.value <- .M2kind(value) if(k.x != k.value) { map <- `names<-`(1:5, c("n", "l", "i", "d", "z")) if(map[[k.x]] < map[[k.value]]) x <- .V2kind(x, k.value) } ## TODO }) setMethod("[<-", signature(x = "sparseVector", i = "nsparseVector", j = "missing", value = "ANY"), function(x, i, j, ..., drop = TRUE) { if(missing(value)) stop("missing subassignment value") if(nargs() > 3L) stop("incorrect number of dimensions") x[.subscript.recycle(i, length(x), TRUE)] <- value x }) setMethod("[<-", signature(x = "sparseVector", i = "lsparseVector", j = "missing", value = "ANY"), function(x, i, j, ..., drop = TRUE) { if(missing(value)) stop("missing subassignment value") if(nargs() > 3L) stop("incorrect number of dimensions") x[.subscript.recycle(i, length(x), FALSE)] <- value x }) setMethod("[<-", signature(x = "sparseVector", i = "NULL", j = "ANY", value = "ANY"), function(x, i, j, ..., value) { i <- integer(0L) callGeneric() }) } # TODO ## ==== Matrix ========================================================= ## A[ ij ] <- value, where ij is (i,j) 2-column matrix : ## ---------------- ## The cheap general method, now only used for "pMatrix","indMatrix" ## sparse all use .TM.repl.i.mat() ## NOTE: need '...' below such that setMethod() does ## not use .local() such that nargs() will work correctly: .M.repl.i.2col <- function (x, i, j, ..., value) { nA <- nargs() if(nA == 3) { ## M [ cbind(ii,jj) ] <- value or M [ Lmat ] <- value if(!is.integer(nc <- ncol(i))) stop(".M.repl.i.2col(): 'i' has no integer column number;\n should never happen; please report") else if(!is.numeric(i) || nc != 2) stop("such indexing must be by logical or 2-column numeric matrix") if(is.logical(i)) { message(".M.repl.i.2col(): drop 'matrix' case ...") ## c(i) : drop "matrix" to logical vector return( callGeneric(x, i=c(i), value=value) ) } if(!is.integer(i)) storage.mode(i) <- "integer" if(any(i < 0)) stop("negative values are not allowed in a matrix subscript") if(anyNA(i)) stop("NAs are not allowed in subscripted assignments") if(any(i0 <- (i == 0))) # remove them i <- i[ - which(i0, arr.ind = TRUE)[,"row"], ] ## now have integer i >= 1 m <- nrow(i) ## mod.x <- .type.kind[.M.kind(x)] if(length(value) > 0 && m %% length(value) != 0) warning("number of items to replace is not a multiple of replacement length") ## recycle: value <- rep_len(value, m) i1 <- i[,1] i2 <- i[,2] if(m > 2) message("m[ ] <- v: inefficiently treating single elements") ## inefficient -- FIXME -- (also loses "symmetry" unnecessarily) for(k in seq_len(m)) x[i1[k], i2[k]] <- value[k] x } else stop(gettextf("nargs() = %d. Extraneous illegal arguments inside '[ .. ]' ?", nA), domain = NA) } setReplaceMethod("[", signature(x = "Matrix", i = "matrix", j = "missing", value = "replValue"), .M.repl.i.2col) ## Three catch-all methods ... would be very inefficient for sparse* ## --> extra methods in ./sparseMatrix.R setReplaceMethod("[", signature(x = "Matrix", i = "missing", j = "ANY", value = "Matrix"), function(x, i, j, ..., value) callGeneric(x=x, , j=j, value = as.vector(value))) setReplaceMethod("[", signature(x = "Matrix", i = "ANY", j = "missing", value = "Matrix"), function(x, i, j, ..., value) if(nargs() == 3) callGeneric(x=x, i=i, value = as.vector(value)) else callGeneric(x=x, i=i, , value = as.vector(value))) setReplaceMethod("[", signature(x = "Matrix", i = "ANY", j = "ANY", value = "Matrix"), function(x, i, j, ..., value) callGeneric(x=x, i=i, j=j, value = as.vector(value))) setReplaceMethod("[", signature(x = "Matrix", i = "missing", j = "ANY", value = "matrix"), function(x, i, j, ..., value) callGeneric(x=x, , j=j, value = c(value))) setReplaceMethod("[", signature(x = "Matrix", i = "ANY", j = "missing", value = "matrix"), function(x, i, j, ..., value) if(nargs() == 3) callGeneric(x=x, i=i, value = c(value)) else callGeneric(x=x, i=i, , value = c(value))) setReplaceMethod("[", signature(x = "Matrix", i = "ANY", j = "ANY", value = "matrix"), function(x, i, j, value) callGeneric(x=x, i=i, j=j, value = c(value))) ## M [ ] <- value; used notably for x = "CsparseMatrix" .repl.i.lDMat <- function (x, i, j, ..., value) `[<-`(x, i=which(as.vector(i)), value=value) setReplaceMethod("[", signature(x = "Matrix", i = "ldenseMatrix", j = "missing", value = "replValue"), .repl.i.lDMat) setReplaceMethod("[", signature(x = "Matrix", i = "ndenseMatrix", j = "missing", value = "replValue"), .repl.i.lDMat) rm(.repl.i.lDMat) .repl.i.lSMat <- function (x, i, j, ..., value) `[<-`(x, i=which(as(i, "sparseVector")), value=value) setReplaceMethod("[", signature(x = "Matrix", i = "lsparseMatrix", j = "missing", value = "replValue"), .repl.i.lSMat) setReplaceMethod("[", signature(x = "Matrix", i = "nsparseMatrix", j = "missing", value = "replValue"), .repl.i.lSMat) rm(.repl.i.lSMat) ## (ANY,ANY,ANY) is used when no `real method' is implemented : setReplaceMethod("[", signature(x = "Matrix", i = "ANY", j = "ANY", value = "ANY"), function (x, i, j, value) { if(!is.atomic(value)) stop(gettextf("RHS 'value' (class %s) matches 'ANY', but must match matrix class %s", class(value), class(x)), domain = NA) else stop("not-yet-implemented 'Matrix[<-' method") }) ## ==== denseMatrix ==================================================== ## x[] <- value : setReplaceMethod("[", signature(x = "denseMatrix", i = "missing", j = "missing", value = "ANY"),## double/logical/... function (x, value) { x <- .M2gen(x) x@x[] <- value validObject(x)# check if type and lengths above match x }) ## FIXME: 1) These are far from efficient ## ----- setReplaceMethod("[", signature(x = "denseMatrix", i = "index", j = "missing", value = "replValue"), function (x, i, j, ..., value) { r <- as(x, "matrix") ## message("`[<-` with nargs()= ",nargs()) if((na <- nargs()) == 3) r[i] <- value else if(na == 4) r[i, ] <- value else stop(gettextf("invalid nargs()= %d", na), domain=NA) .m2dense(r, paste0(.M.kind(x), "ge")) }) setReplaceMethod("[", signature(x = "denseMatrix", i = "missing", j = "index", value = "replValue"), function (x, i, j, ..., value) { r <- as(x, "matrix") r[, j] <- value .m2dense(r, paste0(.M.kind(x), "ge")) }) setReplaceMethod("[", signature(x = "denseMatrix", i = "index", j = "index", value = "replValue"), function (x, i, j, ..., value) { r <- as(x, "matrix") r[i, j] <- value as_denseClass(r, class(x)) ## was as(r, class(x)) }) setReplaceMethod("[", signature(x = "denseMatrix", i = "matrix", # 2-col.matrix j = "missing", value = "replValue"), function(x, i, j, ..., value) { r <- as(x, "matrix") r[ i ] <- value .m2dense(r, paste0(.M.kind(x), "ge")) }) ## ==== sparseMatrix =================================================== ## x[] <- value : setReplaceMethod("[", signature(x = "sparseMatrix", i = "missing", j = "missing", value = "ANY"),## double/logical/... function (x, i, j,..., value) { if(all0(value)) { # be faster cld <- getClassDef(class(x)) x <- diagU2N(x, cl = cld) for(nm in intersect(nsl <- names(cld@slots), c("x", "i","j", "factors"))) length(slot(x, nm)) <- 0L if("p" %in% nsl) x@p <- rep.int(0L, ncol(x)+1L) } else { ## typically non-sense: assigning to full sparseMatrix x[TRUE] <- value } x }) ## Do not use as.vector() (see ./Matrix.R ) for sparse matrices : setReplaceMethod("[", signature(x = "sparseMatrix", i = "missing", j = "ANY", value = "sparseMatrix"), function (x, i, j, ..., value) callGeneric(x=x, , j=j, value=as(value, "sparseVector"))) setReplaceMethod("[", signature(x = "sparseMatrix", i = "ANY", j = "missing", value = "sparseMatrix"), function (x, i, j, ..., value) if(nargs() == 3) callGeneric(x=x, i=i, value=as(value, "sparseVector")) else callGeneric(x=x, i=i, , value=as(value, "sparseVector"))) setReplaceMethod("[", signature(x = "sparseMatrix", i = "ANY", j = "ANY", value = "sparseMatrix"), function (x, i, j, ..., value) callGeneric(x=x, i=i, j=j, value=as(value, "sparseVector"))) ## ==== CsparseMatrix ================================================== ## workhorse for "[<-" -- for d*, l*, and n..C-sparse matrices : ## --------- ----- replCmat <- function (x, i, j, ..., value) { di <- dim(x) dn <- dimnames(x) iMi <- missing(i) jMi <- missing(j) na <- nargs() Matrix.message("replCmat[x,i,j,..,val] : nargs()=", na, "; ", if(iMi || jMi) sprintf("missing (i,j) = (%d,%d)", iMi, jMi), .M.level = 2) if(na == 3L) { ## vector (or 2-col) indexing M[i] <- v : includes M[TRUE] <- v or M[] <- v ! x <- .M2T(x) x[i] <- value # may change class, e.g., from dtT* to dgT* cl.C <- sub(".Matrix$", "CMatrix", class(x)) if(.hasSlot(x, "x") && any0(x@x)) ## drop all values that "happen to be 0" drop0(x, is.Csparse = FALSE) else as_CspClass(x, cl.C) } else ## nargs() == 4 : replCmat4(x, i1 = if(iMi) seq.int(from = 0L, length.out = di[1L]) else .ind.prep2(i, 1L, di, dn), i2 = if(jMi) seq.int(from = 0L, length.out = di[2L]) else .ind.prep2(j, 2L, di, dn), iMi = iMi, jMi = jMi, value = value) } ## replCmat replCmat4 <- function(x, i1, i2, iMi, jMi, value, spV = is(value, "sparseVector")) { dind <- c(length(i1), length(i2)) # dimension of replacement region lenRepl <- prod(dind) lenV <- length(value) if(lenV == 0) { if(lenRepl != 0L) stop("nothing to replace with") return(x) } ## else: lenV := length(value) is > 0 if(lenRepl %% lenV != 0L) stop("number of items to replace is not a multiple of replacement length") if(lenV > lenRepl) stop("too many replacement values") clx <- class(x) clDx <- getClassDef(clx) # extends() , is() etc all use the class definition ## keep "symmetry" if changed here: x.sym <- extends(clDx, "symmetricMatrix") if(x.sym) { ## only half the indices are there.. ## using array() for large dind is a disaster... mkArray <- if(spV) # TODO: room for improvement function(v, dim) spV2M(v, dim[1L], dim[2L]) else array x.sym <- (dind[1L] == dind[2L] && all(i1 == i2) && (lenRepl == 1L || lenV == 1L || isSymmetric(mkArray(value, dim=dind)))) ## x.sym : result is *still* symmetric x <- .M2gen(x) ## but do *not* redefine clx! } else if(extends(clDx, "triangularMatrix")) { xU <- x@uplo == "U" r.tri <- ((any(dind == 1) || dind[1L] == dind[2L]) && if(xU) max(i1) <= min(i2) else max(i2) <= min(i1)) if(r.tri) { ## result is *still* triangular if(any(i1 == i2)) # diagonal will be changed x <- diagU2N(x) # keeps class (!) } else { # go to "generalMatrix" and (do not redefine clx!) and continue x <- .M2gen(x) # was as(x, paste0(.M.kind(x), "gCMatrix")) } } ## Temporary hack for debugging --- remove eventually -- FIXME : ## see also MATRIX_SUBASSIGN_VERBOSE in ../src/t_Csparse_subassign.c if(!is.null(v <- getOption("Matrix.subassign.verbose")) && v) { op <- options(Matrix.verbose = 2); on.exit(options(op)) ## the "hack" to signal "verbose" to the C code: if(i1[1L] != 0L) i1[1L] <- -i1[1L] else warning("i1[1] == 0 ==> C-level verbosity will not happen!") } if(extends(clDx, "dMatrix")) { has.x <- TRUE x <- .Call(dCsparse_subassign, if(clx %in% c("dgCMatrix", "dtCMatrix")) x else .M2gen(x), # must get "dgCMatrix" i1, i2, as(value, "sparseVector")) } else if(extends(clDx, "lMatrix")) { has.x <- TRUE x <- .Call(lCsparse_subassign, if(clx %in% c("lgCMatrix", "ltCMatrix")) x else .M2gen(x), # must get "lgCMatrix" i1, i2, as(value, "sparseVector")) } else if(extends(clDx, "nMatrix")) { has.x <- FALSE x <- .Call(nCsparse_subassign, if(clx %in% c("ngCMatrix", "ntCMatrix"))x else .M2gen(x), # must get "ngCMatrix" i1, i2, as(value, "sparseVector")) } else if(extends(clDx, "iMatrix")) { has.x <- TRUE x <- .Call(iCsparse_subassign, if(clx %in% c("igCMatrix", "itCMatrix"))x else .M2gen(x), # must get "igCMatrix" i1, i2, as(value, "sparseVector")) } else if(extends(clDx, "zMatrix")) { has.x <- TRUE x <- .Call(zCsparse_subassign, if(clx %in% c("zgCMatrix", "ztCMatrix"))x else .M2gen(x), # must get "zgCMatrix" i1, i2, ## here we only want zsparseVector {to not have to do this in C}: as(value, "zsparseVector")) } else { ## use "old" code ... ## does this happen ? ==> if(identical(Sys.getenv("USER"),"maechler"))## does it still happen? __ FIXME __ stop("using \"old code\" part in Csparse subassignment") ## else warning("using\"old code\" part in Csparse subassignment\n >>> please report to Matrix-authors@r-project.org", immediate. = TRUE) xj <- .Call(Matrix_expand_pointers, x@p) sel <- (!is.na(match(x@i, i1)) & !is.na(match( xj, i2))) has.x <- "x" %in% slotNames(clDx)# === slotNames(x), ## has.x <==> *not* nonzero-pattern == "nMatrix" if(has.x && sum(sel) == lenRepl) { ## all entries to be replaced are non-zero: ## need indices instead of just 'sel', for, e.g., A[2:1, 2:1] <- v non0 <- cbind(match(x@i[sel], i1), match(xj [sel], i2), deparse.level=0L) iN0 <- 1L + .Call(m_encodeInd, non0, di = dind, orig1=TRUE, checkBounds=FALSE) has0 <- if(spV) length(value@i) < lenV else any(value[!is.na(value)] == 0) if(lenV < lenRepl) value <- rep_len(value, lenRepl) ## Ideally we only replace them where value != 0 and drop the value==0 ## ones; FIXME: see Davis(2006) "2.7 Removing entries", p.16, e.g. use cs_dropzeros() ## but really could be faster and write something like cs_drop_k(A, k) ## v0 <- 0 == value ## if (lenRepl == 1) and v0 is TRUE, the following is not doing anything ##- --> ./Tsparse.R and its replTmat() ## x@x[sel[!v0]] <- value[!v0] x@x[sel] <- as.vector(value[iN0]) if(extends(clDx, "compMatrix") && length(x@factors)) # drop cached ones x@factors <- list() if(has0) x <- .drop0(x) return(if(x.sym) as_CspClass(x, clx) else x) } ## else go via Tsparse.. {FIXME: a waste! - we already have 'xj' ..} ## and inside Tsparse... the above i1, i2,..., sel are *all* redone! ## Happens too often {not anymore, I hope!} ## Matrix.message("wasteful C -> T -> C in replCmat(x,i,j,v) for [i,j] <- v") x <- as(x, "TsparseMatrix") if(iMi) x[ ,i2+1L] <- value else if(jMi) x[i1+1L, ] <- value else x[i1+1L,i2+1L] <- value if(extends(clDx, "compMatrix") && length(x@factors)) # drop cached ones x@factors <- list() }# else{ not using new memory-sparse code if(has.x && any0(x@x)) ## drop all values that "happen to be 0" as_CspClass(drop0(x), clx) else as_CspClass(x, clx) } ## replCmat4 setReplaceMethod("[", signature(x = "CsparseMatrix", i = "index", j = "missing", value = "replValue"), replCmat) setReplaceMethod("[", signature(x = "CsparseMatrix", i = "missing", j = "index", value = "replValue"), replCmat) setReplaceMethod("[", signature(x = "CsparseMatrix", i = "index", j = "index", value = "replValue"), replCmat) ### When the RHS 'value' is a sparseVector, now can use replCmat as well setReplaceMethod("[", signature(x = "CsparseMatrix", i = "missing", j = "index", value = "sparseVector"), replCmat) setReplaceMethod("[", signature(x = "CsparseMatrix", i = "index", j = "missing", value = "sparseVector"), replCmat) setReplaceMethod("[", signature(x = "CsparseMatrix", i = "index", j = "index", value = "sparseVector"), replCmat) rm(replCmat) ## A[ ij ] <- value, where ij is (i,j) 2-column matrix setReplaceMethod("[", signature(x = "CsparseMatrix", i = "matrix", j = "missing", value = "replValue"), function(x, i, j, ..., value) ## goto Tsparse modify and convert back: as(.TM.repl.i.mat(as(x, "TsparseMatrix"), i=i, value=value), "CsparseMatrix")) ## more in ./sparseMatrix.R (and ./Matrix.R ) setReplaceMethod("[", signature(x = "CsparseMatrix", i = "Matrix", j = "missing", value = "replValue"), function(x, i, j, ..., value) ## goto Tsparse modify and convert back: as(.TM.repl.i.mat(as(x, "TsparseMatrix"), i=i, value=value), "CsparseMatrix")) ## ==== RsparseMatrix ================================================== setReplaceMethod("[", signature(x = "RsparseMatrix", i = "index", j = "missing", value = "replValue"), function (x, i, j, ..., value) replTmat(.M2T(x), i=i, , value=value)) setReplaceMethod("[", signature(x = "RsparseMatrix", i = "missing", j = "index", value = "replValue"), function (x, i, j, ..., value)# extra " , ": want nargs() == 4 replTmat(.M2T(x), , j=j, value=value)) setReplaceMethod("[", signature(x = "RsparseMatrix", i = "index", j = "index", value = "replValue"), function (x, i, j, ..., value) replTmat(.M2T(x), i=i, j=j, value=value)) setReplaceMethod("[", signature(x = "RsparseMatrix", i = "index", j = "missing", value = "sparseVector"), function (x, i, j, ..., value) { if(nargs() == 3L) replTmat(.M2T(x), i=i, value=value) # x[i] <- v else replTmat(.M2T(x), i=i, , value=value) # x[i, ] <- v }) setReplaceMethod("[", signature(x = "RsparseMatrix", i = "missing", j = "index", value = "sparseVector"), function (x, i, j, ..., value)# extra " , ": want nargs() == 4 replTmat(.M2T(x), , j=j, value=value)) setReplaceMethod("[", signature(x = "RsparseMatrix", i = "index", j = "index", value = "sparseVector"), function (x, i, j, ..., value) replTmat(.M2T(x), i=i, j=j, value=value)) setReplaceMethod("[", signature(x = "RsparseMatrix", i = "matrix", j = "missing", value = "replValue"), function (x, i, j, ..., value) { if(nargs() == 3L) .TM.repl.i.mat(.M2T(x), i=i, value=value) else replTmat(.M2T(x), i=as.vector(i), , value=value) }) ## ==== TsparseMatrix ================================================== ##' a simplified "subset" of intI() below int2i <- function(i, n) { if(any(i < 0L)) { if(any(i > 0L)) stop("you cannot mix negative and positive indices") seq_len(n)[i] } else { if(length(i) && max(i, na.rm=TRUE) > n) stop(gettextf("index larger than maximal %d", n), domain=NA) if(any(z <- i == 0)) i <- i[!z] i } } intI <- function(i, n, dn, give.dn = TRUE) { ## Purpose: translate numeric | logical | character index ## into 0-based integer ## ---------------------------------------------------------------------- ## Arguments: i: index vector (numeric | logical | character) ## n: array extent { == dim(.) [margin] } ## dn: character col/rownames or NULL { == dimnames(.)[[margin]] } ## ---------------------------------------------------------------------- ## Author: Martin Maechler, Date: 23 Apr 2007 has.dn <- !is.null.DN(dn) DN <- has.dn && give.dn if(is.numeric(i) || is(i, "numeric")) { # inherits(, "numeric") is FALSE storage.mode(i) <- "integer" if(anyNA(i)) stop("'NA' indices are not (yet?) supported for sparse Matrices") if(any(i < 0L)) { if(any(i > 0L)) stop("you cannot mix negative and positive indices") i0 <- (0:(n - 1L))[i] } else { if(length(i) && max(i, na.rm=TRUE) > n) # base has "subscript out of bounds": stop(gettextf("index larger than maximal %d", n), domain=NA) if(any(z <- i == 0)) i <- i[!z] i0 <- i - 1L # transform to 0-indexing } if(DN) dn <- dn[i] } else if (is.logical(i) || inherits(i, "logical")) { if(length(i) > n) stop(gettextf("logical subscript too long (%d, should be %d)", length(i), n), domain=NA) if(anyNA(i)) stop("'NA' indices are not (yet?) supported for sparse Matrices") i0 <- (0:(n - 1L))[i] if(DN) dn <- dn[i] } else { ## character if(!has.dn) stop("no 'dimnames[[.]]': cannot use character indexing") i0 <- match(i, dn) if(anyNA(i0)) stop("invalid character indexing") if(DN) dn <- dn[i0] i0 <- i0 - 1L } if(!give.dn) i0 else list(i0 = i0, dn = dn) } ## {intI} .ind.prep <- function(xi, intIlist, iDup = duplicated(i0), anyDup = any(iDup)) { ## Purpose: do the ``common things'' for "*gTMatrix" indexing for 1 dim. ## and return match(.,.) + li = length of corresponding dimension ## ## xi = "x@i" ; intIlist = intI(i, dim(x)[margin], ....) i0 <- intIlist$i0 stopifnot(is.numeric(i0))# cheap fast check (i0 may have length 0 !) m <- match(xi, i0, nomatch=0) if(anyDup) { # assuming anyDup <- any(iDup <- duplicated(i0)) ## i0i: where in (non-duplicated) i0 are the duplicated ones i0i <- match(i0[iDup], i0) i.x <- which(iDup) - 1L jm <- lapply(i0i, function(.) which(. == m)) } c(list(m = m, li = length(i0), i0 = i0, anyDup = anyDup, dn = intIlist$dn), ## actually, iDup is rarely needed in calling code if(anyDup) list(iDup = iDup, i0i = i0i, i.x = i.x, jm = unlist(jm), i.xtra = rep.int(i.x, lengths(jm)))) } ## {.ind.prep} ##' ##' Do the ``common things'' for "*gTMatrix" sub-assignment ##' for 1 dimension, 'margin' , ##'
##' @title Indexing Preparation ##' @param i "index" ##' @param margin in {1,2}; ##' @param di = dim(x) { used when i is not character } ##' @param dn = dimnames(x) ##' @return match(.,.) + li = length of corresponding dimension ##' difference to .ind.prep(): use 1-indices; no match(xi,..), no dn at end ##' @author Martin Maechler .ind.prep2 <- function(i, margin, di, dn) intI(i, n = di[margin], dn = dn[[margin]], give.dn = FALSE) ### FIXME: make this `very fast' for the very very common case of ### ----- M[i,j] <- v with i,j = length-1-numeric; v= length-1 number ### *and* M[i,j] == 0 previously ## ## FIXME(2): keep in sync with replCmat() in ./Csparse.R ## FIXME(3): It's terribly slow when used e.g. from diag(M[,-1]) <- value ## ----- which has "workhorse" M[,-1] <- ## ## workhorse for "[<-" : replTmat <- function (x, i, j, ..., value) { ## NOTE: need '...', i.e., exact signature such that setMethod() ## does not use .local() such that nargs() will work correctly: di <- dim(x) dn <- dimnames(x) iMi <- missing(i) jMi <- missing(j) ## "FIXME": could pass this (and much ? more) when this function would not *be* a ## method but be *called* from methods clDv <- getClassDef(class(value)) spV <- extends(clDv, "sparseVector") ## own version of all0() that works both for sparseVector and atomic vectors: .all0 <- function(v) if(spV) length(v@i) == 0 else all0(v) delayedAssign("value.not.logical", !(if(spV) { extends1of(clDv, "lsparseVector", "nsparseVector") } else { is.logical(value) || is.logical(as.vector(value)) })) na <- nargs() if(na == 3) { ## i = vector indexing M[i] <- v, e.g., M[TRUE] <- v or M[] <- v ! Matrix.message("diagnosing replTmat(x,i,j,v): nargs()= 3; ", if(iMi | jMi) sprintf("missing (i,j) = (%d,%d)", iMi,jMi)) if(iMi) stop("internal bug: missing 'i' in replTmat(): please report") if(is.character(i)) stop("[ ] indexing not allowed: forgot a \",\" ?") if(is.matrix(i)) stop("internal bug: matrix 'i' in replTmat(): please report") ## Now: have M[i] <- v with vector logical or "integer" i : ## Tmatrix maybe non-unique, have an entry split into a sum of several ones: if(!is(x,"generalMatrix")) { cl <- class(x) x <- .M2gen(x) Matrix.message("'sub-optimal sparse 'x[i] <- v' assignment: Coercing class ", cl," to ",class(x)) } nr <- di[1] x <- aggregateT(x) x.i <- .Call(m_encodeInd2, x@i, x@j, di=di, FALSE, FALSE) n <- prod(di) i <- if(is.logical(i)) { # full-size logical indexing if(n) { if(isTRUE(i)) # shortcut 0:(n-1) else { if(length(i) < n) i <- rep_len(i, n) (0:(n-1))[i] # -> 0-based index vector as well {maybe LARGE!} } } else integer(0) } else { ## also works with *negative* indices etc: int2i(as.integer(i), n) - 1L ## 0-based indices [to match m_encodeInd2()] } clx <- class(x) clDx <- getClassDef(clx) # extends(), is() etc all use the class definition has.x <- "x" %in% slotNames(clDx) # === slotNames(x) if(!has.x && # <==> "n.TMatrix" ((iNA <- any(ina <- is.na(value))) || value.not.logical)) { if(value.not.logical) value <- as.logical(value) if(iNA) { value[ina] <- TRUE warning( gettextf("x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced; NA |--> TRUE.", dQuote(clx)), domain=NA) } else warning( gettextf("x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced.", dQuote(clx)), domain=NA) } ## now have 0-based indices x.i (entries) and i (new entries) ## the simplest case: if(.all0(value)) { ## just drop the non-zero entries if(!all(sel <- is.na(match(x.i, i)))) { ## non-zero there x@i <- x@i[sel] x@j <- x@j[sel] if(has.x) x@x <- x@x[sel] if(.hasSlot(x, "factors") && length(x@factors)) # drop cached ones x@factors <- list() } return(x) } m <- length(i) if(length(value) != m) { ## use recycling rules if(m %% length(value) != 0) warning("number of items to replace is not a multiple of replacement length") value <- rep_len(value, m) } ## With duplicated entries i, only use the last ones! if(id <- anyDuplicated(i, fromLast=TRUE)) { i <- i[-id] value <- value[-id] if(any(id <- duplicated(i, fromLast=TRUE))) { nd <- -which(id) i <- i[nd] value <- value[nd] } } ## matching existing non-zeros and new entries; isE := "is Existing" ## isE <- i %in% x.i; mi <- {matching i's} isE <- !is.na(mi <- match(i, x.i)) ## => mi[isE] entries in (i,j,x) to be set to new value[]s ## 1) Change the matching non-zero entries if(has.x) x@x[mi[isE]] <- as(value[isE], class(x@x)) else if(any0(value[isE])) { ## "n.TMatrix" : remove (i,j) where value is FALSE get0 <- !value[isE] ## x[i,j] is TRUE, should become FALSE i.rm <- - mi[isE][get0] x@i <- x@i[i.rm] x@j <- x@j[i.rm] } ## 2) add the new non-zero entries i <- i[!isE] xv <- value[!isE] ## --- Be be efficient when 'value' is sparse : if(length(notE <- which(isN0(xv)))) { # isN0(): non-0's; NAs counted too xv <- xv[notE] i <- i[notE] if(has.x) { x@x <- c(x@x, as(xv, class(x@x))) } else { # n.TMatrix : assign (i,j) only where value is TRUE: i <- i[xv] } x@i <- c(x@i, i %% nr) x@j <- c(x@j, i %/% nr) } if(.hasSlot(x, "factors") && length(x@factors)) # drop cached ones x@factors <- list() return(x) } ## {nargs = 3; x[ii] <- value } ## nargs() == 4 : x[i,j] <- value ## -------------------------------------------------------------------------- lenV <- length(value) Matrix.message(".. replTmat(x,i,j,v): nargs()= 4; cl.(x)=", class(x),"; len.(value)=", lenV,"; ", if(iMi | jMi) sprintf("missing (i,j) = (%d,%d)", iMi,jMi), .M.level = 2)# level 1 gives too many messages ## FIXME: use 'abIndex' or a better algorithm, e.g. if(iMi) i1 <- if(iMi) 0:(di[1] - 1L) else .ind.prep2(i, 1, di, dn) i2 <- if(jMi) 0:(di[2] - 1L) else .ind.prep2(j, 2, di, dn) dind <- c(length(i1), length(i2)) # dimension of replacement region lenRepl <- prod(dind) if(lenV == 0) { if(lenRepl != 0) stop("nothing to replace with") else return(x) } ## else: lenV := length(value) is > 0 if(lenRepl %% lenV != 0) stop("number of items to replace is not a multiple of replacement length") if(!spV && lenRepl > 2^16) { # (somewhat arbitrary cutoff) value <- as(value, "sparseVector")# so that subsequent rep(.) are fast spV <- TRUE } ## Now deal with duplicated / repeated indices: "last one wins" if(!iMi && any(dup <- duplicated(i1, fromLast = TRUE))) { ## duplicated rows keep <- !dup i1 <- i1[keep] ## keep is "internally" recycled below {and that's important: it is dense!} lenV <- length(value <- rep_len(value, lenRepl)[keep]) dind[1] <- length(i1) lenRepl <- prod(dind) } if(!jMi && any(dup <- duplicated(i2, fromLast = TRUE))) { ## duplicated columns iDup <- which(dup) ## The following is correct, but rep(keep,..) can be *HUGE* ## keep <- !dup ## i2 <- i2[keep] ## lenV <- length(value <- rep_len(value, lenRepl)[rep(keep, each=dind[1])]) ## solution: sv[-i] is efficient for sparseVector: i2 <- i2[- iDup] nr <- dind[1] iDup <- rep((iDup - 1)*nr, each=nr) + seq_len(nr) lenV <- length(value <- rep_len(value, lenRepl)[-iDup]) dind[2] <- length(i2) lenRepl <- prod(dind) } clx <- class(x) clDx <- getClassDef(clx) # extends() , is() etc all use the class definition stopifnot(extends(clDx, "TsparseMatrix")) ## Tmatrix maybe non-unique, have an entry split into a sum of several ones: x <- aggregateT(x) toGeneral <- r.sym <- FALSE if(extends(clDx, "symmetricMatrix")) { ## using array() for large dind is a disaster... mkArray <- if(spV) # TODO: room for improvement function(v, dim) spV2M(v, dim[1],dim[2]) else array r.sym <- (dind[1] == dind[2] && all(i1 == i2) && (lenRepl == 1 || lenV == 1 || isSymmetric(mkArray(value, dim=dind)))) if(r.sym) { ## result is *still* symmetric --> keep symmetry! xU <- x@uplo == "U" # later, we will consider only those indices above / below diagonal: } else toGeneral <- TRUE } else if(extends(clDx, "triangularMatrix")) { xU <- x@uplo == "U" r.tri <- ((any(dind == 1) || dind[1] == dind[2]) && if(xU) max(i1) <= min(i2) else max(i2) <= min(i1)) if(r.tri) { ## result is *still* triangular if(any(i1 == i2)) # diagonal will be changed x <- diagU2N(x) # keeps class (!) } else toGeneral <- TRUE } if(toGeneral) { # go to "generalMatrix" and continue Matrix.message("M[i,j] <- v : coercing symmetric M[] into non-symmetric") x <- .M2gen(x) clDx <- getClassDef(clx <- class(x)) } ## TODO (efficiency): replace 'sel' by 'which(sel)' get.ind.sel <- function(ii,ij) (match(x@i, ii, nomatch = 0L) & match(x@j, ij, nomatch = 0L)) ## sel[k] := TRUE iff k-th non-zero entry (typically x@x[k]) is to be replaced sel <- get.ind.sel(i1,i2) has.x <- "x" %in% slotNames(clDx) # === slotNames(x) ## the simplest case: for all Tsparse, even for i or j missing if(.all0(value)) { ## just drop the non-zero entries if(any(sel)) { ## non-zero there x@i <- x@i[!sel] x@j <- x@j[!sel] if(has.x) x@x <- x@x[!sel] if(.hasSlot(x, "factors") && length(x@factors)) # drop cached ones x@factors <- list() } return(x) } ## else -- some( value != 0 ) -- if(lenV > lenRepl) stop("too many replacement values") ## now have lenV <= lenRepl if(!has.x && # <==> "n.TMatrix" ((iNA <- anyNA(value)) || value.not.logical)) warning(if(iNA) gettextf("x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced NA |--> TRUE.", dQuote(clx)) else gettextf("x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced.", dQuote(clx)), domain=NA) ## another simple, typical case: if(lenRepl == 1) { if(spV && has.x) value <- as(value, "vector") if(any(sel)) { ## non-zero there if(has.x) x@x[sel] <- value } else { ## new non-zero x@i <- c(x@i, i1) x@j <- c(x@j, i2) if(has.x) x@x <- c(x@x, value) } if(.hasSlot(x, "factors") && length(x@factors)) # drop cached ones x@factors <- list() return(x) } ### Otherwise, for large lenRepl, we get into trouble below if(lenRepl > 2^20) { # (somewhat arbitrary cutoff) ## FIXME: just for testing !! ## if(identical(Sys.getenv("USER"),"maechler") ## if(lenRepl > 2) { # __________ ___ JUST for testing! _______________ if(!isTRUE(getOption("Matrix.quiet"))) message(gettextf("x[.,.] <- val : x being coerced from Tsparse* to CsparseMatrix"), domain = NA) return(replCmat4(.M2C(x), i1, i2, iMi=iMi, jMi=jMi, value = if(spV) value else as(value, "sparseVector"), spV = TRUE)) } ## if(r.sym) # value already adjusted, see above ## lenRepl <- length(value) # shorter (since only "triangle") if(!r.sym && lenV < lenRepl) value <- rep_len(value, lenRepl) ## now: length(value) == lenRepl {but value is sparseVector if it's "long" !} ## value[1:lenRepl]: which are structural 0 now, which not? ## v0 <- is0(value) ## - replaced by using isN0(as.vector(.)) on a typical small subset value[.] ## --> more efficient for sparse 'value' & large 'lenRepl' : ## FIXME [= FIXME(3) above]: ## ----- The use of seq_len(lenRepl) below is *still* inefficient ## (or impossible e.g. when lenRepl == 50000^2) ## and the vN0 <- isN0(as.vector(value[iI0])) is even more ... ## One idea: use "abIndex", (a very efficient storage of index vectors which are ## a concatenation of only a few arithmetic seq()ences use.abI <- isTRUE(getOption("Matrix.use.abIndex")) ## This 'use.abI' should later depend on the *dimension* of things ! ##>>> But for that, we need to implement the following abIndex - "methods": ##>>> [-n], [ ] , intersect(, ) ## and for intersect(): typically sort(), unique() & similar iI0 <- if(use.abI) abIseq1(1L, lenRepl) else seq_len(lenRepl) if(any(sel)) { ## the 0-based indices of non-zero entries -- WRT to submatrix iN0 <- 1L + .Call(m_encodeInd2, match(x@i[sel], i1), match(x@j[sel], i2), di = dind, orig1=TRUE, FALSE) ## 1a) replace those that are already non-zero with non-0 values vN0 <- isN0(value[iN0]) if(any(vN0) && has.x) { vv0 <- which(vN0) x@x[sel][vv0] <- as.vector(value[iN0[vv0]]) } ## 1b) replace non-zeros with 0 --> drop entries if(!all(vN0)) { ##-> ii will not be empty ii <- which(sel)[which(!vN0)] # <- vN0 may be sparseVector if(has.x) x@x <- x@x[-ii] x@i <- x@i[-ii] x@j <- x@j[-ii] } iI0 <- if(length(iN0) < lenRepl) iI0[-iN0] ## else NULL # == complementInd(non0, dind) } if(length(iI0)) { if(r.sym) { ## should only set new entries above / below diagonal, i.e., ## subset iI0 such as to contain only above/below .. iSel <- if(use.abI) abIindTri(dind[1], upper=xU, diag=TRUE) else indTri(dind[1], upper=xU, diag=TRUE) ## select also the corresponding triangle of values ### TODO for "abIndex" -- note we KNOW that both iI0 and iSel ### are strictly increasing : iI0 <- intersect(iI0, iSel) } full <- length(iI0) == lenRepl vN0 <- if(spV) ## "sparseVector" (if(full) value else value[iI0])@i else which(isN0(if(full) value else value[iI0])) if(length(vN0)) { ## 2) add those that were structural 0 (where value != 0) iIN0 <- if(full) vN0 else iI0[vN0] ij0 <- decodeInd(iIN0 - 1L, nr = dind[1]) x@i <- c(x@i, i1[ij0[,1] + 1L]) x@j <- c(x@j, i2[ij0[,2] + 1L]) if(has.x) x@x <- c(x@x, as.vector(value[iIN0])) } } if(.hasSlot(x, "factors") && length(x@factors)) # drop cached ones x@factors <- list() x } ## end{replTmat} ## A[ ij ] <- value, where ij is a matrix; typically (i,j) 2-column matrix : ## ---------------- ./Matrix.R has a general cheap method ## This one should become as fast as possible -- is also used from Csparse.R -- .TM.repl.i.mat <- function (x, i, j, ..., value) { nA <- nargs() if(nA != 3) stop(gettextf("nargs() = %d should never happen; please report.", nA), domain=NA) ## else: nA == 3 i.e., M [ cbind(ii,jj) ] <- value or M [ Lmat ] <- value if(is.logical(i)) { Matrix.message(".TM.repl.i.mat(): drop 'matrix' case ...", .M.level=2) ## c(i) : drop "matrix" to logical vector x[as.vector(i)] <- value return(x) } else if(extends1of(cli <- getClassDef(class(i)), c("lMatrix", "nMatrix"))) { Matrix.message(".TM.repl.i.mat(): \"lMatrix\" case ...", .M.level=2) i <- which(as(i, if(extends(cli, "sparseMatrix")) "sparseVector" else "vector")) ## x[i] <- value ; return(x) return(`[<-`(x,i, value=value)) } else if(extends(cli, "Matrix")) { # "dMatrix" or "iMatrix" if(ncol(i) != 2) stop("such indexing must be by logical or 2-column numeric matrix") i <- as(i, "matrix") } else if(!is.numeric(i) || ncol(i) != 2) stop("such indexing must be by logical or 2-column numeric matrix") if(!is.integer(i)) storage.mode(i) <- "integer" if(any(i < 0)) stop("negative values are not allowed in a matrix subscript") if(anyNA(i)) stop("NAs are not allowed in subscripted assignments") if(any(i0 <- (i == 0))) # remove them i <- i[ - which(i0, arr.ind = TRUE)[,"row"], ] if(length(attributes(i)) > 1) # more than just 'dim'; simplify: will use identical attributes(i) <- list(dim = dim(i)) ## now have integer i >= 1 m <- nrow(i) if(m == 0) return(x) if(length(value) == 0) stop("nothing to replace with") ## mod.x <- .type.kind[.M.kind(x)] if(length(value) != m) { ## use recycling rules if(m %% length(value) != 0) warning("number of items to replace is not a multiple of replacement length") value <- rep_len(value, m) } clx <- class(x) clDx <- getClassDef(clx) # extends() , is() etc all use the class definition stopifnot(extends(clDx, "TsparseMatrix")) di <- dim(x) nr <- di[1] nc <- di[2] i1 <- i[,1] i2 <- i[,2] if(any(i1 > nr)) stop(gettextf("row indices must be <= nrow(.) which is %d", nr), domain=NA) if(any(i2 > nc)) stop(gettextf("column indices must be <= ncol(.) which is %d", nc), domain=NA) ## Tmatrix maybe non-unique, have an entry split into a sum of several ones: x <- aggregateT(x) toGeneral <- FALSE isN <- extends(clDx, "nMatrix") if(r.sym <- extends(clDx, "symmetricMatrix")) { ## Tests to see if the assignments are symmetric as well r.sym <- all(i1 == i2) if(!r.sym) { # do have *some* Lower or Upper entries iL <- i1 > i2 iU <- i1 < i2 r.sym <- sum(iL) == sum(iU) # same number if(r.sym) { iLord <- order(i1[iL], i2[iL]) iUord <- order(i2[iU], i1[iU]) # row <-> col. ! r.sym <- { identical(i[iL, , drop=FALSE][iLord,], i[iU, 2:1, drop=FALSE][iUord,]) && all(value[iL][iLord] == value[iU][iUord]) } } } if(r.sym) { ## result is *still* symmetric --> keep symmetry! ## now consider only those indices above / below diagonal: useI <- if(x@uplo == "U") i1 <= i2 else i2 <= i1 i <- i[useI, , drop=FALSE] value <- value[useI] } else toGeneral <- TRUE } else if(extends(clDx, "triangularMatrix")) { r.tri <- all(if(x@uplo == "U") i1 <= i2 else i2 <= i1) if(r.tri) { ## result is *still* triangular if(any(ieq <- i1 == i2)) { # diagonal will be changed if(x@diag == "U" && all(ieq) && all(value == if(isN) TRUE else as1(x@x))) ## only diagonal values are set to 1 -- i.e. unchanged return(x) x <- diagU2N(x) # keeps class (!) } } else toGeneral <- TRUE } if(toGeneral) { # go to "generalMatrix" and continue Matrix.message("M[ij] <- v : coercing symmetric M[] into non-symmetric") x <- .M2gen(x) clDx <- getClassDef(clx <- class(x)) } ii.v <- .Call(m_encodeInd, i, di, orig1=TRUE, checkBounds = TRUE) if(id <- anyDuplicated(ii.v, fromLast=TRUE)) { Matrix.message("M[ij] <- v : duplicate ij-entries; using last") ii.v <- ii.v [-id] value <- value[-id] if(any(id <- duplicated(ii.v, fromLast=TRUE))) { nd <- -which(id) ii.v <- ii.v [nd] value <- value[nd] } } ii.x <- .Call(m_encodeInd2, x@i, x@j, di, FALSE, FALSE) m1 <- match(ii.v, ii.x) i.repl <- !is.na(m1) # those that need to be *replaced* if(isN) { ## no 'x' slot isN <- is.logical(value) # will result remain "nMatrix" ? if(!isN) x <- .M2kind(x, "d") } has.x <- !isN ## isN <===> "remains pattern matrix" <===> has no 'x' slot if(any(i.repl)) { ## some to replace at matching (@i, @j) if(has.x) x@x[m1[i.repl]] <- value[i.repl] else { # nMatrix ; eliminate entries that are set to FALSE; keep others if(any(isF <- is0(value[i.repl]))) { ii <- m1[i.repl][isF] x@i <- x@i[ -ii] x@j <- x@j[ -ii] } } } if(any(i.new <- !i.repl & isN0(value))) { ## some new entries i.j <- decodeInd(ii.v[i.new], nr) x@i <- c(x@i, i.j[,1]) x@j <- c(x@j, i.j[,2]) if(has.x) x@x <- c(x@x, value[i.new]) } if(.hasSlot(x, "factors") && length(x@factors)) # drop cached ones x@factors <- list() x } ## end{.TM.repl.i.mat} setReplaceMethod("[", signature(x = "TsparseMatrix", i = "index", j = "missing", value = "replValue"), replTmat) setReplaceMethod("[", signature(x = "TsparseMatrix", i = "missing", j = "index", value = "replValue"), replTmat) setReplaceMethod("[", signature(x = "TsparseMatrix", i = "index", j = "index", value = "replValue"), replTmat) setReplaceMethod("[", signature(x = "TsparseMatrix", i = "matrix", j = "missing", value = "replValue"), .TM.repl.i.mat) setReplaceMethod("[", signature(x = "TsparseMatrix", i = "Matrix", j = "missing", value = "replValue"), .TM.repl.i.mat) ### When the RHS 'value' is a sparseVector, now can use replTmat as well setReplaceMethod("[", signature(x = "TsparseMatrix", i = "missing", j = "index", value = "sparseVector"), replTmat) setReplaceMethod("[", signature(x = "TsparseMatrix", i = "index", j = "missing", value = "sparseVector"), replTmat) setReplaceMethod("[", signature(x = "TsparseMatrix", i = "index", j = "index", value = "sparseVector"), replTmat) ## ==== diagonalMatrix ================================================= ## When you assign to a diagonalMatrix, the result should be ## diagonal or sparse --- replDiag <- function(x, i, j, ..., value) { ## FIXME: if (i == j) && isSymmetric(value) then -- want symmetricMatrix result! -- or diagMatrix x <- .diag2sparse(x, ".", "g", "C") # was ->TsparseMatrix till 2012-07 if(missing(i)) x[, j] <- value else if(missing(j)) { ## x[i , ] <- v *OR* x[i] <- v na <- nargs() ## message("diagnosing replDiag() -- nargs()= ", na) if(na == 4L) x[i, ] <- value else if(na == 3L) x[i] <- value else stop(gettextf("Internal bug: nargs()=%d; please report", na), domain=NA) } else x[i,j] <- value ## TODO: the following is a bit expensive; have cases above e.g. [i,] where ## ----- we could check *much* faster : if(isDiagonal(x)) forceDiagonal(x) else if(isSymmetric(x)) forceSymmetric(x) else if(!(it <- isTriangular(x))) x else if(attr(it, "kind") == "U") triu(x) else tril(x) } setReplaceMethod("[", signature(x = "diagonalMatrix", i = "index", j = "index", value = "replValue"), replDiag) setReplaceMethod("[", signature(x = "diagonalMatrix", i = "index", j = "missing", value = "replValue"), function(x,i,j, ..., value) { ## message("before replDiag() -- nargs()= ", nargs()) if(nargs() == 3L) replDiag(x, i=i, value=value) else ## nargs() == 4 : replDiag(x, i=i, , value=value) }) setReplaceMethod("[", signature(x = "diagonalMatrix", i = "missing", j = "index", value = "replValue"), function(x,i,j, ..., value) replDiag(x, j=j, value=value)) ## x[] <- value : setReplaceMethod("[", signature(x = "diagonalMatrix", i = "missing", j = "missing", value = "ANY"), function(x,i,j, ..., value) { if(all0(value)) { # be faster r <- new(paste0(.M.kind(x), "tTMatrix")) # of all "0" r@Dim <- x@Dim r@Dimnames <- x@Dimnames r } else { ## typically non-sense: assigning to full sparseMatrix x[TRUE] <- value x } }) setReplaceMethod("[", signature(x = "diagonalMatrix", i = "matrix", # 2-col.matrix j = "missing", value = "replValue"), function(x,i,j, ..., value) { if(ncol(i) == 2L) { if(all((ii <- i[,1L]) == i[,2L])) { ## replace in diagonal only if(x@diag == "U") { one <- as1(x@x) if(any(value != one | is.na(value))) { x@diag <- "N" x@x <- rep.int(one, x@Dim[1L]) } else return(x) } x@x[ii] <- value x } else { ## no longer diagonal, but remain sparse: ### FIXME: use uplo="U" or uplo="L" (or *not* "triangularMatrix") ### depending on LE <- i <= j ### all(LE) // all(!LE) // remaining cases x <- .diag2sparse(x, ".", "t", "C") # was ->TsparseMatrix x[i] <- value x } } else { # behave as "base R": use as if vector x <- as(x, "matrix") x[i] <- value Matrix(x) } }) ## value = "sparseMatrix": setReplaceMethod("[", signature(x = "diagonalMatrix", i = "missing", j = "index", value = "sparseMatrix"), function (x, i, j, ..., value) callGeneric(x=x, , j=j, value=as(value, "sparseVector"))) setReplaceMethod("[", signature(x = "diagonalMatrix", i = "index", j = "missing", value = "sparseMatrix"), function (x, i, j, ..., value) callGeneric(x=x, i=i, , value=as(value, "sparseVector"))) setReplaceMethod("[", signature(x = "diagonalMatrix", i = "index", j = "index", value = "sparseMatrix"), function (x, i, j, ..., value) callGeneric(x=x, i=i, j=j, value=as(value, "sparseVector"))) ## value = "sparseVector": setReplaceMethod("[", signature(x = "diagonalMatrix", i = "missing", j = "index", value = "sparseVector"), replDiag) setReplaceMethod("[", signature(x = "diagonalMatrix", i = "index", j = "missing", value = "sparseVector"), replDiag) setReplaceMethod("[", signature(x = "diagonalMatrix", i = "index", j = "index", value = "sparseVector"), replDiag) ## ==== indMatrix ====================================================== .indMatrix.sub <- function(x, i, j, ..., value) { x <- as(x, "TsparseMatrix") callGeneric() } for (.i in c("missing", "index")) for (.j in c("missing", "index")) setReplaceMethod("[", signature(x = "indMatrix", i = .i, j = .j, value = "ANY"), .indMatrix.sub) rm(.indMatrix.sub, .i, .j) ## ==== sparseVector =================================================== ## This is a simplified intI() -- for sparseVector indexing: intIv <- function(i, n, cl.i = getClassDef(class(i))) { ### Note: undesirable to use this for negative indices; ### ---- using seq_len(n) below means we are NON-sparse ... ### Fixed, for "x[i] with negative i" at least. ## Purpose: translate numeric | logical index into 1-based integer ## -------------------------------------------------------------------- ## Arguments: i: index vector (numeric | logical) *OR* sparseVector ## n: array extent { == length(.) } if(missing(i)) seq_len(n) else if(extends(cl.i, "numeric")) { ## not ok, when max(i) > .Machine$integer.max ! storage.mode(i) <- "integer" int2i(i,n) ##-> ./Tsparse.R } else if (extends(cl.i, "logical")) { seq_len(n)[i] } else if(extends(cl.i, "nsparseVector")) { i@i # the indices are already there ! } else if(extends(cl.i, "lsparseVector")) { i@i[i@x] # "drop0", i.e. FALSE; NAs ok } else if (extends(cl.i, "sparseVector")) { ## 'i'sparse, 'd'sparse (etc) as.integer(i@x[i@i]) } else stop("index must be numeric, logical or sparseVector for indexing sparseVectors") } ## intIv() replSPvec <- function (x, i, value) { n <- x@length ii <- intIv(i, n) lenRepl <- length(ii) if(!lenRepl) return(x) ## else: lenRepl = length(ii) > 0 lenV <- length(value) if(lenV == 0) stop("nothing to replace with") ## else: lenV := length(value) > 0 if(lenRepl %% lenV != 0) stop("number of items to replace is not a multiple of replacement length") if(anyDuplicated(ii)) { ## multiple *replacement* indices: last one wins ## TODO: in R 2.6.0 use duplicate(*, fromLast=TRUE) ir <- lenRepl:1 keep <- match(ii, ii[ir]) == ir ii <- ii[keep] lenV <- length(value <- rep(value, length.out = lenRepl)[keep]) lenRepl <- length(ii) } has.x <- .hasSlot(x, "x")## has "x" slot m <- match(x@i, ii, nomatch = 0) sel <- m > 0L ## the simplest case if(all0(value)) { ## just drop the non-zero entries if(any(sel)) { ## non-zero there x@i <- x@i[!sel] if(has.x) x@x <- x@x[!sel] } return(x) } ## else -- some( value != 0 ) -- if(lenV > lenRepl) stop("too many replacement values") else if(lenV < lenRepl) value <- rep(value, length.out = lenRepl) ## now: length(value) == lenRepl > 0 v0 <- is0(value) ## value[1:lenRepl]: which are structural 0 now, which not? v.sp <- inherits(value, "sparseVector") if(any(sel)) { ## indices of non-zero entries -- WRT to subvector iN0 <- m[sel] ## == match(x@i[sel], ii) ## 1a) replace those that are already non-zero with new val. vN0 <- !v0[iN0] if(any(vN0) && has.x) { vs <- value[iN0[vN0]] x@x[sel][vN0] <- if(v.sp) sp2vec(vs, mode=typeof(x@x)) else vs } ## 1b) replace non-zeros with 0 --> drop entries if(any(!vN0)) { i <- which(sel)[!vN0] if(has.x) x@x <- x@x[-i] x@i <- x@i[-i] } iI0 <- if(length(iN0) < lenRepl) seq_len(lenRepl)[-iN0] # else NULL } else iI0 <- seq_len(lenRepl) if(length(iI0) && any(vN0 <- !v0[iI0])) { ## 2) add those that were structural 0 (where value != 0) ij0 <- iI0[vN0] ii <- c(x@i, ii[ij0]) # new x@i, must be sorted: iInc <- sort.list(ii) x@i <- ii[iInc] if(has.x) # new @x, sorted along '@i': x@x <- c(x@x, if(v.sp) sp2vec(value[ij0], mode=typeof(x@x)) else value[ij0] )[iInc] } x } setReplaceMethod("[", signature(x = "sparseVector", i = "index", j = "missing", value = "replValueSp"), replSPvec) setReplaceMethod("[", signature(x = "sparseVector", i = "sparseVector", j = "missing", value = "replValueSp"), ## BTW, the important case: 'i' a *logical* sparseVector replSPvec) ���������������������������������������������������������������������������������������������������������������������������������������������Matrix/R/perm.R�������������������������������������������������������������������������������������0000644�0001762�0000144�00000001111�14467055256�013015� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������invertPerm <- function(p, off = 1L, ioff = 1L) .Call(R_invertPerm, as.integer(p), as.integer(off), as.integer(ioff)) signPerm <- function(p, off = 1L) .Call(R_signPerm, as.integer(p), as.integer(off)) isPerm <- function(p, off = 1L) .Call(R_isPerm, as.integer(p), as.integer(off)) asPerm <- function(pivot, off = 1L, ioff = 1L, n = length(pivot)) .Call(R_asPerm, as.integer(pivot), as.integer(off), as.integer(ioff), as.integer(n)) invPerm <- function(p, zero.p = FALSE, zero.res = FALSE) invertPerm(p, if(zero.p) 0L else 1L, if(zero.res) 0L else 1L) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/R/all.equal.R��������������������������������������������������������������������������������0000644�0001762�0000144�00000016453�14511521056�013731� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## METHODS FOR GENERIC: all.equal ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .V.a.e <- function(target, current, ...) { if((l1 <- length(target)) != (l2 <- length(current))) return(paste0("length(target) is ", l1, ", length(current) is ", l2)) if(is.integer(l1) || l1 <= .Machine$integer.max) { i1 <- as.integer( target@i) i2 <- as.integer(current@i) } else { i1 <- trunc( target@i) i2 <- trunc(current@i) } x1 <- if(.hasSlot( target, "x")) target@x else rep.int(TRUE, length(i1)) x2 <- if(.hasSlot(current, "x")) current@x else rep.int(TRUE, length(i2)) if(!identical(i1, i2)) { i3 <- sort.int(unique.default(c(i1, i2))) x1 <- replace(vector(typeof(x1), length(i3)), match(i1, i3, 0L), x1) x2 <- replace(vector(typeof(x2), length(i3)), match(i2, i3, 0L), x2) } all.equal(x1, x2, ...) } .M.attributes <- function(x, exclude.informal, exclude.factors) { a <- attributes(x) if(isS4(x) && exclude.informal) a <- a[.slotNames(a)] if(length(a) == 0L) return(NULL) exclude <- if(!isS4(x)) c("class", "dim", "dimnames") else if(.isMatrix(x)) c("class", "Dim", "Dimnames", switch(.M.repr(x), "C" = c("p", "i", if(.M.kind(x) != "n") "x"), "R" = c("p", "j", if(.M.kind(x) != "n") "x"), "T" = c("i", "j", if(.M.kind(x) != "n") "x"), "d" = , "u" = , "p" = "x", "i" = "perm"), switch(.M.shape(x), "g" = if(exclude.factors) "factors", "s" = c("uplo", if(exclude.factors) "factors"), "t" = c("uplo", "diag"), "d" = "diag")) else "class" nms <- names(a) i <- match(nms, exclude, 0L) == 0L if(any(i)) a[sort.int(nms[i])] else NULL } .M.attr.all.equal <- function(target, current, check.type, check.class, check.attributes, check.factors, ...) { msg <- msg. <- NULL if(check.type && !identical(t1 <- typeof(target), t2 <- typeof(current))) msg <- c(msg, paste0("typeof(target) is ", deparse(t1), ", typeof(current) is ", deparse(t2))) if(check.class && !identical(c1 <- class(target), c2 <- class(current))) msg <- c(msg, paste0( "class(target) is ", deparse(c1), ", class(current) is ", deparse(c2))) if(is.na(check.attributes) || check.attributes) { if(!isTRUE(ae <- all.equal.raw(dim(target), dim(current), ...))) msg <- c(msg, paste0("dim: < ", ae, " >")) if(!isTRUE(ae <- all.equal.list(dimnames( target) %||% list(NULL, NULL), dimnames(current) %||% list(NULL, NULL), ...))) msg <- c(msg, paste0("dimnames: < ", ae, " >")) a1 <- .M.attributes( target, is.na(check.attributes), !check.factors) a2 <- .M.attributes(current, is.na(check.attributes), !check.factors) if(!((is.null(a1) && is.null(a2)) || isTRUE(ae <- all.equal.list(a1, a2, ...)))) msg <- msg. <- c(msg, paste0("Attributes: < ", ae, " >")) } list(msg, is.null(msg) != is.null(msg.)) } .M.all.equal <- function(target, current, check.type = check.class, check.class = TRUE, check.attributes = TRUE, check.factors = FALSE, ...) { msg <- .M.attr.all.equal(target, current, check.type = check.type, check.class = check.class, check.attributes = check.attributes, check.factors = check.factors, ...) if(!msg[[2L]]) { ae <- if(.isVector( target) || .isSparse( target) || .isVector(current) || .isSparse(current)) { v1 <- as( target, "sparseVector") v2 <- as(current, "sparseVector") ae <- .V.a.e(v1, v2, ...) } else { v1 <- as( target, "vector") v2 <- as(current, "vector") ae <- all.equal(v1, v2, ...) } if(!isTRUE(ae)) return(c(msg[[1L]], ae)) } if(is.null(msg[[1L]])) TRUE else msg[[1L]] } setMethod("all.equal", signature(target = "Matrix", current = "vector"), .M.all.equal) setMethod("all.equal", signature(target = "vector", current = "Matrix"), .M.all.equal) setMethod("all.equal", signature(target = "Matrix", current = "Matrix"), .M.all.equal) ## And for completeness: setMethod("all.equal", signature(target = "Matrix", current = "sparseVector"), .M.all.equal) .V.attributes <- function(x, exclude.informal) { a <- attributes(x) if(isS4(x) && exclude.informal) a <- a[.slotNames(a)] if(length(a) == 0L) return(NULL) exclude <- if(.isVector(x)) c("class", "length", "i", if(.M.kind(x) != "n") "x") else "class" nms <- names(a) i <- match(nms, exclude, 0L) == 0L if(any(i)) a[sort.int(nms[i])] else NULL } .V.attr.all.equal <- function(target, current, check.type, check.class, check.attributes, ...) { msg <- msg. <- NULL if(check.type && !identical(t1 <- typeof(target), t2 <- typeof(current))) msg <- c(msg, paste0("typeof(target) is ", deparse(t1), ", typeof(current) is ", deparse(t2))) if(check.class && !identical(c1 <- class(target), c2 <- class(current))) msg <- c(msg, paste0( "class(target) is ", deparse(c1), ", class(current) is ", deparse(c2))) if(is.na(check.attributes) || check.attributes) { if((l1 <- length(target)) != (l2 <- length(current))) msg <- c(msg, paste0("length(target) is ", l1, ", length(current) is ", l2)) a1 <- .V.attributes( target, is.na(check.attributes)) a2 <- .V.attributes(current, is.na(check.attributes)) if(!((is.null(a1) && is.null(a2)) || isTRUE(ae <- all.equal.list(a1, a2, ...)))) msg <- msg. <- c(msg, paste0("Attributes: < ", ae, " >")) } list(msg, is.null(msg) != is.null(msg.)) } .V.all.equal <- function(target, current, check.type = check.class, check.class = TRUE, check.attributes = TRUE, ...) { msg <- .V.attr.all.equal(target, current, check.type = check.type, check.class = check.class, check.attributes = check.attributes, ...) if(!msg[[2L]]) { if(.isVector( target) || .isSparse( target) || .isVector(current) || .isSparse(current)) { v1 <- as( target, "sparseVector") v2 <- as(current, "sparseVector") ae <- .V.a.e(v1, v2, ...) } else { v1 <- as( target, "vector") v2 <- as(current, "vector") ae <- all.equal(v1, v2, ...) } if(!isTRUE(ae)) return(c(msg[[1L]], ae)) } if(is.null(msg[[1L]])) TRUE else msg[[1L]] } setMethod("all.equal", signature(target = "sparseVector", current = "vector"), .V.all.equal) setMethod("all.equal", signature(target = "vector", current = "sparseVector"), .V.all.equal) setMethod("all.equal", signature(target = "sparseVector", current = "sparseVector"), .V.all.equal) ## And for completeness: setMethod("all.equal", signature(target = "sparseVector", current = "Matrix"), .V.all.equal) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/R/sparseMatrix.R�����������������������������������������������������������������������������0000644�0001762�0000144�00000014156�14502666502�014541� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## METHODS FOR CLASS: sparseMatrix, [CRT]sparseMatrix (virtual) ## sparse matrices, in some cases restricted to CSC, CSR, triplet ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .sparse.band <- function(x, k1, k2, ...) .Call(R_sparse_band, x, k1, k2) .sparse.triu <- function(x, k = 0L, ...) .Call(R_sparse_band, x, k, NULL) .sparse.tril <- function(x, k = 0L, ...) .Call(R_sparse_band, x, NULL, k) .sparse.diag.get <- function(x, nrow, ncol, names = TRUE) .Call(R_sparse_diag_get, x, names) .sparse.diag.set <- function(x, value) .Call(R_sparse_diag_set, x, value) .sparse.t <- function(x) .Call(R_sparse_transpose, x, FALSE) .sparse.fS1 <- function(x, uplo) .Call(R_sparse_force_symmetric, x, NULL) .sparse.fS2 <- function(x, uplo) .Call(R_sparse_force_symmetric, x, uplo) .sparse.symmpart <- function(x) .Call(R_sparse_symmpart, x) .sparse.skewpart <- function(x) .Call(R_sparse_skewpart, x) .sparse.is.di <- function(object) .Call(R_sparse_is_diagonal, object) .sparse.is.tr <- function(object, upper = NA, ...) .Call(R_sparse_is_triangular, object, upper) .sparse.is.sy <- function(object, checkDN = TRUE, ...) { if(checkDN) { ca <- function(check.attributes = TRUE, ...) check.attributes checkDN <- ca(...) } .Call(R_sparse_is_symmetric, object, checkDN) } .sparse.is.sy.dz <- function(object, checkDN = TRUE, tol = 100 * .Machine$double.eps, ...) { ## backwards compatibility: don't check DN if check.attributes=FALSE if(checkDN) { ca <- function(check.attributes = TRUE, ...) check.attributes checkDN <- ca(...) } ## be very fast when requiring exact symmetry if(tol <= 0) return(.Call(R_sparse_is_symmetric, object, checkDN)) ## pretest: is it square? d <- object@Dim if((n <- d[2L]) != d[1L]) return(FALSE) ## pretest: are DN symmetric in the sense of validObject()? if(checkDN && !isSymmetricDN(object@Dimnames)) return(FALSE) if(n == 0L) return(TRUE) ## now handling an n-by-n [dz]g[CRT]Matrix, n >= 1: Cj <- if(is.complex(object@x)) Conj else identity ae <- function(check.attributes, ...) { ## discarding possible user-supplied check.attributes all.equal(..., check.attributes = FALSE) } isTRUE(ae(target = .M2V( object ), current = .M2V(Cj(t(object))), tolerance = tol, ...)) } setMethod("diff", signature(x = "sparseMatrix"), ## Mostly cut and paste of base::diff.default : function(x, lag = 1L, differences = 1L, ...) { if(length(lag) != 1L || length(differences) != 1L || lag < 1L || differences < 1L) stop(gettextf("'%s' and '%s' must be positive integers", "lag", "differences"), domain = NA) if(lag * differences >= x@Dim[1L]) return(x[0L]) i1 <- -seq_len(lag) for(i in seq_len(differences)) { m <- x@Dim[1L] x <- x[i1, , drop = FALSE] - x[-m:-(m - lag + 1L), , drop = FALSE] } x }) setMethod("mean", signature(x = "sparseMatrix"), function(x, ...) mean(as(x, "sparseVector"), ...)) setMethod("rep", "sparseMatrix", function(x, ...) rep(as(x, "sparseVector"), ...)) for(.cl in paste0(c("C", "R", "T"), "sparseMatrix")) { setMethod("band" , signature(x = .cl), .sparse.band) setMethod("triu" , signature(x = .cl), .sparse.triu) setMethod("tril" , signature(x = .cl), .sparse.tril) setMethod("diag" , signature(x = .cl), .sparse.diag.get) setMethod("diag<-", signature(x = .cl), .sparse.diag.set) setMethod("t" , signature(x = .cl), .sparse.t) setMethod("forceSymmetric", signature(x = .cl, uplo = "missing"), .sparse.fS1) setMethod("forceSymmetric", signature(x = .cl, uplo = "character"), .sparse.fS2) setMethod("symmpart", signature(x = .cl), .sparse.symmpart) setMethod("skewpart", signature(x = .cl), .sparse.skewpart) setMethod("isSymmetric" , signature(object = .cl), .sparse.is.sy) setMethod("isTriangular", signature(object = .cl), .sparse.is.tr) setMethod("isDiagonal" , signature(object = .cl), .sparse.is.di) } .sparse.subclasses <- names(getClassDef("sparseMatrix")@subclasses) for(.cl in grep("^[dz][gt][CRT]Matrix$", .sparse.subclasses, value = TRUE)) setMethod("isSymmetric" , signature(object = .cl), .sparse.is.sy.dz) rm(.cl, .sparse.subclasses) rm(list = c(grep("^[.]sparse[.](band|tri[ul]|diag[.](get|set)|t|fS[12]|symmpart|skewpart|is[.](sy|tr|di)([.]dz)?)$", ls(all.names = TRUE), value = TRUE))) if(FALSE) ### FIXME: This would *NOT* be needed, if as.matrix() was a no-op ; ### ----- and then, base::scale() -> base::scale.default() would work "magically" already.. scale.sparseMatrix <- function(x, center = FALSE, scale = TRUE) { if(center) warning("a sparseMatrix should rarely be centered: will not be sparse anymore") ## x <- as.matrix(x) ## This rest is *identically* == base :: scale.default : nc <- ncol(x) if (is.logical(center)) { if (center) { center <- colMeans(x, na.rm=TRUE) x <- sweep(x, 2L, center, check.margin=FALSE) } } else if (is.numeric(center) && (length(center) == nc)) x <- sweep(x, 2L, center, check.margin=FALSE) else stop("length of 'center' must equal the number of columns of 'x'") if (is.logical(scale)) { if (scale) { f <- function(v) { v <- v[!is.na(v)] sqrt(sum(v^2) / max(1, length(v) - 1L)) } scale <- apply(x, 2L, f) x <- sweep(x, 2L, scale, "/", check.margin=FALSE) } } else if (is.numeric(scale) && length(scale) == nc) x <- sweep(x, 2L, scale, "/", check.margin=FALSE) else stop("length of 'scale' must equal the number of columns of 'x'") if(is.numeric(center)) attr(x, "scaled:center") <- center if(is.numeric(scale)) attr(x, "scaled:scale") <- scale x } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/R/chol.R�������������������������������������������������������������������������������������0000644�0001762�0000144�00000052307�14503364553�013006� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## METHODS FOR GENERIC: chol ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("chol", signature(x = "generalMatrix"), function(x, uplo = "U", ...) { ch <- chol(forceSymmetric(x, uplo), ...) ch@Dimnames <- x@Dimnames # restore asymmetric 'Dimnames' ch }) setMethod("chol", signature(x = "symmetricMatrix"), function(x, ...) chol(.M2kind(x, ","), ...)) setMethod("chol", signature(x = "triangularMatrix"), function(x, uplo = "U", ...) { if(identical(uplo, x@uplo)) { ch <- chol(forceSymmetric(x, uplo), ...) ch@Dimnames <- x@Dimnames # restore asymmetric 'Dimnames' ch } else chol(forceDiagonal(x, x@diag), ...) }) setMethod("chol", signature(x = "diagonalMatrix"), function(x, ...) chol(.M2kind(x, ","), ...)) setMethod("chol", signature(x = "dsyMatrix"), function(x, pivot = FALSE, tol = -1, ...) { ch <- as(Cholesky(x, perm = pivot, tol = tol), "dtrMatrix") ch@Dimnames <- dimnames(x) if(ch@uplo != "U") t(ch) else ch }) setMethod("chol", signature(x = "dspMatrix"), function(x, ...) { ch <- as(Cholesky(x), "dtpMatrix") ch@Dimnames <- dimnames(x) if(ch@uplo != "U") t(ch) else ch }) for(.cl in paste0("ds", c("C", "R", "T"), "Matrix")) setMethod("chol", signature(x = .cl), function(x, pivot = FALSE, ...) { ch <- t(as(Cholesky(x, perm = pivot, LDL = FALSE, super = FALSE), "dtCMatrix")) # FIXME? give dtRMatrix, dtTMatrix? ch@Dimnames <- dimnames(x) ch }) rm(.cl) setMethod("chol", signature(x = "ddiMatrix"), function(x, ...) { if(length(y <- x@x)) { if(is.na(min.y <- min(y)) || min.y < 0) stop(gettextf("%1$s(%2$s) is undefined: '%2$s' is not positive semidefinite", "chol", "x"), domain = NA) x@x <- sqrt(y) } x }) ## METHODS FOR GENERIC: Cholesky ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("Cholesky", signature(A = "generalMatrix"), function(A, uplo = "U", ...) { ch <- Cholesky(forceSymmetric(A, uplo), ...) ch@Dimnames <- A@Dimnames # restore asymmetric 'Dimnames' ch }) setMethod("Cholesky", signature(A = "symmetricMatrix"), function(A, ...) Cholesky(.M2kind(A, ","), ...)) setMethod("Cholesky", signature(A = "triangularMatrix"), function(A, uplo = "U", ...) { ch <- Cholesky(forceSymmetric(A, uplo), ...) ch@Dimnames <- A@Dimnames # restore asymmetric 'Dimnames' ch }) setMethod("Cholesky", signature(A = "diagonalMatrix"), function(A, ...) Cholesky(.M2kind(A, ","), ...)) setMethod("Cholesky", signature(A = "dsyMatrix"), function(A, perm = TRUE, tol = -1, ...) .Call(dpoMatrix_trf, A, if(perm) 1L else 2L, perm, tol)) setMethod("Cholesky", signature(A = "dspMatrix"), function(A, ...) .Call(dppMatrix_trf, A, 2L)) setMethod("Cholesky", signature(A = "dsCMatrix"), function(A, perm = TRUE, LDL = !super, super = FALSE, Imult = 0, ...) .Call(dpCMatrix_trf, A, perm, LDL, super, Imult)) setMethod("Cholesky", signature(A = "dsRMatrix"), function(A, ...) Cholesky(.tCRT(A), ...)) setMethod("Cholesky", signature(A = "dsTMatrix"), function(A, ...) Cholesky(.M2C(A), ...)) setMethod("Cholesky", signature(A = "ddiMatrix"), function(A, ...) { if(length(y <- A@x) && (is.na(min.y <- min(y)) || min.y < 0)) stop(gettextf("%1$s(%2$s) is undefined: '%2$s' is not positive semidefinite", "Cholesky", "x"), domain = NA) n <- (d <- A@Dim)[1L] r <- new("dCHMsimpl") r@Dim <- d r@Dimnames <- A@Dimnames r@colcount <- r@nz <- rep.int(1L, n) r@type <- c(0L, 0L, 0L, 1L, 0L, 0L) r@p <- 0:n r@i <- s <- seq.int(0L, length.out = n) r@x <- if(length(y)) y else rep.int(1, n) r@nxt <- c(seq_len(n), -1L, 0L) r@prv <- c(n + 1L, s, -1L) # @<- will error if n + 1L overflows r }) setMethod("Cholesky", signature(A = "matrix"), function(A, uplo = "U", ...) { ch <- Cholesky(forceSymmetric(A, uplo), ...) if(!is.null(dn <- dimnames(A))) ch@Dimnames <- dn # restore asymmetric 'Dimnames' ch }) ## METHODS FOR GENERIC: chol2inv ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("chol2inv", signature(x = "generalMatrix"), function(x, uplo = "U", ...) { d <- x@Dim if(d[1L] != d[2L]) stop("matrix is not square") chol2inv((if( uplo == "U") triu else tril)(x), ...) }) setMethod("chol2inv", signature(x = "symmetricMatrix"), function(x, ...) chol2inv((if(x@uplo == "U") triu else tril)(x), ...)) setMethod("chol2inv", signature(x = "triangularMatrix"), function(x, ...) chol2inv(.M2kind(x, ","), ...)) setMethod("chol2inv", signature(x = "diagonalMatrix"), function(x, ...) chol2inv(.M2kind(x, ","), ...)) for(.cl in paste0("dt", c("r", "p"), "Matrix")) setMethod("chol2inv", signature(x = .cl), function(x, ...) { if(x@diag != "N") x <- ..diagU2N(x) r <- .Call(Cholesky_solve, x, NULL) i <- if(x@uplo == "U") 2L else 1L r@Dimnames <- x@Dimnames[c(i, i)] r }) rm(.cl) for(.cl in paste0("dt", c("C", "R", "T"), "Matrix")) setMethod("chol2inv", signature(x = .cl), function(x, ...) (if(x@uplo == "U") tcrossprod else crossprod)(solve(x))) rm(.cl) ## 'uplo' can affect the 'Dimnames' of the result here : setMethod("chol2inv", signature(x = "ddiMatrix"), function(x, uplo = "U", ...) (if( uplo == "U") tcrossprod else crossprod)(solve(x))) ## METHODS FOR CLASS: p?Cholesky ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setAs("Cholesky", "dtrMatrix", function(from) { to <- new("dtrMatrix") to@Dim <- from@Dim to@uplo <- from@uplo to@x <- from@x to }) setAs("pCholesky", "dtpMatrix", function(from) { to <- new("dtpMatrix") to@Dim <- from@Dim to@uplo <- from@uplo to@x <- from@x to }) setMethod("diag", signature(x = "Cholesky"), function(x, nrow, ncol, names = TRUE) { d <- diag(as(x, "dtrMatrix"), names = FALSE) d * d }) setMethod("diag", signature(x = "pCholesky"), function(x, nrow, ncol, names = TRUE) { d <- diag(as(x, "dtpMatrix"), names = FALSE) d * d }) .def.unpacked <- .def.packed <- function(x, which, ...) { d <- x@Dim switch(which, "P1" =, "P1." = { r <- new("pMatrix") r@Dim <- d r@perm <- if(length(x@perm)) x@perm else seq_len(d[1L]) if(which == "P1.") r@margin <- 2L r }, "L" =, "L." =, "L1" =, "L1." = { r <- as(x, .CL) uplo <- x@uplo if(which == "L1" || which == "L1.") { r.ii <- diag(r, names = FALSE) r@x <- r@x / if(uplo == "U") .UP else .LO r@diag <- "U" } if((which == "L." || which == "L1.") == (uplo == "U")) r else t(r) }, "D" = { r <- new("ddiMatrix") r@Dim <- d r@x <- diag(x, names = FALSE) r }, stop(gettextf("'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%3$s\", \"%3$s.\", \"%3$s1\", \"%3$s1.\", or \"%4$s\"", "which", "P", "L", "D"), domain = NA)) } body(.def.unpacked) <- do.call(substitute, list(body(.def.unpacked), list(.CL = "dtrMatrix", .UP = quote(r.ii), .LO = quote(rep(r.ii, each = d[1L]))))) body(.def.packed) <- do.call(substitute, list(body(.def.packed), list(.CL = "dtpMatrix", .UP = quote(r.ii[sequence.default(seq_len(d[1L]))]), .LO = quote(rep.int(r.ii, seq.int(to = 1L, by = -1L, length.out = d[1L])))))) setMethod("expand1", signature(x = "Cholesky"), .def.unpacked) setMethod("expand1", signature(x = "pCholesky"), .def.packed) rm(.def.unpacked, .def.packed) ## returning list(P1', L1, D, L1', P1) or list(P1', L, L', P1), ## where A = P1' L1 D L1' P1 = P1' L L' P1 and L = L1 sqrt(D) .def.unpacked <- .def.packed <- function(x, LDL = TRUE, ...) { d <- x@Dim dn <- x@Dimnames uplo <- x@uplo perm <- x@perm P <- new("pMatrix") P@Dim <- d P@Dimnames <- c(list(NULL), dn[2L]) P@margin <- 2L P@perm <- if(length(perm)) invertPerm(perm) else seq_len(d[1L]) P. <- P P.@Dimnames <- c(dn[1L], list(NULL)) P.@margin <- 1L X <- as(x, .CL) if(LDL) { L.ii <- diag(X, names = FALSE) X@x <- X@x / if(uplo == "U") .UP else .LO X@diag <- "U" } L <- if(uplo == "U") t(X) else X L. <- if(uplo == "U") X else t(X) if(LDL) { D <- new("ddiMatrix") D@Dim <- d D@x <- L.ii * L.ii list(P1. = P., L1 = L, D = D, L1. = L., P1 = P) } else list(P1. = P., L = L, L. = L., P1 = P) } body(.def.unpacked) <- do.call(substitute, list(body(.def.unpacked), list(.CL = "dtrMatrix", .UP = quote(L.ii), .LO = quote(rep(L.ii, each = d[1L]))))) body(.def.packed) <- do.call(substitute, list(body(.def.packed), list(.CL = "dtpMatrix", .UP = quote(L.ii[sequence.default(seq_len(d[1L]))]), .LO = quote(rep.int(L.ii, seq.int(to = 1L, by = -1L, length.out = d[1L])))))) ## returning list(L1, D, L1') or list(L, L'), where A = L1 D L1' = L L' setMethod("expand2", signature(x = "Cholesky"), .def.unpacked) setMethod("expand2", signature(x = "pCholesky"), .def.packed) rm(.def.unpacked, .def.packed) ## METHODS FOR CLASS: CHMfactor ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .CHM.is.perm <- function(x) !as.logical(x@type[1L]) .CHM.is.LDL <- function(x) !as.logical(x@type[2L]) .CHM.is.super <- function(x) as.logical(x@type[3L]) # Exported: isLDL <- function(x) { if(is(x, "CHMfactor")) .CHM.is.LDL(x) else stop(gettextf("'%s' does not inherit from virtual class %s", "x", "CHMfactor"), domain = NA) } setAs("CHMsimpl", "dtCMatrix", function(from) { nz <- from@nz k <- sequence.default(nz, from@p[seq_along(nz)] + 1L) to <- new("dtCMatrix") to@Dim <- from@Dim to@uplo <- "L" to@p <- c(0L, cumsum(nz)) to@i <- from@i[k] to@x <- from@x[k] to }) setAs("CHMsuper", "dgCMatrix", function(from) { super <- from@super pi <- from@pi b <- length(super) nr <- pi[-1L] - pi[-b] nc <- super[-1L] - super[-b] dp <- rep.int(nr, nc) to <- new("dgCMatrix") to@Dim <- from@Dim to@p <- c(0L, cumsum(dp)) to@i <- from@s[sequence.default(dp, rep.int(pi[-b] + 1L, nc))] to@x <- from@x to }) setMethod("diag", signature(x = "CHMfactor"), function(x, nrow, ncol, names = TRUE) .Call(CHMfactor_diag_get, x, TRUE)) setMethod("expand1", signature(x = "CHMsimpl"), function(x, which, ...) { switch(which, "P1" =, "P1." = { r <- new("pMatrix") r@Dim <- d <- x@Dim r@perm <- if(length(x@perm)) x@perm + 1L else seq_len(d[1L]) if(which == "P1.") r@margin <- 2L r }, "L" =, "L." =, "L1" =, "L1." = { r <- as(x, "dtCMatrix") LDL. <- .CHM.is.LDL(x) if(which == "L1" || which == "L1.") { if(!LDL.) { r.ii <- diag(r, names = FALSE) r.p <- r@p r@x <- r@x / rep.int(r.ii , r.p[-1L] - r.p[-length(r.p)]) } diag(r) <- 1 } else if(LDL.) { r.ii <- diag(r, names = FALSE) r.p <- r@p if(anyNA(r.ii)) stop(gettextf("D[i,i] is NA, i=%d", which.max(is.na(r.ii))), domain = NA) if(min(r.ii) < 0) stop(gettextf("D[i,i] is negative, i=%d", which.max(r.ii < 0)), domain = NA) diag(r) <- 1 r@x <- r@x * rep.int(sqrt(r.ii), r.p[-1L] - r.p[-length(r.p)]) } if(which == "L" || which == "L1") r else t(r) }, "D" = { r <- new("ddiMatrix") r@Dim <- x@Dim r@x <- diag(x, names = FALSE) r }, stop(gettextf("'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%3$s\", \"%3$s.\", \"%3$s1\", \"%3$s1.\", or \"%4$s\"", "which", "P", "L", "D"), domain = NA)) }) setMethod("expand1", signature(x = "CHMsuper"), function(x, which, ...) { switch(which, "P1" =, "P1." = { r <- new("pMatrix") r@Dim <- d <- x@Dim r@perm <- if(length(x@perm)) x@perm + 1L else seq_len(d[1L]) if(which == "P1.") r@margin <- 2L r }, "L" =, "L." =, "L1" =, "L1." = { r <- as(x, "dgCMatrix") if(which == "L1" || which == "L1.") { r.ii <- diag(r, names = FALSE) r.p <- r@p r@x <- r@x / rep.int(r.ii, r.p[-1L] - r.p[-length(r.p)]) diag(r) <- 1 } if(which == "L" || which == "L1") r else t(r) }, "D" = { r <- new("ddiMatrix") r@Dim <- x@Dim r@x <- diag(x, names = FALSE) r }, stop(gettextf("'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%3$s\", \"%3$s.\", \"%3$s1\", \"%3$s1.\", or \"%4$s\"", "which", "P", "L", "D"), domain = NA)) }) ## returning list(P1', L1, D, L1', P1) or list(P1', L, L', P1), ## where A = P1' L1 D L1' P1 = P1' L L' P1 and L = L1 sqrt(D) setMethod("expand2", signature(x = "CHMsimpl"), function(x, LDL = TRUE, ...) { d <- x@Dim dn <- x@Dimnames perm <- x@perm P <- new("pMatrix") P@Dim <- d P@Dimnames <- c(list(NULL), dn[2L]) P@margin <- 2L P@perm <- if(length(perm)) invertPerm(perm, 0L, 1L) else seq_len(d[1L]) P. <- P P.@Dimnames <- c(dn[1L], list(NULL)) P.@margin <- 1L L <- as(x, "dtCMatrix") LDL. <- .CHM.is.LDL(x) if(!LDL && !LDL.) return(list(P1. = P., L = L, L. = t(L), P1 = P)) L.ii <- diag(L, names = FALSE) L.p <- L@p if(!LDL) { if(anyNA(L.ii)) stop(gettextf("D[i,i] is NA, i=%d", which.max(is.na(L.ii))), domain = NA) if(min(L.ii) < 0) stop(gettextf("D[i,i] is negative, i=%d", which.max(L.ii < 0)), domain = NA) diag(L) <- 1 L@x <- L@x * rep.int(sqrt(L.ii), L.p[-1L] - L.p[-length(L.p)]) return(list(P1. = P., L = L, L. = t(L), P1 = P)) } D <- new("ddiMatrix") D@Dim <- d if(LDL.) { diag(L) <- 1 D@x <- L.ii } else { L@x <- L@x / rep.int(L.ii , L.p[-1L] - L.p[-length(L.p)]) D@x <- L.ii * L.ii } list(P1. = P., L1 = L, D = D, L1. = t(L), P1 = P) }) ## returning list(P1', L1, D, L1', P1) or list(P1', L, L', P1), ## where A = P1' L1 D L1' P1 = P1' L L' P1 and L = L1 sqrt(D) setMethod("expand2", signature(x = "CHMsuper"), function(x, LDL = TRUE, ...) { d <- x@Dim dn <- x@Dimnames perm <- x@perm P <- new("pMatrix") P@Dim <- d P@Dimnames <- c(list(NULL), dn[2L]) P@margin <- 2L P@perm <- if(length(perm)) invertPerm(perm, 0L, 1L) else seq_len(d[1L]) P. <- P P.@Dimnames <- c(dn[1L], list(NULL)) P.@margin <- 1L L <- as(x, "dgCMatrix") if(!LDL) return(list(P1. = P., L = L, L. = t(L), P1 = P)) L.ii <- diag(L, names = FALSE) L.p <- L@p L@x <- L@x / rep.int(L.ii, L.p[-1L] - L.p[-length(L.p)]) diag(L) <- 1 D <- new("ddiMatrix") D@Dim <- d D@x <- L.ii * L.ii list(P1. = P., L1 = L, D = D, L1. = t(L), P1 = P) }) ## returning list(P, L), where A = P' L L' P ## MJ: for backwards compatibility setMethod("expand", signature(x = "CHMfactor"), function(x, ...) list(P = expand1(x, "P1"), L = expand1(x, "L"))) .updateCHMfactor <- function(object, parent, mult = 0) .Call(CHMfactor_update, object, parent, mult) setMethod("update", signature(object = "CHMfactor"), function(object, parent, mult = 0, ...) { parent <- .M2kind(.M2C(parent), ",") if((shape <- .M.shape(parent)) != "s") { Matrix.message(gettextf("'%1$s' is not formally symmetric; factorizing tcrossprod(%1$s)", "parent"), domain = NA) if(shape == "t" && parent@diag != "N") parent <- ..diagU2N(parent) } .updateCHMfactor(object, parent, mult) }) .updownCHMfactor <- function(update, C, L) .Call(CHMfactor_updown, L, C, update) setMethod("updown", signature(update = "character", C = "ANY", L = "ANY"), function(update, C, L) updown(identical(update, "+"), C, L)) setMethod("updown", signature(update = "logical", C = "Matrix", L = "CHMfactor"), function(update, C, L) updown(update, .M2kind(.M2C(C), ","), L)) for(.cl in c("dgCMatrix", "dsCMatrix")) setMethod("updown", signature(update = "logical", C = .cl, L = "CHMfactor"), function(update, C, L) { if(length(perm <- L@perm)) C <- C[perm + 1L, , drop = FALSE] .updownCHMfactor(update, C, L) }) rm(.cl) setMethod("updown", signature(update = "logical", C = "dtCMatrix", L = "CHMfactor"), function(update, C, L) { if(C@diag != "N") C <- ..diagU2N(C) if(length(perm <- L@perm)) C <- C[perm + 1L, , drop = FALSE] .updownCHMfactor(update, C, L) }) setMethod("updown", signature(update = "logical", C = "matrix", L = "CHMfactor"), function(update, C, L) updown(update, .m2sparse(C, ",gC"), L)) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Matrix/R/abIndex.R����������������������������������������������������������������������������������0000644�0001762�0000144�00000056660�12622367447�013446� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#### Methods for the "abIndex" := ``abstract Index'' class ### Note: this partly builds on ideas and code from Jens Oehlschlaegel, ### ---- as implemented (in the GPL'ed part of) package 'ff'. ## Basic idea: a vector x of integer indices often has long stretches ## i, i+1, i+2, ... such that diff(x) has stretches of '1'. ## Now keep x[1] =: first and diff(x) =: d, ## and use rle() to encode d. Here, use a C version for rle() rleMaybe <- function(i, force = FALSE) { ## TODO: move all this to a new C fnc., still keeping the *_i() and *_d() if(is.na(force <- as.logical(force))) stop("'force' must be (coercable to) TRUE or FALSE") int <- is.integer(i) || is.logical(i) || { i. <- suppressWarnings(as.integer(i)) if(r <- isTRUE(all(is.na(i) | i. == i))) i <- i. r } ## if(int), 'i' will be coerced to integer on C level ##N R-devel codetools get FP again: ##N Matrix.rle <- if(int) Matrix_rle_i else Matrix_rle_d ##N .Call(Matrix.rle, i, force) if(int) Matrix_rle_d <- Matrix_rle_i .Call(Matrix_rle_d, i, force) } .rle <- function(lengths, values) structure(list(lengths = lengths, values = values), class = "rle") ##' @param x ##' ##' @return diff(x), giving '0' for 'Inf - Inf' or similar .diff <- function(x) { ## TODO: considerably faster in C if((n <- length(x)) <= 1) return(x[0]) r <- (x1 <- x[-1]) - (x2 <- x[-n]) if(any(ina <- is.na(r))) r[ina & (x1 == x2 | (is.na(x1) & is.na(x2)))] <- 0 r } ##' @param from: logical or numeric vector ##' ##' @return an "abIndex" vector, "semantically equivalent" to 'from' vec2abI <- function(from, force = FALSE) { ans <- new("abIndex") r <- rleMaybe(.diff(from), force=force)## .diff(): also work for rep(Inf, *) if(is.null(r)) { ## no "compression" ans@kind <- if(is.integer(from)) "int32" else "double" ans@x <- from } else { ans@kind <- "rleDiff" ## ans@x <- integer(0) # <- prototype does that ans@rleD <- new("rleDiff", first = from[1], rle = r) } ans } ## "abIndex" version of indDiag(n) === which(diag(n) == 1) -> ./Auxiliaries.R abIindDiag <- function(n) { ## cumsum(c(1L, rep.int(n+1L, n-1))) stopifnot((n <- as.integer(n)) >= 1) rl <- if(n == 1) .rle(n[0],n[0]) else .rle(n-1L, n+1L) new("abIndex", kind = "rleDiff", rleD = new("rleDiff", first = 1, rle = rl)) } ## "abIndex" version of indTri(n) ... --> ./Auxiliaries.R abIindTri <- function(n, upper = TRUE, diag = FALSE) { ## Indices of strict upper/lower triangular part ## == which(upper.tri(diag(n), diag=diag) or ## which(lower.tri(diag(n), diag=diag) -- but as abIndex stopifnot(length(n) == 1, n == (n. <- as.integer(n)), (n <- n.) >= 0) if(n <= 2) { vec2abI( if(n == 0) integer(0) else if(n == 1) { if(diag) 1L else integer(0) } else { ## n == 2 v <- if(upper) 3L else 2L if(diag) c(1L, v, 4L) else v }) } else { ## n >= 3 [also for n == 2 && diag (==TRUE)] : ## First, compute the 'diff(.)' of the result [fast, using integers] n. <- if(diag) n else n - 1L n1 <- n. - 1L tt <- if(diag) 2L else 3L mk1s <- function(n,m) as.vector(rbind(1L, n:m)) mks1 <- function(n,m) as.vector(rbind(n:m, 1L)) rl <- .rle(lengths= if(upper) mk1s(1L,n1) else mks1(n1,1L), values = if(upper) mks1(n, tt) else mk1s(tt, n)) frst <- if(diag) 1L else if(upper) n+1L else 2L new("abIndex", kind = "rleDiff", rleD = new("rleDiff", first = frst, rle = rl)) } } setAs("numeric", "abIndex", function(from) vec2abI(from)) setAs("logical", "abIndex", function(from) vec2abI(from)) setMethod("show", "rleDiff", function(object) { cat(sprintf(## first can be 'NULL' --> cannot use %g " RLE difference (class 'rleDiff'): first = %s, \"rle\":%s", format(object@first), if(length(rl <- object@rle)) "\n" else " ")) print(rl, prefix = " ") invisible(object) }) setMethod("show", "abIndex", function(object) { knd <- object@kind cat(sprintf( "Abstract Index vector (class 'abIndex') of length %.0f, kind \"%s\"\n", length(object), knd)) if(knd == "rleDiff") { ### FIXME: show something like this is equivalent to c(2:10, 13:34, ...) cat(" and slot \"rleD\":\n") show(object@rleD) } else { cat(" and \"x\" slot\n") show(object@x) } invisible(object) }) ##' Constructor of "abIndex" version of n:m ##' @param from ##' @param to ##' ##' @return an "abIndex" object semantically equivalent to from:to abIseq1 <- function(from = 1, to = 1) { stopifnot(length(from) == 1L, length(to) == 1L) to <- to - from new("abIndex", kind="rleDiff", rleD = new("rleDiff", first = as.integer(from), rle = .rle(lengths = abs(to),# <- double : maybe > .Machine$integer.max values = as.integer(sign(to))))) } ## an "abIndex" version of seq(), i.e. seq.default(): abIseq <- function(from = 1, to = 1, by = ((to - from)/(length.out - 1)), length.out = NULL, along.with = NULL) { if((One <- nargs() == 1L) && !missing(from)) { lf <- length(from) return(if(mode(from) == "numeric" && lf == 1L) abIseq1(1L, from) else if(lf) abIseq1(1L, lf) else new("abIndex")) } if(!missing(along.with)) { length.out <- length(along.with) if(One) return(if(length.out) abIseq1(1L, length.out) else new("abIndex")) } else if(!missing(length.out)) length.out <- ceiling(length.out) if(is.null(length.out)) if(missing(by)) abIseq1(from,to) else { # dealing with 'by' del <- to - from if(del == 0 && to == 0) return(as(to, "abIndex")) n <- del/by if(!(length(n) && is.finite(n))) { if(length(by) && by == 0 && length(del) && del == 0) return(as(from, "abIndex")) stop("invalid (to - from)/by in seq(.)") } if(n < 0L) stop("wrong sign in 'by' argument") if(n > .Machine$integer.max) stop("'by' argument is much too small") dd <- abs(del)/max(abs(to), abs(from)) if (dd < 100*.Machine$double.eps) return(from) n <- as.integer(n + 1e-7) x <- from + abIseq1(0L,n) * by ## correct for overshot because of fuzz -- FIXME: need pmin() for "abIndex": if(by > 0) pmin(x, to) else pmax(x, to) } else if(!is.finite(length.out) || length.out < 0L) stop("length must be non-negative number") else if(length.out == 0L) new("abIndex") else if (One) abIseq1(1L, length.out) else if(missing(by)) { # if(from == to || length.out < 2) by <- 1 if(missing(to)) to <- from + length.out - 1L if(missing(from)) from <- to - length.out + 1L if(length.out > 2L) if(from == to) rep2abI(from, length.out) ## rep.int(from, length.out) else c(as(from,"abIndex"), from + abIseq1(1L, length.out - 2L) * by, to) else as(c(from, to)[seq_len(length.out)],"abIndex") } else if(missing(to)) from + abIseq1(0L, length.out - 1L) * by else if(missing(from)) to - abIseq1(length.out - 1L, 0L) * by else stop("too many arguments") } ##' rep.int(x, times) " as abIndex " ##' @param x numeric vector ##' @param times integer (valued) scalar: the number of repetitions ##' ##' @return an "abIndex" vector rep2abI <- function(x, times) { r <- new("abIndex") if((n <- length(x)) == 0) return(r) if(n == 1) { # clear case for compression r@kind <- "rleDiff" rD <- new("rleDiff") rD@first <- x[1L] rD@rle <- .rle(lengths = times - 1L, values = 0L) r@rleD <- rD } else { ## n >= 2 .. check if compression is worth it: ## .. say if compression of x itself is worth {FIXME? optimal cutoff} rr <- rleMaybe(.diff(x)) if(is.null(rr)) { r@kind <- if(is.integer(x)) "int32" else "double" r@x <- rep.int(x, times) } else { r@kind <- "rleDiff" rD <- new("rleDiff") rD@first <- x[1L] Dx <- x[1L] - x[length(x)] N <- (length(rr$lengths) + 1L)*times rD@rle <- .rle(lengths = rep.int(c(rr$lengths, 1L), times)[-N], values = rep.int(c(rr$values, Dx), times)[-N]) r@rleD <- rD } } r } combine_rleD <- function(rleList, m = length(rleList)) { ## Combine list of "rleDiff"s into a new one -- for c(..) ## auxiliary (and main working horse) for c.abIndex() ### TODO: really should do this in C i1 <- unlist(lapply(rleList, slot, "first")) rles <- lapply(rleList, slot, "rle") ## the list of vectors of 'lengths' and 'values' : lens <- lapply(rles, `[[`, "lengths") vals <- lapply(rles, `[[`, "values") ## the 'ends' are needed for the "jump sizes" in between: ends2 <- function(x) # related to ends.rleD() above x@first + c(0, with(x@rle, sum(lengths*values))) ends <- unlist(lapply(rleList, ends2))[-c(1, 2*m)] ii <- 2L*seq_len(m - 1) d.ends <- ends[ii] - ends[ii-1L] ## llen1 <- unlist(lapply(lens, length)) + 1L ## n <- sum(llen1) n <- m + sum(lengths(lens, use.names=FALSE)) ## comb(): intersperse x2[[j]] between lis[[j] & lis[[j+1]] : comb <- function(lis, x2) unlist(mapply(c, lis, x2, SIMPLIFY=FALSE, USE.NAMES=FALSE)) n.len <- comb(lens, 1L)[-n] n.val <- comb(vals, c(d.ends,NA))[-n] new("rleDiff", first = i1[1], rle = .rle(lengths = n.len, values = n.val)) } ## {combine_rleD} ## For now -- S4 method on c(), i.e., setMethod("c", ...) ## seems "difficult", and this works "magically" ## when the first argument is an abIndex : c.abIndex <- function(...) { m <- length(list(...)) if(m <= 1) return(if(m == 0) new("abIndex") else as(..1, "abIndex")) ## else: have length m >= 2 labi <- lapply(list(...), as, Class = "abIndex") knd <- unlist(lapply(labi, slot, "kind")) ## Convention: Result kind should be the 'kind' of the first neq.k <- knd != (k1 <- knd[1]) if(any(neq.k)) { if(all(not.rD <- knd != "rleDiff")) { ## either "double" or "int32" .. using 'x' k1 <- "double" ## and it will just work to c(.) the 'x' slots } else { warning("c(,..) of different kinds, coercing all to 'rleDiff'") labi[not.rD] <- lapply(labi[not.rD], function(av) vec2abI(av@x, force=TRUE)) k1 <- "rleDiff" } } switch(k1, "rleDiff" = { new("abIndex", kind="rleDiff", rleD = combine_rleD(lapply(labi, slot, "rleD"), m)) }, "double" =, "int32" = { new("abIndex", kind = k1, x = do.call(c, lapply(labi, slot, "x"))) }) } setMethod("length", "abIndex", function(x) if(identical(x@kind, "rleDiff")) sum(x@rleD@rle$lengths)+ 1L else length(x@x)) abI2num <- function(from) { switch(from@kind, "rleDiff" = { x <- from@rleD ## as inverse.rle(): cumsum(c(x@first, rep.int(x@rle$values, x@rle$lengths))) }, "int32" =, "double" = from@x) } setAs("abIndex", "numeric", abI2num) setAs("abIndex", "vector", abI2num) setAs("abIndex", "integer", function(from) as.integer(abI2num(from))) ## for S3 lovers and back-compatibility: setMethod(as.integer, "abIndex", function(x) as.integer(abI2num(x))) setMethod(as.numeric, "abIndex", function(x) abI2num(x)) setMethod("as.vector", "abIndex", function(x, mode) as.vector(abI2num(x), mode)) ## Need max(
), min(), all( == ) any( == ) ## ---> Groups "Summary" and "Compare" (maybe all "Ops") ## For that, we really need "[" and/or "rep"() methods -- TODO -- ## setMethod("[", signature(x = "abIndex", i = "index"), function (x, i, j, ..., drop) { switch(x@kind, "rleDiff" = { ## FIXME ## intIv() in ./sparseVector.R -- not memory-efficient (??) ## n <- length(x) ## ii <- intIv(i, n) ## ii : 1-based integer indices ## d <- x@rleD ## Now work with the equivalent of ## cumsum(c(d@first, rep.int(d@rle$values, d@rle$lengths))) stop("[i] is not yet implemented") }, "int32" =, "double" = ## as it's not rle-packed, can remain simple: x@x[i]) }) ##' Endpoints of all linear stretches -- auxiliary for range(.) ##' @param x an "rleDiff" object ##' ##' @return numeric vector of end points of all linear stretches of x. ends.rleD <- function(x) { rl <- x@rle stopifnot(length(lens <- rl$lengths) == length(vals <- rl$values)) cumsum(c(x@first, lens*vals)) } ##' Collapse or "uniquify" an 'rle' object, i.e., ##' 1) drop 'lengths' 0 parts ##' 2) *merge* adjacent parts where 'values' are the same ##' ##' @param x an "rle" object ##' ##' @return an "rle" object, a "unique" version of the input 'x' rleCollapse <- function(x) { ## TODO: faster (and simpler!) in C ## TODO(2): move this to 'R base' L <- x$lengths V <- x$values chng <- FALSE if((chng <- any(i0 <- L == 0))) { ## drop 0 'lengths' parts L <- L[!i0] ; V <- V[!i0] } ## FIXME: This is not elegant nor efficient: while(any(i0 <- diff(V) == 0)) { ## merge adjacent parts with same values if(!chng) chng <- TRUE ## fix one stretch (and repeat), starting at ii0 and total length 1+ li0 ii0 <- which.max(i0)# index of first TRUE li0 <- if((l0 <- length(i0)) <= ii0) 1 else which.min(!i0[ii0:l0]) stopifnot(li0 >= 1)## <- for now L[ii0] <- sum(L[ii0+(0:li0)]) ii <- -(ii0 + seq_len(li0)) L <- L[ii] V <- V[ii] } if(chng) { x$lengths <- L ; x$values <- V } x } ## {rleCollapse} setMethod("drop", "abIndex", function(x) { if(x@kind == "rleDiff") x@rleD@rle <- rleCollapse(x@rleD@rle) x }) ## Summary: { max, min, range, prod, sum, any, all } : ## have 'summGener1' := those without prod, sum setMethod("Summary", signature(x = "abIndex", na.rm = "ANY"), function(x, ..., na.rm) { switch(x@kind, "rleDiff" = { d <- x@rleD if(.Generic %in% c("range","min","max")) { callGeneric(ends.rleD(d), ..., na.rm=na.rm) } else { ## "sum", "prod" : switch(.Generic, "all" = { ## these often, but *not* always come in pairs ## en <- ends.rleD(d) ## so maybe it does not really help! stop("all() is not yet implemented") ## all(c(d@first, d@rle$values), ..., na.rm=na.rm) }, "any" = any(c(d@first, d@rle$values), ..., na.rm=na.rm), "sum" = { stop("sum() is not yet implemented") }, "prod"= { stop("prod() is not yet implemented") }) } }, "int32" =, "double" = callGeneric(x@x, ..., na.rm = na.rm) ) }) ### "Ops" := sub-groups "Arith", "Compare", and "Logic" ## ## For now (*), only "Arith" does make sense ## --> keep "Ops" undefined and define "Arith" : ## ---- ## (*) : TODO: logical <-> abIndex --> "Compare" etc as well setMethod("Ops", signature(e1 = "abIndex", e2 = "abIndex"), function(e1, e2) { .bail.out.2(.Generic, class(e1), class(e2)) }) setMethod("Ops", signature(e1 = "abIndex", e2 = "ANY"), function(e1, e2) { .bail.out.2(.Generic, class(e1), class(e2)) }) setMethod("Ops", signature(e1 = "ANY", e2 = "abIndex"), function(e1, e2) { .bail.out.2(.Generic, class(e1), class(e2)) }) setMethod("Arith", signature(e1 = "abIndex", e2 = "abIndex"), function(e1, e2) { l1 <- length(e1) l2 <- length(e2) mM <- range(l1,l2) stop("not yet implemented") ## FIXME ------------------ if(mM[1] != mM[2]) { ## lengths differ if(mM[1] %% mM[2] != 0) ## identical warning as in main/arithmetic.c warning("longer object length\n\tis not a multiple of shorter object length") if(l1 < l2) { } else { ## l1 > l2 } } switch(e1@kind, "rleDiff" = { }, "int32" =, "double" = { }) }) ## numLike = {numeric, logical}: setMethod("Arith", signature(e1 = "abIndex", e2 = "numLike"), function(e1, e2) { if(!length(e1)) return(e1) if(e1@kind != "rleDiff") { # no compression e1@x <- callGeneric(e1@x, e2) if(e1@kind != "double" && is.double(e1@x)) e1@kind <- "double" return(e1) } if(length(e2) == 1) { ## scalar if(is.na(e2)) return(rep2abI(e2, length(e1))) ## else 'e2' is not NA and scalar switch(.Generic, "+" =, "-" = { e1@rleD@first <- callGeneric(e1@rleD@first, e2) e1 }, "*" = { e1@rleD@first <- e1@rleD@first * e2 r <- e1@rleD@rle$values * e2 if(is0(e2) && all0(r)) { ## result all 0: collapse e1@rleD@rle$values <- r[1L] e1@rleD@rle$lengths <- sum(e1@rleD@rle$lengths) } else ## normal case e1@rleD@rle$values <- r e1 }, "/" = { if(is0(e2) ## division by 0 && length(unique(sign(ends.rleD(e1@rleD)))) > 1) { ## at least one subsequence contains 0, i.e., changes sign: warning("x / 0 for an x with sign-change\n no longer representable as 'rleDiff'") return(vec2abI(abI2num(e1) / 0)) } e1@rleD@first <- e1@rleD@first / e2 e1@rleD@rle$values <- e1@rleD@rle$values / e2 e1 }, "^" = { if(e2 == 1) e1 else vec2abI(abI2num(e1) ^ e2) }, "%%" = , "%/%" = vec2abI(callGeneric(abI2num(e1), e2))) } else ## length(e2) != 1 callGeneric(e1, as(e2, "abIndex")) }) setMethod("Arith", signature(e1 = "numLike", e2 = "abIndex"), function(e1, e2) { if(!length(e2)) return(e2) if(e2@kind != "rleDiff") { # no compression e2@x <- callGeneric(e1, e2@x) if(e2@kind != "double" && is.double(e2@x)) e2@kind <- "double" return(e2) } if(length(e1) == 1) { ## scalar if(is.na(e1)) return(rep2abI(e1, length(e2))) ## else 'e1' is not NA and scalar switch(.Generic, "+" = { e2@rleD@first <- e1 + e2@rleD@first e2 }, "-" = { e2@rleD@first <- e1 - e2@rleD@first e2@rleD@rle$values <- -e2@rleD@rle$values e2 }, "*" = { e2@rleD@first <- e1 * e2@rleD@first r <- e1 * e2@rleD@rle$values if(is0(e1) && all0(r)) { ## result all 0: collapse e2@rleD@rle$values <- r[1L] e2@rleD@rle$lengths <- sum(e2@rleD@rle$lengths) } else ## normal case e2@rleD@rle$values <- r e2 }, "/" = , "^" =, "%%" = , "%/%" = vec2abI(callGeneric(e1, abI2num(e2)))) } else ## length(e1) != 1 callGeneric(as(e1, "abIndex"), e2) }) setMethod("is.na", signature(x = "abIndex"), function(x) { if(x@kind != "rleDiff") is.na(x@x) else { rd <- x@rleD rl <- rd@rle len <- 1+ sum(L <- rl$lengths) if(is.na(rd@first)) rep.int(TRUE, len) else { ## interesting case V <- rl$values if(!any(ina <- is.na(V))) rep.int(FALSE, len) else { ## at least one V is NA --> "x" is NA from then on: k <- match(TRUE,ina) # the first one l1 <- 1+ sum(L[seq_len(k-1)]) c(rep.int(FALSE, l1), rep.int(TRUE, len - l1)) } } } }) ## TODO ?? "is.nan" analogously ?? ## setMethod("is.finite", signature(x = "abIndex"), function(x) { if(x@kind != "rleDiff") is.finite(x@x) else { rd <- x@rleD rl <- rd@rle len <- 1+ sum(L <- rl$lengths) if(!is.finite(rd@first)) rep.int(FALSE, len) else { ## interesting case V <- rl$values if(all(iFin <- is.finite(V))) rep.int(TRUE, len) else { ## at least one V is +- Inf --> "x" is Inf/NaN from there k <- match(FALSE,iFin) # the first non-finite one l1 <- 1+ sum(L[seq_len(k-1)]) c(rep.int(TRUE, l1), rep.int(FALSE, len - l1)) } } } }) setMethod("is.infinite", signature(x = "abIndex"), function(x) { if(x@kind != "rleDiff") is.infinite(x@x) else { rd <- x@rleD rl <- rd@rle len <- 1+ sum(L <- rl$lengths) if(is.infinite(rd@first)) rep.int(TRUE, len) else { ## interesting case V <- rl$values if(!any(iInf <- is.infinite(V))) rep.int(FALSE, len) else { ## at least one V is +- Inf --> "x" is Inf/NaN from there k <- match(TRUE,iInf) # the first one l1 <- 1+ sum(L[seq_len(k-1)]) ## FIXME? do *not* consider 'NaN' (changing TRUE to FALSE): c(rep.int(FALSE, l1), rep.int(TRUE, len - l1)) } } } }) all.equal.abI <- function(target, current, ...) { if(!is(target, "abIndex") || !is(current, "abIndex")) return(paste0("target is ", data.class(target), ", current is ", data.class(current))) lt <- length(target) lc <- length(current) if(lt != lc) paste0("abIndex", ": lengths (", lt, ", ", lc, ") differ") else if(target@kind == current@kind) { all.equal.default(target, current, ...) } else ## different 'kinds' -- take "easy" exit: all.equal(abI2num(target), abI2num(current), ...) } ## {all.equal.abI} setMethod("all.equal", c(target = "abIndex", current = "abIndex"), all.equal.abI) setMethod("all.equal", c(target = "abIndex", current = "numLike"), function(target, current, ...) all.equal.abI(target, as(current, "abIndex"), ...)) setMethod("all.equal", c(target = "numLike", current = "abIndex"), function(target, current, ...) all.equal.abI(as(target, "abIndex"), current, ...)) ## Then I want something like get.ind.sel(.) [ ./Tsparse.R ] working, ## i.e. possibly match(i, , nomatch = 0) setAs("seqMat", "numeric", function(from) { do.call(c, lapply(seq_len(ncol(from)), function(j) seq(from=from[1L,j], to = from[2L,j]))) }) setAs("numeric", "seqMat", function(from) as(as(from, "abIndex"), "seqMat")) setAs("abIndex", "seqMat", function(from) { n <- length(from) d <- from@rleD va <- d@rle$values le <- d@rle$lengths m <- length(le) ## Now work the 'ends' are cumsum(c(d@first, le * va)) ## we need to care for the "length 1" stretches: if(any(nonPair <- le[2* seq_len(m2 <- m %/% 2)] != 1)) { m2 + n + va + nonPair # <- "dummy" using "unused" ## an "easy" (but not so efficient when 'm' is "large") ## way would be to "make these" into pairs, then work for that case... } ## use ~/R/MM/Pkg-ex/Matrix/abIndex-experi.R for trying things ... stop(" --> is not yet implemented") }) setAs("seqMat", "abIndex", function(from) { stop(" --> is not yet implemented") }) Matrix/R/SparseM-conv.R0000644000176200001440000000642114461520115014361 0ustar liggesusers## METHODS ENHANCING PACKAGE: sparseM ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## ~~~~ COERCIONS FROM SparseM TO Matrix ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## Natural pairs setAs("matrix.csc", "dgCMatrix", function(from) new("dgCMatrix", Dim = from@dimension, p = from@ia - 1L, i = from@ja - 1L, x = from@ra)) setAs("matrix.csr", "dgRMatrix", function(from) new("dgRMatrix", Dim = from@dimension, p = from@ia - 1L, j = from@ja - 1L, x = from@ra)) setAs("matrix.coo", "dgTMatrix", function(from) new("dgTMatrix", Dim = from@dimension, i = from@ia - 1L, j = from@ja - 1L, x = from@ra)) ## Remaining matrix.c(sc|sr|oo) to dgCMatrix setAs("matrix.csr", "dgCMatrix", function(from) .M2C(as(from, "dgRMatrix"))) setAs("matrix.coo", "dgCMatrix", function(from) .M2C(as(from, "dgTMatrix"))) ## Each matrix.c(sc|sr|oo) to each [CRT]sparseMatrix setAs("matrix.csc", "CsparseMatrix", function(from) as(from, "dgCMatrix")) setAs("matrix.csc", "RsparseMatrix", function(from) .M2R(as(from, "dgCMatrix"))) setAs("matrix.csc", "TsparseMatrix", function(from) .M2T(as(from, "dgCMatrix"))) setAs("matrix.csr", "CsparseMatrix", function(from) .M2C(as(from, "dgRMatrix"))) setAs("matrix.csr", "RsparseMatrix", function(from) as(from, "dgRMatrix")) setAs("matrix.csr", "TsparseMatrix", function(from) .M2T(as(from, "dgRMatrix"))) setAs("matrix.coo", "CsparseMatrix", function(from) .M2C(as(from, "dgTMatrix"))) setAs("matrix.coo", "RsparseMatrix", function(from) .M2R(as(from, "dgTMatrix"))) setAs("matrix.coo", "TsparseMatrix", function(from) as(from, "dgTMatrix")) ## Each matrix.c(sc|sr|oo) to sparseMatrix, Matrix ("easy") ## NB: favouring column format over row format setAs("matrix.csc", "sparseMatrix", function(from) as(from, "CsparseMatrix")) setAs("matrix.csr", "sparseMatrix", function(from) as(from, "CsparseMatrix")) setAs("matrix.coo", "sparseMatrix", function(from) as(from, "TsparseMatrix")) setAs("matrix.csc", "Matrix", function(from) as(from, "CsparseMatrix")) setAs("matrix.csr", "Matrix", function(from) as(from, "CsparseMatrix")) setAs("matrix.coo", "Matrix", function(from) as(from, "TsparseMatrix")) ## ~~~~ COERCIONS FROM Matrix TO SparseM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## Natural pairs setAs("dgCMatrix", "matrix.csc", function(from) new("matrix.csc", dimension = from@Dim, ia = from@p + 1L, ja = from@i + 1L, ra = from@x)) setAs("dgRMatrix", "matrix.csr", function(from) new("matrix.csr", dimension = from@Dim, ia = from@p + 1L, ja = from@j + 1L, ra = from@x)) setAs("dgTMatrix", "matrix.coo", function(from) new("matrix.coo", dimension = from@Dim, ia = from@i + 1L, ja = from@j + 1L, ra = from@x)) ## Everything else setAs("Matrix", "matrix.csc", function(from) as(as(as(as(from, "dMatrix"), "generalMatrix"), "CsparseMatrix"), "matrix.csc")) setAs("Matrix", "matrix.csr", function(from) as(as(as(as(from, "dMatrix"), "generalMatrix"), "RsparseMatrix"), "matrix.csr")) setAs("Matrix", "matrix.coo", function(from) as(as(as(as(from, "dMatrix"), "generalMatrix"), "TsparseMatrix"), "matrix.coo")) Matrix/R/HBMM.R0000644000176200001440000002002414467575574012613 0ustar liggesusers## Utilities for the Harwell-Boeing and MatrixMarket formats readone <- function(ln, iwd, nper, conv) { ln <- gsub("D", "E", ln) inds <- seq(0, by = iwd, length.out = nper + 1) (conv)(substring(ln, 1 + inds[-length(inds)], inds[-1])) } readmany <- function(conn, nlines, nvals, fmt, conv) { if (!grep("[[:digit:]]+[DEFGI][[:digit:]]+", fmt)) stop("Not a valid format") Iind <- regexpr('[DEFGI]', fmt) nper <- as.integer(substr(fmt, regexpr('[[:digit:]]+[DEFGI]', fmt), Iind - 1)) iwd <- as.integer(substr(fmt, Iind + 1, regexpr('[\\.\\)]', fmt) - 1)) rem <- nvals %% nper full <- nvals %/% nper ans <- vector("list", nvals %/% nper) for (i in seq_len(full)) ans[[i]] <- readone(readLines(conn, 1, ok = FALSE), iwd, nper, conv) if (!rem) return(unlist(ans)) c(unlist(ans), readone(readLines(conn, 1, ok = FALSE), iwd, rem, conv)) } readHB <- function(file) { if (is.character(file)) file <- if (file == "") stdin() else file(file) if (!inherits(file, "connection")) stop("'file' must be a character string or connection") if (!isOpen(file)) { open(file) on.exit(close(file)) } hdr <- readLines(file, 4, ok = FALSE) ## Title <- sub('[[:space:]]+$', '', substr(hdr[1], 1, 72)) ## Key <- sub('[[:space:]]+$', '', substr(hdr[1], 73, 80)) ## totln <- as.integer(substr(hdr[2], 1, 14)) ptrln <- as.integer(substr(hdr[2], 15, 28)) indln <- as.integer(substr(hdr[2], 29, 42)) valln <- as.integer(substr(hdr[2], 43, 56)) rhsln <- as.integer(substr(hdr[2], 57, 70)) if (!(t1 <- substr(hdr[3], 1, 1)) %in% c('C', 'R', 'P')) stop(gettextf("Invalid storage type: %s", t1), domain=NA) if (t1 != 'R') stop("Only numeric sparse matrices allowed") ## _FIXME: Patterns should also be allowed if (!(t2 <- substr(hdr[3], 2, 2)) %in% c('H', 'R', 'S', 'U', 'Z')) stop(gettextf("Invalid storage format: %s", t2), domain=NA) if (!(t3 <- substr(hdr[3], 3, 3)) %in% c('A', 'E')) stop(gettextf("Invalid assembled indicator: %s", t3), domain=NA) nr <- as.integer(substr(hdr[3], 15, 28)) nc <- as.integer(substr(hdr[3], 29, 42)) nz <- as.integer(substr(hdr[3], 43, 56)) ## nel <- as.integer(substr(hdr[3], 57, 70)) ptrfmt <- toupper(sub('[[:space:]]+$', '', substr(hdr[4], 1, 16))) indfmt <- toupper(sub('[[:space:]]+$', '', substr(hdr[4], 17, 32))) valfmt <- toupper(sub('[[:space:]]+$', '', substr(hdr[4], 33, 52))) ## rhsfmt <- toupper(sub('[[:space:]]+$', '', substr(hdr[4], 53, 72))) if (!is.na(rhsln) && rhsln > 0) readLines(file, 1, ok = FALSE) # h5 ptr <- readmany(file, ptrln, nc + 1, ptrfmt, as.integer) ind <- readmany(file, indln, nz, indfmt, as.integer) vals <- readmany(file, valln, nz, valfmt, as.numeric) if (t2 == 'S') new("dsCMatrix", uplo = "L", p = ptr - 1L, i = ind - 1L, x = vals, Dim = c(nr, nc)) else new("dgCMatrix", p = ptr - 1L, i = ind - 1L, x = vals, Dim = c(nr, nc)) } readMM <- function(file) { if (is.character(file)) file <- if(file == "") stdin() else file(file) if (!inherits(file, "connection")) stop("'file' must be a character string or connection") if (!isOpen(file)) { open(file) on.exit(close(file)) } scan1 <- function(what, ...) scan(file, nmax = 1, what = what, quiet = TRUE, ...) if (scan1(character()) != "%%MatrixMarket")# hdr stop("file is not a MatrixMarket file") if (!(typ <- tolower(scan1(character()))) %in% "matrix") stop(gettextf("type '%s' not recognized", typ), domain = NA) if (!(repr <- tolower(scan1(character()))) %in% c("coordinate", "array")) stop(gettextf("representation '%s' not recognized", repr), domain = NA) elt <- tolower(scan1(character())) if (!elt %in% c("real", "complex", "integer", "pattern")) stop(gettextf("element type '%s' not recognized", elt), domain = NA) sym <- tolower(scan1(character())) if (!sym %in% c("general", "symmetric", "skew-symmetric", "hermitian")) stop(gettextf("symmetry form '%s' not recognized", sym), domain = NA) nr <- scan1(integer(), comment.char = "%") nc <- scan1(integer()) nz <- scan1(integer()) checkIJ <- function(els) { if((nz. <- length(els$i)) < nz) warning(gettextf("readMM(): expected %d entries but found only %d", nz, nz.), call. = FALSE, domain = NA) if(any(is.na(els$i) | els$i < 1L | els$i > nr)) stop(gettextf("readMM(): row indices 'i' are not in 1:nrow[=%d]", nr), call. = FALSE, domain = NA) if(any(is.na(els$j) | els$j < 1L | els$j > nc)) stop(gettextf("readMM(): column indices 'j' are not in 1:ncol[=%d]", nc), call. = FALSE, domain = NA) } if (repr == "coordinate") { switch(elt, "real" = , "integer" = { ## TODO: the "integer" element type should be returned as ## an object of an "iMatrix" subclass--once there are els <- scan(file, nmax = nz, quiet = TRUE, what= list(i= integer(), j= integer(), x= numeric())) checkIJ(els) switch(sym, "general" = { new("dgTMatrix", Dim = c(nr, nc), i = els$i - 1L, j = els$j - 1L, x = els$x) }, "symmetric" = { new("dsTMatrix", uplo = "L", Dim = c(nr, nc), i = els$i - 1L, j = els$j - 1L, x = els$x) }, "skew-symmetric" = { stop("symmetry form 'skew-symmetric' not yet implemented for reading") ## FIXME: use dgT... but must expand the (i,j,x) slots! new("dgTMatrix", uplo = "L", Dim = c(nr, nc), i = els$i - 1L, j = els$j - 1L, x = els$x) }, "hermitian" = { stop("symmetry form 'hermitian' not yet implemented for reading") }, ## otherwise (not possible; just defensive programming): stop(gettextf("symmetry form '%s' is not yet implemented", sym), domain = NA) ) }, "pattern" = { els <- scan(file, nmax = nz, quiet = TRUE, what = list(i = integer(), j = integer())) checkIJ(els) switch(sym, "general" = { new("ngTMatrix", Dim = c(nr, nc), i = els$i - 1L, j = els$j - 1L) }, "symmetric" = { new("nsTMatrix", uplo = "L", Dim = c(nr, nc), i = els$i - 1L, j = els$j - 1L) }, "skew-symmetric" = { stop("symmetry form 'skew-symmetric' not yet implemented for reading") ## FIXME: use dgT... but must expand the (i,j,x) slots! new("ngTMatrix", uplo = "L", Dim = c(nr, nc), i = els$i - 1L, j = els$j - 1L) }, "hermitian" = { stop("symmetry form 'hermitian' not yet implemented for reading") }, ## otherwise (not possible; just defensive programming): stop(gettextf("symmetry form '%s' is not yet implemented", sym), domain = NA) ) }, "complex" = { stop("element type 'complex' not yet implemented") }, ## otherwise (not possible currently): stop(gettextf("'%s()' is not yet implemented for element type '%s'", "readMM", elt), domain = NA)) } else stop(gettextf("'%s()' is not yet implemented for representation '%s'", "readMM", repr), domain = NA) } setMethod("writeMM", "CsparseMatrix", function(obj, file, ...) .Call(Csparse_MatrixMarket, obj, path.expand(as.character(file)))) setMethod("writeMM", "sparseMatrix", function(obj, file, ...) writeMM(.M2C(obj), file, ...)) Matrix/R/subscript.R0000644000176200001440000006453614542726437014114 0ustar liggesusers## METHODS FOR GENERIC: [ ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .subscript.invalid <- function(i) { if(is.object(i)) gettextf("invalid subscript class \"%s\"", class(i)[1L]) else gettextf("invalid subscript type \"%s\"", typeof(i)) } .subscript.recycle <- function(i, n, pattern) { ## Return integer or double vector corresponding ## to [nl]sparseVector 'i' recycled to length 'n' : if(length(i.i <- i@i) == 0L) integer(0L) else if((i.length <- length(i)) >= n) { if(i.length > n) { if(n < 0x1p+53) { if(i.i[length(i.i)] >= n + 1) i.i[i.i >= n + 1] <- NA } else { if(i.i[length(i.i)] > n) i.i[i.i > n] <- NA } } if(pattern) i.i else i.i[i@x] } else { r <- ceiling(n / i.length) n. <- r * i.length i.i <- if(n. <= .Machine$integer.max) rep.int(as.integer(i.i), r) + rep(seq.int(from = 0L, by = as.integer(i.length), length.out = r), each = length(i.i)) else if(i.i[length(i.i)] + (r - 1) * i.length <= 0x1p+53) rep.int(as.double(i.i), r) + rep(seq.int(from = 0, by = as.double(i.length), length.out = r), each = length(i.i)) else stop(gettextf("recycled %s would have maximal index exceeding %s", "[nl]sparseVector", "2^53"), domain = NA) if(pattern) { if(n. > n) i.i[ i.i <= n] else i.i } else { if(n. > n) i.i[i@x & i.i <= n] else i.i[i@x] } } } ## x[i] where 'i' is NULL or any vector or sparseVector .subscript.1ary <- function(x, i) { x.length <- prod(x@Dim) if(is.null(i)) i <- integer(0L) else if(isS4(i)) { if(!.isVector(i)) stop(.subscript.invalid(i), domain = NA) kind <- .M.kind(i) if((pattern <- kind == "n") || kind == "l") { ## [nl]sparseVector i <- .subscript.recycle(i, x.length, pattern) return(..subscript.1ary(x, i, unsorted = !pattern && anyNA(i))) } i <- i@x } switch(typeof(i), double = { r <- min(1, i, na.rm = TRUE) if(r < 1) i <- if(r <= -1) seq_len(x.length)[i] # FIXME else i[i >= 1] ..subscript.1ary(x, i) }, integer = { r <- min(1L, i, na.rm = TRUE) if(r < 1L) i <- if(r <= -1L) seq_len(x.length)[i] # FIXME else i[i >= 1L] ..subscript.1ary(x, i) }, logical = { if((i.length <- length(i)) && !is.na(a <- all(i)) && a) { if(i.length <= x.length) as.vector(x) else c(as.vector(x), rep.int(NA, i.length - x.length)) } else .subscript.1ary(x, .m2V(i)) # recursively }, character = { rep.int(if(.hasSlot(x, "x")) x@x[NA_integer_] else NA, length(i)) }, stop(.subscript.invalid(i), domain = NA)) } ## x[i] where 'i' is vector of type "integer" or "double" ## with elements greater than or equal to 1 (or NA) ..subscript.1ary <- function(x, i, shape = .M.shape(x), repr = .M.repr(x), unsorted = is.unsorted(i)) { if(!any(repr == c("C", "R", "T"))) return(.Call(R_subscript_1ary, x, i)) if(shape == "t" && x@diag != "N") x <- ..diagU2N(x) if(shape == "s" || repr == "R") { x.length <- prod(d <- x@Dim) if(x.length < 0x1p+53) { r <- max(x.length, i, na.rm = TRUE) if(r >= x.length + 1) i[i >= x.length + 1] <- NA } else if(is.double(i)) { r <- max(0x1p+53, i, na.rm = TRUE) if(r > 0x1p+53) { if(any(i > 0x1p+53 && i <= x.length, na.rm = TRUE)) ## could be avoided in C, which has 64-bit integers : warning(gettextf("subscripts exceeding %s replaced with NA", "2^53"), domain = NA) i[i > 0x1p+53] <- NA } } i1s <- i - 1L m <- d[1L] i. <- as.integer(i1s %% m) if(shape == "s") { j. <- as.integer(i1s %/% m) op <- if(x@uplo == "U") `>` else `<` if(length(w <- which(op(i., j.)))) { i.. <- i.[w] j.. <- j.[w] if(repr == "R") i.[w] <- j.. if(x.length > .Machine$integer.max) m <- as.double(m) i[w] <- m * i.. + j.. + 1L } } } o <- if(repr == "R") order(i., i) else if(is.na(unsorted) || unsorted) sort.list(i) else return(.Call(R_subscript_1ary, x, i)) if(is.unsorted(o)) { s <- .Call(R_subscript_1ary, x, i[o]) s[o] <- s s } else .Call(R_subscript_1ary, x, i) } ## x[i] where 'i' is any array or Matrix .subscript.1ary.mat <- function(x, i) { if(isS4(i)) { if(!.isMatrix(i)) stop(.subscript.invalid(i), domain = NA) if((logic <- any(.M.kind(i) == c("n", "l"))) || i@Dim[2L] != 2L) { if(logic && all(i@Dim) && !is.na(a <- all(i)) && a) { x <- as.vector(x) if((i.length <- length(i)) <= (x.length <- length(x))) return(x) else return(c(x, rep.int(NA, i.length - x.length))) } i <- if(.isDense(i)) .M2v(i) else .M2V(i) return(.subscript.1ary(x, i)) } i <- as(i, "matrix") } else if(is.logical(i) || length(di <- dim(i)) != 2L || di[2L] != 2L) return(.subscript.1ary(x, i)) switch(typeof(i), double =, integer = { storage.mode(i) <- "integer" if(min(1L, i, na.rm = TRUE) < 1L) stop("negative values are not allowed in a matrix subscript") dx <- x@Dim m <- dx[1L] n <- dx[2L] if(m == n) { if(max(n, i, na.rm = TRUE) > n) stop("subscript out of bounds") } else { if(max(m, i[, 1L], na.rm = TRUE) > m || max(n, i[, 2L], na.rm = TRUE) > n) stop("subscript out of bounds") } ## * rows containing 0 are deleted ## * rows containing NA are kept ## * rows containing both 0 and NA are handled ## according to value in first column if(is.na(a <- all(i. <- i[, 1L])) || !a) i <- i[i. > 0L, , drop = FALSE] if(!all(j. <- i[, 2L], na.rm = TRUE)) i <- i[j. > 0L, , drop = FALSE] ..subscript.1ary.mat(x, i) }, character = { dnx <- dimnames(x) m <- c(match(i[, 1L], dnx[[1L]]), match(i[, 2L], dnx[[2L]])) dim(m) <- di if(any(!rowSums(is.na(i)) & rowSums(is.na(m)))) ## error if character row contains zero NA and ## integer row contains at least one NA, ## indicating non-match that should not be ignored stop("subscript out of bounds") ..subscript.1ary.mat(x, m) }, stop(.subscript.invalid(i), domain = NA)) } ## x[i] where 'i' is a 2-column matrix of type "integer" ## with i[, 1L] in 1:m (or NA) and i[, 2L] in 1:n (or NA) ..subscript.1ary.mat <- function(x, i, shape = .M.shape(x), repr = .M.repr(x)) { if(!any(repr == c("C", "R", "T"))) return(.Call(R_subscript_1ary_mat, x, i)) if(shape == "t" && x@diag != "N") x <- ..diagU2N(x) i. <- i[, 1L] j. <- i[, 2L] if(shape == "s") { op <- if(x@uplo == "U") `>` else `<` if(length(w <- which(op(i., j.)))) { i[w, ] <- i[w, 2:1] i. <- i[, 1L] j. <- i[, 2L] } } o <- if(repr == "R") { if(anyNA(j.)) i.[is.na(j.)] <- NA order(i., j.) } else { if(anyNA(i.)) j.[is.na(i.)] <- NA order(j., i.) } if(is.unsorted(o)) { s <- .Call(R_subscript_1ary_mat, x, i[o, , drop = FALSE]) s[o] <- s s } else .Call(R_subscript_1ary_mat, x, i) } ## x[i, j, drop] where 'i' and 'j' are NULL or any vector .subscript.2ary <- function(x, i, j, drop) { d <- x@Dim l <- list(if(missing(i)) NULL else if(is.null(i)) integer(0L) else i, if(missing(j)) NULL else if(is.null(j)) integer(0L) else j) for(pos in 1:2) { if(!is.null(k <- l[[pos]])) { l[pos] <- list( switch(typeof(k), double = { r <- d[pos] if(max(r, k, na.rm = TRUE) >= r + 1) stop("subscript out of bounds") if(min(1, k, na.rm = TRUE) < 1) seq_len(r)[k] else as.integer(k) }, integer = { r <- d[pos] if(max(r, k, na.rm = TRUE) > r) stop("subscript out of bounds") if(min(1L, k, na.rm = TRUE) < 1L) seq_len(r)[k] else k }, logical = { r <- d[pos] if(length(k) > r) stop("logical subscript too long") if(length(k) && !is.na(a <- all(k)) && a) NULL else seq_len(r)[k] }, character = { if(length(k) == 0L) integer(0L) else if(is.null(nms <- dimnames(x)[[pos]]) || anyNA(k <- match(k, nms))) stop("subscript out of bounds") else k }, stop(.subscript.invalid(k), domain = NA))) } } if(is.double(lengths(l, use.names = FALSE))) stop(gettextf("dimensions cannot exceed %s", "2^31-1"), domain = NA) ..subscript.2ary(x, l[[1L]], l[[2L]], drop = drop[1L]) } ## x[i, j, drop] where 'i' and 'j' are vectors of type "integer" ## of length not exceeding 2^31-1 with 'i' in 1:m (or NA) and 'j' ## in 1:n (or NA) ... NULL => missing ..subscript.2ary <- function(x, i, j, drop) { if(is.null(i) && is.null(j)) r <- x else { r <- .Call(R_subscript_2ary, x, i, j) dn <- dimnames(x) if(!(is.null(i) || is.null(rn <- dn[[1L]]))) dn[1L] <- list(if(length(i)) rn[i] else NULL) if(!(is.null(j) || is.null(cn <- dn[[2L]]))) dn[2L] <- list(if(length(j)) cn[j] else NULL) r@Dimnames <- dn } if((is.na(drop) || drop) && any(r@Dim == 1L)) drop(as(r, "matrix")) else r } setMethod("[", signature(x = "Matrix", i = "missing", j = "missing", drop = "missing"), function(x, i, j, ..., drop = TRUE) { na <- nargs() if(na == 2L) ## x[] x else if(na == 3L) ## x[, ] drop(x) else ## x[, , ], etc. stop("incorrect number of dimensions") }) setMethod("[", signature(x = "Matrix", i = "missing", j = "missing", drop = "logical"), function(x, i, j, ..., drop = TRUE) { na <- nargs() if(na < 4L) ## x[drop=], x[, drop=], x[drop=, ] x else if(na == 4L) ## x[, , drop=], x[, drop=, ], x[drop=, , ] if(is.na(drop <- drop[1L]) || drop) drop(x) else x else ## x[, , , drop=], etc. stop("incorrect number of dimensions") }) setMethod("[", signature(x = "Matrix", i = "index", j = "missing", drop = "missing"), function(x, i, j, ..., drop = TRUE) { na <- nargs() if(na == 2L) ## x[i=] .subscript.1ary(x, i) else if(na == 3L) ## x[i=, ], x[, i=] .subscript.2ary(x, i, , drop = TRUE) else ## x[i=, , ], etc. stop("incorrect number of dimensions") }) setMethod("[", signature(x = "Matrix", i = "index", j = "missing", drop = "logical"), function(x, i, j, ..., drop = TRUE) { na <- nargs() if(na == 3L) ## x[i=, drop=] .subscript.1ary(x, i) else if(na == 4L) ## x[i=, , drop=], x[, i=, drop=] .subscript.2ary(x, i, , drop = drop) else ## x[i=, , , drop=], etc. stop("incorrect number of dimensions") }) setMethod("[", signature(x = "Matrix", i = "missing", j = "index", drop = "missing"), function(x, i, j, ..., drop = TRUE) { na <- nargs() if(na == 2L) ## x[j=] .subscript.1ary(x, j) else if(na == 3L) ## x[j=, ], x[, j=] .subscript.2ary(x, , j, drop = TRUE) else ## x[, j=, ], etc. stop("incorrect number of dimensions") }) setMethod("[", signature(x = "Matrix", i = "missing", j = "index", drop = "logical"), function(x, i, j, ..., drop = TRUE) { na <- nargs() if(na == 3L) ## x[j=, drop=] .subscript.1ary(x, j) else if(na == 4L) ## x[j=, , drop=], x[, j=, drop=] .subscript.2ary(x, , j, drop = drop) else ## x[, j=, , drop=], etc. stop("incorrect number of dimensions") }) setMethod("[", signature(x = "Matrix", i = "index", j = "index", drop = "missing"), function(x, i, j, ..., drop = TRUE) { na <- nargs() if(na == 3L) ## x[i=, j=], x[j=, i=] .subscript.2ary(x, i, j, drop = TRUE) else ## x[i=, j=, ], etc. stop("incorrect number of dimensions") }) setMethod("[", signature(x = "Matrix", i = "index", j = "index", drop = "logical"), function(x, i, j, ..., drop = TRUE) { na <- nargs() if(na == 4L) ## x[i=, j=, drop=], x[j=, i=, drop=] .subscript.2ary(x, i, j, drop = drop) else ## x[i=, j=, , drop=], etc. stop("incorrect number of dimensions") }) for(.cl in c("matrix", "nMatrix", "lMatrix")) setMethod("[", signature(x = "Matrix", i = .cl, j = "missing", drop = "missing"), function(x, i, j, ..., drop = TRUE) { na <- nargs() if(na == 2L) ## x[i=] .subscript.1ary.mat(x, i) else if(na == 3L) ## x[i=, ], x[, i=] .subscript.2ary(x, i, , drop = TRUE) else ## x[i=, , ], etc. stop("incorrect number of dimensions") }) rm(.cl) setMethod("[", signature(x = "Matrix", i = "NULL", j = "ANY", drop = "ANY"), function(x, i, j, ..., drop = TRUE) { i <- integer(0L) callGeneric() }) setMethod("[", signature(x = "Matrix", i = "ANY", j = "NULL", drop = "ANY"), function(x, i, j, ..., drop = TRUE) { j <- integer(0L) callGeneric() }) setMethod("[", signature(x = "Matrix", i = "NULL", j = "NULL", drop = "ANY"), function(x, i, j, ..., drop = TRUE) { i <- integer(0L) j <- integer(0L) callGeneric() }) setMethod("[", signature(x = "sparseVector", i = "missing", j = "missing", drop = "missing"), function(x, i, j, ..., drop = TRUE) { if(nargs() != 2L) stop("incorrect number of dimensions") x }) setMethod("[", signature(x = "sparseVector", i = "index", j = "missing", drop = "missing"), function(x, i, j, ..., drop = TRUE) { if(nargs() != 2L) stop("incorrect number of dimensions") x.length <- length(x) pattern <- .M.kind(x) == "n" switch(typeof(i), double = { r <- min(1, i, na.rm = TRUE) if(r <= -1) { if(r <= -x.length - 1) i <- i[i > -x.length - 1] r <- max(-1, i) if(is.na(r) || r >= 1) stop("only zeros may be mixed with negative subscripts") if(r > -1) i <- i[i <= -1] d <- unique.default(sort.int(-trunc(i))) k <- match(x@i, d, 0L) == 0L x@length <- length(x) - length(d) x@i <- { tmp <- x@i[k] tmp - findInterval(tmp, d) # !! } if(!pattern) x@x <- x@x[k] } else { if(r < 1) i <- i[i >= 1] if(max(0, i, na.rm = TRUE) >= x.length + 1) i[i >= x.length + 1] <- NA if((a <- anyNA(i)) && pattern) { x <- .V2kind(x, "l") pattern <- FALSE } j <- match(trunc(i), x@i, 0L) x@length <- length(i) x@i <- if(!a) which(j != 0L) else { i. <- is.na(i) j[i.] <- NA which(j != 0L | i.) } if(!pattern) x@x <- x@x[j] } x }, integer = { r <- min(1L, i, na.rm = TRUE) if(r <= -1L) { if(r < -x.length) i <- i[i >= -x.length] r <- max(-1L, i) if(is.na(r) || r >= 1L) stop("only zeros may be mixed with negative subscripts") if(r > -1L) i <- i[i <= -1L] d <- unique.default(sort.int(-i)) k <- is.na(match(x@i, d)) x@length <- length(x) - length(d) x@i <- { tmp <- x@i[k] tmp - findInterval(tmp, d) # !! } if(!pattern) x@x <- x@x[k] } else { if(r < 1L) i <- i[i >= 1L] if(max(0L, i, na.rm = TRUE) > x.length) i[i > x.length] <- NA if((a <- anyNA(i)) && pattern) { x <- .V2kind(x, "l") pattern <- FALSE } j <- match(i, x@i, 0L) x@length <- length(i) x@i <- if(!a) which(j != 0L) else { i. <- is.na(i) j[i.] <- NA which(j != 0L | i.) } if(!pattern) x@x <- x@x[j] } x }, logical = { if((i.length <- length(i)) && !is.na(a <- all(i)) && a) { if(i.length > x.length) { if(pattern) x <- .V2kind(x, "l") x@length <- i.length x@i <- c(x@i, (x.length + 1):i.length) x@x <- c(x@x, rep.int(NA, i.length - x.length)) } x } else x[.m2V(i)] # recursively }, stop(.subscript.invalid(i), domain = NA)) }) setMethod("[", signature(x = "sparseVector", i = "nsparseVector", j = "missing", drop = "missing"), function(x, i, j, ..., drop = TRUE) { if(nargs() != 2L) stop("incorrect number of dimensions") x[.subscript.recycle(i, length(x), TRUE)] }) setMethod("[", signature(x = "sparseVector", i = "lsparseVector", j = "missing", drop = "missing"), function(x, i, j, ..., drop = TRUE) { if(nargs() != 2L) stop("incorrect number of dimensions") x[.subscript.recycle(i, length(x), FALSE)] }) setMethod("[", signature(x = "sparseVector", i = "NULL", j = "ANY", drop = "ANY"), function(x, i, j, ..., drop = TRUE) { i <- integer(0L) callGeneric() }) ## METHODS FOR GENERIC: head ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("head", signature(x = "Matrix"), head.matrix) setMethod("head", signature(x = "sparseVector"), function(x, n = 6L, ...) { stopifnot(is.numeric(n), length(n) == 1L, !is.na(n)) len <- length(x) n <- if(n < 0L) max(len + n, 0L) else min(n, len) if(n >= len) return(x) nnz <- length(i <- x@i) x@length <- n <- if(is.integer(i)) as.integer(n) else trunc(n) if(nnz > 0L && i[nnz] > n) { pattern <- .M.kind(x) == "n" if(i[1L] > n) { x@i <- integer(0L) if(!pattern) x@x <- x@x[0L] } else { ii <- 1L:(which.max(i > n) - 1L) x@i <- i[ii] if(!pattern) x@x <- x@x[ii] } } x }) ## METHODS FOR GENERIC: tail ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("tail", signature(x = "Matrix"), tail.matrix) setMethod("tail", signature(x = "sparseVector"), function(x, n = 6L, ...) { stopifnot(is.numeric(n), length(n) == 1L, !is.na(n)) len <- length(x) n <- if(n < 0L) max(len + n, 0L) else min(n, len) if(n >= len) return(x) nnz <- length(i <- x@i) x@length <- n <- if(is.integer(i)) as.integer(n) else trunc(n) if(nnz > 0L && i[1L] <= (k <- len - n)) { pattern <- .M.kind(x) == "n" if(i[nnz] <= k) { x@i <- integer(0L) if(!pattern) x@x <- x@x[0L] } else { ii <- which.min(i <= k):nnz x@i <- i[ii] - k if(!pattern) x@x <- x@x[ii] } } x }) Matrix/R/construct.R0000644000176200001440000006675314511521056014107 0ustar liggesusersMatrix <- function(data = NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL, sparse = NULL, doDiag = TRUE, forceCheck = FALSE) { i.M <- i.sM <- i.dM <- i.sV <- i.m <- FALSE mnrow <- missing(nrow) mncol <- missing(ncol) if(isS4(data)) { cld <- getClassDef(class(data)) i.M <- extends(cld, "Matrix") if(i.M) { i.sM <- extends(cld, "sparseMatrix") i.dM <- i.sM && extends(cld, "diagonalMatrix") } else if(extends(cld, "sparseVector")) { ## need to transmit missingness to 'spV2M' call. <- quote(spV2M(x = data, nrow =, ncol =, byrow = byrow)) if(!mnrow) call.[[3L]] <- quote(nrow) if(!mncol) call.[[4L]] <- quote(ncol) data <- eval(call.) i.M <- i.sM <- i.sV <- forceCheck <- TRUE } } else { i.m <- is.matrix(data) } if(!i.M) { ## validate non-Matrix 'data', throwing type errors _early_ if(is.object(data)) { if(i.m) class(data) <- NULL # retaining 'dim' else data <- as.vector(data) } mode. <- mode(data) kind <- switch(mode., numeric = "d", logical = "l", stop("invalid 'data'")) } if(i.M || i.m) { ## 'data' is a Matrix or a numeric or logical matrix ## without a 'class' attribute if(!i.sV && !(mnrow && mncol && missing(byrow))) warning("'nrow', 'ncol', 'byrow' disregarded for [mM]atrix 'data'") if(!is.null(dimnames)) dimnames(data) <- dimnames if(is.null(sparse)) sparse <- sparseDefault(data) if(i.M) { ## return early in these cases: if(i.dM) ## !doDiag has been documented to result in a coercion to ## symmetricMatrix; we must use diag2*() below because the ## "usual" as(, "(Csparse|unpacked)Matrix") ## inherits from triangularMatrix, _not_ symmetricMatrix return(if(doDiag) data else if(sparse) .diag2sparse(data, ".", "s", "C", "U") else .diag2dense(data, ".", "s", FALSE, "U")) if(!forceCheck) return(if(i.sM == sparse) data else if(sparse) as(data, "CsparseMatrix") else as(data, "unpackedMatrix")) } } else { ## 'data' is a numeric or logical vector or non-matrix array ## without a 'class' attribute if(length(data) == 1L && !is.na(data) && data == 0 && (is.null(sparse) || sparse)) { ## Matrix(0, ...): sparseMatrix unless sparse=FALSE ## MJ: we should _try_ to behave as R's do_matrix() ## in the edge cases ... integer overflow is "OK" ## since anyNA(Dim) is caught by validity methods if(mnrow == mncol) { nrow <- as.integer(nrow) ncol <- as.integer(ncol) } else if(mnrow) { ncol <- as.integer(ncol) if(ncol == 0L) stop("data is too long") nrow <- as.integer(ceiling(1 / ncol)) } else { nrow <- as.integer(nrow) if(nrow == 0L) stop("data is too long") ncol <- as.integer(ceiling(1 / nrow)) } square <- nrow == ncol if(is.null(dimnames)) dimnames <- list(NULL, NULL) if(square && doDiag) return(new(paste0(kind, "diMatrix"), Dim = c(nrow, ncol), Dimnames = dimnames, x = vector(mode., nrow))) data <- new(paste0(kind, if(square) "s" else "g", "CMatrix"), Dim = c(nrow, ncol), Dimnames = dimnames, p = integer(ncol + 1)) i.M <- i.sM <- sparse <- TRUE } else { ## usual case: vector|array->matrix data <- .External(Mmatrix, data, nrow, ncol, byrow, dimnames, mnrow, mncol) if(is.null(sparse)) sparse <- sparseDefault(data) i.m <- TRUE } } ## 'data' is a Matrix (but _not_ a diagonalMatrix) or a ## numeric or logical matrix without a 'class' attribute if(doDiag && isDiagonal(data)) ## as(<[mM]atrix>, "diagonalMatrix") uses check = TRUE (a waste) return(forceDiagonal(data)) if(i.m || i.sM != sparse) { data <- as(data, if(sparse) "CsparseMatrix" else "unpackedMatrix") if(i.m) ## as(, "CsparseMatrix"), as(, "unpackedMatrix") ## already check for symmetric, triangular structure return(data) } if(!is(data, "generalMatrix")) data else if(isSymmetric(data)) forceSymmetric(data) else if(!(it <- isTriangular(data))) data else if(attr(it, "kind") == "U") triu(data) else tril(data) } sparseMatrix <- function(i, j, p, x, dims, dimnames, symmetric = FALSE, triangular = FALSE, index1 = TRUE, repr = c("C", "R", "T"), giveCsparse, check = TRUE, use.last.ij = FALSE) { if((m.i <- missing(i)) + (m.j <- missing(j)) + (m.p <- missing(p)) != 1L) stop("exactly one of 'i', 'j', and 'p' must be missing from call") if(symmetric && triangular) stop("use Diagonal() to construct diagonal (symmetric && triangular) sparse matrices") index1 <- as.logical(index1) # allowing {0,1} repr <- # keep in sync with toeplitz() ## NB: prior to 2020-05, we had 'giveCsparse' {T->"C" [default], F->"T"} ## but no 'repr' ... the following is to remain backwards compatible if(missing(giveCsparse)) match.arg(repr) else if(!missing(repr)) { warning("'giveCsparse' is deprecated; using 'repr' instead") match.arg(repr) ## } else { ## repr <- if(giveCsparse) "C" else "T" ## warning(gettextf("'giveCsparse' is deprecated; setting repr=\"%s\" for you", repr), ## domain = NA) ## } } else if(giveCsparse) { ## NOT YET: ## warning("'giveCsparse' is deprecated; setting repr=\"C\" for you") "C" } else { warning("'giveCsparse' is deprecated; setting repr=\"T\" for you") "T" } if(!m.p) { p <- as.integer(p) if((n.p <- length(p)) == 0L || anyNA(p) || p[1L] != 0L || any((dp <- p[-1L] - p[-n.p]) < 0L)) stop("'p' must be a nondecreasing vector c(0, ...)") if((n.dp <- length(dp)) > .Machine$integer.max) stop("dimensions cannot exceed 2^31-1") i. <- rep.int(seq.int(from = 0L, length.out = n.dp), dp) if(m.i) i <- i. else j <- i. } if(!m.i) i <- if(index1) as.integer(i) - 1L else as.integer(i) # need 0-index if(!m.j) j <- if(index1) as.integer(j) - 1L else as.integer(j) # need 0-index rij <- cbind(if(n.i <- length(i)) range(i) else 0:-1, if(n.j <- length(j)) range(j) else 0:-1, deparse.level = 0L) if(anyNA(rij)) stop("'i' and 'j' must not contain NA") # and not overflow if(any(rij[1L, ] < 0L)) stop("'i' and 'j' must be ", if(index1) "positive" else "non-negative") dims <- if(!missing(dims)) { if(length(dims) != 2L || any(is.na(dims) | dims < 0L | dims >= .Machine$integer.max + 1)) stop("invalid 'dims'") if(any(dims - 1L < rij[2L, ])) stop("'dims' must contain all (i,j) pairs") as.integer(dims) } else if(symmetric || triangular) rep.int(max(rij), 2L) + 1L else rij[2L, ] + 1L kind <- if(m.x <- missing(x)) "n" else if(is.integer(x)) "d" else .M.kind(x) shape <- if(symmetric) { if(dims[1L] != dims[2L]) stop("symmetric matrix must be square") "s" } else if(triangular) { if(dims[1L] != dims[2L]) stop("triangular matrix must be square") "t" } else "g" r <- new(paste0(kind, shape, "TMatrix")) r@Dim <- dims if(!missing(dimnames) && !is.null(dimnames)) r@Dimnames <- if(is.character(validDN(dimnames, dims))) dimnames else fixupDN(dimnames) # needs a valid argument if((symmetric || triangular) && all(i >= j)) r@uplo <- "L" # else "U", the prototype if(!m.x) { if(is.integer(x)) x <- as.double(x) if((n.x <- length(x)) > 0L && n.x != n.i) { if(n.x < n.i) { if(n.i %% n.x != 0L) warning(if(m.i) "p[length(p)] " else "length(i) ", "is not an integer multiple of length(x)") x <- rep_len(x, n.i) # recycle } else if(n.x == 1L) x <- x[0L] # tolerate length(i) = 0, length(x) = 1 else stop("length(x) must not exceed ", if(m.i) "p[length(p)]" else "length(i)") } if(use.last.ij && n.i == n.j && anyDuplicated.matrix(ij <- cbind(i, j, deparse.level = 0L), fromLast = TRUE)) { which.not.dup <- which(!duplicated(ij, fromLast = TRUE)) i <- i[which.not.dup] j <- j[which.not.dup] x <- x[which.not.dup] } r@x <- x } r@i <- i r@j <- j if(check) validObject(r) switch(repr, "C" = .M2C(r), "T" = r, "R" = .M2R(r), ## should never happen: stop("invalid 'repr'; must be \"C\", \"R\", or \"T\"")) } spMatrix <- function(nrow, ncol, i = integer(0L), j = integer(0L), x = double(0L)) new(paste0(if(is.integer(x)) "d" else .M.kind(x), "gTMatrix"), Dim = c(as.integer(nrow), as.integer(ncol)), i = as.integer(i) - 1L, j = as.integer(j) - 1L, x = if(is.integer(x)) as.double(x) else x) Diagonal <- function(n, x = NULL, names = FALSE) { nx <- length(x) if(missing(n)) n <- nx else if(!is.numeric(n) || length(n) != 1L || is.na(n) || n < 0L) stop("'n' must be a non-negative integer") if(is.double(n) && n >= .Machine$integer.max + 1) stop("dimensions cannot exceed 2^31-1") n <- as.integer(n) # discarding attributes if(is.null(x)) { r <- new("ddiMatrix") r@diag <- "U" if(n > 0L) { r@Dim <- c(n, n) if(is.character(names) && length(names) == n) r@Dimnames <- list(names, names) } return(r) } if(is.object(x)) stop(gettextf("'x' has unsupported class \"%s\"", class(x)[1L]), domain = NA) names.x <- names(x) # keeping for later r <- new(switch(typeof(x), ## discarding attributes, incl. 'dim' and 'names' logical = { x <- as.logical(x); "ldiMatrix" }, integer =, double = { x <- as.double(x); "ddiMatrix" }, stop(gettextf("'x' has unsupported type \"%s\"", typeof(x)), domain = NA))) if(n == 0L) return(r) if(nx != 1L) r@x <- if(nx == n) x else if(nx > 0L) rep_len(x, n) else stop("attempt to recycle 'x' of length 0 to length 'n' (n > 0)") else if(is.na(x) || x != 1) r@x <- rep.int(x, n) else r@diag <- "U" r@Dim <- c(n, n) if(is.character(names)) { if(length(names) == n) r@Dimnames <- list(names, names) } else if(isTRUE(names) && !is.null(names.x)) { names.x <- rep_len(names.x, n) # we know length(names.x) > 0L r@Dimnames <- list(names.x, names.x) } r } .sparseDiagonal <- function(n, x = NULL, uplo = "U", shape = "t", unitri = TRUE, kind, cols) { if(missing(n)) n <- length(x) else if(!is.numeric(n) || length(n) != 1L || is.na(n) || n < 0L) stop("'n' must be a non-negative integer") if(is.double(n) && n >= .Machine$integer.max + 1) stop("dimensions cannot exceed 2^31-1") n <- nj <- as.integer(n) # stripping attributes if(!(missing(shape) || (is.character(shape) && length(shape) == 1L && !is.na(shape) && any(shape == c("g", "t", "s"))))) stop("'shape' must be one of \"g\", \"t\", \"s\"") if(!((m.kind <- missing(kind)) || (is.character(kind) && length(kind) == 1L && !is.na(kind) && any(kind == c("d", "l", "n"))))) stop("'kind' must be one of \"d\", \"l\", \"n\"") if(m.kind || kind != "n") { if(is.null(x)) x <- if(m.kind) { kind <- "d"; 1 } else switch(kind, d = 1, l = TRUE) else if(is.object(x)) stop(gettextf("'x' has unsupported class \"%s\"", class(x)[1L]), domain = NA) else { kind. <- switch(typeof(x), ## discarding attributes, incl. 'dim' in array case logical = { x <- as.logical(x); "l" }, integer =, double = { x <- as.double(x); "d" }, stop(gettextf("'x' has unsupported type \"%s\"", typeof(x)), domain = NA)) if(m.kind) kind <- kind. else if(kind != kind.) { warning(gettextf("mismatch between typeof(x)=\"%s\" and kind=\"%s\"; using kind=\"%s\"", typeof(x), kind, kind.), domain = NA) kind <- kind. } } } if(!(m.cols <- missing(cols))) { if(!is.numeric(cols)) stop("'cols' must be numeric") else if((nj <- length(cols)) > 0L && (n == 0L || anyNA(rj <- range(cols)) || rj[1L] < 0L || rj[2L] >= n)) stop("'cols' has elements not in seq(0, length.out = n)") else { cols <- as.integer(cols) shape <- "g" } } r <- new(paste0(kind, shape, "CMatrix")) r@Dim <- c(n, nj) if(shape != "g") { if(!missing(uplo)) { if(is.character(uplo) && length(uplo) == 1L && !is.na(uplo) && any(uplo == c("U", "L"))) r@uplo <- uplo else stop("'uplo' must be \"U\" or \"L\"") } if(shape == "t" && unitri && (kind == "n" || (!anyNA(x) && all(if(kind == "l") x else x == 1)))) { r@diag <- "U" r@p <- integer(nj + 1) return(r) } } if(nj > 0L) { r@p <- 0:nj r@i <- if(m.cols) 0:(nj - 1L) else cols if(kind != "n") { x <- if((nx <- length(x)) == n) x else if(nx > 0L) rep_len(x, n) else stop("attempt to recycle 'x' of length 0 to length 'n' (n > 0)") r@x <- if(m.cols) x else x[1L + cols] } } r } .trDiagonal <- function(n, x = NULL, uplo = "U", unitri = TRUE, kind) .sparseDiagonal(n, x, uplo, shape = "t", unitri = unitri, kind = kind) .symDiagonal <- function(n, x = NULL, uplo = "U", kind) .sparseDiagonal(n, x, uplo, shape = "s", kind = kind) .bdiag <- function(lst) { if(!is.list(lst)) stop("'lst' must be a list") if((n <- length(lst)) == 0L) return(new("dgTMatrix")) if(n == 1L) return(.M2T(asCspN(lst[[1L]]))) ### FIXME? this is _slow_ when 'lst' is list of 75000 3-by-3 dense matrices lst <- unname(lapply(lst, function(x) .M2T(asCspN(x)))) cl <- vapply(lst, class, "") kind <- substr(cl, 1L, 1L) # "n", "l", or "d" shape <- substr(cl, 2L, 2L) # "g", "s", or "t" if(!(any(kind == (kind. <- "d")) || any(kind == (kind. <- "l")))) kind. <- "n" else if(any(z <- kind == "n")) lst[z] <- lapply(lst[z], .sparse2kind, kind.) shape. <- if(all(symmetric <- shape == "s")) "s" else if(all(shape == "t")) "t" else "g" if(shape. != "g") { uplo <- vapply(lst, slot, "", "uplo") # "U" or "L" if(shape. == "s") uplo. <- if(all(z <- uplo == "U")) "U" else if(!any(z)) "L" else { uplo.. <- if(2 * sum(z) >= n) { z <- !z; "U" } else "L" lst[z] <- lapply(lst[z], .tCRT) uplo.. } else if(any(uplo != (uplo. <- uplo[1L]))) shape. <- "g" } i_off <- c(0L, cumsum(vapply(lst, function(x) x@Dim[1L], 0L))) j_off <- c(0L, cumsum(vapply(lst, function(x) x@Dim[2L], 0L))) r <- new(paste0(kind., shape., "TMatrix")) r@Dim <- r@Dim <- c(i_off[n + 1L], j_off[n + 1L]) if(shape. == "g") lst[symmetric] <- lapply(lst[symmetric], .sparse2g) else r@uplo <- uplo. r@i <- unlist(lapply(seq_len(n), function(k) i_off[k] + lst[[k]]@i), FALSE, FALSE) r@j <- unlist(lapply(seq_len(n), function(k) j_off[k] + lst[[k]]@j), FALSE, FALSE) if(kind. != "n") r@x <- unlist(lapply(lst, slot, "x"), FALSE, FALSE) r } bdiag <- function(...) { if((n <- ...length()) == 0L) new("dgCMatrix") else if(n > 1L) .M2C(.bdiag(list(...))) else if(!is.list(x <- ..1)) as(x, "CsparseMatrix") else if(length(x) == 1L) as(x[[1L]], "CsparseMatrix") else .M2C(.bdiag(x)) } bandSparse <- function(n, m = n, k, diagonals, symmetric = FALSE, repr = "C", giveCsparse = (repr == "C")) { ## Purpose: Compute a band-matrix by speciyfying its (sub-)diagonal(s) ## ---------------------------------------------------------------------- ## Arguments: (n,m) : Matrix dimension ## k : integer vector of "diagonal numbers", with identical ## meaning as in band(*, k) ## diagonals: (optional!) list of (sub/super)diagonals ## symmetric: if TRUE, specify only upper or lower triangle; ## ---------------------------------------------------------------------- ## Author: Martin Maechler, Date: 20 Feb 2009, 22:42 if(use.x <- !missing(diagonals)) # when specified, must be matrix or list diag.isMat <- is.matrix(diagonals) len.k <- length(k) stopifnot(!use.x || is.list(diagonals) || diag.isMat, k == as.integer(k), n == as.integer(n), m == as.integer(m)) k <- as.integer(k) n <- as.integer(n) m <- as.integer(m) stopifnot(n >= 0, m >= 0, -n+1 <= (mik <- min(k)), (mak <- max(k)) <= m - 1) if(missing(repr) && !giveCsparse) { warning("'giveCsparse' has been deprecated; setting 'repr = \"T\"' for you") repr <- "T" } else if(!missing(repr) && !missing(giveCsparse)) warning("'giveCsparse' has been deprecated; will use 'repr' instead") if(use.x) { if(diag.isMat) { if(ncol(diagonals) != len.k) stop(gettextf("'diagonals' matrix must have %d columns (= length(k) )", len.k), domain=NA) getD <- function(j) diagonals[,j] } else { ## is.list(diagonals): if(length(diagonals) != len.k) stop(gettextf("'diagonals' must have the same length (%d) as 'k'", len.k), domain=NA) getD <- function(j) diagonals[[j]] } } sqr <- n == m if(symmetric) { if(!sqr) stop("matrix can only be symmetric if square, but n != m") if(mik < 0 && mak > 0) stop("for symmetric band matrix, only specify upper or lower triangle\n hence, all k must have the same sign") } else tri <- sqr && sign(mik)*sign(mak) >= 0 # triangular result dims <- c(n,m) k.lengths <- ## This is a bit "ugly"; I got the cases "by inspection" if(n >= m) { ifelse(k >= m-n, m - pmax(0,k), n+k) } else { ## n < m (?? k >= -n+1 always !!) ifelse(k >= -n+1, n + pmin(0,k), m-k) } i <- j <- integer(sum(k.lengths)) if(use.x) x <- if(len.k > 0) # carefully getting correct type/mode rep.int(getD(1)[1], length(i)) off.i <- 0L for(s in seq_len(len.k)) { kk <- k[s] ## *is* integer l.kk <- k.lengths[s] ## == length of (sub-)diagonal kk ii1 <- seq_len(l.kk) ind <- ii1 + off.i if(kk >= 0) { i[ind] <- ii1 j[ind] <- ii1 + kk } else { ## k < 0 i[ind] <- ii1 - kk j[ind] <- ii1 } if(use.x) { xx <- getD(s) if(length(xx) < l.kk) warning(gettextf("the %d-th (sub)-diagonal (k = %d) is too short; filling with NA's", s, kk), domain=NA) x[ind] <- xx[ii1] } off.i <- off.i + l.kk } if(symmetric) { ## we should have smarter sparseMatrix() UpLo <- if(min(k) >= 0) "U" else "L" T <- if(use.x) { if(is.integer(x)) x <- as.double(x) cc <- paste0(.M.kind(x), "sTMatrix") new(cc, i= i-1L, j= j-1L, x = x, Dim= dims, uplo=UpLo) } else new("nsTMatrix", i= i-1L, j= j-1L, Dim= dims, uplo=UpLo) switch(repr, "C" = .M2C(T), "T" = T, "R" = .M2R(T), stop("invalid 'repr'; must be \"C\", \"T\", or \"R\"")) } else { ## not symmetric, possibly triangular if(use.x) sparseMatrix(i=i, j=j, x=x, dims=dims, triangular=tri, repr=repr) else sparseMatrix(i=i, j=j, dims=dims, triangular=tri, repr=repr) } } rsparsematrix <- function(nrow, ncol, density, nnz = round(density * maxE), symmetric = FALSE, rand.x = function(n) signif(rnorm(n), 2L), ...) { maxE <- if(symmetric) nrow*(nrow+1)/2 else nrow*ncol stopifnot((nnz <- as.integer(nnz)) >= 0, nrow >= 0, ncol >= 0, nnz <= maxE) ## sampling with*out* replacement (replace=FALSE !): ijI <- -1L + if(symmetric) sample(indTri(nrow, diag=TRUE), nnz) else sample.int(maxE, nnz) ## i,j below correspond to ij <- decodeInd(code, nr) : if(is.null(rand.x)) sparseMatrix(i = ijI %% nrow, j = ijI %/% nrow, index1 = FALSE, symmetric = symmetric, dims = c(nrow, ncol), ...) else sparseMatrix(i = ijI %% nrow, j = ijI %/% nrow, x = rand.x(nnz), index1 = FALSE, symmetric = symmetric, dims = c(nrow, ncol), ...) } Hilbert <- function(n) { n <- as.integer(n) i <- seq_len(n) new("dpoMatrix", Dim = c(n, n), x = c(1/outer(i - 1L, i, `+`))) } spV2M <- function(x, nrow, ncol, byrow = FALSE, check = TRUE, symmetric = FALSE) { if(check && !is(x, "sparseVector")) stop("'x' must inherit from \"sparseVector\"") if(!missing(ncol)) { ncol <- as.integer(ncol) if(ncol < 0) stop("'ncol' must be >= 0") } if(!missing(nrow)) { nrow <- as.integer(nrow) if(nrow < 0) stop("'nrow' must be >= 0") } n <- length(x) if(symmetric) { if(missing(nrow)) stop("Must specify 'nrow' when 'symmetric' is true") if(!missing(ncol) && nrow != ncol) stop("'nrow' and 'ncol' must be the same when 'symmetric' is true") ## otherwise ncol will not used at all when (symmetric) if(check && as.double(nrow)^2 != n) stop("'x' must have length nrow^2 when 'symmetric' is true") ## x <- x[indTri(nrow, upper=TRUE, diag=TRUE)] } else if(missing(nrow)) { nrow <- as.integer( if(missing(ncol)) { ## both missing: --> (n x 1) ncol <- 1L n } else { if(n %% ncol != 0) warning("'ncol' is not a factor of length(x)") as.integer(ceiling(n / ncol)) }) } else if(missing(ncol)) { ncol <- if(symmetric) nrow else { if(n %% nrow != 0) warning("'nrow' is not a factor of length(x)") as.integer(ceiling(n / nrow)) } } else { ## both nrow and ncol specified n.n <- as.double(ncol) * nrow # no integer overflow if(n.n < n) stop("nrow * ncol < length(x)", domain = NA) if(n.n != n) warning("nrow * ncol != length(x)", domain = NA) } ## now nrow * ncol >= n (or 'symmetric') ## ~~~~~~~~~~~~~~~~ kind <- .M.kind(x) # "d", "n", "l", "i", "z", ... has.x <- kind != "n" clStem <- if(symmetric) "sTMatrix" else "gTMatrix" ## "careful_new()" : cNam <- paste0(kind, clStem) chngCl <- is.null(newCl <- getClassDef(cNam)) if(chngCl) { ## e.g. "igTMatrix" is not yet implemented if(kind == "z") stop(gettextf("Class %s is not yet implemented", dQuote(cNam)), domain = NA) ## coerce to "double": newCl <- getClassDef(paste0("d", clStem)) } r <- new(newCl, Dim = c(nrow, ncol)) ## now "compute" the (i,j,x) slots given x@(i,x) i0 <- x@i - 1L if(byrow) { ## need as.integer(.) since @ i can be double j <- as.integer(i0 %% ncol) i <- as.integer(i0 %/% ncol) } else { ## default{byrow = FALSE} i <- as.integer(i0 %% nrow) j <- as.integer(i0 %/% nrow) } if(has.x) x <- if(chngCl) as.numeric(x@x) else x@x if(symmetric) { ## using uplo = "U" i0 <- i <= j ## i.e., indTri(nrow, upper=TRUE, diag=TRUE) i <- i[i0] j <- j[i0] if(has.x) x <- x[i0] } r@j <- j r@i <- i if(has.x) r@x <- x r } .sparseV2Mat <- function(from) spV2M(from, nrow = from@length, ncol = 1L, check = FALSE) sp2vec <- function(x, mode = .type.kind[.M.kind(x)]) { ## sparseVector -> vector has.x <- .hasSlot(x, "x")## has "x" slot m.any <- (mode == "any") if(m.any) mode <- if(has.x) mode(x@x) else "logical" else if(has.x) # is.() is much faster than inherits() | is(): xxOk <- switch(mode, "double" = is.double(x@x), "logical" = is.logical(x@x), "integer" = is.integer(x@x), "complex" = is.complex(x@x), ## otherwise (does not happen with default 'mode'): inherits(x@x, mode)) r <- vector(mode, x@length) r[x@i] <- if(has.x) { if(m.any || xxOk) x@x else as(x@x, mode) } else TRUE r } newSpV <- function(class, x, i, length, drop0 = TRUE, checkSort = TRUE) { if(has.x <- !missing(x)) { if(length(x) == 1 && (li <- length(i)) != 1) ## recycle x : x <- rep.int(x, li) if(drop0 && isTRUE(any(x0 <- x == 0))) { keep <- is.na(x) | !x0 x <- x[keep] i <- i[keep] } } if(checkSort && is.unsorted(i)) { ii <- sort.list(i) if(has.x) x <- x[ii] i <- i[ii] } if(has.x) new(class, x = x, i = i, length = length) else new(class, i = i, length = length) } newSpVec <- function(class, x, prev) newSpV(class = class, x = x, i = prev@i, length = prev@length) sparseVector <- function(x, i, length) newSpV(class = paste0(if(missing(x)) "n" else .M.kind(x), "sparseVector"), x = x, i = i, length = length) Matrix/R/qr.R0000644000176200001440000003206114503364553012476 0ustar liggesusers## METHODS FOR GENERIC: qr ## pivoted QR factorization of dense and sparse matrices ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## MJ: Well, I'd very much like to _not_ truncate by default ... ## not least because qr.qy and qr.qty should remain inverses ... .qr.rank.def.truncating <- TRUE .qr.rank.def.warn <- function(qr) { if(m0 <- qr@V@Dim[1L] - qr@Dim[1L]) warning(gettextf("matrix is structurally rank deficient; using augmented matrix with additional %d row(s) of zeros", m0), domain = NA) m0 } setMethod("qr", signature(x = "sparseMatrix"), function(x, ...) qr(.M2gen(.M2C(x), ","), ...)) setMethod("qr", signature(x = "dgCMatrix"), function(x, order = 3L, ...) { r <- .Call(dgCMatrix_orf, x, order, TRUE) .qr.rank.def.warn(r) r }) ## METHODS FOR CLASS: sparseQR ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("expand1", signature(x = "sparseQR"), function(x, which, ...) { .qr.rank.def.warn(x) R <- x@R d <- R@Dim m <- d[1L] n <- d[2L] switch(which, "P1" =, "P1." = { r <- new("pMatrix") r@Dim <- c(m, m) r@perm <- x@p + 1L if(which == "P1.") r@margin <- 2L r }, "P2" =, "P2." = { r <- new("pMatrix") r@Dim <- c(n, n) r@perm <- if(length(x@q)) x@q + 1L else seq_len(n) if(which == "P2") r@margin <- 2L r }, "Q" = .Call(sparseQR_matmult, x, NULL, 6L, TRUE, NULL), "Q1" = .Call(sparseQR_matmult, x, NULL, 6L, FALSE, NULL), "R" = R, "R1" = triu(if(m == n) R else R[seq_len(n), , drop = FALSE]), stop(gettextf("'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%2$s2\", \"%2$s2.\", \"%3$s\", \"%3$s1\", \"%4$s\", or \"%4$s1\"", "which", "P", "Q", "R"), domain = NA)) }) ## returning list(P1', Q, R, P2'), where A = P1' Q R P2' setMethod("expand2", signature(x = "sparseQR"), function(x, complete = FALSE, ...) { m0 <- .qr.rank.def.warn(x) R <- x@R d <- R@Dim m <- d[1L] n <- d[2L] dn <- x@Dimnames if(m0 && !is.null(dn[[1L]])) length(dn[[1L]]) <- m Q <- .Call(sparseQR_matmult, x, NULL, 6L, complete, NULL) if(!complete && n < m) R <- R[seq_len(n), , drop = FALSE] p1 <- x@p p2 <- x@q P1. <- new("pMatrix", Dim = c(m, m), Dimnames = c(dn[1L], list(NULL)), margin = 1L, perm = invertPerm(p1, 0L, 1L)) P2. <- new("pMatrix", Dim = c(n, n), Dimnames = c(list(NULL), dn[2L]), margin = 2L, perm = if(length(p2)) invertPerm(p2, 0L, 1L) else seq_len(n)) if(complete) list(P1. = P1., Q = Q, R = R, P2. = P2.) else list(P1. = P1., Q1 = Q, R1 = triu(R), P2. = P2.) }) setMethod("qr.Q", signature(qr = "sparseQR"), function(qr, complete = FALSE, Dvec) { m0 <- .qr.rank.def.warn(qr) if(missing(Dvec)) Dvec <- NULL else { storage.mode(Dvec) <- "double" if(length(Dvec) != qr@V@Dim[if(complete) 1L else 2L]) stop(gettextf("'%s' has the wrong length", "Dvec"), domain = NA) } Q <- .Call(sparseQR_matmult, qr, NULL, 4L, complete, Dvec) dn <- c(qr@Dimnames[1L], list(NULL)) if(!is.null(rn <- dn[[1L]])) { if(m0) length(rn) <- length(rn) + m0 if(is.unsorted(p1 <- qr@p, strictly = TRUE)) rn <- rn[p1 + 1L] dn[[1L]] <- rn } Q@Dimnames <- dn if(m0 && .qr.rank.def.truncating) { i <- seq_len(Q@Dim[1L] - m0) Q <- if(complete) Q[i, i, drop = FALSE] else Q[i, , drop = FALSE] } Q }) qrR <- function(qr, complete = FALSE, backPermute = TRUE, row.names = TRUE) { m0 <- .qr.rank.def.warn(qr) R <- qr@R d <- R@Dim m <- d[1L] n <- d[2L] dn <- qr@Dimnames p2 <- qr@q + 1L p2.uns <- is.unsorted(p2, strictly = TRUE) # FALSE if length is 0 if(!row.names) dn <- c(list(NULL), dn[2L]) else if(m0 && !is.null(rn <- dn[[1L]])) length(dn[[1L]]) <- length(rn) + m0 if(p2.uns && !is.null(cn <- dn[[2L]])) dn[[2L]] <- cn[p2] R@Dimnames <- dn R <- if(!complete && n < m) { if(backPermute && p2.uns) R[seq_len(n), invertPerm(p2), drop = FALSE] else R[seq_len(n), , drop = FALSE] } else { if(backPermute && p2.uns) R[, invertPerm(p2), drop = FALSE] else R } if(m0 && .qr.rank.def.truncating && complete) R <- R[seq_len(m - m0), , drop = FALSE] if(complete || backPermute) R else triu(R) } setMethod("qr.R", signature(qr = "sparseQR"), function(qr, complete = FALSE, backPermute = FALSE, ...) qrR(qr, complete = complete, backPermute = backPermute, row.names = FALSE)) ## https://stat.ethz.ch/pipermail/r-devel/2023-June/082649.html setMethod("qr.X", signature(qr = "sparseQR"), function(qr, complete = FALSE, ncol) { m0 <- .qr.rank.def.warn(qr) R <- qr@R d <- R@Dim m <- d[1L] n <- d[2L] if(missing(ncol)) ncol <- if(complete) m else min(m, n) else { ncol <- as.integer(ncol) if(ncol < 0L || ncol > m) stop(gettextf("invalid '%s': not in %d:%d", "ncol", 0L, m), domain = NA) } p2 <- qr@q + 1L p2.uns <- is.unsorted(p2, strictly = TRUE) # FALSE if length is 0 if(p2.uns && ncol < n) stop(gettextf("need greater '%s' as pivoting occurred", "ncol"), domain = NA) else if(ncol < n) R <- R[, seq_len(ncol), drop = FALSE] else if(ncol > n) { Rp <- R@p Ri <- R@i Rx <- R@x Rnnz <- Rp[length(Rp)] R@Dim[2L] <- ncol R@p <- c(Rp, Rnnz + seq_len(ncol - n)) R@i <- c(if(length(Ri) == Rnnz) Ri else Ri[seq_len(Rnnz)], n:(ncol - 1L)) R@x <- c(if(length(Rx) == Rnnz) Rx else Rx[seq_len(Rnnz)], rep.int(1, ncol - n)) } r <- .Call(sparseQR_matmult, qr, .sparse2dense(R), 4L, NA, NULL) if(p2.uns) { j <- invertPerm(p2) if(ncol > n) j <- c(j, (n + 1L):ncol) r <- r[, j, drop = FALSE] } dn <- qr@Dimnames if(m0 && !is.null(rn <- dn[[1L]])) length(dn[[1L]]) <- length(rn) + m0 if(!is.null(cn <- dn[[2L]]) && length(cn) != ncol) length(dn[[2L]]) <- ncol r@Dimnames <- dn if(m0 && .qr.rank.def.truncating) { i <- seq_len(r@Dim[1L] - m0) r <- if(ncol > length(j)) r[i, i, drop = FALSE] else r[i, , drop = FALSE] } r }) .qr.y0 <- function(y, m0) { d <- y@Dim d[1L] <- (m <- d[1L]) + m0 dn <- y@Dimnames if(!is.null(dn[[1L]])) length(dn[[1L]]) <- d[1L] y0 <- new("dgeMatrix") y0@Dim <- d y0@Dimnames <- dn y0@x <- as.double(`[<-`(array(0, d), seq_len(m), , y@x)) y0 } setMethod("qr.coef", signature(qr = "sparseQR", y = "dgeMatrix"), function(qr, y) { if(m0 <- .qr.rank.def.warn(qr)) y <- .qr.y0(y, m0) r <- .Call(sparseQR_matmult, qr, y, 0L, NA, NULL) r@Dimnames <- c(qr@Dimnames[2L], y@Dimnames[2L]) r }) setMethod("qr.coef", signature(qr = "sparseQR", y = "vector"), function(qr, y) drop(qr.coef(qr, .m2dense(y, ",ge")))) setMethod("qr.coef", signature(qr = "sparseQR", y = "matrix"), function(qr, y) qr.coef(qr, .m2dense(y, ",ge"))) setMethod("qr.coef", signature(qr = "sparseQR", y = "Matrix"), function(qr, y) qr.coef(qr, .m2dense(.M2m(y), ",ge"))) setMethod("qr.fitted", signature(qr = "sparseQR", y = "dgeMatrix"), function(qr, y, k = qr$rank) { if(m0 <- .qr.rank.def.warn(qr)) y <- .qr.y0(y, m0) r <- .Call(sparseQR_matmult, qr, y, 1L, NA, NULL) r@Dimnames <- y@Dimnames if(m0 && .qr.rank.def.truncating) r <- r[seq_len(r@Dim[1L] - m0), , drop = FALSE] r }) setMethod("qr.fitted", signature(qr = "sparseQR", y = "vector"), function(qr, y, k = qr$rank) drop(qr.fitted(qr, .m2dense(y, ",ge")))) setMethod("qr.fitted", signature(qr = "sparseQR", y = "matrix"), function(qr, y, k = qr$rank) qr.fitted(qr, .m2dense(y, ",ge"))) setMethod("qr.fitted", signature(qr = "sparseQR", y = "Matrix"), function(qr, y, k = qr$rank) qr.fitted(qr, .m2dense(.M2m(y), ",ge"))) setMethod("qr.resid", signature(qr = "sparseQR", y = "dgeMatrix"), function(qr, y) { if(m0 <- .qr.rank.def.warn(qr)) y <- .qr.y0(y, m0) r <- .Call(sparseQR_matmult, qr, y, 2L, NA, NULL) r@Dimnames <- y@Dimnames if(m0 && .qr.rank.def.truncating) r <- r[seq_len(r@Dim[1L] - m0), , drop = FALSE] r }) setMethod("qr.resid", signature(qr = "sparseQR", y = "vector"), function(qr, y) drop(qr.resid(qr, .m2dense(y, ",ge")))) setMethod("qr.resid", signature(qr = "sparseQR", y = "matrix"), function(qr, y) qr.resid(qr, .m2dense(y, ",ge"))) setMethod("qr.resid", signature(qr = "sparseQR", y = "Matrix"), function(qr, y) qr.resid(qr, .m2dense(.M2m(y), ",ge"))) setMethod("qr.qty", signature(qr = "sparseQR", y = "dgeMatrix"), function(qr, y) { if(m0 <- .qr.rank.def.warn(qr)) y <- .qr.y0(y, m0) r <- .Call(sparseQR_matmult, qr, y, 3L, NA, NULL) r@Dimnames <- c(list(NULL), y@Dimnames[2L]) if(m0 && .qr.rank.def.truncating) r <- r[seq_len(r@Dim[1L] - m0), , drop = FALSE] r }) setMethod("qr.qty", signature(qr = "sparseQR", y = "vector"), function(qr, y) drop(qr.qty(qr, .m2dense(y, ",ge")))) setMethod("qr.qty", signature(qr = "sparseQR", y = "matrix"), function(qr, y) qr.qty(qr, .m2dense(y, ",ge"))) setMethod("qr.qty", signature(qr = "sparseQR", y = "Matrix"), function(qr, y) qr.qty(qr, .m2dense(.M2m(y), ",ge"))) setMethod("qr.qy", signature(qr = "sparseQR", y = "dgeMatrix"), function(qr, y) { if(m0 <- .qr.rank.def.warn(qr)) y <- .qr.y0(y, m0) r <- .Call(sparseQR_matmult, qr, y, 4L, NA, NULL) dn <- c(qr@Dimnames[1L], y@Dimnames[2L]) if(!is.null(rn <- dn[[1L]])) { if(m0) length(rn) <- length(rn) + m0 if(is.unsorted(p1 <- qr@p, strictly = TRUE)) rn <- rn[p1 + 1L] dn[[1L]] <- rn } r@Dimnames <- dn if(m0 && .qr.rank.def.truncating) r <- r[seq_len(r@Dim[1L] - m0), , drop = FALSE] r }) setMethod("qr.qy", signature(qr = "sparseQR", y = "vector"), function(qr, y) drop(qr.qy(qr, .m2dense(y, ",ge")))) setMethod("qr.qy", signature(qr = "sparseQR", y = "matrix"), function(qr, y) qr.qy(qr, .m2dense(y, ",ge"))) setMethod("qr.qy", signature(qr = "sparseQR", y = "Matrix"), function(qr, y) qr.qy(qr, .m2dense(.M2m(y), ",ge"))) Matrix/R/is.na.R0000644000176200001440000003211014511521056013047 0ustar liggesusers## METHODS FOR GENERIC: anyNA ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("anyNA", signature(x = "denseMatrix"), function(x) { cl <- .M.nonvirtual(x) if(substr(cl, 1L, 1L) == "n") return(FALSE) if((shape <- substr(cl, 2L, 2L)) == "g") anyNA(x@x) else { if(shape == "t" && x@diag != "N") { x@diag <- "N" if(anyNA(diag(x, names = FALSE))) diag(x) <- TRUE } anyNA(pack(x)@x) } }) setMethod("anyNA", signature(x = "sparseMatrix"), function(x) .M.kind(x) != "n" && anyNA(x@x)) setMethod("anyNA", signature(x = "diagonalMatrix"), function(x) .M.kind(x) != "n" && length(y <- x@x) > 0L && anyNA(y)) setMethod("anyNA", signature(x = "indMatrix"), function(x) FALSE) setMethod("anyNA", signature(x = "sparseVector"), function(x) .M.kind(x) != "n" && anyNA(x@x)) ## METHODS FOR GENERIC: is.na ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("is.na", signature(x = "denseMatrix"), function(x) { cl <- .M.nonvirtual(x) never <- substr(cl, 1L, 1L) == "n" substr(cl, 1L, 1L) <- "n" r <- new(cl) r@Dim <- x@Dim r@Dimnames <- x@Dimnames if((shape <- substr(cl, 2L, 2L)) != "g") { r@uplo <- x@uplo if(!never && shape == "t" && x@diag != "N") { x@diag <- "N" if(anyNA(diag(x, names = FALSE))) diag(x) <- TRUE } } r@x <- if(never) logical(length(x@x)) else is.na(x@x) r }) setMethod("is.na", signature(x = "sparseMatrix"), function(x) { cl <- .M.nonvirtual(x) never <- substr(cl, 1L, 1L) == "n" substr(cl, 1L, 1L) <- if(never) "n" else "l" r <- new(cl) r@Dim <- d <- x@Dim r@Dimnames <- x@Dimnames if(substr(cl, 2L, 2L) != "g") r@uplo <- x@uplo if(never) { switch(substr(cl, 3L, 3L), "C" = { r@p <- integer(d[2L] + 1) }, "R" = { r@p <- integer(d[1L] + 1) }) r } else { switch(substr(cl, 3L, 3L), "C" = { r@p <- x@p; r@i <- x@i }, "R" = { r@p <- x@p; r@j <- x@j }, "T" = { r@i <- x@i; r@j <- x@j }) r@x <- is.na(x@x) .M2kind(.drop0(r), "n") } }) setMethod("is.na", signature(x = "diagonalMatrix"), function(x) { r <- new("ndiMatrix") r@Dim <- d <- x@Dim r@Dimnames <- x@Dimnames r@x <- if(x@diag != "N" || .M.kind(x) == "n") logical(d[1L]) else is.na(x@x) r }) setMethod("is.na", signature(x = "indMatrix"), function(x) { m <- x@margin r <- new(if(m == 1L) "ngRMatrix" else "ngCMatrix") r@Dim <- d <- x@Dim r@Dimnames <- x@Dimnames r@p <- integer(d[m] + 1) r }) setMethod("is.na", signature(x = "sparseVector"), function(x) { r <- new("nsparseVector") r@length <- x@length if(.M.kind(x) != "n") r@i <- x@i[is.na(x@x)] r }) ## METHODS FOR GENERIC: is.nan ## NB: mostly parallel to is.na, completely parallel to is.infinite ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("is.nan", signature(x = "denseMatrix"), function(x) { cl <- .M.nonvirtual(x) never <- switch(substr(cl, 1L, 1L), "d" = , "z" = FALSE, TRUE) substr(cl, 1L, 1L) <- "n" r <- new(cl) r@Dim <- x@Dim r@Dimnames <- x@Dimnames if((shape <- substr(cl, 2L, 2L)) != "g") { r@uplo <- x@uplo if(!never && shape == "t" && x@diag != "N") { x@diag <- "N" if(any(is.nan(diag(x, names = FALSE)))) diag(x) <- TRUE } } r@x <- if(never) logical(length(x@x)) else is.nan(x@x) r }) setMethod("is.nan", signature(x = "sparseMatrix"), function(x) { cl <- .M.nonvirtual(x) never <- switch(substr(cl, 1L, 1L), "d" = , "z" = FALSE, TRUE) substr(cl, 1L, 1L) <- if(never) "n" else "l" r <- new(cl) r@Dim <- d <- x@Dim r@Dimnames <- x@Dimnames if(substr(cl, 2L, 2L) != "g") r@uplo <- x@uplo if(never) { switch(substr(cl, 3L, 3L), "C" = { r@p <- integer(d[2L] + 1) }, "R" = { r@p <- integer(d[1L] + 1) }) r } else { switch(substr(cl, 3L, 3L), "C" = { r@p <- x@p; r@i <- x@i }, "R" = { r@p <- x@p; r@j <- x@j }, "T" = { r@i <- x@i; r@j <- x@j }) r@x <- is.nan(x@x) .M2kind(.drop0(r), "n") } }) setMethod("is.nan", signature(x = "diagonalMatrix"), function(x) { r <- new("ndiMatrix") r@Dim <- d <- x@Dim r@Dimnames <- x@Dimnames r@x <- if(x@diag != "N") logical(d[1L]) else switch(.M.kind(x), "d" = , "z" = is.nan(x@x), logical(d[1L])) r }) setMethod("is.nan", signature(x = "indMatrix"), function(x) { m <- x@margin r <- new(if(m == 1L) "ngRMatrix" else "ngCMatrix") r@Dim <- d <- x@Dim r@Dimnames <- x@Dimnames r@p <- integer(d[m] + 1) r }) setMethod("is.nan", signature(x = "sparseVector"), function(x) { r <- new("nsparseVector") r@length <- x@length switch(.M.kind(x), "d" = , "z" = { r@i <- x@i[is.nan(x@x)] }) r }) ## METHODS FOR GENERIC: is.infinite ## NB: mostly parallel to is.na, completely parallel to is.nan ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("is.infinite", signature(x = "denseMatrix"), function(x) { cl <- .M.nonvirtual(x) never <- switch(substr(cl, 1L, 1L), "d" = , "z" = FALSE, TRUE) substr(cl, 1L, 1L) <- "n" r <- new(cl) r@Dim <- x@Dim r@Dimnames <- x@Dimnames if((shape <- substr(cl, 2L, 2L)) != "g") { r@uplo <- x@uplo if(!never && shape == "t" && x@diag != "N") { x@diag <- "N" if(any(is.infinite(diag(x, names = FALSE)))) diag(x) <- TRUE } } r@x <- if(never) logical(length(x@x)) else is.infinite(x@x) r }) setMethod("is.infinite", signature(x = "sparseMatrix"), function(x) { cl <- .M.nonvirtual(x) never <- switch(substr(cl, 1L, 1L), "d" = , "z" = FALSE, TRUE) substr(cl, 1L, 1L) <- if(never) "n" else "l" r <- new(cl) r@Dim <- d <- x@Dim r@Dimnames <- x@Dimnames if(substr(cl, 2L, 2L) != "g") r@uplo <- x@uplo if(never) { switch(substr(cl, 3L, 3L), "C" = { r@p <- integer(d[2L] + 1) }, "R" = { r@p <- integer(d[1L] + 1) }) r } else { switch(substr(cl, 3L, 3L), "C" = { r@p <- x@p; r@i <- x@i }, "R" = { r@p <- x@p; r@j <- x@j }, "T" = { r@i <- x@i; r@j <- x@j }) r@x <- is.infinite(x@x) .M2kind(.drop0(r), "n") } }) setMethod("is.infinite", signature(x = "diagonalMatrix"), function(x) { r <- new("ndiMatrix") r@Dim <- d <- x@Dim r@Dimnames <- x@Dimnames r@x <- if(x@diag != "N") logical(d[1L]) else switch(.M.kind(x), "d" = , "z" = is.infinite(x@x), logical(d[1L])) r }) setMethod("is.infinite", signature(x = "indMatrix"), function(x) { m <- x@margin r <- new(if(m == 1L) "ngRMatrix" else "ngCMatrix") r@Dim <- d <- x@Dim r@Dimnames <- x@Dimnames r@p <- integer(d[m] + 1) r }) setMethod("is.infinite", signature(x = "sparseVector"), function(x) { r <- new("nsparseVector") r@length <- x@length switch(.M.kind(x), "d" = , "z" = { r@i <- x@i[is.infinite(x@x)] }) r }) ## METHODS FOR GENERIC: is.finite ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("is.finite", signature(x = "denseMatrix"), function(x) { cl <- .M.nonvirtual(x) always <- substr(cl, 1L, 1L) == "n" packed <- substr(cl, 3L, 3L) == "p" if((shape <- substr(cl, 2L, 2L)) != "s") r <- new("ngeMatrix") else { r <- new(if(!packed) "nsyMatrix" else "nspMatrix") r@uplo <- x@uplo } r@Dim <- d <- x@Dim r@Dimnames <- x@Dimnames r@x <- if(shape != "t") { if(always) rep.int(TRUE, length(x@x)) else is.finite(x@x) } else { if(always) rep.int(TRUE, prod(d)) else if(!packed) { tmp <- is.finite(x@x) tmp[indTri(d[1L], x@uplo != "U", x@diag != "N", FALSE)] <- TRUE tmp } else { tmp <- rep.int(TRUE, prod(d)) tmp[indTri(d[1L], x@uplo == "U", TRUE, FALSE)] <- is.finite(x@x) if(x@diag != "N") { dim(tmp) <- d diag(tmp) <- TRUE dim(tmp) <- NULL } tmp } } r }) setMethod("is.finite", signature(x = "sparseMatrix"), function(x) { cl <- .M.nonvirtual(x) always <- substr(cl, 1L, 1L) == "n" if(substr(cl, 2L, 2L) != "s") r <- new("ngeMatrix") else { r <- new("nsyMatrix") r@uplo <- x@uplo } r@Dim <- d <- x@Dim r@Dimnames <- x@Dimnames tmp <- rep.int(TRUE, prod(d)) if(!always && !all(k <- is.finite(x@x))) { if(substr(cl, 3L, 3L) != "T") { x <- .M2T(x) if(length(k) > length(x@x)) # was overallocated k <- is.finite(x@x) } i <- c(x@i, x@j) + 1L dim(i) <- c(length(k), 2L) dim(tmp) <- d tmp[i] <- k dim(tmp) <- NULL } r@x <- tmp r }) setMethod("is.finite", signature(x = "diagonalMatrix"), function(x) { r <- new("nsyMatrix") r@Dim <- d <- x@Dim r@Dimnames <- x@Dimnames tmp <- rep.int(TRUE, prod(d)) if(x@diag == "N" && .M.kind(x) != "n" && !all(k <- is.finite(x@x))) { dim(tmp) <- d diag(tmp) <- k dim(tmp) <- NULL } r@x <- tmp r }) setMethod("is.finite", signature(x = "indMatrix"), function(x) { r <- new("ngeMatrix") r@Dim <- d <- x@Dim r@Dimnames <- x@Dimnames r@x <- rep.int(TRUE, prod(d)) r }) setMethod("is.finite", signature(x = "sparseVector"), function(x) { r <- rep.int(TRUE, x@length) if(.M.kind(x) != "n") r[x@i[!is.finite(x@x)]] <- FALSE r }) Matrix/R/nearPD.R0000644000176200001440000001122314466777721013237 0ustar liggesusers## Copyright (C) 2007-2019 Martin Maechler ## ## nearcor.R : ## Copyright (C) 2007 Jens Oehlschlägel ## ## 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 2 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. ## ## A copy of the GNU General Public License is available at ## https://www.R-project.org/Licenses/ nearPD <- ## Computes the nearest correlation matrix to an approximate ## correlation matrix, i.e. not positive semidefinite. function(x # n-by-n approx covariance/correlation matrix , corr = FALSE, keepDiag = FALSE , base.matrix = FALSE # if TRUE return "base matrix" otherwise "dpoMatrix" , do2eigen = TRUE # if TRUE do a sfsmisc::posdefify() eigen step , doSym = FALSE # symmetrize after tcrossprod() , doDykstra = TRUE # do use Dykstra's correction , only.values = FALSE# if TRUE simply return lambda[j]. , ensureSymmetry = !isSymmetric(x)# so user can set to FALSE iff she knows.. , eig.tol = 1e-6 # defines relative positiveness of eigenvalues compared to largest , conv.tol = 1e-7 # convergence tolerance for algorithm , posd.tol = 1e-8 # tolerance for enforcing positive definiteness , maxit = 100L # maximum number of iterations allowed , conv.norm.type = "I" , trace = FALSE # set to TRUE (or 1 ..) to trace iterations ) { if(ensureSymmetry) { ## only if needed/wanted ... ## message("applying nearPD() to symmpart(x)") x <- symmpart(x) } n <- ncol(x) if(keepDiag) diagX0 <- diag(x) if(doDykstra) { ## D_S should be like x, but filled with '0' -- following also works for 'Matrix': D_S <- x; D_S[] <- 0 } X <- x iter <- 0L ; converged <- FALSE; conv <- Inf while (iter < maxit && !converged) { Y <- X if(doDykstra) R <- Y - D_S ## project onto PSD matrices X_k = P_S (R_k) e <- eigen(if(doDykstra) R else Y, symmetric = TRUE) ## Q <- e$vectors d <- e$values ## D <- diag(d) ## create mask from relative positive eigenvalues p <- d > eig.tol*d[1] if(!any(p)) stop("Matrix seems negative semi-definite") ## use p mask to only compute 'positive' part Q <- Q[,p, drop = FALSE] ## X <- Q %*% D[p,p,drop = FALSE] %*% t(Q) --- more efficiently : X <- tcrossprod(Q * rep(d[p], each=nrow(Q)), Q) if(doDykstra) ## update Dykstra's correction D_S = \Delta S_k D_S <- X - R ## project onto symmetric and possibly 'given diag' matrices: if(doSym) X <- (X + t(X))/2 if(corr) diag(X) <- 1 else if(keepDiag) diag(X) <- diagX0 conv <- norm(Y-X, conv.norm.type) / norm(Y, conv.norm.type) iter <- iter + 1L if (trace) cat(sprintf("iter %3d : #{p}=%d, ||Y-X|| / ||Y||= %11g\n", iter, sum(p), conv)) converged <- (conv <= conv.tol) } if(!converged) warning(gettextf("'nearPD()' did not converge in %d iterations", iter), domain = NA) ## force symmetry is *NEVER* needed, we have symmetric X here! ## X <- (X + t(X))/2 if(do2eigen || only.values) { ## begin from posdefify(sfsmisc) e <- eigen(X, symmetric = TRUE) d <- e$values Eps <- posd.tol * abs(d[1]) if (d[n] < Eps) { d[d < Eps] <- Eps if(!only.values) { Q <- e$vectors o.diag <- diag(X) X <- Q %*% (d * t(Q)) D <- sqrt(pmax(Eps, o.diag)/diag(X)) X[] <- D * X * rep(D, each = n) } } if(only.values) return(d) ## unneeded(?!): X <- (X + t(X))/2 if(corr) diag(X) <- 1 else if(keepDiag) diag(X) <- diagX0 } ## end from posdefify(sfsmisc) r <- if(base.matrix) X else new("dpoMatrix", Dim = c(n, n), Dimnames = dimnames(x) %||% list(NULL, NULL), x = as.vector(X)) structure(list(mat = r, eigenvalues = d, corr = corr, normF = norm(x - X, "F"), iterations = iter, rel.tol = conv, converged = converged), class = "nearPD") } Matrix/R/products.R0000644000176200001440000017461314511521056013721 0ustar liggesusersmatmultDim <- function(d.a, d.b, type = 1L) { ## Return the 'dim' of the product indicated by 'type': ## type 1: a %*% b ## 2: t(a) %*% b { crossprod} ## 3: a %*% t(b) {tcrossprod} ## after asserting that ncol() == nrow() i.a <- 1L + (type != 2L) i.b <- 1L + (type == 3L) if(d.a[i.a] != d.b[i.b]) stop("non-conformable arguments") c(d.a[-i.a], d.b[-i.b]) } matmultDN <- function(dn.a, dn.b, type = 1L) ## Return the 'dimnames' of the product indicated by 'type': ## type 1: a %*% b ## 2: t(a) %*% b { crossprod} ## 3: a %*% t(b) {tcrossprod} c(if(is.null(dn.a)) list(NULL) else dn.a[2L - (type != 2L)], if(is.null(dn.b)) list(NULL) else dn.b[2L - (type == 3L)]) ## METHODS FOR GENERIC: %*% ## NB: x %*% y == t(t(y) %*% t(x)) ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for(.cl in c("Matrix", "sparseVector")) { setMethod("%*%", signature(x = .cl, y = "ANY"), function(x, y) x %*% (if(length(dim(y)) == 2L) as.matrix else as.vector)(y)) setMethod("%*%", signature(x = "ANY", y = .cl), function(x, y) (if(length(dim(x)) == 2L) as.matrix else as.vector)(x) %*% y) } ## .... denseMatrix .................................................... setMethod("%*%", signature(x = "denseMatrix", y = "denseMatrix"), function(x, y) .Call(R_dense_matmult, x, y, FALSE, FALSE)) for(.cl in c("matrix", "vector")) { setMethod("%*%", signature(x = "denseMatrix", y = .cl), function(x, y) .Call(R_dense_matmult, x, y, FALSE, FALSE)) setMethod("%*%", signature(x = .cl, y = "denseMatrix"), function(x, y) .Call(R_dense_matmult, x, y, FALSE, FALSE)) } ## .... CsparseMatrix .................................................. setMethod("%*%", signature(x = "CsparseMatrix", y = "CsparseMatrix"), function(x, y) .Call(R_sparse_matmult, x, y, FALSE, FALSE, FALSE, FALSE)) setMethod("%*%", signature(x = "CsparseMatrix", y = "RsparseMatrix"), function(x, y) .Call(R_sparse_matmult, x, y, FALSE, FALSE, FALSE, FALSE)) setMethod("%*%", signature(x = "CsparseMatrix", y = "TsparseMatrix"), function(x, y) .Call(R_sparse_matmult, x, y, FALSE, FALSE, FALSE, FALSE)) for(.cl in c("denseMatrix", "matrix", "vector")) { setMethod("%*%", signature(x = "CsparseMatrix", y = .cl), function(x, y) .Call(R_sparse_matmult, x, y, FALSE, FALSE, FALSE, FALSE)) setMethod("%*%", signature(x = .cl, y = "CsparseMatrix"), function(x, y) .Call(R_sparse_matmult, y, x, TRUE, TRUE, TRUE, FALSE)) } ## .... RsparseMatrix .................................................. setMethod("%*%", signature(x = "RsparseMatrix", y = "CsparseMatrix"), function(x, y) .Call(R_sparse_matmult, y, x, TRUE, TRUE, TRUE, FALSE)) setMethod("%*%", signature(x = "RsparseMatrix", y = "RsparseMatrix"), function(x, y) .Call(R_sparse_matmult, y, x, TRUE, TRUE, TRUE, FALSE)) setMethod("%*%", signature(x = "RsparseMatrix", y = "TsparseMatrix"), function(x, y) .Call(R_sparse_matmult, y, x, TRUE, TRUE, TRUE, FALSE)) for(.cl in c("denseMatrix", "matrix", "vector")) { setMethod("%*%", signature(x = "RsparseMatrix", y = .cl), function(x, y) .Call(R_sparse_matmult, x, y, FALSE, FALSE, FALSE, FALSE)) setMethod("%*%", signature(x = .cl, y = "RsparseMatrix"), function(x, y) .Call(R_sparse_matmult, y, x, TRUE, TRUE, TRUE, FALSE)) } ## .... TsparseMatrix .................................................. setMethod("%*%", signature(x = "TsparseMatrix", y = "CsparseMatrix"), function(x, y) .Call(R_sparse_matmult, x, y, FALSE, FALSE, FALSE, FALSE)) setMethod("%*%", signature(x = "TsparseMatrix", y = "RsparseMatrix"), function(x, y) .Call(R_sparse_matmult, y, x, TRUE, TRUE, TRUE, FALSE)) setMethod("%*%", signature(x = "TsparseMatrix", y = "TsparseMatrix"), function(x, y) .Call(R_sparse_matmult, x, y, FALSE, FALSE, FALSE, FALSE)) for(.cl in c("denseMatrix", "matrix", "vector")) { setMethod("%*%", signature(x = "TsparseMatrix", y = .cl), function(x, y) .Call(R_sparse_matmult, x, y, FALSE, FALSE, FALSE, FALSE)) setMethod("%*%", signature(x = .cl, y = "TsparseMatrix"), function(x, y) .Call(R_sparse_matmult, y, x, TRUE, TRUE, TRUE, FALSE)) } ## .... diagonalMatrix ................................................. setMethod("%*%", signature(x = "diagonalMatrix", y = "diagonalMatrix"), function(x, y) { r <- new("ddiMatrix") r@Dim <- matmultDim(x@Dim, y@Dim, type = 1L) r@Dimnames <- matmultDN(x@Dimnames, y@Dimnames, type = 1L) xu <- x@diag != "N" yu <- y@diag != "N" if(xu && yu) r@diag <- "U" else { if(!xu) { xii <- x@x if(.M.kind(x) == "n" && anyNA(xii)) xii <- xii | is.na(xii) } if(!yu) { yii <- y@x if(.M.kind(y) == "n" && anyNA(yii)) yii <- yii | is.na(yii) } r@x <- if(xu) as.double(yii) else if(yu) as.double(xii) else as.double(xii * yii) } r }) for(.cl in c("CsparseMatrix", "RsparseMatrix", "TsparseMatrix", "denseMatrix", "matrix", "vector")) { setMethod("%*%", signature(x = "diagonalMatrix", y = .cl), function(x, y) .Call(R_diagonal_matmult, x, y, FALSE, FALSE, FALSE)) setMethod("%*%", signature(x = .cl, y = "diagonalMatrix"), function(x, y) .Call(R_diagonal_matmult, x, y, FALSE, FALSE, FALSE)) } ## .... indMatrix ...................................................... setMethod("%*%", signature(x = "indMatrix", y = "indMatrix"), function(x, y) { mx <- x@margin my <- y@margin px <- x@perm py <- y@perm r <- new(if(mx == my) "indMatrix" else if(mx == 1L) "dgeMatrix" else "dgTMatrix") r@Dim <- matmultDim(x@Dim, y@Dim, type = 1L) r@Dimnames <- matmultDN(x@Dimnames, y@Dimnames, type = 1L) if(mx == my) r@perm <- if(mx == 1L) py[px] else { r@margin <- 2L; px[py] } else if(mx == 1L) r@x <- as.double(px == rep(py, each = length(px))) else { r@i <- px - 1L r@j <- py - 1L r@x <- rep.int(1, length(px)) } r }) setMethod("%*%", signature(x = "indMatrix", y = "Matrix"), function(x, y) { if(x@margin != 1L) return(.M2kind(x, "d") %*% y) matmultDim(x@Dim, y@Dim, type = 1L) r <- .M2kind(y[x@perm, , drop = FALSE], ",") r@Dimnames <- matmultDN(x@Dimnames, dimnames(y), type = 1L) r }) setMethod("%*%", signature(x = "Matrix", y = "indMatrix"), function(x, y) { if(y@margin == 1L) return(x %*% .M2kind(y, "d")) matmultDim(x@Dim, y@Dim, type = 1L) r <- .M2kind(x[, y@perm, drop = FALSE], ",") r@Dimnames <- matmultDN(dimnames(x), y@Dimnames, type = 1L) r }) setMethod("%*%", signature(x = "indMatrix", y = "matrix"), function(x, y) { if(x@margin != 1L) return(.M2kind(x, "d") %*% y) matmultDim(x@Dim, dim(y), type = 1L) r <- .m2dense(y[x@perm, , drop = FALSE], ",ge") r@Dimnames <- matmultDN(x@Dimnames, dimnames(y), type = 1L) r }) setMethod("%*%", signature(x = "matrix", y = "indMatrix"), function(x, y) { if(y@margin == 1L) return(x %*% .M2kind(y, "d")) matmultDim(dim(x), y@Dim, type = 1L) r <- .m2dense(x[, y@perm, drop = FALSE], ",ge") r@Dimnames <- matmultDN(dimnames(x), y@Dimnames, type = 1L) r }) setMethod("%*%", signature(x = "indMatrix", y = "vector"), function(x, y) { if(x@margin != 1L) return(.M2kind(x, "d") %*% y) k <- (d <- x@Dim)[2L] r <- if(k == length(y)) .m2dense(y[x@perm], ",ge") else if(k == 1L) .m2dense(matrix(y, d[1L], length(y), byrow = TRUE), ",ge") else stop("non-conformable arguments") r@Dimnames <- c(x@Dimnames[1L], list(NULL)) r }) setMethod("%*%", signature(x = "vector", y = "indMatrix"), function(x, y) { if(y@margin == 1L) return(x %*% .M2kind(y, "d")) k <- (d <- y@Dim)[1L] r <- if(k == length(x)) .m2dense(x[y@perm], ",ge", trans = TRUE) else if(k == 1L) .m2dense(matrix(x, length(x), d[2L]), ",ge") else stop("non-conformable arguments") r@Dimnames <- c(list(NULL), y@Dimnames[2L]) r }) ## .... pMatrix ........................................................ setMethod("%*%", signature(x = "pMatrix", y = "pMatrix"), function(x, y) { r <- new("pMatrix") r@Dim <- matmultDim(x@Dim, y@Dim, type = 1L) r@Dimnames <- matmultDN(x@Dimnames, y@Dimnames, type = 1L) r@perm <- if(y@margin == 1L) y@perm[if(x@margin == 1L) x@perm else invertPerm(x@perm)] else { r@margin <- 2L (if(x@margin == 1L) invertPerm(x@perm) else x@perm)[y@perm] } r }) setMethod("%*%", signature(x = "pMatrix", y = "indMatrix"), function(x, y) { r <- new("indMatrix") r@Dim <- matmultDim(x@Dim, y@Dim, type = 1L) r@Dimnames <- matmultDN(x@Dimnames, y@Dimnames, type = 1L) r@perm <- if(y@margin == 1L) y@perm[if(x@margin == 1L) x@perm else invertPerm(x@perm)] else { r@margin <- 2L (if(x@margin == 1L) invertPerm(x@perm) else x@perm)[y@perm] } r }) setMethod("%*%", signature(x = "indMatrix", y = "pMatrix"), function(x, y) { r <- new("indMatrix") r@Dim <- matmultDim(x@Dim, y@Dim, type = 1L) r@Dimnames <- matmultDN(x@Dimnames, y@Dimnames, type = 1L) r@perm <- if(x@margin == 1L) (if(y@margin == 1L) y@perm else invertPerm(y@perm))[x@perm] else { r@margin <- 2L x@perm[if(y@margin == 1L) invertPerm(x@perm) else y@perm] } r }) setMethod("%*%", signature(x = "pMatrix", y = "Matrix"), function(x, y) { matmultDim(x@Dim, y@Dim, type = 1L) perm <- if(x@margin == 1L) x@perm else invertPerm(x@perm) r <- .M2kind(y[perm, , drop = FALSE], ",") r@Dimnames <- matmultDN(x@Dimnames, dimnames(y), type = 1L) r }) setMethod("%*%", signature(x = "Matrix", y = "pMatrix"), function(x, y) { matmultDim(x@Dim, y@Dim, type = 1L) perm <- if(y@margin == 1L) invertPerm(y@perm) else y@perm r <- .M2kind(x[, perm, drop = FALSE], ",") r@Dimnames <- matmultDN(dimnames(x), y@Dimnames, type = 1L) r }) setMethod("%*%", signature(x = "pMatrix", y = "matrix"), function(x, y) { matmultDim(x@Dim, dim(y), type = 1L) perm <- if(x@margin == 1L) x@perm else invertPerm(x@perm) r <- .m2dense(y[perm, , drop = FALSE], ",ge") r@Dimnames <- matmultDN(x@Dimnames, dimnames(y), type = 1L) r }) setMethod("%*%", signature(x = "matrix", y = "pMatrix"), function(x, y) { matmultDim(dim(x), y@Dim, type = 1L) perm <- if(y@margin == 1L) invertPerm(y@perm) else y@perm r <- .m2dense(x[, perm, drop = FALSE], ",ge") r@Dimnames <- matmultDN(dimnames(x), y@Dimnames, type = 1L) r }) setMethod("%*%", signature(x = "pMatrix", y = "vector"), function(x, y) { k <- x@Dim[2L] r <- if(k == length(y)) { perm <- if(x@margin == 1L) x@perm else invertPerm(x@perm) .m2dense(y[perm], ",ge") } else if(k == 1L) .m2dense(y, ",ge", trans = TRUE) else stop("non-conformable arguments") r@Dimnames <- c(x@Dimnames[1L], list(NULL)) r }) setMethod("%*%", signature(x = "vector", y = "pMatrix"), function(x, y) { k <- y@Dim[1L] r <- if(k == length(x)) { perm <- if(y@margin == 1L) invertPerm(y@perm) else y@perm .m2dense(x[perm], ",ge", trans = TRUE) } else if(k == 1L) .m2dense(x, ",ge") else stop("non-conformable arguments") r@Dimnames <- c(list(NULL), y@Dimnames[2L]) r }) ## .... sparseVector ................................................... setMethod("%*%", signature(x = "sparseVector", y = "sparseVector"), function(x, y) if((nx <- length(x)) == 1L) .tCRT(.V2C(x * y)) else if(nx == length(y)) ## else if((ny <- length(y)) == 1L) ## .V2C(x * y) ## else if(nx == ny) .m2sparse(sum(x * y), ",gR") else stop("non-conformable arguments")) for(.cl in c("Matrix", "matrix")) { setMethod("%*%", signature(x = "sparseVector", y = .cl), function(x, y) if((k <- dim(y)[1L]) == length(x)) .tCRT(.V2C(x)) %*% y else if(k == 1L) .V2C(x) %*% y else stop("non-conformable arguments")) setMethod("%*%", signature(x = .cl, y = "sparseVector"), function(x, y) if((k <- dim(x)[2L]) == length(y)) x %*% .V2C(y) else if(k == 1L) x %*% .tCRT(.V2C(y)) else stop("non-conformable arguments")) } setMethod("%*%", signature(x = "sparseVector", y = "vector"), function(x, y) if((nx <- length(x)) == 1L) .m2dense(.V2v(x * y), ",ge", trans = TRUE) else if(nx == length(y)) ## else if((ny <- length(y)) == 1L) ## .m2dense(.V2v(x * y), ",ge") ## else if(nx == ny) .m2dense(sum(x * y), ",ge") else stop("non-conformable arguments")) setMethod("%*%", signature(x = "vector", y = "sparseVector"), function(x, y) if((nx <- length(x)) == 1L) .m2dense(.V2v(x * y), ",ge", trans = TRUE) else if(nx == length(y)) ## else if((ny <- length(y)) == 1L) ## .m2dense(.V2v(x * y), ",ge") ## else if(nx == ny) .m2dense(sum(x * y), ",ge") else stop("non-conformable arguments")) ## METHODS FOR GENERIC: %&% ## NB: x %*% y == t(t(y) %*% t(x)) ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("%&%", signature(x = "ANY", y = "ANY"), function(x, y) (if(length(dim(x)) == 2L) as.matrix else as.vector)(x) %&% (if(length(dim(y)) == 2L) as.matrix else as.vector)(y)) for(.cl in c("Matrix", "sparseVector", "matrix", "vector")) { setMethod("%&%", signature(x = .cl, y = "ANY"), function(x, y) x %&% (if(length(dim(y)) == 2L) as.matrix else as.vector)(y)) setMethod("%&%", signature(x = "ANY", y = .cl), function(x, y) (if(length(dim(x)) == 2L) as.matrix else as.vector)(x) %&% y) } setMethod("%&%", signature(x = "matrix", y = "matrix"), function(x, y) .m2sparse(x, "ngC") %&% .m2sparse(y, "ngC")) setMethod("%&%", signature(x = "matrix", y = "vector"), function(x, y) .m2sparse(x, "ngC") %&% y ) setMethod("%&%", signature(x = "vector", y = "matrix"), function(x, y) x %&% .m2sparse(y, "ngC")) setMethod("%&%", signature(x = "vector", y = "vector"), function(x, y) { r <- if((nx <- length(x)) == 1L) .m2sparse(x, "ngC") %&% .m2sparse(y, "ngR", trans = TRUE) else if(nx == length(y)) ## else if((ny <- length(y)) == 1L || nx == ny) .m2sparse(x, "ngR", trans = TRUE) %&% .m2sparse(y, "ngC") else stop("non-conformable arguments") r@Dimnames <- list(NULL, NULL) r }) ## .... denseMatrix .................................................... setMethod("%&%", signature(x = "denseMatrix", y = "denseMatrix"), function(x, y) .Call(R_sparse_matmult, x, y, FALSE, FALSE, FALSE, TRUE)) for(.cl in c("matrix", "vector")) { setMethod("%&%", signature(x = "denseMatrix", y = .cl), function(x, y) .Call(R_sparse_matmult, x, y, FALSE, FALSE, FALSE, TRUE)) setMethod("%&%", signature(x = .cl, y = "denseMatrix"), function(x, y) .Call(R_sparse_matmult, x, y, FALSE, FALSE, FALSE, TRUE)) } ## .... CsparseMatrix .................................................. setMethod("%&%", signature(x = "CsparseMatrix", y = "CsparseMatrix"), function(x, y) .Call(R_sparse_matmult, x, y, FALSE, FALSE, FALSE, TRUE)) setMethod("%&%", signature(x = "CsparseMatrix", y = "RsparseMatrix"), function(x, y) .Call(R_sparse_matmult, x, y, FALSE, FALSE, FALSE, TRUE)) setMethod("%&%", signature(x = "CsparseMatrix", y = "TsparseMatrix"), function(x, y) .Call(R_sparse_matmult, x, y, FALSE, FALSE, FALSE, TRUE)) for(.cl in c("denseMatrix", "matrix", "vector")) { setMethod("%&%", signature(x = "CsparseMatrix", y = .cl), function(x, y) .Call(R_sparse_matmult, x, y, FALSE, FALSE, FALSE, TRUE)) setMethod("%&%", signature(x = .cl, y = "CsparseMatrix"), function(x, y) .Call(R_sparse_matmult, x, y, FALSE, FALSE, FALSE, TRUE)) } ## .... RsparseMatrix .................................................. setMethod("%&%", signature(x = "RsparseMatrix", y = "CsparseMatrix"), function(x, y) .Call(R_sparse_matmult, y, x, TRUE, TRUE, TRUE, TRUE)) setMethod("%&%", signature(x = "RsparseMatrix", y = "RsparseMatrix"), function(x, y) .Call(R_sparse_matmult, y, x, TRUE, TRUE, TRUE, TRUE)) setMethod("%&%", signature(x = "RsparseMatrix", y = "TsparseMatrix"), function(x, y) .Call(R_sparse_matmult, y, x, TRUE, TRUE, TRUE, TRUE)) for(.cl in c("denseMatrix", "matrix", "vector")) { setMethod("%&%", signature(x = "RsparseMatrix", y = .cl), function(x, y) .Call(R_sparse_matmult, y, x, TRUE, TRUE, TRUE, TRUE)) setMethod("%&%", signature(x = .cl, y = "RsparseMatrix"), function(x, y) .Call(R_sparse_matmult, y, x, TRUE, TRUE, TRUE, TRUE)) } ## .... TsparseMatrix .................................................. setMethod("%&%", signature(x = "TsparseMatrix", y = "CsparseMatrix"), function(x, y) .Call(R_sparse_matmult, x, y, FALSE, FALSE, FALSE, TRUE)) setMethod("%&%", signature(x = "TsparseMatrix", y = "RsparseMatrix"), function(x, y) .Call(R_sparse_matmult, y, x, TRUE, TRUE, TRUE, TRUE)) setMethod("%&%", signature(x = "TsparseMatrix", y = "TsparseMatrix"), function(x, y) .Call(R_sparse_matmult, x, y, FALSE, FALSE, FALSE, TRUE)) for(.cl in c("denseMatrix", "matrix", "vector")) { setMethod("%&%", signature(x = "TsparseMatrix", y = .cl), function(x, y) .Call(R_sparse_matmult, x, y, FALSE, FALSE, FALSE, TRUE)) setMethod("%&%", signature(x = .cl, y = "TsparseMatrix"), function(x, y) .Call(R_sparse_matmult, x, y, FALSE, FALSE, FALSE, TRUE)) } ## .... diagonalMatrix ................................................. setMethod("%&%", signature(x = "diagonalMatrix", y = "diagonalMatrix"), function(x, y) { r <- new("ndiMatrix") r@Dim <- matmultDim(x@Dim, y@Dim, type = 1L) r@Dimnames <- matmultDN(x@Dimnames, y@Dimnames, type = 1L) xu <- x@diag != "N" yu <- y@diag != "N" if(xu && yu) r@diag <- "U" else r@x <- if(xu) as.logical(y@x) else if(yu) as.logical(x@x) else x@x & y@x r }) for(.cl in c("CsparseMatrix", "RsparseMatrix", "TsparseMatrix", "denseMatrix", "matrix", "vector")) { setMethod("%&%", signature(x = "diagonalMatrix", y = .cl), function(x, y) .Call(R_diagonal_matmult, x, y, FALSE, FALSE, TRUE)) setMethod("%&%", signature(x = .cl, y = "diagonalMatrix"), function(x, y) .Call(R_diagonal_matmult, x, y, FALSE, FALSE, TRUE)) } ## .... indMatrix ...................................................... setMethod("%&%", signature(x = "indMatrix", y = "indMatrix"), function(x, y) { mx <- x@margin my <- y@margin px <- x@perm py <- y@perm r <- new(if(mx == my) "indMatrix" else if(mx == 1L) "ngeMatrix" else "ngTMatrix") r@Dim <- matmultDim(x@Dim, y@Dim, type = 1L) r@Dimnames <- matmultDN(x@Dimnames, y@Dimnames, type = 1L) if(mx == my) r@perm <- if(mx == 1L) py[px] else { r@margin <- 2L; px[py] } else if(mx == 1L) r@x <- px == rep(py, each = length(px)) else { r@i <- px - 1L r@j <- py - 1L } r }) setMethod("%&%", signature(x = "indMatrix", y = "Matrix"), function(x, y) { if(x@margin != 1L) return(.M2kind(x, "n") %&% y) matmultDim(x@Dim, y@Dim, type = 1L) r <- .M2kind(y[x@perm, , drop = FALSE], "n") r@Dimnames <- matmultDN(x@Dimnames, dimnames(y), type = 1L) r }) setMethod("%&%", signature(x = "Matrix", y = "indMatrix"), function(x, y) { if(y@margin == 1L) return(x %&% .M2kind(y, "n")) matmultDim(x@Dim, y@Dim, type = 1L) r <- .M2kind(x[, y@perm, drop = FALSE], "n") r@Dimnames <- matmultDN(dimnames(x), y@Dimnames, type = 1L) r }) setMethod("%&%", signature(x = "indMatrix", y = "matrix"), function(x, y) { if(x@margin != 1L) return(.M2kind(x, "n") %&% y) matmultDim(x@Dim, dim(y), type = 1L) r <- .m2dense(y[x@perm, , drop = FALSE], "nge") r@Dimnames <- matmultDN(x@Dimnames, dimnames(y), type = 1L) r }) setMethod("%&%", signature(x = "matrix", y = "indMatrix"), function(x, y) { if(y@margin == 1L) return(x %&% .M2kind(y, "n")) matmultDim(dim(x), y@Dim, type = 1L) r <- .m2dense(x[, y@perm, drop = FALSE], "nge") r@Dimnames <- matmultDN(dimnames(x), y@Dimnames, type = 1L) r }) setMethod("%&%", signature(x = "indMatrix", y = "vector"), function(x, y) { if(x@margin != 1L) return(.M2kind(x, "n") %&% y) k <- (d <- x@Dim)[2L] r <- if(k == length(y)) .m2dense(y[x@perm], "nge") else if(k == 1L) .m2dense(matrix(y, d[1L], length(y), byrow = TRUE), "nge") else stop("non-conformable arguments") r@Dimnames <- c(x@Dimnames[1L], list(NULL)) r }) setMethod("%&%", signature(x = "vector", y = "indMatrix"), function(x, y) { if(y@margin == 1L) return(x %&% .M2kind(y, "n")) k <- (d <- y@Dim)[1L] r <- if(k == length(x)) .m2dense(x[y@perm], "nge", trans = TRUE) else if(k == 1L) .m2dense(matrix(x, length(x), d[2L]), "nge") else stop("non-conformable arguments") r@Dimnames <- c(list(NULL), y@Dimnames[2L]) r }) ## .... pMatrix ........................................................ setMethod("%&%", signature(x = "pMatrix", y = "pMatrix"), function(x, y) { r <- new("pMatrix") r@Dim <- matmultDim(x@Dim, y@Dim, type = 1L) r@Dimnames <- matmultDN(x@Dimnames, y@Dimnames, type = 1L) r@perm <- if(y@margin == 1L) y@perm[if(x@margin == 1L) x@perm else invertPerm(x@perm)] else { r@margin <- 2L (if(x@margin == 1L) invertPerm(x@perm) else x@perm)[y@perm] } r }) setMethod("%&%", signature(x = "pMatrix", y = "indMatrix"), function(x, y) { r <- new("indMatrix") r@Dim <- matmultDim(x@Dim, y@Dim, type = 1L) r@Dimnames <- matmultDN(x@Dimnames, y@Dimnames, type = 1L) r@perm <- if(y@margin == 1L) y@perm[if(x@margin == 1L) x@perm else invertPerm(x@perm)] else { r@margin <- 2L (if(x@margin == 1L) invertPerm(x@perm) else x@perm)[y@perm] } r }) setMethod("%&%", signature(x = "indMatrix", y = "pMatrix"), function(x, y) { r <- new("indMatrix") r@Dim <- matmultDim(x@Dim, y@Dim, type = 1L) r@Dimnames <- matmultDN(x@Dimnames, y@Dimnames, type = 1L) r@perm <- if(x@margin == 1L) (if(y@margin == 1L) y@perm else invertPerm(y@perm))[x@perm] else { r@margin <- 2L x@perm[if(y@margin == 1L) invertPerm(x@perm) else y@perm] } r }) setMethod("%&%", signature(x = "pMatrix", y = "Matrix"), function(x, y) { matmultDim(x@Dim, y@Dim, type = 1L) perm <- if(x@margin == 1L) x@perm else invertPerm(x@perm) r <- .M2kind(y[perm, , drop = FALSE], "n") r@Dimnames <- matmultDN(x@Dimnames, dimnames(y), type = 1L) r }) setMethod("%&%", signature(x = "Matrix", y = "pMatrix"), function(x, y) { matmultDim(x@Dim, y@Dim, type = 1L) perm <- if(y@margin == 1L) invertPerm(y@perm) else y@perm r <- .M2kind(x[, perm, drop = FALSE], "n") r@Dimnames <- matmultDN(dimnames(x), y@Dimnames, type = 1L) r }) setMethod("%&%", signature(x = "pMatrix", y = "matrix"), function(x, y) { matmultDim(x@Dim, dim(y), type = 1L) perm <- if(x@margin == 1L) x@perm else invertPerm(x@perm) r <- .m2dense(y[perm, , drop = FALSE], "nge") r@Dimnames <- matmultDN(x@Dimnames, dimnames(y), type = 1L) r }) setMethod("%&%", signature(x = "matrix", y = "pMatrix"), function(x, y) { matmultDim(dim(x), y@Dim, type = 1L) perm <- if(y@margin == 1L) invertPerm(y@perm) else y@perm r <- .m2dense(x[, perm, drop = FALSE], "nge") r@Dimnames <- matmultDN(dimnames(x), y@Dimnames, type = 1L) r }) setMethod("%&%", signature(x = "pMatrix", y = "vector"), function(x, y) { k <- x@Dim[2L] r <- if(k == length(y)) { perm <- if(x@margin == 1L) x@perm else invertPerm(x@perm) .m2dense(y[perm], "nge") } else if(k == 1L) .m2dense(y, "nge", trans = TRUE) else stop("non-conformable arguments") r@Dimnames <- c(x@Dimnames[1L], list(NULL)) r }) setMethod("%&%", signature(x = "vector", y = "pMatrix"), function(x, y) { k <- y@Dim[1L] r <- if(k == length(x)) { perm <- if(y@margin == 1L) invertPerm(y@perm) else y@perm .m2dense(x[perm], "nge", trans = TRUE) } else if(k == 1L) .m2dense(x, "nge") else stop("non-conformable arguments") r@Dimnames <- c(list(NULL), y@Dimnames[2L]) r }) ## .... sparseVector ................................................... setMethod("%&%", signature(x = "sparseVector", y = "sparseVector"), function(x, y) { x <- .V2kind(.drop0(x, isM = FALSE), "n") y <- .V2kind(.drop0(y, isM = FALSE), "n") if((nx <- length(x)) == 1L) { if(length(x@i) == 0L) y@i <- integer(0L) .tCRT(.V2C(y)) } else if(nx == length(y)) ## } else if((ny <- length(y)) == 1L) { ## if(length(y@i)) ## x@i <- integer(0L) ## .V2C(x) ## } else if(nx == ny) .m2sparse(any(match(x@i, y@i, 0L)), "ngR") else stop("non-conformable arguments") }) for(.cl in c("Matrix", "matrix")) { setMethod("%&%", signature(x = "sparseVector", y = .cl), function(x, y) { x <- .V2kind(.drop0(x, isM = FALSE), "n") if((k <- dim(y)[1L]) == length(x)) .tCRT(.V2C(x)) %&% y else if(k == 1L) .V2C(x) %&% y else stop("non-conformable arguments") }) setMethod("%&%", signature(x = .cl, y = "sparseVector"), function(x, y) { y <- .V2kind(.drop0(y, isM = FALSE), "n") if((k <- dim(x)[2L]) == length(y)) x %&% .V2C(y) else if(k == 1L) x %&% .tCRT(.V2C(y)) else stop("non-conformable arguments") }) } setMethod("%&%", signature(x = "sparseVector", y = "vector"), function(x, y) .V2kind(.drop0(x, isM = FALSE), "n") %&% .m2V(y, "n")) setMethod("%&%", signature(x = "vector", y = "sparseVector"), function(x, y) .m2V(x, "n") %&% .V2kind(.drop0(y, isM = FALSE), "n")) ## METHODS FOR GENERIC: crossprod ## NB: t(x) %*% y == t(t(y) %*% x) ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for(.cl in c("Matrix", "sparseVector")) { setMethod("crossprod", signature(x = .cl, y = "ANY"), function(x, y = NULL, ...) crossprod(x, (if(length(dim(y)) == 2L) as.matrix else as.vector)(y), ...)) setMethod("crossprod", signature(x = "ANY", y = .cl), function(x, y = NULL, ...) crossprod((if(length(dim(x)) == 2L) as.matrix else as.vector)(x), y, ...)) } ## .... denseMatrix .................................................... setMethod("crossprod", signature(x = "denseMatrix", y = "missing"), function(x, y = NULL, boolArith = NA, ...) if(if(is.na(boolArith)) .M.kind(x) == "n" else boolArith) .Call(R_sparse_matmult, x, y, TRUE, FALSE, FALSE, TRUE) else .Call(R_dense_matmult, x, y, TRUE, FALSE)) setMethod("crossprod", signature(x = "denseMatrix", y = "denseMatrix"), function(x, y = NULL, boolArith = NA, ...) if(if(is.na(boolArith)) .M.kind(x) == "n" && .M.kind(y) == "n" else boolArith) .Call(R_sparse_matmult, x, y, TRUE, FALSE, FALSE, TRUE) else .Call(R_dense_matmult, x, y, TRUE, FALSE)) for(.cl in c("matrix", "vector")) { setMethod("crossprod", signature(x = "denseMatrix", y = .cl), function(x, y = NULL, boolArith = NA, ...) if(!is.na(boolArith) && boolArith) .Call(R_sparse_matmult, x, y, TRUE, FALSE, FALSE, TRUE) else .Call(R_dense_matmult, x, y, TRUE, FALSE)) setMethod("crossprod", signature(x = .cl, y = "denseMatrix"), function(x, y = NULL, boolArith = NA, ...) if(!is.na(boolArith) && boolArith) .Call(R_sparse_matmult, x, y, TRUE, FALSE, FALSE, TRUE) else .Call(R_dense_matmult, x, y, TRUE, FALSE)) } ## .... CsparseMatrix .................................................. setMethod("crossprod", signature(x = "CsparseMatrix", y = "missing"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, TRUE, FALSE, FALSE, boolArith)) setMethod("crossprod", signature(x = "CsparseMatrix", y = "CsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, TRUE, FALSE, FALSE, boolArith)) setMethod("crossprod", signature(x = "CsparseMatrix", y = "RsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, TRUE, FALSE, FALSE, boolArith)) setMethod("crossprod", signature(x = "CsparseMatrix", y = "TsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, TRUE, FALSE, FALSE, boolArith)) for(.cl in c("denseMatrix", "matrix", "vector")) { setMethod("crossprod", signature(x = "CsparseMatrix", y = .cl), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, TRUE, FALSE, FALSE, boolArith)) setMethod("crossprod", signature(x = .cl, y = "CsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, y, x, TRUE, FALSE, TRUE, boolArith)) } ## .... RsparseMatrix .................................................. setMethod("crossprod", signature(x = "RsparseMatrix", y = "missing"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, TRUE, FALSE, TRUE, boolArith)) setMethod("crossprod", signature(x = "RsparseMatrix", y = "CsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, y, x, TRUE, FALSE, TRUE, boolArith)) setMethod("crossprod", signature(x = "RsparseMatrix", y = "RsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, y, x, TRUE, FALSE, TRUE, boolArith)) setMethod("crossprod", signature(x = "RsparseMatrix", y = "TsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, y, x, TRUE, FALSE, TRUE, boolArith)) for(.cl in c("denseMatrix", "matrix", "vector")) { setMethod("crossprod", signature(x = "RsparseMatrix", y = .cl), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, TRUE, FALSE, FALSE, boolArith)) setMethod("crossprod", signature(x = .cl, y = "RsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, y, x, TRUE, FALSE, TRUE, boolArith)) } ## .... TsparseMatrix .................................................. setMethod("crossprod", signature(x = "TsparseMatrix", y = "missing"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, TRUE, FALSE, FALSE, boolArith)) setMethod("crossprod", signature(x = "TsparseMatrix", y = "CsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, TRUE, FALSE, FALSE, boolArith)) setMethod("crossprod", signature(x = "TsparseMatrix", y = "RsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, TRUE, FALSE, FALSE, boolArith)) setMethod("crossprod", signature(x = "TsparseMatrix", y = "TsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, TRUE, FALSE, FALSE, boolArith)) for(.cl in c("denseMatrix", "matrix", "vector")) { setMethod("crossprod", signature(x = "TsparseMatrix", y = .cl), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, TRUE, FALSE, FALSE, boolArith)) setMethod("crossprod", signature(x = .cl, y = "TsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, y, x, TRUE, FALSE, TRUE, boolArith)) } ## .... diagonalMatrix ................................................. setMethod("crossprod", signature(x = "diagonalMatrix", y = "missing"), function(x, y = NULL, boolArith = NA, ...) { boolArith <- !is.na(boolArith) && boolArith r <- new(if(boolArith) "ndiMatrix" else "ddiMatrix") r@Dim <- x@Dim r@Dimnames <- x@Dimnames[c(2L, 2L)] if(x@diag != "N") r@diag <- "U" else { xii <- x@x r@x <- if(boolArith) as.logical(xii) else { if(.M.kind(x) == "n" && anyNA(xii)) xii <- xii | is.na(xii) as.double(xii * xii) } } r }) setMethod("crossprod", signature(x = "diagonalMatrix", y = "diagonalMatrix"), function(x, y = NULL, boolArith = NA, ...) (if(!is.na(boolArith) && boolArith) `%&%` else `%*%`)(t(x), y)) for(.cl in c("CsparseMatrix", "RsparseMatrix", "TsparseMatrix", "denseMatrix", "matrix", "vector")) { setMethod("crossprod", signature(x = "diagonalMatrix", y = .cl), function(x, y = NULL, boolArith = NA, ...) .Call(R_diagonal_matmult, x, y, TRUE, FALSE, boolArith)) setMethod("crossprod", signature(x = .cl, y = "diagonalMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_diagonal_matmult, x, y, TRUE, FALSE, boolArith)) } ## .... indMatrix ...................................................... setMethod("crossprod", signature(x = "indMatrix", y = "missing"), function(x, y = NULL, boolArith = NA, ...) { if(x@margin != 1L) return(tcrossprod(t(x), boolArith = boolArith, ...)) boolArith <- !is.na(boolArith) && boolArith tt <- tabulate(x@perm, x@Dim[2L]) r <- new(if(boolArith) "ndiMatrix" else "ddiMatrix") r@Dim <- x@Dim[c(2L, 2L)] r@Dimnames <- x@Dimnames[c(2L, 2L)] r@x <- if(boolArith) as.logical(tt) else as.double(tt) r }) for(.cl in c("Matrix", "matrix", "vector")) setMethod("crossprod", signature(x = "indMatrix", y = .cl), function(x, y = NULL, boolArith = NA, ...) (if(!is.na(boolArith) && boolArith) `%&%` else `%*%`)(t(x), y)) setMethod("crossprod", signature(x = "Matrix", y = "indMatrix"), function(x, y = NULL, boolArith = NA, ...) { matmultDim(x@Dim, y@Dim, type = 2L) l <- if(!is.na(boolArith) && boolArith) "n" else "," if(y@margin == 1L) r <- crossprod(x, .M2kind(y, l), boolArith = boolArith, ...) else { r <- .M2kind(t(x)[, y@perm, drop = FALSE], l) r@Dimnames <- matmultDN(dimnames(x), y@Dimnames, type = 2L) } r }) setMethod("crossprod", signature(x = "matrix", y = "indMatrix"), function(x, y = NULL, boolArith = NA, ...) { matmultDim(dim(x), y@Dim, type = 2L) l <- if(!is.na(boolArith) && boolArith) "n" else "," if(y@margin == 1L) r <- crossprod(x, .M2kind(y, l), boolArith = boolArith, ...) else { r <- .m2dense(t(x)[, y@perm, drop = FALSE], paste0(l, "ge")) r@Dimnames <- matmultDN(dimnames(x), y@Dimnames, type = 2L) } r }) setMethod("crossprod", signature(x = "vector", y = "indMatrix"), function(x, y = NULL, boolArith = NA, ...) { if(y@Dim[1L] != length(x)) stop("non-conformable arguments") l <- if(!is.na(boolArith) && boolArith) "n" else "," if(y@margin == 1L) r <- crossprod(x, .M2kind(y, l), boolArith = boolArith, ...) else { r <- .m2dense(x[y@perm], paste0(l, "ge"), trans = TRUE) r@Dimnames <- c(list(NULL), y@Dimnames[2L]) } r }) ## .... pMatrix ........................................................ setMethod("crossprod", signature(x = "pMatrix", y = "missing"), function(x, y = NULL, boolArith = NA, ...) { boolArith <- !is.na(boolArith) && boolArith r <- new(if(boolArith) "ndiMatrix" else "ddiMatrix") r@Dim <- x@Dim r@Dimnames <- x@Dimnames[c(2L, 2L)] r@diag <- "U" r }) setMethod("crossprod", signature(x = "pMatrix", y = "pMatrix"), function(x, y = NULL, boolArith = NA, ...) { r <- new("pMatrix") r@Dim <- matmultDim(x@Dim, y@Dim, type = 2L) r@Dimnames <- matmultDN(x@Dimnames, y@Dimnames, type = 2L) r@perm <- if(y@margin == 1L) y@perm[if(x@margin == 1L) invertPerm(x@perm) else x@perm] else { r@margin <- 2L (if(x@margin == 1L) x@perm else invertPerm(x@perm))[y@perm] } r }) setMethod("crossprod", signature(x = "Matrix", y = "pMatrix"), function(x, y = NULL, boolArith = NA, ...) { matmultDim(x@Dim, y@Dim, type = 2L) l <- if(!is.na(boolArith) && boolArith) "n" else "," perm <- if(y@margin == 1L) invertPerm(y@perm) else y@perm r <- .M2kind(t(x)[, perm, drop = FALSE], l) r@Dimnames <- matmultDN(dimnames(x), y@Dimnames, type = 2L) r }) setMethod("crossprod", signature(x = "matrix", y = "pMatrix"), function(x, y = NULL, boolArith = NA, ...) { matmultDim(dim(x), y@Dim, type = 2L) l <- if(!is.na(boolArith) && boolArith) "n" else "," perm <- if(y@margin == 1L) invertPerm(y@perm) else y@perm r <- .m2dense(t(x)[, perm, drop = FALSE], paste0(l, "ge")) r@Dimnames <- matmultDN(dimnames(x), y@Dimnames, type = 2L) r }) setMethod("crossprod", signature(x = "vector", y = "pMatrix"), function(x, y = NULL, boolArith = NA, ...) { if(y@Dim[1L] != length(x)) stop("non-conformable arguments") l <- if(!is.na(boolArith) && boolArith) "n" else "," perm <- if(y@margin == 1L) invertPerm(y@perm) else y@perm r <- .m2dense(x[perm], paste0(l, "ge"), trans = TRUE) r@Dimnames <- c(list(NULL), y@Dimnames[2L]) r }) ## .... sparseVector ................................................... setMethod("crossprod", signature(x = "sparseVector", y = "missing"), function(x, y = NULL, boolArith = NA, ...) if(if(is.na(boolArith)) .M.kind(x) == "n" else boolArith) { if(!is.na(boolArith)) x <- .V2kind(.drop0(x, isM = FALSE), "n") .m2sparse(length(x@i) > 0L, "nsR") } else .m2sparse(sum(x * x), ",sR")) setMethod("crossprod", signature(x = "sparseVector", y = "sparseVector"), function(x, y = NULL, boolArith = NA, ...) if(if(is.na(boolArith)) .M.kind(x) == "n" && .M.kind(y) == "n" else boolArith) { if(!is.na(boolArith)) { x <- .V2kind(.drop0(x, isM = FALSE), "n") y <- .V2kind(.drop0(y, isM = FALSE), "n") } if((nx <- length(x)) == 1L) { if(length(x@i) == 0L) y@i <- integer(0L) .tCRT(.V2C(y)) } else if(nx == length(y)) .m2sparse(any(match(x@i, y@i, 0L)), "ngR") else stop("non-conformable arguments") } else { if((nx <- length(x)) == 1L) .tCRT(.V2C(x * y)) else if(nx == length(y)) .m2sparse(sum(x * y), ",gR") else stop("non-conformable arguments") }) for(.cl in c("Matrix", "matrix")) { setMethod("crossprod", signature(x = "sparseVector", y = .cl), function(x, y = NULL, boolArith = NA, ...) crossprod(.tCRT(.V2C(x)), y, boolArith = boolArith, ...)) setMethod("crossprod", signature(x = .cl, y = "sparseVector"), function(x, y = NULL, boolArith = NA, ...) if(dim(x)[1L] == length(y)) crossprod(x, .V2C(y) , boolArith = boolArith, ...) else crossprod(x, .tCRT(.V2C(y)), boolArith = boolArith, ...)) } setMethod("crossprod", signature(x = "sparseVector", y = "vector"), function(x, y = NULL, boolArith = NA, ...) if(!is.na(boolArith) && boolArith) { x <- .V2kind(.drop0(x, isM = FALSE), "n") y <- .m2V(y, "n") if((nx <- length(x)) == 1L) { if(length(x@i) == 0L) y@i <- integer(0L) .tCRT(.V2C(y)) } else if(nx == length(y)) .m2sparse(any(match(x@i, y@i, 0L)), "ngR") else stop("non-conformable arguments") } else { if((nx <- length(x)) == 1L) .m2dense(.V2v(x * y), ",ge", trans = TRUE) else if(nx == length(y)) .m2dense(sum(x * y), ",ge") else stop("non-conformable arguments") }) setMethod("crossprod", signature(x = "vector", y = "sparseVector"), function(x, y = NULL, boolArith = NA, ...) if(!is.na(boolArith) && boolArith) { x <- .m2V(x, "n") y <- .V2kind(.drop0(y, isM = FALSE), "n") if((nx <- length(x)) == 1L) { if(length(x@i) == 0L) y@i <- integer(0L) .tCRT(.V2C(y)) } else if(nx == length(y)) .m2sparse(any(match(x@i, y@i, 0L)), "ngR") else stop("non-conformable arguments") } else { if((nx <- length(x)) == 1L) .m2dense(.V2v(x * y), ",ge", trans = TRUE) else if(nx == length(y)) .m2dense(sum(x * y), ",ge") else stop("non-conformable arguments") }) ## METHODS FOR GENERIC: tcrossprod ## NB: x %*% t(y) == t(y %*% t(x)) ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for(.cl in c("Matrix", "sparseVector")) { setMethod("tcrossprod", signature(x = .cl, y = "ANY"), function(x, y = NULL, ...) tcrossprod(x, (if(length(dim(y)) == 2L) as.matrix else as.vector)(y), ...)) setMethod("tcrossprod", signature(x = "ANY", y = .cl), function(x, y = NULL, ...) tcrossprod((if(length(dim(x)) == 2L) as.matrix else as.vector)(x), y, ...)) } ## .... denseMatrix .................................................... setMethod("tcrossprod", signature(x = "denseMatrix", y = "missing"), function(x, y = NULL, boolArith = NA, ...) if(if(is.na(boolArith)) .M.kind(x) == "n" else boolArith) .Call(R_sparse_matmult, x, y, FALSE, TRUE, FALSE, TRUE) else .Call(R_dense_matmult, x, y, FALSE, TRUE)) setMethod("tcrossprod", signature(x = "denseMatrix", y = "denseMatrix"), function(x, y = NULL, boolArith = NA, ...) if(if(is.na(boolArith)) .M.kind(x) == "n" && .M.kind(y) == "n" else boolArith) .Call(R_sparse_matmult, x, y, FALSE, TRUE, FALSE, TRUE) else .Call(R_dense_matmult, x, y, FALSE, TRUE)) for(.cl in c("matrix", "vector")) { setMethod("tcrossprod", signature(x = "denseMatrix", y = .cl), function(x, y = NULL, boolArith = NA, ...) if(!is.na(boolArith) && boolArith) .Call(R_sparse_matmult, x, y, FALSE, TRUE, FALSE, TRUE) else .Call(R_dense_matmult, x, y, FALSE, TRUE)) setMethod("tcrossprod", signature(x = .cl, y = "denseMatrix"), function(x, y = NULL, boolArith = NA, ...) if(!is.na(boolArith) && boolArith) .Call(R_sparse_matmult, x, y, FALSE, TRUE, FALSE, TRUE) else .Call(R_dense_matmult, x, y, FALSE, TRUE)) } ## .... CsparseMatrix .................................................. setMethod("tcrossprod", signature(x = "CsparseMatrix", y = "missing"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, FALSE, TRUE, FALSE, boolArith)) setMethod("tcrossprod", signature(x = "CsparseMatrix", y = "CsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, FALSE, TRUE, FALSE, boolArith)) setMethod("tcrossprod", signature(x = "CsparseMatrix", y = "RsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, FALSE, TRUE, FALSE, boolArith)) setMethod("tcrossprod", signature(x = "CsparseMatrix", y = "TsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, FALSE, TRUE, FALSE, boolArith)) for(.cl in c("denseMatrix", "matrix", "vector")) { setMethod("tcrossprod", signature(x = "CsparseMatrix", y = .cl), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, FALSE, TRUE, FALSE, boolArith)) setMethod("tcrossprod", signature(x = .cl, y = "CsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, y, x, FALSE, TRUE, TRUE, boolArith)) } ## .... RsparseMatrix .................................................. setMethod("tcrossprod", signature(x = "RsparseMatrix", y = "missing"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, FALSE, TRUE, TRUE, boolArith)) setMethod("tcrossprod", signature(x = "RsparseMatrix", y = "CsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, y, x, FALSE, TRUE, TRUE, boolArith)) setMethod("tcrossprod", signature(x = "RsparseMatrix", y = "RsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, y, x, FALSE, TRUE, TRUE, boolArith)) setMethod("tcrossprod", signature(x = "RsparseMatrix", y = "TsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, y, x, FALSE, TRUE, TRUE, boolArith)) for(.cl in c("denseMatrix", "matrix", "vector")) { setMethod("tcrossprod", signature(x = "RsparseMatrix", y = .cl), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, FALSE, TRUE, FALSE, boolArith)) setMethod("tcrossprod", signature(x = .cl, y = "RsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, y, x, FALSE, TRUE, TRUE, boolArith)) } ## .... TsparseMatrix .................................................. setMethod("tcrossprod", signature(x = "TsparseMatrix", y = "missing"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, FALSE, TRUE, FALSE, boolArith)) setMethod("tcrossprod", signature(x = "TsparseMatrix", y = "CsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, FALSE, TRUE, FALSE, boolArith)) setMethod("tcrossprod", signature(x = "TsparseMatrix", y = "RsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, FALSE, TRUE, FALSE, boolArith)) setMethod("tcrossprod", signature(x = "TsparseMatrix", y = "TsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, FALSE, TRUE, FALSE, boolArith)) for(.cl in c("denseMatrix", "matrix", "vector")) { setMethod("tcrossprod", signature(x = "TsparseMatrix", y = .cl), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, x, y, FALSE, TRUE, FALSE, boolArith)) setMethod("tcrossprod", signature(x = .cl, y = "TsparseMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_sparse_matmult, y, x, FALSE, TRUE, TRUE, boolArith)) } ## .... diagonalMatrix ................................................. setMethod("tcrossprod", signature(x = "diagonalMatrix", y = "missing"), function(x, y = NULL, boolArith = NA, ...) { boolArith <- !is.na(boolArith) && boolArith r <- new(if(boolArith) "ndiMatrix" else "ddiMatrix") r@Dim <- x@Dim r@Dimnames <- x@Dimnames[c(1L, 1L)] if(x@diag != "N") r@diag <- "U" else { xii <- x@x r@x <- if(boolArith) as.logical(xii) else { if(.M.kind(x) == "n" && anyNA(xii)) xii <- xii | is.na(xii) as.double(xii * xii) } } r }) setMethod("tcrossprod", signature(x = "diagonalMatrix", y = "diagonalMatrix"), function(x, y = NULL, boolArith = NA, ...) (if(!is.na(boolArith) && boolArith) `%&%` else `%*%`)(x, t(y))) for(.cl in c("CsparseMatrix", "RsparseMatrix", "TsparseMatrix", "denseMatrix", "matrix", "vector")) { setMethod("tcrossprod", signature(x = "diagonalMatrix", y = .cl), function(x, y = NULL, boolArith = NA, ...) .Call(R_diagonal_matmult, x, y, FALSE, TRUE, boolArith)) setMethod("tcrossprod", signature(x = .cl, y = "diagonalMatrix"), function(x, y = NULL, boolArith = NA, ...) .Call(R_diagonal_matmult, x, y, FALSE, TRUE, boolArith)) } ## .... indMatrix ...................................................... setMethod("tcrossprod", signature(x = "indMatrix", y = "missing"), function(x, y = NULL, boolArith = TRUE, ...) { if(x@margin != 1L) return(crossprod(t(x), boolArith = boolArith, ...)) boolArith <- !is.na(boolArith) && boolArith r <- new(if(boolArith) "ngeMatrix" else "dgeMatrix") r@Dim <- x@Dim[c(1L, 1L)] r@Dimnames <- x@Dimnames[c(1L, 1L)] r@x <- as.vector(`storage.mode<-`( .M2m(x), if(boolArith) "logical" else "double")[, x@perm]) r }) for(.cl in c("Matrix", "matrix", "vector")) setMethod("tcrossprod", signature(x = .cl, y = "indMatrix"), function(x, y = NULL, boolArith = NA, ...) (if(!is.na(boolArith) && boolArith) `%&%` else `%*%`)(x, t(y))) setMethod("tcrossprod", signature(x = "indMatrix", y = "Matrix"), function(x, y = NULL, boolArith = NA, ...) { matmultDim(x@Dim, y@Dim, type = 3L) l <- if(!is.na(boolArith) && boolArith) "n" else "," if(y@margin != 1L) r <- tcrossprod(.M2kind(x, l), y, boolArith = boolArith, ...) else { r <- .M2kind(t(y)[x@perm, , drop = FALSE], l) r@Dimnames <- matmultDN(x@Dimnames, dimnames(y), type = 3L) } r }) setMethod("tcrossprod", signature(x = "indMatrix", y = "matrix"), function(x, y = NULL, boolArith = NA, ...) { matmultDim(x@Dim, dim(y), type = 3L) l <- if(!is.na(boolArith) && boolArith) "n" else "," if(y@margin != 1L) r <- tcrossprod(.M2kind(x, l), y, boolArith = boolArith, ...) else { r <- .m2dense(t(y)[x@perm, , drop = FALSE], paste0(l, "ge")) r@Dimnames <- matmultDN(x@Dimnames, dimnames(y), type = 3L) } r }) setMethod("tcrossprod", signature(x = "indMatrix", y = "vector"), function(x, y = NULL, boolArith = NA, ...) { d <- x@Dim m <- d[1L] k <- d[2L] if(k != (if(m == 1L) length(y) else 1L)) stop("non-conformable arguments") boolArith <- !is.na(boolArith) && boolArith h <- if(boolArith) isN0 else as.double r <- new(if(boolArith) "ngeMatrix" else "dgeMatrix") r@Dim <- d <- c(m, if(m == 1L) 1L else length(y)) r@Dimnames <- c(x@Dimnames[1L], list(NULL)) r@x <- if(m == 1L) { if(x@margin == 1L) h(y[x@perm]) else (if(boolArith) any else sum)(h(y)) } else { if(x@margin == 1L) as.vector(matrix(h(y), m, length(y), byrow = TRUE)) else { tmp <- array(if(boolArith) FALSE else 0, d) tmp[y@perm, ] <- h(y) dim(tmp) <- NULL tmp } } r }) ## .... pMatrix ........................................................ setMethod("tcrossprod", signature(x = "pMatrix", y = "missing"), function(x, y = NULL, boolArith = NA, ...) { boolArith <- !is.na(boolArith) && boolArith r <- new(if(boolArith) "ndiMatrix" else "ddiMatrix") r@Dim <- x@Dim r@Dimnames <- x@Dimnames[c(1L, 1L)] r@diag <- "U" r }) setMethod("tcrossprod", signature(x = "pMatrix", y = "pMatrix"), function(x, y = NULL, boolArith = NA, ...) { r <- new("pMatrix") r@Dim <- matmultDim(x@Dim, y@Dim, type = 2L) r@Dimnames <- matmultDN(x@Dimnames, y@Dimnames, type = 2L) r@perm <- if(y@margin != 1L) y@perm[if(x@margin == 1L) x@perm else invertPerm(x@perm)] else { r@margin <- 2L (if(x@margin == 1L) invertPerm(x@perm) else x@perm)[y@perm] } r }) setMethod("tcrossprod", signature(x = "pMatrix", y = "Matrix"), function(x, y = NULL, boolArith = NA, ...) { matmultDim(x@Dim, y@Dim, type = 3L) l <- if(!is.na(boolArith) && boolArith) "n" else "," perm <- if(x@margin == 1L) x@perm else invertPerm(x@perm) r <- .M2kind(t(y)[perm, , drop = FALSE], l) r@Dimnames <- matmultDN(x@Dimnames, dimnames(y), type = 3L) r }) setMethod("tcrossprod", signature(x = "pMatrix", y = "matrix"), function(x, y = NULL, boolArith = NA, ...) { matmultDim(x@Dim, dim(y), type = 3L) l <- if(!is.na(boolArith) && boolArith) "n" else "," perm <- if(x@margin == 1L) x@perm else invertPerm(x@perm) r <- .m2dense(t(y)[perm, , drop = FALSE], paste0(l, "ge")) r@Dimnames <- matmultDN(x@Dimnames, dimnames(y), type = 3L) r }) setMethod("tcrossprod", signature(x = "pMatrix", y = "vector"), function(x, y = NULL, boolArith = NA, ...) { if(x@Dim[2L] != 1L || length(y) != 1L) stop("non-conformable arguments") l <- if(!is.na(boolArith) && boolArith) "n" else "," r <- .m2dense(y, paste0(l, "ge"), trans = TRUE) r@Dimnames <- c(x@Dimnames[1L], list(NULL)) r }) ## .... sparseVector ................................................... setMethod("tcrossprod", signature(x = "sparseVector", y = "missing"), function(x, y = NULL, boolArith = NA, ...) tcrossprod(.V2C(x), boolArith = boolArith, ...)) setMethod("tcrossprod", signature(x = "sparseVector", y = "sparseVector"), function(x, y = NULL, boolArith = NA, ...) (if(if(is.na(boolArith)) .M.kind(x) == "n" && .M.kind(y) == "n" else boolArith) `%&%` else `%*%`)(x, .tCRT(.V2C(y)))) for(.cl in c("Matrix", "matrix")) { setMethod("tcrossprod", signature(x = "sparseVector", y = .cl), function(x, y = NULL, boolArith = NA, ...) { x <- if(dim(y)[2L] == length(x)) .tCRT(.V2C(x)) else .V2C(x) tcrossprod(x, y, boolArith = boolArith, ...) }) setMethod("tcrossprod", signature(x = .cl, y = "sparseVector"), function(x, y = NULL, boolArith = NA, ...) { y <- if(dim(x)[1L] == 1L) .tCRT(.V2C(y)) else .V2C(y) tcrossprod(x, y, boolArith = boolArith, ...) }) } setMethod("tcrossprod", signature(x = "sparseVector", y = "vector"), function(x, y = NULL, boolArith = NA, ...) { r <- if(!is.na(boolArith) && boolArith) x %&% .m2sparse(y, "ngR", trans = TRUE) else x %*% .m2dense (y, ",ge", trans = TRUE) r@Dimnames <- list(NULL, NULL) r }) setMethod("tcrossprod", signature(x = "vector", y = "sparseVector"), function(x, y = NULL, boolArith = NA, ...) (if(!is.na(boolArith) && boolArith) `%&%` else `%*%`)(x, .tCRT(.V2C(y)))) rm(.cl) Matrix/R/spModels.R0000644000176200001440000005324614470702707013652 0ustar liggesusers#### Utilities for Sparse Model Matrices ## > from <- factor(sample(c(1:100, NA), size = 1e+04, replace = TRUE, ## + prob = rep.int(c(1, 20), c(100L, 1L)))) ## > microbenchmark::microbenchmark( ## + Matrix:::fac2sparse1(from, drop.unused.levels = FALSE), ## + Matrix:::fac2sparse2(from, drop.unused.levels = FALSE), ## + Matrix:::fac2sparse (from, drop.unused.levels = FALSE), ## + times = 10000L) ## Unit: microseconds ## expr min lq mean median uq max neval ## Matrix:::fac2sparse1(from, drop.unused.levels = FALSE) 94.997 105.001 118.6117 107.789 110.413 4439.111 10000 ## Matrix:::fac2sparse2(from, drop.unused.levels = FALSE) 538.289 586.341 643.7947 595.197 602.700 43128.556 10000 ## Matrix:::fac2sparse (from, drop.unused.levels = FALSE) 163.139 185.115 221.7241 190.117 193.889 44887.784 10000 if(FALSE) { ## The "first" version, no longer used: fac2sparse1 <- function(from, to = c("d", "i", "l", "n", "z"), drop.unused.levels = FALSE) { ## factor(-like) --> sparseMatrix {also works for integer, character} fact <- if (drop.unused.levels) factor(from) else as.factor(from) levs <- levels(fact) n <- length(fact) to <- match.arg(to) ## MM: using new() and then assigning slots has efficiency "advantage" ## of *not* validity checking res <- new(paste0(to, "gCMatrix")) res@i <- as.integer(fact) - 1L # 0-based res@p <- 0:n res@Dim <- c(length(levs), n) res@Dimnames <- list(levs, NULL) if(to != "n") res@x <- rep.int(switch(to, "d" = 1., "i" = 1L, "l" = TRUE, "z" = 1+0i), n) res } ## The "second" version, no longer used: ## * this one handles NAs correctly but may be slightly less efficient ## than fac2sparse1() above fac2sparse2 <- function(from, to = c("d", "i", "l", "n", "z"), drop.unused.levels = TRUE, repr = c("C", "T", "R"), giveCsparse) { ## factor(-like) --> sparseMatrix {also works for integer, character} fact <- if (drop.unused.levels) factor(from) else as.factor(from) levs <- levels(fact) n <- length(fact) to <- match.arg(to) i <- as.integer(fact) - 1L ## 0-based indices df <- data.frame(i = i, j = if(n) 0:(n-1L) else integer())[!is.na(i),] if(to != "n") df$x <- rep.int(switch(to, "d" = 1., "i" = 1L, "l" = TRUE, "z" = 1+0i), nrow(df)) T <- do.call(new, c(list(Class = paste0(to, "gTMatrix"), Dim = c(length(levs), n), Dimnames = list(levs, names(fact))), df)) ## silent, back compatible (not yet warning about 'giveCsparse' deprecation): repr <- if(missing(repr) && !missing(giveCsparse)) if(giveCsparse) "C" else "T" else match.arg(repr) switch(repr, "C" = .M2C(T), "T" = T,# TsparseMatrix "R" = .M2R(T)) } } # if(FALSE) ## The "third" version, dealing with NAs _and_ fast: fac2sparse <- function(from, to = c("d", "l", "n"), # no "i" or "z" yet drop.unused.levels = TRUE, repr = c("C", "R", "T"), giveCsparse) { cl <- ".g.Matrix" substr(cl, 1L, 1L) <- to <- match.arg(to) substr(cl, 3L, 3L) <- repr <- if(!missing(repr) || missing(giveCsparse)) match.arg(repr) else if(giveCsparse) "C" else "T" ## Arguments are valid: _now_ allocate from <- if(drop.unused.levels && is.factor(from)) factor(from) else as.factor(from) n <- length(from) lv <- levels(from) nlv <- length(lv) res <- new(cl) res@Dim <- c(nlv, n) res@Dimnames <- list(lv, names(from)) i. <- switch(repr, "C" = { not.na <- !is.na(from) res@p <- c(0L, cumsum(not.na)) res@i <- as.integer(from)[not.na] - 1L }, "R" = { res@p <- c(0L, cumsum(tabulate(from, nlv))) res@j <- order(from, na.last = NA) - 1L }, "T" = { which.not.na <- which(!is.na(from)) res@i <- as.integer(from)[which.not.na] - 1L res@j <- which.not.na - 1L } ) if(to != "n") res@x <- rep.int(switch(to, "d" = 1, "l" = TRUE, "i" = 1L, "z" = 1+0i), length(i.)) res } setAs("factor", "sparseMatrix", function(from) fac2sparse(from, to = "d")) ## FIXME? support factor->[dlnCRT]sparseMatrix? ##' fac2Sparse() := fac2sparse w/ contrasts ##' ##' @param from factor of which we want the "contrasted" (indicator) ##' design matrix ##' @param to character string specifying the response type ##' @param drop.unused.level logical indicating if non-present factor ##' levels should be dropped, via factor(from) ##' @param factorPatt12 logical vector fp[] of length 2 ##' fp[1] : give contrasted t(X); fp[2] : give "dummy" t(X) [=fac2sparse()] ##' @param contrasts.arg character string or NULL or (coercible to) ##' sparseMatrix, specifying the contrast ##' ##' @return a list of length two, each with the corresponding t(model matrix), ##' when the corresponding factorPatt12 is true. fac2Sparse <- function(from, to = c("d", "l", "n"), # no "i" or "z" yet drop.unused.levels = TRUE, repr = c("C", "R", "T"), giveCsparse, factorPatt12, contrasts.arg = NULL) { stopifnot(is.logical(factorPatt12), length(factorPatt12) == 2L) if(!any(factorPatt12)) return(list(NULL, NULL)) # nothing to do m <- fac2sparse(from, to = to, drop.unused.levels = drop.unused.levels, repr = repr, giveCsparse = giveCsparse) list(if(factorPatt12[1L]) { ## contrasted coding, using 'contrasts.arg' if(is.null(contrasts.arg)) contrasts.arg <- getOption("contrasts")[[if(is.ordered(from)) "ordered" else "unordered"]] crossprod(if(is.character(contrasts.arg)) { ## calling contr.*() with level names directly: contr <- get(contrasts.arg, mode = "function") contr(m@Dimnames[[1L]], sparse = TRUE) } else as(contrasts.arg, "sparseMatrix"), m) }, if(factorPatt12[2L]) ## uncontrasted ("dummy") coding m ) } ## Cut and paste from stats:::deparse2() in stats/R/models.R deparse2 <- function(x) paste(deparse(x, width.cutoff = 500L, backtick = !is.symbol(x) && is.language(x)), collapse = " ") ## Cut and paste from stats:::model.matrix.default() in stats/R/models.R, ## with some adaptation, most notably at the very end where we do _not_ ## call the C-level utility of 'stats' sparse.model.matrix <- function(object, data = environment(object), contrasts.arg = NULL, xlev = NULL, transpose = FALSE, drop.unused.levels = FALSE, row.names = TRUE, sep = "", verbose = FALSE, ...) { t <- if(missing(data)) terms(object) else terms(object, data=data) if (is.null(attr(data, "terms"))) data <- model.frame(object, data, xlev=xlev) else { reorder <- match(vapply(attr(t, "variables"), deparse2, "")[-1L], names(data)) if (anyNA(reorder)) stop("model frame and formula mismatch in sparse.model.matrix()") if(!identical(reorder, seq_len(ncol(data)))) data <- data[,reorder, drop=FALSE] } int <- attr(t, "response") if(length(data)) { contr.funs <- as.character(getOption("contrasts")) namD <- names(data) ## turn any character columns into factors for(i in namD) if(is.character(data[[i]])) data[[i]] <- factor(data[[i]]) isF <- vapply(data, function(x) is.factor(x) || is.logical(x), NA) isF[int] <- FALSE isOF <- vapply(data, is.ordered, NA) for(nn in namD[isF]) # drop response if(is.null(attr(data[[nn]], "contrasts"))) contrasts(data[[nn]]) <- contr.funs[1 + isOF[nn]] ## it might be safer to have numerical contrasts: ## get(contr.funs[1 + isOF[nn]])(nlevels(data[[nn]])) if (!is.null(contrasts.arg)) { if (!is.list(contrasts.arg)) warning("non-list contrasts argument ignored") else { ## contrasts.arg is a list if (is.null(namC <- names(contrasts.arg))) stop("'contrasts.arg' argument must be named") for (nn in namC) { if (is.na(ni <- match(nn, namD))) warning(gettextf("variable '%s' is absent, its contrast will be ignored", nn), domain = NA) else { ca <- contrasts.arg[[nn]] ## contrasts(*, ncol(m)) <- m works also ## for function||character 'm' in R >= 4.2, ## which supports how.many=NULL if(is.matrix(ca) || is(ca, "Matrix")) contrasts(data[[ni]], ncol(ca)) <- ca else contrasts(data[[ni]]) <- ca } } } } ## non-null contrasts.arg } else { # no rhs terms ('~1', or '~0'): internal model.matrix needs some variable isF <- FALSE data[["x"]] <- raw(nrow(data)) } ## ## ans <- .External2(C_modelmatrix, t, data) ## if(any(isF)) ## attr(ans, "contrasts") <- lapply(data[isF], attr, "contrasts") ## ## if(verbose) { cat("model.spmatrix(t, data, ...) with t =\n") str(t, give.attr = FALSE) } ans <- model.spmatrix(trms = t, mf = data, transpose = transpose, drop.unused.levels = drop.unused.levels, row.names = row.names, sep = sep, verbose = verbose) ## MJ: hmm ... our tests require that this "slot" exists, ## even in the empty case, i.e., !any(isF) ... why? attr(ans, "contrasts") <- lapply(data[isF], attr, "contrasts") ## ans } # sparse.model.matrix ##' Produce the t(Z); Z = "design matrix" of (X : Y), where ##' --- t(Z) : aka rowwise -version : "r" ##' ##' @title sparse model matrix for 2-way interaction ##' @param X and Y either are numeric matrices {maybe 1-column} ##' @param Y or "as(, sparseM)" {dgCMatrix} ##' @param do.names logical ##' @param forceSparse logical ##' @return ##' @author Martin Maechler .sparse.interaction.2 <- # formerly sparse2int() function(X, Y, do.names = TRUE, forceSparse = FALSE, verbose = FALSE) { ### FIXME -- the X[rep(..), ] * Y[rep(..), ] construct can become HUGE, even for sparse X[],Y[] ### ----- --> Matrix bug #1330 and ~/R/MM/Pkg-ex/Matrix/sparse-matrix-fix.R ## MJ: Moreover, as(, "sparseMatrix") is a dgCMatrix, ## for which row-indexing is already rather inefficient ... FIXME? sx <- isS4(X) sy <- isS4(Y) nx <- (dx <- dim(X))[1L] ny <- (dy <- dim(Y))[1L] if(verbose) cat(sprintf(".sparse.interaction.2(%s[%d], %s[%d])\n", if(sx) "" else "", nx, if(sy) "" else "", ny)) if(do.names) { dnx <- dimnames(X) dny <- dimnames(Y) } dimnames(X) <- dimnames(Y) <- list(NULL, NULL) r <- if(sx && sy) { ## 'X' and 'Y' are dgCMatrix (if(ny == 1L) X else X[rep.int(seq_len(nx), times = ny), ]) * (if(nx == 1L) Y else Y[rep (seq_len(ny), each = nx), ]) } else if (sx) { ## 'X' is a dgCMatrix, 'Y' is a numeric matrix if(ny <= 1L) { ## FIXME: a similar trick would be applicable for ny > 1 r <- X dp <- X@p[-1L] - X@p[-(dx[2L]+1L)] ## stopifnot(all(dp %in% 0:1)) r@x <- Y[dp == 1L] * X@x r } else { X[rep.int(seq_len(nx), times = ny), ] * (if(nx == 1L) Y else Y[rep (seq_len(ny), each = nx), ]) } } else if(sy) { ## 'X' is a numeric matrix, 'Y' is a dgCMatrix if(nx <= 1L) { ## FIXME: a similar trick would be applicable for nx > 1 r <- Y dp <- Y@p[-1L] - Y@p[-(dy[2L]+1L)] ## stopifnot(all(dp %in% 0:1)) r@x <- X[dp == 1L] * Y@x r } else { (if(ny == 1L) X else X[rep.int(seq_len(nx), times = ny), ]) * Y[rep (seq_len(ny), each = nx), ] } } else { ## 'X' and 'Y' are numeric matrices r <- (if(ny == 1L) X else X[rep.int(seq_len(nx), times = ny), ]) * (if(nx == 1L) Y else Y[rep (seq_len(ny), each = nx), ]) if(forceSparse) .m2sparse(r, "dgC") else r } ## FIXME: This 'names' business needs a good solution ... ## but maybe "up in the caller" ... if(do.names && !is.null(dim(r)) && !is.null(rnx <- dnx[[1L]]) && !is.null(rny <- dny[[1L]])) dimnames(r)[[1L]] <- outer(rnx, rny, paste, sep = ":") r } # .sparse.interaction.2 ##' Sparse Model Matrix for a (high order) interaction term A:B:x:C ##' ##' @param rList list(.) of (transposed) single-factor model matrices, ##' belonging to, say, factors a, b, c,... ##' @param do.names ##' @param forceSparse ##' @param verbose ##' @return the model matrix corresponding to a:b:... .sparse.interaction.N <- # formerly sparseInt.r() function(rList, do.names = TRUE, forceSparse = FALSE, verbose = FALSE) { if((n <- length(rList)) == 0L) return(NULL) # caller beware if(verbose) cat(sprintf(".sparse.interaction.N([%d], fS=%s): is.mat=(%s)\n", n, forceSparse, paste0(symnum(vapply(rList, is.matrix, NA)), collapse = "")), sep = "") r <- rList[[1L]] if(n > 1L) for(i in 2:n) r <- .sparse.interaction.2(r, rList[[i]], forceSparse = forceSparse, do.names = do.names, verbose = verbose) if(!forceSparse) r else if(!isS4(r)) .m2sparse(r, "dgC") else if(is(r, "denseMatrix")) .dense2sparse(r, "C") else r } # .sparse.interaction.N ## MJ: unused if(FALSE) { is.model.frame <- function(x) { ## Purpose: check if x is a "valid" model.frame ## ------------------------------------------------------------ ## Author: Martin Maechler, Date: 3 Jul 2009 is.data.frame(x) && !is.null(tms <- attr(x, "terms")) && inherits(tms, "terms") && ## is.terms() would be better inherits(tms, "formula") && is.matrix(attr(tms, "factors")) && is.language(vv <- attr(tms, "variables")) && vv[[1]] == as.symbol("list") && all(vapply(as.list(vv[-1]), as.character, "") %in% colnames(x)) ## all((vars <- sapply(as.list(vv[-1]), as.character)) %in% colnames(x)) ## and we could go on testing vars } } ## MJ ##' Create a sparse model matrix from a model frame. ##' ##' @title Sparse Model Matrix from Model Frame ##' @param trms a "terms" object ##' @param mf a data frame, typically resulting from model.frame() ##' @param transpose logical indicating if X' = t(X) {is faster!} ##' or X should be returned ##' @param drop.unused.levels logical indicating if unused factor ##' levels should be dropped ##' @param row.names ##' @return sparse matrix (class "dgCMatrix") ##' @author Martin Maechler model.spmatrix <- function(trms, mf, transpose=FALSE, drop.unused.levels = FALSE, row.names=TRUE, sep="", verbose=FALSE) { ## Author: Martin Maechler, Date: 7 Jul 2009 ## mf is a model frame or a "simple" data.frame [after reorder !] stopifnot(is.data.frame(mf)) n <- nrow(mf) if(row.names) rnames <- row.names(mf) ## mf: make into list, dropping all attributes (but the names) ### FIXME: for poly(., 5) mf has a 5-column matrix as "one column" => looses names here fnames <- names(mf <- unclass(mf)) attributes(mf) <- list(names = fnames) if(length(factorPattern <- attr(trms, "factors"))) { d <- dim(factorPattern) nVar <- d[1] nTrm <- d[2] n.fP <- dimnames(factorPattern) fnames <- n.fP[[1]] # == names of variables {incl. "F(var)"} in the model Names <- n.fP[[2]] # == colnames == names of terms: "a", "b:c", ... } else { ## degenerate, e.g. 'Y ~ 1' nVar <- nTrm <- 0L fnames <- Names <- character(0) } ## all the "variables in the model" are also in "mf", including "sin(x)"; ## actually, ..../src/main/model.c even assumes stopifnot((m <- length(mf)) >= nVar) if(verbose) cat(sprintf("model.spmatrix(): (n=%d, nVar=%d (m=%d), nTrm=%d)\n", n, nVar,m, nTrm)) if(m > nVar) mf <- mf[seq_len(nVar)] stopifnot(fnames == names(mf), allow.logical0 = TRUE) noVar <- nVar == 0 ##>> this seems wrong; we use 1:nVar for indexing mf[] below .. ##>> if(noVar) nVar <- 1L # (as in ~/R/D/r-devel/R/src/main/model.c) ## Note: "character" variables have been changed to factor in the caller; ## hence: both factor and *logical* should be dealt as factor : is.f <- if(noVar) logical(0) else vapply(mf, function(.) is.factor(.) | is.logical(.), NA) indF <- which(is.f) if(verbose) { cat(" --> indF =\n"); print(indF) } hasInt <- attr(trms, "intercept") == 1 ## the degree of interaction: ## intOrder <- attr(trms, "order") ## if(!hasInt && length(indF)) { ## change the '1' of the first factor into a '2' : if(any(i1 <- factorPattern[indF, ] == 1)) ## replace at the first '1' location: factorPattern[indF,][which.max(i1)] <- 2L else {} ## nothing to do } ## Convert "factors" to "Rowwise- sparseMatrix ("dummy"-matrix) ----------- ## Result: a list of sparse model matrices for the "factor"s : f.matr <- structure(vector("list", length = length(indF)), names = fnames[indF]) i.f <- 0 ## ---- For each variable in the model ------------------- for(i in seq_len(nVar)) { nam <- fnames[i] f <- mf[[i]] if(is.f[i]) { fp <- factorPattern[i,] ## == factorPattern[nam,] contr <- attr(f, "contrasts") f.matr[[(i.f <- i.f + 1)]] <- # a list of 2 lapply(fac2Sparse(f, to = "d", drop.unused.levels=drop.unused.levels, factorPatt12 = 1:2 %in% fp, contrasts.arg = contr), function(s) { if(!is.null(s)) { ## for some contr.*(), have lost rownames; hmm.. if(is.null(rn <- rownames(s))) rn <- seq_len(nrow(s)) rownames(s) <- paste(nam, rn, sep = sep) } s }) } else { ## continuous variable --> "matrix" - for all of them if(any(iA <- (cl <- class(f)) == "AsIs")) # drop "AsIs" class class(f) <- if(length(cl) > 1L) cl[!iA] nr <- if(is.matrix(f)) nrow(f <- t(f)) else (dim(f) <- c(1L, length(f)))[1] if(is.null(rownames(f))) rownames(f) <- if(nr == 1) nam else paste(nam, seq_len(nr), sep=sep) mf[[i]] <- f } } if(verbose) { cat(" ---> f.matr list :\n") str(f.matr, max.level = as.integer(verbose)) fNms <- format(dQuote(Names)) dim.string <- gsub('5', as.character(floor(1+log10(n))), " -- concatenating (r, rj): dim = (%5d,%5d) | (%5d,%5d)\n") } ## FIXME: do all this in C -- getR <- function(N) # using 'nm' if(!is.null(r <- f.matr[[N]])) r[[factorPattern[N, nm]]] else mf[[N]] vNms <- "(Intercept)"[hasInt] counts <- integer(nTrm) r <- if(hasInt) ## column of 1's - as sparse new("dgCMatrix", i = 0:(n-1L), p = c(0L, n), Dim = c(n, 1L), x = rep.int(1, n)) else new("dgCMatrix", Dim = c(n, 0L)) if(transpose) r <- t(r) iTrm <- seq_len(nTrm) for(j in iTrm) { ## j-th term nm <- Names[j] if(verbose) cat(sprintf("term[%2d] %s .. ", j, fNms[j])) nmSplits <- strsplit(nm, ":", fixed=TRUE)[[1]] ## NOTA BENE: This can be very slow when many terms are involved ## FIXME ??? why does it use *much* memory in those cases ?? rj <- .sparse.interaction.N(lapply(nmSplits, getR), do.names = TRUE, forceSparse = TRUE, verbose = verbose) # or just (verbose >= 2) if(verbose) cat(sprintf(dim.string, nrow(r), ncol(r), nrow(rj),ncol(rj))) ## fast version of cbind2() / rbind2(), w/o checks, dimnames, etc r <- if(transpose) rbind.Matrix(r, rj ) else cbind.Matrix(r, t(rj)) ## if(verbose) cat(" [Ok]\n") vNms <- c(vNms, dimnames(rj)[[1]]) counts[j] <- nrow(rj) } rns <- if(row.names) rnames dimnames(r) <- if(transpose) list(vNms, rns) else list(rns, vNms) attr(r, "assign") <- c(if(hasInt) 0L, rep(iTrm, counts)) r } ## model.spmatrix() Matrix/R/rankMatrix.R0000644000176200001440000001427214516234475014203 0ustar liggesusers#### Determine *the* rank of a matrix #### -------------------------------- ## ## As this is not such a well-defined problem as people think, ## we provide *some* possibilities here, including the Matlab one. ## ## Ideas by Martin Maechler (April 2007) and Ravi Varadhan (October 2007) qr2rankMatrix <- function(qr, tol = NULL, isBqr = is.qr(qr), do.warn=TRUE) { ## NB: 1) base::qr(*, LAPACK = TRUE/FALSE) differ via attr(.,"useLAPACK") ## 2) if LAPACK=TRUE, .$rank is useless (always = full rank) ## ## return ( . ) : if(isBqr && !isTRUE(attr(qr, "useLAPACK"))) qr$rank else { diagR <- if(isBqr) # hence "useLAPACK" here diag(qr$qr) # faster than, but equivalent to diag(qr.R(q.r)) else ## ==> assume Matrix::qr() i.e., currently "sparseQR" ## FIXME: Here, we could be quite a bit faster, ## by not returning the full sparseQR, but just ## doing the following in C, and return the rank. diag(qr@R) if(anyNA(diagR) || !all(is.finite(diagR))) { if(do.warn) { ifi <- is.finite(diagR) warning(gettextf( "qr2rankMatrix(.): QR with only %d out of %d finite diag(R) entries", sum(ifi), length(ifi))) } ## return NA_integer_ ## alternative: gives *too* small rank in typical cases ## reduce the maximal rank by omitting all non-finite entries: ## diagR <- diagR[is.finite(diagR)] ## if(length(diagR) == 0) ## return(NA_integer_) } else { diagR <- abs(diagR) # sign( diag(R) ) are *not* coerced to positive ## declare those entries to be zero that are < tol*max(.) if((mdi <- max(diagR, na.rm=TRUE)) > 0) { if(!is.numeric(tol)) { ## d := dim(x) extracted from qr, in both (dense and sparse) qr() cases d <- dim(if(isBqr) qr$qr else qr) tol <- max(d) * .Machine$double.eps } sum(diagR >= tol * mdi) ## was sum(diag(q.r@R) != 0) } else 0L # for 0-matrix or all NaN or negative diagR[] } } ## else {Lapack or sparseQR} } rankMatrix <- function(x, tol = NULL, method = c("tolNorm2", "qr.R", "qrLINPACK", "qr", "useGrad", "maybeGrad"), sval = svd(x, 0,0)$d, warn.t = TRUE, warn.qr = TRUE) { ## Purpose: rank of a matrix ``as Matlab'' or "according to Ravi V" ## ---------------------------------------------------------------------- ## Arguments: x: a numerical matrix, maybe non-square ## tol: numerical tolerance (compared to singular values) ## sval: vector of non-increasing singular values of x ## (pass as argument if already known) ## ---------------------------------------------------------------------- ## Author: Martin Maechler, Date: 7 Apr 2007, 16:16 ## ---------------------------------------------------------------------- ## ## maybeGrad (Ravi V.): This algorithm determines the rank based on the ## "gradient" of the ## absolute, singular values, rather than enforcing a rigid ## tolerance criterion, ## ## Author: Ravi Varadhan, Date: 22 October 2007 // Tweaks: MM, Oct.23 ## ---------------------------------------------------------------------- stopifnot(length(d <- dim(x)) == 2) p <- min(d) ## miss.meth <- missing(method) method <- match.arg(method) if(useGrad <- (method %in% c("useGrad", "maybeGrad"))) { stopifnot(length(sval) == p) if(p > 1) stopifnot(diff(sval) <= 0) # must be sorted non-increasingly: max = s..[1] if(sval[1] == 0) { ## <==> all singular values are zero <==> Matrix = 0 <==> rank = 0 useGrad <- FALSE method <- eval(formals()[["method"]])[[1]] } else { ln.av <- log(abs(sval)) if(any(s0 <- sval == 0)) ln.av[s0] <- - .Machine$double.xmax # so we get diff() == 0 diff1 <- diff(ln.av) if(method == "maybeGrad") { grad <- (min(ln.av) - max(ln.av)) / p useGrad <- !is.na(grad) && p > 1 && min(diff1) <= min(-3, 10 * grad) }# ------- } } if(!useGrad) { x.dense <- is.numeric(x) || is(x,"denseMatrix") ## "qr" is allowed for backcompatibility [change @ 2013-11-24] if((Meth <- method) == "qr") method <- if(x.dense) "qrLINPACK" else "qr.R" else Meth <- substr(method, 1,2) if(Meth == "qr") { if(is.null(tol)) tol <- max(d) * .Machine$double.eps } else { ## (Meth != "qr"), i.e. "tolNorm2" if(is.null(tol)) { if(!x.dense && missing(sval) && prod(d) >= 100000L) warning(gettextf( "rankMatrix(, method = '%s') coerces to dense matrix. Probably should rather use method = 'qr' !?", method), immediate.=TRUE, domain=NA) ## the "Matlab" default: if(p > 1) stopifnot(diff(sval) <= 0) #=> sval[1]= max(sval) tol <- max(d) * .Machine$double.eps } else stopifnot((tol <- as.numeric(tol)[[1]]) >= 0) } } structure(## rank : if(useGrad) which.min(diff1) else if(Meth == "qr") { if((do.t <- (d[1L] < d[2L])) && warn.t) warning(gettextf( "rankMatrix(x, method='qr'): computing t(x) as nrow(x) < ncol(x)")) q.r <- qr(if(do.t) t(x) else x, tol=tol, LAPACK = method != "qrLINPACK") qr2rankMatrix(q.r, tol=tol, isBqr = x.dense, do.warn = warn.qr) } else if(sval[1] > 0) sum(sval >= tol * sval[1]) else 0L, ## "tolNorm2" "method" = method, "useGrad" = useGrad, "tol" = if(useGrad) NA else tol) } ## Ravi's plot of the absolute singular values: if(FALSE) { ## if (plot.eigen) { plot(abs(sval), type = "b", xlab = "Index", xaxt = "n", log = "y", ylab = "|singular value| [log scaled]") axis(1, at = unique(c(axTicks(1), rank, p))) abline(v = rank, lty = 3) mtext(sprintf("rank = %d (used %s (%g))", rank, if(use.grad)"'gradient'" else "fixed tol.", if(use.grad) min(diff1) else tol)) } Matrix/R/LU.R0000644000176200001440000003152114503364553012374 0ustar liggesusers## METHODS FOR GENERIC: lu ## pivoted LU factorization, returning denseLU or sparseLU ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("lu", signature(x = "matrix"), function(x, ...) lu(.m2dense(x, ",ge"), ...)) setMethod("lu", signature(x = "denseMatrix"), function(x, ...) lu(.M2kind(x, ","), ...)) setMethod("lu", signature(x = "dgeMatrix"), function(x, warnSing = TRUE, ...) .Call(dgeMatrix_trf, x, as.logical(warnSing))) setMethod("lu", signature(x = "dsyMatrix"), function(x, cache = TRUE, ...) { if(!is.null(ch <- x@factors[["denseLU"]])) return(ch) r <- lu(.M2gen(x), ...) if(cache) .set.factor(x, "denseLU", r) else r }) setMethod("lu", signature(x = "dspMatrix"), function(x, cache = TRUE, ...) { if(!is.null(ch <- x@factors[["denseLU"]])) return(ch) r <- lu(.M2gen(x), ...) if(cache) .set.factor(x, "denseLU", r) else r }) for(.cl in c("dtrMatrix", "dtpMatrix")) setMethod("lu", signature(x = .cl), function(x, ...) { if(x@uplo == "U" || x@diag == "U") { r <- new("denseLU") r@Dim <- d <- x@Dim r@Dimnames <- x@Dimnames r@perm <- seq_len(d[1L]) r@x <- .M2gen(x)@x r } else lu(.M2gen(x), ...) }) rm(.cl) setMethod("lu", signature(x = "sparseMatrix"), function(x, ...) lu(.M2kind(.M2C(x), ","), ...)) setMethod("lu", signature(x = "dgCMatrix"), function(x, errSing = TRUE, order = NA_integer_, tol = 1, ...) .Call(dgCMatrix_trf, x, order, tol, errSing)) setMethod("lu", signature(x = "dsCMatrix"), function(x, cache = TRUE, ...) { if(!is.null(ch <- x@factors[["sparseLU"]])) return(ch) r <- lu(.M2gen(x), ...) if(cache) .set.factor(x, "sparseLU", r) else r }) setMethod("lu", "dtCMatrix", function(x, ...) { if((upper <- x@uplo == "U") || x@diag == "U") { n <- (d <- x@Dim)[1L] r <- new("sparseLU") y <- new("dtCMatrix") y@Dim <- d y@uplo <- if(upper) "L" else "U" y@diag <- "U" y@p <- integer(n + 1L) r@Dim <- d r@Dimnames <- x@Dimnames r@L <- if(upper) y else x r@U <- if(upper) x else y r@p <- r@q <- seq.int(from = 0L, length.out = n) } else lu(.M2gen(x), ...) }) setMethod("lu", signature(x = "dgRMatrix"), function(x, cache = TRUE, ...) { if(!is.null(ch <- x@factors[["sparseLU"]])) return(ch) r <- lu(.M2C(x), ...) if(cache) .set.factor(x, "sparseLU", r) else r }) setMethod("lu", signature(x = "dsRMatrix"), function(x, cache = TRUE, ...) { if(!is.null(ch <- x@factors[["sparseLU"]])) return(ch) r <- lu(.M2gen(.tCRT(x)), ...) if(cache) .set.factor(x, "sparseLU", r) else r }) setMethod("lu", signature(x = "dtRMatrix"), function(x, ...) { if((upper <- x@uplo == "U") || x@diag == "U") { n <- (d <- x@Dim)[1L] r <- new("sparseLU") y <- new("dtCMatrix") y@Dim <- d y@uplo <- if(upper) "L" else "U" y@diag <- "U" y@p <- integer(n + 1L) r@Dim <- d r@Dimnames <- x@Dimnames r@L <- if(upper) y else .M2C(x) r@U <- if(upper) .M2C(x) else y r@p <- r@q <- seq.int(from = 0L, length.out = n) } else lu(.M2gen(.M2C(x)), ...) }) setMethod("lu", signature(x = "dgTMatrix"), function(x, cache = TRUE, ...) { if(!is.null(ch <- x@factors[["sparseLU"]])) return(ch) r <- lu(.M2C(x), ...) if(cache) .set.factor(x, "sparseLU", r) else r }) setMethod("lu", signature(x = "dsTMatrix"), function(x, cache = TRUE, ...) { if(!is.null(ch <- x@factors[["sparseLU"]])) return(ch) r <- lu(.M2gen(.M2C(x)), ...) if(cache) .set.factor(x, "sparseLU", r) else r }) setMethod("lu", signature(x = "dtTMatrix"), function(x, ...) { if((upper <- x@uplo == "U") || x@diag == "U") { n <- (d <- x@Dim)[1L] r <- new("sparseLU") y <- new("dtCMatrix") y@Dim <- d y@uplo <- if(upper) "L" else "U" y@diag <- "U" y@p <- integer(n + 1L) r@Dim <- d r@Dimnames <- x@Dimnames r@L <- if(upper) y else .M2C(x) r@U <- if(upper) .M2C(x) else y r@p <- r@q <- seq.int(from = 0L, length.out = n) r } else lu(.M2gen(.M2C(x)), ...) }) setMethod("lu", "diagonalMatrix", function(x, ...) { x <- .M2kind(x, ",") n <- (d <- x@Dim)[1L] L <- new("dtCMatrix") r <- new("sparseLU") L@Dim <- d L@uplo <- "L" L@diag <- "U" L@p <- integer(n + 1L) r@L <- L if(x@diag == "N") { L@diag <- "N" L@p <- seq.int(from = 0L, length.out = n + 1L) L@x <- x@x } r@U <- L r@Dim <- d r@Dimnames <- x@Dimnames r@p <- r@q <- seq.int(from = 0L, length.out = n) r }) ## METHODS FOR CLASS: denseLU ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## TODO: we have C-level functions that do this, but no R interface .mkL <- function(x, m, n) { if(m == n) x else if(m < n) x[seq_len(prod(m, m))] else { x[seq.int(from = 1L, by = m + 1, length.out = n)] <- 1 if(n > 1L) { nvec <- seq_len(n - 1L) from <- seq.int(from = m + 1, by = m, length.out = n - 1L) x[sequence.default(nvec, from)] <- 0 } x } } .mkU <- function(x, m, n) { if(m == n) x else if(m > n) { nvec <- rep.int(n, n) from <- seq.int(from = 1L, by = m, length.out = n) x[sequence.default(nvec, from)] } else { if(m > 1L) { nvec <- seq.int(to = 1L, by = -1L, length.out = m - 1L) from <- seq.int(from = 2L, by = m + 1, length.out = m - 1L) x[sequence.default(nvec, from)] <- 0 } x } } setAs("denseLU", "dgeMatrix", function(from) { to <- new("dgeMatrix") to@Dim <- from@Dim to@x <- from@x to }) setMethod("expand1", signature(x = "denseLU"), function(x, which, ...) { d <- x@Dim m <- d[1L] n <- d[2L] switch(which, "P1" =, "P1." = { r <- new("pMatrix") r@Dim <- c(m, m) r@perm <- asPerm(x@perm, n = m) if(which == "P1.") r@margin <- 2L r }, "L" = { if(m <= n) { r <- new("dtrMatrix") r@Dim <- c(m, m) r@uplo <- "L" r@diag <- "U" } else { r<- new("dgeMatrix") r@Dim <- d } r@x <- .mkL(x@x, m, n) r }, "U" = { if (m >= n) { r <- new("dtrMatrix") r@Dim <- c(n, n) } else { r <- new("dgeMatrix") r@Dim <- d } r@x <- .mkU(x@x, m, n) r }, stop(gettextf("'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%3$s\", or \"%4$s\"", "which", "P", "L", "U"), domain = NA)) }) ## returning list(P1', L, U), where A = P1' L U setMethod("expand2", signature(x = "denseLU"), function(x, ...) { d <- x@Dim dn <- x@Dimnames m <- d[1L] n <- d[2L] P1. <- new("pMatrix") P1.@Dim <- c(m, m) P1.@Dimnames <- c(dn[1L], list(NULL)) P1.@perm <- invertPerm(asPerm(x@perm, n = m)) if(m <= n) { L <- new("dtrMatrix") L@Dim <- c(m, m) L@uplo <- "L" L@diag <- "U" } else { L <- new("dgeMatrix") L@Dim <- d } L@x <- .mkL(x@x, m, n) if (m >= n) { U <- new("dtrMatrix") U@Dim <- c(n, n) } else { U <- new("dgeMatrix") U@Dim <- d } U@Dimnames <- c(list(NULL), dn[2L]) U@x <- .mkU(x@x, m, n) list(P1. = P1., L = L, U = U) }) ## returning list(L, U, P), where A = P L U ## MJ: for backwards compatibility setMethod("expand", signature(x = "denseLU"), function(x, ...) { r <- expand2(x)[c(2L, 3L, 1L)] names(r) <- c("L", "U", "P") NN <- list(NULL, NULL) for(i in 1:3) r[[i]]@Dimnames <- NN r }) ## METHODS FOR CLASS: sparseLU ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("expand1", signature(x = "sparseLU"), function(x, which, ...) { switch(which, "P1" =, "P1." = { r <- new("pMatrix") r@Dim <- x@Dim r@perm <- x@p + 1L if(which == "P1.") r@margin <- 2L r }, "P2" =, "P2." = { r <- new("pMatrix") r@Dim <- d <- x@Dim r@perm <- if(length(x@q)) x@q + 1L else seq_len(d[1L]) if(which == "P2") r@margin <- 2L r }, "L" = x@L, "U" = x@U, stop(gettextf("'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%2$s2\", \"%2$s2.\", \"%3$s\", or \"%4$s\"", "which", "P", "L", "U"), domain = NA)) }) ## returning list(P1', L, U, P2'), where A = P1' L U P2' setMethod("expand2", signature(x = "sparseLU"), function(x, ...) { d <- x@Dim dn <- x@Dimnames p1 <- x@p p2 <- x@q P1. <- new("pMatrix") P1.@Dim <- d P1.@Dimnames <- c(dn[1L], list(NULL)) P1.@perm <- invertPerm(p1, 0L, 1L) P2. <- new("pMatrix") P2.@Dim <- d P2.@Dimnames <- c(list(NULL), dn[2L]) P2.@margin <- 2L P2.@perm <- if(length(p2)) invertPerm(p2, 0L, 1L) else seq_len(d[1L]) list(P1. = P1., L = x@L, U = x@U, P2. = P2.) }) ## returning list(P, L, U, Q), where A = P' L U Q ## MJ: for backwards compatibility setMethod("expand", signature(x = "sparseLU"), function(x, ...) { d <- x@Dim dn <- x@Dimnames p <- x@p + 1L q <- x@q + 1L if(length(p) && !is.null(rn <- dn[[1L]])) dn[[1L]] <- rn[p] if(length(q) && !is.null(cn <- dn[[2L]])) dn[[2L]] <- cn[q] P <- new("pMatrix") P@Dim <- d P@perm <- p Q <- new("pMatrix") Q@Dim <- d Q@perm <- if(length(q)) q else seq_len(d[1L]) L <- x@L L@Dimnames <- c(dn[1L], list(NULL)) U <- x@U U@Dimnames <- c(list(NULL), dn[2L]) list(P = P, L = L, U = U, Q = Q) }) Matrix/R/dim.R0000644000176200001440000001445414534140574012632 0ustar liggesusersvalidDim <- function(dim) .Call(R_Dim_validate, dim) validDimGetsValue <- function(value, mn) { if(mode(value) != "numeric") gettextf("assigned dimensions are not of type \"%s\" or \"%s\"", "integer", "double") else if(length(value) != 2L) gettextf("assigned dimensions do not have length %d", 2L) else if(anyNA(value)) gettext("assigned dimensions are NA") else if(any(value < 0L)) gettext("assigned dimensions are negative") else if(is.double(value) && any(trunc(value) > .Machine$integer.max)) gettextf("assigned dimensions exceed %s", "2^31-1") else if((p <- prod(value)) != mn) gettextf("assigned dimensions [product %.0f] do not match object length [%.0f]", p, as.double(mn)) else TRUE } validDN <- function(dn, dim) .Call(R_DimNames_validate, dn, dim) fixupDN <- function(dn) .Call(R_DimNames_fixup, dn) fixupDN.if.valid <- function(dn, dim) { if(is.character(s <- validDim(dim)) || is.character(s <- validDN(dn, dim))) stop(s, domain = NA) fixupDN(dn) } symDN <- function(dn) .Call(R_symDN, dn) symmetrizeDN <- function(x) { if(isS4(x)) # assuming is(x, "Matrix") `dimnames<-`(x, symDN(x@Dimnames)) else if(!is.null(dn <- dimnames(x))) # assuming list of length 2 `dimnames<-`(x, symDN(dn)) else x } isSymmetricDN <- function(dn) .Call(R_DimNames_is_symmetric, dn) is.null.DN <- function(dn) { if(is.null(dn)) return(TRUE) if(!is.null(names(dn))) names(dn) <- NULL ch0 <- character(0L) identical(dn, list(NULL, NULL)) || identical(dn, list( ch0, NULL)) || identical(dn, list(NULL, ch0)) || identical(dn, list( ch0, ch0)) } ## METHODS FOR GENERIC: dim ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("dim", signature(x = "Matrix"), function(x) x@Dim) setMethod("dim", signature(x = "MatrixFactorization"), function(x) x@Dim) ## METHODS FOR GENERIC: dim<- ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("dim<-", signature(x = "denseMatrix"), function(x, value) { if(is.character(s <- validDimGetsValue(value, prod(d <- x@Dim)))) stop(s, domain = NA) value <- as.integer(value) if(all(value == d)) return(x) r <- .M2gen(x) r@Dim <- value if(length(r@factors)) r@factors <- list() r }) setMethod("dim<-", signature(x = "sparseMatrix"), function(x, value) { if(is.character(s <- validDimGetsValue(value, prod(d <- x@Dim)))) stop(s, domain = NA) value <- as.integer(value) if(all(value == d)) return(x) r <- spV2M(.M2V(x), nrow = value[1L], ncol = value[2L]) switch(.M.repr(x), "C" = .M2C(r), "R" = .M2R(r), r) }) setMethod("dim<-", signature(x = "sparseVector"), function(x, value) { if(is.character(s <- validDimGetsValue(value, length(x)))) stop(s, domain = NA) value <- as.integer(value) spV2M(x, nrow = value[1L], ncol = value[2L]) }) ## METHODS FOR GENERIC: length ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("length", "Matrix", function(x) if((r <- prod(x@Dim)) > .Machine$integer.max) r else as.integer(r)) setMethod("length", "MatrixFactorization", function(x) if((r <- prod(x@Dim)) > .Machine$integer.max) r else as.integer(r)) setMethod("length", "sparseVector", function(x) if(is.integer(r <- x@length)) r else if(r - 1 <= .Machine$integer.max) as.integer(r) else trunc(r)) ## METHODS FOR GENERIC: dimnames ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("dimnames", signature(x = "Matrix"), function(x) x@Dimnames) setMethod("dimnames", signature(x = "symmetricMatrix"), function(x) symDN(x@Dimnames)) setMethod("dimnames", signature(x = "MatrixFactorization"), function(x) x@Dimnames) ## METHODS FOR GENERIC: dimnames<- ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("dimnames<-", signature(x = "Matrix", value = "NULL"), function(x, value) { x@Dimnames <- list(NULL, NULL) x }) setMethod("dimnames<-", signature(x = "compMatrix", value = "NULL"), function(x, value) { if(length(x@factors)) x@factors <- list() x@Dimnames <- list(NULL, NULL) x }) setMethod("dimnames<-", signature(x = "MatrixFactorization", value = "NULL"), function(x, value) { x@Dimnames <- list(NULL, NULL) x }) setMethod("dimnames<-", signature(x = "Matrix", value = "list"), function(x, value) { x@Dimnames <- fixupDN.if.valid(value, x@Dim) x }) setMethod("dimnames<-", signature(x = "compMatrix", value = "list"), function(x, value) { if(length(x@factors)) x@factors <- list() x@Dimnames <- fixupDN.if.valid(value, x@Dim) x }) setMethod("dimnames<-", signature(x = "MatrixFactorization", value = "list"), function(x, value) { x@Dimnames <- fixupDN.if.valid(value, x@Dim) x }) ## METHODS FOR GENERIC: unname ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("unname", signature(obj = "Matrix"), function(obj, force = FALSE) { obj@Dimnames <- list(NULL, NULL) obj }) setMethod("unname", signature(obj = "MatrixFactorization"), function(obj, force = FALSE) { obj@Dimnames <- list(NULL, NULL) obj }) ## METHODS FOR GENERIC: drop ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("drop", signature(x = "Matrix"), function(x) if(any(x@Dim == 1L)) drop(.M2m(x)) else x) Matrix/R/KhatriRao.R0000644000176200001440000000541414461537243013743 0ustar liggesusers# Efficient Khatri-Rao product for large sparse matrices # Assumes two matrices in CsparseMatrix format # Written by Michael Cysouw ## MM: there's a "public" Matlab version, at ## http://www.mathworks.com/matlabcentral/fileexchange/28872-khatri-rao-product/content/kr.m ## with documentation ## ## % Khatri-Rao product. ## ## % kr(A,B) returns the Khatri-Rao product of two matrices A and B, of ## % dimensions I-by-K and J-by-K respectively. The result is an I*J-by-K ## % matrix formed by the matching columnwise Kronecker products, i.e. ## % the k-th column of the Khatri-Rao product is defined as ## % kron(A(:,k),B(:,k)). KhatriRao <- function(X, Y = X, FUN = "*", sparseY = TRUE, make.dimnames = FALSE) { stopifnot((p <- ncol(X)) == ncol(Y)) ## TODO? speedup when X = Diagonal() X <- asCspN(X) # not-U-diag CsparseMatrix --> can use @x, @p, @i ## xn, yn; number of non-zero values per column xn <- diff(X@p) n1 <- nrow(X); n2 <- nrow(Y) if(sparseY) { Y <- asCspN(Y) yn <- diff(yp <- Y@p) ## both of length p } else { if(!is.matrix(Y)) Y <- as.matrix(Y)# needed e.g. in c(Y) below) yn <- rep(n2, p) } newp <- as.integer(diffinv(xn*yn)) ## indices for new values ## dense: = newp <- as.integer(diffinv(xn*nrow(Y))) xn.yp <- xn[ as.logical(yn) ] # xn "where" Y is present yj <- if(sparseY) .Call(Matrix_expand_pointers, yp)## as(Y,"TsparseMatrix")@j else rep(seq(p)-1L, each = n2) yj <- factor(yj) # for split() below non0 <- length(xn.yp) > 0L && any(xn.yp != 0L) rep.yn <- rep.int(yn, xn) i1 <- rep.int(X@i, rep.yn) i2 <- if(non0) { if(sparseY) unlist(rep(split.default(Y@i,yj), xn.yp), use.names=FALSE) else rep.int(seq.int(n2)-1L, p) } else integer() newi <- i1*n2 + i2 dim <- as.integer(c(n1*n2, p)) dns <- if (make.dimnames) { ## this is not good enough: dnx, dny may be NULL list(as.vector(outer(rownames(Y),rownames(X), FUN = "paste", sep = ":")), colnames(X)) } else list(NULL,NULL) if((nX <- is(X, "nMatrix")) & (nY <- is(Y, "nMatrix"))) new("ngCMatrix", Dim=dim, Dimnames=dns, i = newi, p = newp) else { ## at least one of 'X' and 'Y' has an "x" slot: if(nX) X <- .M2gen(.M2kind(X, "l")) x1 <- rep.int(X@x, rep.yn) x2 <- if(non0) { if(nY && sparseY) Y <- .M2gen(.M2kind(X, "l")) yx <- if(sparseY) Y@x else c(Y) unlist(rep(split.default(yx, yj), xn.yp), use.names=FALSE) } else if(nY) logical() else (if(sparseY) Y@x else c(Y))[0] if(!is.double(x1)) x1 <- as.double(x1) ## or if we had "igCMatrix" ... new("dgCMatrix", Dim=dim, Dimnames=dns, i = newi, p = newp, x = match.fun(FUN) (x1,x2)) } } Matrix/R/Summary.R0000644000176200001440000001466314507217006013513 0ustar liggesusers## METHODS FOR GENERIC: Summary (group) ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## > getGroupMembers("Summary") ## [1] "max" "min" "range" "prod" "sum" "any" "all" ## NB: Summary depends on the existence, _not_ count, of zeros and ones. ## The only exception is 'sum' which ignores zeros and counts ones. setMethod("Summary", signature(x = "denseMatrix"), function(x, ..., na.rm = FALSE) { ## Avoid wrong overflow : if(.Generic == "sum") return(sum (.Call(R_dense_sum , x, na.rm), ..., na.rm = na.rm)) if(.Generic == "prod") return(prod(.Call(R_dense_prod, x, na.rm), ..., na.rm = na.rm)) cl <- .M.nonvirtual(x) kind <- substr(cl, 1L, 1L) shape <- substr(cl, 2L, 2L) repr <- substr(cl, 3L, 3L) zero <- switch(kind, "n" = , "l" = FALSE, "i" = 0L, "d" = 0, "z" = 0+0i) if(shape != "g") { if(repr != "p") x <- .M2packed(x) if(shape == "t" && x@diag != "N") diag(x) <- TRUE # copying, sadly } n <- x@Dim[2L] y <- x@x y1 <- if(kind != "n" || !anyNA(y)) y else y | is.na(y) y2 <- if(shape == "t" && n > 1L) zero get(.Generic, mode = "function")(y1, y2, ..., na.rm = na.rm) }) setMethod("Summary", signature(x = "sparseMatrix"), function(x, ..., na.rm = FALSE) { ## Avoid wrong overflow : if(.Generic == "sum") return(sum (.Call(R_sparse_sum , x, na.rm), ..., na.rm = na.rm)) if(.Generic == "prod") return(prod(.Call(R_sparse_prod, x, na.rm), ..., na.rm = na.rm)) cl <- .M.nonvirtual(x) kind <- substr(cl, 1L, 1L) shape <- substr(cl, 2L, 2L) repr <- substr(cl, 3L, 3L) switch(kind, "n" = , "l" = { zero <- FALSE; one <- TRUE }, "i" = { zero <- 0L ; one <- 1L }, "d" = { zero <- 0 ; one <- 1 }, "z" = { zero <- 0+0i ; one <- 1+0i }) ## Handle overallocation (hopefully rare ...) : if(repr == "T") { x <- aggregateT(x) nnz <- length(x@i) } else { nnz <- { p <- x@p; p[length(p)] } if(length(if(repr == "C") x@i else x@j) > nnz) { h <- seq_len(nnz) if(repr == "C") x@i <- x@i[h] else x@j <- x@j[h] if(kind != "n") x@x <- x@x[h] } } n <- (d <- x@Dim)[2L] nnz.max <- if(shape == "s") 0.5 * (prod(d) + n) else prod(d) y1 <- if(kind != "n") x@x else if(nnz > 0L) TRUE else logical(0L) y2 <- if(nnz < nnz.max) zero y3 <- if(n > 0L && shape == "t" && x@diag != "N") one get(.Generic, mode = "function")(y1, y2, y3, ..., na.rm = na.rm) }) setMethod("Summary", signature(x = "diagonalMatrix"), function(x, ..., na.rm = FALSE) { kind <- .M.kind(x) switch(kind, "n" = , "l" = { zero <- FALSE; one <- TRUE }, "i" = { zero <- 0L ; one <- 1L }, "d" = { zero <- 0 ; one <- 1 }, "z" = { zero <- 0+0i ; one <- 1+0i }) n <- x@Dim[2L] y1 <- if(x@diag == "N") { y <- x@x if(kind != "n") { if(.Generic == "prod" && n > 1L) ## Avoid wrong overflow : c(y[1L], zero, y[-1L]) else y } else if(!anyNA(y)) y else y | is.na(y) } y2 <- if(n > 1L) zero y3 <- if(x@diag != "N") { if(.Generic == "sum") one * n else if(n > 0L) one else one[0L] } get(.Generic, mode = "function")(y1, y2, y3, ..., na.rm = na.rm) }) setMethod("Summary", signature(x = "indMatrix"), function(x, ..., na.rm = FALSE) { nnz <- length(x@perm) y1 <- if(.Generic == "sum") nnz else if(nnz > 0L) TRUE else logical(0L) y2 <- if(nnz < prod(x@Dim)) FALSE get(.Generic, mode = "function")(y1, y2, ..., na.rm = na.rm) }) setMethod("Summary", signature(x = "sparseVector"), function(x, ..., na.rm = FALSE) { kind <- .M.kind(x) zero <- switch(kind, "n" = , "l" = FALSE, "i" = 0L, "d" = 0, "z" = 0+0i) nnz <- length(i <- x@i) nnz.max <- length(x) y1 <- if(kind != "n") { y <- x@x if(.Generic == "prod" && nnz > 0L && nnz < nnz.max) { ## Avoid wrong overflow : if(i[1L] > 1L) c(zero, y) else if(nnz >= (q <- which.min(i == seq_along(i)))) c(y[1L:(q - 1L)], zero, y[q:nnz]) else y } else y } else if(.Generic == "sum") nnz else if(nnz > 0L) TRUE else logical(0L) y2 <- if(nnz < nnz.max) zero get(.Generic, mode = "function")(y1, y2, ..., na.rm = na.rm) }) Matrix/R/eigen.R0000644000176200001440000001232614503364553013145 0ustar liggesusers## METHODS FOR GENERIC: Schur ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("Schur", signature(x = "dgeMatrix"), function(x, vectors = TRUE, ...) { if(length(x.x <- x@x) && !all(is.finite(range(x.x)))) stop(gettextf("'%s' has non-finite values", "x"), domain = NA) cl <- .Call(dgeMatrix_Schur, x, vectors, TRUE) if(all(cl$WI == 0)) { vals <- cl$WR T <- triu(cl$T) } else { vals <- complex(real = cl$WR, imaginary = cl$WI) T <- .m2dense(cl$T, ",ge") } if(vectors) new("Schur", Dim = x@Dim, Dimnames = x@Dimnames, Q = .m2dense(cl$Z, ",ge"), T = T, EValues = vals) else list(T = T, EValues = vals) }) setMethod("Schur", signature(x = "dsyMatrix"), function(x, vectors = TRUE, ...) { e <- eigen(x, symmetric = TRUE, only.values = !vectors) vals <- as.double(e$values) T <- new("ddiMatrix", Dim = x@Dim, x = vals) if(vectors) new("Schur", Dim = x@Dim, Dimnames = symDN(x@Dimnames), Q = .m2dense(e$vectors, ",ge"), T = T, EValues = vals) else list(T = T, EValues = vals) }) setMethod("Schur", signature(x = "matrix"), function(x, vectors = TRUE, ...) { ## FIXME: wrong for complex, but package 'control' seems to ## rely on the complex->double coercion (!?) storage.mode(x) <- "double" if(length(x) && !all(is.finite(range(x)))) stop(gettextf("'%s' has non-finite values", "x"), domain = NA) cl <- .Call(dgeMatrix_Schur, x, vectors, FALSE) vals <- if(all(cl$WI == 0)) cl$WR else complex(real = cl$WR, imaginary = cl$WI) if(vectors) list(Q = cl$Z, T = cl$T, EValues = vals) else list(T = cl$T, EValues = vals) }) ## FIXME: don't coerce from sparse to dense setMethod("Schur", signature(x = "generalMatrix"), function(x, vectors = TRUE, ...) Schur(.M2unpacked(.M2kind(x, ",")), vectors, ...)) ## FIXME: don't coerce from sparse to dense setMethod("Schur", signature(x = "symmetricMatrix"), function(x, vectors = TRUE, ...) Schur(.M2unpacked(.M2kind(x, ",")), vectors, ...)) setMethod("Schur", signature(x = "triangularMatrix"), function(x, vectors = TRUE, ...) { x <- .M2kind(x, ",") n <- (d <- x@Dim)[1L] if(n == 0L) x@uplo <- "U" else if(.M.kind(x) != "n" && !all(is.finite(range(x)))) stop(gettextf("'%s' has non-finite values", "x"), domain = NA) vals <- diag(x, names = FALSE) if(x@uplo == "U") { if(vectors) { Q <- new("ddiMatrix", Dim = d, diag = "U") new("Schur", Dim = d, Dimnames = x@Dimnames, Q = Q, T = x, EValues = vals) } else list(T = x, EValues = vals) } else { perm <- n:1L vals <- vals[perm] T <- triu(x[perm, perm, drop = FALSE]) if(vectors) { Q <- new("pMatrix", Dim = d, perm = perm) new("Schur", Dim = d, Dimnames = x@Dimnames, Q = Q, T = T, EValues = vals) } else list(T = x, EValues = vals) } }) setMethod("Schur", signature(x = "diagonalMatrix"), function(x, vectors = TRUE, ...) { x <- .M2kind(x, ",") d <- x@Dim if(x@diag != "N") { vals <- rep.int(1, d[1L]) T <- new("ddiMatrix", Dim = d, diag = "U") } else { vals <- x@x if(length(vals) && !all(is.finite(range(vals)))) stop(gettextf("'%s' has non-finite values", "x"), domain = NA) T <- new("ddiMatrix", Dim = d, x = vals) } if(vectors) { Q <- new("ddiMatrix", Dim = d, diag = "U") new("Schur", Dim = d, Dimnames = x@Dimnames, Q = Q, T = T, EValues = vals) } else list(T = T, EValues = vals) }) ## METHODS FOR CLASS: Schur ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("expand1", signature(x = "Schur"), function(x, which, ...) switch(which, "Q" = x@Q, "T" = x@T, "Q." = t(x@Q), stop(gettextf("'%1$s' is not \"%2$s\", \"%3$s\", or \"%2$s.\"", "which", "Q", "T"), domain = NA))) setMethod("expand2", signature(x = "Schur"), function(x, ...) { Q <- x@Q Q. <- t(Q) dn <- x@Dimnames Q @Dimnames <- c(dn[1L], list(NULL)) Q.@Dimnames <- c(list(NULL), dn[2L]) list(Q = Q, T = x@T, Q. = Q.) }) Matrix/R/denseMatrix.R0000644000176200001440000001764114513276125014344 0ustar liggesusers## METHODS FOR CLASS: denseMatrix (virtual) ## dense matrices with unpacked _or_ packed storage ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .dense.band <- function(x, k1, k2, ...) .Call(R_dense_band, x, k1, k2) .dense.triu <- function(x, k = 0L, ...) .Call(R_dense_band, x, k, NULL) .dense.tril <- function(x, k = 0L, ...) .Call(R_dense_band, x, NULL, k) .dense.diag.get <- function(x, nrow, ncol, names = TRUE) .Call(R_dense_diag_get, x, names) .dense.diag.set <- function(x, value) .Call(R_dense_diag_set, x, value) .dense.t <- function(x) .Call(R_dense_transpose, x) .dense.fS1 <- function(x, uplo) .Call(R_dense_force_symmetric, x, NULL) .dense.fS2 <- function(x, uplo) .Call(R_dense_force_symmetric, x, uplo) .dense.symmpart <- function(x) .Call(R_dense_symmpart, x) .dense.skewpart <- function(x) .Call(R_dense_skewpart, x) .dense.is.di <- function(object) .Call(R_dense_is_diagonal, object) .dense.is.tr <- function(object, upper = NA, ...) .Call(R_dense_is_triangular, object, upper) .dense.is.sy <- function(object, checkDN = TRUE, ...) { if(checkDN) { ca <- function(check.attributes = TRUE, ...) check.attributes checkDN <- ca(...) } .Call(R_dense_is_symmetric, object, checkDN) } .dense.is.sy.dz <- function(object, checkDN = TRUE, tol = 100 * .Machine$double.eps, tol1 = 8 * tol, ...) { ## backwards compatibility: don't check DN if check.attributes=FALSE if(checkDN) { ca <- function(check.attributes = TRUE, ...) check.attributes checkDN <- ca(...) } ## be very fast when requiring exact symmetry if(tol <= 0) return(.Call(R_dense_is_symmetric, object, checkDN)) ## pretest: is it square? d <- object@Dim if((n <- d[2L]) != d[1L]) return(FALSE) ## pretest: are DN symmetric in the sense of validObject()? if(checkDN && !isSymmetricDN(object@Dimnames)) return(FALSE) if(n == 0L) return(TRUE) object <- .M2gen(object) ## now handling n-by-n [dz]geMatrix, n >= 1: Cj <- if(is.complex(object@x)) Conj else identity ae <- function(check.attributes, ...) { ## discarding possible user-supplied check.attributes all.equal.numeric(..., check.attributes = FALSE) } ## pretest: outermost rows ~= outermost columns? ## (fast for large asymmetric) if(length(tol1)) { i. <- if(n <= 4L) 1L:n else c(1L, 2L, n - 1L, n) for(i in i.) if(!isTRUE(ae(target = object[i, ], current = Cj(object[, i]), tolerance = tol1, ...))) return(FALSE) } isTRUE(ae(target = object @x, current = Cj(t(object))@x, tolerance = tol, ...)) } setMethod("diff", signature(x = "denseMatrix"), ## Mostly cut and paste of base::diff.default : function(x, lag = 1L, differences = 1L, ...) { if(length(lag) != 1L || length(differences) != 1L || lag < 1L || differences < 1L) stop(gettextf("'%s' and '%s' must be positive integers", "lag", "differences"), domain = NA) if(lag * differences >= x@Dim[1L]) return(x[0L]) i1 <- -seq_len(lag) for(i in seq_len(differences)) { m <- x@Dim[1L] x <- x[i1, , drop = FALSE] - x[-m:-(m - lag + 1L), , drop = FALSE] } x }) setMethod("mean", signature(x = "denseMatrix"), function(x, ...) mean.default(.M2v(x), ...)) setMethod("rep", signature(x = "denseMatrix"), function(x, ...) rep(.M2v(x), ...)) setMethod("band" , signature(x = "denseMatrix"), .dense.band) setMethod("triu" , signature(x = "denseMatrix"), .dense.triu) setMethod("tril" , signature(x = "denseMatrix"), .dense.tril) setMethod("diag" , signature(x = "denseMatrix"), .dense.diag.get) setMethod("diag<-", signature(x = "denseMatrix"), .dense.diag.set) setMethod("t" , signature(x = "denseMatrix"), .dense.t) setMethod("forceSymmetric", signature(x = "denseMatrix", uplo = "missing"), .dense.fS1) setMethod("forceSymmetric", signature(x = "denseMatrix", uplo = "character"), .dense.fS2) setMethod("symmpart", signature(x = "denseMatrix"), .dense.symmpart) setMethod("skewpart", signature(x = "denseMatrix"), .dense.skewpart) setMethod("isSymmetric" , signature(object = "denseMatrix"), .dense.is.sy) setMethod("isTriangular", signature(object = "denseMatrix"), .dense.is.tr) setMethod("isDiagonal" , signature(object = "denseMatrix"), .dense.is.di) .dense.subclasses <- names(getClassDef("denseMatrix")@subclasses) for (.cl in grep("^[dz](ge|tr|tp)Matrix$", .dense.subclasses, value = TRUE)) setMethod("isSymmetric" , signature(object = .cl), .dense.is.sy.dz) rm(.cl, .dense.subclasses) ## METHODS FOR CLASS: unpackedMatrix (virtual) ## dense matrices with unpacked storage ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("unpack", signature(x = "packedMatrix"), function(x, ...) .Call(R_dense_as_unpacked, x)) setMethod("pack", signature(x = "packedMatrix"), function(x, ...) x) ## METHODS FOR CLASS: packedMatrix (virtual) ## dense matrices with packed storage ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .uM.pack <- function(x, ...) .Call(R_dense_as_packed, x, NULL, NULL) .uM.pack.ge <- function(x, symmetric = NA, upperTri = NA, ...) { if(((sna <- is.na(symmetric)) || symmetric) && isSymmetric(x, ...)) .Call(R_dense_as_packed, x, "U", NULL) else if((sna || !symmetric) && (it <- isTriangular(x, upper = upperTri))) { uplo <- if(is.na(upperTri)) attr(it, "kind") else if(upperTri) "U" else "L" .Call(R_dense_as_packed, x, uplo, "N") } else { if(sna) stop("matrix is not symmetric or triangular") else if(symmetric) stop("matrix is not symmetric") else stop("matrix is not triangular") } } setMethod("unpack", signature(x = "unpackedMatrix"), function(x, ...) x) setMethod("pack", signature(x = "unpackedMatrix"), .uM.pack) .uM.subclasses <- names(getClassDef("unpackedMatrix")@subclasses) for(.cl in grep("^.geMatrix$", .uM.subclasses, value = TRUE)) setMethod("pack", signature(x = .cl), .uM.pack.ge) rm(.cl, .uM.subclasses) ## METHODS FOR CLASS: matrix ## traditional matrices, which really are "dense" ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .m.pack <- .uM.pack.ge body(.m.pack)[[2L]][[3L]] <- quote(.m2dense(x, ".sp", "U")) body(.m.pack)[[2L]][[4L]][[3L]][[3L]] <- quote(.m2dense(x, ".tp", uplo)) setMethod("unpack", signature(x = "matrix"), function(x, ...) .m2dense.checking(x, ".")) setMethod("pack", signature(x = "matrix"), .m.pack) setMethod("band", signature(x = "matrix"), .dense.band) setMethod("triu", signature(x = "matrix"), .dense.triu) setMethod("tril", signature(x = "matrix"), .dense.tril) setMethod("forceSymmetric", signature(x = "matrix", uplo = "missing"), function(x, uplo) .m2dense(x, ".sy", "U")) setMethod("forceSymmetric", signature(x = "matrix", uplo = "character"), function(x, uplo) .m2dense(x, ".sy", uplo)) setMethod("symmpart", signature(x = "matrix"), function(x) symmetrizeDN(0.5 * (x + t(x)))) setMethod("skewpart", signature(x = "matrix"), function(x) symmetrizeDN(0.5 * (x - t(x)))) setMethod("isTriangular", signature(object = "matrix"), .dense.is.tr) setMethod("isDiagonal" , signature(object = "matrix"), .dense.is.di) rm(.uM.pack, .uM.pack.ge, .m.pack, list = c(grep("^[.]dense[.](band|tri[ul]|diag[.](get|set)|t|fS[12]|symmpart|skewpart|is[.](sy|tr|di)([.]dz)?)$", ls(all.names = TRUE), value = TRUE))) Matrix/R/diagMatrix.R0000644000176200001440000001316214503364553014146 0ustar liggesusers## METHODS FOR CLASS: diagonalMatrix (virtual) ## diagonal matrices ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("band", signature(x = "diagonalMatrix"), function(x, k1, k2, ...) { if(k1 <= 0L && k2 >= 0L) return(x) r <- new(.M.nonvirtual(x)) r@Dim <- d <- x@Dim r@Dimnames <- x@Dimnames r@x <- vector(typeof(x@x), d[1L]) r }) setMethod("triu", signature(x = "diagonalMatrix"), function(x, k = 0L, ...) { if(k <= 0L) return(x) r <- new(.M.nonvirtual(x)) r@Dim <- d <- x@Dim r@Dimnames <- x@Dimnames r@x <- vector(typeof(x@x), d[1L]) r }) setMethod("tril", signature(x = "diagonalMatrix"), function(x, k = 0L, ...) { if(k >= 0L) return(x) r <- new(.M.nonvirtual(x)) r@Dim <- d <- x@Dim r@Dimnames <- x@Dimnames r@x <- vector(typeof(x@x), d[1L]) r }) setMethod("diag", signature(x = "diagonalMatrix"), function(x, nrow, ncol, names = TRUE) { kind <- .M.kind(x) r <- if(x@diag != "N") { one <- switch(kind, "n" = , "l" = TRUE, "i" = 1L, "d" = 1, "z" = 1+0i) rep.int(one, x@Dim[1L]) } else { y <- x@x if(kind == "n" && anyNA(y)) y | is.na(y) else y } if(names && !any(vapply(dn <- x@Dimnames, is.null, NA)) && { i <- seq_len(min(x@Dim)) identical(nms <- dn[[1L]][i], dn[[2L]][i]) }) names(r) <- nms r }) setMethod("diag<-", signature(x = "diagonalMatrix"), function(x, value) { n <- x@Dim[2L] nv <- length(value) if(nv != 1L && nv != n) stop("replacement diagonal has wrong length") x@x <- if(is.logical(x@x)) switch(typeof(value), logical = rep_len(value, n), integer =, double = { x <- .M2kind(x, "d") rep_len(as.double(x), n) }, stop(gettextf("replacement diagonal has incompatible type \"%s\"", typeof(value)), domain = NA)) else switch(typeof(value), logical =, integer =, double = rep_len(as.double(value), n), stop(gettextf("replacement diagonal has incompatible type \"%s\"", typeof(value)), domain = NA)) x@diag <- "N" x }) setMethod("t", signature(x = "diagonalMatrix"), function(x) { x@Dimnames <- x@Dimnames[2:1]; x }) setMethod("forceSymmetric", signature(x = "diagonalMatrix", uplo = "missing"), function(x, uplo) .diag2sparse(x, ".", "s", "C", "U")) setMethod("forceSymmetric", signature(x = "diagonalMatrix", uplo = "character"), function(x, uplo) .diag2sparse(x, ".", "s", "C", uplo)) setMethod("symmpart", signature(x = "diagonalMatrix"), function(x) { kind <- .M.kind(x) r <- new(if(kind == "z") "zdiMatrix" else "ddiMatrix") r@Dim <- x@Dim r@Dimnames <- symDN(x@Dimnames) if(x@diag != "N") r@diag <- "U" else { y <- x@x r@x <- switch(kind, "n" = as.double(y | is.na(y)), "l" = , "i" = , "d" = as.double(y), "z" = complex(real = Re(y), imaginary = 0)) } r }) setMethod("skewpart", signature(x = "diagonalMatrix"), function(x) { kind <- .M.kind(x) r <- new(if(kind == "z") "zdiMatrix" else "ddiMatrix") r@Dim <- d <- x@Dim r@Dimnames <- symDN(x@Dimnames) r@x <- if(kind == "z") { if(x@diag != "N") complex(d[1L]) else complex(real = 0, imaginary = Im(x@x)) } else double(d[1L]) r }) setMethod("isDiagonal", signature(object = "diagonalMatrix"), function(object) TRUE) setMethod("isTriangular", signature(object = "diagonalMatrix"), function(object, upper = NA, ...) if(is.na(upper)) `attr<-`(TRUE, "kind", "U") else TRUE) setMethod("isSymmetric", signature(object = "diagonalMatrix"), function(object, checkDN = TRUE, ...) { if(checkDN) { ca <- function(check.attributes = TRUE, ...) check.attributes if(ca(...) && !isSymmetricDN(object@Dimnames)) return(FALSE) } .M.kind(object) != "z" || object@diag != "N" || { x <- object@x; isTRUE(all.equal.numeric(x, Conj(x), ...)) } }) Matrix/R/BunchKaufman.R0000644000176200001440000001000114503364553014404 0ustar liggesusers## METHODS FOR GENERIC: BunchKaufman ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("BunchKaufman", signature(x = "dsyMatrix"), function(x, warnSing = TRUE, ...) .Call(dsyMatrix_trf, x, as.logical(warnSing))) setMethod("BunchKaufman", signature(x = "dspMatrix"), function(x, warnSing = TRUE, ...) .Call(dspMatrix_trf, x, as.logical(warnSing))) setMethod("BunchKaufman", signature(x = "matrix"), function(x, uplo = "U", ...) BunchKaufman(.m2dense(x, ",sy", uplo), ...)) ## METHODS FOR CLASS: p?BunchKaufman ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setAs("BunchKaufman", "dtrMatrix", function(from) { to <- new("dtrMatrix") to@Dim <- from@Dim to@uplo <- from@uplo to@x <- from@x to }) setAs("pBunchKaufman", "dtpMatrix", function(from) { to <- new("dtpMatrix") to@Dim <- from@Dim to@uplo <- from@uplo to@x <- from@x to }) .def.unpacked <- .def.packed <- function(x, which, ...) { r <- .Call(BunchKaufman_expand, x, .PACKED) b <- length(r) - 1L switch(which, "DU" =, "DL" = { if(!endsWith(which, x@uplo)) stop(gettextf("%s=\"%s\" invalid for %s@uplo=\"%s\"", "which", which, "x", x@uplo), domain = NA) r[[b + 1L]] }, "U" =, "U." =, "L" =, "L." = { if(!startsWith(which, x@uplo)) stop(gettextf("%s=\"%s\" invalid for %s@uplo=\"%s\"", "which", which, "x", x@uplo), domain = NA) if(b > 0L) { m <- r[[b]] if(b > 1L) for(i in (b - 1L):1L) m <- r[[i]] %*% m if(endsWith(which, ".")) t(m) else m } else { m <- new("ddiMatrix") m@Dim <- x@Dim m@diag <- "U" m } }, stop(gettextf("'%s' is not \"%1$s\", \"D%1$s\", or \"%1$s.\"", "which", x@uplo), domain = NA)) } body(.def.unpacked) <- do.call(substitute, list(body(.def.unpacked), list(.PACKED = FALSE))) body(.def.packed) <- do.call(substitute, list(body(.def.packed ), list(.PACKED = TRUE))) setMethod("expand1", signature(x = "BunchKaufman"), .def.unpacked) setMethod("expand1", signature(x = "pBunchKaufman"), .def.packed) rm(.def.unpacked, .def.packed) .def.unpacked <- .def.packed <- function(x, complete = FALSE, ...) { r <- .Call(BunchKaufman_expand, x, .PACKED) b <- length(r) - 1L if(complete) { if(b > 0L) r <- c(r, lapply(r[b:1L], t)) } else { if(b > 0L) { m <- r[[b]] if(b > 1L) for(i in (b - 1L):1L) m <- r[[i]] %*% m r <- list(m, r[[b + 1L]], t(m)) } else { m <- new("ddiMatrix") m@Dim <- x@Dim m@diag <- "U" r <- list(m, r[[1L]], m) } names(r) <- if(x@uplo == "U") c("U", "DU", "U.") else c("L", "DL", "L.") } dn <- x@Dimnames if(length(r) == 1L) r[[1L]]@Dimnames <- dn else { r[[1L]]@Dimnames <- c(dn[1L], list(NULL)) r[[length(r)]]@Dimnames <- c(list(NULL), dn[2L]) } r } body(.def.unpacked) <- do.call(substitute, list(body(.def.unpacked), list(.PACKED = FALSE))) body(.def.packed) <- do.call(substitute, list(body(.def.packed ), list(.PACKED = TRUE))) ## returning ## list(U, DU, U') where A = U DU U' and U = P[b] U[b] ... P[1] U[1] ## OR ## list(L, DL, L') where A = L DL L' and L = P[1] L[1] ... P[b] L[b] setMethod("expand2", signature(x = "BunchKaufman"), .def.unpacked) setMethod("expand2", signature(x = "pBunchKaufman"), .def.packed) rm(.def.unpacked, .def.packed) Matrix/R/coerce.R0000644000176200001440000005055414534140574013322 0ustar liggesusers## METHODS FOR GENERIC: coerce, as.* ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .M2kind <- function(from, kind = ".", sparse = NA) .Call(R_Matrix_as_kind, from, kind, sparse) .M2gen <- function(from, kind = ".") .Call(R_Matrix_as_general, from, kind) ..M2gen <- function(from) # for setAs() .Call(R_Matrix_as_general, from, ".") .M2sym <- function(from, ...) { if(isSymmetric(from, ...)) forceSymmetric(from) else stop("matrix is not symmetric; consider forceSymmetric(.) or symmpart(.)") } ..M2sym <- .M2sym # for setAs() formals(..M2sym) <- formals(..M2sym)[-2L] body(..M2sym)[[2L]][[2L]] <- body(..M2sym)[[2L]][[2L]][-3L] .M2tri <- function(from, ...) { if(!(it <- isTriangular(from, ...))) stop("matrix is not triangular; consider triu(.) or tril(.)") else if(attr(it, "kind") == "U") triu(from) else tril(from) } ..M2tri <- .M2tri # for setAs() formals(..M2tri) <- formals(..M2tri)[-2L] body(..M2tri)[[2L]][[2L]][[2L]][[2L]][[3L]] <- body(..M2tri)[[2L]][[2L]][[2L]][[2L]][[3L]][-3L] .M2diag <- function(from) { if (!isDiagonal(from)) stop("matrix is not diagonal; consider Diagonal(x=diag(.))") forceDiagonal(from) } .M2v <- function(from) .Call(R_Matrix_as_vector, from) .M2m <- function(from) .Call(R_Matrix_as_matrix, from) .M2unpacked <- function(from) .Call(R_Matrix_as_unpacked, from) .M2packed <- function(from) .Call(R_Matrix_as_packed, from) .M2C <- function(from) .Call(R_Matrix_as_Csparse, from) .M2R <- function(from) .Call(R_Matrix_as_Rsparse, from) .M2T <- function(from) .Call(R_Matrix_as_Tsparse, from) .sparse2dense <- function(from, packed = FALSE) .Call(R_sparse_as_dense, from, packed) .diag2dense <- function(from, kind = ".", shape = "t", packed = FALSE, uplo = "U") .Call(R_diagonal_as_dense, from, kind, shape, packed, uplo) .ind2dense <- function(from, kind = "n") .Call(R_index_as_dense, from, kind) .dense2sparse <- function(from, repr = "C") .Call(R_dense_as_sparse, from, repr) .diag2sparse <- function(from, kind = ".", shape = "t", repr = "C", uplo = "U") .Call(R_diagonal_as_sparse, from, kind, shape, repr, uplo) .ind2sparse <- function(from, kind = "n", repr = ".") .Call(R_index_as_sparse, from, kind, repr) .m2dense <- function(from, class = ".ge", uplo = "U", diag = "N", trans = FALSE) .Call(R_matrix_as_dense, from, class, uplo, diag, trans) .m2dense.checking <- function(from, kind = ".", ...) { switch(typeof(from), logical =, integer =, double = NULL, stop(gettextf("invalid type \"%s\" in '%s'", typeof(from), ".m2dense.checking"), domain = NA)) if(kind != ".") { ## These must happen before isSymmetric() call storage.mode(from) <- switch(kind, n =, l = "logical", d = "double", stop(gettextf("invalid %s=\"%s\" to '%s'", "kind", kind, ".m2dense.checking"), domain = NA)) if(kind == "n" && anyNA(from)) from[is.na(from)] <- TRUE } if(isSymmetric(from, ...)) .m2dense(from, paste0(kind, "sy"), "U", NULL) else if(it <- isTriangular(from)) .m2dense(from, paste0(kind, "tr"), attr(it, "kind"), "N") else .m2dense(from, paste0(kind, "ge"), NULL, NULL) } .m2sparse <- function(from, class = ".gC", uplo = "U", diag = "N", trans = FALSE) .Call(R_matrix_as_sparse, from, class, uplo, diag, trans) .m2sparse.checking <- function(from, kind = ".", repr = "C", ...) { switch(typeof(from), logical =, integer =, double = NULL, stop(gettextf("invalid type \"%s\" in '%s'", typeof(from), ".m2sparse.checking"), domain = NA)) if(kind != ".") { ## These must happen before isSymmetric() call storage.mode(from) <- switch(kind, n =, l = "logical", d = "double", stop(gettextf("invalid %s=\"%s\" to '%s'", "kind", kind, ".m2sparse.checking"), domain = NA)) if(kind == "n" && anyNA(from)) from[is.na(from)] <- TRUE } if(isSymmetric(from, ...)) .m2sparse(from, paste0(kind, "s", repr), "U", NULL) else if(it <- isTriangular(from)) .m2sparse(from, paste0(kind, "t", repr), attr(it, "kind"), "N") else .m2sparse(from, paste0(kind, "g", repr), NULL, NULL) } .V2kind <- function(from, kind = ".") { if(kind == ".") return(from) kind. <- .M.kind(from) if(kind == ",") kind <- if(kind. == "z") "z" else "d" if(kind == kind.) return(from) to <- new(paste0(kind, "sparseVector")) to@length <- from@length to@i <- from@i if(kind != "n") to@x <- if(kind. == "n") rep.int(switch(kind, "l" = TRUE, "i" = 1L, "d" = 1, "z" = 1+0i), length(from@i)) else as.vector(from@x, typeof(to@x)) to } .V2v <- function(from) { if(.M.kind(from) != "n") { to <- vector(typeof(from@x), from@length) to[from@i] <- from@x } else { to <- logical(from@length) to[from@i] <- TRUE } to } .V2m <- function(from) { if(is.double(m <- length(from))) stop(gettextf("dimensions cannot exceed %s", "2^31-1"), domain = NA) to <- .V2v(from) dim(to) <- c(m, 1L) to } .V2a <- function(from) { if(is.double(m <- length(from))) stop(gettextf("dimensions cannot exceed %s", "2^31-1"), domain = NA) to <- .V2v(from) dim(to) <- m to } .V2unpacked <- function(from) { if(is.double(m <- length(from))) stop(gettextf("dimensions cannot exceed %s", "2^31-1"), domain = NA) kind <- .M.kind(from) to <- new(paste0(if(kind == "i") "d" else kind, "geMatrix")) to@Dim <- c(m, 1L) to@x <- replace(vector(typeof(to@x), m), from@i, if(kind == "n") TRUE else from@x) to } .V2C <- function(from) { if(is.double(m <- length(from))) stop(gettextf("dimensions cannot exceed %s", "2^31-1"), domain = NA) kind <- .M.kind(from) to <- new(paste0(if(kind == "i") "d" else kind, "gCMatrix")) to@Dim <- c(m, 1L) to@p <- c(0L, length(from@i)) to@i <- as.integer(from@i) - 1L if(kind != "n") to@x <- if(kind == "i") as.double(from@x) else from@x to } .V2R <- function(from) { if(is.double(m <- length(from))) stop(gettextf("dimensions cannot exceed %s", "2^31-1"), domain = NA) kind <- .M.kind(from) to <- new(paste0(if(kind == "i") "d" else kind, "gRMatrix")) to@Dim <- c(m, 1L) to@p <- c(0L, cumsum(replace(logical(m), from@i, TRUE))) to@j <- integer(length(from@i)) if(kind != "n") to@x <- if(kind == "i") as.double(from@x) else from@x to } .V2T <- function(from) { if(is.double(m <- length(from))) stop(gettextf("dimensions cannot exceed %s", "2^31-1"), domain = NA) kind <- .M.kind(from) to <- new(paste0(if(kind == "i") "d" else kind, "gTMatrix")) to@Dim <- c(m, 1L) to@i <- as.integer(from@i) - 1L to@j <- integer(length(from@i)) if(kind != "n") to@x <- if(kind == "i") as.double(from@x) else from@x to } ## FIXME: define R_Matrix_as_sparseVector in ../src/coerce.c and use here .M2V <- function(from) { repr <- .M.repr(from) if(repr == "u" || repr == "p") return(.Call( v2spV, .M2v(from))) if(repr == "C" || repr == "R") return(.Call(CR2spV, from )) if(repr == "T") return(.Call(CR2spV, .M2C(from))) if(repr != "d" && repr != "i") { if(is.object(from)) stop(gettextf("invalid class \"%s\" in '%s'", class(from)[1L], ".M2V"), domain = NA) else stop(gettextf("invalid type \"%s\" in '%s'", typeof(from), ".M2V"), domain = NA) } d <- from@Dim m <- d[1L] n <- d[2L] mn <- prod(d) if(mn <= .Machine$integer.max) mn <- as.integer(mn) else if(mn > 0x1p+53) stop(gettextf("%s length cannot exceed %s", "sparseVector", "2^53"), domain = NA) kind <- .M.kind(from) to <- new(paste0(kind, "sparseVector")) to@length <- mn to@i <- if(repr == "d") { if(kind == "n" && from@diag == "N") indDiag(n)[from@x | is.na(from@x)] else indDiag(n) } else if(is.integer(mn)) { if(from@margin == 1L) seq.int(to = 0L, by = 1L, length.out = m) + from@perm * m else seq.int(from = 0L, by = m, length.out = n) + from@perm } else { if(from@margin == 1L) seq.int( to = 0, by = 1, length.out = m) + from@perm * as.double(m) else seq.int(from = 0, by = as.double(m), length.out = n) + as.double(from@perm) } if(kind != "n") to@x <- if(from@diag == "N") from@x else rep.int(switch(kind, "l" = TRUE, "i" = 1L, "d" = 1, "z" = 1+0i), n) to } .m2V <- function(from, kind = ".") { to <- .Call(v2spV, from) if(kind == ".") to else { to. <- new(paste0(kind, "sparseVector")) to.@length <- to@length to.@i <- to@i if(kind != "n") to.@x <- as.vector(to@x, typeof(to.@x)) to. } } ## ==== To vector ====================================================== ## Need 'base' functions calling as.*() to dispatch to our S4 methods: if (FALSE) { ## 2023-08-10: breaks iGraphMatch, mcmcsae, mcompanion ## which define proper subclasses of Matrix not extending ## any of _our_ proper subclasses of Matrix as.matrix.Matrix <- function(x, ...) .M2m(x) as.array.Matrix <- function(x, ...) .M2m(x) } else { as.matrix.Matrix <- function(x, ...) as(x, "matrix") as.array.Matrix <- function(x, ...) as(x, "matrix") setAs("Matrix", "matrix", .M2m) } as.matrix.sparseVector <- function(x, ...) .V2m(x) as.array.sparseVector <- function(x, ...) .V2a(x) setMethod("as.vector" , signature(x = "Matrix"), function(x, mode = "any") as.vector(.M2v(x), mode)) setMethod("as.matrix" , signature(x = "Matrix"), as.matrix.Matrix) setMethod("as.array" , signature(x = "Matrix"), as.array.Matrix) setMethod("as.logical", signature(x = "Matrix"), function(x, ...) as.logical(.M2v(x))) setMethod("as.integer", signature(x = "Matrix"), function(x, ...) as.integer(.M2v(x))) setMethod("as.numeric", signature(x = "Matrix"), function(x, ...) as.numeric(.M2v(x))) setMethod("as.complex", signature(x = "Matrix"), function(x, ...) as.complex(.M2v(x))) setMethod("as.vector" , signature(x = "sparseVector"), function(x, mode = "any") as.vector(.V2v(x), mode)) setMethod("as.matrix" , signature(x = "sparseVector"), as.matrix.sparseVector) setMethod("as.array" , signature(x = "sparseVector"), as.array.sparseVector) setMethod("as.logical", signature(x = "sparseVector"), function(x, ...) as.logical(.V2v(x))) setMethod("as.integer", signature(x = "sparseVector"), function(x, ...) as.integer(.V2v(x))) setMethod("as.numeric", signature(x = "sparseVector"), function(x, ...) as.numeric(.V2v(x))) setMethod("as.complex", signature(x = "sparseVector"), function(x, ...) as.complex(.V2v(x))) ## ==== To Matrix ====================================================== setAs("sparseVector", "Matrix", .V2C) setAs("matrix", "Matrix", function(from) { if(isDiagonal(from)) forceDiagonal(from) else if(.sparseDefault(from)) .m2sparse.checking(from, ".", "C") else .m2dense.checking(from, ".") }) setAs("vector", "Matrix", function(from) { if(is.object(from) && length(dim(from)) == 2L) # e.g., data.frame as(as.matrix(from), "Matrix") else if(.sparseDefault(from)) .m2sparse(from, ".gC") else .m2dense(from, ".ge") }) setAs( "ANY", "Matrix", function(from) as(as(from, "matrix"), "Matrix")) if(FALSE) { ## MJ: not yet ... existing as(, "Matrix") must become defunct first setAs("MatrixFactorization", "Matrix", function(from) { n <- length(x <- expand2(from)) to <- x[[1L]] if(n >= 2L) for(i in 2L:n) to <- to %*% x[[i]] to }) } ## ==== To sparseVector ================================================ setAs("Matrix", "sparseVector", function(from) .M2V(from)) setAs("matrix", "sparseVector", function(from) .m2V(from)) setAs("vector", "sparseVector", function(from) .m2V(from)) setAs( "ANY", "sparseVector", function(from) as(as.vector(from), "sparseVector")) ## ==== To "kind" ====================================================== setAs("Matrix", "nMatrix", function(from) .M2kind(from, "n", NA)) setAs("Matrix", "lMatrix", function(from) .M2kind(from, "l", NA)) setAs("Matrix", "dMatrix", function(from) .M2kind(from, "d", NA)) setAs("Matrix", "ndenseMatrix", function(from) .M2kind(from, "n", FALSE)) setAs("Matrix", "ldenseMatrix", function(from) .M2kind(from, "l", FALSE)) setAs("Matrix", "ddenseMatrix", function(from) .M2kind(from, "d", FALSE)) setAs("Matrix", "nsparseMatrix", function(from) .M2kind(from, "n", TRUE)) setAs("Matrix", "lsparseMatrix", function(from) .M2kind(from, "l", TRUE)) setAs("Matrix", "dsparseMatrix", function(from) .M2kind(from, "d", TRUE)) setAs("matrix", "nMatrix", function(from) { if(.sparseDefault(from)) .m2sparse.checking(from, "n", "C") else .m2dense.checking(from, "n") }) setAs("matrix", "lMatrix", function(from) { if(isDiagonal(from)) forceDiagonal(`storage.mode<-`(from, "logical")) else if(.sparseDefault(from)) .m2sparse.checking(from, "l", "C") else .m2dense.checking(from, "l") }) setAs("matrix", "dMatrix", function(from) { if(isDiagonal(from)) forceDiagonal(`storage.mode<-`(from, "double")) else if(.sparseDefault(from)) .m2sparse.checking(from, "d", "C") else .m2dense.checking(from, "d") }) setAs("matrix", "ndenseMatrix", function(from) .m2dense.checking(from, "n")) setAs("matrix", "ldenseMatrix", function(from) .m2dense.checking(from, "l")) setAs("matrix", "ddenseMatrix", function(from) .m2dense.checking(from, "d")) setAs("matrix", "nsparseMatrix", function(from) .m2sparse.checking(from, "n", "C")) setAs("matrix", "lsparseMatrix", function(from) .m2sparse.checking(from, "l", "C")) setAs("matrix", "dsparseMatrix", function(from) .m2sparse.checking(from, "d", "C")) setAs("vector", "nMatrix", function(from) { if(.sparseDefault(from)) .m2sparse(from, "ngC") else .m2dense(from, "nge") }) setAs("vector", "lMatrix", function(from) { if(.sparseDefault(from)) .m2sparse(from, "lgC") else .m2dense(from, "lge") }) setAs("vector", "dMatrix", function(from) { if(.sparseDefault(from)) .m2sparse(from, "dgC") else .m2dense(from, "dge") }) setAs("vector", "ndenseMatrix", function(from) .m2dense(from, "nge")) setAs("vector", "ldenseMatrix", function(from) .m2dense(from, "lge")) setAs("vector", "ddenseMatrix", function(from) .m2dense(from, "dge")) setAs("vector", "nsparseMatrix", function(from) .m2sparse(from, "ngC")) setAs("vector", "lsparseMatrix", function(from) .m2sparse(from, "lgC")) setAs("vector", "dsparseMatrix", function(from) .m2sparse(from, "dgC")) setAs("sparseVector", "nsparseVector", function(from) .V2kind(from, "n")) setAs("sparseVector", "lsparseVector", function(from) .V2kind(from, "l")) setAs("sparseVector", "isparseVector", function(from) .V2kind(from, "i")) setAs("sparseVector", "dsparseVector", function(from) .V2kind(from, "d")) setAs("sparseVector", "zsparseVector", function(from) .V2kind(from, "z")) setAs("vector", "nsparseVector", function(from) .m2V(from, "n")) setAs("vector", "lsparseVector", function(from) .m2V(from, "l")) setAs("vector", "isparseVector", function(from) .m2V(from, "i")) setAs("vector", "dsparseVector", function(from) .m2V(from, "d")) setAs("vector", "zsparseVector", function(from) .m2V(from, "z")) ## ==== To "shape" ===================================================== ..m2gen <- function(from) .m2dense(from, ".ge") setAs( "Matrix", "generalMatrix", ..M2gen) setAs( "matrix", "generalMatrix", ..m2gen) setAs( "vector", "generalMatrix", ..m2gen) setAs("sparseVector", "generalMatrix", .V2C) setAs("Matrix", "symmetricMatrix", ..M2sym) setAs("matrix", "symmetricMatrix", ..M2sym) setAs("Matrix", "triangularMatrix", ..M2tri) setAs("matrix", "triangularMatrix", ..M2tri) rm(..m2gen) setAs("diagonalMatrix", "symmetricMatrix", function(from) { if(!isSymmetricDN(from@Dimnames)) stop("matrix is not symmetric; consider forceSymmetric(.) or symmpart(.)") .diag2sparse(from, ".", "s", "C", "U") }) setAs("diagonalMatrix", "triangularMatrix", function(from) .diag2sparse(from, ".", "t", "C", "U")) ## ==== To "representation" ============================================ setAs("Matrix", "denseMatrix", .M2unpacked) setAs("Matrix", "unpackedMatrix", .M2unpacked) setAs("Matrix", "packedMatrix", .M2packed) setAs("Matrix", "sparseMatrix", .M2C) setAs("Matrix", "CsparseMatrix", .M2C) setAs("Matrix", "RsparseMatrix", .M2R) setAs("Matrix", "TsparseMatrix", .M2T) ## Do test for structure: ## FIXME: wrongly assumes that methods are defined for pack() ... setAs("generalMatrix", "packedMatrix", function(from) pack(from)) setAs("matrix", "denseMatrix", function(from) .m2dense.checking(from, ".")) setAs("matrix", "unpackedMatrix", function(from) .m2dense.checking(from, ".")) setAs("matrix", "packedMatrix", function(from) pack(from)) setAs("matrix", "sparseMatrix", function(from) .m2sparse.checking(from, ".", "C")) setAs("matrix", "CsparseMatrix", function(from) .m2sparse.checking(from, ".", "C")) setAs("matrix", "RsparseMatrix", function(from) .m2sparse.checking(from, ".", "R")) setAs("matrix", "TsparseMatrix", function(from) .m2sparse.checking(from, ".", "T")) ## Many people want this coercion to be available and fast: setAs("matrix", "dgCMatrix", function(from) .m2sparse(from, "dgC")) setAs("vector", "denseMatrix", function(from) if(is.object(from) && length(dim(from)) == 2L) # e.g., data.frame as(as.matrix(from), "denseMatrix") else .m2dense(from, ".ge")) setAs("vector", "unpackedMatrix", function(from) .m2dense(from, ".ge")) setAs("vector", "sparseMatrix", function(from) if(is.object(from) && length(dim(from)) == 2L) # e.g., data.frame as(as.matrix(from), "sparseMatrix") else .m2sparse(from, ".gC")) setAs("vector", "CsparseMatrix", function(from) .m2sparse(from, ".gC")) setAs("vector", "RsparseMatrix", function(from) .m2sparse(from, ".gR")) setAs("vector", "TsparseMatrix", function(from) .m2sparse(from, ".gT")) setAs("ANY", "denseMatrix", function(from) as(as(from, "matrix"), "denseMatrix")) setAs("ANY", "sparseMatrix", function(from) as(as(from, "matrix"), "sparseMatrix")) setAs("sparseVector", "denseMatrix", .V2unpacked) setAs("sparseVector", "unpackedMatrix", .V2unpacked) setAs("sparseVector", "sparseMatrix", .V2C) setAs("sparseVector", "CsparseMatrix", .V2C) setAs("sparseVector", "RsparseMatrix", .V2R) setAs("sparseVector", "TsparseMatrix", .V2T) setAs("Matrix", "diagonalMatrix", .M2diag) setAs("matrix", "diagonalMatrix", .M2diag) setAs("Matrix", "indMatrix", function(from) as(as(from, "nsparseMatrix"), "indMatrix")) setAs("matrix", "indMatrix", function(from) as(as(from, "nsparseMatrix"), "indMatrix")) setAs("Matrix", "pMatrix", function(from) as(as(from, "nsparseMatrix"), "pMatrix")) setAs("matrix", "pMatrix", function(from) as(as(from, "nsparseMatrix"), "pMatrix")) Matrix/R/condest.R0000644000176200001440000003234112070371667013515 0ustar liggesusers#### This is a "translation" of GNU octave's #### ~/src/octave-3.2.4/scripts/linear-algebra/condest.m #### and ~/src/octave-3.2.4/scripts/linear-algebra/onenormest.m #### which have identical copyright and references (see below): #### ##__\begin{copyright clause}______________________________________________ ## Copyright (C) 2007, 2008, 2009 Regents of the University of California ## ## This file is part of Octave. ## ## Octave 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. ## ## Octave 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 Octave; see the file COPYING. If not, see ## . ## Code originally licensed under ## ## Copyright (c) 2007, Regents of the University of California ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## ## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## ## * Redistributions in binary form must reproduce the above ## copyright notice, this list of conditions and the following ## disclaimer in the documentation and/or other materials provided ## with the distribution. ## ## * Neither the name of the University of California, Berkeley nor ## the names of its contributors may be used to endorse or promote ## products derived from this software without specific prior ## written permission. ## ## THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A ## PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ## SUCH DAMAGE. ## Author: Jason Riedy ## Keywords: linear-algebra norm estimation ## Version: 0.2 ##__\end{copyright clause}________________________________________________ condest <- function(A, t = min (n, 5), normA = norm(A, "1"), silent = FALSE, quiet = TRUE) { ## Octave has further optional args and "calling sequences" ## may be implement at a later time point ## if(length(d <- dim(A)) != 2 || (n <- d[1]) != d[2]) stop("'A' must be a square matrix") luA <- lu(A) i.n <- seq_len(n) isSparse <- is(A, "sparseMatrix") if(isSparse) { ### FIXME: if A is not a Matrix, but already a "CHMfactor" as resulting from ### Cholesky() , then we can procede more efficiently , notably ### because of the solve(A, b, system = ".*") options ! ## luA = "sparseLU": slots (L, U, p,q, Dim); ## expand(luA) == list(P, L, U, Q) <----> A = P' L U Q ## where P A == A[p +1,] and A Q' == A[, q +1] ## <==> A^(-1) x = Q' U^-1 L^-1 P x = Q'y ## and A^(-T) x =(Q' U^-1 L^-1 P)' x = P' L^-T U^-T Q x = P'z q. <- q.i <- luA@q + 1L; q.i[q.i] <- i.n p. <- p.i <- luA@p + 1L; p.i[p.i] <- i.n ## q.i := inv(q.) & p.i := inv(p.), the inverse permutations Ut <- t(luA@U) Lt <- t(luA@L) f.solve <- function(x) solve(luA@U, solve(luA@L, x[p.,]))[q.i,] f.solve_t <- function(x) solve(Lt, solve(Ut, x[q.,]))[p.i,] ##Oct [L, U, P, Pc] = lu (A); ##Oct solve = @(x) Pc' * (U \ (L \ (P * x))); ##Oct solve_t = @(x) P' * (L' \ (U' \ (Pc * x))); } else { ## luA is "denseLU" : e.A <- expand(luA) ## == list(L, U, P), where A = PLU p. <- p.i <- luA@perm; p.i[p.i] <- i.n ## p.i := inv(p.), the inverse permutation Ut <- t(e.A$U) Lt <- t(e.A$L) ## A = PLU <--> A^{-1} x = U^-1 L^-1 P x ## A^{-T} x = (U^-1 L^-1 P)' x = P' L^-T U^-T x = P'z f.solve <- function(x) solve(e.A$U, solve(e.A$L, x[p.,])) f.solve_t <- function(x) solve(Lt, solve(Ut, x))[p.i,] ##Oct [L, U, P] = lu (A); ##Oct solve = @(x) U \ (L \ (P*x)); ##Oct solve_t = @(x) P' * (L' \ (U' \ x)); } n1.res <- ## onenormest (A^{-1}, t=t) -- of course,that's *NOT* what we want onenormest (A.x = f.solve, At.x = f.solve_t, t=t, n=n, quiet=quiet, silent=silent) ## [Ainv_norm, v, w] = onenormest (solve, solve_t, n, t); w <- n1.res[["w"]] list(est = normA * n1.res[["est"]], v = w / sum(abs(w))) # sum(|w|) = norm(w, "1") } ## %!demo ## %! N = 100; ## %! A = randn (N) + eye (N); ## %! condest (A) ## %! [L,U,P] = lu (A); ## %! condest (A, @(x) U\ (L\ (P*x)), @(x) P'*(L'\ (U'\x))) ## %! condest (@(x) A*x, @(x) A'*x, @(x) U\ (L\ (P*x)), @(x) P'*(L'\ (U'\x)), N) ## %! norm (inv (A), 1) * norm (A, 1) ### Yes, these test bounds are really loose. There's ### enough randomization to trigger odd cases with hilb(). ## %!test ## %! N = 6; ## %! A = hilb (N); ## %! cA = condest (A); ## %! cA_test = norm (inv (A), 1) * norm (A, 1); ## %! assert (cA, cA_test, -2^-8); ## %!test ## %! N = 6; ## %! A = hilb (N); ## %! solve = @(x) A\x; solve_t = @(x) A'\x; ## %! cA = condest (A, solve, solve_t); ## %! cA_test = norm (inv (A), 1) * norm (A, 1); ## %! assert (cA, cA_test, -2^-8); ## %!test ## %! N = 6; ## %! A = hilb (N); ## %! apply = @(x) A*x; apply_t = @(x) A'*x; ## %! solve = @(x) A\x; solve_t = @(x) A'\x; ## %! cA = condest (apply, apply_t, solve, solve_t, N); ## %! cA_test = norm (inv (A), 1) * norm (A, 1); ## %! assert (cA, cA_test, -2^-6); ## %!test ## %! N = 12; ## %! A = hilb (N); ## %! [rcondA, v] = condest (A); ## %! x = A*v; ## %! assert (norm(x, inf), 0, eps); ##------------ onenormest ------------------------------------------ onenormest <- function(A, t = min(n, 5), A.x, At.x, n, silent = FALSE, quiet = silent, iter.max = 10, eps = 4* .Machine$double.eps) { mi.A <- missing(A) mi.A.x <- missing(A.x) mi.At.x <- missing(At.x) no.A.x <- mi.A.x || !is.function(A.x) no.At.x <- mi.At.x || !is.function(At.x) if(mi.A && (no.A.x || no.At.x)) stop("must either specify 'A' or the functions 'A.x' and 'At.x'") if(!mi.A && (!mi.A.x || !mi.At.x)) warning("when 'A' is specified, 'A.x' and 'At.x' are disregarded") if(mi.A) { stopifnot(is.numeric(n), length(n) == 1, n == round(n), n >= 0) } else { ## using 'A' if(length(d <- dim(A)) != 2 || (n <- d[1]) != d[2]) stop("'A' must be a square matrix") rm(d) } stopifnot(is.numeric(t), length(t) == 1, t >= 1, iter.max >= 1) ## Initial test vectors X. X <- matrix(runif(n*t), n,t) # X = rand (n, t); ## scale X to have column sums == 1 : X <- X / rep(colSums(X), each=n) ## Track if a vertex has been visited. been_there <- logical(n) # zeros (n, 1); I.t <- diag(nrow = t) ## To check if the estimate has increased. est_old <- 0 ## Normalized vector of signs. S <- matrix(0, n, t) for(iter in 1:(iter.max + 1)) { Y <- if(mi.A) A.x(X) else A %*% X ## is n x t ## Find the initial estimate as the largest A*x. ## [est, imax] = max (sum (abs (Y), 1)) imax <- which.max(cY <- colSums(abs(Y))) est <- cY[imax] if (est > est_old || iter == 2) w <- Y[, imax] if (iter >= 2 && est < est_old) { ## No improvement, so stop. est <- est_old break } est_old <- est S_old <- S if (iter > iter.max) { ## Gone too far. Stop. if(!silent) warning(gettextf("not converged in %d iterations", iter.max), domain = NA) break } S <- sign (Y) ## n x t ## Test if any of S are approximately parallel to previous S ## vectors or current S vectors. If everything is parallel, ## stop. Otherwise, replace any parallel vectors with ## rand{-1,+1}. partest <- apply(abs(crossprod(S_old, S) - n) < eps*n, 2, any) if (all(partest)) { ## All the current vectors are parallel to old vectors. ## We've hit a cycle, so stop. if(!quiet) message("hit a cycle (1) -- stop iterations") break } if (any(partest)) { ## Some vectors are parallel to old ones and are cycling, ## but not all of them. Replace the parallel vectors with ## rand{-1,+1}. numpar <- sum (partest) replacements <- matrix(sample(c(-1,1), n*numpar,replace=TRUE), n, numpar) S[,partest] <- replacements } ## Now test for parallel vectors within S. partest <- apply(crossprod(S) - I.t == n, 2, any) if (any(partest)) { numpar <- sum(partest) replacements <- matrix(sample(c(-1,1), n*numpar,replace=TRUE), n, numpar) S[,partest] <- replacements } Z <- if(mi.A) At.x(S) else crossprod(A, S) ## -- n x t ## Now find the largest non-previously-visted index per vector. ## h = max(2, abs(Z)) ## -- n x t h <- pmax.int(2, as(abs(Z),"matrix")); dim(h) <- dim(Z) ## -- n x t ## [mh, mhi] = max (h) : for each column h[,j]: ## mh[j] = max(h[,j]); mhi = argmax(..) mhi <- apply(h, 2, which.max) ## mh <- h[cbind(mhi,1:t)] if (iter >= 2 && all(mhi == imax)) { ## (mhi == imax) : in octave this is only true when it's for all() ## Hit a cycle, stop. if(!quiet) message("hit a cycle (2) -- stop iterations") break } ## [h, ind] = sort (h, 'descend'): r <- apply(h, 2, sort.int, decreasing=TRUE, index.return=TRUE) #-> list h <- sapply(r, `[[`, "x") ind <- sapply(r, `[[`, "ix") #-> n x t {each column = permutation of 1:n} if (t > 1) { firstind <- ind[1:t] if (all (been_there[firstind])) { ## Visited all these before, so stop. break } ind <- ind[!been_there[ind]] ##-> now ind is a simple vector if(length(ind) < t) { ## There aren't enough new vectors, so we're practically ## in a cycle. Stop. if(!quiet) message("not enough new vecs -- stop iterations") break } } ## Visit the new indices. X <- matrix(0, n, t) X[cbind(ind[1:t], 1:t)] <- 1 ## for(zz in 1:t) X[ind[zz],zz] <- 1 been_there [ind[1:t]] <- TRUE } ## for(iter ...) ## The estimate est and vector w are set in the loop above. The ## vector v selects the imax column of A. v <- integer(n) v[imax] <- 1L list(est=est, v=v, w=w, iter=iter) }## {onenormest} ## %!demo ## %! N = 100; ## %! A = randn(N) + eye(N); ## %! [L,U,P] = lu(A); ## %! nm1inv = onenormest(@(x) U\(L\(P*x)), @(x) P'*(L'\(U'\x)), N, 30) ## %! norm(inv(A), 1) ## %!test ## %! N = 10; ## %! A = ones (N); ## %! [nm1, v1, w1] = onenormest (A); ## %! [nminf, vinf, winf] = onenormest (A', 6); ## %! assert (nm1, N, -2*eps); ## %! assert (nminf, N, -2*eps); ## %! assert (norm (w1, 1), nm1 * norm (v1, 1), -2*eps) ## %! assert (norm (winf, 1), nminf * norm (vinf, 1), -2*eps) ## %!test ## %! N = 10; ## %! A = ones (N); ## %! [nm1, v1, w1] = onenormest (@(x) A*x, @(x) A'*x, N, 3); ## %! [nminf, vinf, winf] = onenormest (@(x) A'*x, @(x) A*x, N, 3); ## %! assert (nm1, N, -2*eps); ## %! assert (nminf, N, -2*eps); ## %! assert (norm (w1, 1), nm1 * norm (v1, 1), -2*eps) ## %! assert (norm (winf, 1), nminf * norm (vinf, 1), -2*eps) ## %!test ## %! N = 5; ## %! A = hilb (N); ## %! [nm1, v1, w1] = onenormest (A); ## %! [nminf, vinf, winf] = onenormest (A', 6); ## %! assert (nm1, norm (A, 1), -2*eps); ## %! assert (nminf, norm (A, inf), -2*eps); ## %! assert (norm (w1, 1), nm1 * norm (v1, 1), -2*eps) ## %! assert (norm (winf, 1), nminf * norm (vinf, 1), -2*eps) ## ## Only likely to be within a factor of 10. ## %!test ## %! N = 100; ## %! A = rand (N); ## %! [nm1, v1, w1] = onenormest (A); ## %! [nminf, vinf, winf] = onenormest (A', 6); ## %! assert (nm1, norm (A, 1), -.1); ## %! assert (nminf, norm (A, inf), -.1); ## %! assert (norm (w1, 1), nm1 * norm (v1, 1), -2*eps) ## %! assert (norm (winf, 1), nminf * norm (vinf, 1), -2*eps) Matrix/R/Ops.R0000644000176200001440000027701514511522651012621 0ustar liggesusers## METHODS FOR GENERIC: Ops = {Arith, Compare, Logic} (group) ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## > getGroupMembers("Ops") ## [1] "Arith" "Compare" "Logic" ## > getGroupMembers("Arith") ## [1] "+" "-" "*" "^" "%%" "%/%" "/" ## > getGroupMembers("Compare") ## [1] "==" ">" "<" "!=" "<=" ">=" ## > getGroupMembers("Logic") # excluding unary "!" -> ./not.R ## [1] "&" "|" if(FALSE) { ## vvvv MJ: for _after_ 1.6-2, ditto ./(Arith|Compare|Logic).R .Ops.invalid <- function(x) { if(is.object(x)) gettextf("invalid class \"%s\" in '%s' method", class(x)[1L], "Ops") else gettextf("invalid type \"%s\" in '%s' method", typeof(x), "Ops") } for(.cl in c("Matrix", "sparseVector")) { setMethod("Ops", signature(e1 = .cl, e2 = "ANY"), function(e1, e2) if(any(typeof(e2) == c("logical", "integer", "double"))) { if(is.matrix(e2)) callGeneric(e1, unclass(e2)) else callGeneric(e2, as.vector(e2)) } else stop(.Ops.invalid(e2), domain = NA)) setMethod("Ops", signature(e1 = "ANY", e2 = .cl), function(e1, e2) if(any(typeof(e1) == c("logical", "integer", "double"))) { if(is.matrix(e1)) callGeneric(unclass(e1), e2) else callGeneric(as.vector(e1), e2) } else stop(.Ops.invalid(e1), domain = NA)) setMethod("Ops", signature(e1 = .cl, e2 = "NULL"), function(e1, e2) callGeneric(e1, logical(0L))) setMethod("Ops", signature(e1 = "NULL", e2 = .cl), function(e1, e2) callGeneric(logical(0L), e2)) ## MJ: OK, but I'd prefer to handle all "matrix" as ".geMatrix" setMethod("Ops", signature(e1 = .cl, e2 = "matrix"), function(e1, e2) if(any(typeof(e2) == c("logical", "integer", "double"))) callGeneric(e1, Matrix(e2)) else stop(.Ops.invalid(e2), domain = NA)) ## MJ: OK, but I'd prefer to handle all "matrix" as ".geMatrix" setMethod("Ops", signature(e1 = "matrix", e2 = .cl), function(e1, e2) if(any(typeof(e1) == c("logical", "integer", "double"))) callGeneric(Matrix(e1), e2) else stop(.Ops.invalid(e1), domain = NA)) } rm(.cl) ## ^^^^ MJ: for _after_ 1.6-2, ditto ./(Arith|Compare|Logic).R } .Ops.checkDim <- function(d.a, d.b) { if(any(d.a != d.b)) stop(gettextf("non-conformable matrix dimensions in %s", deparse(sys.call(sys.parent()))), call. = FALSE, domain = NA) d.a } .Ops.checkDimNames <- function(dn.a, dn.b, useFirst = TRUE, check = FALSE) { ## behave as described in ?Arithmetic nullDN <- list(NULL, NULL) h.a <- !identical(nullDN, dn.a) h.b <- !identical(nullDN, dn.b) if(h.a || h.b) { if(useFirst) { if(!h.a) dn.b else dn.a } else { if (!h.b) dn.a else if(!h.a) dn.b else { ## both have non-trivial dimnames r <- dn.a # "default" result for(j in 1:2) if(!is.null(dn <- dn.b[[j]])) { if(is.null(r[[j]])) r[[j]] <- dn else if(check && !identical(r[[j]], dn)) warning(gettextf("dimnames [%d] mismatch in %s", j, deparse(sys.call(sys.parent()))), call. = FALSE, domain = NA) } r } } } else nullDN } ## cache them [rather in package 'methods' ??] .ArithGenerics <- getGroupMembers("Arith") if(FALSE) { # unused .CompareGenerics <- getGroupMembers("Compare") .LogicGenerics <- getGroupMembers("Logic") } ### Design decision for *sparseMatrix*: ### work via Csparse since Tsparse are not-unique (<-> slots not compatible) ### -- 0 -- (not dense *or* sparse) ----------------------------------- ##-------- originally from ./Matrix.R -------------------- ## Some ``Univariate'' "Arith" (univariate := 2nd argument 'e2' is missing) setMethod("+", signature(e1 = "Matrix", e2 = "missing"), function(e1,e2) e1) ## "fallback": setMethod("-", signature(e1 = "Matrix", e2 = "missing"), function(e1, e2) { warning("inefficient method used for \"- e1\"") 0 - e1 }) setMethod("-", signature(e1 = "denseMatrix", e2 = "missing"), function(e1, e2) { e1@x <- -e1@x if(.hasSlot(e1, "factors") && length(e1@factors)) e1@factors <- list() e1 }) setMethod("-", signature(e1 = "diagonalMatrix", e2 = "missing"), function(e1, e2) { kind <- .M.kind(e1) r <- new(if(kind == "z") "zdiMatrix" else "ddiMatrix") r@Dim <- d <- e1@Dim r@Dimnames <- e1@Dimnames r@x <- if(e1@diag != "N") rep.int(if(kind == "z") -1+0i else -1, d[1L]) else -(if(kind == "n") e1@x | is.na(e1@x) else e1@x) r }) ## old-style matrices are made into new ones setMethod("Ops", signature(e1 = "Matrix", e2 = "matrix"), function(e1, e2) callGeneric(e1, Matrix(e2))) setMethod("Ops", signature(e1 = "matrix", e2 = "Matrix"), function(e1, e2) callGeneric(Matrix(e1), e2)) ## Note: things like callGeneric(Matrix(e1, sparse=is(e2,"sparseMatrix")), e2)) ## may *not* be better: e.g. Matrix(.) can give *diagonal* instead of sparse ## NULL should be treated as logical(0) {which often will be coerced to numeric(0)}: setMethod("Ops", signature(e1 = "Matrix", e2 = "NULL"), function(e1, e2) callGeneric(e1, logical())) setMethod("Ops", signature(e1 = "NULL", e2 = "Matrix"), function(e1, e2) callGeneric(logical(), e2)) setMethod("Ops", signature(e1 = "Matrix", e2 = "ANY"), function(e1, e2) if(is.object(e2) && is.matrix(e2)) callGeneric(e1, unclass(e2)) # e.g., for "table" else .bail.out.2(.Generic, class(e1), class(e2))) setMethod("Ops", signature(e1 = "ANY", e2 = "Matrix"), function(e1, e2) if(is.object(e1) && is.matrix(e1)) callGeneric(unclass(e1), e2) # e.g., for "table" else .bail.out.2(.Generic, class(e1), class(e2))) ## "General principle" ## - - - - - - - - - ## For "Arith" it is sufficient (though not optimal, once we have "iMatrix"!) ## to define "dMatrix" methods and coerce all other "[nli]Matrix" to "dMatrix" setMethod("Arith", signature(e1 = "Matrix", e2 = "Matrix"), function(e1, e2) callGeneric(as(e1, "dMatrix"), as(e2, "dMatrix"))) ## For "Compare", this would be feasible too, but is clearly suboptimal, ## particularly for "==" and "!=" ## and for "lMatrix" and "nMatrix" should not coerce at all if(FALSE) setMethod("Compare", signature(e1 = "Matrix", e2 = "Matrix"), function(e1, e2) { if(is.na(match(.Generic, c("==", "!=")))) callGeneric(as(e1, "dMatrix"), as(e2, "dMatrix")) else { ## no coercion needed for "==" or "!=" ## ## what now ? <<<<<<<<<<< FIXME >>>>>>>>> .bail.out.2(.Generic, class(e1), class(e2)) } }) ## Working entirely on "matching" x slot: ## can be done for matching-dim "*geMatrix", and also ## matching-{dim + uplo} for *packed* (only!) symmetric+triangular .Ops.via.x <- function(e1, e2) { .Ops.checkDim(dim(e1), dim(e2)) e1@x <- callGeneric(e1@x, e2@x) if(.hasSlot(e1, "factors") && length(e1@factors)) e1@factors <- list() e1 } ###-------- originally from ./dMatrix.R -------------------- ## ## Note that there extra methods for o ! ## ## "Compare" -> returning logical Matrices; .Cmp.swap() is in ./Auxiliaries.R setMethod("Compare", signature(e1 = "numeric", e2 = "dMatrix"), .Cmp.swap) setMethod("Compare", signature(e1 = "logical", e2 = "dMatrix"), .Cmp.swap) setMethod("Compare", signature(e1 = "numeric", e2 = "lMatrix"), .Cmp.swap) setMethod("Compare", signature(e1 = "logical", e2 = "lMatrix"), .Cmp.swap) setMethod("Compare", signature(e1 = "numeric", e2 = "nMatrix"), .Cmp.swap) setMethod("Compare", signature(e1 = "logical", e2 = "nMatrix"), .Cmp.swap) ## This is parallel to Logic.Mat.atomic() below ---> __keep parallel__ ! Cmp.Mat.atomic <- function(e1, e2) { ## result will inherit from "lMatrix" n1 <- prod(d <- e1@Dim) cl <- class(e1) if((l2 <- length(e2)) == 0) return(if(n1 == 0) as(e1, "lMatrix") else as.logical(e2)) ## else if(n1 && n1 < l2) stop(sprintf("dim [product %d] do not match the length of object [%d]", n1, l2)) cl1 <- getClassDef(cl) slots1 <- names(cl1@slots) has.x <- any("x" == slots1)# *fast* check for "x" slot presence if(l2 > 1 && has.x) return(if(n1 == 0) { sNms <- .slotNames(e1) r <- copyClass(e1, class2(cl,"l"), sNames = sNms[sNms != "x"], check = FALSE) r@x <- callGeneric(e1@x, e2) r } else # cannot simply compare e2, e1@x -> use another method callGeneric(e1, Matrix(e2, nrow=d[1], ncol=d[2])) ) ## else Udg <- extends(cl1, "triangularMatrix") && e1@diag == "U" r0 <- callGeneric(0, e2) r <- callGeneric(if(has.x) e1@x else TRUE, e2) ## Udg: append the diagonal at *end*, as diagU2N(): r. <- if(Udg) c(r, callGeneric(..diag.x(e1), e2)) else r ## trivial case first (beware of NA) if(isTRUE(all(r0) && all(r.))) { r <- new(if(d[1] == d[2]) "lsyMatrix" else "lgeMatrix") r@Dim <- d r@Dimnames <- e1@Dimnames r@x <- rep.int(TRUE, n1) } else if(extends(cl1, "denseMatrix")) { full <- !.isPacked(e1) # << both "dtr" and "dsy" are 'full' if(full || allFalse(r0) || extends(cl1, "symmetricMatrix")) { isTri <- extends(cl1, "triangularMatrix") ## FIXME? using copyClass() to copy "relevant" slots r <- new(class2(cl, "l"), x = r, Dim = d, Dimnames = e1@Dimnames) if(extends(cl1, "symmetricMatrix")) { r@uplo <- e1@uplo } else if(isTri) { r@uplo <- e1@uplo r@diag <- e1@diag } } else { ## packed matrix with structural 0 and r0 is not all FALSE: ##--> result cannot be packed anymore ## [dense & packed & not symmetric ] ==> must be "dtp*" : if(!extends(cl1, "dtpMatrix")) stop("internal bug in \"Compare\" method (Cmp.Mat.atomic); please report") rx <- rep_len(r0, n1) rx[indTri(d[1], upper = (e1@uplo == "U"), diag=TRUE)] <- r. r <- new("lgeMatrix", x = rx, Dim = d, Dimnames = e1@Dimnames) } } else { ##---- e1 is(. , sparseMatrix) ----------------- ## FIXME: remove this test eventually if(extends(cl1, "diagonalMatrix")) stop("Cmp.Mat.atomic() should not be called for diagonalMatrix") remainSparse <- allFalse(r0) ## <==> things remain sparse if(Udg) { # e1 *is* unit-diagonal (triangular sparse) r1 <- callGeneric(1, e2) Udg <- all(r1) # maybe Unit-diagonal (sparse) result ## if(!remainSparse) we'll use non0ind() which *has* unit-diag. indices at end ## if(Udg && remainSparse) { } else { ## result will not be unit-diagonal sparse e1 <- .diagU2N(e1, cl = cl1) # otherwise, result is U-diag ## FIXME? rather ## if(extends1of(cl1, c("CsparseMatrix", "RsparseMatrix","TsparseMatrix")) { if(extends(cl1, "CsparseMatrix")) { ## repeat computation if e1 has changed r. <- callGeneric(if(has.x) e1@x else TRUE, e2) } } } if(remainSparse) { if(!anyNA(r) && ((Ar <- all(r)) || !any(r))) { lClass <- class2(cl, "l") # is "lsparse*" r <- new(lClass) r@Dim <- d r@Dimnames <- e1@Dimnames if(Ar) { # 'TRUE' instead of 'x': same sparsity: for(n in intersect(c("i","j","p","uplo","diag"), slots1)) slot(r, n) <- slot(e1, n) n <- if(has.x) length(e1@x) else if(any("p" == slots1)) e1@p[d[2]+1L] else length(e1@i) r@x <- rep.int(TRUE, n) } else { ## !any(r): all FALSE: keep empty 'r' matrix ## but may need a valid 'pointer' slot: if(extends(lClass, "CsparseMatrix")) r@p <- rep.int(0L, 1+ncol(r)) else if(extends(lClass, "RsparseMatrix")) r@p <- rep.int(0L, 1+nrow(r)) } } else { # some TRUE, FALSE, NA : go via unique 'Tsparse' M <- asUniqueT(e1) nCl <- class2(class(M), 'l') # logical Tsparse sN <- slotNames(nCl) ## copy "the other slots" (important for "tr"/"sym"): r <- copyClass(M, nCl, sNames = sN[is.na(match(sN, "x"))]) r@x <- callGeneric(if(has.x) M@x else 1, e2) if(extends(cl1, "CsparseMatrix")) r <- .M2C(r) else if(extends(cl1, "RsparseMatrix")) r <- .M2R(r) } } else { ## non sparse result; triangularity also gone, typically lClass <- if(extends(cl1, "symmetricMatrix")) "lsyMatrix" else "lgeMatrix" Matrix.message(sprintf("sparse to dense (%s) coercion in '%s' -> %s", lClass, .Generic, "Cmp.Mat.atomic"), .M.level = 2) rx <- rep_len(r0, n1) ## Here, we assume that 'r.' and the indices align (!) encI <- .Call(m_encodeInd, non0ind(e1, cl1, uniqT=FALSE, xtendSymm=FALSE), di = d, orig1=FALSE, checkBounds=FALSE) rx[1L + encI] <- r. r <- new(lClass, x = rx, Dim = d, Dimnames = e1@Dimnames) } } r } setMethod("Compare", signature(e1 = "dMatrix", e2 = "numeric"), Cmp.Mat.atomic) setMethod("Compare", signature(e1 = "dMatrix", e2 = "logical"), Cmp.Mat.atomic) setMethod("Compare", signature(e1 = "lMatrix", e2 = "numeric"), Cmp.Mat.atomic) setMethod("Compare", signature(e1 = "lMatrix", e2 = "logical"), Cmp.Mat.atomic) setMethod("Compare", signature(e1 = "nMatrix", e2 = "numeric"), Cmp.Mat.atomic) setMethod("Compare", signature(e1 = "nMatrix", e2 = "logical"), Cmp.Mat.atomic) rm(Cmp.Mat.atomic) ## "xMatrix <-> work with 'x' slot {was originally just for "Compare"}: ## ------- {also used for "Arith"}: Ops.x.x <- function(e1, e2) { d <- .Ops.checkDim(dim(e1), dim(e2)) if((dens1 <- extends(c1 <- class(e1), "denseMatrix"))) gen1 <- extends(c1, "generalMatrix") if((dens2 <- extends(c2 <- class(e2), "denseMatrix"))) gen2 <- extends(c2, "generalMatrix") if(dens1 && dens2) { ## both inherit from ddense* geM <- TRUE if(!gen1) { if(!gen2) { ## consider preserving "triangular" / "symmetric" geM <- FALSE le <- prod(d) isPacked <- function(x) length(x@x) < le Mclass <- if(extends(c1, "symmetricMatrix") && extends(c2, "symmetricMatrix")) { if(e1@uplo != e2@uplo) ## one is upper, one is lower e2 <- t(e2) if((p1 <- isPacked(e1)) | (p2 <- isPacked(e2))) { ## at least one is packed if(p1 != p2) { ## one is not packed --> *do* pack it: if(p1) e2 <- pack(e2) else e1 <- pack(e1) } "spMatrix" } else "syMatrix" } else if(extends(c1, "triangularMatrix") && extends(c2, "triangularMatrix")) { geM <- e1@uplo != e2@uplo || isN0(callGeneric(0,0)) if(!geM) { if(e1@diag == "U") e1 <- ..diagU2N(e1) if(e2@diag == "U") e2 <- ..diagU2N(e2) p1 <- isPacked(e1) p2 <- isPacked(e2) if(p1 || p2) { ## at least one is packed if(p1 != p2) { ## one is not packed --> *do* pack it: if(p1) e2 <- pack(e2) else e1 <- pack(e1) } "tpMatrix" } else "trMatrix" } } else { ## not symmetric, not triangular ==> "general" geM <- TRUE } if(geM) e2 <- .M2gen(e2) } if(geM) e1 <- .M2gen(e1) # was "dgeMatrix" } else { ## gen1 if(!gen2) e2 <- .M2gen(e2) } ## now, in all cases @x should be matching & correct ## {only "uplo" part is used} r <- callGeneric(e1@x, e2@x) if(is.integer(r)) ## as "igeMatrix" does not yet exist! r <- as.double(r) kr <- .M.kind(r) if(geM) new(paste0(kr, "geMatrix"), x = r, Dim = d, Dimnames = e1@Dimnames) else new(paste0(kr, Mclass), x = r, Dim = d, Dimnames = e1@Dimnames, uplo = e1@uplo) } else { r <- if(!dens1 && !dens2) ## both e1 _and_ e2 are sparse. ## Now (new method dispatch, 2009-01) *does* happen ## even though we have o methods callGeneric(as(e1, "CsparseMatrix"), as(e2, "CsparseMatrix")) else if(dens1 && !dens2) ## go to dense callGeneric(e1, as(e2, "denseMatrix")) else ## if(!dens1 && dens2) callGeneric(as(e1, "denseMatrix"), e2) if(!is(r, "sparseMatrix") && sparseDefault(r)) as(r, "sparseMatrix") else r } } setMethod("Ops", signature(e1 = "dMatrix", e2 = "dMatrix"), Ops.x.x) setMethod("Ops", signature(e1 = "lMatrix", e2 = "lMatrix"), Ops.x.x) ## n*: for "Arith" go via dMatrix, for "Logic" via "lMatrix" setMethod("Compare", signature(e1 = "nMatrix", e2 = "nMatrix"), Ops.x.x) ## l o d : depends on *kind* of Ops -- but Ops.x.x works on slots - correctly: setMethod("Ops", signature(e1="lMatrix", e2="dMatrix"), Ops.x.x) setMethod("Ops", signature(e1="dMatrix", e2="lMatrix"), Ops.x.x) ## lMatrix & nMatrix ... probably should also just use "Matrix" ? ## ## Hmm, the coercion should differ, depending on subgroup ("Logic", "Arith",..) ## --> try to get rid of these setMethod("Ops", signature(e1="lMatrix", e2="numeric"), function(e1, e2) callGeneric(as(e1,"dMatrix"), e2)) setMethod("Ops", signature(e1="numeric", e2="lMatrix"), function(e1, e2) callGeneric(e1, as(e2,"dMatrix"))) setMethod("Ops", signature(e1="nMatrix", e2="numeric"), function(e1, e2) callGeneric(as(e1,"dMatrix"), e2)) setMethod("Ops", signature(e1="numeric", e2="nMatrix"), function(e1, e2) callGeneric(e1, as(e2,"dMatrix"))) ## setMethod("Ops", signature(e1="Matrix", e2="logical"), ## function(e1,e2) callGeneric(as(e1,"lMatrix"), e2)) ## setMethod("Ops", signature(e1="logical", e2="Matrix"), ## function(e1,e2) callGeneric(e1, as(e2,"lMatrix"))) ## "dpoMatrix" / "dppMatrix" : ## Positive-definiteness is lost with all "Ops" but some "Arith" cases for(cl in c("numeric", "logical")) { # "complex", "raw" : basically "replValue" setMethod("Arith", signature(e1 = cl, e2 = "dpoMatrix"), function(e1, e2) { if(!(l1 <- length(e1))) double(0L) else if(l1 == 1 && any(.Generic == c("*","/","+")) && (e1 > 0)) { e2@x <- callGeneric(e1, e2@x) if(length(e2@factors)) e2@factors <- list() e2 # remains "dpo" } else callGeneric(e1, as(e2, "dsyMatrix")) }) setMethod("Arith", signature(e1 = cl, e2 = "dppMatrix"), function(e1, e2) { if(!(l1 <- length(e1))) double(0L) else if(l1 == 1 && any(.Generic == c("*","/","+")) && (e1 > 0)) { e2@x <- callGeneric(e1, e2@x) if(length(e2@factors)) e2@factors <- list() e2 # remains "dpp" } else callGeneric(e1, as(e2, "dspMatrix")) }) setMethod("Arith", signature(e1 = "dpoMatrix", e2 = cl), function(e1, e2) { if(!(l2 <- length(e2))) double(0L) else if(l2 == 1 && any(.Generic == c("*","/","+")) && (e2 > 0)) { e1@x <- callGeneric(e1@x, e2) if(length(e1@factors)) e1@factors <- list() e1 # remains "dpo" } else callGeneric(as(e1, "dsyMatrix"), e2) }) setMethod("Arith", signature(e1 = "dppMatrix", e2 = cl), function(e1, e2) { if(!(l2 <- length(e2))) double(0L) else if(l2 == 1 && any(.Generic == c("*","/","+")) && (e2 > 0)) { e1@x <- callGeneric(e1@x, e2) if(length(e1@factors)) e1@factors <- list() e1 # remains "dpp" } else callGeneric(as(e1, "dspMatrix"), e2) }) setMethod("Ops", signature(e1 = cl, e2 = "dpoMatrix"), function(e1, e2) callGeneric(e1, as(e2, "dsyMatrix"))) setMethod("Ops", signature(e1 = cl, e2 = "dppMatrix"), function(e1, e2) callGeneric(e1, as(e2, "dspMatrix"))) setMethod("Ops", signature(e1 = "dpoMatrix", e2 = cl), function(e1, e2) callGeneric(as(e1, "dsyMatrix"), e2)) setMethod("Ops", signature(e1 = "dppMatrix", e2 = cl), function(e1, e2) callGeneric(as(e1, "dspMatrix"), e2)) }# for(cl...) ### -- I -- dense ----------------------------------------------------------- ##-------- originally from ./dgeMatrix.R -------------------- ## ----- only work with NAMESPACE importFrom(methods, ..) setMethod("Arith", signature(e1 = "dgeMatrix", e2 = "dgeMatrix"), ## "+", "-", "*", "^", "%%", "%/%", "/" function(e1, e2) { ## NB: triangular, symmetric, etc may need own method d1 <- e1@Dim d2 <- e2@Dim eqD <- d1 == d2 if(!eqD[1]) stop("Matrices must have same number of rows for arithmetic") same.dim <- eqD[2] x1 <- e1@x x2 <- e2@x if(same.dim) { d <- d1 dn <- .Ops.checkDimNames(dimnames(e1), dimnames(e2)) } else { # nrows differ ----> maybe recycling if(d2[2] %% d1[2] == 0) { # nrow(e2) is a multiple x1 <- rep.int(x1, d2[2] %/% d1[2]) d <- d2 dn <- e2@Dimnames } else if(d1[2] %% d2[2] == 0) { # nrow(e1) is a multiple x2 <- rep.int(x2, d1[2] %/% d2[2]) d <- d1 dn <- e1@Dimnames } else stop(gettextf("number of rows are not compatible for %s", .Generic), domain = NA) } new("dgeMatrix", Dim = d, Dimnames = dn, x = callGeneric(x1, x2)) }) A.M.n <- function(e1, e2) { d <- e1@Dim le <- length(e2) if(le == 0) { if(prod(d) == 0) new(class2(class(e1), "d"), Dim = d, Dimnames = e1@Dimnames) else as.numeric(e2) } else if(le == 1 || le == d[1] || any(prod(d) == c(le, 0L))) { ## matching dim e1@x <- callGeneric(e1@x, as.vector(e2)) if(length(e1@factors)) e1@factors <- list() e1 } else stop("length of 2nd arg does not match dimension of first") } setMethod("Arith", signature(e1 = "dgeMatrix", e2 = "numeric"), A.M.n) setMethod("Arith", signature(e1 = "dgeMatrix", e2 = "logical"), A.M.n) setMethod("Arith", signature(e1 = "dgeMatrix", e2 = "sparseVector"), A.M.n) A.n.M <- function(e1, e2) { d <- e2@Dim le <- length(e1) if(le == 0) { if(prod(d) == 0) new(class2(class(e2), "d"), Dim = d, Dimnames = e2@Dimnames) else as.numeric(e1) } else if(le == 1 || le == d[1] || any(prod(d) == c(le, 0L))) { ## matching dim e2@x <- callGeneric(as.vector(e1), e2@x) if(length(e2@factors)) e2@factors <- list() e2 } else stop("length of 1st arg does not match dimension of 2nd") } setMethod("Arith", signature(e1 = "numeric", e2 = "dgeMatrix"), A.n.M) setMethod("Arith", signature(e1 = "logical", e2 = "dgeMatrix"), A.n.M) setMethod("Arith", signature(e1 = "sparseVector", e2 = "dgeMatrix"), A.n.M) ## rm(A.M.n, A.n.M) ##-------- originally from ./ddenseMatrix.R -------------------- ## Cheap version: work via "dgeMatrix" and use the group methods there: if(FALSE)## preserve "symmetric", "triangular", --> rather use Ops.x.x setMethod("Arith", signature(e1 = "ddenseMatrix", e2 = "ddenseMatrix"), function(e1, e2) callGeneric(as(e1, "generalMatrix"), as(e2, "generalMatrix"))) .Arith.denseM.atom <- function(e1, e2) { ## since e1 = "dgeMatrix" has its own method, we have ## either symmetric or triangular ! n1 <- prod(d <- e1@Dim) le <- length(e2 <- as.vector(e2)) if(n1 && n1 < le) stop(sprintf("dim [product %d] do not match the length of object [%d]", n1, le)) if(le == 0) { if(prod(d) == 0) new(class2(class(e1), "d"), Dim = d, Dimnames = e1@Dimnames) else as.numeric(e2) } else if(le == 1 || le == d[1] || any(prod(d) == c(le, 0L))) { ## matching dim if(is(e1, "triangularMatrix")) { r0 <- callGeneric(0, e2) if(all0(r0)) { # result remains triangular if(e1@diag == "U" && !all(1 == callGeneric(1,e2))) e1 <- diagU2N(e1) e1@x <- callGeneric(e1@x, e2) e1 } else { ## result *general* callGeneric(.M2gen(e1), e2) } } else { ## symmetric if(le == 1) { ## result remains symmetric e1@x <- callGeneric(e1@x, e2) if(length(e1@factors)) e1@factors <- list() e1 } else { ## (le == d[1] || prod(d) == le) ## *might* remain symmetric, but 'x' may contain garbage ## *testing* for symmetry is also a bit expensive ==> simple: callGeneric(.M2gen(e1), e2) } } } else stop("length of 2nd arg does not match dimension of first") } setMethod("Arith", signature(e1 = "ddenseMatrix", e2 = "numeric"), .Arith.denseM.atom) setMethod("Arith", signature(e1 = "ddenseMatrix", e2 = "logical"), .Arith.denseM.atom) setMethod("Arith", signature(e1 = "ddenseMatrix", e2 = "sparseVector"), .Arith.denseM.atom) rm(.Arith.denseM.atom) .Arith.atom.denseM <- function(e1, e2) { d <- e2@Dim ## note that e2 is either symmetric or triangular here le <- length(e1 <- as.vector(e1)) if(le == 0) { if(prod(d) == 0) new(class2(class(e2), "d"), Dim = d, Dimnames = e2@Dimnames) else as.numeric(e1) } else if(le == 1 || le == d[1] || any(prod(d) == c(le, 0L))) { ## matching dim if(is(e2, "triangularMatrix")) { r0 <- callGeneric(e1, 0) if(all0(r0)) { # result remains triangular if(e2@diag == "U" && !all(1 == callGeneric(e1,1))) e2 <- diagU2N(e2) e2@x <- callGeneric(e1, e2@x) e2 } else { # result *general* callGeneric(e1, .M2gen(e2)) } } else { ## symmetric if(le == 1) { # result remains symmetric e2@x <- callGeneric(e1, e2@x) if(length(e2@factors)) e2@factors <- list() e2 } else { ## (le == d[1] || prod(d) == le) ## *might* remain symmetric, but 'x' may contain garbage ## *testing* for symmetry is also a bit expensive ==> simple: callGeneric(e1, .M2gen(e2)) } } } else stop("length of 1st arg does not match dimension of 2nd") } setMethod("Arith", signature(e1 = "numeric", e2 = "ddenseMatrix"), .Arith.atom.denseM) setMethod("Arith", signature(e1 = "logical", e2 = "ddenseMatrix"), .Arith.atom.denseM) setMethod("Arith", signature(e1 = "sparseVector", e2 = "ddenseMatrix"), .Arith.atom.denseM) rm(.Arith.atom.denseM) ## "Logic" ## ------- ##-------- originally from ./ldenseMatrix.R -------------------- ## These all had "Logic", now also for "Compare", ## but "Arith" differs: result will be "dgeMatrix' : .Ops2dge.via.x <- function(e1,e2) { .Ops.checkDim(dim(e1), dim(e2)) r <- copyClass(e1, "dgeMatrix", sNames = c("Dim","Dimnames")) r@x <- as.numeric(callGeneric(e1@x, e2@x)) r } setMethod("Compare", signature(e1="lgeMatrix", e2="lgeMatrix"), .Ops.via.x) setMethod("Logic", signature(e1="lgeMatrix", e2="lgeMatrix"), .Ops.via.x) setMethod("Arith", signature(e1="lgeMatrix", e2="lgeMatrix"), .Ops2dge.via.x) setMethod("Compare", signature(e1="ngeMatrix", e2="ngeMatrix"), .Ops.via.x) setMethod("Logic", signature(e1="ngeMatrix", e2="ngeMatrix"), .Ops.via.x) setMethod("Arith", signature(e1="ngeMatrix", e2="ngeMatrix"), .Ops2dge.via.x) rm(.Ops.via.x, .Ops2dge.via.x) ## nMatrix -> lMatrix conversions when "the other" is not nMatrix ## Use Ops.x.x unless both are sparse setMethod("Ops", signature(e1="dMatrix", e2="dMatrix"), Ops.x.x) setMethod("Ops", signature(e1="lMatrix", e2="lMatrix"), Ops.x.x) setMethod("Ops", signature(e1="nMatrix", e2="nMatrix"), Ops.x.x) setMethod("Ops", signature(e1="nMatrix", e2="lMatrix"), Ops.x.x) setMethod("Ops", signature(e1="lMatrix", e2="nMatrix"), Ops.x.x) setMethod("Ops", signature(e1="nMatrix", e2="dMatrix"), Ops.x.x) setMethod("Ops", signature(e1="dMatrix", e2="nMatrix"), Ops.x.x) rm(Ops.x.x) ## ... both are sparse: cannot use Ops.x.x setMethod("Ops", signature(e1="nsparseMatrix", e2="lsparseMatrix"), function(e1,e2) callGeneric(.M2kind(e1, "l"), e2)) setMethod("Ops", signature(e1="lsparseMatrix", e2="nsparseMatrix"), function(e1,e2) callGeneric(e1, .M2kind(e2, "l"))) setMethod("Ops", signature(e1="nsparseMatrix", e2="dsparseMatrix"), function(e1,e2) callGeneric(.M2kind(e1, "l"), e2)) setMethod("Ops", signature(e1="dsparseMatrix", e2="nsparseMatrix"), function(e1,e2) callGeneric(e1, .M2kind(e2, "l"))) ## For "Arith" go to "d*", not "l*": {the above, replaced "l by "d : setMethod("Arith", signature(e1="nsparseMatrix", e2="lsparseMatrix"), function(e1,e2) callGeneric(.M2kind(e1, "d"), e2)) setMethod("Arith", signature(e1="lsparseMatrix", e2="nsparseMatrix"), function(e1,e2) callGeneric(e1, .M2kind(e2, "d"))) setMethod("Arith", signature(e1="nsparseMatrix", e2="dsparseMatrix"), function(e1,e2) callGeneric(.M2kind(e1, "d"), e2)) setMethod("Arith", signature(e1="dsparseMatrix", e2="nsparseMatrix"), function(e1,e2) callGeneric(e1, .M2kind(e2, "d"))) if(FALSE) { ##-- not yet --------- ## New: for both "nsparseMatrix", *preserve* nsparse* -- via Tsp -- "nTsparseMatrix" setMethod("Ops", signature(e1 = "nsparseMatrix", e2 = "nsparseMatrix"), function(e1, e2) callGeneric(as(e1, "TsparseMatrix"), as(e2, "TsparseMatrix"))) Ops.nT.nT <- function(e1,e2) { d <- .Ops.checkDim(dim(e1), dim(e2)) ## e1, e2 are nTsparse, i.e., inheriting from "ngTMatrix", "ntTMatrix", "nsTMatrix" gen1 <- extends(cD1 <- getClassDef(class(e1)), "generalMatrix") gen2 <- extends(cD2 <- getClassDef(class(e2)), "generalMatrix") sym1 <- !gen1 && extends(cD1, "symmetricMatrix") sym2 <- !gen2 && extends(cD2, "symmetricMatrix") tri1 <- !gen1 && !sym1 tri2 <- !gen2 && !sym2 G <- gen1 && gen2 S <- sym1 && sym2 && e1@uplo == e2@uplo T <- tri1 && tri2 && e1@uplo == e2@uplo } setMethod("Ops", signature(e1="nTsparseMatrix", e2="nTsparseMatrix"), Ops.nT.nT) }##--- not yet ------------- ## Have this for "Ops" already above ## setMethod("Logic", signature(e1 = "logical", e2 = "Matrix"), ## function(e1, e2) callGeneric(e1, as(e2, "lMatrix"))) ## setMethod("Logic", signature(e1 = "Matrix", e2 = "logical"), ## function(e1, e2) callGeneric(as(e1, "lMatrix"), e2)) .ll <- function(e1, e2) callGeneric(as(e1,"lMatrix"), as(e2, "lMatrix")) setMethod("Logic", signature(e1 = "nMatrix", e2 = "Matrix"), .ll) setMethod("Logic", signature(e1 = "Matrix", e2 = "nMatrix"), .ll) setMethod("Logic", signature(e1 = "nMatrix", e2 = "nMatrix"), .ll) rm(.ll) ### "ANY" here means "any non-Matrix" (since "Ops"(ANY) has already bailout above): setMethod("Logic", signature(e1 = "ANY", e2 = "Matrix"), function(e1, e2) callGeneric(as.logical(e1), as(e2, "lMatrix"))) setMethod("Logic", signature(e1 = "Matrix", e2 = "ANY"), function(e1, e2) callGeneric(as(e1, "lMatrix"), as.logical(e2))) ## "swap RHS and LHS" and use the method below -- can do this, since ## "Logic" := { "&" , "|" } and both are commutative for(Mcl in c("lMatrix","nMatrix","dMatrix")) for(cl in c("logical", "numeric", "sparseVector")) setMethod("Logic", signature(e1 = cl, e2 = Mcl), function(e1,e2) callGeneric(e2, e1)) ## conceivably "numeric" could use callGeneric(e2, as.logical(e1)) ## but that's not useful at the moment, since Logic.Mat.atomic() does as.logical() ## This is parallel to Cmp.Mat.atomic() above ---> __keep parallel__ ! Logic.Mat.atomic <- function(e1, e2) { ## result will typically be "like" e1: l2 <- length(e2 <- as.logical(e2)) n1 <- prod(d <- e1@Dim) if(n1 && n1 < l2) stop(sprintf("dim [product %d] do not match the length of object [%d]", n1, l2)) if(.Generic == "&" && l2 && allTrue (e2)) return(as(e1, "lMatrix")) if(.Generic == "|" && l2 && allFalse(e2)) return(as(e1, "lMatrix")) cl <- class(e1) if(l2 == 0) return(if(n1 == 0) as(e1, "lMatrix") else as.logical(e2)) ## else cl1 <- getClassDef(cl) slots1 <- names(cl1@slots) has.x <- any("x" == slots1)# *fast* check for "x" slot presence if(l2 > 1 && has.x) return(if(n1 == 0) { sNms <- .slotNames(e1) r <- copyClass(e1, class2(cl, "l"), sNames = sNms[sNms != "x"], check = FALSE) r@x <- callGeneric(e1@x, e2) r } else # cannot simply compare e2, e1@x -> use another method callGeneric(e1, Matrix(e2, nrow=d[1], ncol=d[2])) ) ## else Udg <- extends(cl1, "triangularMatrix") && e1@diag == "U" r0 <- callGeneric(0, e2) r <- callGeneric(if(has.x) e1@x else TRUE, e2) ## Udg: append the diagonal at *end*, as diagU2N(): r. <- if(Udg) c(r, callGeneric(..diag.x(e1), e2)) else r ## trivial case first (beware of NA) if(isTRUE(all(r0) && all(r.))) { r <- new(if(d[1] == d[2]) "lsyMatrix" else "lgeMatrix") r@Dim <- d r@Dimnames <- e1@Dimnames r@x <- rep.int(TRUE, n1) } else if(extends(cl1, "denseMatrix")) { full <- !.isPacked(e1) # << both "dtr" and "dsy" are 'full' if(full || allFalse(r0) || extends(cl1, "symmetricMatrix")) { isTri <- extends(cl1, "triangularMatrix") ## FIXME? using copyClass() to copy "relevant" slots r <- new(class2(cl, "l"), x = r, Dim = d, Dimnames = e1@Dimnames) if(extends(cl1, "symmetricMatrix")) { r@uplo <- e1@uplo } else if(isTri) { r@uplo <- e1@uplo r@diag <- e1@diag } } else { ## packed matrix with structural 0 and r0 is not all FALSE: ##--> result cannot be packed anymore ## [dense & packed & not symmetric ] ==> must be "ltp*" : if(!extends(cl1, "ltpMatrix")) stop("internal bug in \"Logic\" method (Logic.Mat.atomic); please report") rx <- rep_len(r0, n1) rx[indTri(d[1], upper = (e1@uplo == "U"), diag=TRUE)] <- r. r <- new("lgeMatrix", x = rx, Dim = d, Dimnames = e1@Dimnames) } } else { ##---- e1 is(. , sparseMatrix) ----------------- ## FIXME: remove this test eventually if(extends(cl1, "diagonalMatrix")) stop("Logic.Mat.atomic() should not be called for diagonalMatrix") remainSparse <- allFalse(r0) ## <==> things remain sparse if(Udg) { # e1 *is* unit-diagonal (triangular sparse) r1 <- callGeneric(1, e2) Udg <- all(r1) # maybe Unit-diagonal (sparse) result ## if(!remainSparse) we'll use non0ind() which *has* unit-diag. indices at end ## if(Udg && remainSparse) { } else { ## result will not be unit-diagonal sparse e1 <- .diagU2N(e1, cl = cl1) # otherwise, result is U-diag ## FIXME? rather ## if(extends1of(cl1, c("CsparseMatrix", "RsparseMatrix","TsparseMatrix")) { if(extends(cl1, "CsparseMatrix")) { ## repeat computation if e1 has changed r. <- callGeneric(if(has.x) e1@x else TRUE, e2) } } } if(remainSparse) { if(!anyNA(r) && ((Ar <- all(r)) || !any(r))) { lClass <- class2(cl, "l") # is "lsparse*" r <- new(lClass) r@Dim <- d r@Dimnames <- e1@Dimnames if(Ar) { # 'TRUE' instead of 'x': same sparsity: for(n in intersect(c("i","j","p","uplo","diag"), slots1)) slot(r, n) <- slot(e1, n) n <- if(has.x) length(e1@x) else if(any("p" == slots1)) e1@p[d[2]+1L] else length(e1@i) r@x <- rep.int(TRUE, n) } else { ## !any(r): all FALSE: keep empty 'r' matrix ## but may need a valid 'pointer' slot: if(extends(lClass, "CsparseMatrix")) r@p <- rep.int(0L, 1+ncol(r)) else if(extends(lClass, "RsparseMatrix")) r@p <- rep.int(0L, 1+nrow(r)) } } else { # some TRUE, FALSE, NA : go via unique 'Tsparse' M <- asUniqueT(e1) nCl <- class2(class(M), 'l') # logical Tsparse sN <- slotNames(nCl) ## copy "the other slots" (important for "tr"/"sym"): r <- copyClass(M, nCl, sNames = sN[is.na(match(sN, c("x","factors")))]) r@x <- callGeneric(if(has.x) M@x else TRUE, e2) if(extends(cl1, "CsparseMatrix")) r <- .M2C(r) else if(extends(cl1, "RsparseMatrix")) r <- .M2R(r) } } else { ## non sparse result lClass <- if(extends(cl1, "symmetricMatrix")) "lsyMatrix" else "lgeMatrix" Matrix.message(sprintf("sparse to dense (%s) coercion in '%s' -> %s", lClass, .Generic, "Logic.Mat.atomic"), .M.level = 2) rx <- rep_len(r0, n1) ## Here, we assume that 'r.' and the indices align (!) encI <- .Call(m_encodeInd, non0ind(e1, cl1, uniqT=FALSE, xtendSymm=FALSE), di = d, orig1=FALSE, checkBounds=FALSE) rx[1L + encI] <- r. r <- new(lClass, x = rx, Dim = d, Dimnames = e1@Dimnames) } } r } for(Mcl in c("lMatrix","nMatrix","dMatrix")) for(cl in c("logical", "numeric", "sparseVector")) setMethod("Logic", signature(e1 = Mcl, e2 = cl), Logic.Mat.atomic) rm(Logic.Mat.atomic, Mcl, cl) ### -- II -- sparse ---------------------------------------------------------- Ops.x.x.via.d <- function(e1, e2) callGeneric(.M2kind(e1, "d"), .M2kind(e2, "d")) ## Have lgC o lgC and then lgT o lgT Logic - quite similarly - ## also lsC o * and ltC o * : ## Here's the common functionality .do.Logic.lsparse <- function(e1,e2, d, dn, isOR, ij1, ij2) { ## NB non-diagonalMatrix := Union{ general, symmetric, triangular} gen1 <- extends(cD1 <- getClassDef(class(e1)), "generalMatrix") gen2 <- extends(cD2 <- getClassDef(class(e2)), "generalMatrix") sym1 <- !gen1 && extends(cD1, "symmetricMatrix") sym2 <- !gen2 && extends(cD2, "symmetricMatrix") tri1 <- !gen1 && !sym1 tri2 <- !gen2 && !sym2 G <- gen1 && gen2 S <- sym1 && sym2 && e1@uplo == e2@uplo T <- tri1 && tri2 && e1@uplo == e2@uplo if(T && e1@diag != e2@diag) { ## one is "U" the other "N" if(e1@diag == "U") e1 <- diagU2N(e1) else ## (e2@diag == "U" e2 <- diagU2N(e2) shape <- "t" } else if(!G && !S && !T) { ## e.g. one symmetric, one general ## coerce to generalMatrix and go : if(!gen1) e1 <- .M2gen(e1) if(!gen2) e2 <- .M2gen(e2) shape <- "g" } else { shape <- if(T) "t" else if(S) "s" else "g" } ii <- WhichintersectInd(ij1, ij2, di=d) I1 <- ii[[1]] ; has1 <- length(I1) > 0 I2 <- ii[[2]] ; has2 <- length(I2) > 0 ## 1) common indices i <- ij1[I1, 1] j <- ij1[I1, 2] if(isOR) { ## i.e. .Generic == "|" i.e. not "&" x <- e1@x[I1] | e2@x[I2] ## 2) "e1 o FALSE": x2 <- if(has1) e1@x[- I1] else e1@x # == callGeneric(e1@x[- I1], FALSE) ## 3) "0 o e1": x3 <- if(has2) e2@x[- I2] else e2@x # == callGeneric(FALSE, e2@x[- I2]) i <- c(i, if(has1) ij1[-I1, 1] else ij1[, 1], if(has2) ij2[-I2, 1] else ij2[, 1]) j <- c(j, if(has1) ij1[-I1, 2] else ij1[, 2], if(has2) ij2[-I2, 2] else ij2[, 2]) x <- c(x, x2, x3) } else { ## AND x <- e1@x[I1] & e2@x[I2] } if(any(!(x. <- x | is.na(x)))) { ## drop 'FALSE's i <- i[x.] j <- j[x.] x <- x[x.] } if(shape == "g") new("lgTMatrix", Dim = d, Dimnames = dn, i = i, j = j, x = x) else new(paste0("l",shape,"TMatrix"), Dim = d, Dimnames = dn, i = i, j = j, x = x, uplo = e1@uplo) } Logic.lCMat <- function(e1, e2, isOR) { stopifnot(is.logical(isOR)) d <- .Ops.checkDim(dim(e1), dim(e2)) dn <- .Ops.checkDimNames(dimnames(e1), dimnames(e2)) ## Very easy case first : if(identical(e1@i, e2@i) && identical(e1@p, e2@p)) { e1@x <- if(isOR) e1@x | e2@x else e1@x & e2@x if(.hasSlot(e1, "factors") && length(e1@factors)) e1@factors <- list() return(e1) } ## else : .M2C(.do.Logic.lsparse(e1, e2, d = d, dn = dn, isOR = isOR, ij1 = .Call(compressed_non_0_ij, e1, TRUE), ij2 = .Call(compressed_non_0_ij, e2, TRUE))) } m.Logic.lCMat <- function(e1, e2) Logic.lCMat(e1, e2, isOR = .Generic == "|") Logic.lTMat <- function(e1,e2) { d <- .Ops.checkDim(dim(e1), dim(e2)) dn <- .Ops.checkDimNames(dimnames(e1), dimnames(e2)) ## Very easy case first : if(identical(e1@i, e2@i) && identical(e1@j, e2@j)) { e1@x <- callGeneric(e1@x, e2@x) if(.hasSlot(e1, "factors") && length(e1@factors)) e1@factors <- list() return(e1) } ## else : cld <- getClassDef(class(e1)) .do.Logic.lsparse(e1, e2, d = d, dn = dn, isOR = .Generic == "|", ij1 = non0ind(e1, cld), ij2 = non0ind(e2, cld)) } setMethod("Logic", signature(e1="lgCMatrix", e2="lgCMatrix"), m.Logic.lCMat) setMethod("Logic", signature(e1="lgTMatrix", e2="lgTMatrix"), Logic.lTMat) rm(m.Logic.lCMat, Logic.lTMat) setMethod("Logic", signature(e1 = "lsCMatrix", e2 = "lsCMatrix"), function(e1, e2) { if(e1@uplo == e2@uplo) Logic.lCMat(e1, e2, isOR = .Generic == "|") else Logic.lCMat(e1, t(e2), isOR = .Generic == "|") }) setMethod("Logic", signature(e1 = "ltCMatrix", e2 = "ltCMatrix"), function(e1, e2) { isOR <- .Generic == "|" if(e1@uplo == e2@uplo) { if(e1@diag == e2@diag) ## both "N" or both "U" (!) Logic.lCMat(e1, e2, isOR=isOR) else if(e1@diag == "U") Logic.lCMat(diagU2N(e1), e2, isOR=isOR) else ## e1@diag == "N" *and* e2@diag == "U" Logic.lCMat(e1, diagU2N(e2), isOR=isOR) } else { ## differing triangle (upper *and* lower): if(isOR) # both triangles => "general" Logic.lCMat(.M2gen(e1), .M2gen(e2), isOR=TRUE) else { ## have '&': all FALSE apart from diagonal d <- .Ops.checkDim(dim(e1), dim(e2)) .diag2sparse(new("ldiMatrix", Dim = d, x = get(.Generic)(diag(e1), diag(e2))), kind = ".", shape = "t", repr = "C", uplo = e1@uplo) } } }) ## Now the other "Ops" for the "lgT" and "lgC" cases: setMethod("Arith", signature(e1="lgCMatrix", e2="lgCMatrix"), Ops.x.x.via.d) setMethod("Arith", signature(e1="lgTMatrix", e2="lgTMatrix"), Ops.x.x.via.d) rm(Ops.x.x.via.d) ## More generally: Arith: l* and n* via d* setMethod("Arith", signature(e1="lsparseMatrix", e2="Matrix"), function(e1, e2) callGeneric(.M2kind(e1, "d"), as(e2,"dMatrix"))) setMethod("Arith", signature(e1="Matrix", e2="lsparseMatrix"), function(e1, e2) callGeneric(as(e1,"dMatrix"), .M2kind(e2, "d"))) setMethod("Arith", signature(e1="nsparseMatrix", e2="Matrix"), function(e1, e2) callGeneric(.M2kind(e1, "d"), as(e2,"dMatrix"))) setMethod("Arith", signature(e1="Matrix", e2="nsparseMatrix"), function(e1, e2) callGeneric(as(e1,"dMatrix"), .M2kind(e2, "d"))) ## for(cl in c("numeric", "logical")) # "complex", "raw" : basically "replValue" for(Mcl in c("lMatrix", "nMatrix")) { setMethod("Arith", signature(e1=Mcl, e2=cl), function(e1, e2) callGeneric(as(e1, "dMatrix"), e2)) setMethod("Arith", signature(e1=cl, e2=Mcl), function(e1, e2) callGeneric(e1, as(e2,"dMatrix"))) } rm(cl, Mcl) ## FIXME: These are really too cheap: currently almost all go via dgC*() : ## setMethod("Compare", signature(e1="lgCMatrix", e2="lgCMatrix"), ## setMethod("Compare", signature(e1="lgTMatrix", e2="lgTMatrix"), ## setMethod("Compare", signature(e1="lsparseMatrix", e2="lsparseMatrix"), ## function(e1, e2) callGeneric(as(e1, "dgCMatrix"), ## as(e2, "dgCMatrix"))) ##. Have "Ops" below which only goes *conditionally* via Csparse ##.setMethod("Compare", signature(e1="lsparseMatrix", e2="lsparseMatrix"), ##. function(e1, e2) callGeneric(as(e1, "CsparseMatrix"), ##. as(e2, "CsparseMatrix"))) ## setMethod("Compare", signature(e1="lgTMatrix", e2="lgTMatrix"), ## function(e1, e2) callGeneric(as(e1, "dgCMatrix"), ## as(e2, "dgCMatrix"))) ###--- Sparse ... ---------- setMethod("Ops", signature(e1="lsparseMatrix", e2="lsparseMatrix"), function(e1,e2) callGeneric(as(e1, "CsparseMatrix"), as(e2, "CsparseMatrix"))) setMethod("Logic", signature(e1="lsparseMatrix", e2="ldenseMatrix"), function(e1,e2) callGeneric(as(e1, "generalMatrix"), as(e2, "sparseMatrix"))) setMethod("Logic", signature(e1="ldenseMatrix", e2="lsparseMatrix"), function(e1,e2) callGeneric(as(e1, "sparseMatrix"), as(e2, "generalMatrix"))) setMethod("Logic", signature(e1="lsparseMatrix", e2="lsparseMatrix"), function(e1,e2) { if(!is(e1,"generalMatrix")) callGeneric(as(.M2gen(e1), "CsparseMatrix"), e2) else if(!is(e2,"generalMatrix")) callGeneric(e1, as(.M2gen(e2), "CsparseMatrix")) else # both are general, i.e. lg[CRT] callGeneric(as(e1, "CsparseMatrix"), as(e2, "CsparseMatrix")) }) ## FIXME: also want (symmetric o symmetric) , (triangular o triangular) ## ----- setMethod("Arith", signature(e1 = "dsCMatrix", e2 = "dsCMatrix"), function(e1, e2) { Matrix.message("suboptimal 'Arith' implementation of 'dsC* o dsC*'") forceSymmetric(callGeneric(.M2gen(e1), .M2gen(e2))) }) ##-------- originally from ./dgCMatrix.R -------------------- .Arith.Csparse <- function(e1, e2, Generic, class., triangular = FALSE, check.dimnames = TRUE) { ## Generic is one of "+", "-", "*", "^", "%%", "%/%", "/" ## triangular: TRUE iff e1,e2 are triangular _and_ e1@uplo == e2@uplo d <- .Ops.checkDim(dim(e1), dim(e2)) dn <- .Ops.checkDimNames(dimnames(e1), dimnames(e2), check = check.dimnames) if(triangular) { ## need these for the 'x' slots in any case e1 <- .Call(R_sparse_diag_U2N, e1) e2 <- .Call(R_sparse_diag_U2N, e2) ## slightly more efficient than non0.i() or non0ind(): ij1 <- .Call(compressed_non_0_ij, e1, isC=TRUE) ij2 <- .Call(compressed_non_0_ij, e2, isC=TRUE) newTMat <- function(i,j,x) new("dtTMatrix", Dim = d, Dimnames = dn, i = i, j = j, x = x, uplo = e1@uplo) } else { cld <- getClassDef(class.) ij1 <- non0ind(e1, cld) ij2 <- non0ind(e2, cld) newTMat <- function(i,j,x) new("dgTMatrix", Dim = d, Dimnames = dn, i = i, j = j, x = x) } switch(Generic, "+" = , "-" = { ## care for over-allocated 'x' slot: nc1 <- d[2] + 1L if((nz <- e1@p[nc1]) < length(e1@x)) e1@x <- e1@x[seq_len(nz)] if((nz <- e2@p[nc1]) < length(e2@x)) e2@x <- e2@x[seq_len(nz)] ## special "T" convention: repeated entries are *summed* .M2C(newTMat(i = c(ij1[,1], ij2[,1]), j = c(ij1[,2], ij2[,2]), x = if(Generic == "+") c(e1@x, e2@x) else c(e1@x, - e2@x))) }, "*" = { ## X * 0 == 0 * X == 0 --> keep common non-0 ii <- WhichintersectInd(ij1, ij2, di=d) ij <- ij1[ii[[1]], , drop = FALSE] .M2C(newTMat(i = ij[,1], j = ij[,2], x = e1@x[ii[[1]]] * e2@x[ii[[2]]])) }, "^" = { ii <- WhichintersectInd(ij1, ij2, di=d) ## 3 cases: ## 1) X^0 := 1 (even for X=0) ==> dense ## 2) 0^Y := 0 for Y != 0 ===== ## 3) x^y : ## FIXME: dgeM[cbind(i,j)] <- V is not yet possible ## nor dgeM[ i_vect ] <- V ## r <- as(e2, "dgeMatrix") ## ... r <- as(e2, "matrix") Yis0 <- is0(r) r[complementInd(ij1, dim=d)] <- 0 ## 2) r[1L + ij2[ii[[2]], , drop=FALSE]] <- e1@x[ii[[1]]] ^ e2@x[ii[[2]]] ## 3) r[Yis0] <- 1 ## 1) if(triangular) .m2dense(r, "dtr", e1@uplo, "N") else .m2dense(r, "dge", NULL, NULL) }, "%%" = , "%/%" = , "/" = ## 0 op 0 |-> NaN => dense { get(Generic)(as(e1, "unpackedMatrix"), e2) }) # end{switch(..)} } setMethod("Arith", signature(e1 = "dgCMatrix", e2 = "dgCMatrix"), function(e1,e2) .Arith.Csparse(e1,e2, .Generic, class.= "dgCMatrix")) setMethod("Arith", signature(e1 = "dtCMatrix", e2 = "dtCMatrix"), function(e1, e2) { U1 <- e1@uplo ## will the result definitely be triangular? isTri <- U1 == e2@uplo && .Generic != "^" if(isTri) .Arith.Csparse(e1,e2, .Generic, class. = "dtCMatrix", triangular = TRUE) else # lowerTri o upperTri: |--> "all 0" {often} -- FIXME? .Arith.Csparse(.M2gen(e1), .M2gen(e2), .Generic, class.= "dgCMatrix") }) ## TODO : Consider going a level up, and do this for all "Ops" ## ## NB: For "dgCMatrix" have special method ==> this is for dsC*, lgC*, ... ## now also for Tsparse etc {*must* as method directly: "callGeneric()"} .Arith.CM.atom <- function(e1, e2) { if(length(e2) == 1) { ## e.g., Mat ^ a f0 <- callGeneric(0, e2) if(is0(f0)) { ## remain sparse, symm., tri.,... e1 <- .M2kind(e1, "d") if(!extends(cld <- getClassDef(class(e1)), "CsparseMatrix")) cld <- getClassDef(class(e1 <- as(e1, "CsparseMatrix"))) if(extends(cld, "triangularMatrix") && e1@diag == "U" && !all(1 == callGeneric(1, e2))) e1 <- .diagU2N(e1, cld) e1@x <- callGeneric(e1@x, e2) if(.hasSlot(e1, "factors") && length(e1@factors)) e1@factors <- list() return(e1) } } ## all other (potentially non-sparse) cases: give up symm, tri,.. callGeneric(as(.M2gen(.M2kind(e1, "d")), "CsparseMatrix"), e2) } ## The same, e1 <-> e2 : .Arith.atom.CM <- function(e1, e2) { if(length(e1) == 1) { f0 <- callGeneric(e1, 0) if(is0(f0)) { e2 <- .M2kind(e2, "d") if(!extends(cld <- getClassDef(class(e2)), "CsparseMatrix")) cld <- getClassDef(class(e2 <- as(e2, "CsparseMatrix"))) if(extends(cld, "triangularMatrix") && e2@diag == "U" && !all(1 == callGeneric(e1, 1))) e2 <- .diagU2N(e2, cld) e2@x <- callGeneric(e1, e2@x) if(.hasSlot(e2, "factors") && length(e2@factors)) e2@factors <- list() return(e2) } } callGeneric(e1, as(.M2gen(.M2kind(e2, "d")), "CsparseMatrix")) } setMethod("Arith", signature(e1 = "CsparseMatrix", e2 = "numeric"), .Arith.CM.atom) setMethod("Arith", signature(e1 = "numeric", e2 = "CsparseMatrix"), .Arith.atom.CM) ##' compute indices for recycling of length 'len' ##' to match sparseMatrix 'spM' .Ops.recycle.ind <- function(spM, len) { n <- prod(d <- dim(spM)) if(n && n < len) stop("vector too long in Matrix - vector operation") if(n %% len != 0) ## identical warning as in main/arithmetic.c warning("longer object length\n\tis not a multiple of shorter object length") ## TODO(speedup!): construction of [1L + in0 %%len] via one .Call() in0 <- .Call(m_encodeInd, .Call(compressed_non_0_ij, spM, TRUE), d, FALSE, FALSE) 1L + in0 %% len } A.M.n <- function(e1, e2) { if((l2 <- length(e2)) == 0) # return 0-vector of e1's kind, as matrix()+<0> return(if(length(e1)) vector(.type.kind[.M.kind(e1)]) else e1) is0f <- is0(f0 <- callGeneric(0, e2)) # if(all(is0f)) { ## result keeps sparseness structure of e1 if(l2 > 1) { # "recycle" e2 "carefully" e2 <- e2[.Ops.recycle.ind(e1, len = l2)] } e1@x <- callGeneric(e1@x, e2) if(length(e1@factors)) e1@factors <- list() e1 } else if(mean(is0f) > 7/8) { ## remain sparse ['7/8' is *somewhat* arbitrary] if(l2 > 1) ## as not all callGeneric(0, e2) is 0, e2 is typically sparse callGeneric(e1, as(e2, "sparseVector")) else { ## l2 == 1: e2 is "scalar" e1@x <- callGeneric(e1@x, e2) if(length(e1@factors)) e1@factors <- list() e1 } } else { ## non-sparse, since '0 o e2' is not (all) 0 r <- as(e1, "matrix") if(l2 == 1) { r[] <- f0 r[non0ind(e1, getClassDef("dgCMatrix")) + 1L] <- callGeneric(e1@x, e2) .m2dense(r, "dge", NULL, NULL) } else { .m2dense(callGeneric(r, e2), "dge", NULL, NULL) } } } setMethod("Arith", signature(e1 = "dgCMatrix", e2 = "numeric"), A.M.n) setMethod("Arith", signature(e1 = "dgCMatrix", e2 = "logical"), A.M.n) ## coercing to "general*" / "dgC*" would e.g. lose symmetry of 'S * 3' setMethod("Arith", signature(e1 = "dsparseMatrix", e2 = "numeric"), .Arith.CM.atom) setMethod("Arith", signature(e1 = "dsparseMatrix", e2 = "logical"), .Arith.CM.atom) A.n.M <- function(e1, e2) { if((l1 <- length(e1)) == 0) ## return 0-vector of e2's kind, as <0> + matrix() return(if(length(e2)) vector(.type.kind[.M.kind(e2)]) else e2) is0f <- is0(f0 <- callGeneric(e1, 0)) if(all(is0f)) { ## result keeps sparseness structure of e2 if(l1 > 1) { # "recycle" e1 "carefully" e1 <- e1[.Ops.recycle.ind(e2, len = l1)] } e2@x <- callGeneric(e1, e2@x) if(length(e2@factors)) e2@factors <- list() e2 } else if(mean(is0f) > 7/8) { ## remain sparse ['7/8' is *somewhat* arbitrar if(l1 > 1) ## as not all callGeneric(e1, 0) is 0, e1 is typically sparse callGeneric(as(e1, "sparseVector"), e2) else { ## l1 == 1: e1 is "scalar" e2@x <- callGeneric(e1, e2@x) if(length(e2@factors)) e2@factors <- list() e2 } } else { ## non-sparse, since '0 o e2' is not (all) 0 r <- as(e2, "matrix") if(l1 == 1) { r[] <- f0 r[non0ind(e2, getClassDef("dgCMatrix")) + 1L] <- callGeneric(e1, e2@x) .m2dense(r, "dge", NULL, NULL) } else { .m2dense(callGeneric(e1, r), "dge", NULL, NULL) } } } setMethod("Arith", signature(e1 = "numeric", e2 = "dgCMatrix"), A.n.M) setMethod("Arith", signature(e1 = "logical", e2 = "dgCMatrix"), A.n.M) ## coercing to "general*" / "dgC*" would e.g. lose symmetry of '3 * S' setMethod("Arith", signature(e1 = "numeric", e2 = "dsparseMatrix"), .Arith.atom.CM) setMethod("Arith", signature(e1 = "logical", e2 = "dsparseMatrix"), .Arith.atom.CM) rm(A.M.n, A.n.M, .Arith.atom.CM, .Arith.CM.atom) ##-------- originally from ./dgTMatrix.R -------------------- ## Uses the triplet convention of *adding* entries with same (i,j): setMethod("+", signature(e1 = "dgTMatrix", e2 = "dgTMatrix"), function(e1, e2) { .Ops.checkDim(dim(e1), dim(e2)) new("dgTMatrix", i = c(e1@i, e2@i), j = c(e1@j, e2@j), x = c(e1@x, e2@x), Dim = e1@Dim, Dimnames = e1@Dimnames) }) ##-------- originally from ./Csparse.R -------------------- setMethod("Arith", signature(e1 = "CsparseMatrix", e2 = "CsparseMatrix"), function(e1, e2) { ## go via "symmetric" if both are symmetric, etc... s1 <- .M.shape(e1) s2 <- .M.shape(e2) ## as(*, "d.CMatrix") is deprecated: ## viaCl <- paste0("d", if(s1 == s2) s1 else "g", "CMatrix") if(s1 != s2) ## go via "general" callGeneric(.M2gen(.M2kind(e1, "d")), .M2gen(.M2kind(e2, "d"))) else callGeneric(.M2kind(e1, "d"), .M2kind(e2, "d")) }) setMethod("Logic", signature(e1 = "CsparseMatrix", e2 = "CsparseMatrix"), ## go via "symmetric" if both are symmetric, etc... function(e1, e2) { s1 <- .M.shape(e1) s2 <- .M.shape(e2) ## as(*, "d.CMatrix") is deprecated: ## viaCl <- paste0("l", if(s1 == s2) s1 else "g", "CMatrix") if(s1 != s2) ## go via "general" callGeneric(.M2gen(.M2kind(e1, "l")), .M2gen(.M2kind(e2, "l"))) else callGeneric(.M2kind(e1, "l"), .M2kind(e2, "l")) }) setMethod("Compare", signature(e1 = "CsparseMatrix", e2 = "CsparseMatrix"), function(e1, e2) { d <- .Ops.checkDim(dim(e1), dim(e2)) ## How do the "0" or "FALSE" entries compare? ## Depends if we have an "EQuality RELation" or not: EQrel <- switch(.Generic, "==" =, "<=" =, ">=" = TRUE, "!=" =, "<" =, ">" = FALSE) if(EQrel) { ## The (0 op 0) or (FALSE op FALSE) comparison gives TRUE ## -> result becomes *dense*; the following may be suboptimal return(callGeneric(.sparse2dense(e1), .sparse2dense(e2))) } ## else: INequality: 0 op 0 gives FALSE ---> remain sparse! cD1 <- getClassDef(class(e1)) cD2 <- getClassDef(class(e2)) Matrix.message(sprintf("Compare -- \"%s\" %s \"%s\" :\n", cD1@className, .Generic, cD2@className), .M.level = 2) ## NB non-diagonalMatrix := Union{ general, symmetric, triangular} gen1 <- extends(cD1, "generalMatrix") gen2 <- extends(cD2, "generalMatrix") sym1 <- !gen1 && extends(cD1, "symmetricMatrix") sym2 <- !gen2 && extends(cD2, "symmetricMatrix") tri1 <- !gen1 && !sym1 tri2 <- !gen2 && !sym2 G <- gen1 && gen2 S <- sym1 && sym2 && e1@uplo == e2@uplo T <- tri1 && tri2 && e1@uplo == e2@uplo if(T && e1@diag != e2@diag) { ## one is "U" the other "N" if(e1@diag == "U") e1 <- diagU2N(e1) else ## (e2@diag == "U" e2 <- diagU2N(e2) shape <- "t" } else if(!G && !S && !T) { ## e.g. one symmetric, one general ## coerce to generalMatrix and go : if(!gen1) e1 <- .M2gen(e1) if(!gen2) e2 <- .M2gen(e2) shape <- "g" } else { shape <- if(T) "t" else if(S) "s" else "g" } dn <- .Ops.checkDimNames(dimnames(e1), dimnames(e2)) ## ^^ FIXME: for 'S'; allow staying ## the result object: newC <- sub("^.", "l", MatrixClass(class(e1))) ## FIXME: "n" result when e1 & e2 are "n", ## or even whenever possible r <- new(newC) e1is.n <- extends(cD1, "nMatrix") e2is.n <- extends(cD2, "nMatrix") ## Easy case: identical sparsity pattern if(identical(e1@i, e2@i) && identical(e1@p, e2@p)) { if(e1is.n) { if(e2is.n) ## non-equality of identical pattern matrices: ## all FALSE r@p <- rep.int(0L, d[2]+1L) # and r@i, r@x remain empty else { # e1 pattern, e2@x rx <- callGeneric(TRUE, e2@x) if(allFalse(rx)) r@p <- rep.int(0L, d[2]+1L) # r@i, r@x remain empty else { r@x <- rx r@i <- e2@i r@p <- e2@p } } } else if(e2is.n) { ## e1@x, e2 pattern rx <- callGeneric(e1@x, TRUE) if(allFalse(rx)) r@p <- rep.int(0L, d[2]+1L) # and r@i, r@x remain empty else { r@x <- rx r@i <- e1@i r@p <- e1@p } } else { # both have 'x' slot r@x <- callGeneric(e1@x, e2@x) ## and all others are '0 op 0' which give FALSE r@i <- e1@i r@p <- e1@p } r@Dim <- d r@Dimnames <- dn r } else { ## now the 'x' slots ``match'' insofar as they are for the ## same "space" (triangle for tri* and symm*; else rectangle) ## not non0ind() which gives more; ## want only those which correspond to 'x' slot ij1 <- .Call(compressed_non_0_ij, e1, TRUE) ij2 <- .Call(compressed_non_0_ij, e2, TRUE) ii <- WhichintersectInd(ij1, ij2, di=d) I1 <- ii[[1]]; has1 <- length(I1) > 0 I2 <- ii[[2]]; has2 <- length(I2) > 0 ## potentially could be faster for 'nsparse' ## but this is simple: e1x <- if(e1is.n) rep.int(1L, length(e1@i)) else e1@x e2x <- if(e2is.n) rep.int(1L, length(e2@i)) else e2@x ## 1) common x <- callGeneric(e1x[I1], e2x[I2]) ## 2) "e1 o 0": x2 <- callGeneric(if(has1) e1x[- I1] else e1x, 0) ## 3) "0 o e2": x3 <- callGeneric(0, if(has2) e2x[- I2] else e2x) i <- c(ij1[I1, 1], if(has1) ij1[-I1, 1] else ij1[, 1], if(has2) ij2[-I2, 1] else ij2[, 1]) j <- c(ij1[I1, 2], if(has1) ij1[-I1, 2] else ij1[, 2], if(has2) ij2[-I2, 2] else ij2[, 2]) x <- c(x, x2, x3) if(any(i0x <- is0(x))) { # drop 'FALSE's n0 <- !i0x i <- i[n0] j <- j[n0] x <- x[n0] } .M2C(if(e1is.n && e2is.n) new(paste0("n",shape,"TMatrix"), Dim = d, Dimnames = dn, i = i, j = j) else if(!S && !T) new(paste0("l",shape,"TMatrix"), Dim = d, Dimnames = dn, i = i, j = j, x = x) else # S or T new(paste0("l",shape,"TMatrix"), Dim = d, Dimnames = dn, i = i, j = j, x = x, uplo = e1@uplo)) } }) ##-------- originally from ./sparseMatrix.R -------------------- ## "Arith" short cuts / exceptions setMethod("-", signature(e1 = "sparseMatrix", e2 = "missing"), function(e1, e2) { e1 <- diagU2N(e1) e1@x <- -e1@x if(.hasSlot(e1, "factors") && length(e1@factors)) e1@factors <- list() e1 }) ## with the following exceptions: setMethod("-", signature(e1 = "nsparseMatrix", e2 = "missing"), function(e1, e2) -.M2kind(e1, "d")) setMethod("-", signature(e1 = "indMatrix", e2 = "missing"), function(e1, e2) -as(e1, "dsparseMatrix")) ## Group method "Arith" ## have CsparseMatrix methods above ## which may preserve "symmetric", "triangular" -- simply defer to those: setMethod("Ops", signature(e1 = "sparseMatrix", e2 = "nsparseMatrix"), function(e1, e2) callGeneric(as(e1, "CsparseMatrix"), .M2kind(e2, "l"))) setMethod("Ops", signature(e1 = "nsparseMatrix", e2 = "sparseMatrix"), function(e1, e2) callGeneric(.M2kind(e1, "l"), as(e2, "CsparseMatrix"))) ## these were 'Arith', now generalized: if(FALSE) { ## just shifts the ambiguity warnings .. ## o more complicated - against PITA disambiguation warnings: setMethod("Ops", signature(e1 = "TsparseMatrix", e2 = "TsparseMatrix"), function(e1, e2) callGeneric(as(e1, "CsparseMatrix"), as(e2, "CsparseMatrix"))) setMethod("Ops", signature(e1 = "TsparseMatrix", e2 = "CsparseMatrix"), function(e1, e2) callGeneric(as(e1, "CsparseMatrix"), e2)) setMethod("Ops", signature(e1 = "CsparseMatrix", e2 = "TsparseMatrix"), function(e1, e2) callGeneric(e1, as(e2, "CsparseMatrix"))) } ## catch the rest: Rsparse* and T* o R* setMethod("Ops", signature(e1 = "sparseMatrix", e2 = "sparseMatrix"), function(e1, e2) callGeneric(as(e1, "CsparseMatrix"), as(e2, "CsparseMatrix"))) setMethod("Ops", signature(e1 = "sparseMatrix", e2 = "numeric"), function(e1, e2) callGeneric(as(e1, "CsparseMatrix"), e2)) setMethod("Ops", signature(e1 = "numeric", e2 = "sparseMatrix"), function(e1, e2) callGeneric(e1, as(e2, "CsparseMatrix"))) ## setMethod("Compare", signature(e1 = "sparseMatrix", e2 = "sparseMatrix"), ## function(e1, e2) callGeneric(as(e1, "CsparseMatrix"), ## as(e2, "CsparseMatrix"))) ###-------- sparseVector ------------- ###-------- ============ ------------- ## Catch all remaining setMethod("Ops", signature(e1 = "sparseVector", e2 = "ANY"), function(e1, e2) .bail.out.2(.Generic, class(e1), class(e2))) setMethod("Ops", signature(e1 = "ANY", e2 = "sparseVector"), function(e1, e2) .bail.out.2(.Generic, class(e1), class(e2))) ## 1) spVec o (sp)Vec : ------------- ## FIXME: ## 2. o should also happen directly and ## |-> sparse for o = {'*', "/", '&&', '==', ... setMethod("Ops", signature(e1 = "sparseVector", e2 = "atomicVector"), function(e1, e2) { if(length(e2) == 1) { ## scalar ------ special case - "fast" if(all0(callGeneric(FALSE, e2))) { # result remains sparse if(is(e1, "nsparseVector")) { # no 'x' slot, i.e. all TRUE r <- callGeneric(TRUE, e2) if(is.logical(r)) { if(isTRUE(all(r))) # (could be NA) e1 # result unchanged else newSpVec("lsparseVector", x = r, e1) } else { newSpVec(paste0(if(is.integer(r)) "i" else "d", "sparseVector"), x = r, e1) } } else { # has x slot r <- callGeneric(e1@x, e2) if(identical(class(r), class(e1@x))) { e1@x <- r e1 } else { newSpVec(paste0(.M.kind(r), "sparseVector"), x = r, e1) } } } else ## non-sparse result callGeneric(sp2vec(e1), e2) } else ## e2 is not scalar callGeneric(e1, as(e2, "sparseVector")) }) setMethod("Ops", signature(e1 = "atomicVector", e2 = "sparseVector"), function(e1, e2) { if(length(e1) == 1) { ## scalar ------ special case - "fast" if(all0(callGeneric(e1, FALSE))) { # result remains sparse if(is(e2, "nsparseVector")) { # no 'x' slot, i.e. all TRUE r <- callGeneric(e1, TRUE) if(is.logical(r)) { if(isTRUE(all(r))) # (could be NA) e2 # result unchanged else newSpVec("lsparseVector", x = r, e2) } else { newSpVec(paste0(if(is.integer(r)) "i" else "d", "sparseVector"), x = r, e2) } } else { # has x slot r <- callGeneric(e1, e2@x) if(identical(class(r), class(e2@x))) { e2@x <- r e2 } else { newSpVec(paste0(.M.kind(r), "sparseVector"), x = r, e2) } } } else ## non-sparse result callGeneric(e1, sp2vec(e2)) } else ## e1 is not scalar callGeneric(as(e1, "sparseVector"), e2) }) Ops.spV.spV <- function(e1, e2) { n1 <- e1@length n2 <- e2@length if(!n1 || !n2) ## return 0-length : return(if(is.na(match(.Generic, .ArithGenerics))) logical() else numeric()) ## else n1, n2 >= 1 : if(n1 != n2) { if(n1 < n2) { n <- n1 ; N <- n2 } else { n <- n2 ; N <- n1 } if(n == 1L) { # simple case, do not really recycle if(n1 < n2) return(callGeneric(sp2vec(e1), e2)) else return(callGeneric(e1, sp2vec(e2))) } ## else : 2 <= n < N if(N %% n != 0) warning("longer object length is not a multiple of shorter object length") ## recycle the shorter one if(n1 < n2) { e1 <- rep(e1, length.out = N) } else { e2 <- rep(e2, length.out = N) } } else { ## n1 == n2 N <- n1 } ## ---- e1 & e2 now are both of length 'N' ---- ## First check the (0 o 0) result is1n <- extends(class(e1), "nsparseVector") is2n <- extends(class(e2), "nsparseVector") r00 <- callGeneric(if(is1n) FALSE else as0(e1@x), if(is2n) FALSE else as0(e2@x)) if(is0(r00)) { ## -> sparseVector e1x <- if(is1n) TRUE else e1@x e2x <- if(is2n) TRUE else e2@x sp <- .setparts(e1@i, e2@i) ## Idea: Modify 'e2' and return it : new.x <- c(callGeneric(e1x[sp[["ix.only"]]], 0), # e1-only callGeneric(0, e2x[sp[["iy.only"]]]), # e2-only callGeneric(e1x[sp[["my"]]], # common to both e2x[sp[["mx"]]])) i. <- c(sp[["x.only"]], sp[["y.only"]], sp[["int"]]) cl2x <- typeof(e2x) ## atomic "class"es - can use in is(), as(), too: if(!is2n && is(new.x, cl2x)) { i. <- sort.int(i., method = "quick", index.return=TRUE) e2@x <- as(new.x, cl2x)[i.$ix] e2@i <- i.$x e2 } else { newSpV(paste0(.kind.type[typeof(new.x)],"sparseVector"), x = new.x, i = i., length = e2@length) } } else { ## 0 o 0 is NOT in {0 , FALSE} --> "dense" result callGeneric(sp2vec(e1), sp2vec(e2)) } } ## {Ops.spV.spV} ## try to use it in all cases setMethod("Ops", signature(e1 = "sparseVector", e2 = "sparseVector"), Ops.spV.spV) ## was function(e1, e2) .bail.out.2(.Generic, class(e1), class(e2))) setMethod("Arith", signature(e1 = "sparseVector", e2 = "sparseVector"), function(e1, e2) callGeneric(as(e1, "dsparseVector"), as(e2, "dsparseVector"))) setMethod("Arith", signature(e1 = "dsparseVector", e2 = "dsparseVector"), Ops.spV.spV) ## "Arith" exception (shortcut) setMethod("-", signature(e1 = "dsparseVector", e2 = "missing"), function(e1) { e1@x <- -e1@x ; e1 }) setMethod("Logic", signature(e1 = "sparseVector", e2 = "sparseVector"), ## FIXME: this is suboptimal for "nsparseVector" !! function(e1, e2) callGeneric(as(e1, "lsparseVector"), as(e2, "lsparseVector"))) setMethod("Logic", signature(e1 = "lsparseVector", e2 = "lsparseVector"), Ops.spV.spV) ## "nsparse" have no 'x' slot --> version of Ops.spV.spV.. ## -------- but also for (nsp.. o lsp..) etc, when lsp... has no NA if(FALSE) ### FIXME setMethod("Logic", signature(e1 = "nsparseVector", e2 = "nsparseVector"), function(e1, e2) { .bail.out.2(.Generic, class(e1), class(e2)) }) rm(Ops.spV.spV) ## 2) spVec o [Mm]atrix : ------------- Ops.M.spV <- function(e1, e2) { d <- e1@Dim n1 <- prod(d) n2 <- e2@length if(n1 != n2) { if(n1 && n1 < n2) { # 0-extent matrix + vector is fine stop(sprintf("dim [product %d] do not match the length of object [%d]", n1, n2)) } ## else n1 > n2 [vector] N <- n1 if(n2 == 1) ## simple case, do not really recycle return(callGeneric(e1, sp2vec(e2))) if(N %% n2 != 0) warning("longer object length is not a multiple of shorter object length") ## else : 2 <= n < N --- recycle the vector e2 <- rep(e2, length.out = N) } else { ## n1 == n2 N <- n1 } ## ---- e1 & e2 now are both of length 'N' ---- dim(e2) <- d #-> sparseMatrix (!) callGeneric(e1, e2) }## {Ops.M.spV} Ops.spV.M <- function(e1, e2) { n1 <- e1@length d <- e2@Dim n2 <- prod(d) if(n2 != n1) { if(n2 && n2 < n1) { # vector + 0-extent matrix is fine stop(sprintf("dim [product %d] do not match the length of object [%d]", n2, n1)) } ## else n2 > n1 [vector] N <- n2 if(n1 == 1) ## simple case, do not really recycle return(callGeneric(sp2vec(e1), e2)) if(N %% n1 != 0) warning("longer object length is not a multiple of shorter object length") ## else : 2 <= n < N --- recycle the vector e1 <- rep(e1, length.out = N) } else { ## n2 == n1 N <- n2 } ## ---- e2 & e1 now are both of length 'N' ---- dim(e1) <- d #-> sparseMatrix (!) callGeneric(e1, e2) }## {Ops.spV.M} ## try to use it in all cases setMethod("Ops", signature(e1 = "Matrix", e2 = "sparseVector"), Ops.M.spV) setMethod("Ops", signature(e1 = "sparseVector", e2 = "Matrix"), Ops.spV.M) rm(Ops.M.spV, Ops.spV.M) ###---------------- diagonalMatrix ---------------------- .diag2tT.smart <- function(from, x, kind = ".") { shape <- .M.shape(x) uplo <- if(shape == "t") x@uplo else "U" .diag2sparse(from, kind, "t", "T", uplo) } .diag2T.smart <- function(from, x, kind = ".") { shape <- .M.shape(x) uplo <- if(shape == "s" || shape == "t") x@uplo else "U" .diag2sparse(from, kind, if(shape == "s") "s" else "t", "T", uplo) } .diag.x <- function(m) if(m@diag != "N") rep.int(as1(m@x), m@Dim[1L]) else m@x ..diag.x <- function(m) rep.int(as1(m@x), m@Dim[1L]) ## Use as S4 method for several signatures ==> using callGeneric() diagOdiag <- function(e1,e2) { ## result should also be diagonal _ if possible _ r <- callGeneric(.diag.x(e1), .diag.x(e2)) # error if not "compatible" ## Check what happens with non-diagonals, i.e. (0 o 0), (FALSE o 0), ...: r00 <- callGeneric(if(is.numeric(e1@x)) 0 else FALSE, if(is.numeric(e2@x)) 0 else FALSE) if(is0(r00)) { ## r00 == 0 or FALSE --- result *is* diagonal if(is.numeric(r)) { # "double" *or* "integer" if(!is.double(r)) r <- as.double(r) if(is.double(e2@x)) { e2@x <- r e2@diag <- "N" return(e2) } if(!is.double(e1@x)) ## e.g. e1, e2 are logical; e1 <- .M2kind(e1, "d") } else if(is.logical(r)) e1 <- .M2kind(e1, "l") else stop(gettextf("intermediate 'r' is of type %s", typeof(r)), domain=NA) e1@x <- r e1@diag <- "N" e1 } else { ## result not diagonal, but at least symmetric: ## e.g., m == m isNum <- (is.numeric(r) || is.numeric(r00)) isLog <- (is.logical(r) || is.logical(r00)) Matrix.message("exploding o into dense matrix", .M.level = 2) d <- e1@Dim n <- d[1L] stopifnot(length(r) == n) if(isNum && !is.double(r)) r <- as.double(r) ## faster (?) than m <- matrix(r00,n,n); diag(m) <- r ; as.vector(m) xx <- rbind(r, matrix(r00,n,n), deparse.level=0L)[seq_len(n*n)] newcl <- paste0(if(isNum) "d" else if(isLog) { if(!anyNA(r) && !anyNA(r00)) "n" else "l" } else stop("not yet implemented .. please report"), "syMatrix") new(newcl, Dim = e1@Dim, Dimnames = e1@Dimnames, x = xx) } } ### This would be *the* way, but we get tons of "ambiguous method dispatch" ## we use this hack instead of signature x = "diagonalMatrix" : diCls <- names(getClassDef("diagonalMatrix")@subclasses) if(FALSE) { setMethod("Ops", signature(e1 = "diagonalMatrix", e2 = "diagonalMatrix"), diagOdiag) } else { ## These are just for method disambiguation: for(c1 in diCls) for(c2 in diCls) setMethod("Ops", signature(e1 = c1, e2 = c2), diagOdiag) rm(c1, c2) } rm(diagOdiag) ## diagonal o triangular |--> triangular ## diagonal o symmetric |--> symmetric ## {also when other is sparse: do these "here" -- ## before conversion to sparse, since that loses "diagonality"} diagOtri <- function(e1,e2) { ## result must be triangular r <- callGeneric(d1 <- .diag.x(e1), diag(e2)) # error if not "compatible" ## Check what happens with non-diagonals, i.e. (0 o 0), (FALSE o 0), ...: e1.0 <- if(is.numeric(d1)) 0 else FALSE r00 <- callGeneric(e1.0, if(.n2 <- is.numeric(e2[0L])) 0 else FALSE) if(is0(r00)) { ## r00 == 0 or FALSE --- result *is* triangular diag(e2) <- r ## check what happens "in the triangle" e2.2 <- if(.n2) 2 else TRUE if(!callGeneric(e1.0, e2.2) == e2.2) { # values "in triangle" can change: n <- dim(e2)[1L] it <- indTri(n, upper = (e2@uplo == "U")) e2[it] <- callGeneric(e1.0, e2[it]) } e2 } else { ## result not triangular ---> general rr <- as(e2, "generalMatrix") diag(rr) <- r rr } } setMethod("Ops", signature(e1 = "diagonalMatrix", e2 = "triangularMatrix"), diagOtri) rm(diagOtri) ## For the reverse, Ops == "Arith" | "Compare" | "Logic" ## 'Arith' := '"+"', '"-"', '"*"', '"^"', '"%%"', '"%/%"', '"/"' setMethod("Arith", signature(e1 = "triangularMatrix", e2 = "diagonalMatrix"), function(e1, e2) { ## this must only trigger for *dense* e1 switch(.Generic, "+" = `diag<-`(e1, as.double(diag(e1, names=FALSE) + .diag.x(e2))), "-" = `diag<-`(e1, as.double(diag(e1, names=FALSE) - .diag.x(e2))), "*" = { n <- e2@Dim[1L] d2 <- if(e2@diag == "U") { # unit-diagonal d <- rep.int(as1(e2@x), n) e2@x <- d e2@diag <- "N" d } else e2@x e2@x <- diag(e1) * d2 e2 }, "^" = { ## will be dense ( as ^ 0 == 1 ): e1 ^ .diag2dense(e2, ".", "g", FALSE) }, ## otherwise: callGeneric(e1, .diag2T.smart(e2, e1))) }) ## Compare --> 'swap' (e.g. e1 < e2 <==> e2 > e1 ): setMethod("Compare", signature(e1 = "triangularMatrix", e2 = "diagonalMatrix"), .Cmp.swap) ## '&' and "|' are commutative: setMethod("Logic", signature(e1 = "triangularMatrix", e2 = "diagonalMatrix"), function(e1, e2) callGeneric(e2, e1)) ## For almost everything else, diag* shall be treated "as sparse" : ## These are cheap implementations via coercion ## For disambiguation --- define this for "sparseMatrix" , then for "ANY"; ## and because we can save an .M.kind() call, we use this explicit ## "hack" for all diagonalMatrix *subclasses* instead of just "diagonalMatrix" : ## ## ddi*: setMethod("Ops", signature(e1 = "ddiMatrix", e2 = "sparseMatrix"), function(e1,e2) callGeneric(.diag2T.smart(e1, e2, kind = "d"), e2)) setMethod("Ops", signature(e1 = "sparseMatrix", e2 = "ddiMatrix"), function(e1,e2) callGeneric(e1, .diag2T.smart(e2, e1, kind = "d"))) ## ldi* setMethod("Ops", signature(e1 = "ldiMatrix", e2 = "sparseMatrix"), function(e1,e2) callGeneric(.diag2T.smart(e1, e2, kind = "l"), e2)) setMethod("Ops", signature(e1 = "sparseMatrix", e2 = "ldiMatrix"), function(e1,e2) callGeneric(e1, .diag2T.smart(e2, e1, kind = "l"))) ## Ops: Arith --> numeric : "dMatrix" ## Compare --> logical ## Logic --> logical: "lMatrix" ## Other = "numeric" : stay diagonal if possible ## ddi*: Arith: result numeric, potentially ddiMatrix for(arg2 in c("numeric","logical")) setMethod("Arith", signature(e1 = "ddiMatrix", e2 = arg2), function(e1,e2) { n <- e1@Dim[1L] if(length(e2) == 0L) return(if(n) numeric() else e1) f0 <- callGeneric(0, e2) if(all0(f0)) { # remain diagonal if(e1@diag == "U") { if(any((r <- callGeneric(1, e2)) != 1)) { e1@diag <- "N" e1@x[seq_len(n)] <- r # possibly recycling r } ## else: result = e1 (is "U" diag) } else if(n) { L1 <- (le <- length(e2)) == 1L r <- callGeneric(e1@x, e2) ## "future fixme": if we have idiMatrix, and r is 'integer', use idiMatrix e1@x[] <- if(L1) r else r[1L + ((n+1)*(0:(n-1L))) %% le] } e1 } else callGeneric(.diag2tT.smart(e1, e2, kind = "d"), e2) }) rm(arg2) for(arg1 in c("numeric","logical")) setMethod("Arith", signature(e1 = arg1, e2 = "ddiMatrix"), function(e1,e2) { n <- e2@Dim[1L] if(length(e1) == 0L) return(if(n) numeric() else e2) f0 <- callGeneric(e1, 0) if(all0(f0)) { # remain diagonal if(e2@diag == "U") { if(any((r <- callGeneric(e1, 1)) != 1)) { e2@diag <- "N" e2@x[seq_len(n)] <- r # possibly recycling r } ## else: result = e2 (is "U" diag) } else { L1 <- (le <- length(e1)) == 1L r <- callGeneric(e1, e2@x) ## "future fixme": if we have idiMatrix, and r is 'integer', use idiMatrix e2@x[] <- if(L1) r else r[1L + ((n+1)*(0:(n-1L))) %% le] } e2 } else callGeneric(e1, .diag2tT.smart(e2, e1, kind = "d")) }) rm(arg1) ## ldi* Arith --> result numeric, potentially ddiMatrix for(arg2 in c("numeric","logical")) setMethod("Arith", signature(e1 = "ldiMatrix", e2 = arg2), function(e1,e2) { n <- e1@Dim[1L] if(length(e2) == 0L) return(if(n) numeric() else copyClass(e1, "ddiMatrix", c("diag", "Dim", "Dimnames"), check=FALSE)) f0 <- callGeneric(0, e2) if(all0(f0)) { # remain diagonal E <- copyClass(e1, "ddiMatrix", c("diag", "Dim", "Dimnames"), check=FALSE) ## storage.mode(E@x) <- "double" if(e1@diag == "U") { if(any((r <- callGeneric(1, e2)) != 1)) { E@diag <- "N" E@x[seq_len(n)] <- r # possibly recycling r } ## else: result = E (is "U" diag) } else if(n) { L1 <- (le <- length(e2)) == 1L r <- callGeneric(e1@x, e2) ## "future fixme": if we have idiMatrix, and r is 'integer', use idiMatrix E@x[seq_len(n)] <- if(L1) r else r[1L + ((n+1)*(0:(n-1L))) %% le] } E } else callGeneric(.diag2tT.smart(e1, e2, kind = "l"), e2) }) rm(arg2) for(arg1 in c("numeric","logical")) setMethod("Arith", signature(e1 = arg1, e2 = "ldiMatrix"), function(e1,e2) { n <- e2@Dim[1L] if(length(e1) == 0L) return(if(n) numeric() else copyClass(e2, "ddiMatrix", c("diag", "Dim", "Dimnames"), check=FALSE)) f0 <- callGeneric(e1, 0) if(all0(f0)) { # remain diagonal E <- copyClass(e2, "ddiMatrix", c("diag", "Dim", "Dimnames"), check=FALSE) ## storage.mode(E@x) <- "double" if(e2@diag == "U") { if(any((r <- callGeneric(e1, 1)) != 1)) { E@diag <- "N" E@x[seq_len(n)] <- r # possibly recycling r } ## else: result = E (is "U" diag) } else if(n) { L1 <- (le <- length(e1)) == 1L r <- callGeneric(e1, e2@x) ## "future fixme": if we have idiMatrix, ## and r is 'integer', use idiMatrix E@x[seq_len(n)] <- if(L1) r else r[1L + ((n+1)*(0:(n-1L))) %% le] } E } else callGeneric(e1, .diag2tT.smart(e2, e1, kind = "l")) }) rm(arg1) ## ddi*: for "Ops" without "Arith": or --> result logical, potentially ldi ## ## Note that ("numeric", "ddiMatrix") is simply swapped, e.g., if(FALSE) { selectMethod("<", c("numeric","lMatrix"))# Compare selectMethod("&", c("numeric","lMatrix"))# Logic } ## so we don't need to define a method here : for(arg2 in c("numeric","logical")) setMethod("Ops", signature(e1 = "ddiMatrix", e2 = arg2), function(e1,e2) { n <- e1@Dim[1L] if(length(e2) == 0L) return(if(n) logical() else copyClass(e1, "ldiMatrix", c("diag", "Dim", "Dimnames"), check=FALSE)) f0 <- callGeneric(0, e2) if(all0(f0)) { # remain diagonal E <- copyClass(e1, "ldiMatrix", c("diag", "Dim", "Dimnames"), check=FALSE) ## storage.mode(E@x) <- "logical" if(e1@diag == "U") { if(any((r <- callGeneric(1, e2)) != 1)) { E@diag <- "N" E@x[seq_len(n)] <- r # possibly recycling r } ## else: result = E (is "U" diag) } else if(n) { L1 <- (le <- length(e2)) == 1L r <- callGeneric(e1@x, e2) ## "future fixme": if we have idiMatrix, ### and r is 'integer', use idiMatrix E@x[seq_len(n)] <- if(L1) r else r[1L + ((n+1)*(0:(n-1L))) %% le] } E } else callGeneric(.diag2tT.smart(e1, e2, kind = "d"), e2) }) rm(arg2) ## ldi*: for "Ops" without "Arith": or --> result logical, potentially ldi for(arg2 in c("numeric","logical")) setMethod("Ops", signature(e1 = "ldiMatrix", e2 = arg2), function(e1,e2) { n <- e1@Dim[1L] if(length(e2) == 0L) return(if(n) logical() else e1) f0 <- callGeneric(FALSE, e2) if(all0(f0)) { # remain diagonal if(e1@diag == "U") { if(any((r <- callGeneric(TRUE, e2)) != 1)) { e1@diag <- "N" e1@x[seq_len(n)] <- r # possibly recycling r } ## else: result = e1 (is "U" diag) } else if(n) { L1 <- (le <- length(e2)) == 1L r <- callGeneric(e1@x, e2) ## "future fixme": if we have idiMatrix, ## and r is 'integer', use idiMatrix e1@x[] <- if(L1) r else r[1L + ((n+1)*(0:(n-1L))) %% le] } e1 } else callGeneric(.diag2tT.smart(e1, e2, kind = "l"), e2) }) rm(arg2) ## Not {"sparseMatrix", "numeric} : {"denseMatrix", "matrix", ... } for(other in c("ANY", "Matrix", "dMatrix")) { ## ddi*: setMethod("Ops", signature(e1 = "ddiMatrix", e2 = other), function(e1,e2) callGeneric(.diag2T.smart(e1, e2, kind="d"), e2)) setMethod("Ops", signature(e1 = other, e2 = "ddiMatrix"), function(e1,e2) callGeneric(e1, .diag2T.smart(e2, e1, kind="d"))) ## ldi*: setMethod("Ops", signature(e1 = "ldiMatrix", e2 = other), function(e1,e2) callGeneric(.diag2T.smart(e1, e2, kind="l"), e2)) setMethod("Ops", signature(e1 = other, e2 = "ldiMatrix"), function(e1,e2) callGeneric(e1, .diag2T.smart(e2, e1, kind="l"))) } rm(other) ## Direct subclasses of "denseMatrix": currently ddenseMatrix, ldense... : if(FALSE) # now also contains "geMatrix" dense.subCl <- local({ dM.scl <- getClassDef("denseMatrix")@subclasses names(dM.scl)[vapply(dM.scl, slot, 0, "distance") == 1] }) dense.subCl <- paste0(c("d","l","n"), "denseMatrix") for(DI in diCls) { dMeth <- if(extends(DI, "dMatrix")) function(e1,e2) callGeneric(.diag2T.smart(e1, e2, kind = "d"), e2) else # "lMatrix", the only other kind for now function(e1,e2) callGeneric(.diag2T.smart(e1, e2, kind = "l"), e2) for(c2 in c(dense.subCl, "Matrix")) { for(Fun in c("*", "&")) { setMethod(Fun, signature(e1 = DI, e2 = c2), function(e1,e2) callGeneric(e1, Diagonal(x = diag(e2)))) setMethod(Fun, signature(e1 = c2, e2 = DI), function(e1,e2) callGeneric(Diagonal(x = diag(e1)), e2)) } setMethod("^", signature(e1 = c2, e2 = DI), function(e1,e2) callGeneric(Diagonal(x = diag(e1)), e2)) for(Fun in c("%%", "%/%", "/")) ## 0 0 |--> NaN for these. setMethod(Fun, signature(e1 = DI, e2 = c2), dMeth) } } rm(dense.subCl, DI, dMeth, c2, Fun) Matrix/R/not.R0000644000176200001440000000347014503334136012650 0ustar liggesusers## METHODS FOR GENERIC: ! (not) ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("!", signature(x = "Matrix"), function(x) !.M2kind(x, "l")) setMethod("!", signature(x = "sparseVector"), function(x) !.V2kind(x, "l")) setMethod("!", signature(x = "ndenseMatrix"), function(x) { if(.M.shape(x) == "t") x <- .M2gen(x) x@x <- { y <- x@x; if(anyNA(y)) !(y | is.na(y)) else !y } x }) setMethod("!", signature(x = "ldenseMatrix"), function(x) { if(.M.shape(x) == "t") x <- .M2gen(x) x@x <- !x@x x }) setMethod("!", signature(x = "nsparseMatrix"), function(x) { x <- .sparse2dense(if(.M.shape(x) == "t") .M2gen(x) else x) x@x <- !x@x x }) setMethod("!", signature(x = "lsparseMatrix"), function(x) { x <- .sparse2dense(if(.M.shape(x) == "t") .M2gen(x) else x) x@x <- !x@x x }) setMethod("!", signature(x = "ndiMatrix"), function(x) { if(x@diag == "N" && anyNA(y <- x@x)) x@x <- y | is.na(y) x <- .diag2dense(x, ".", "g") x@x <- !x@x x }) setMethod("!", signature(x = "ldiMatrix"), function(x) { x <- .diag2dense(x, ".", "g") x@x <- !x@x x }) setMethod("!", signature(x = "nsparseVector"), function(x) !.V2v(x)) setMethod("!", signature(x = "lsparseVector"), function(x) !.V2v(x)) setMethod("!", signature(x = "indMatrix"), function(x) { x <- .ind2dense(x) x@x <- !x@x x }) Matrix/R/Auxiliaries.R0000644000176200001440000003702014533700334014325 0ustar liggesusers#### "Namespace private" Auxiliaries such as method functions #### (called from more than one place --> need to be defined early) is0 <- function(x) !(is.na(x) | x) isN0 <- function(x) is.na(x) | x is1 <- function(x) !is.na(x) & x == 1L isN1 <- function(x) is.na(x) | x != 1L allTrue <- function(x) !is.na(a <- all( x)) && a allFalse <- function(x) if(is.atomic(x)) .Call(R_all0, x) else !is.na(a <- any( x)) && !a all0 <- function(x) if(is.atomic(x)) .Call(R_all0, x) else !is.na(a <- all(!x)) && a anyFalse <- function(x) if(is.atomic(x)) .Call(R_any0, x) else !is.na(a <- all( x)) && !a any0 <- function(x) if(is.atomic(x)) .Call(R_any0, x) else !is.na(a <- any(!x)) && a ## NB: change to using 'typeof' when we define iMatrix as1 <- function(x, mode. = mode(x)) switch(mode., "logical" = TRUE, "integer" = 1L, "double" = , "numeric" = 1, "complex" = 1+0i, stop(gettextf("invalid mode \"%s\"", mode.), domain = NA)) ## NB: change to using 'typeof' when we define iMatrix as0 <- function(x, mode. = mode(x)) switch(mode., "logical" = FALSE, "integer" = 0L, "double" = , "numeric" = 0, "complex" = 0+0i, stop(gettextf("invalid mode \"%s\"", mode.), domain = NA)) .bail.out.2 <- function(name, cl1, cl2) stop(gettextf("%s(<%s>, <%s>) is not yet implemented; ask maintainer(\"%s\") to implement the missing method", name, cl1[1L], cl2[1L], "Matrix"), call. = FALSE, domain = NA) Matrix.verbose <- function() getOption("Matrix.verbose", .MatrixEnv[["verbose"]]) Matrix.warn <- function() getOption("Matrix.warn", .MatrixEnv[["warn"]]) ## MJ: or maybe a general one? if(FALSE) { Matrix.getOption <- function(x, default = .Matrix.Env[[x]]) getOption(paste0("Matrix.", x), default) } ## MJ Matrix.message <- function(..., .M.level = 1, call. = FALSE, domain = NULL) { if(Matrix.verbose() >= .M.level) { m <- if((w <- Matrix.warn()) < 1) function(..., call., domain) message(..., domain = domain) else if(w < 2) warning else stop m(..., call. = call., domain = domain) } } ## MJ: Implement forceTriangular() and export this and that? ## MJ: Notably this provides a model for (maybe, in the future) allowing ## forceSymmetric() ... by truncating the "too long" dimension. forceDiagonal <- function(x, diag = NA_character_) { y <- diag(x, names = FALSE) # FIXME? don't allocate if diag == "U" cl <- switch(typeof(y), logical = { if(is.na(diag)) diag <- if(!is.na(a <- all(y )) && a) "U" else "N" if(.M.kind(x) == "n") "ndiMatrix" else "ldiMatrix" }, integer = { if(is.na(diag)) diag <- if(!is.na(a <- all(y == 1L )) && a) "U" else "N" storage.mode(y) <- "double" "ddiMatrix" }, ## integer = ## { ## if(is.na(diag)) ## diag <- ## if(!is.na(a <- all(y == 1L )) && a) "U" else "N" ## "idiMatrix" ## }, double = { if(is.na(diag)) diag <- if(!is.na(a <- all(y == 1 )) && a) "U" else "N" "ddiMatrix" }, complex = stop(gettextf("complex %s not yet implemented", "diagonalMatrix"), domain = NA), ## complex = ## { ## if(is.na(diag)) ## diag <- ## if(!is.na(a <- all(y == 1+0i)) && a) "U" else "N" ## "zdiMatrix" ## }, stop(gettextf("cannot coerce matrix of type \"%s\" to %s", typeof(y), "diagonalMatrix"), domain = NA)) n <- length(y) d <- dim(x) dn <- dimnames(x) %||% list(NULL, NULL) if(any(d > n)) { d <- c(n, n) w <- if(d[1L] > n) 1L else 2L if(!is.null(dnw <- dn[[w]])) dn[[w]] <- dnw[seq_len(n)] } new(cl, Dim = d, Dimnames = dn, diag = diag, x = if(diag == "N") y else y[FALSE]) } .tCRT <- function(x, lazy = TRUE) .Call(R_sparse_transpose, x, lazy) .drop0 <- function(x, tol = 0, isM = TRUE) { if(isM) return(.Call(R_sparse_drop0, x, tol)) ## TODO: write sparseVector code in C and respecting 'tol' if(.M.kind(x) == "n") return(x) x.x <- x@x k <- which(is.na(x.x) | x.x) if(length(k)) { x@i <- x@i[k] x@x <- x.x[k] } x } drop0 <- function(x, tol = 0, is.Csparse = NA, give.Csparse = TRUE) { tryCoerce <- if(give.Csparse) is.na(is.Csparse) || !is.Csparse else if(.M.kind(x) != "n") !.isCRT(x) else if(all(.M.repr(x) != c("C", "R", "T", "i"))) TRUE else return(x) # n[gst][CRT]Matrix or indMatrix if(tryCoerce) x <- if(isS4(x)) .M2C(x) else .m2sparse.checking(x, ".", "C") .Call(R_sparse_drop0, x, as.double(tol)) } indDiag <- function(n, upper = TRUE, packed = FALSE) .Call(R_index_diagonal, n, packed, upper) indTri <- function(n, upper = TRUE, diag = FALSE, packed = FALSE) .Call(R_index_triangle, n, packed, upper, diag) ## For sparseness handling, return a ## 2-column (i,j) matrix of 0-based indices of non-zero entries: ##' the workhorse for non0ind(.), but occasionally used directly non0.i <- function(M, cM = class(M), uniqT = TRUE) { cld <- getClassDef(cM) if(extends(cld, "CsparseMatrix")) .Call(compressed_non_0_ij, M, TRUE) else if(extends(cld, "RsparseMatrix")) .Call(compressed_non_0_ij, M, FALSE) else if(extends(cld, "TsparseMatrix")) { if(uniqT && !isUniqueT(M)) .Call(compressed_non_0_ij, .M2C(M), TRUE) else cbind(M@i, M@j, deparse.level = 0L) } else if(extends(cld, "diagonalMatrix")) { i <- seq.int(from = 0L, length.out = M@Dim[1L]) if(M@diag == "N") i <- i[isN0(M@x)] cbind(i, i, deparse.level = 0L) } else if(extends(cld, "indMatrix")) { perm <- M@perm i <- seq.int(from = 0L, length.out = length(perm)) if(M@margin == 1L) cbind(i, perm - 1L, deparse.level = 0L) else cbind(perm - 1L, i, deparse.level = 0L) } else stop(gettextf("non0.i() not yet implemented for class %s", dQuote(cM)), domain = NA) } ##' the "more versatile / user" function (still not exported): non0ind <- function(x, cld = getClassDef(class(x)), uniqT = TRUE, xtendSymm = TRUE, check.Udiag = TRUE) { if(is.numeric(x)) { n <- length(x) return(if(n == 0L) integer(0L) else if(is.matrix(x)) arrayInd(seq_len(n)[isN0(x)], dim(x)) - 1L else (0:(n-1L))[isN0(x)]) } stopifnot(extends(cld, "sparseMatrix")) ij <- non0.i(x, cld, uniqT = uniqT) if(xtendSymm && extends(cld, "symmetricMatrix")) { ## also get "other" triangle, but not the diagonal again notdiag <- ij[, 1L] != ij[, 2L] rbind(ij, ij[notdiag, 2:1], deparse.level = 0L) } else if(check.Udiag && extends(cld, "triangularMatrix") && x@diag == "U") { i <- seq.int(from = 0L, length.out = x@Dim[1L]) rbind(ij, cbind(i, i, deparse.level = 0L), deparse.level = 0L) } else ij } ##' Decode "encoded" (i,j) indices back to cbind(i,j) ##' This is the inverse of encodeInd(.) ##' ##' @title Decode "Encoded" (i,j) Indices ##' @param code integer in 0:((n x m - 1) <==> encodeInd(.) result ##' @param nr the number of rows ##' @return ##' @author Martin Maechler decodeInd <- function(code, nr) cbind(as.integer(code %% nr), as.integer(code %/% nr), deparse.level = 0L) complementInd <- function(ij, dim, orig1=FALSE, checkBnds=FALSE) { ## Purpose: Compute the complement of the 2-column 0-based ij-matrix ## but as 1-based indices n <- prod(dim) if(n == 0L) return(integer(0L)) seq_len(n)[-(1L + .Call(m_encodeInd, ij, dim, orig1, checkBnds))] } WhichintersectInd <- function(ij1, ij2, di, orig1=FALSE, checkBnds=FALSE) { ## from 2-column (i,j) matrices where i \in {0,.., nrow-1}, ## find *where* common entries are in ij1 & ij2 m1 <- match(.Call(m_encodeInd, ij1, di, orig1, checkBnds), .Call(m_encodeInd, ij2, di, orig1, checkBnds)) ni <- !is.na(m1) list(which(ni), m1[ni]) } anyDuplicatedT <- function(x, ...) { mn <- prod(d <- x@Dim) if(mn <= .Machine$integer.max) anyDuplicated.default( x@j * d[1L] + x@i, ...) else if(mn <= 0x1p+53) anyDuplicated.default(as.double(x@j) * d[1L] + x@i, ...) else anyDuplicated.default(.mapply(c, list(x@i, x@j), NULL), ...) } isUniqueT <- function(x, byrow = FALSE, isT = is(x, "TsparseMatrix")) isT && !is.unsorted(if(byrow) order(x@i, x@j) else order(x@j, x@i), strictly = TRUE) asUniqueT <- function(x, byrow = FALSE, isT = is(x, "TsparseMatrix")) if(isUniqueT(x, byrow, isT)) x else .M2T(if(byrow) .M2R(x) else .M2C(x)) aggregateT <- function(x) .Call(Tsparse_aggregate, x) mat2triplet <- function(x, uniqT = FALSE) { T <- as(x, "TsparseMatrix") if(uniqT) T <- asUniqueT(T, isT = TRUE) if(is(T, "nsparseMatrix")) list(i = T@i + 1L, j = T@j + 1L) else list(i = T@i + 1L, j = T@j + 1L, x = T@x) } .validateCsparse <- function(x, sort.if.needed = FALSE) { if(sort.if.needed) .Call(CsparseMatrix_validate_maybe_sorting, x) else .Call(CsparseMatrix_validate, x) } dmperm <- function(x, nAns = 6L, seed = 0L) { ## NB: result is determined entirely by nonzero pattern of 'x' stopifnot(length(nAns <- as.integer(nAns)) == 1L, any(nAns == 2L * (1L:3L)), length(seed <- as.integer(seed)) == 1L, any(seed == -1L:1L)) x <- if(isS4(x)) .M2gen(.M2C(x), "n") else .m2sparse(x, "ngC") .Call(Csparse_dmperm, x, nAns, seed) } ## (matrix|denseMatrix)->denseMatrix as similar as possible to "target" as_denseClass <- function(x, cl, cld = getClassDef(cl)) { kind <- .M.kind(x) cl <- .M.nonvirtual(new(cld)) if(cl == "indMatrix") cl <- "ngeMatrix" symmetric <- substr(cl, 2L, 2L) == "s" && isSymmetric(x) triangular <- !symmetric && substr(cl, 2L, 2L) == "t" && (it <- isTriangular(x)) packed <- (symmetric || triangular) && substr(cl, 3L, 3L) == "p" if(isS4(x)) { r <- if(symmetric || triangular) .M2kind(if(symmetric) forceSymmetric(x) else if(attr(it, "kind") == "U") triu(x) else tril(x), kind) else .M2gen(x, kind) if(packed) pack(r) else r } else if(symmetric) .m2dense(x, paste0(kind, "s", if(packed) "p" else "y"), "U", NULL) else if(triangular) .m2dense(x, paste0(kind, "t", if(packed) "p" else "r"), attr(it, "kind"), "N") else .m2dense(x, paste0(kind, "ge")) } ## (matrix|sparseMatrix)->CsparseMatrix as similar as possible to "target" as_CspClass <- function(x, cl, cld = getClassDef(cl)) { kind <- .M.kind(x) cl <- .M.nonvirtual(new(cld)) if(cl == "indMatrix") cl <- "ngeMatrix" symmetric <- substr(cl, 2L, 2L) == "s" && isSymmetric(x) triangular <- !symmetric && substr(cl, 2L, 2L) == "t" && (it <- isTriangular(x)) if(isS4(x)) { r <- if(symmetric || triangular) .M2kind(if(symmetric) forceSymmetric(x) else if(attr(it, "kind") == "U") triu(x) else tril(x), kind) else .M2gen(x, kind) .M2C(r) } else if(symmetric) .m2sparse(x, paste0(kind, "sC"), "U", NULL) else if(triangular) .m2sparse(x, paste0(kind, "tC"), attr(it, "kind"), "N") else .m2sparse(x, paste0(kind, "gC")) } ## as(<[Mm]atrix>, ) asCspN <- function(x) .Call(R_sparse_diag_U2N, as(x, "CsparseMatrix")) diagU2N <- function (x, cl = getClassDef(class(x)), checkDense = FALSE) { if(extends(cl, "triangularMatrix") && x@diag == "U") .diagU2N(x, cl = cl, checkDense = checkDense) else x } .diagU2N <- function(x, cl = getClassDef(class(x)), checkDense = FALSE) { if(!checkDense && extends(cl, "denseMatrix")) x <- as(x, "CsparseMatrix") ..diagU2N(x) } ..diagU2N <- function(x) { diag(x) <- TRUE x } diagN2U <- function(x, cl = getClassDef(class(x)), checkDense = FALSE) { if(extends(cl, "triangularMatrix") && x@diag == "N") .diagN2U(x, cl = cl, checkDense = checkDense) else x } .diagN2U <- function(x, cl = getClassDef(class(x)), checkDense = FALSE) { if(!checkDense & (isDense <- extends(cl, "denseMatrix"))) ..diagN2U(as(x, "CsparseMatrix"), sparse = TRUE) else ..diagN2U(x, sparse = !isDense) } ..diagN2U <- function(x, sparse) { if(sparse && x@Dim[1L] > 0L) x <- switch(x@uplo, U = .Call(R_sparse_band, x, 1L, NULL), L = .Call(R_sparse_band, x, NULL, -1L)) x@diag <- "U" x } ## Caches 'value' in the 'factors' slot of 'x' { NOT a copy of 'x' ! } ## and returns 'value' .set.factor <- function(x, name, value, warn.no.slot = FALSE) .Call(R_set_factor, x, name, value, warn.no.slot) ##' Compute the three "parts" of two sets: .setparts <- function(x, y) { n1 <- length(m1 <- match(x, y, 0L)) n2 <- length(m2 <- match(y, x, 0L)) ix <- which(m1 == 0L) iy <- which(m2 == 0L) list(x.only = x[ix], ix.only = ix, mx = m1, y.only = y[iy], iy.only = iy, my = m2, int = if(n1 < n2) y[m1] else x[m2]) } ##' *Only* to be used as function in ##' setMethod.("Compare", ...., .Cmp.swap) --> ./Ops.R & ./diagMatrix.R .Cmp.swap <- function(e1, e2) { ## "swap RHS and LHS" and use the method below: switch(.Generic, "==" =, "!=" = callGeneric(e2, e1), "<" = e2 > e1, "<=" = e2 >= e1, ">" = e2 < e1, ">=" = e2 <= e1) } .diag.dsC <- function(x, Chx = Cholesky(x, LDL = TRUE), res.kind = "diag") { if(!missing(Chx)) stopifnot(.CHM.is.LDL(Chx), is.integer(Chx@p), is.double(Chx@x)) .Call(tCsparse_diag, Chx, res.kind) ## ^^^^^^^^^^^^^ in ../src/Csparse.c } dimScale <- function(x, d1 = sqrt(1/diag(x, names = FALSE)), d2 = d1) { dim.x <- dim(x) D1 <- Diagonal(n = dim.x[1L], x = d1) D2 <- if(missing(d2)) D1 else Diagonal(n = dim.x[2L], x = d2) y <- D1 %*% x %*% D2 # inefficient for symmetricMatrix 'x', but "general" if(isS4(x) && is(x, "symmetricMatrix") && identical(d1, d2)) y <- forceSymmetric(y, x@uplo) if(is.list(dn <- dimnames(x))) y@Dimnames <- dn y } rowScale <- function(x, d) { y <- Diagonal(n = nrow(x), x = d) %*% x if(is.list(dn <- dimnames(x))) y@Dimnames <- dn y } colScale <- function(x, d) { y <- x %*% Diagonal(n = ncol(x), x = d) if(is.list(dn <- dimnames(x))) y@Dimnames <- dn y } Matrix/R/colSums.R0000644000176200001440000001250514476673516013515 0ustar liggesusers## METHODS FOR GENERIC: colSums, rowSums, colMeans, rowMeans ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## ==== denseMatrix ==================================================== setMethod("colSums", signature(x = "denseMatrix"), function(x, na.rm = FALSE, dims = 1L, ...) .Call(R_dense_marginsum, x, 1L, na.rm, FALSE)) setMethod("colMeans", signature(x = "denseMatrix"), function(x, na.rm = FALSE, dims = 1L, ...) .Call(R_dense_marginsum, x, 1L, na.rm, TRUE)) setMethod("rowSums", signature(x = "denseMatrix"), function(x, na.rm = FALSE, dims = 1L, ...) .Call(R_dense_marginsum, x, 0L, na.rm, FALSE)) setMethod("rowMeans", signature(x = "denseMatrix"), function(x, na.rm = FALSE, dims = 1L, ...) .Call(R_dense_marginsum, x, 0L, na.rm, TRUE)) ## ==== sparseMatrix =================================================== ## ---- [CRT]sparseMatrix ---------------------------------------------- for (.cl in paste0(c("C", "R", "T"), "sparseMatrix")) { setMethod("colSums", signature(x = .cl), function(x, na.rm = FALSE, dims = 1L, sparseResult = FALSE, ...) .Call(R_sparse_marginsum, x, 1L, na.rm, FALSE, sparseResult)) setMethod("colMeans", signature(x = .cl), function(x, na.rm = FALSE, dims = 1L, sparseResult = FALSE, ...) .Call(R_sparse_marginsum, x, 1L, na.rm, TRUE, sparseResult)) setMethod("rowSums", signature(x = .cl), function(x, na.rm = FALSE, dims = 1L, sparseResult = FALSE, ...) .Call(R_sparse_marginsum, x, 0L, na.rm, FALSE, sparseResult)) setMethod("rowMeans", signature(x = .cl), function(x, na.rm = FALSE, dims = 1L, sparseResult = FALSE, ...) .Call(R_sparse_marginsum, x, 0L, na.rm, TRUE, sparseResult)) } rm(.cl) ## ---- diagonalMatrix ------------------------------------------------- .diag.cS <- .diag.rS <- function(x, na.rm = FALSE, dims = 1L, ...) { kind <- .M.kind(x) if((n <- x@Dim[1L]) == 0L) return(vector(switch(kind, "z" = "complex", "d" = , "i" = "double", "integer"), 0L)) else if(x@diag != "N") r <- rep.int(switch(kind, "z" = 1+0i, "d" = , "i" = 1, 1L), n) else { r <- switch(kind, "z" = , "d" = x@x, "i" = as.double(x@x), as.integer(x@x)) if((na.rm || kind == "n") && anyNA(r)) r[is.na(r)] <- switch(kind, "z" = 0+0i, "d" = , "i" = 0, "n" = 1L, 0L) } if(!is.null(nms <- x@Dimnames[[.MARGIN]])) names(r) <- nms r } body(.diag.cS) <- do.call(substitute, list(body(.diag.cS), list(.MARGIN = 2L))) body(.diag.rS) <- do.call(substitute, list(body(.diag.rS), list(.MARGIN = 1L))) .diag.cM <- .diag.rM <- function(x, na.rm = FALSE, dims = 1L, ...) { kind <- .M.kind(x) if((n <- x@Dim[1L]) == 0L) return(vector(switch(kind, "z" = "complex", "double"), 0L)) else if(x@diag != "N") r <- rep.int(switch(kind, "z" = 1+0i, 1) / n, n) else { r <- x@x / n if((na.rm || kind == "n") && anyNA(r)) r[is.na(r)] <- switch(kind, "z" = if(n == 1L) NaN * (0+0i) else 0+0i, "n" = 1 / n, if(n == 1L) NaN else 0) } if(!is.null(nms <- x@Dimnames[[.MARGIN]])) names(r) <- nms r } body(.diag.cM) <- do.call(substitute, list(body(.diag.cM), list(.MARGIN = 2L))) body(.diag.rM) <- do.call(substitute, list(body(.diag.rM), list(.MARGIN = 1L))) setMethod("colSums", signature(x = "diagonalMatrix"), .diag.cS) setMethod("colMeans", signature(x = "diagonalMatrix"), .diag.cM) setMethod("rowSums", signature(x = "diagonalMatrix"), .diag.rS) setMethod("rowMeans", signature(x = "diagonalMatrix"), .diag.rM) rm(.diag.cS, .diag.cM, .diag.rS, .diag.rM) ## ---- indMatrix (incl. pMatrix) -------------------------------------- setMethod("colSums", signature(x = "indMatrix"), function(x, na.rm = FALSE, dims = 1L, ...) { n <- x@Dim[2L] r <- if(x@margin == 1L) tabulate(x@perm, n) else rep.int(1L, n) if(!is.null(nms <- x@Dimnames[[2L]])) names(r) <- nms r }) setMethod("colMeans", signature(x = "indMatrix"), function(x, na.rm = FALSE, dims = 1L, ...) { n <- (d <- x@Dim)[2L] r <- if(x@margin == 1L) tabulate(x@perm, n) / d[1L] else rep.int(1 / d[1L], n) if(!is.null(nms <- x@Dimnames[[2L]])) names(r) <- nms r }) setMethod("rowSums", signature(x = "indMatrix"), function(x, na.rm = FALSE, dims = 1L, ...) { m <- x@Dim[1L] r <- if(x@margin == 1L) rep.int(1L, m) else tabulate(x@perm, m) if(!is.null(nms <- x@Dimnames[[1L]])) names(r) <- nms r }) setMethod("rowMeans", signature(x = "indMatrix"), function(x, na.rm = FALSE, dims = 1L, ...) { m <- (d <- x@Dim)[1L] r <- if(x@margin == 1L) rep.int(1 / d[2L], m) else tabulate(x@perm, m) / d[2L] if(!is.null(nms <- x@Dimnames[[1L]])) names(r) <- nms r }) Matrix/R/which.R0000644000176200001440000000437014500446564013160 0ustar liggesusers## METHODS FOR GENERIC: which ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("which", signature(x = "ndenseMatrix"), function(x, arr.ind = FALSE, useNames = TRUE) { wh <- which(.M2v(x)) if(arr.ind) arrayInd(wh, x@Dim, dimnames(x), useNames = useNames) else wh }) setMethod("which", signature(x = "ldenseMatrix"), function(x, arr.ind = FALSE, useNames = TRUE) { wh <- which(.M2v(x)) if(arr.ind) arrayInd(wh, x@Dim, dimnames(x), useNames = useNames) else wh }) setMethod("which", signature(x = "nsparseMatrix"), function(x, arr.ind = FALSE, useNames = TRUE) { wh <- .M2V(x)@i if(arr.ind) arrayInd(wh, x@Dim, dimnames(x), useNames = useNames) else wh }) setMethod("which", signature(x = "lsparseMatrix"), function(x, arr.ind = FALSE, useNames = TRUE) { wh <- { x. <- .M2V(x); x.@i[which(x.@x)] } if(arr.ind) arrayInd(wh, x@Dim, dimnames(x), useNames = useNames) else wh }) setMethod("which", signature(x = "ndiMatrix"), function(x, arr.ind = FALSE, useNames = TRUE) { wh <- .M2V(x)@i if(arr.ind) arrayInd(wh, x@Dim, x@Dimnames, useNames = useNames) else wh }) setMethod("which", signature(x = "ldiMatrix"), function(x, arr.ind = FALSE, useNames = TRUE) { wh <- { x. <- .M2V(x); x.@i[which(x.@x)] } if(arr.ind) arrayInd(wh, x@Dim, x@Dimnames, useNames = useNames) else wh }) setMethod("which", signature(x = "nsparseVector"), function(x, arr.ind = FALSE, useNames = TRUE) x@i) setMethod("which", signature(x = "lsparseVector"), function(x, arr.ind = FALSE, useNames = TRUE) x@i[which(x@x)]) setMethod("which", signature(x = "indMatrix"), function(x, arr.ind = FALSE, useNames = TRUE) { wh <- .M2V(x)@i if(arr.ind) arrayInd(wh, x@Dim, x@Dimnames, useNames = useNames) else wh }) Matrix/R/determinant.R0000644000176200001440000001720614506763205014372 0ustar liggesusers## METHODS FOR GENERIC: determinant ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## Constructor for "det" objects, used liberally below .mkDet <- function(modulus = sum(log(abs(x))), logarithm = TRUE, sign = if(prod(base::sign(x)) < 0) -1L else 1L, x) { if(!logarithm) modulus <- exp(modulus) attr(modulus, "logarithm") <- logarithm val <- list(modulus = modulus, sign = sign) class(val) <- "det" val } ## 'base::det' calls 'base::determinant', which is not S4 generic, ## so we define own our 'det' calling 'Matrix::determinant' ... det <- base::det environment(det) <- environment() # the Matrix namespace ######################################################################## ## 1. MatrixFactorization ######################################################################## setMethod("determinant", signature(x = "MatrixFactorization", logarithm = "missing"), function(x, logarithm = TRUE, ...) determinant(x, TRUE, ...)) ## FIXME: if we knew the specific class of 'T', then we could optimize ## knowing that 'T' is block upper triangular with 1-by-1 and 2-by-2 ## diagonal blocks setMethod("determinant", signature(x = "Schur", logarithm = "logical"), function(x, logarithm = TRUE, ...) determinant(x@T, logarithm, ...)) setMethod("determinant", signature(x = "denseLU", logarithm = "logical"), function(x, logarithm = TRUE, ...) .Call(denseLU_determinant, x, logarithm)) setMethod("determinant", signature(x = "sparseLU", logarithm = "logical"), function(x, logarithm = TRUE, ...) .Call(sparseLU_determinant, x, logarithm)) setMethod("determinant", signature(x = "sparseQR", logarithm = "logical"), function(x, logarithm = TRUE, ...) .Call(sparseQR_determinant, x, logarithm)) for(.cl in c("BunchKaufman", "pBunchKaufman")) setMethod("determinant", signature(x = .cl, logarithm = "logical"), function(x, logarithm = TRUE, ...) .Call(BunchKaufman_determinant, x, logarithm)) rm(.cl) for(.cl in c("Cholesky", "pCholesky")) setMethod("determinant", signature(x = .cl, logarithm = "logical"), function(x, logarithm = TRUE, ...) .Call(Cholesky_determinant, x, logarithm)) rm(.cl) setMethod("determinant", signature(x = "CHMfactor", logarithm = "logical"), function(x, logarithm = TRUE, sqrt = TRUE, ...) { if(missing(sqrt)) { w <- getOption("Matrix.warnSqrtDefault", .MatrixEnv[["warnSqrtDefault"]]) if(is.atomic(w) && length(w) == 1L && ((w.na <- is.na(w <- as.integer(w))) || w > 0L)) { if(w.na) on.exit(options(Matrix.warnSqrtDefault = 0L)) else if(w > 1L) { oop <- options(warn = 2L) on.exit(options(oop)) } warning(gettextf("the default value of argument '%s' of method '%s(<%s>, <%s>)' may change from %s to %s as soon as the next release of Matrix; set '%s' when programming", "sqrt", "determinant", "CHMfactor", "logical", "TRUE", "FALSE", "sqrt"), domain = NA) } } .Call(CHMfactor_determinant, x, logarithm, sqrt) }) ######################################################################## ## 2. Matrix ######################################################################## setMethod("determinant", signature(x = "Matrix", logarithm = "missing"), function(x, logarithm = TRUE, ...) determinant(x, TRUE, ...)) setMethod("determinant", signature(x = "Matrix", logarithm = "logical"), function(x, logarithm = TRUE, ...) determinant(.M2kind(x, ","), logarithm, ...)) ## .... GENERAL ........................................................ setMethod("determinant", signature(x = "dgeMatrix", logarithm = "logical"), function(x, logarithm = TRUE, ...) { d <- x@Dim if(d[1L] != d[2L]) stop("determinant of non-square matrix is undefined") trf <- lu(x, warnSing = FALSE) determinant(trf, logarithm, ...) }) setMethod("determinant", signature(x = "dgCMatrix", logarithm = "logical"), function(x, logarithm = TRUE, ...) { d <- x@Dim if(d[1L] != d[2L]) stop("determinant of non-square matrix is undefined") trf <- lu(x, errSing = FALSE) if(isS4(trf)) determinant(trf, logarithm, ...) else .mkDet(if(anyNA(x@x)) NaN else -Inf, logarithm, 1L) }) setMethod("determinant", signature(x = "dgRMatrix", logarithm = "logical"), function(x, logarithm = TRUE, ...) determinant(.tCRT(x), logarithm, ...)) setMethod("determinant", signature(x = "dgTMatrix", logarithm = "logical"), function(x, logarithm = TRUE, ...) determinant(.M2C(x), logarithm, ...)) setMethod("determinant", signature(x = "indMatrix", logarithm = "logical"), function(x, logarithm = TRUE, ...) { d <- x@Dim if(d[1L] != d[2L]) stop("determinant of non-square matrix is undefined") if(anyDuplicated.default(perm <- x@perm)) .mkDet(-Inf, logarithm, 1L) else .mkDet(0, logarithm, signPerm(perm)) }) setMethod("determinant", signature(x = "pMatrix", logarithm = "logical"), function(x, logarithm = TRUE, ...) .mkDet(0, logarithm, signPerm(x@perm))) ## .... SYMMETRIC ...................................................... for(.cl in c("dsyMatrix", "dspMatrix")) setMethod("determinant", signature(x = .cl, logarithm = "logical"), function(x, logarithm = TRUE, ...) { trf <- BunchKaufman(x, warnSing = FALSE) determinant(trf, logarithm, ...) }) rm(.cl) for(.cl in c("dpoMatrix", "dppMatrix")) setMethod("determinant", signature(x = .cl, logarithm = "logical"), function(x, logarithm = TRUE, ...) { trf <- tryCatch( Cholesky(x, perm = FALSE), error = function(e) BunchKaufman(x, warnSing = FALSE)) determinant(trf, logarithm, ...) }) rm(.cl) setMethod("determinant", signature(x = "dsCMatrix", logarithm = "logical"), function(x, logarithm = TRUE, ...) { trf <- tryCatch( Cholesky(x, perm = TRUE, LDL = TRUE, super = FALSE), error = function(e) lu(x, errSing = FALSE)) if(isS4(trf)) determinant(trf, logarithm, sqrt = FALSE, ...) else .mkDet(if(anyNA(x@x)) NaN else -Inf, logarithm, 1L) }) setMethod("determinant", signature(x = "dsRMatrix", logarithm = "logical"), function(x, logarithm = TRUE, ...) determinant(.tCRT(x), logarithm, ...)) setMethod("determinant", signature(x = "dsTMatrix", logarithm = "logical"), function(x, logarithm = TRUE, ...) determinant(.M2C(x), logarithm, ...)) ## .... TRIANGULAR ..................................................... for(.cl in c("triangularMatrix", "diagonalMatrix")) setMethod("determinant", signature(x = .cl, logarithm = "logical"), function(x, logarithm = TRUE, ...) if(x@diag == "N") .mkDet(x = diag(x, names = FALSE), logarithm = logarithm) else .mkDet(0, logarithm, 1L)) rm(.cl) Matrix/R/expm.R0000644000176200001440000000420114513276125013016 0ustar liggesusers## METHODS FOR GENERIC: expm ## the matrix exponential ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## MJ: currently going via ddiMatrix or dgeMatrix in all cases setMethod("expm", signature(x = "Matrix"), function(x) { d <- x@Dim if(d[1L] != d[2L]) stop("matrix is not square") expm(.M2kind(x, "d")) }) setMethod("expm", signature(x = "dsparseMatrix"), function(x) { d <- x@Dim if(d[1L] != d[2L]) stop("matrix is not square") expm(.sparse2dense(x)) }) setMethod("expm", signature(x = "ddiMatrix"), function(x) { if(x@diag == "N") { x@x <- exp(x@x) } else { x@diag <- "N" x@x <- rep.int(exp(1), x@Dim[1L]) } x }) setMethod("expm", signature(x = "dgeMatrix"), function(x) .Call(dgeMatrix_exp, x)) setMethod("expm", signature(x = "dtrMatrix"), function(x) { r <- .Call(dgeMatrix_exp, .M2gen(x)) if(x@uplo == "U") triu(r) else tril(r) }) setMethod("expm", signature(x = "dtpMatrix"), function(x) { r <- .Call(dgeMatrix_exp, .M2gen(x)) ## Pack without checking: .Call(R_dense_as_packed, r, x@uplo, "N") }) setMethod("expm", signature(x = "dsyMatrix"), function(x) { r <- .Call(dgeMatrix_exp, .M2gen(x)) forceSymmetric(r) }) setMethod("expm", signature(x = "dspMatrix"), function(x) { r <- .Call(dgeMatrix_exp, .M2gen(x)) ## Pack without checking: .Call(R_dense_as_packed, r, x@uplo, NULL) }) ## Until R supports it: setMethod("expm", signature(x = "matrix"), function(x) { d <- dim(x) if(d[1L] != d[2L]) stop("matrix is not square") storage.mode(x) <- "double" expm(if(isDiagonal(x)) forceDiagonal(x) else .m2dense(x, ".ge")) }) Matrix/R/graph-conv.R0000644000176200001440000001416414473555676014142 0ustar liggesusers## METHODS ENHANCING PACKAGE: graph ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## README: These need package 'graph', from which we do not import, ## _on purpose_. Hence we must use graph:: in case 'graph' ## is only loaded, not attached ... ## NB: undirected graph <==> symmetric matrix ## ~~~~ UTILITIES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## NB: These may no longer be needed in future versions of 'graph' graph.has.weights <- function(g) "weight" %in% names(graph::edgeDataDefaults(g)) graph.non.1.weights <- function(g) any(unlist(graph::edgeData(g, attr = "weight")) != 1) graph.wgtMatrix <- function(g) { ## Purpose: work around "graph" package's as(g, "matrix") bug ## ---------------------------------------------------------------------- ## Arguments: g: an object inheriting from (S4) class "graph" ## ---------------------------------------------------------------------- ## Author: Martin Maechler, based on Seth Falcon's code; Date: 12 May 2006 ## MM: another buglet for the case of "no edges": if(graph::numEdges(g) == 0) { p <- length(nd <- graph::nodes(g)) return( matrix(0, p,p, dimnames = list(nd, nd)) ) } ## Usual case, when there are edges: if(has.w <- graph.has.weights(g)) { ## graph.non.1.weights(g) : w <- unlist(graph::edgeData(g, attr = "weight")) has.w <- any(w != 1) } ## now 'has.w' is TRUE iff there are weights != 1 m <- as(g, "matrix") ## now is a 0/1 - matrix (instead of 0/wgts) with the 'graph' bug if(has.w) { ## fix it if needed tm <- t(m) tm[tm != 0] <- w t(tm) } else m } graph2T <- function(from, use.weights = graph.has.weights(from) && graph.non.1.weights(from)) { nd <- graph::nodes(from); dnms <- list(nd,nd) dm <- rep.int(length(nd), 2) edge2i <- function(e) { ## return (0-based) row indices 'i' rep.int(0:(dm[1]-1L), lengths(e)) } if(use.weights) { eWts <- graph::edgeWeights(from); names(eWts) <- NULL i <- edge2i(eWts) To <- unlist(lapply(eWts, names)) j <- as.integer(match(To,nd)) - 1L # columns indices (0-based) ## symm <- symm && : improbable ## if(symm) new("dsTMatrix", .....) else new("dgTMatrix", i = i, j = j, x = unlist(eWts), Dim = dm, Dimnames = dnms) } else { ## no weights: 0/1 matrix -> pattern edges <- lapply(from@edgeL[nd], "[[", "edges") symm <- graph::edgemode(from) == "undirected" if(symm)# each edge appears twice; keep upper triangle only edges <- lapply(seq_along(edges), function(i) {e <- edges[[i]]; e[e >= i]}) i <- edge2i(edges) j <- as.integer(unlist(edges)) - 1L # column indices (0-based) ## if(symm) { # symmetric: ensure upper triangle ## tmp <- i ## flip <- i > j ## i[flip] <- j[flip] ## j[flip] <- tmp[flip] ## new("nsTMatrix", i = i, j = j, Dim = dm, Dimnames = dnms, ## uplo = "U") ## } else { ## new("ngTMatrix", i = i, j = j, Dim = dm, Dimnames = dnms) ## } new(if(symm) "nsTMatrix" else "ngTMatrix", i = i, j = j, Dim = dm, Dimnames = dnms)# uplo = "U" is default } } T2graph <- function(from, need.uniq = !isUniqueT(from), edgemode = NULL) { d <- dim(from) if((n <- d[1L]) != d[2L]) stop("only square matrices can be used as graph incidence matrices") if(n == 0L) return(new("graphNEL")) if(is.null(rn <- dimnames(from)[[1]])) rn <- as.character(1:n) if(need.uniq) ## Need to 'uniquify' the triplets! from <- .M2T(.M2C(from)) if(is.null(edgemode)) edgemode <- if(isSymmetric(from)) { # either "symmetricMatrix" or otherwise ##-> undirected graph: every edge only once! if(!is(from, "symmetricMatrix")) { ## a general matrix which happens to be symmetric ## ==> remove the double indices from <- tril(from) } "undirected" } else { "directed" } ## every edge is there only once, either upper or lower triangle ft1 <- cbind(rn[from@i + 1L], rn[from@j + 1L]) graph::ftM2graphNEL(ft1, W = if(.hasSlot(from,"x")) as.numeric(from@x), V = rn, edgemode = edgemode) } ## ~~~~ COERCIONS FROM graph TO Matrix ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setAs("graphAM", "TsparseMatrix", function(from) { symm <- graph::edgemode(from) == "undirected" && isSymmetric(from@adjMat) if(graph.has.weights(from)) .m2sparse(graph.wgtMatrix(from), if(symm) "dsT" else "dgT") else ## no weights: 0/1 matrix -> pattern .m2sparse( as(from, "matrix"), if(symm) "nsT" else "ngT") }) setAs("graphNEL", "TsparseMatrix", function(from) graph2T(from)) setAs("graph", "CsparseMatrix", function(from) .M2C(graph2T(as(from, "graphNEL")))) setAs("graph", "RsparseMatrix", function(from) .M2R(graph2T(as(from, "graphNEL")))) setAs("graph", "TsparseMatrix", function(from) graph2T(as(from, "graphNEL")) ) setAs("graph", "sparseMatrix", function(from) .M2C(graph2T(as(from, "graphNEL")))) setAs("graph", "Matrix", function(from) .M2C(graph2T(as(from, "graphNEL")))) ## ~~~~ COERCIONS FROM Matrix TO graph ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## NB: Since we have a method for TsparseMatrix (below), the method ## for Matrix can assume that 'from' is _not_ a TsparseMatrix, ## and therefore expect that as(from, "TsparseMatrix") is "unique" setAs("TsparseMatrix", "graphNEL", function(from) T2graph( from )) setAs("Matrix", "graphNEL", function(from) T2graph(.M2T(from), need.uniq = FALSE)) setAs("Matrix", "graph", function(from) T2graph(.M2T(from), need.uniq = FALSE)) Matrix/R/AllGeneric.R0000644000176200001440000000550414476652011014061 0ustar liggesusers## NB: Here, we do _not_ define generic versions of functions that: ## * are already (S3) generic in their package of origin ## (e.g., isSymmetric), because our first setMethod call ## will define a correct (S4) generic function automatically ## * already have _implicit_ generic definitions in package ## methods (e.g., qr.R); see methods/R/makeBasicFunsList.R setGeneric("%&%", function(x, y) standardGeneric("%&%")) setGeneric("BunchKaufman", function(x, ...) standardGeneric("BunchKaufman")) setGeneric("Cholesky", function(A, ...) standardGeneric("Cholesky")) setGeneric("Schur", function(x, vectors = TRUE, ...) standardGeneric("Schur"), signature = "x") setGeneric("band", function(x, k1, k2, ...) standardGeneric("band"), signature = "x") setGeneric("expand", function(x, ...) standardGeneric("expand")) setGeneric("expand1", function(x, which, ...) standardGeneric("expand1"), signature = "x") setGeneric("expand2", function(x, ...) standardGeneric("expand2")) setGeneric("expm", function(x) standardGeneric("expm")) setGeneric("facmul", function(x, factor, y, trans = FALSE, left = TRUE, ...) standardGeneric("facmul"), signature = c("x", "y")) setGeneric("forceSymmetric", function(x, uplo) standardGeneric("forceSymmetric")) setGeneric("isDiagonal", function(object) standardGeneric("isDiagonal")) setGeneric("isTriangular", function(object, upper = NA, ...) standardGeneric("isTriangular"), signature = "object") setGeneric("lu", function(x, ...) standardGeneric("lu")) setGeneric("nnzero", function(x, na.counted = NA) standardGeneric("nnzero"), signature = "x") setGeneric("pack", function(x, ...) standardGeneric("pack")) setGeneric("skewpart", function(x) standardGeneric("skewpart")) setGeneric("symmpart", function(x) standardGeneric("symmpart")) setGeneric("tril", function(x, k = 0L, ...) standardGeneric("tril"), signature = "x") setGeneric("triu", function(x, k = 0L, ...) standardGeneric("triu"), signature = "x") setGeneric("unpack", function(x, ...) standardGeneric("unpack")) setGeneric("updown", function(update, C, L) standardGeneric("updown")) setGeneric("writeMM", function(obj, file, ...) standardGeneric("writeMM")) Matrix/R/kappa.R0000644000176200001440000002715214504476335013160 0ustar liggesusers## METHODS FOR GENERIC: norm ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("norm", signature(x = "ANY", type = "missing"), function(x, type, ...) norm(x, type = "O", ...)) setMethod("norm", signature(x = "denseMatrix", type = "character"), function(x, type, ...) { if(identical(type, "2")) return(base::norm(.M2m(x), type = "2")) x <- .M2kind(x, ",") switch(substr(.M.nonvirtual(x), 2L, 3L), "ge" = .Call(dgeMatrix_norm, x, type), "sy" = .Call(dsyMatrix_norm, x, type), "sp" = .Call(dspMatrix_norm, x, type), "tr" = .Call(dtrMatrix_norm, x, type), "tp" = .Call(dtpMatrix_norm, x, type)) }) setMethod("norm", signature(x = "sparseMatrix", type = "character"), function(x, type, ...) { if(any(x@Dim == 0L)) return(0) switch(EXPR = type[1L], "O" = , "o" = , "1" = max(colSums(abs(x))), "I" = , "i" = max(rowSums(abs(x))), "2" = { warning(gettextf("'%s' via sparse -> dense coercion", "norm"), domain = NA) base::norm(.M2m(x), type = "2") }, "M" = , "m" = max(abs(x)), "F" = , "f" = , "E" = , "e" = { if(.M.kind(x) == "z") x <- abs(x) sqrt(sum(x * x)) }, stop(gettextf("invalid %s=\"%s\"", "type", type[1L]), domain = NA)) }) setMethod("norm", signature(x = "diagonalMatrix", type = "character"), function(x, type, ...) { if((n <- x@Dim[1L]) == 0L) return(0) if(nonunit <- x@diag == "N") { y <- x@x if(.M.kind(x) == "n" && anyNA(y)) y <- y | is.na(y) } switch(EXPR = type[1L], "O" = , "o" = , "1" = , "I" = , "i" = , "2" = , "M" = , "m" = if(nonunit) max(abs(y)) else 1, "F" = , "f" = , "E" = , "e" = if(nonunit) { if(is.complex(y)) y <- abs(y) sqrt(sum(y * y)) } else sqrt(n), stop(gettextf("invalid %s=\"%s\"", "type", type[1L]), domain = NA)) }) setMethod("norm", signature(x = "indMatrix", type = "character"), function(x, type, ...) { d <- x@Dim if((m <- d[1L]) == 0L || (n <- d[2L]) == 0L) return(0) switch(EXPR = type[1L], "O" = , "o" = , "1" = if(x@margin == 1L) max(tabulate(x@perm, n)) else 1, "I" = , "i" = if(x@margin == 1L) 1 else max(tabulate(x@perm, m)), "2" = sqrt(max(tabulate(x@perm, if(x@margin == 1L) n else m))), "M" = , "m" = 1, "F" = , "f" = , "E" = , "e" = if(x@margin == 1L) sqrt(m) else sqrt(n), stop(gettextf("invalid %s=\"%s\"", "type", type[1L]), domain = NA)) }) setMethod("norm", signature(x = "pMatrix", type = "character"), function(x, type, ...) { if((n <- x@Dim[1L]) == 0L) return(0) switch(EXPR = type[1L], "O" = , "o" = , "1" = , "I" = , "i" = , "2" = , "M" = , "m" = 1, "F" = , "f" = , "E" = , "e" = sqrt(n), stop(gettextf("invalid %s=\"%s\"", "type", type[1L]), domain = NA)) }) ## METHODS FOR GENERIC: rcond ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("rcond", signature(x = "ANY", norm = "missing"), function(x, norm, ...) rcond(x, norm = "O", ...)) setMethod("rcond", signature(x = "denseMatrix", norm = "character"), function(x, norm, ...) { x <- .M2kind(x, ",") switch(substr(.M.nonvirtual(x, strict = TRUE), 2L, 3L), "ge" = { d <- x@Dim m <- d[1L] n <- d[2L] if(m == n) { trf <- lu(x, warnSing = FALSE) .Call(dgeMatrix_rcond, x, trf, norm) } else { ## MJ: norm(A = P1' Q R P2') = norm(R) holds ## in general only for norm == "2", but ## La_rcond_type() disallows norm == "2" ## ... FIXME ?? if(m < n) { x <- t(x) n <- m } R <- triu(qr(x)[["qr"]][seq_len(n), , drop = FALSE]) rcond(R, norm = norm, ...) } }, "sy" = { trf <- BunchKaufman(x, warnSing = FALSE) .Call(dsyMatrix_rcond, x, trf, norm) }, "sp" = { trf <- BunchKaufman(x, warnSing = FALSE) .Call(dspMatrix_rcond, x, trf, norm) }, "po" = , "or" = # corMatrix { ok <- TRUE trf <- tryCatch( Cholesky(x, perm = FALSE), error = function(e) { ok <<- FALSE BunchKaufman(x, warnSing = FALSE) }) if(ok) .Call(dpoMatrix_rcond, x, trf, norm) else .Call(dsyMatrix_rcond, x, trf, norm) }, "pp" = , "co" = # pcorMatrix { ok <- TRUE trf <- tryCatch( Cholesky(x, perm = FALSE), error = function(e) { ok <<- FALSE BunchKaufman(x, warnSing = FALSE) }) if(ok) .Call(dppMatrix_rcond, x, trf, norm) else .Call(dspMatrix_rcond, x, trf, norm) }, "tr" = .Call(dtrMatrix_rcond, x, norm), "tp" = .Call(dtpMatrix_rcond, x, norm)) }) setMethod("rcond", signature(x = "sparseMatrix", norm = "character"), function(x, norm, useInv = FALSE, ...) { d <- x@Dim if((m <- d[1L]) == 0L || (n <- d[2L]) == 0L) return(Inf) if(m == n) { if(isS4(useInv) || useInv) { if(!isS4(useInv)) useInv <- solve(x) 1 / (norm(x, type = norm) * norm(useInv, type = norm)) } else { warning(gettextf("'%s' via sparse -> dense coercion", "rcond"), domain = NA) rcond(.M2unpacked(x), norm = norm, ...) } } else { ## MJ: norm(A = P1' Q R P2') = norm(R) holds in general ## only for norm == "2", but La_rcond_type() disallows ## norm == "2" ... FIXME ?? if(m < n) { x <- t(x) n <- m } R <- triu(qr(x)@R[seq_len(n), , drop = FALSE]) rcond(R, norm = norm, ...) } }) setMethod("rcond", signature(x = "diagonalMatrix", norm = "character"), function(x, norm, ...) { if((n <- x@Dim[1L]) == 0L) return(Inf) if(nonunit <- x@diag == "N") { y <- x@x if(.M.kind(x) == "n" && anyNA(y)) y <- y | is.na(y) } switch(EXPR = norm[1L], "O" = , "o" = , "1" = , "I" = , "i" = , "2" = , "M" = , "m" = if(nonunit) { ry <- range(abs(y)) ry[1L] / ry[2L] } else 1, "F" = , "f" = , "E" = , "e" = if(nonunit) { if(is.complex(y)) y <- abs(y) yy <- y * y 1 / sqrt(sum(yy) * sum(1 / yy)) } else 1 / n, stop(gettext("invalid %s=\"%s\"", "norm", norm[1L]), domain = NA)) }) setMethod("rcond", signature(x = "indMatrix", norm = "character"), function(x, norm, ...) { d <- x@Dim if((m <- d[1L]) == 0L || (n <- d[2L]) == 0L) return(Inf) if (m == n) { if(anyDuplicated.default(x@perm)) return(0) switch(EXPR = norm[1L], "O" = , "o" = , "1" = , "I" = , "i" = , "2" = , "M" = , "m" = 1, "F" = , "f" = , "E" = , "e" = 1 / n, stop(gettext("invalid %s=\"%s\"", "norm", norm[1L]), domain = NA)) } else { if(m < n) { x <- t(x) n <- m } R <- triu(qr(x)@R[seq_len(n), , drop = FALSE]) rcond(R, norm = norm, ...) } }) setMethod("rcond", signature(x = "pMatrix", norm = "character"), function(x, norm, ...) { if((n <- x@Dim[1L]) == 0L) return(Inf) switch(EXPR = norm[1L], "O" = , "o" = , "1" = , "I" = , "i" = , "2" = , "M" = , "m" = 1, "F" = , "f" = , "E" = , "e" = 1 / n, stop(gettext("invalid %s=\"%s\"", "norm", norm[1L]), domain = NA)) }) Matrix/R/Math.R0000644000176200001440000002456514511521056012747 0ustar liggesusers## METHODS FOR GENERIC: Math (group) ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## > getGroupMembers("Math") ## [1] "abs" "sign" "sqrt" "ceiling" "floor" "trunc" ## [7] "cummax" "cummin" "cumprod" "cumsum" "exp" "expm1" ## [13] "log" "log10" "log2" "log1p" "cos" "cosh" ## [19] "sin" "sinh" "tan" "tanh" "acos" "acosh" ## [25] "asin" "asinh" "atan" "atanh" "cospi" "sinpi" ## [31] "tanpi" "gamma" "lgamma" "digamma" "trigamma" setMethod("Math", signature(x = "denseMatrix"), function(x) { g <- get(.Generic, mode = "function") if(startsWith(.Generic, "cum")) return(g(.M2v(x))) cl <- .M.nonvirtual(x) kind <- substr(cl, 1L, 1L) shape <- substr(cl, 2L, 2L) if (kind == "z") { zero <- 0+0i; one <- 1+0i; a <- as.complex } else { zero <- 0 ; one <- 1 ; a <- as.double substr(cl, 1L, 1L) <- "d" } if(shape == "t") { stay0 <- is0(a(g(zero))) if(!stay0) { x <- .M2gen(x) substr(cl, 2L, 3L) <- "ge" } } r <- new(cl) r@Dim <- x@Dim r@Dimnames <- x@Dimnames if(shape == "s" || (shape == "t" && stay0)) r@uplo <- x@uplo r@x <- a(g({ y <- x@x; if(kind == "n") y | is.na(y) else y })) if(shape == "t" && stay0 && x@diag != "N") { if(is1(g1 <- a(g(one)))) r@diag <- "U" else diag(r) <- g1 } r }) setMethod("log", signature(x = "denseMatrix"), function(x, ...) { cl <- .M.nonvirtual(x) kind <- substr(cl, 1L, 1L) shape <- substr(cl, 2L, 2L) if(kind != "z") substr(cl, 1L, 1L) <- "d" if(shape == "t") { x <- .M2gen(x) substr(cl, 2L, 3L) <- "ge" } r <- new(cl) r@Dim <- x@Dim r@Dimnames <- x@Dimnames if(shape == "s") r@uplo <- x@uplo r@x <- log({ y <- x@x; if(kind == "n") y | is.na(y) else y }, ...) r }) setMethod("Math", signature(x = "sparseMatrix"), function(x) { g <- get(.Generic, mode = "function") if(startsWith(.Generic, "cum")) return(g(.M2v(x))) cl <- .M.nonvirtual(x) kind <- substr(cl, 1L, 1L) shape <- substr(cl, 2L, 2L) repr <- substr(cl, 3L, 3L) if (kind == "z") { zero <- 0+0i; one <- 1+0i; a <- as.complex } else { zero <- 0 ; one <- 1 ; a <- as.double substr(cl, 1L, 1L) <- "d" } stay0 <- is0(g0 <- a(g(zero))) if(!stay0) substr(cl, 2L, 3L) <- if(shape == "s") "sy" else "ge" r <- new(cl) r@Dim <- x@Dim r@Dimnames <- x@Dimnames if(shape == "s" || (shape == "t" && stay0)) r@uplo <- x@uplo if(!stay0) { y <- .Call(CR2spV, if(repr == "T") .M2C(x) else x) tmp <- rep.int(g0, y@length) tmp[y@i] <- a(g(if(kind == "n") one else y@x)) r@x <- tmp } else { if(shape == "t" && x@diag != "N") { if(is1(a(g(one)))) r@diag <- "U" else diag(x) <- TRUE } nnz <- length( switch(repr, "C" = { r@p <- x@p; r@i <- x@i }, "R" = { r@p <- x@p; r@j <- x@j }, "T" = { r@i <- x@i; r@j <- x@j })) r@x <- if(kind == "n") rep.int(a(g(one)), nnz) else a(g(x@x)) } r }) setMethod("log", signature(x = "sparseMatrix"), function(x, ...) { cl <- .M.nonvirtual(x) kind <- substr(cl, 1L, 1L) shape <- substr(cl, 2L, 2L) repr <- substr(cl, 3L, 3L) if(kind == "z") { zero <- 0+0i; one <- 1+0i } else { zero <- 0 ; one <- 1 substr(cl, 1L, 1L) <- "d" } substr(cl, 2L, 3L) <- if(shape == "s") "sy" else "ge" r <- new(cl) r@Dim <- x@Dim r@Dimnames <- x@Dimnames if(shape == "s") r@uplo <- x@uplo y <- .Call(CR2spV, if(repr == "T") .M2C(x) else x) tmp <- rep.int(log(zero, ...), y@length) tmp[y@i] <- log(if(kind == "n") one else y@x, ...) r@x <- tmp r }) setMethod("Math", signature(x = "diagonalMatrix"), function(x) { g <- get(.Generic, mode = "function") if(startsWith(.Generic, "cum")) return(g(.M2v(x))) cl <- .M.nonvirtual(x) kind <- substr(cl, 1L, 1L) if (kind == "z") { zero <- 0+0i; one <- 1+0i; a <- as.complex } else { zero <- 0 ; one <- 1 ; a <- as.double substr(cl, 1L, 1L) <- "d" } stay0 <- is0(g0 <- a(g(zero))) if(!stay0) substr(cl, 2L, 3L) <- "ge" r <- new(cl) r@Dim <- d <- x@Dim r@Dimnames <- x@Dimnames if(!stay0) { if((n <- d[2L]) > 0L) { tmp <- matrix(g0, n, n) diag(tmp) <- a(g(if(x@diag != "N") one else { y <- x@x; if(kind == "n" && anyNA(y)) y | is.na(y) else y })) dim(tmp) <- NULL r@x <- tmp } } else { if(x@diag != "N") { if(is1(g1 <- a(g(one)))) r@diag <- "U" else r@x <- rep.int(g1, d[1L]) } else r@x <- a(g({ y <- x@x; if(kind == "n" && anyNA(y)) y | is.na(y) else y })) } r }) setMethod("log", signature(x = "diagonalMatrix"), function(x, ...) { cl <- .M.nonvirtual(x) kind <- substr(cl, 1L, 1L) if(kind == "z") { zero <- 0+0i; one <- 1+0i } else { zero <- 0 ; one <- 1 substr(cl, 1L, 1L) <- "d" } substr(cl, 2L, 3L) <- "ge" r <- new(cl) r@Dim <- d <- x@Dim r@Dimnames <- x@Dimnames if((n <- d[2L]) > 0L) { tmp <- matrix(log(zero, ...), n, n) diag(tmp) <- log(if(x@diag != "N") one else { y <- x@x; if(kind == "n" && anyNA(y)) y | is.na(y) else y }, ...) dim(tmp) <- NULL r@x <- tmp } r }) setMethod("Math", signature(x = "indMatrix"), function(x) get(.Generic, mode = "function")(.M2kind(x, "n"))) setMethod("log", signature(x = "indMatrix"), function(x, ...) log(.M2kind(x, "n"), ...)) setMethod("Math", signature(x = "sparseVector"), function(x) { g <- get(.Generic, mode = "function") if(startsWith(.Generic, "cum")) return(g(.V2v(x))) kind <- .M.kind(x) if(kind == "z") { zero <- 0+0i; one <- 1+0i; l <- "z" } else if(kind == "d" || .Generic != "abs") { zero <- 0 ; one <- 1 ; l <- "d" } else { zero <- 0L ; one <- 1L ; l <- "i" } if(isN0(g0 <- g(zero))) { r <- rep.int(g0, x@length) if((nnz <- length(x@i)) > 0L) r[x@i] <- if(kind == "n") rep.int(g(one), nnz) else g(x@x) } else { r <- new(paste0(l, "sparseVector")) r@length <- x@length r@i <- x@i if((nnz <- length(x@i)) > 0L) r@x <- if(kind == "n") rep.int(g(one), nnz) else g(x@x) } r }) setMethod("log", signature(x = "sparseVector"), function(x, ...) { kind <- .M.kind(x) if(kind == "z") { zero <- 0+0i; one <- 1+0i } else { zero <- 0 ; one <- 1 } r <- rep.int(log(zero, ...), x@length) if(length(x@i) > 0L) r[x@i] <- log(if(kind == "n") one else x@x, ...) r }) ## METHODS FOR GENERIC: Math2 (group) ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## > getGroupMembers("Math2") ## [1] "round" "signif" setMethod("Math2", signature(x = "Matrix"), function(x, digits) { x <- .indefinite(.M2kind(x, ",")) x@x <- get(.Generic, mode = "function")(x@x, digits = digits) if(.hasSlot(x, "factors") && length(x@factors) > 0L) x@factors <- list() x }) setMethod("Math2", signature(x = "sparseVector"), function(x, digits) { x <- .V2kind(x, ",") x@x <- get(.Generic, mode = "function")(x@x, digits = digits) x }) ## METHODS FOR GENERIC: zapsmall ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setMethod("zapsmall", signature(x = "Matrix"), function(x, digits = getOption("digits")) { x <- .indefinite(.M2kind(x, ",")) x@x <- zapsmall(x@x, digits = digits) if(.hasSlot(x, "factors") && length(x@factors) > 0L) x@factors <- list() x }) setMethod("zapsmall", signature(x = "sparseVector"), function(x, digits = getOption("digits")) { x <- .V2kind(x, ",") x@x <- zapsmall(x@x, digits = digits) x }) Matrix/R/solve.R0000644000176200001440000005542214534140574013211 0ustar liggesusers## METHODS FOR GENERIC: solve ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .solve.checkDim1 <- function(nrow.a, ncol.a) { if(nrow.a != ncol.a) stop(gettextf("'%s' is not square", "a"), domain = NA) } .solve.checkDim2 <- function(nrow.a, nrow.b) { if(nrow.a != nrow.b) stop(gettextf("dimensions of '%s' and '%s' are inconsistent", "a", "b"), domain = NA) } .solve.checkCond <- function(a, tol, rcond.a = rcond(a)) { if(tol > 0 && a@Dim[1L] > 0L && rcond.a < tol) stop(gettextf("'%1$s' is computationally singular, rcond(%1$s)=%2$g", "a", rcond.a), domain = NA) } ## Factorize A as P1 A P2 = L U . Then : ## ## kappa(A) <= kappa(P1') * kappa(L) * kappa(U) * kappa(P2') ## == 1 * kappa(L) * kappa(U) * 1 ## ## If U is diagonally dominant, i.e., if there exists a > 1 such that : ## ## abs(U[i,i]) >= a * sum(abs(U[i,-i])) i = 1, ... , n ## ## then : ## ## kappa(U) <= ((a + 1) / (a - 1)) * max(abs(diag(U))) / min(abs(diag(U))) ## ## The bound contracts as a --> Inf and in the limit we have: ## ## kappa(A) / kappa(L) <= kappa(U) <= max(abs(diag(U))) / min(abs(diag(U))) ## .solve.checkCondBound <- function(u, tol, rad.u = range(abs(diag(u, names = FALSE)))) { if(tol > 0 && u@Dim[1L] > 0L) { r <- rad.u[1L] / rad.u[2L] if(r < tol) stop(gettextf("'%s' is computationally singular, min(d)/max(d)=%g, d=abs(diag(U))", "a", r), domain = NA) } } .solve.checkDiagonal <- function(diag.a) { zero <- diag.a == 0 if(any(zero, na.rm = TRUE)) stop(gettextf("matrix is exactly singular, D[i,i]=0, i=%d", which.max(zero)), domain = NA) } .solve.checkInd <- function(perm, margin, n) { if(anyDuplicated.default(perm)) { i <- seq_len(n)[-perm][1L] if(margin == 1L) stop(gettextf("matrix is exactly singular, J[,j]=0, j=%d", i), domain = NA) else stop(gettextf("matrix exactly singular, J[i,]=0, i=%d", i), domain = NA) } } ######################################################################## ## 1. MatrixFactorization incl. triangularMatrix ######################################################################## for(.cl in c("MatrixFactorization", "triangularMatrix")) { setMethod("solve", signature(a = .cl, b = "vector"), function(a, b, ...) drop(solve(a, .m2dense(b, ",ge"), ...))) setMethod("solve", signature(a = .cl, b = "matrix"), function(a, b, ...) solve(a, .m2dense(b, ",ge"), ...)) setMethod("solve", signature(a = .cl, b = "denseMatrix"), function(a, b, ...) solve(a, .M2gen(b, ","), ...)) setMethod("solve", signature(a = .cl, b = "CsparseMatrix"), function(a, b, ...) solve(a, .M2gen(b, ","), ...)) setMethod("solve", signature(a = .cl, b = "RsparseMatrix"), function(a, b, ...) solve(a, .M2gen(.M2C(b), ","), ...)) setMethod("solve", signature(a = .cl, b = "TsparseMatrix"), function(a, b, ...) solve(a, .M2gen(.M2C(b), ","), ...)) setMethod("solve", signature(a = .cl, b = "diagonalMatrix"), function(a, b, ...) solve(a, .diag2sparse(b, ",", "g", "C"), ...)) setMethod("solve", signature(a = .cl, b = "indMatrix"), function(a, b, ...) solve(a, .ind2sparse(b, ","), ...)) setMethod("solve", signature(a = .cl, b = "dgeMatrix"), function(a, b, ...) solve(a, .dense2sparse(b, "C"), ...)) setMethod("solve", signature(a = .cl, b = "dgCMatrix"), function(a, b, ...) solve(a, .sparse2dense(b, FALSE), ...)) } rm(.cl) setMethod("solve", signature(a = "denseLU", b = "missing"), function(a, b, ...) .Call(denseLU_solve, a, NULL)) setMethod("solve", signature(a = "denseLU", b = "dgeMatrix"), function(a, b, ...) .Call(denseLU_solve, a, b)) for(.cl in c("BunchKaufman", "pBunchKaufman")) { setMethod("solve", signature(a = .cl, b = "missing"), function(a, b, ...) .Call(BunchKaufman_solve, a, NULL)) setMethod("solve", signature(a = .cl, b = "dgeMatrix"), function(a, b, ...) .Call(BunchKaufman_solve, a, b)) } rm(.cl) for(.cl in c("Cholesky", "pCholesky")) { setMethod("solve", signature(a = .cl, b = "missing"), function(a, b, ...) .Call(Cholesky_solve, a, NULL)) setMethod("solve", signature(a = .cl, b = "dgeMatrix"), function(a, b, ...) .Call(Cholesky_solve, a, b)) } rm(.cl) setMethod("solve", signature(a = "sparseLU", b = "missing"), function(a, b, tol = .Machine$double.eps, sparse = TRUE, ...) { .solve.checkCondBound(a@U, tol) .Call(sparseLU_solve, a, NULL, sparse) }) setMethod("solve", signature(a = "sparseLU", b = "dgeMatrix"), function(a, b, tol = .Machine$double.eps, ...) { .solve.checkCondBound(a@U, tol) .Call(sparseLU_solve, a, b, FALSE) }) setMethod("solve", signature(a = "sparseLU", b = "dgCMatrix"), function(a, b, tol = .Machine$double.eps, ...) { .solve.checkCondBound(a@U, tol) .Call(sparseLU_solve, a, b, TRUE) }) setMethod("solve", signature(a = "sparseQR", b = "missing"), function(a, b, sparse = TRUE, ...) { r <- qr.coef(a, diag(a@Dim[2L])) if(is.na(sparse) || sparse) .dense2sparse(r, "C") else r }) setMethod("solve", signature(a = "sparseQR", b = "dgeMatrix"), function(a, b, ...) qr.coef(a, b)) setMethod("solve", signature(a = "sparseQR", b = "dgCMatrix"), function(a, b, ...) .dense2sparse(qr.coef(a, .sparse2dense(b, FALSE)), "C")) setMethod("solve", signature(a = "CHMfactor", b = "missing"), function(a, b, sparse = TRUE, system = c("A","LDLt","LD","DLt","L","Lt","D","P","Pt"), ...) { if((is.na(sparse) || sparse) && !missing(system)) { ## Do the "right" thing : if(identical(system, "D")) { r <- new("ddiMatrix") r@Dim <- a@Dim r@Dimnames <- a@Dimnames[2:1] if(.CHM.is.LDL(a)) r@x <- a@x[a@p + 1L] else r@diag <- "U" return(r) } else if(identical(system, "P") || identical(system, "Pt")) { r <- new("pMatrix") r@Dim <- a@Dim r@Dimnames <- a@Dimnames[2:1] if(system == "Pt") r@margin <- 2L r@perm <- a@perm + 1L return(r) } } .Call(CHMfactor_solve, a, NULL, sparse, system) }) setMethod("solve", signature(a = "CHMfactor", b = "dgeMatrix"), function(a, b, system = c("A","LDLt","LD","DLt","L","Lt","D","P","Pt"), ...) .Call(CHMfactor_solve, a, b, FALSE, system)) setMethod("solve", signature(a = "CHMfactor", b = "dgCMatrix"), function(a, b, system = c("A","LDLt","LD","DLt","L","Lt","D","P","Pt"), ...) .Call(CHMfactor_solve, a, b, TRUE, system)) for(.cl in c("dtrMatrix", "dtpMatrix")) { setMethod("solve", signature(a = .cl, b = "missing"), function(a, b, tol = .Machine$double.eps, ...) { .solve.checkCond(a, tol) .Call(dtrMatrix_solve, a, NULL) }) setMethod("solve", signature(a = .cl, b = "dgeMatrix"), function(a, b, tol = .Machine$double.eps, ...) { .solve.checkCond(a, tol) .Call(dtrMatrix_solve, a, b) }) } rm(.cl) setMethod("solve", signature(a = "dtCMatrix", b = "missing"), function(a, b, sparse = TRUE, ...) { if(a@diag != "N") a <- ..diagU2N(a) .Call(dtCMatrix_solve, a, NULL, sparse) }) setMethod("solve", signature(a = "dtCMatrix", b = "dgeMatrix"), function(a, b, sparse = FALSE, ...) { if(a@diag != "N") a <- ..diagU2N(a) if(is.na(sparse) || sparse) b <- .dense2sparse(b, "C") .Call(dtCMatrix_solve, a, b, sparse) }) setMethod("solve", signature(a = "dtCMatrix", b = "dgCMatrix"), function(a, b, sparse = TRUE, ...) { if(a@diag != "N") a <- ..diagU2N(a) if(!(is.na(sparse) || sparse)) b <- .sparse2dense(b, FALSE) .Call(dtCMatrix_solve, a, b, sparse) }) for(.cl in c("dtrMatrix", "dtpMatrix", "dtCMatrix")) setMethod("solve", signature(a = .cl, b = "triangularMatrix"), function(a, b, ...) { r <- solve(a, .M2gen(b), ...) if(a@uplo == b@uplo) { r <- if(a@uplo == "U") triu(r) else tril(r) if(a@diag != "N" && b@diag != "N") r <- ..diagN2U(r, sparse = .isCRT(r)) } r }) rm(.cl) ## MJ: truly an exceptional case ... setMethod("solve", signature(a = "Schur", b = "ANY"), function(a, b, ...) { Q <- a@Q T <- a@T if(missing(b)) { r <- Q %*% solve(T, t(Q)) r@Dimnames <- a@Dimnames[2:1] r } else { db <- dim(b) dnb <- dimnames(b) r <- Q %*% solve(T, crossprod(Q, b)) r@Dimnames <- c(a@Dimnames[2L], if(is.null(dnb)) list(NULL) else dnb[2L]) if(is.null(db)) drop(r) else r } }) ######################################################################## ## 2. denseMatrix excl. triangularMatrix ######################################################################## setMethod("solve", signature(a = "denseMatrix", b = "ANY"), function(a, b, ...) { a <- .M2kind(a, ",") if(missing(b)) solve(a, ...) else solve(a, b, ...) }) setMethod("solve", signature(a = "dgeMatrix", b = "ANY"), function(a, b, tol = .Machine$double.eps, ...) { d <- a@Dim .solve.checkDim1(d[1L], d[2L]) .solve.checkCond(a, tol) trf <- lu(a, warnSing = FALSE) if(missing(b)) solve(trf, ...) else solve(trf, b, ...) }) for(.cl in c("dsyMatrix", "dspMatrix")) setMethod("solve", signature(a = .cl, b = "ANY"), function(a, b, tol = .Machine$double.eps, ...) { .solve.checkCond(a, tol) trf <- BunchKaufman(a, warnSing = FALSE) if(missing(b)) solve(trf, ...) else solve(trf, b, ...) }) rm(.cl) for(.cl in c("dpoMatrix", "dppMatrix")) setMethod("solve", signature(a = .cl, b = "ANY"), function(a, b, tol = .Machine$double.eps, ...) { .solve.checkCond(a, tol) trf <- Cholesky(a, perm = FALSE) if(missing(b)) solve(trf, ...) else solve(trf, b, ...) }) rm(.cl) ######################################################################## ## 3. CsparseMatrix excl. triangularMatrix ######################################################################## setMethod("solve", signature(a = "CsparseMatrix", b = "ANY"), function(a, b, ...) { a <- .M2kind(a, ",") if(missing(b)) solve(a, ...) else solve(a, b, ...) }) setMethod("solve", signature(a = "dgCMatrix", b = "missing"), function(a, b, sparse = TRUE, ...) { trf <- lu(a, errSing = TRUE) solve(trf, sparse = sparse, ...) }) setMethod("solve", signature(a = "dgCMatrix", b = "vector"), function(a, b, ...) { trf <- lu(a, errSing = TRUE) solve(trf, b, ...) }) setMethod("solve", signature(a = "dgCMatrix", b = "matrix"), function(a, b, sparse = FALSE, ...) { trf <- lu(a, errSing = TRUE) if(is.na(sparse) || sparse) b <- .m2sparse(b, ",gC") solve(trf, b, ...) }) setMethod("solve", signature(a = "dgCMatrix", b = "denseMatrix"), function(a, b, sparse = FALSE, ...) { trf <- lu(a, errSing = TRUE) if(is.na(sparse) || sparse) b <- .M2C(b) solve(trf, b, ...) }) setMethod("solve", signature(a = "dgCMatrix", b = "sparseMatrix"), function(a, b, sparse = TRUE, ...) { trf <- lu(a, errSing = TRUE) if(!(is.na(sparse) || sparse)) b <- .M2unpacked(b) solve(trf, b, ...) }) setMethod("solve", signature(a = "dsCMatrix", b = "missing"), function(a, b, sparse = TRUE, ...) { trf <- tryCatch( Cholesky(a, perm = TRUE, LDL = TRUE, super = FALSE), error = function(e) lu(a, errSing = TRUE)) solve(trf, sparse = sparse, ...) }) setMethod("solve", signature(a = "dsCMatrix", b = "vector"), function(a, b, ...) { trf <- tryCatch( Cholesky(a, perm = TRUE, LDL = TRUE, super = FALSE), error = function(e) lu(a, errSing = TRUE)) solve(trf, b, ...) }) setMethod("solve", signature(a = "dsCMatrix", b = "matrix"), function(a, b, sparse = FALSE, ...) { trf <- tryCatch( Cholesky(a, perm = TRUE, LDL = TRUE, super = FALSE), error = function(e) lu(a, errSing = TRUE)) if(is.na(sparse) || sparse) b <- .m2sparse(b, ",gC") solve(trf, b, ...) }) setMethod("solve", signature(a = "dsCMatrix", b = "denseMatrix"), function(a, b, sparse = FALSE, ...) { trf <- tryCatch( Cholesky(a, perm = TRUE, LDL = TRUE, super = FALSE), error = function(e) lu(a, errSing = TRUE)) if(is.na(sparse) || sparse) b <- .M2C(b) solve(trf, b, ...) }) setMethod("solve", signature(a = "dsCMatrix", b = "sparseMatrix"), function(a, b, sparse = TRUE, ...) { trf <- tryCatch( Cholesky(a, perm = TRUE, LDL = TRUE, super = FALSE), error = function(e) lu(a, errSing = TRUE)) if(!(is.na(sparse) || sparse)) b <- .M2unpacked(b) solve(trf, b, ...) }) ######################################################################## ## 4. RsparseMatrix excl. triangularMatrix ######################################################################## ## TODO: implement triangular solver for dtRMatrix, so that we can handle ## A = and A' = .tCRT(A) like so: ## ## P1 A' P2 = L U ## A x = b <==================> x = P1' inv(L') inv(U') P2' b ## setMethod("solve", signature(a = "RsparseMatrix", b = "ANY"), function(a, b, ...) { a <- .M2kind(.M2C(a), ",") if(missing(b)) solve(a, ...) else solve(a, b, ...) }) ######################################################################## ## 5. TsparseMatrix excl. triangularMatrix ######################################################################## setMethod("solve", signature(a = "TsparseMatrix", b = "ANY"), function(a, b, ...) { a <- .M2kind(.M2C(a), ",") if(missing(b)) solve(a, ...) else solve(a, b, ...) }) ######################################################################## ## 6. diagonalMatrix ######################################################################## setMethod("solve", signature(a = "diagonalMatrix", b = "ANY"), function(a, b, ...) { a <- .M2kind(a, ",") if(missing(b)) solve(a, ...) else solve(a, b, ...) }) setMethod("solve", signature(a = "ddiMatrix", b = "missing"), function(a, b, ...) { if(a@diag == "N") { x <- a@x .solve.checkDiagonal(x) a@x <- 1 / x } a@Dimnames <- a@Dimnames[2:1] a }) setMethod("solve", signature(a = "ddiMatrix", b = "vector"), function(a, b, ...) { m <- length(b) .solve.checkDim2(a@Dim[1L], m) r <- if(a@diag == "N") { x <- a@x .solve.checkDiagonal(x) as.double(b) / x } else as.double(b) names(r) <- a@Dimnames[[2L]] r }) setMethod("solve", signature(a = "ddiMatrix", b = "matrix"), function(a, b, ...) { d <- dim(b) .solve.checkDim2(a@Dim[1L], d[1L]) dn <- dimnames(b) r <- new("dgeMatrix") r@Dim <- d r@Dimnames <- c(a@Dimnames[2L], if(is.null(dn)) list(NULL) else dn[2L]) r@x <- if(a@diag == "N") { x <- a@x .solve.checkDiagonal(x) as.double(b) / x } else as.double(b) r }) setMethod("solve", signature(a = "ddiMatrix", b = "Matrix"), function(a, b, ...) { .solve.checkDim2(a@Dim[1L], b@Dim[1L]) if(a@diag == "N") { x <- a@x .solve.checkDiagonal(x) a@x <- 1 / x } a@Dimnames <- a@Dimnames[2:1] a %*% b }) ######################################################################## ## 7. indMatrix ######################################################################## setMethod("solve", signature(a = "indMatrix", b = "ANY"), function(a, b, ...) { d <- a@Dim .solve.checkDim1(d[1L], d[2L]) perm <- a@perm margin <- a@margin .solve.checkInd(perm, margin, d[1L]) p <- new("pMatrix") p@Dim <- d p@Dimnames <- a@Dimnames p@perm <- perm p@margin <- margin if(missing(b)) solve(p, ...) else solve(p, b, ...) }) setMethod("solve", signature(a = "pMatrix", b = "missing"), function(a, b, ...) { a@Dimnames <- a@Dimnames[2:1] a@margin <- if(a@margin == 1L) 2L else 1L a }) setMethod("solve", signature(a = "pMatrix", b = "vector"), function(a, b, ...) { m <- length(b) .solve.checkDim2(a@Dim[1L], m) perm <- if(a@margin == 1L) invertPerm(a@perm) else a@perm r <- as.double(b)[perm] names(r) <- a@Dimnames[[2L]] r }) setMethod("solve", signature(a = "pMatrix", b = "matrix"), function(a, b, ...) { d <- dim(b) .solve.checkDim2(a@Dim[1L], d[1L]) dn <- dimnames(b) perm <- if(a@margin == 1L) invertPerm(a@perm) else a@perm r <- new("dgeMatrix") r@Dim <- d r@Dimnames <- c(a@Dimnames[2L], if(is.null(dn)) list(NULL) else dn[2L]) r@x <- as.double(b[perm, , drop = FALSE]) r }) setMethod("solve", signature(a = "pMatrix", b = "Matrix"), function(a, b, ...) { .solve.checkDim2(a@Dim[1L], b@Dim[1L]) perm <- if(a@margin == 1L) invertPerm(a@perm) else a@perm r <- b[perm, , drop = FALSE] r@Dimnames <- c(a@Dimnames[2L], b@Dimnames[2L]) r }) ######################################################################## ## 8. Other ... a=matrix OR b=sparseVector ######################################################################## ## for now ... fast for this special case ... .spV2dgC <- function(x) { if(is.double(m <- length(x))) stop(gettextf("dimensions cannot exceed %s", "2^31-1"), domain = NA) i <- as.integer(x@i) - 1L nnz <- length(i) r <- new("dgCMatrix") r@Dim <- c(m, 1L) r@p <- c(0L, nnz) r@i <- i r@x <- if(!.hasSlot(x, "x")) rep.int(1, nnz) else if(is.complex(y <- x@x)) stop(gettextf("cannot coerce from %s to %s", "zsparseVector", "dgCMatrix"), domain = NA) else y r } ## for now ... fast for this special case ... .spV2dge <- function(x) { if(is.double(m <- length(x))) stop(gettextf("dimensions cannot exceed %s", "2^31-1"), domain = NA) r <- new("dgeMatrix") r@Dim <- c(m, 1L) r@x <- replace(double(m), x@i, if(!.hasSlot(x, "x")) 1 else if(is.complex(y <- x@x)) stop(gettextf("cannot coerce from %s to %s", "zsparseVector", "dgCMatrix"), domain = NA) else y) r } setMethod("solve", signature(a = "Matrix", b = "sparseVector"), function(a, b, ...) solve(a, .spV2dgC(b), ...)) # FIXME? drop(.)? setMethod("solve", signature(a = "MatrixFactorization", b = "sparseVector"), function(a, b, ...) solve(a, .spV2dgC(b), ...)) # FIXME? drop(.)? setMethod("solve", signature(a = "matrix", b = "Matrix"), function(a, b, ...) solve(.m2dense(a, ",ge"), b, ...)) setMethod("solve", signature(a = "matrix", b = "sparseVector"), function(a, b, ...) solve(.m2dense(a, ",ge"), .spV2dge(b), ...)) # FIXME? drop(.)? ######################################################################## ## 9. Exported solvers ######################################################################## ## a=dgCMatrix ## b=vector, matrix, or Matrix ## x=dg[Ce]Matrix .solve.dgC.lu <- function(a, b, tol = .Machine$double.eps, check = TRUE) { if(check && !is(a, "dgCMatrix")) a <- as(as(as(a, "CsparseMatrix"), "generalMatrix"), "dMatrix") trf <- lu(a, errSing = TRUE) solve(trf, b, tol = tol) } ## a=dgCMatrix ## b=vector or 1-column matrix ## x=double vector .solve.dgC.qr <- function(a, b, order = 3L, check = TRUE) { # -> MatrixModels if(check && !is(a, "dgCMatrix")) a <- as(as(as(a, "CsparseMatrix"), "generalMatrix"), "dMatrix") .Call(dgCMatrix_qrsol, a, b, order) # calls cs_qrsol } ## a=dgCMatrix ## b=vector or 1-column matrix ## x=list(L, coef, Xty, resid) .solve.dgC.chol <- function(a, b, check = TRUE) { # -> MatrixModels if(check && !is(a, "dgCMatrix")) a <- as(as(as(a, "CsparseMatrix"), "generalMatrix"), "dMatrix") .Call(dgCMatrix_cholsol, a, b) } Matrix/R/kronecker.R0000644000176200001440000010440214503364553014036 0ustar liggesusers## METHODS FOR GENERIC: kronecker ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kroneckerDN <- function(dnX, dX = lengths(dnX, FALSE), dnY, dY = lengths(dnX, FALSE), sep = ":") { dnr <- list(NULL, NULL) if(identical(dnX, dnr) && identical(dnY, dnr)) return(NULL) for(i in 1:2) { if(have.sX <- (nY <- dY[i]) && !is.null(sX <- dnX[[i]])) sX <- rep (sX, each = nY) if(have.sY <- (nX <- dX[i]) && !is.null(sY <- dnY[[i]])) sY <- rep.int(sY, times = nX) dnr[[i]] <- if(have.sX && have.sY) paste0(sX, sep, sY) else if(have.sX) paste0(sX, sep ) else if(have.sY) paste0( sep, sY) else if(nX && nY) rep.int(sep, nX * nY) } dnr } setMethod("kronecker", signature(X = "diagonalMatrix", Y = "diagonalMatrix"), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) { if(!(missing(FUN) || identical(FUN, "*"))) stop(gettextf("'%s' method must use default %s=\"%s\"", "kronecker", "FUN", "*"), domain = NA) if(any(as.double(dX <- X@Dim) * (dY <- Y@Dim) > .Machine$integer.max)) stop(gettextf("dimensions cannot exceed %s", "2^31-1"), domain = NA) r <- new("ddiMatrix") r@Dim <- dX * dY uX <- X@diag != "N" uY <- Y@diag != "N" if(uX && uY) r@diag <- "U" else { if(!uX) { X.ii <- X@x if(.M.kind(X) == "n" && anyNA(X.ii)) X.ii <- X.ii | is.na(X.ii) } if(!uY) { Y.ii <- Y@x if(.M.kind(Y) == "n" && anyNA(Y.ii)) Y.ii <- Y.ii | is.na(Y.ii) } r@x <- if(uX) rep.int(as.double(Y.ii), dX[1L]) else if(uY) rep(as.double(X.ii), each = dY[1L]) else rep(X.ii, each = dY[1L]) * Y.ii } if(make.dimnames && !is.null(dnr <- kroneckerDN(dimnames(X), dX, dimnames(Y), dY))) r@Dimnames <- dnr r }) if(FALSE) { # --NOT YET-- setMethod("kronecker", signature(X = "diagonalMatrix", Y = "denseMatrix"), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) { if(!(missing(FUN) || identical(FUN, "*"))) stop(gettextf("'%s' method must use default %s=\"%s\"", "kronecker", "FUN", "*"), domain = NA) if(any(as.double(dX <- X@Dim) * (dY <- Y@Dim) > .Machine$integer.max)) stop(gettextf("dimensions cannot exceed %s", "2^31-1"), domain = NA) uX <- X@diag != "N" uY <- FALSE shape <- .M.shape(Y) r <- new(`substr<-`("d.CMatrix", 2L, 2L, shape)) r@Dim <- dr <- dX * dY if(shape != "g") { uplo <- r@uplo <- Y@uplo if(shape == "t") uY <- Y@diag != "N" } if(!all(dr)) { r@p <- integer(dr[2L] + 1) if(uX && uY) r@diag <- "U" } else { m <- dY[1L] nX <- dX[1L] nY <- length(y <- Y@x) if(shape != "g" && nY > 1L && nY == prod(dY)) { Y <- pack(Y) nY <- length(y <- Y@x) } if(as.double(nX) * nY > .Machine$integer.max) stop(gettextf("number of nonzero entries cannot exceed %s", "2^31-1"), domain = NA) if(!uX && uY) { diag(Y) <- TRUE nY <- length(y <- Y@x) } if(is.logical(y) && .M.kind(Y) == "n") y <- y | is.na(y) if(shape == "g") { r@p <- seq.int(0L, by = m, length.out = dr[2L] + 1) r@i <- rep(seq.int(0L, by = m, length.out = nX), each = nY) + 0:(m-1L) } else if(uplo == "U") { r@p <- c(0L, cumsum(rep.int(1:m, nX))) r@i <- rep(seq.int(0L, by = m, length.out = nX), each = nY) + sequence.default(nvec = 1:m, from = 0L) } else { r@p <- c(0L, cumsum(rep.int(m:1, nX))) r@i <- rep(seq.int(0L, by = m, length.out = nX), each = nY) + sequence.default(nvec = m:1, from = 0:(m-1L)) } r@x <- if(uX) rep.int(as.double(y), nX) else { X.ii <- X@x if(.M.kind(X) == "n" && anyNA(X.ii)) X.ii <- X.ii | is.na(X.ii) as.double(y) * rep(X.ii, each = nY) } if(uX && uY) r <- ..diagN2U(r, sparse = TRUE) } if(make.dimnames && !is.null(dnr <- kroneckerDN(dimnames(X), dX, dimnames(Y), dY))) { if(shape == "s" && !isSymmetricDN(dnr)) r <- .M2gen(r) r@Dimnames <- dnr } r }) setMethod("kronecker", signature(X = "denseMatrix", Y = "diagonalMatrix"), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) { if(!(missing(FUN) || identical(FUN, "*"))) stop(gettextf("'%s' method must use default %s=\"%s\"", "kronecker", "FUN", "*"), domain = NA) if(any(as.double(dX <- X@Dim) * (dY <- Y@Dim) > .Machine$integer.max)) stop(gettextf("dimensions cannot exceed %s", "2^31-1"), domain = NA) shape <- .M.shape(X) uX <- FALSE uY <- Y@diag != "N" r <- new(`substr<-`("d.CMatrix", 2L, 2L, shape)) r@Dim <- dr <- dX * dY if(shape != "g") { uplo <- r@uplo <- X@uplo if(shape == "t") uX <- X@diag != "N" } if(!all(dr)) { r@p <- integer(dr[2L] + 1) if(uX && uY) r@diag <- "U" } else { m <- dX[1L] n <- dX[2L] nX <- length(x <- X@x) nY <- dY[1L] if(shape != "g" && nX > 1L && nX == prod(dX)) { X <- pack(X) nX <- length(x <- X@x) } if(as.double(nX) * nY > .Machine$integer.max) stop(gettextf("number of nonzero entries cannot exceed %s", "2^31-1"), domain = NA) if(uX && !uY) { diag(X) <- TRUE nX <- length(x <- X@x) } if(is.logical(x) && .M.kind(X) == "n") x <- x | is.na(x) if(shape == "g") { x. <- function() { j <- rep(1:n, each = nY) as.vector(`dim<-`(as.double(x), dX)[, j]) } r@p <- seq.int(0L, by = m, length.out = dr[2L] + 1) r@i <- rep.int(sequence.default(nvec = rep.int(m, nY), from = 0:(nY-1L), by = nY), n) r@x <- if(uY) x.() else { Y.ii <- Y@x if(.M.kind(Y) == "n" && anyNA(Y.ii)) Y.ii <- Y.ii | is.na(Y.ii) x.() * rep(Y.ii, each = m) } } else if(uplo == "U") { rep.1.n <- rep(1:n, each = nY) s <- sequence.default( nvec = rep.1.n, from = rep(1L + cumsum(0:(n-1L)), each = nY), by = 1L) r@p <- c(0L, cumsum(rep.1.n)) r@i <- sequence.default(nvec = rep.1.n, from = rep.int(0:(nY-1L), n), by = nY) r@x <- if(uY) as.double(x)[s] else as.double(x)[s] * rep.int(rep.int(Y@x, n), rep.1.n) } else { rep.n.1 <- rep(n:1, each = nY) s <- sequence.default( nvec = rep.n.1, from = rep(1L + cumsum(c(0L, if(n > 1L) n:2)), each = nY), by = 1L) r@p <- c(0L, cumsum(rep.n.1)) r@i <- sequence.default(nvec = rep.n.1, from = 0:(n*nY-1L), by = nY) r@x <- if(uY) as.double(x)[s] else as.double(x)[s] * rep.int(rep.int(Y@x, n), rep.n.1) } if(uX && uY) r <- ..diagN2U(r, sparse = TRUE) } if(make.dimnames && !is.null(dnr <- kroneckerDN(dimnames(X), dX, dimnames(Y), dY))) { if(shape == "s" && !isSymmetricDN(dnr)) r <- .M2gen(r) r@Dimnames <- dnr } r }) } # --NOT YET-- setMethod("kronecker", signature(X = "denseMatrix", Y = "denseMatrix"), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) { if(!(missing(FUN) || identical(FUN, "*"))) stop(gettextf("'%s' method must use default %s=\"%s\"", "kronecker", "FUN", "*"), domain = NA) if(any(as.double(dX <- X@Dim) * (dY <- Y@Dim) > .Machine$integer.max)) stop(gettextf("dimensions cannot exceed %s", "2^31-1"), domain = NA) shape <- switch(.M.shape(X), g = "g", t = if(.M.shape(Y) == "t" && X@uplo == Y@uplo) "t" else "g", s = if(.M.shape(Y) == "s") "s" else "g") r <- new(switch(shape, g = "dgeMatrix", t = "dtrMatrix", s = "dsyMatrix")) r@Dim <- dr <- dX * dY if(shape != "g") { r@uplo <- X@uplo if(shape == "t" && X@diag != "N" && Y@diag != "N") r@diag <- "U" } if(all(dr)) { X <- .M2m(X) Y <- .M2m(Y) storage.mode(X) <- "double" storage.mode(Y) <- "double" r@x <- as.vector(X[rep(seq_len(dX[1L]), each = dY[1L]), rep(seq_len(dX[2L]), each = dY[2L])]) * as.vector(Y[rep.int(seq_len(dY[1L]), dX[1L]), ]) } if(make.dimnames && !is.null(dnr <- kroneckerDN(dimnames(X), dX, dimnames(Y), dY))) { if(shape == "s" && !isSymmetricDN(dnr)) r <- .M2gen(r) r@Dimnames <- dnr } r }) setMethod("kronecker", signature(X = "diagonalMatrix", Y = "CsparseMatrix"), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) { if(!(missing(FUN) || identical(FUN, "*"))) stop(gettextf("'%s' method must use default %s=\"%s\"", "kronecker", "FUN", "*"), domain = NA) if(any(as.double(dX <- X@Dim) * (dY <- Y@Dim) > .Machine$integer.max)) stop(gettextf("dimensions cannot exceed %s", "2^31-1"), domain = NA) uX <- X@diag != "N" uY <- FALSE shape <- .M.shape(Y) r <- new(`substr<-`("d.CMatrix", 2L, 2L, shape)) r@Dim <- dr <- dX * dY if(shape != "g") { r@uplo <- Y@uplo if(shape == "t" && (uX & (uY <- Y@diag != "N"))) r@diag <- "U" } if(!all(dr)) r@p <- integer(dr[2L] + 1) else { if(!uX && uY) Y <- ..diagU2N(Y) if((nY <- (p <- Y@p)[length(p)]) == 0L) r@p <- integer(dr[2L] + 1) else if(as.double(nX <- dX[1L]) * nY > .Machine$integer.max) stop(gettextf("number of nonzero entries cannot exceed %s", "2^31-1"), domain = NA) else { head. <- if(length(Y@i) > nY) function(x) x[seq_len(nY)] else identity r@p <- c(0L, cumsum(rep.int(p[-1L] - p[-length(p)], nX))) r@i <- rep(seq.int(0L, by = dY[1L], length.out = nX), each = nY) + head.(Y@i) r@x <- if(uX) { if(.M.kind(Y) == "n") rep.int(1, nX * nY) else rep.int(as.double(head.(Y@x)), nX) } else { X.ii <- X@x if(.M.kind(X) == "n" && anyNA(X.ii)) X.ii <- X.ii | is.na(X.ii) if(.M.kind(Y) == "n") rep(as.double(X.ii), each = nY) else rep(as.double(X.ii), each = nY) * as.double(head.(Y@x)) } } } if(make.dimnames && !is.null(dnr <- kroneckerDN(dimnames(X), dX, dimnames(Y), dY))) { if(shape == "s" && !isSymmetricDN(dnr)) r <- .M2gen(r) r@Dimnames <- dnr } r }) setMethod("kronecker", signature(X = "CsparseMatrix", Y = "diagonalMatrix"), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) { if(!(missing(FUN) || identical(FUN, "*"))) stop(gettextf("'%s' method must use default %s=\"%s\"", "kronecker", "FUN", "*"), domain = NA) if(any(as.double(dX <- X@Dim) * (dY <- Y@Dim) > .Machine$integer.max)) stop(gettextf("dimensions cannot exceed %s", "2^31-1"), domain = NA) uX <- FALSE uY <- Y@diag != "N" shape <- .M.shape(X) r <- new(`substr<-`("d.CMatrix", 2L, 2L, shape)) r@Dim <- dr <- dX * dY if(shape != "g") { r@uplo <- X@uplo if(shape == "t" && (uX <- X@diag != "N") && uY) r@diag <- "U" } if(!all(dr)) r@p <- integer(dr[2L] + 1) else { if(uX && !uY) X <- ..diagU2N(X) if((nX <- (p <- X@p)[length(p)]) == 0L) r@p <- integer(dr[2L] + 1) else if(as.double(nY <- dY[1L]) * nX > .Machine$integer.max) stop(gettextf("number of nonzero entries cannot exceed %s", "2^31-1"), domain = NA) else { dp <- p[-1L] - p[-length(p)] j. <- which(dp > 0L) nj. <- length(j.) rep.dp <- rep(dp[j.], each = nY) s. <- sequence.default( nvec = rep.dp, from = rep(1L + p[j.], each = nY), by = 1L) r@p <- c(0L, cumsum(rep(dp, each = nY))) r@i <- (nY * X@i)[s.] + rep.int(rep.int(0:(nY-1L), nj.), rep.dp) r@x <- if(uY) { if(.M.kind(X) == "n") rep.int(1, nX * nY) else as.double(X@x)[s.] } else { Y.ii <- Y@x if(.M.kind(Y) == "n" && anyNA(Y.ii)) Y.ii <- Y.ii | is.na(Y.ii) if(.M.kind(X) == "n") rep.int(rep.int(as.double(Y.ii), nj.), rep.dp) else rep.int(rep.int(as.double(Y.ii), nj.), rep.dp) * as.double(X@x)[s.] } } } if(make.dimnames && !is.null(dnr <- kroneckerDN(dimnames(X), dX, dimnames(Y), dY))) { if(shape == "s" && !isSymmetricDN(dnr)) r <- .M2gen(r) r@Dimnames <- dnr } r }) setMethod("kronecker", signature(X = "CsparseMatrix", Y = "CsparseMatrix"), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) { if(!(missing(FUN) || identical(FUN, "*"))) stop(gettextf("'%s' method must use default %s=\"%s\"", "kronecker", "FUN", "*"), domain = NA) if(any(as.double(dX <- X@Dim) * (dY <- Y@Dim) > .Machine$integer.max)) stop(gettextf("dimensions cannot exceed %s", "2^31-1"), domain = NA) uX <- uY <- FALSE if((sX <- .M.shape(X)) == "t") uX <- X@diag != "N" if((sY <- .M.shape(Y)) == "t") uY <- Y@diag != "N" shape <- switch(sX, g = "g", t = if(sY == "t" && X@uplo == Y@uplo) "t" else "g", s = if(sY == "s") "s" else "g") cl <- "d.CMatrix" if(!all(dr <- dX * dY)) { substr(cl, 2L, 2L) <- shape r <- new(cl) r@Dim <- dr r@p <- integer(dr[2L] + 1) if(shape != "g") { r@uplo <- X@uplo if(shape == "t" && uX && uY) r@diag <- "U" } } else { substr(cl, 2L, 2L) <- if(shape == "s") "g" else shape r <- new(cl) r@Dim <- dr if(uX) X <- ..diagU2N(X) if(uY) Y <- ..diagU2N(Y) if(sY == "s") Y <- .M2gen(Y) else if(sX == "s") X <- .M2gen(X) if((nX <- (pX <- X@p)[length(pX)]) == 0L || (nY <- (pY <- Y@p)[length(pY)]) == 0L) r@p <- integer(dr[2L] + 1) else if(as.double(nX) * nY > .Machine$integer.max) stop(gettextf("number of nonzero entries cannot exceed %s", "2^31-1"), domain = NA) else { dpX <- pX[-1L] - (pX. <- pX[-length(pX)]) dpY <- pY[-1L] - (pY. <- pY[-length(pY)]) rep.dpX <- rep(dpX, each = dY[2L]) rep.dpY <- rep.int(dpY, dX[2L]) t1 <- rep.int(rep.dpY, rep.dpX) s1 <- sequence.default( nvec = rep.dpX, from = rep(1L + pX., each = dY[2L]), by = 1L) s2 <- sequence.default( nvec = t1, from = rep.int(rep.int(1L + pY., dX[2L]), rep.dpX), by = 1L) r@p <- c(0L, cumsum(rep.dpX * dpY)) r@i <- rep.int((dY[1L] * X@i)[s1], t1) + Y@i[s2] r@x <- if(.M.kind(X) == "n") { if(.M.kind(Y) == "n") rep.int(1, nX * nY) else as.double(Y@x)[s2] } else { if(.M.kind(Y) == "n") rep.int(as.double(X@x)[s1], t1) else rep.int(as.double(X@x)[s1], t1) * as.double(Y@x)[s2] } } if(shape == "t") { r@uplo <- X@uplo if(uX && uY) r <- ..diagN2U(r, sparse = TRUE) } else if(shape == "s") r <- .Call(R_sparse_force_symmetric, r, X@uplo) } if(make.dimnames && !is.null(dnr <- kroneckerDN(dimnames(X), dX, dimnames(Y), dY))) { if(shape == "s" && !isSymmetricDN(dnr)) r <- .M2gen(r) r@Dimnames <- dnr } r }) setMethod("kronecker", signature(X = "diagonalMatrix", Y = "RsparseMatrix"), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) .tCRT(kronecker(t(X), .tCRT(Y), FUN, make.dimnames, ...))) setMethod("kronecker", signature(X = "RsparseMatrix", Y = "diagonalMatrix"), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) .tCRT(kronecker(.tCRT(X), t(Y), FUN, make.dimnames, ...))) setMethod("kronecker", signature(X = "RsparseMatrix", Y = "RsparseMatrix"), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) .tCRT(kronecker(.tCRT(X), .tCRT(Y), FUN, make.dimnames, ...))) setMethod("kronecker", signature(X = "diagonalMatrix", Y = "TsparseMatrix"), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) { if(!(missing(FUN) || identical(FUN, "*"))) stop(gettextf("'%s' method must use default %s=\"%s\"", "kronecker", "FUN", "*"), domain = NA) if(any(as.double(dX <- X@Dim) * (dY <- Y@Dim) > .Machine$integer.max)) stop(gettextf("dimensions cannot exceed %s", "2^31-1"), domain = NA) uX <- X@diag != "N" uY <- FALSE shape <- .M.shape(Y) r <- new(`substr<-`("d.TMatrix", 2L, 2L, shape)) r@Dim <- dr <- dX * dY if(shape != "g") { r@uplo <- Y@uplo if(shape == "t" && (uX & (uY <- Y@diag != "N"))) r@diag <- "U" } if(all(dr)) { if(any((kind <- .M.kind(Y)) == c("n", "l"))) Y <- aggregateT(Y) if(!uX && uY) Y <- ..diagU2N(Y) nX <- dX[1L] nY <- length(Y@i) r@i <- rep(seq.int(0L, by = dY[1L], length.out = nX), each = nY) + Y@i r@j <- rep(seq.int(0L, by = dY[2L], length.out = nX), each = nY) + Y@j r@x <- if(uX) { if(kind == "n") rep.int(1, as.double(nX) * nY) else rep.int(as.double(Y@x), nX) } else { X.ii <- X@x if(.M.kind(X) == "n" && anyNA(X.ii)) X.ii <- X.ii | is.na(X.ii) if(kind == "n") rep(as.double(X.ii), each = nY) else rep(as.double(X.ii), each = nY) * as.double(Y@x) } } if(make.dimnames && !is.null(dnr <- kroneckerDN(dimnames(X), dX, dimnames(Y), dY))) { if(shape == "s" && !isSymmetricDN(dnr)) r <- .M2gen(r) r@Dimnames <- dnr } r }) setMethod("kronecker", signature(X = "TsparseMatrix", Y = "diagonalMatrix"), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) { if(!(missing(FUN) || identical(FUN, "*"))) stop(gettextf("'%s' method must use default %s=\"%s\"", "kronecker", "FUN", "*"), domain = NA) if(any(as.double(dX <- X@Dim) * (dY <- Y@Dim) > .Machine$integer.max)) stop(gettextf("dimensions cannot exceed %s", "2^31-1"), domain = NA) uX <- FALSE uY <- Y@diag != "N" shape <- .M.shape(X) r <- new(`substr<-`("d.TMatrix", 2L, 2L, shape)) r@Dim <- dr <- dX * dY if(shape != "g") { r@uplo <- X@uplo if(shape == "t" && (uX <- X@diag != "N") && uY) r@diag <- "U" } if(all(dr)) { if(any((kind <- .M.kind(X)) == c("n", "l"))) X <- aggregateT(X) if(uX && !uY) X <- ..diagU2N(X) nX <- length(X@i) nY <- dY[1L] r@i <- rep(nY * X@i, each = nY) + 0:(nY-1L) r@j <- rep(nY * X@j, each = nY) + 0:(nY-1L) r@x <- if(uY) { if(kind == "n") rep.int(1, as.double(nX) * nY) else rep(as.double(X@x), each = nY) } else { Y.ii <- Y@x if(.M.kind(Y) == "n" && anyNA(Y.ii)) Y.ii <- Y.ii | is.na(Y.ii) if(kind == "n") rep.int(as.double(Y.ii), nX) else rep(as.double(X@x), each = nY) * as.double(Y.ii) } } if(make.dimnames && !is.null(dnr <- kroneckerDN(dimnames(X), dX, dimnames(Y), dY))) { if(shape == "s" && !isSymmetricDN(dnr)) r <- .M2gen(r) r@Dimnames <- dnr } r }) setMethod("kronecker", signature(X = "TsparseMatrix", Y = "TsparseMatrix"), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) { if(!(missing(FUN) || identical(FUN, "*"))) stop(gettextf("'%s' method must use default %s=\"%s\"", "kronecker", "FUN", "*"), domain = NA) if(any(as.double(dX <- X@Dim) * (dY <- Y@Dim) > .Machine$integer.max)) stop(gettextf("dimensions cannot exceed %s", "2^31-1"), domain = NA) uX <- uY <- FALSE if((sX <- .M.shape(X)) == "t") uX <- X@diag != "N" if((sY <- .M.shape(Y)) == "t") uY <- Y@diag != "N" shape <- switch(sX, g = "g", t = if(sY == "t" && X@uplo == Y@uplo) "t" else "g", s = if(sY == "s") "s" else "g") cl <- "d.TMatrix" if(!all(dr <- dX * dY)) { substr(cl, 2L, 2L) <- shape r <- new(cl) r@Dim <- dr if(shape != "g") { r@uplo <- X@uplo if(shape == "t" && uX && uY) r@diag <- "U" } } else { substr(cl, 2L, 2L) <- if(shape == "s") "g" else shape r <- new(cl) r@Dim <- dr if(uX) X <- ..diagU2N(X) if(uY) Y <- ..diagU2N(Y) if(sY == "s") Y <- .M2gen(Y) else if(sX == "s") X <- .M2gen(X) nY <- length(Y@i) r@i <- i. <- rep(dY[1L] * X@i, each = nY) + Y@i r@j <- rep(dY[2L] * X@j, each = nY) + Y@j r@x <- if(.M.kind(X) == "n") { if(.M.kind(Y) == "n") rep.int(1, length(i.)) else rep.int(as.double(X@x), nY) } else { if(.M.kind(Y) == "n") rep(as.double(X@x), each = nY) else rep(as.double(X@x), each = nY) * as.double(Y@x) } if(shape == "t") { r@uplo <- X@uplo if(uX && uY) r <- ..diagN2U(r, sparse = TRUE) } else if(shape == "s") r <- .Call(R_sparse_force_symmetric, r, X@uplo) } if(make.dimnames && !is.null(dnr <- kroneckerDN(dimnames(X), dX, dimnames(Y), dY))) { if(shape == "s" && !isSymmetricDN(dnr)) r <- .M2gen(r) r@Dimnames <- dnr } r }) setMethod("kronecker", signature(X = "diagonalMatrix", Y = "indMatrix"), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) kronecker(X, .M2kind(Y, "n"), FUN, make.dimnames, ...)) setMethod("kronecker", signature(X = "indMatrix", Y = "diagonalMatrix"), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) kronecker(.M2kind(X, "n"), Y, FUN, make.dimnames, ...)) setMethod("kronecker", signature(X = "indMatrix", Y = "indMatrix"), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) { if((margin <- X@margin) != Y@margin) kronecker(.M2C(X), .M2C(Y), FUN, make.dimnames, ...) if(!(missing(FUN) || identical(FUN, "*"))) stop(gettextf("'%s' method must use default %s=\"%s\"", "kronecker", "FUN", "*"), domain = NA) if(any(as.double(dX <- X@Dim) * (dY <- Y@Dim) > .Machine$integer.max)) stop(gettextf("dimensions cannot exceed %s", "2^31-1"), domain = NA) r <- new("indMatrix") r@Dim <- dX * dY r@perm <- if(margin == 1L) rep(dY[2L] * (X@perm - 1L), each = dY[1L]) + rep.int(Y@perm, dX[1L]) else { r@margin <- 1L rep(dY[1L] * (X@perm - 1L), each = dY[2L]) + rep.int(Y@perm, dX[2L]) } if(make.dimnames && !is.null(dnr <- kroneckerDN(dimnames(X), dX, dimnames(Y), dY))) r@Dimnames <- dnr r }) ## Catch everything else with these: for(.cl in c("vector", "matrix")) { setMethod("kronecker", signature(X = "Matrix", Y = .cl), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) kronecker(X, .m2dense(Y, ",ge"), FUN, make.dimnames, ...)) setMethod("kronecker", signature(X = .cl, Y = "Matrix"), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) kronecker(.m2dense(X, ",ge"), Y, FUN, make.dimnames, ...)) } rm(.cl) setMethod("kronecker", signature(X = "denseMatrix", Y = "Matrix"), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) kronecker(.M2C(X), Y, FUN, make.dimnames, ...)) setMethod("kronecker", signature(X = "CsparseMatrix", Y = "Matrix"), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) kronecker(X, .M2C(Y), FUN, make.dimnames, ...)) setMethod("kronecker", signature(X = "RsparseMatrix", Y = "Matrix"), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) kronecker(X, .M2R(Y), FUN, make.dimnames, ...)) setMethod("kronecker", signature(X = "TsparseMatrix", Y = "Matrix"), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) kronecker(X, .M2T(Y), FUN, make.dimnames, ...)) setMethod("kronecker", signature(X = "diagonalMatrix", Y = "Matrix"), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) kronecker(X, .M2C(Y), FUN, make.dimnames, ...)) setMethod("kronecker", signature(X = "indMatrix", Y = "Matrix"), function(X, Y, FUN = "*", make.dimnames = FALSE, ...) kronecker(.M2kind(X, "n"), Y, FUN, make.dimnames, ...)) Matrix/MD50000644000176200001440000006466714550025127012052 0ustar liggesusersdead28547ab9f4749a4630fa7e7881e4 *DESCRIPTION 7866cc186e8ad4d6a243c271f64c13fc *LICENCE ba6604808100abfe8137ad02b0a04f22 *NAMESPACE d641435295187325a3663988363105bb *R/AllClass.R 41bdc701502b0096f23a48bde2df7b89 *R/AllGeneric.R 863a228d6948c7e1f0efddb4e0fef824 *R/Auxiliaries.R 94b926ced0ed00c0fd056996865155e0 *R/BunchKaufman.R f20a1e47661e7bf1ea1ffd0dbc145b3a *R/HBMM.R 7acb17192c1c08969822defdd531e35a *R/KhatriRao.R 17d0f339b9cd030f13ffc873abde414b *R/LU.R 383391d5e4d12c4c7369abb1990b6b21 *R/Math.R 72a0d8605a295bf56528b844cf59e313 *R/Ops.R 85747aff2573a899b697e2e727120871 *R/SparseM-conv.R b20351ebc9920c3528219fcc5522f61c *R/Summary.R e0e755ece77810961adf04e91b70230d *R/abIndex.R e2d05abaf1f4ebbe1adda99af6863935 *R/all.equal.R 0a3d332743633e23f1f178098be0d5d6 *R/bind2.R 5ba76f2df9a7550ba8762851525fad7f *R/chol.R 9a8bce4a85126b3b3935cdd890ef5bf8 *R/coerce.R 4b3415e4af41dabcbd6048b32280ec29 *R/colSums.R 73f70ce30c4eb94c71d69d824173f8e3 *R/condest.R a848a0850272aac7b5562d679adaea69 *R/construct.R dc61ddb7ae05aa3133071ba579837c72 *R/denseMatrix.R 79c09a13e4d88aaaf9a55735543441c5 *R/determinant.R 629d04a285348773c4e8bd34308d33cc *R/diagMatrix.R 067989137256de2d8e537d40471aa47a *R/dim.R 6b2a21f53902ea2a062e9b97895ed5a5 *R/eigen.R 8d5d3c7b32c7b9f7d7eebc1be0d76220 *R/expm.R ab5cc27deac115816214f76aa0ec9bdd *R/graph-conv.R cc55b09add598ed7fe8c723a5c630b52 *R/image.R dc8d8f51145233a1d0141dfef262f275 *R/indMatrix.R ee20f86a83c09162cce6a92ea40b121d *R/is.na.R bea101095f5f5c9b4705c11056440108 *R/kappa.R 618b44c13d0f660e8a6b91917593f007 *R/kronecker.R 8befb12aeaaa31bc53817f73d4528381 *R/nearPD.R b3fcccad9e9f23904619a072016db501 *R/nnzero.R 830390da54d850cdb68ce2c47c0de55e *R/not.R a165f9f3e6f7474e247d42e7b8414fcf *R/objects.R 66c8030926759f87234d58628bafe364 *R/perm.R 3da7275623f7bf2d32d28276a511f765 *R/posdef.R f77336ef6dbc816ab069a90d482728d9 *R/products.R 3c12768b00d5e2845f55d13c4b00b188 *R/qr.R 49a56dab6ff6e6a943dda3bb4ccf46b7 *R/rankMatrix.R eb631f40e60461240c94a9eeee347e64 *R/show.R 89b8a1434e8109b332810c2d0d0d6542 *R/solve.R 31b8d3853f6bed848a0714af7e9f94df *R/spModels.R 8418d68302196cfa3f2380a94e4d2a35 *R/sparseMatrix.R 768e95dd230030db02fa41b83c54e37f *R/sparseVector.R 64f26baaf7096cf33df4aaefd58be4d7 *R/subassign.R e79d7adbfcc224017905e2d9c3306bc3 *R/subscript.R 4e983e0d3d1a87f0e9058bc9cf0b6143 *R/which.R 4b678c1d95b4f8a0f5dd259904ba6bfa *R/zzz.R af387b75c02032478c85023d8e53cf37 *build/Matrix.pdf 4f3dda2ade8b34ae0296685e81dfc10a *build/stage23.rdb 75b445cb0f3b5549d3132a7236c6d050 *build/vignette.rds afeec9c25bf3c232f8567ee3f27cf0f6 *cleanup 9f8e37cf17a5d4811d0c28f07148cf7d *data/CAex.R c60c038f2c6d15c5303d81330991c838 *data/KNex.R d6193dad1031a61ebc3d3e38fabd252d *data/USCounties.R 0d65337740b3914f535239cbe6e8a2df *data/datalist a40150a1c71deabec67e61af2b8f7e38 *data/wrld_1deg.R f4f31b32389050a5f38097160a185de7 *inst/NEWS.Rd d1092f2de709b554fb06b516ee00a885 *inst/doc/Comparisons.R f6c9e4986022f1db4c085b8429d06fca *inst/doc/Comparisons.Rnw 1c06a154d9826ce6b0ea20a7786a2bc1 *inst/doc/Comparisons.pdf 3f45bdb5515081392d14b87f4770cb2b *inst/doc/Design-issues.R 2bd2896847fb11eaf102158b8696c884 *inst/doc/Design-issues.Rnw 4d96b8c1ac1f86a3cc193b08b38b53e7 *inst/doc/Design-issues.pdf 3f87d045a10e0afc85a3385bab8f215b *inst/doc/Intro2Matrix.R 448278dab638a78df6eb59270772cbe2 *inst/doc/Intro2Matrix.Rnw ddaf6aedae6a73934bdd9c234a6c6d88 *inst/doc/Intro2Matrix.pdf 1a59a7d3257a30349a5e10285ea05a69 *inst/doc/Introduction.R c39a26dfe7ccaafd044e88468155b153 *inst/doc/Introduction.Rnw 506df511b5cfdb6b51d965a19f8997f9 *inst/doc/Introduction.pdf 20ced7019f5a55639aa1af1a2dfa1057 *inst/doc/SuiteSparse/AMD.txt facc21d5bf9bcbf3e57a8b3c7bd1caa0 *inst/doc/SuiteSparse/CHOLMOD.txt a6693872cf6e74e758f3fa327c606fec *inst/doc/SuiteSparse/COLAMD.txt d75882d4bb768ba0ea352291652daaee *inst/doc/SuiteSparse/SPQR.txt c7da19803d926fe0e3604c08bedfb3c5 *inst/doc/SuiteSparse/SuiteSparse_config.txt e4e486aee6a99cb21909bb6de32db68d *inst/doc/sparseModels.R 813e0c8cc7a5f7ecff43e5882270a431 *inst/doc/sparseModels.Rnw 635d7015f327e21d48f20a6dbd079a1c *inst/doc/sparseModels.pdf dcd11f6947f910f743254824e930b2c7 *inst/external/CAex_slots.rda be886d6bb832210bb654b9ad064fe0ff *inst/external/KNex_slots.rda 90f019ec81e67d7f3542f7ca39bf3f2d *inst/external/USCounties_slots.rda ecf98cf53529ca8e794e48f1ce4e4bde *inst/external/Z_NA_rnk.rds f01fae298b6f33c20cef0ab32ee468c4 *inst/external/jgl009.mtx 47bc35200e7b3fc1cdd6ab1adbeef3a0 *inst/external/lund_a.mtx fc72dd2599982f25f9ffbfc75f149134 *inst/external/lund_a.rsa a5748e10322306f8c2114db09cd58dd8 *inst/external/pores_1.mtx 8758e19cf3478732e62e563b638bcda7 *inst/external/symA.rda 7980f700b4fd62d0d6de7f96201b2645 *inst/external/symW.rda 7e22a368a5d129fc7396432949fb72ab *inst/external/test3comp.rda 697db4242eb44425ce2550fafdc957a8 *inst/external/utm300.rua ca51a0b8b76e7ea3e7881cc8da1390b1 *inst/external/wrld_1deg_slots.rda 5ce5ea63a73e4641173fe37b6a809a01 *inst/external/wrong.mtx 9a7e9eac66c8e2e4f302ef50e52e7a56 *inst/include/Matrix.h 393d17634a64d5414c62d83cb4b05764 *inst/include/Matrix/Matrix.h a8f80507036f68ab0180c36e4d874abd *inst/include/Matrix/alloca.h 9453d69ed641a1842043a4b28b677784 *inst/include/Matrix/cholmod-utils.h 573270a60b73ad502ab087e00bb22d91 *inst/include/Matrix/cholmod.h 851b528969721a8bfa532fd9ec412642 *inst/include/Matrix/remap.h 60c91702300acb03cf57dfda5fc26a56 *inst/include/Matrix/stubs.c 7cd2c1c3b9a38364f561a7ae0ff84c3d *inst/include/Matrix/version.h 7d96680b80f7792dda638a3900abab51 *inst/include/Matrix_stubs.c 521f406135ff54057933d9a152482ec7 *inst/include/cholmod.h f16fb9f317d02aa9f4b0423532a2826c *inst/po/de/LC_MESSAGES/Matrix.mo e64d7f98b7b164d7519ae7f385ad91ba *inst/po/de/LC_MESSAGES/R-Matrix.mo 283a18fda23fb8628c5e3f8cad1ec439 *inst/po/en@quot/LC_MESSAGES/Matrix.mo 1b3fd5aba1569b97f681c07f53a1453d *inst/po/en@quot/LC_MESSAGES/R-Matrix.mo 215caefb1c998a6ee9fc101523c1b30c *inst/po/fr/LC_MESSAGES/Matrix.mo 205f3b581952a8f3ddbc4d4cafa59ba4 *inst/po/fr/LC_MESSAGES/R-Matrix.mo aa7f2b397344536699a2bb3a3164f2da *inst/po/it/LC_MESSAGES/Matrix.mo 648f3d77497c576252e81fa04d8ca03c *inst/po/it/LC_MESSAGES/R-Matrix.mo ec0e2a979284da186be81f9103a684bb *inst/po/ko/LC_MESSAGES/Matrix.mo d06bf95a913cc6981ddc8d7c7c870b7f *inst/po/ko/LC_MESSAGES/R-Matrix.mo 936d175c18f4fb816fa4a4970bc39367 *inst/po/lt/LC_MESSAGES/Matrix.mo b4d9022d77514c2a71fc5692ac69c80e *inst/po/lt/LC_MESSAGES/R-Matrix.mo 8e3ad6e4b476f6bea60a6a5429dd20b7 *inst/po/pl/LC_MESSAGES/Matrix.mo 71c78aeb12f673f7e0665cc97cec9c76 *inst/po/pl/LC_MESSAGES/R-Matrix.mo 5d9af34027b624cf8ec958cbfdfe915b *inst/test-tools-1.R 53816ab0f5d228096e37b3aaa3bd6fc0 *inst/test-tools-Matrix.R c54af18acaf2a18fad0cfe5f4fe54e83 *inst/test-tools.R 2f258fd7ae54ca8e0c16d7538fb1810e *man/BunchKaufman-class.Rd cefbc46d17630ba3c2a013206b741886 *man/BunchKaufman-methods.Rd ea7ad17e8de043439cfdeebbb25ff032 *man/CAex.Rd 7e59df3e663ffc1d92e78307739b3339 *man/CHMfactor-class.Rd c867760baa3dee3b88eae2f615327b15 *man/Cholesky-class.Rd fad43eb7e5b857b535f8cdeeb7f72c46 *man/Cholesky.Rd 967b9180ff69515cf75eeabd0212cc0f *man/CsparseMatrix-class.Rd bec00d32ab2f01ac1a0c10b85bf3508b *man/Diagonal.Rd 0cf81d62916c9f84c70bb3df8bac66f6 *man/Hilbert.Rd 245096209777000baa3d711f452beed0 *man/KNex.Rd 766bcb9db86ea1733136c73bdeb29508 *man/KhatriRao.Rd b738442c0f0993f176337480e48b9d0d *man/LU-class.Rd a0a7ddddbe42a96656fcf174d7644ae5 *man/Matrix-class.Rd 27640f6262dab5c41f35014d291dbe19 *man/Matrix-defunct.Rd f76b61291a35e0f638d309a32a70e376 *man/Matrix-deprecated.Rd 598516534cf2b915ff341b4d63aad61d *man/Matrix.Rd 3c4bf32296b8480193fe30125bca1bb5 *man/MatrixClass.Rd bd3dce068f6b3cc626dd331fd21f873e *man/MatrixFactorization-class.Rd 9342c1c4c46385d83ba6e153e98f93cb *man/RsparseMatrix-class.Rd 64047cfd57b039ebfe665176bbd6556e *man/Schur-class.Rd bb8e14699a2db8acd01a2b1383aadaed *man/Schur.Rd d7da791c3f651790bd3762ceb2426c3c *man/SparseM-conv.Rd 5a159696cf62f4098a1fc9c28d84a7d3 *man/Subassign-methods.Rd afc8dc11f750be8e2baeb2f250502829 *man/TsparseMatrix-class.Rd 878b685a8830a6a9b246e271f08de034 *man/USCounties.Rd e8742ccaf058cc44a9482cbcdfd50e2f *man/Xtrct-methods.Rd 3de3d37c17171bf90a417615ee83d74b *man/abIndex-class.Rd fcc83ecd00de345e89e3f4fd51544255 *man/abIseq.Rd 2b6cb5615438cdc36e89f5b96ff94baf *man/all.equal-methods.Rd 2b5d4a17103a74dd33b0d68b5a35b3b5 *man/atomicVector-class.Rd 6648de3757eb262eb643c87f2d1945bd *man/band.Rd bdbedf88db3709b91fee02404f570928 *man/bandSparse.Rd 0a71443575762f0c15fed79a880e117a *man/bdiag.Rd d9c43ef03b0db490d2548c4889c0ce1b *man/boolean-matprod.Rd d4d34696eceef2a9fb972a1db930f0a2 *man/cBind.Rd ae7ee7c0dd1c9f4181623dae808f4fe8 *man/chol.Rd 93ca58a43078f2cf5f20f0dcd586d63e *man/chol2inv-methods.Rd 57cf38160f8d7ca08c3c8e197a4be3fd *man/colSums.Rd cc0baa18fab662acc1dec8136367c98a *man/compMatrix-class.Rd 37187eb2930421a7a8058dfe28420e4e *man/condest.Rd d05401de9e47c8b5d36f10891cec5300 *man/dMatrix-class.Rd af2b6fa724abf84be877a4552095e067 *man/ddenseMatrix-class.Rd 14120a7152aa753135199518d9df7865 *man/ddiMatrix-class.Rd 3185e295c17031665892edfcaad5fed6 *man/denseMatrix-class.Rd 97d2afdab45dca3b2818620845225870 *man/dgCMatrix-class.Rd c0b134f5e751f760f4f60495888439f2 *man/dgRMatrix-class.Rd a17c04aa44294870428deb29386a5fa2 *man/dgTMatrix-class.Rd f0407dddde00f3e54ca4d4b656a3c079 *man/dgeMatrix-class.Rd 837f10f351fac09f984104016461926d *man/diagU2N.Rd 287f4956dc7629d18dc3b8c09ddf7d1b *man/diagonalMatrix-class.Rd 1589473042f7a3649b2e231a96222512 *man/dimScale.Rd 326daf4ed53d4314f8b298f88da4ee95 *man/dmperm.Rd 9dcd996d506f0a1a92259ab658a25192 *man/dpoMatrix-class.Rd 1b4b6104d111472373cfe1acdc605085 *man/drop0.Rd 0e3390f6d482c4a5cd4372639ebe6f6e *man/dsCMatrix-class.Rd b61082a3e562b1a5ac36a25d934df38b *man/dsRMatrix-class.Rd 0dfbd82b81b8881f3ddb4cf6ec8d8433 *man/dsparseMatrix-class.Rd 7f295e2662e5ccb28bc7a3079d8ed7f0 *man/dsyMatrix-class.Rd 8fc3d49bfa636ace0f9f09ff5726521d *man/dtCMatrix-class.Rd 09bad402e9ce15538b62fedc8641da36 *man/dtRMatrix-class-def.Rd a65c8694c345ab574ddd7ca26ab9b986 *man/dtpMatrix-class.Rd dbb9523ebdb9c6f90b6d42c5043dc104 *man/dtrMatrix-class.Rd 1571202ebd7ccac77355a3948895ff2b *man/expand.Rd 5349189c7d182d444a83d35768a2e626 *man/expm.Rd 8e94ad028775467cd069de4afe77d804 *man/externalFormats.Rd 02c720f10b2ee80593bc385a9ba7dfb9 *man/facmul.Rd 59db1566e0cf830e4198c57f977feeb2 *man/fastMisc.Rd b3a0c135476b28bf7569e96174bbeb8e *man/forceSymmetric.Rd 544ea441f152320cf9a6e94c11ff84c0 *man/formatSparseM.Rd 0f54fb0f3457bb48b78da8521be53128 *man/generalMatrix-class.Rd da8ce2fc366523d31ec02e036c8d4690 *man/graph2T.Rd 334d679156521d39c80673b7138736c8 *man/image-methods.Rd 35673a6311eb2119721fa1fdf91515a6 *man/indMatrix-class.Rd a1ab8d5ea99ad38051701c106e033a99 *man/index-class.Rd cbb67630dfbac437f9d7e9a7648e03ed *man/invPerm.Rd 44270ed554b737f9ebf9050ac16505c0 *man/is.na-methods.Rd 390ef00efc06f4e5ba986179f9be1f28 *man/is.null.DN.Rd d095e553e6911c14d31a319dfa3c9591 *man/isSymmetric-methods.Rd 767fe8a839b710ff0e6cc278be3f48d2 *man/isTriangular.Rd 73fff25f929d0743e6c80ffa1d714d06 *man/kronecker-methods.Rd 7fc275d08b1b5122cf363ba3b047b78c *man/ldenseMatrix-class.Rd fa91e53c4ec47d073e09c126b3739244 *man/ldiMatrix-class.Rd 618fc22c94018fb2b422a93cb5a08ad0 *man/lgeMatrix-class.Rd 4cd7c11599e2b72cee0e1be8ce63d8b2 *man/lsparseMatrix-classes.Rd ba8662010144ffc10b1f1504f8122950 *man/lsyMatrix-class.Rd a08a6989e10415fe94aadafeadeeb57c *man/ltrMatrix-class.Rd 03608a3346e9cb3686c9ed0ebecb6f7e *man/lu.Rd 4ca9cecf4789f9d6c063b1a7f0bc91df *man/macros/local.Rd e4b848a97c4d271ddd245ddb0757e604 *man/mat2triplet.Rd cbb84c3f84d7ae45ee527fd4c67a90dc *man/matrix-products.Rd b1c829c1061f4b6d68baa86413b3312e *man/nMatrix-class.Rd bcc0684524ef635f554b0e473e40c07d *man/ndenseMatrix-class.Rd cc6c44c14a8392071abe325799cc90c2 *man/nearPD.Rd 28930b1c705719e6afcab8aea870ec0c *man/ngeMatrix-class.Rd fa06fd574d4e47d3c17d765b6d7b6018 *man/nnzero.Rd 9ae810a456018192a784228abcececd9 *man/norm.Rd da6e6d571207b17edb907ca23774902f *man/nsparseMatrix-classes.Rd abc1d387f0b990d7b92edf8179a7638a *man/nsyMatrix-class.Rd 9e2a8c507c74de92a095f0850af4826b *man/ntrMatrix-class.Rd 76f34ad30ce23c52a8cdb5e2fd3203d6 *man/number-class.Rd 6ab28432582e3d39abf69ee16493fa9d *man/pMatrix-class.Rd fb6a793c391cc14f23f368aee00baa9f *man/packedMatrix-class.Rd e4ee4dcf3182e1879220877382b4f963 *man/printSpMatrix.Rd d04bb8807a93274f6dd80c7c0b18d8a9 *man/qr-methods.Rd 6e3a120611604781386e5186158b0873 *man/rankMatrix.Rd e5d1405bf89e755ca3e9f08fffacc35b *man/rcond.Rd e477841f445dcdc94519c80406941469 *man/rep2abI.Rd 59c06c927969324f27b47585ecb18410 *man/replValue-class.Rd a4109e704374bad3ef6aab75ccb8f8d9 *man/rleDiff-class.Rd 9a4e3ae4ca031791c7c366b5db715334 *man/rsparsematrix.Rd ea9a120657e97f87769b241dd536764f *man/solve-methods.Rd 753adc3e257e2d4bc9d9cff17779ec15 *man/spMatrix.Rd fd22402875896e84469ab3e8b9a06856 *man/sparse.model.matrix.Rd 19907299c8cad824cc36fec5bf469499 *man/sparseLU-class.Rd f2ec428a78fc56b8281872efcd4e56d5 *man/sparseMatrix-class.Rd f4f5ea8780961c40e4eaa051cbcd0460 *man/sparseMatrix.Rd e2fc23af3acb46256f52620a786ee08b *man/sparseQR-class.Rd e861d6fe9ee84f33de30851bf09b72a1 *man/sparseVector-class.Rd c44929260581afc4a5958dd01a3ce944 *man/sparseVector.Rd 9d3271af3afc2721a3fa48329d959873 *man/symmetricMatrix-class.Rd 7844008e1a149822f8c5f6085bf7510f *man/symmpart.Rd 66409f3da0094a78d44adfb7faf12b17 *man/triangularMatrix-class.Rd a1fc3f49b50407991ef4c9be7ee7401e *man/uniqTsparse.Rd b535f1c3a83155c6f97a9f099537a328 *man/unpack.Rd 0c8af014b0ee2fab6c08b98eafb59832 *man/unpackedMatrix-class.Rd 9d74e16af8d8612781eb7432f8194b1f *man/unused-classes.Rd 673d3bd30c6c5855e5ec845950ee8fdc *man/updown.Rd 88a8da5ec55171d282a0ca47e0951a51 *man/wrld_1deg.Rd 20a1c583fe09781cb828778f916696da *po/Matrix.pot 868d688e0641c2965e0d277b960187ac *po/R-Matrix.pot 5e0bef95460914366b1f184347f5f786 *po/R-de.po 0de17281f74bf11c7f37ee23178cb2b0 *po/R-fr.po 261e860c4dcf6528bca1f10e0701b1bb *po/R-it.po d9b097244348a62df9422a6f978814bc *po/R-ko.po 1a33730601671dd25bb02dab9ab4575c *po/R-lt.po 43872f008f14d5498f9a9fce90c2dca1 *po/R-pl.po 60fbf799f1910b7e43f0e5dd60cd9aaa *po/de.po 4fee617ac2da78f689ac9b947085506b *po/fr.po 8eb96b681aa671d7d6a1f32462d2888c *po/it.po d8c201b5a23fdca11bcab566b879dcce *po/ko.po f5c42ed3d1e81aab0c7bbe3872f85312 *po/lt.po ac472f54cf760d6828cb8cdaa9b3db10 *po/pl.po d564f974ab9d0216714a4e9bb460888a *src/AMD/Include/amd.h 99cad8231a3e300cbfd5561f86cfc35c *src/AMD/Include/amd_internal.h 44b5e7133f7f818d07d17637c8410c51 *src/AMD/Makefile 2df4e18aa3b3cc889f3d521e98a42c20 *src/AMD/Source/Makefile 41ec90eacd97a62c7393f9a66f714662 *src/AMD/Source/amd_1.c fc12596df9e5a12177d1c6e5dba8fce5 *src/AMD/Source/amd_2.c 23003d2ff7e400dc8738a838951a80cb *src/AMD/Source/amd_aat.c 359f2804fbe6f2cdf92a592a8bb6346e *src/AMD/Source/amd_control.c c0a3524d4f5ddcb63065eeabe8ae57f8 *src/AMD/Source/amd_defaults.c 896cccbf9ea7f21142964fe1868da79d *src/AMD/Source/amd_dump.c d2c2d032a544ad771e1cbc5c4919c4e0 *src/AMD/Source/amd_info.c 086739e8011cdb4d98a8605cca59f0ab *src/AMD/Source/amd_order.c 5f8f83de491e328aefbff08a09c3b467 *src/AMD/Source/amd_post_tree.c d696467688131d58e3acf9e5a627360e *src/AMD/Source/amd_postorder.c 5d46a2442b5d099f6ba9fa6b427d7a1f *src/AMD/Source/amd_preprocess.c 56f64a3203f5752b5a012b806f101d8c *src/AMD/Source/amd_valid.c c07546f3d3e2857387fe0cdce6d7b255 *src/AMD/Source/make-Make.R 55d6a34f38b378f64f9bc05c96168890 *src/AMD/Source/make_o.mk d2d49c52f19cae17de0efe9bbd0e50b0 *src/CHOLMOD/Check/License.txt a6a8759ae19d9078ec04530d31c5180b *src/CHOLMOD/Check/cholmod_check.c a790fc8c409f465c93400cbaf8e2ea49 *src/CHOLMOD/Check/cholmod_read.c f538b7f07e4248e2eb67d16c7571fb41 *src/CHOLMOD/Check/cholmod_write.c 887d3c7dc221e09fa581c96ce66e76f2 *src/CHOLMOD/Cholesky/License.txt ea289556183948c4b3f5309656beb0b6 *src/CHOLMOD/Cholesky/cholmod_amd.c 0bec6c175861bf722413633c5127d21a *src/CHOLMOD/Cholesky/cholmod_analyze.c 2b0f3a59a18076d7270c5c856f65ae94 *src/CHOLMOD/Cholesky/cholmod_colamd.c ab14e2224df91d90a726aa8d37125d1f *src/CHOLMOD/Cholesky/cholmod_etree.c 24793eeb061a9c26b3834f0f422d8441 *src/CHOLMOD/Cholesky/cholmod_factorize.c d139d2ca810efcb360eba3dedb3a29b5 *src/CHOLMOD/Cholesky/cholmod_postorder.c 6637f976d6cbec2bbea62c1964fec0a7 *src/CHOLMOD/Cholesky/cholmod_rcond.c 8ec749d7a2b29875841b598d3672ed89 *src/CHOLMOD/Cholesky/cholmod_resymbol.c 336f36a7952773b8b724b5932d6f9e17 *src/CHOLMOD/Cholesky/cholmod_rowcolcounts.c e1725967691d217d614e749bb3db913d *src/CHOLMOD/Cholesky/cholmod_rowfac.c 42790e888b94da5ce7f8d822258336f4 *src/CHOLMOD/Cholesky/cholmod_solve.c 0b29fb59bd00892cee38508bd6c1be00 *src/CHOLMOD/Cholesky/cholmod_spsolve.c 189e18b2104803d0e0d39a3b6b03e99f *src/CHOLMOD/Cholesky/debug_c 9574c620c6e39670d278947452787ded *src/CHOLMOD/Cholesky/t_cholmod_lsolve.c 1e79a8a5620e2cd5d76c18ce352245d8 *src/CHOLMOD/Cholesky/t_cholmod_ltsolve.c 4596c898fa5572f49cf428c9ea23366f *src/CHOLMOD/Cholesky/t_cholmod_rowfac.c f648c37e680eb79b677aaa0efe66c810 *src/CHOLMOD/Cholesky/t_cholmod_solve.c 0b650d81b9287230f7335cb5d6404b97 *src/CHOLMOD/Core/License.txt eb4c6ad7286636777285b2163ce8b44c *src/CHOLMOD/Core/cholmod_aat.c 270db0e35c4bba3b73fabc1d1cf4c297 *src/CHOLMOD/Core/cholmod_add.c a2af0345308ccae36d74456a752735ac *src/CHOLMOD/Core/cholmod_band.c a750efa7b7a60dc535b8786dbcc6e95b *src/CHOLMOD/Core/cholmod_change_factor.c 32d83812ab434be37e53f8bc0a6c3e1f *src/CHOLMOD/Core/cholmod_common.c ff68b20bd393e64b72a82a7297a2f5be *src/CHOLMOD/Core/cholmod_complex.c 9cf2038ab02d7f1a1398e7a792bceee8 *src/CHOLMOD/Core/cholmod_copy.c f12e1b0e82a3d318a8c39634ffc18867 *src/CHOLMOD/Core/cholmod_dense.c c6cb3cc439b75d3f899b4bc6a373a047 *src/CHOLMOD/Core/cholmod_error.c 98d05f2c2021391e2436b3d98fcc9b72 *src/CHOLMOD/Core/cholmod_factor.c e52ca0b9a66e14c51adcd5bdf2518233 *src/CHOLMOD/Core/cholmod_memory.c f6a9a08dcfa01c17a2db3ff197ea5cd9 *src/CHOLMOD/Core/cholmod_sparse.c cc8a39157e8a4bfd5d09d67216ad2df9 *src/CHOLMOD/Core/cholmod_transpose.c 896f74cc1d05206ddb210503e289e59b *src/CHOLMOD/Core/cholmod_triplet.c edf80c5be30905b6e7d39c6bb475614f *src/CHOLMOD/Core/cholmod_version.c b9a0f158d3c428138474b466317b05eb *src/CHOLMOD/Core/t_cholmod_change_factor.c d312cf79f2399b70f12009f7f4c97bed *src/CHOLMOD/Core/t_cholmod_dense.c c0a69959da9f6c8d9b7ccefff044ac88 *src/CHOLMOD/Core/t_cholmod_transpose.c e7557b90fc46f07d8a1a3a0ca97f4367 *src/CHOLMOD/Core/t_cholmod_triplet.c 43dea0a98ff00c4d001efdcf9e1107fe *src/CHOLMOD/Include/License.txt aebdd50c54b3d11988fa4be5fb71d05f *src/CHOLMOD/Include/README.txt cf4197c2fc01aca0b8f09a2a912f1e3e *src/CHOLMOD/Include/cholmod.h ff92b3b77108a58e9aa71b645c3accb3 *src/CHOLMOD/Include/cholmod_blas.h b6e1a9dd6eda272f5fd566ae2a3f1b19 *src/CHOLMOD/Include/cholmod_camd.h 4af20acf26e4884121f510ab9b9677cb *src/CHOLMOD/Include/cholmod_check.h 79abc202047989ee26ef196e2832afbf *src/CHOLMOD/Include/cholmod_cholesky.h b9b557b4fce4ed0c5d45fdb29eacf094 *src/CHOLMOD/Include/cholmod_complexity.h f30283b57821e962699fcdebe401d29e *src/CHOLMOD/Include/cholmod_config.h 3be9fafda32e1e7cdc1773bd3afea1d4 *src/CHOLMOD/Include/cholmod_core.h af5810b5faf02bc0c2bc32e1ae8f5d3d *src/CHOLMOD/Include/cholmod_internal.h 49b635af7e67fe230a215dc6392c2e81 *src/CHOLMOD/Include/cholmod_io64.h 0150a977ea09e2206eeefc79655e7148 *src/CHOLMOD/Include/cholmod_matrixops.h 314f9a0032e76ebed04f8df80e07d0bf *src/CHOLMOD/Include/cholmod_modify.h 0164f39b8f2a5f88f9b2cfcfbdac3f6a *src/CHOLMOD/Include/cholmod_partition.h a11bda6a441971c0634446a7c8b5cafe *src/CHOLMOD/Include/cholmod_supernodal.h 3ea4215bdf808d34bb7b2fe19e3b4e9e *src/CHOLMOD/Include/cholmod_template.h c678a521e98cb0298997e2ac0109da3f *src/CHOLMOD/Lib/Makefile a298bc42f87addd27a4b4c0834b444e0 *src/CHOLMOD/Makefile e60f67b276c37ca2fc0796a45b61c470 *src/CHOLMOD/MatrixOps/License.txt 9884ada423d22844b53841d5d30c63ee *src/CHOLMOD/MatrixOps/cholmod_drop.c cdaaeb7402db7439d58861281ab7ebaf *src/CHOLMOD/MatrixOps/cholmod_horzcat.c 7aa434c4cfeb67ddd4fc4d21260df4af *src/CHOLMOD/MatrixOps/cholmod_norm.c b3d041382e74124c62ad753781b04a2a *src/CHOLMOD/MatrixOps/cholmod_scale.c 8ecc9194aa1b76412d72ca23704716ba *src/CHOLMOD/MatrixOps/cholmod_sdmult.c a3208187e74f173316038592d21777a7 *src/CHOLMOD/MatrixOps/cholmod_ssmult.c 120868ee7de5785fdd40c9ed6c540544 *src/CHOLMOD/MatrixOps/cholmod_submatrix.c fe53d8a9195fa77ca4bdb401942b8681 *src/CHOLMOD/MatrixOps/cholmod_symmetry.c ab660c53894c46ac21d8db5f4f555a80 *src/CHOLMOD/MatrixOps/cholmod_vertcat.c 7e537be46652d9cb9dd841f2475aacdc *src/CHOLMOD/MatrixOps/t_cholmod_sdmult.c e38b4b22e31f8f215bbf4580cf50619c *src/CHOLMOD/Modify/License.txt 5ffd4e3a5d8847e7d7addd09f1767be4 *src/CHOLMOD/Modify/cholmod_rowadd.c 7c0358e2b63264c221e6760294bf97ba *src/CHOLMOD/Modify/cholmod_rowdel.c 69bccd35100b4e78d4d9bc475f1748b7 *src/CHOLMOD/Modify/cholmod_updown.c 8da287ae47456c8c5e4f7203c41caa00 *src/CHOLMOD/Modify/t_cholmod_updown.c 627b70a1a8817fe8186a540f5a0f5e36 *src/CHOLMOD/Modify/t_cholmod_updown_numkr.c b0cf7a9044494b5ea9481a1728c710e6 *src/CHOLMOD/Partition/License.txt ca532ef26111d9c42d7ba0ec2df1f7ff *src/CHOLMOD/Partition/cholmod_camd.c 6fe37e68727d1cdc783989ced2041f92 *src/CHOLMOD/Partition/cholmod_ccolamd.c c93f24417b08ee13217b2facc68dbde6 *src/CHOLMOD/Partition/cholmod_csymamd.c 04ef9f55e9bc467dd6ccb2b7db0d7482 *src/CHOLMOD/Partition/cholmod_metis.c 0fdefe77fe37ebfdc52e62a638997624 *src/CHOLMOD/Partition/cholmod_nesdis.c 08629b176847ad848a0327e6fde2210a *src/CHOLMOD/Supernodal/License.txt 42a014820a3ccf68e1189d92a6056175 *src/CHOLMOD/Supernodal/cholmod_super_numeric.c 5e0478f02c0954fd0b1b3547e4d2ecdf *src/CHOLMOD/Supernodal/cholmod_super_solve.c f020861359cd23510fb14489e403d349 *src/CHOLMOD/Supernodal/cholmod_super_symbolic.c 1ad404233a51f38540a959c36d880bda *src/CHOLMOD/Supernodal/t_cholmod_gpu.c 47985c9e3105b2eb8ad5545f843b4d49 *src/CHOLMOD/Supernodal/t_cholmod_super_numeric.c 087752a1b22d12e5e51a5a4852d57323 *src/CHOLMOD/Supernodal/t_cholmod_super_solve.c 22baa75870c7411e901df9b3bc420eaa *src/COLAMD/Include/colamd.h 44b5e7133f7f818d07d17637c8410c51 *src/COLAMD/Makefile 7110287b532b98a27a8324742cbf8edd *src/COLAMD/Source/Makefile b4a48a5fb881806aa039010f5f62ca26 *src/COLAMD/Source/colamd.c cf83eea5f65899ece9d5c64868738458 *src/Csparse.c 0de98909758e80a20a1947a4e7d20804 *src/Csparse.h 42a5a13f71df7c64201fc5dfe518e0b4 *src/Lapack-etc.h 978fc87397951d44f82e7908b6671998 *src/Makevars 6c9b4ba256a8beda2c6783290046b412 *src/Matrix-win.def 1a782516965babb6d929ccc81dba4b06 *src/Mdefines.h 101dd13bfa422f3fb71336f95eb61eb4 *src/Minlines.h 34a94c6db1f395da28ca4e94dd9cf9ca *src/SuiteSparse_config/Makefile 0815699f04c57aec0cf1c4f701cfd1d9 *src/SuiteSparse_config/SuiteSparse_config.c dc05db23c181f81d363fb6cc69ac31b2 *src/SuiteSparse_config/SuiteSparse_config.h d41d8cd98f00b204e9800998ecf8427e *src/SuiteSparse_config/SuiteSparse_config.mk 28438ed30c5bcfeb627f207b4bb81b7a *src/Syms.h adf54d07a4c37305f145130c06afaeba *src/abIndex.c 35bfd5db20bfaed2fe5317dc8c466a4b *src/abIndex.h 2b6c0d590e8364a254f32d84c39a7a46 *src/attrib.c f957aa1decb3ab62e5768873dacbd08d *src/attrib.h 2c5fba5b2b59e716446291cf65d1beaa *src/bind.c ae9faa18a9b4d9e424979c2c8018c110 *src/bind.h 6cca0e47eb4327b104a91669926d67f9 *src/chm_common.c 24051279363b37a028c285c20946d43d *src/chm_common.h 77ec5a3483474020d20a39b7bfce0c99 *src/cholmod-etc.c c5b0558d153b6934275104fa21a43013 *src/cholmod-etc.h a9604ad03ae7eb048de303d9a2d57fe2 *src/coerce.c b28b0cb0755257433a153e528a0efe5c *src/coerce.h ff38f95916965b86bb63a18dc828f884 *src/cs-etc.c bdeb2fdd1d475a5af6614bcc5e3a6c38 *src/cs-etc.h e90b77e2b99ecfc3829ae442f64ab69f *src/cs.c 1bcb7a109eed6463413de50e66989bb3 *src/cs.h 98f16ec801ccad037f30d9bace8efda7 *src/dense.c 1b283c24487fa2a8a08a5d5a5a8a5728 *src/dense.h fb5d6b8b559b3c6f369d335d7286afec *src/determinant.c 22ba2bee6a8de4cda0c60534be652beb *src/determinant.h a185ea4e2e2f70839987babcb9278f2e *src/dgCMatrix.c 8af47c57d737a21b3d359e4106384075 *src/dgCMatrix.h 1dc03c08a01a382c278b10f747ab2ae3 *src/dgeMatrix.c eb3f4325b448c588de89782c3ac6d8c8 *src/dgeMatrix.h 034fc363412798d349a7bad8296f50ef *src/factorizations.c e8265b2a487f2c17ab46a4bba3c4fbb9 *src/factorizations.h 3a00ec0197947e526799ddef28b9f265 *src/idz.c 0b015211a474aa369610621fd3c543c2 *src/idz.h 9df4d8eeb26e33b8964bd8c1db8a94af *src/init.c 15d79a179e59c135b44f5967efd8d90f *src/kappa.c 6204a5bcb90a0715baf19669ef9eb940 *src/kappa.h 9bc0932a84ef35921138ccb7e22112d3 *src/objects.c 1278d3c21ed8726e9048f7031fc4cbd5 *src/objects.h c868b7a3a85521769278f47fc2860c28 *src/perm.c 2ca56d1833e400fe657f963a72c87bd5 *src/perm.h a612fd75964761da5067c260b4883be4 *src/products.c 1045cb4a68b0bbf5f63395a85f89beba *src/products.h 37883884bc19a49e8585dc4f325c8bbd *src/scripts/DEPS.mkf 8f746c52ccc69697252ccec2c601d667 *src/scripts/SOURCES_C.mkf 16e5ab15e7251f9cac15877574f4993e *src/solve.c c7e4d0db483efe92dc836aac9ec0e894 *src/solve.h 0a3c1ca9dddfc78eaab799354e06a1ca *src/sparse.c 1e950bcfe739de1fa814cda80a680aa8 *src/sparse.h e63b80a881df16e35711cd6dfbb56d0b *src/sparseVector.c 024ab3a6d182f9f3e585b802c6e43661 *src/sparseVector.h 239a1593560fe15f100577b5f81814b2 *src/subscript.c 5801e16aa00d9d5188f34e7270057e3b *src/subscript.h bf38710f2a1be89c059d0d0c62b9327d *src/t_Csparse_subassign.c 9542b498b327ff7c9345ed5df2b9fc01 *src/t_Matrix_rle.c d1e9d8b116fdc339313a6d2d63f58e5b *src/utils-R.c 46f34227d88921a56c0eb1e5ce4f17ac *src/utils-R.h 7dd32b8add5da5db098536fd6323bfdd *src/utils.c a819313eb7f9d3c3fc57990d6022b076 *src/utils.h 857a3a8c830efbeef46340ad3c46619b *src/validity.c 9488bc95eb18488965cc74af6674cd76 *src/validity.h 418b002e2b2b78bfabe54f19ddf4b10c *src/version.h 242ec9448d48cc231d1369448e310018 *tests/Class+Meth.R fc506ccab4036af8ad69cc1dd0b3e987 *tests/Simple.R 5e53e6b4552a116eb3a0d6d2feff0105 *tests/abIndex-tsts.R 0de6da80621eb6de7e56a07e766e9a81 *tests/base-matrix-fun.R ffe85c58a3ff60c53ae1d66b4720764e *tests/bind.R c8ab42a19a673f079fda781843914f8a *tests/bind.Rout.save d8d4dec1de3026e421c1faeee559e6fe *tests/dg_Matrix.R d9e757825755abd46eaa5bb29f1b9848 *tests/dpo-test.R c8ee301b09c474efe164f0b1455f74a8 *tests/dtpMatrix.R 3e75f51d54d7ffd38f8a5451cef43c2a *tests/factorizing.R 58db5af64179692469bceceebe17c8e9 *tests/group-methods.R ecda3b001378e86ba5dff287e0c2f91e *tests/indexing.R ff1b0ddb4c97e1da3ac465f113919c1d *tests/indexing.Rout.save 3f2ff4d5c0d6f7678047da84d9f9c23c *tests/matprod.R 33d98d8dcdbe8a42f6ee2b28b97a774a *tests/matr-exp.R dddc7f18c7b0c6404b137941124a2ac7 *tests/other-pkgs.R 6f33d705b9e26359211e9deea270e10b *tests/packed-unpacked.R 21b5499b4f1928d33eeb840b94e69ff4 *tests/spModel.matrix.R 6730c6ccf0899c14ea93bd0559b752d0 *tests/symmDN.R 9aa1a93fa4013f5f69b7129495c7074e *tests/validObj.R 0125b34bc9a1d99bf4062ff55fa705c6 *tests/write-read.R f6c9e4986022f1db4c085b8429d06fca *vignettes/Comparisons.Rnw 2bd2896847fb11eaf102158b8696c884 *vignettes/Design-issues.Rnw 448278dab638a78df6eb59270772cbe2 *vignettes/Intro2Matrix.Rnw c39a26dfe7ccaafd044e88468155b153 *vignettes/Introduction.Rnw f64681e48c222aad57f4d43cad34d68d *vignettes/Matrix.bib 74ca9e8b3e91ace4ee3f9e85506bcdfa *vignettes/myVignette.sty 813e0c8cc7a5f7ecff43e5882270a431 *vignettes/sparseModels.Rnw Matrix/inst/0000755000176200001440000000000014547723665012516 5ustar liggesusersMatrix/inst/test-tools-1.R0000644000176200001440000003475714535165176015126 0ustar liggesusers#### Tools for Package Testing --- in Matrix, sourced by ./test-tools.R #### ------------------------- ## to be used as, e.g., ## source(system.file("test-tools-1.R", package="Matrix"), keep.source=FALSE) ### ------- Part I -- unrelated to "Matrix" classes --------------- identical3 <- function(x,y,z) identical(x,y) && identical (y,z) identical4 <- function(a,b,c,d) identical(a,b) && identical3(b,c,d) identical5 <- function(a,b,c,d,e) identical(a,b) && identical4(b,c,d,e) identical6 <- function(a,b,c,d,e,f) identical(a,b) && identical5(b,c,d,e,f) identical7 <- function(a,b,c,d,e,f,g)identical(a,b) && identical6(b,c,d,e,f,g) require(tools)#-> assertError() and assertWarning() assertWarningAtLeast <- function(expr, verbose=getOption("verbose")) tools::assertCondition(expr, "error", "warning", verbose=verbose) ##' [ from R's demo(error.catching) ] ##' We want to catch *and* save both errors and warnings, and in the case of ##' a warning, also keep the computed result. ##' ##' @title tryCatch both warnings and errors ##' @param expr ##' @return a list with 'value' and 'warning', where ##' 'value' may be an error caught. ##' @author Martin Maechler tryCatch.W.E <- function(expr) { W <- NULL w.handler <- function(w){ # warning handler W <<- w invokeRestart("muffleWarning") } list(value = withCallingHandlers(tryCatch(expr, error = function(e) e), warning = w.handler), warning = W) } ##' Is 'x' a valid object of class 'class' ? isValid <- function(x, class) isTRUE(validObject(x, test=TRUE)) && is(x, class) ##' Signal an error (\code{\link{stop}}), if \code{x} is not a valid object ##' of class \code{class}. ##' ##' @title Stop if Not a Valid Object of Given Class ##' @param x any \R object ##' @param class character string specifying a class name ##' @return \emph{invisibly}, the value of \code{\link{validObject}(x)}, i.e., ##' \code{TRUE}; otherwise an error will have been signalled ##' @author Martin Maechler, March 2015 stopifnotValid <- function(x, class) { if(!is(x, class)) stop(sprintf("%s is not of class \"%s\"", deparse(substitute(x)), class), call. = FALSE) invisible(validObject(x)) } ## Some (sparse) Lin.Alg. algorithms return 0 instead of NA, e.g. ## qr.coef(, y). ## For those cases, need to compare with a version where NA's are replaced by 0 mkNA.0 <- function(x) { x[is.na(x)] <- 0 ; x } ##' ... : further arguments passed to all.equal() such as 'check.attributes' is.all.equal <- function(x,y, tol = .Machine$double.eps^0.5, ...) isTRUE(all.equal(x,y, tolerance=tol, ...)) is.all.equal3 <- function(x,y,z, tol = .Machine$double.eps^0.5, ...) is.all.equal(x,y, tol=tol, ...) && is.all.equal(y,z, tol=tol, ...) is.all.equal4 <- function(x,y,z,u, tol = .Machine$double.eps^0.5, ...) is.all.equal3(x,y,z, tol=tol, ...) && isTRUE(all.equal(z,u, tolerance=tol, ...)) ## A version of all.equal() for the slots all.slot.equal <- function(x,y, ...) { slts <- slotNames(x) for(sl in slts) { aeq <- all.equal(slot(x,sl), slot(y,sl), ...) if(!identical(TRUE, aeq)) return(paste("slot '",sl,"': ", aeq, sep='')) } TRUE } ## all.equal() for list-coercible objects -- apart from *some* components all.equal.X <- function(x,y, except, tol = .Machine$double.eps^0.5, ...) { .trunc <- function(x) { ll <- as.list(x) ll[ - match(except, names(ll), nomatch = 0L)] } all.equal(.trunc(x), .trunc(y), tolerance = tol, ...) } ## e.g. in lme4: ## all.equal.X(env(m1), env(m2), except = c("call", "frame")) ## The relative error typically returned by all.equal: if(!exists("relErr", mode="function"))## use sfsmisc::relErr if {sfsmisc} is attached: relErr <- function(target, current) { ## make this work for 'Matrix' ==> no mean() .. n <- length(current) if(length(target) < n) target <- rep(target, length.out = n) sum(abs(target - current)) / sum(abs(target)) } ##' Compute the signed relative error between target and current vector -- vectorized ##' @title Relative Error (:= 0 when absolute error == 0) ##' @param target numeric, possibly scalar ##' @param current numeric of length() a multiple of length(target) ##' @return *vector* of the same length as current ##' @author Martin Maechler ##' ##' @note OUTDATED/SUPERSEDED by sfsmisc::relErrV() which deals with Inf, denormalized, ... ##' ==> define it only if it does not exist visibly at this point: if(!exists("relErrV", mode="function")) relErrV <- function(target, current) { n <- length(target <- as.vector(target)) ## assert( is multiple of ) : if(length(current) %% n) stop("length(current) must be a multiple of length(target)") RE <- current RE[] <- 0 fr <- current/target neq <- is.na(current) | (current != target) RE[neq] <- 1 - fr[neq] RE } ##' @title Number of correct digits: Based on relErrV(), recoding "Inf" to 'zeroDigs' ##' @param target numeric vector of "true" values ##' @param current numeric vector of "approximate" values ##' @param zeroDigs how many correct digits should zero error give ##' @return basically -log10 (| relErrV(target, current) | ) ##' @author Martin Maechler, Summer 2011 (for 'copula') nCorrDigits <- function(target, current, zeroDigs = 16) { stopifnot(zeroDigs >= -log10(.Machine$double.eps))# = 15.65 RE <- relErrV(target, current) r <- -log10(abs(RE)) r[RE == 0] <- zeroDigs r[is.na(RE) | r < 0] <- 0 # no correct digit, when relErr is NA r } ## is.R22 <- (paste(R.version$major, R.version$minor, sep=".") >= "2.2") pkgRversion <- function(pkgname) sub("^R ([0-9.]+).*", "\\1", packageDescription(pkgname)[["Built"]]) showSys.time <- function(expr, ...) { ## prepend 'Time' for R CMD Rdiff st <- system.time(expr, ...) writeLines(paste("Time", capture.output(print(st)))) invisible(st) } showProc.time <- local({ ## function + 'pct' variable pct <- summary(proc.time())# length 3, shorter names function(final="\n", ind=TRUE) { ## CPU elapsed __since last called__ ot <- pct ; pct <<- summary(proc.time()) delta <- (pct - ot)[ind] ## 'Time' *not* to be translated: tools::Rdiff() skips its lines! cat('Time', paste0("(",paste(names(delta),collapse=" "),"):"), delta, final) } }) ##' A version of sfsmisc::Sys.memGB() which should never give an error ##' ( ~/R/Pkgs/sfsmisc/R/unix/Sys.ps.R ) ##' TODO: on Windows, with memory.size() & memory.limit() defunct, how do I get it ???? Sys.memGB <- function(kind = "MemTotal", ## "MemFree" is typically more relevant NA.value = 2.10201) { if(!file.exists(pf <- "/proc/meminfo")) return(if(.Platform$OS.type == "windows") NA.value ## memory.limit() / 1000 ## no longer with R 4.2.0 else NA.value) mm <- tryCatch(drop(read.dcf(pf, fields=kind)), error = function(e) NULL) if(is.null(mm) || any(is.na(mm)) || !all(grepl(" kB$", mm))) return(NA.value) ## return memory in giga bytes as.numeric(sub(" kB$", "", mm)) / (1000 * 1024) } ##' @title turn an S4 object (with slots) into a list with corresponding components ##' @param obj an R object with a formal class (aka "S4") ##' @return a list with named components where \code{obj} had slots ##' @author Martin Maechler S4_2list <- # <- "old" name (I like less: too hard to remember) as.listS4 <- function(obj) { sn <- .slotNames(obj) ## structure(lapply(sn, slot, object = obj), .Names = sn) `names<-`(lapply(sn, slot, object = obj), sn) } assert.EQ <- function(target, current, tol = if(showOnly) 0 else 1e-15, giveRE = FALSE, showOnly = FALSE, ...) { ## Purpose: check equality *and* show non-equality ## ---------------------------------------------------------------------- ## showOnly: if TRUE, return (and hence typically print) all.equal(...) T <- isTRUE(ae <- all.equal(target, current, tolerance = tol, ...)) if(showOnly) return(ae) else if(giveRE && T) { ## don't show if stop() later: ae0 <- if(tol == 0) ae else all.equal(target, current, tolerance = 0, ...) if(!isTRUE(ae0)) writeLines(ae0) } if(!T) stop("all.equal() |-> ", paste(ae, collapse=sprintf("%-19s","\n"))) else if(giveRE) invisible(ae0) } ##' a version with other "useful" defaults (tol, giveRE, check.attr..) assert.EQ. <- function(target, current, tol = if(showOnly) 0 else .Machine$double.eps^0.5, giveRE = TRUE, showOnly = FALSE, ...) { assert.EQ(target, current, tol=tol, giveRE=giveRE, showOnly=showOnly, check.attributes=FALSE, ...) } ### ------- Part II -- related to matrices, but *not* "Matrix" ----------- add.simpleDimnames <- function(m, named=FALSE) { stopifnot(length(d <- dim(m)) == 2) dimnames(m) <- setNames(list(if(d[1]) paste0("r", seq_len(d[1])), if(d[2]) paste0("c", seq_len(d[2]))), if(named) c("Row", "Col")) m } as.mat <- function(m) { ## as(., "matrix") but with no extraneous empty dimnames d0 <- dim(m) m <- as(m, "matrix") if(!length(m) && is.null(d0)) dim(m) <- c(0L, 0L) # rather than (0, 1) if(identical(dimnames(m), list(NULL,NULL))) dimnames(m) <- NULL m } assert.EQ.mat <- function(M, m, tol = if(showOnly) 0 else 1e-15, showOnly=FALSE, giveRE = FALSE, ...) { ## Purpose: check equality of 'Matrix' M with 'matrix' m ## ---------------------------------------------------------------------- ## Arguments: M: is(., "Matrix") typically {but just needs working as(., "matrix")} ## m: is(., "matrix") ## showOnly: if TRUE, return (and hence typically print) all.equal(...) validObject(M) MM <- as.mat(M) # as(M, "matrix") if(is.logical(MM) && is.numeric(m)) storage.mode(MM) <- "integer" attr(MM, "dimnames") <- attr(m, "dimnames") <- NULL assert.EQ(MM, m, tol=tol, showOnly=showOnly, giveRE=giveRE, ...) } ## a short cut assert.EQ.Mat <- function(M, M2, tol = if(showOnly) 0 else 1e-15, showOnly=FALSE, giveRE = FALSE, ...) assert.EQ.mat(M, as.mat(M2), tol=tol, showOnly=showOnly, giveRE=giveRE, ...) if(getRversion() <= "3.6.1" || R.version$`svn rev` < 77410) ## { methods::canCoerce() : use .class1(), not class() } canCoerce <- function(object, Class) { is(object, Class) || !is.null(selectMethod("coerce", c(methods:::.class1(object), Class), optional = TRUE, useInherited = c(from=TRUE, to=FALSE))) } chk.matrix <- function(M) { ## check object; including coercion to "matrix" : cl <- class(M) cat("class ", dQuote(cl), " [",nrow(M)," x ",ncol(M),"]; slots (", paste(slotNames(M), collapse=","), ")\n", sep='') stopifnot(validObject(M), dim(M) == c(nrow(M), ncol(M)), identical(dim(m <- as(M, "matrix")), dim(M)) ) } isOrthogonal <- function(x, tol = 1e-15) { all.equal(diag(as(zapsmall(crossprod(x)), "diagonalMatrix")), rep(1, ncol(x)), tolerance = tol) } ## .M.DN <- Matrix:::.M.DN -- but do *NOT* want to load Matrix namespace! ## from ../R/Auxiliaries.R : `%||%` <- function(x, orElse) if(!is.null(x)) x else orElse .M.DN <- function(x) dimnames(x) %||% list(NULL,NULL) dnIdentical <- function(x,y) identical (.M.DN(x), .M.DN(y)) dnIdentical3 <- function(x,y,z) identical3(.M.DN(x), .M.DN(y), .M.DN(z)) ##' @title Are two matrices practically equal - including dimnames ##' @param M1, M2: two matrices to be compared, maybe of _differing_ class ##' @param tol ##' @param dimnames logical indicating if dimnames must be equal ##' @param ... passed to all.equal(M1, M2) ##' @return TRUE or FALSE is.EQ.mat <- function(M1, M2, tol = 1e-15, dimnames = TRUE, ...) { (if(dimnames) dnIdentical(M1,M2) else TRUE) && is.all.equal(unname(as(M1, "matrix")), unname(as(M2, "matrix")), tol=tol, ...) } ##' see is.EQ.mat() is.EQ.mat3 <- function(M1, M2, M3, tol = 1e-15, dimnames = TRUE, ...) { (if(dimnames) dnIdentical3(M1,M2,M3) else TRUE) && is.all.equal3(unname(as(M1, "matrix")), unname(as(M2, "matrix")), unname(as(M3, "matrix")), tol=tol, ...) } ##' here, as it also works for qr() chkQR <- function(a, y = seq_len(nrow(a)),## RHS: made to contain no 0 a.qr = qr(a), tol = 1e-11, # 1e-13 failing very rarely (interesting) ##---------- Qinv.chk = !sp.rank.def, QtQ.chk = !sp.rank.def, verbose = getOption("Matrix.verbose", FALSE), giveRE = verbose, quiet = FALSE) { d <- dim(a) stopifnot((n <- d[1]) >= (p <- d[2]), is.numeric(y)) kind <- if(is.qr(a.qr)) "qr" else if(is(a.qr, "sparseQR")) "spQR" else stop("unknown qr() class: ", class(a.qr)) if(!missing(verbose) && verbose) { op <- options(Matrix.verbose = verbose) on.exit(options(op)) } ## rank.def <- switch(kind, ## "qr" = a.qr$rank < length(a.qr$pivot), ## "spQR" = a.qr@V@Dim[1] > a.qr@Dim[1]) sp.rank.def <- (kind == "spQR") && (a.qr@V@Dim[1] > a.qr@Dim[1]) if(sp.rank.def && !quiet && (missing(Qinv.chk) || missing(QtQ.chk))) message("is sparse *structurally* rank deficient: Qinv.chk=", Qinv.chk,", QtQ.chk=",QtQ.chk) if(is.na(QtQ.chk )) QtQ.chk <- !sp.rank.def if(is.na(Qinv.chk)) Qinv.chk <- !sp.rank.def if(Qinv.chk) { ## qr.qy and qr.qty should be inverses, Q'Q y = y = QQ' y : if(verbose) cat("Qinv.chk=TRUE: checking Q'Q y = y = QQ' y :\n") ## FIXME: Fails for structurally rank deficient sparse a's, but never for classical assert.EQ(drop(qr.qy (a.qr, qr.qty(a.qr, y))), y, giveRE=giveRE, tol = tol/64) assert.EQ(drop(qr.qty(a.qr, qr.qy (a.qr, y))), y, giveRE=giveRE, tol = tol/64) } piv <- switch(kind, "qr" = a.qr$pivot, "spQR" = 1L + a.qr@q)# 'q', not 'p' !! invP <- sort.list(piv) .ckQR <- function(cmpl) { ## local function, using parent's variables if(verbose) cat("complete = ",cmpl,": checking X = Q R P*\n", sep="") Q <- qr.Q(a.qr, complete=cmpl) # NB: Q is already "back permuted" R <- qr.R(a.qr, complete=cmpl) rr <- if(cmpl) n else p stopifnot(dim(Q) == c(n,rr), dim(R) == c(rr,p)) assert.EQ.Mat(a, Q %*% R[, invP], giveRE=giveRE, tol=tol) ## = =============== if(QtQ.chk) assert.EQ.mat(crossprod(Q), diag(rr), giveRE=giveRE, tol=tol) ## =========== ==== } .ckQR(FALSE) .ckQR(TRUE) invisible(a.qr) }## end{chkQR} Matrix/inst/test-tools.R0000644000176200001440000000114214464662072014744 0ustar liggesusers#### Will be sourced by several R scripts in ../tests/ ### ------- Part I & -- unrelated to "Matrix" classes --------------------- ### ------- Part II -- related to matrices, but *not* "Matrix" ----------- source(system.file("test-tools-1.R", package = "Matrix"), keep.source = FALSE) ### ------- Part III -- "Matrix" (classes) specific ---------------------- source(system.file("test-tools-Matrix.R", package = "Matrix"), keep.source = FALSE) if(!exists("doExtras", mode="logical")) # << only if not set *before* doExtras <- interactive() || nzchar(Sys.getenv("R_MATRIX_CHECK_EXTRA")) Matrix/inst/doc/0000755000176200001440000000000014547724214013252 5ustar liggesusersMatrix/inst/doc/Comparisons.R0000644000176200001440000001215114547724143015673 0ustar liggesusers### R code from vignette source 'Comparisons.Rnw' ################################################### ### code chunk number 1: preliminaries ################################################### options(width=75) library(stats) # for R_DEFAULT_PACKAGES=NULL library(utils) # ditto ################################################### ### code chunk number 2: modelMatrix ################################################### data(Formaldehyde, package = "datasets") str(Formaldehyde) (m <- cbind(1, Formaldehyde$carb)) (yo <- Formaldehyde$optden) ################################################### ### code chunk number 3: naiveCalc ################################################### solve(t(m) %*% m) %*% t(m) %*% yo ################################################### ### code chunk number 4: timedNaive ################################################### system.time(solve(t(m) %*% m) %*% t(m) %*% yo) ################################################### ### code chunk number 5: catNaive ################################################### dput(c(solve(t(m) %*% m) %*% t(m) %*% yo)) dput(unname(lm.fit(m, yo)$coefficients)) ################################################### ### code chunk number 6: KoenNg ################################################### library(Matrix) data(KNex, package = "Matrix") y <- KNex$y mm <- as(KNex$mm, "matrix") # full traditional matrix dim(mm) system.time(naive.sol <- solve(t(mm) %*% mm) %*% t(mm) %*% y) ################################################### ### code chunk number 7: crossKoenNg ################################################### system.time(cpod.sol <- solve(crossprod(mm), crossprod(mm,y))) all.equal(naive.sol, cpod.sol) ################################################### ### code chunk number 8: xpxKoenNg ################################################### system.time(t(mm) %*% mm) ################################################### ### code chunk number 9: fullMatrix_crossprod ################################################### fm <- mm set.seed(11) fm[] <- rnorm(length(fm)) system.time(c1 <- t(fm) %*% fm) system.time(c2 <- crossprod(fm)) stopifnot(all.equal(c1, c2, tol = 1e-12)) ################################################### ### code chunk number 10: naiveChol ################################################### system.time(ch <- chol(crossprod(mm))) system.time(chol.sol <- backsolve(ch, forwardsolve(ch, crossprod(mm, y), upper = TRUE, trans = TRUE))) stopifnot(all.equal(chol.sol, naive.sol)) ################################################### ### code chunk number 11: MatrixKoenNg ################################################### mm <- as(KNex$mm, "denseMatrix") class(crossprod(mm)) system.time(Mat.sol <- solve(crossprod(mm), crossprod(mm, y))) stopifnot(all.equal(naive.sol, unname(as(Mat.sol,"matrix")))) ################################################### ### code chunk number 12: saveFactor ################################################### xpx <- crossprod(mm) xpy <- crossprod(mm, y) system.time(solve(xpx, xpy)) system.time(solve(xpx, xpy)) # reusing factorization ################################################### ### code chunk number 13: SparseKoenNg ################################################### mm <- KNex$mm class(mm) system.time(sparse.sol <- solve(crossprod(mm), crossprod(mm, y))) stopifnot(all.equal(naive.sol, unname(as(sparse.sol, "matrix")))) ################################################### ### code chunk number 14: SparseSaveFactor ################################################### xpx <- crossprod(mm) xpy <- crossprod(mm, y) system.time(solve(xpx, xpy)) system.time(solve(xpx, xpy)) ################################################### ### code chunk number 15: sessionInfo ################################################### toLatex(sessionInfo()) ################################################### ### code chunk number 16: from_pkg_sfsmisc ################################################### if(identical(1L, grep("linux", R.version[["os"]]))) { ##----- Linux - only ---- Sys.procinfo <- function(procfile) { l2 <- strsplit(readLines(procfile),"[ \t]*:[ \t]*") r <- sapply(l2[sapply(l2, length) == 2], function(c2)structure(c2[2], names= c2[1])) attr(r,"Name") <- procfile class(r) <- "simple.list" r } Scpu <- Sys.procinfo("/proc/cpuinfo") Smem <- Sys.procinfo("/proc/meminfo") } # Linux only ################################################### ### code chunk number 17: Sys_proc_fake (eval = FALSE) ################################################### ## if(identical(1L, grep("linux", R.version[["os"]]))) { ## Linux - only --- ## Scpu <- sfsmisc::Sys.procinfo("/proc/cpuinfo") ## Smem <- sfsmisc::Sys.procinfo("/proc/meminfo") ## print(Scpu[c("model name", "cpu MHz", "cache size", "bogomips")]) ## print(Smem[c("MemTotal", "SwapTotal")]) ## } ################################################### ### code chunk number 18: Sys_proc_out ################################################### if(identical(1L, grep("linux", R.version[["os"]]))) { ## Linux - only --- print(Scpu[c("model name", "cpu MHz", "cache size", "bogomips")]) print(Smem[c("MemTotal", "SwapTotal")]) } Matrix/inst/doc/Comparisons.Rnw0000644000176200001440000002166314444514070016240 0ustar liggesusers\documentclass{article} \usepackage{myVignette} \usepackage[authoryear,round]{natbib} \bibliographystyle{plainnat} %%\VignetteIndexEntry{Comparisons of Least Squares calculation speeds} %%\VignetteDepends{Matrix,datasets,stats,utils} \begin{document} \SweaveOpts{engine=R,eps=FALSE,pdf=TRUE,width=5,height=3,strip.white=true,keep.source=TRUE} \setkeys{Gin}{width=\textwidth} \title{Comparing Least Squares Calculations} \author{Douglas Bates\\R Development Core Team\\\email{Douglas.Bates@R-project.org}} \date{\today} \maketitle \begin{abstract} Many statistics methods require one or more least squares problems to be solved. There are several ways to perform this calculation, using objects from the base R system and using objects in the classes defined in the \code{Matrix} package. We compare the speed of some of these methods on a very small example and on a example for which the model matrix is large and sparse. \end{abstract} <>= options(width=75) library(stats) # for R_DEFAULT_PACKAGES=NULL library(utils) # ditto @ \section{Linear least squares calculations} \label{sec:LeastSquares} Many statistical techniques require least squares solutions \begin{equation} \label{eq:LeastSquares} \widehat{\bm{\beta}}= \arg\min_{\bm{\beta}}\left\|\bm{y}-\bX\bm{\beta}\right\|^2 \end{equation} where $\bX$ is an $n\times p$ model matrix ($p\leq n$), $\bm{y}$ is $n$-dimensional and $\bm{\beta}$ is $p$ dimensional. Most statistics texts state that the solution to (\ref{eq:LeastSquares}) is \begin{equation} \label{eq:XPX} \widehat{\bm{\beta}}=\left(\bX\trans\bX\right)^{-1}\bX\trans\bm{y} \end{equation} when $\bX$ has full column rank (i.e. the columns of $\bX$ are linearly independent) and all too frequently it is calculated in exactly this way. \subsection{A small example} \label{sec:smallLSQ} As an example, let's create a model matrix, \code{mm}, and corresponding response vector, \code{y}, for a simple linear regression model using the \code{Formaldehyde} data. <>= data(Formaldehyde, package = "datasets") str(Formaldehyde) (m <- cbind(1, Formaldehyde$carb)) (yo <- Formaldehyde$optden) @ Using \code{t} to evaluate the transpose, \code{solve} to take an inverse, and the \code{\%*\%} operator for matrix multiplication, we can translate \ref{eq:XPX} into the \Slang{} as <>= solve(t(m) %*% m) %*% t(m) %*% yo @ On modern computers this calculation is performed so quickly that it cannot be timed accurately in \RR{} \footnote{From R version 2.2.0, \code{system.time()} has default argument \code{gcFirst = TRUE} which is assumed and relevant for all subsequent timings} <>= system.time(solve(t(m) %*% m) %*% t(m) %*% yo) @ and it provides essentially the same results as the standard \code{lm.fit} function that is called by \code{lm}. <>= dput(c(solve(t(m) %*% m) %*% t(m) %*% yo)) dput(unname(lm.fit(m, yo)$coefficients)) @ %$ \subsection{A large example} \label{sec:largeLSQ} For a large, ill-conditioned least squares problem, such as that described in \citet{koen:ng:2003}, the literal translation of (\ref{eq:XPX}) does not perform well. <>= library(Matrix) data(KNex, package = "Matrix") y <- KNex$y mm <- as(KNex$mm, "matrix") # full traditional matrix dim(mm) system.time(naive.sol <- solve(t(mm) %*% mm) %*% t(mm) %*% y) @ Because the calculation of a ``cross-product'' matrix, such as $\bX\trans\bX$ or $\bX\trans\bm{y}$, is a common operation in statistics, the \code{crossprod} function has been provided to do this efficiently. In the single argument form \code{crossprod(mm)} calculates $\bX\trans\bX$, taking advantage of the symmetry of the product. That is, instead of calculating the $712^2=506944$ elements of $\bX\trans\bX$ separately, it only calculates the $(712\cdot 713)/2=253828$ elements in the upper triangle and replicates them in the lower triangle. Furthermore, there is no need to calculate the inverse of a matrix explicitly when solving a linear system of equations. When the two argument form of the \code{solve} function is used the linear system \begin{equation} \label{eq:LSQsol} \left(\bX\trans\bX\right) \widehat{\bm{\beta}} = \bX\trans\by \end{equation} is solved directly. Combining these optimizations we obtain <>= system.time(cpod.sol <- solve(crossprod(mm), crossprod(mm,y))) all.equal(naive.sol, cpod.sol) @ On this computer (2.0 GHz Pentium-4, 1 GB Memory, Goto's BLAS, in Spring 2004) the crossprod form of the calculation is about four times as fast as the naive calculation. In fact, the entire crossprod solution is faster than simply calculating $\bX\trans\bX$ the naive way. <>= system.time(t(mm) %*% mm) @ Note that in newer versions of \RR{} and the BLAS library (as of summer 2007), \RR's \code{\%*\%} is able to detect the many zeros in \code{mm} and shortcut many operations, and is hence much faster for such a sparse matrix than \code{crossprod} which currently does not make use of such optimizations. This is not the case when \RR{} is linked against an optimized BLAS library such as GOTO or ATLAS. %% Also, for fully dense matrices, \code{crossprod()} indeed remains faster (by a factor of two, typically) independently of the BLAS library: <>= fm <- mm set.seed(11) fm[] <- rnorm(length(fm)) system.time(c1 <- t(fm) %*% fm) system.time(c2 <- crossprod(fm)) stopifnot(all.equal(c1, c2, tol = 1e-12)) @ % using stopifnot(.) to save output \subsection{Least squares calculations with Matrix classes} \label{sec:MatrixLSQ} The \code{crossprod} function applied to a single matrix takes advantage of symmetry when calculating the product but does not retain the information that the product is symmetric (and positive semidefinite). As a result the solution of (\ref{eq:LSQsol}) is performed using general linear system solver based on an LU decomposition when it would be faster, and more stable numerically, to use a Cholesky decomposition. The Cholesky decomposition could be used but it is rather awkward <>= system.time(ch <- chol(crossprod(mm))) system.time(chol.sol <- backsolve(ch, forwardsolve(ch, crossprod(mm, y), upper = TRUE, trans = TRUE))) stopifnot(all.equal(chol.sol, naive.sol)) @ The \code{Matrix} package uses the S4 class system \citep{R:Chambers:1998} to retain information on the structure of matrices from the intermediate calculations. A general matrix in dense storage, created by the \code{Matrix} function, has class \code{"dgeMatrix"} but its cross-product has class \code{"dpoMatrix"}. The \code{solve} methods for the \code{"dpoMatrix"} class use the Cholesky decomposition. <>= mm <- as(KNex$mm, "denseMatrix") class(crossprod(mm)) system.time(Mat.sol <- solve(crossprod(mm), crossprod(mm, y))) stopifnot(all.equal(naive.sol, unname(as(Mat.sol,"matrix")))) @ Furthermore, any method that calculates a decomposition or factorization stores the resulting factorization with the original object so that it can be reused without recalculation. <>= xpx <- crossprod(mm) xpy <- crossprod(mm, y) system.time(solve(xpx, xpy)) system.time(solve(xpx, xpy)) # reusing factorization @ The model matrix \code{mm} is sparse; that is, most of the elements of \code{mm} are zero. The \code{Matrix} package incorporates special methods for sparse matrices, which produce the fastest results of all. <>= mm <- KNex$mm class(mm) system.time(sparse.sol <- solve(crossprod(mm), crossprod(mm, y))) stopifnot(all.equal(naive.sol, unname(as(sparse.sol, "matrix")))) @ As with other classes in the \code{Matrix} package, the \code{dsCMatrix} retains any factorization that has been calculated although, in this case, the decomposition is so fast that it is difficult to determine the difference in the solution times. <>= xpx <- crossprod(mm) xpy <- crossprod(mm, y) system.time(solve(xpx, xpy)) system.time(solve(xpx, xpy)) @ \subsection*{Session Info} <>= toLatex(sessionInfo()) @ <>= if(identical(1L, grep("linux", R.version[["os"]]))) { ##----- Linux - only ---- Sys.procinfo <- function(procfile) { l2 <- strsplit(readLines(procfile),"[ \t]*:[ \t]*") r <- sapply(l2[sapply(l2, length) == 2], function(c2)structure(c2[2], names= c2[1])) attr(r,"Name") <- procfile class(r) <- "simple.list" r } Scpu <- Sys.procinfo("/proc/cpuinfo") Smem <- Sys.procinfo("/proc/meminfo") } # Linux only @ <>= if(identical(1L, grep("linux", R.version[["os"]]))) { ## Linux - only --- Scpu <- sfsmisc::Sys.procinfo("/proc/cpuinfo") Smem <- sfsmisc::Sys.procinfo("/proc/meminfo") print(Scpu[c("model name", "cpu MHz", "cache size", "bogomips")]) print(Smem[c("MemTotal", "SwapTotal")]) } @ <>= if(identical(1L, grep("linux", R.version[["os"]]))) { ## Linux - only --- print(Scpu[c("model name", "cpu MHz", "cache size", "bogomips")]) print(Smem[c("MemTotal", "SwapTotal")]) } @ \bibliography{Matrix} \end{document} Matrix/inst/doc/sparseModels.pdf0000644000176200001440000031065514547724215016421 0ustar liggesusers%PDF-1.5 % 1 0 obj << /Type /ObjStm /Length 4869 /Filter /FlateDecode /N 99 /First 837 >> stream x\Ys8~_)g؉NȴYHtƙ_ Lޭ- 8 DOn }z>=U|v0Jho<[d<πʜ=|=e4$xW`k0`ߧШ'ihi*)铓Sg:eX(KmͦY2DJXNף:nPhXz&|cջPpξltdPC| ]Io{@,L!SVgudUHOH3@FӇ;۶Vnrv"R \F[V-5damrPIRrgiPY;P&e("<9,2Q.ϫ4Wx5_E[oެ4dqbj-jw5njŎ]Wnv5qp%2!\,U}{NQNri %8y2U[Lmbw;W8;S{&M]f=Y5d>cIi~X LUXOcUXۿ܅ j=KI*ܵ|n**6?\wk; 3^6~wsKP֘ps'r Që=%B@|r&?D #ϞD1MdQvrQ]Qj2\}) R4r%pJ+&P<6&~=- ЭbD^ ߫%`Oˆ:=:6u|Y?b2سQr<H; $ͫKl*,om2(Dpq=Ry~#!(rj;C\nccNf779H%Ak-gEip$yIlדSKww /ԏ1( g =T[0krw=\χᤐ4vߋsuQ4K* a%&.?%S#Z"}USn>B.E0w y.vHTRJ)敥'i_)}S~;и+ϒ!.^rZCIqZ(u-.ys2K쇚~?R~G$> _&ἒg/ȯ&Eg)=az_yV}*΄yQ'zFk|B'^WSIט#;@G:Hh Lg^p(|Kc--=ǖVyZ+y}uݦFJIc)8~{/=MWJWfGuJo~LVLPnrT+ژqe'Db-[; Wj~ /[Ggic*aY*I[Z ǫ1aFiXrlx?=7=8{dhw)h]H{!BZ 6x')ԛ {y؞* 2ۮ-9#S=RŽo%w:e=ƽ{\ˆ1(+(֊onRhBm14iPQ%ֆ- -*P8B\@*v.NE!ګ}ziM7"$kŴP>Xf\1(ƃ,|-#x%Sd=pcs6^ pY^ k<{ 'UD|SVrէNŽC;ꃚ%r)<7y#}~}{)L\yιڦŦSb_/Bo:/UKtom]ϧ"hD?VVgJ *Ue/Gw8CO`,H9e*pGB`~xm7jbt{NJx]dZv)磃Oo2y%zӼKTM RewAk-MZ%Vn] /NO>Ya"okKtOt_M],Fn ]6_:"}.7/?`50iAO_/Sv}Г nq/~$$=TtXq2!fa#JknӒ[>W)Id`-z:-退|IN  ȁF3Ӎ߀碯O7?G~ÀUF@x4I\Tu?n%ua/sq.q"_O+O~PڴN7Z<7WEerӽXڦ[ _}x?uI~4/˼x\uK/MTm`m"a֣DCI"dKfv[Y7@BzZ`Drb́%}Yn77 ao}V?zU{Nec{zaQ#>fȨEZ ssJ̱W yD[80AEYVPzs1{A][_rEŊ8Zw!endstream endobj 101 0 obj << /Subtype /XML /Type /Metadata /Length 1388 >> stream GPL Ghostscript 10.02.1 2024-01-11T09:36:29+01:00 2024-01-11T09:36:29+01:00 LaTeX with hyperref endstream endobj 102 0 obj << /Filter /FlateDecode /Length 2935 >> stream xn#\f. (PU),AIHcIz`5T6U|}Rd^&Ƿo,Ŀ('w?_Pw: _. RL 0& D)SPk'WkӱˢL Hֳ9VWٜU ?(J^;*IlfLQ-ɲngo^"jBiadHׅ5l2g0F+xUt= Ҭ3xc=b*Ku"9Q;S: 0pho71RoDŽlWR1N:KCf5]R* 3FhR:,}>{7y8\H%"%nTsVEAKI^"lI)% ~n+K} [V Or"@є LZmq MA \R-XVԽ8hRYCNU~QPz6`b=\)Ad1]E؄ E -W`2?a$   9?Y9ra s7n\A.bbvYF C-Nj?\{76( , \NEdIw_񾤀%y|q z;(ez_7vkw7j"nIvHFEj(hki5nveS ytRq( C)u!7U4* O1%^E@Ƣ0'c i ꂕ3yJ a20r{#8T!8+y 'uI" [AMT`_Q=V>-pL |P yךpdYuݡA\Dj (qD |(u#B5uI0QtE0F<άT2} J餽 k%]xm}7qdͦn5Iaz*2.f͛"fz!gB/TXZXq" O.-+\rt2e|  rQ ޹zyG'oGnUZ֙.aemNfܦ.- !l>SB.O_1-ޖxF4{{3#Dۨ+hgtUdu*?ta<5xC, >d><Ŝ M n^__fm^ś|fA`Fn]C(ԝeDD]SL# J L$1JWv&mOXKZ0[D_ J$K l}Õ*X@ǮApJVɅ/ ^Y3Kí |`WBR a׎` *AAnEb7/X#*hIC R;nAM*IAhQ2i ZIQl>b,3bR eYy,mOMN.SU|{NӰcЕ)|FG3l-dP_z Ka[H{aр- A 1knMJ5op Sev&}fl$Z-30`f$ @3PF!8[:,+ǢIsZ!*&SA{ʂw}Sp(H'PB_~!븱><ֺ =]&wƒt\!·LAB@!jG\ !xBZ+*s". p4 W&3w~PFrʟdo#a}φ&E^Cҍ PЌ٨%O3QΨ(F[P&?CQyV+SWͺ2ٱ5A,< r@w:0xa\q ghmB BXC$*fxwy3:vln ܭ 0W {z2ܤ {_Նv~ea5R\!6 E|ᬬw3)ST=͵ɠ%w2ba#t@*̀9Ūn7w ^ nӔ҆OaiHZ}?VмfWn{$Pׯ}cz|vtLeE刍BTstO-`GW#2^]F3 sEBǔu% bx%|,Ӈbvb&Lokh|:z?iۦjy8>s093f j&ټcM#qith_R85}$" 6mG"Q uǪ zl9>zX'&ܷNWw= 5>oz7QL7I.Ae=1*ᢟ da8 KX4n?Ԗ:endstream endobj 103 0 obj << /Filter /FlateDecode /Length 2324 >> stream xYKoF딽@aoR]$AIc,(GC*$ǒ.~{FkR7]],,Q?o9Hf`tf?߾"lř bXx&L$N-6(oVќrgAE>z;L9($FR˘_e }*$/󮯾*jEsFe0uzoŬ% bu6M>t-h}$I+.2`O2vX'Tm4eQRn-CKtQvt.of~N9q96L\FB5Cm_ѱ]X$<-^,GsN80@ѰDj€@GRTmTxXKSoO.;RUPvEy9L gq.<~HLO%OrҟlsrqSQ}4V25sJ&7c>{fb/ EGa!vﶝW^>@(Ok,8?KkVPo 07| hlґ{+MynoQxm}Ov#:m'OXR;U|iR?:RoWuUa^Ր^^4 (\n' T(d$)}"WacS (xs5@:N|-T9|NQl6\Y $2a&?/]K P3CHUx+C/g<\`/V0^r_);Y>yA$fFGѾxLHYu6%Nb2sY#6D2ԏQ =ncҷ7b=k>TF+e۬|BGP#ȩ5(&3b zE*r Ɖ?5,MGށ"& 4wRu)niӛ0&"R4@␠Y%nwf "sΩ 2/U )8Rz̓H 1C 9ǥ#[D.SBa9*J5f7;f"54#HwDa(S1zZ#|ӄ %|yaLZ08EaH![ccjqS^]HՏ9Y#k u#m+Wr ˕N\fmz۴KEo#EPU5EzXĉ`H7] +]OE?Uaە:j0%nqۀU{9)~JM[(lqU5A_zQ0tQnJ/| PUU}¿jL\_I2ѽ.An1Fvo?S(d X͋tv{bxEN1<`ܹwS]*c>n 6__v- _)L J u1u&T;~ъ&(l,y^NQfcTف*ԕu^(wܽ!LKSoG' جP LY,Ɠ1..R5y_z5*F`& }"}Mع4PFjΌQd )P<8VV & kqf8pVn;/2e1^|At靍E,}eXE ܤ+*^gg6:ݧ\{'OF|׎-50Q:,Ëj_bkl6F4Np!U~hod(Y/mZR9C_uAr TtAWywyTg|W`rwgنJܱq{֗]p)T6Ҙۏִ >nM[Tofir:vL4åyn D;k]v~xeSTRz{XYR[Waq3wqsendstream endobj 104 0 obj << /Filter /FlateDecode /Length 2654 >> stream xZMB*K=S;To*XJ!\toO| l>~+KQs}iVVJZeQ]. +a9/JԲX>|@Z0JAy!,r7#}9 &/t@ J-.3a#C/pcm!-M1;aNeYQK.u9{M񡝩x?_ BPpQj[&Ҩb;{;c֤KXCT2@ kP\`$%NneTPS u ippRf@tU"0%eg&ҚRJC" (-@mimPubV~95#VIE9쥤zف(6u Ph\Hl[f*+S  9'"^xa$Hl HF3DT/*CuPtN2j~E ƭ%HJ[G3*m2X3 Q籙0QV9g((;p4GI_QGI+8 (iF^E)$AR{ۺJT Բp%X%5^\Ew2)T JPR$jBc^%sR8%%UVxXP9G6k(=19yi5qbG7$z TUeM"$L^쀒l,l 1bQs'n #QwrcUT5/>逸7tʄwiR6p#T2*hrW@-Tqc@-TT*ˣp, *m Ǣ;I^ps21J[8DW@-`TYMT 39yTFr*m j"p.v@- _E-\*Ճp(JeT79Ws㎟TMPsfǠ椉㸃_@s<*c8 Hs*m bN򊨴sRecyT9F)29FT9|6qN'=Pi8/sPi8% sCQi|Bc^6q2lj=*mGc8P9sgcyT9E3J8DZ(,{bAHpQOAI8^Ӥ<(mPRoS(c8/ {H:ʃ2#QLn73<&cv,<(Ȑm YEPڵ)i :xJ{IxU-[ [g Ai8ȅc @I8s1kS] ?D&DJY&XvLjJxvI~V@%M[x:+=¢\5 pfCPҵAn*i!jETҷNBDD%[(q+m&D?1ÐJ7NCH0+=F<J}#*iGeQ)8Y$:'P)vK:!27c\6CSikUlRޓ /(9J BNw$9fקa?_WVÃX'E|ng8f?gbG_WP (K[ rl{t| 4e6\SM֏c;NLBW@.c@\%=9(os)ȌFT~ԡr񩉎q^*xxܯc^%Sd_rU҆DnPC|BnЊ]Cu}lP)8̖iNJ.<#| *8Mnb@VFMYPJyڃ%5 Dl bRrlqݴ~ 2o~`œk^LKbͼNN!5 8aoV*H=@N ϝJT`m³'vvL =}q^9Hx џ $l}}Wd- ^?4~ iaĂ(!+E YoEo~{X[,'_m XL{2f>]p4Dh19Cn.uLҽڵ7} D^]ەHR>Q( վdT32&^ruۮ]dN$5 t> stream xMTkPT>Ŭ5s/~HL5}5ilDVS :v]>]AހaUЈ(DS8 6fڴfLx9LI:pfpI(Y%HsҲ3^𓍉* YrPJA) <fzTb-}𽌢9ECPzJFQϨ j6(#DR(!II2rMVd3Բ'T!(]ܐb]68QXhrR־ 0Ys8Vh+:w_0X醡ډ~)۹|qy"9%c#-?xwEdaho{k#wN i E_NR"KSI5+c׺X"wՃ #C`#ऋc.1k}+Ĭ-<%H0w]^Y&~Y.6]B1t/5=Y"Civ]>/w/+:.btX'T*+}|Zظy @>`zJaqŏIy⑋saXN;.Ix`4qdi<ɾR *5 "Ӌ:ëdk`e57{ٛ+!wbӸ~J nPMDNl7ɚOR٠bn|{yu;+vF_phMߓ= 34V{aՒrkK\‹%ƈ1 pb;@WS!KNwDJ6Zi]F;{"jXq8jQ>4,rƔKxnt*zLsИs|ܶv3, w濽vo̭@W!U٭: ]nZÍ]w-+{WZkoC_vEAi. [ `DTM{hOK$>bQ^vhc(A`@Uz}hD2VX(endstream endobj 106 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3236 >> stream xWitg-![Ufq݁4IK $4` Y"[k}x  d0417$49 ݝtO 'sOϙutTޫw@-k7,\` cE0Ygs3 gcL:-2#+[v:nC|btVi77bEHl&f[mvb A""׈5Zb HaD1BL#,$O`0}Bp$P ,M咋j5D&nxkRͤLN|r ,XyGf. |Y=m1ap2F2"e.#G:=ʨ(瓉2s*y(-f6HNKVXI1|S.}hςoDǷ*{o)EK~`1E_a! EQ&h)5SS–)?zftC)} - i:ބ/A9[FPz{QO]Q]+;Kxƛl dE腒VJR]#Ecs^\*9J޷pKG;q3\[NgQUns0t"cDtB.6/pU [ԑ-x, Nz*>ՒL-ۏ2zi`v)MDKOٺ7-sD5 1CZ}IT̻}0m* >_;qX7ZcmAn$"=>R"nGLz%R9(D.\q1B+q V`3ЩqSԢTHpP$ePFۛ4}Wtj">yx1,б mlm5y^|R3I@n7Xe@P*>\ru%ߧM<A&h:[ ODnFb{Z$c^b}5_ Oo'[M \]d/gWwhJ4NMyVhK# D#*s˾OēL~zџ1 &}P6uvgN9 c1-OOgIl4 R\Gw5IšQwaϻTud[3GȄt~j{nS6†uo$3]CbOB:U$?d?$8Y\N>k$k-(3^al`Xf9)L,v{*%_hYsI;Sgx&G6z? qONt)|/+coI8_]tTs@KPhH!WɔdEZLS))r@YE4MaUCsM -)/v_t8`Mxm(7M?vJ} 5BߠM辄%#Sލ2.t$?^?\EA%v0*M"4\[LYI蹆 CT)97mw%S"_3v^P̺!Z|׊wu<<+=E=12d1| ӥ-=4-m6{pZSRx@.J>X,,<$z>NuF'PV.*Ф$&nC44,0ڌX~VAIä^+YfkV}w/J ^2A!eMTasUV`܏Vz-h#F,}x3-DuNiޒg2xU,hxN4v7Tnݥ G\SY\VF?5+{{M,+ՂwHBH g <FkEs_gEhulpuzxV,qU$2-Oۡ>(O.+A ?cwwImKfoN/]>;YLEfXVya``|-v/9Ltǟ _B_s_{Lq@645 PDaAx!endstream endobj 107 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2074 >> stream xU}Pd(*Z18S-?ӨXdD15*bS ʇwݽ{pwǁGQQу`6RmԘSf^bWwwޝyv{'"(:umZE =̲`Uw*S';gGϋ}6 3cF!lOf-r!Mf"H'kuzb1-CӉB"vQMj[&EE`4INļZ+˰(|QeC ۀEm_`jI49@Dc%nA;s{NL_|ٮ̏Ņa(nchn0Oț7,+bVLɹ~~tegIr:=',Z@\.O Cv8.?zd}Sq0EV^b\jkwBEkWF_-p=GJx`1>e8Ayr:*T28Ti F2ާЕnn#kƷ6:tn9KM!͆OO4vv@@72O|>Է&59[Fӕ"4-% ȢJ5oq .zփ:PdJߣثR]F1`@h9ٚ ߐ5 ؁a AHր5ٻ\"[B5t-?>u+X*k:u]UÖx*RVC 'R> m,J;XɌĊ ~u `Eb>7%۟`i`l$N)s]!"$4A3~YoOޤݴٿKOb4R8tt`=;y3\~[# YќӰMG[%t@|pL`K^$)~2:j6tṄP/hJj($շ]#lU{aM=k<V uP@ضa65G?ף/"$iou>˗oWP-b*m|,/ӛ*u& BCZf,Tkw=W˛ {sŜ_vTSh*Z'խm⫫0wyܩoU>GCvnNCm :_񬆜jņe?PK3B?/_ '6 ^5B)K/v]/=tPF{3ZS`Bc(Ǎ#UhGE.H^2($wڃ' bm5ι74⌝lj=d;УZ4@*]%ql<# (?0JNA8AJ)UC{O 5J?_{S93)2}jTa*3vq^j:̎POӷ+ݝ;n?gT)kx%( |iVOY9lp20E;JRa*xW+WNbNրªT%*H{p*aצEؼUx\7M{ỵ8V]hƢ=@ye,LXu@u>Ϗ#EIF#o U(At(I+R@ yGZ[9 d2YL1kh/W^endstream endobj 108 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2163 >> stream x5{TSWoɹ:n@7-:>;[ŪVex@ $$$ᑈ"H D2U[8VQcf誶:,'jR{s>QcP<o\ʍ1QsF7$\r&aXqLoy}ړ#˗N.9(j=Mf3*ZNmVR"j"DS  }=f-?`E<);@St鯼0_<S"}whW 0wnN2KY[.dd~\&xƽ^(0Y([f?,{Y3&^LhO)G=u.ۄLwkoL]fCrtSey9+,CR)}g 﫧S>6IԤ",QANix"̼³/zX۱<4N‡I#KUBrc>9Ump&@2ĕnHMH >>Vh_-_ x/|/5{œ9J1ZJ%$rYFYa8$~nYayob<}Q04SIVߚsDQ|lhJ6 NTl4HfiwqEq5x7U+;;k3`\<'r-^p^>K`ȊN tqp,h6L/LKR$gŵ+_/M)-`?4scQZ.i`B5VD~4es:Zz ,VhE;|ha.OHdž l f<r*VB xLM]?Pzڧ* ŮzFhV;'ko~KYgX \=/^Qr}e 㷋,rr*`.ԁ7 ,mQe)b-ee .xJg_iINv rIN^[Anzd`LGQ3;endstream endobj 109 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3022 >> stream x}{X/XI3)7jGZgX_ÈD"a BC{1&a)8kڍ'a(Wr IRByuy YD0zfļD3aL Y΄3*-f !#cB?f32RY$FbIg"}$>>}M |/HI./793wuNNJdɢ}?vۙ|1=S]{=-Ko x"d&NzQ*'9 ,wҋq{}{g*WHXAoy+X ˷y-r"f>/` yȅ, /F'FF&kg S0`COI|i)d*/֞n ñj4uiʴ$H,Wf ?G"хAnywݿ+O:ЂjiP|U/교KhWuwrn[.B'Џ0 cӨ,쿈9K ?z( gjʬIʨVXuGώd- :7Vz\zbTj]N~6 ZP7h*s+s͹!K8Y[lD]/,IcYtk 9 d,Vmz=ɮT7WQ>?]z =#[ 3TNH+ ii2;.//~)w'rP`.|^Qr!Nt\Ej2^\q"']5138MgoL6KU{K-\{Kn9JW|B|`nz9Zw$?tp&Nw-)g!Q_}=q{ރ5{\TW:"ܳg_U8'7o:nkmjlU5R o_ֵ’_}yad#[QY{x7y[n/㠴ܨlݪ٢.Rfqdŧ-e$!9q^\8s)G_ }tz`+':-ɜ%O?YI EQSWlԡ…u\nUvAQ,HTwZ^9n ds6| Hm<M_XTѲĺ<ݢoNr{Jmў$=FjWޜ"(,lowe7RK Tɯ;>W]9 >wCAsnmSD*gge)vJt猗^Qrb$PM{ {`y֜$/gBd֤+`OWF]BR6ޮ(JX E0;X_z%_ՠNkk3[O\XSC7^8GIvp[Pz.$FGuoY(ȾF\:DG5[UMaH8R6n5$w U*'%#(5fǤrTwTvSw6`w$m12:; ڱgX3`:T;=Z,=cg=!cE5翟@|sGGWM3<͍v܄>_!+a. .<:.$AқGQf-t9c ܫ=󈘓rRJIffrNg 5k{;2zWwԺR:;P!Z[IGVn;2[Y&=ߝc?ƦWiiAYCC^*9;vRGTw":DbbDc$ $gu 3sh-VBx|o״iX/a~nO:/dUr߅oEf*{uDFK>X%UڼWLC{4d;hkr{ܞ'R-!t<(),p8[{+}qB _}|y ԢtB&W%d)@VMpbf_A|p.\Da XkWrVBeF0.X3 @ۦ)zD]dP o'2h(1RMVhn1 \B/AЕiBx8Yx_IuQ|pG2Xg0 P›8s]g}unh)8\\ܙع 5?C~7>_;=; T 5d3MBoo2:rN/V ! t&eavd??rrendstream endobj 110 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 8032 >> stream xy XSA$XZ\pOmhmZ'g,"! ! sCSApơZ^[[nw}y~y9{w:1DDLLL%3{511dTW}6}zO:̿wfM~wz a,lƤMs 6,ز0u%K3+^o5v܄4G^=&Yb!xxXBH,%È b%1N"#wHb51H$fhb:D![!!.1H "h"҈^Do"K㔬IRW AU}M')I!>OwpiŸ$ `~=(4Bz/eȴ!!Cn<3 C顉C[]ܐ1&OwkDJb9|ȏ`Sy:<6oy@qPP*V]S9 1e$5|XHY*6KVa+0aQEѯwʁz4az{1/^KR@EA@A8wydo]E@wI$AϠ/9p&ێ)o4B+(Md 5}jH{gNE" "0G7.iD!灩`q ~l˽ qsD$NJX-$.{އgu;pP>K,1^bt0iMwmpu9ο9M6^Z @˃.edkLt7\в <ck &|XB25(,YB{ Tm:& ?}aPRygIXC5lh}z/Pp< ?nC @o10 am;6`7FDqaXk=ru%WBϏBwJ J0hEW`E\.˒fuX> yq.bCA+ z|x?htglC ?6 !ާJvv=&PJ=8R3$ Ţ35VqY]ɋIxj+qֹϱ.)~E+@g25+=3 7DXJ (U>]9mb-L-[+)2RP˗y_¶,7߅±M5uR ,Zi˃[d3i.D,C0X^7_+5)fA/Xiۓ]+0+ Nb,u(:KR)o: p:.-:AP,OL[^/Z:i;rxpF^#aXFYYnP[+[|s.+{%{\j}^BwBu.҂BҎ/wJ%AzE;Ð '$y/pXg=<-"A>H/J/ǥ_@fBjzŚ4CI 瑏;R<]|F4rcv. (H&St/ /[6^4B5:~ L5o!5: f{ auӈ:ߣ\:ԛq@E$H Ǖ@;Ynuy]^[u4>L[;S%UoMNIA!f`x Gk[87mޣf2%C.Y},B*p=(p|h3h,0WKёn<Ȥh-4br5WJZodnT"h ܠ g#xǤ1hjU4Uc:mt7e'kY-!$—0h{Vfޣ$r7VilߐW~gn4@1F%'#ͦ;`7EE3U6y)7;;*:ga;y8npE ʮ (\rVX>Yc۲@VA&p b Y0T+ἳ3s&qBMZm#h jv1 tmVpl4ij!Q+LE70Yg)N8' kMrHD (%f!sCFh$ ZMv6㭹ߦ{5uel!H0c9FZu?A~q0U1(E/ՉQ*cP.p {KKJKKK}׏\ w'5ۥ( Beiz#,WQOs~Zl&!J=Օq8~PE jsBRF8 qtQS2پzvw;{z‖2ZZq+ԏk7LgjM3'> (>!@EIW\R\/q{=/]rBFӰ1"% @Uzʒ=[sEf. J++"um<5AFNAN#cUnk (%!]p[N n0x+922Σ"Y"Vƒ7$Gks7oKX<j-)dO8>PBuAK$jP6(`h>,iBH&$E2;-&⃟ncd>?Ϫi=} "L n?0tA%TNEAuMyEh9_f>Qm5 c8où.=-x8 ^}*[ev9Q+V^D}:ΚT l RDiiVj*'TFC!aSG;]űk4ׁ5\[nvm2:շŚDV-4RwxP S9Vyv|Gvg%k+j-X6Fa;Y藗JkEirQm2F &2=к 6*4̊2FD0?AFRpd7SpA_t>ɣkN%mҎ[*ejS5a0Rl#s4%dkq5Q tV.lc-&Yp*Z9X\N Hvt9bzqo@yLqM"gֿHm+r ieTs6 RޑM {Xh,f ~oZ>@L'5^Oʺ=xj4CKkYw[u}}q-5[x #5Pa_5IDaa]mM(R[EӠSG:bB1>Ys&$pn_b)mY=$]fVRhi=f>z553* J11y4Vd|HJhx(58jVGlRWsnqyyvt47p:n@j)D?j,SUJPIՋJ/.9%w̩{ǩFŻG;q:öˑmm{6u jTjlF"3YS;V_NY{qSHm w~L5 Vp #y\v=Tz 2_auzuF(ݩq+J2FBwZ^-%g[!."`WB0g,k2EANf.BIk7n qA 6^'?sǿ7ѽk_7g\HCfi?\̶mA1 ZM朦 d0,O^y]xH(]ߞ; < _i$Zt -vmhXA>G#6]!9"ړ͵:w U;p)8xgKLm¶:^-X$4Rgkmɰwcfp a9UƯ%ہG]5[N5Pfiq."';/?㹏~}i><7:t *f];NHh7%ȓK  @oCwpڪjӂܥ6:v&2JjZʋ`?ءz]ž"CH0 ?Wۻ+ p̮ϡX8XX3Z*wfФ6Y|INN<|ufdz{8Z^AGp.|/{>{ދHyVK^a OKYzg^x `fib?IGɘ?ݻUêUEոe-d܊3Tf.bX*A=dZ=_(\:|3  B5ax np>c&L R*s7u>q==<[Q8=䎏y7dѕbd-v@pѣEGڐT X ޡޜi~ :篷=~ʤb&`֭ 0Fv9rϊz{mn Eu7KsLc,Ödw^U4 ąBOCN̿܀ka"|R'49쁈k;QB[ J_yPj!ysy%2{x%5HHT靇 0!:fȥr+ںne&nz6%φ+h69.?+ؕn]G;S'lh9`634. rymnڮ3-[ \۽}JþyULI_~Vc8cj.C"s-},Xdv; Cg3rRtnrj: (ėureW7ۻG(_B~8D{SÑCVMh pLNˮTy~-_pl Nq[8-fe%Õ-={ cdU>/#kIGI)X''meUTxNucjvZSnGJC&\lIUr@rqDk*fRH\NbJ>v[MK >e%mJ~|,Nr9dlii@/K*D.9Ed>Xo r TP% LTjUtj֜}_ 5m E[iu' h3KPe,[:73oyB}n#BVV [p Y2,S[@C$Dzr-(IWq T[CPЉcDUyTH-,ϫ, i_͘V-ؐ?&4q5W20Sd` -Z &hPیN\p\q WoslV{4v^BTe(LT8hY00ҍbNOiL9*<sG#k/>WWjȚb-^9}a{4+ <~S>~vʦPӶ6{ /֐ *zѨoW_GVv7hS B`L@P[GFWIɥcd,v)bz 5f¨y-5?ilƨg\cilwcd_`3Huk羺`,^Ž2b\oƮʆZI `Å7oߛt?Ds)9 V%@>qeq,}qՌƓcR0FpXWeyzV4?ƭ ?_+^?K<> stream xzxU(uM :+MQ""l5=&Бb"E$RTV﫞;3K~s/'@2gnѳիpڢE5}F$No2;}{:{\x|r+S*_}jj3/ Eų+gKV͑>w5׮[dQKFy鱃ƍ2G[ذeG,9'$At1YwLZtw7>o=wc26}ӿd ާL6ddz`ЈA 31!T 99t-=~hswKWO}Eh\%TI2ɫt8΂F?E>^g_9p44X=/P,RS62mNQpL|Ѩ'z>bE? ~'^xu]Fzj ^FF$qYp XFZs})J-JzȩpQw TLbFZ$ iORI.R)5 %CDL3'N]<}9dK)Z.c,>Y"艇~@Uq:)XJ_[t'J5bjr#hiv%8y|~O`3C!S1Gt4]e9//4/ݙN~-)c ~:z 6ugCKz6QOe} h xT h$|`?s .FK=cO2ust'_)rdZ)ayD5NӅ˔N"ȕNkL09$[6R)o+ TTd%y~b(L2ah<Եrd돰<L fcdW ;%>aj(DJRY;#׵- h5L@ѳ1"3֬vYuB@ItU8@y>fu2 8">Bŵ!aTj^;*G[%a\.Ch0HTW+ jp9p)brsv>@C@!**ga?^t>x/z狽O7:fUp3.{q=CYlUED=zUj B-T!K8e$ռm7^ 1y= LǵJ]&%rv4US%gr/v03-UE%:8t#H؋RGu p̓!rH{7UZ5s;!V!TÙ.(w)؈x1m>*) HUDY"F*-L%NH`$Wė>("ʆ۸u+1pC}zO5̧&O3w.jn;0ܙS^wqr%@<(~ ͐+BpW++ #0GQ`=]1D"aFnA!H ez$4'hחdSp)s.Zd~KvX8o V*W1R, ~ sC^U$RZ ^)Z$ JUeEHւ;WI_oo]b R})SJ5:^7LxNgB ocAZJ0z-Q_P;e .+}@:j7ӊ:Xi@p 7jnA/E@F{/I>@E.oYyP{iX ޑ;'f/Ȅ!X'swC κNLGl1+nwNN`Q_41Ug;t7ngh+i߸Q 6Vs[0p&~zA%_kQ6&&&: OQ3WR<;z跑Nfö '현3QyW)ʝG7c #H1U0 [>#9TG1]88AM&X\摱ZR "zo՛O>ɮwmfCdPKU'R-Y'֢h&baW"UX^QףIAX]z`~9LvAD=}QsCVO*AS6 -f_Ty&w۸Afz#s,&=KN'nõF$ώ{CWP#W Fʸ.,"g] SD=UH*ABP!kMuj@FX3I GA,4[{o$SY9%/n4d%&I@Cm6¤V9-L7R^z eP#aa }+O+("P<Dt5l cUc6hwLhez~ƥ:)Mj+/=E)W *NB3#vo}0 8"-Sp*]aN2 " O,!w فܕ̕̕-U™3Lf0MD,k3m?vZW5"tv洹(FC QhPJVɱ|bڹ/|te]YG`L(Z | |O6qUح.k|%/_; g,?ylLC-Wk;1@'|HDe@^/[.)L.nҘ4f ]OuIAAAɑ|ZL2pZ4{榸ӣ'vݪ PI ]f&CFcv b^jb(uo?]$$ JF`S֤ۂ[c'µtp ,z*MνߓCPun(JmB)^jd>'W".W2 Tc#e(AJX0q~;+v.2򀩳j )f̚)=CwGH㻿h פPGf=E2ZN7. D݈UmXM[)!TŨ gz֫g!_+ ]urqvfە8䥲Ά<mђ7^c3qTj);H}.| ̌قV‹8?zbwק ؽa_ Of*d'hUhB]X)o^<$ <27: X[\S.Q[ր5u*g!EyKhxҗvÁ[F?^K S%Bs==EOݤq(KİrX=ϰ@œ.tsǾcRD"51fE}5ָgT i޾N [x{(m7r&ԯidF%|Xj-p|O:(PAV6W |(.Hߡs5)tMXst:#3ضJb=BJu +IhWjD*ZM DŽdc݄ p'x>[Q蟿3K?dg6I{bwfm2U@,Z[%217.*£5vNm.*N詳VΙ9mؕ֋$ H < ,c7}$ԍ ( p!,P.[bCcյBIo+ N6Ipc#"cԧ3Bرp$nǽpuqe*g-Y8c\ )ع#y#HM2QmF} ѐs_ˑe-dq!=&c|2z1`_4p󷵂6veHɫu̮f/yY aە=k5ٌvL 4 Ic'n> R( 2}$ˁ(സ04+}X1rR& nb\avCuwYNl,b[h/ x-`# Jh YĒ8t(P\p>4߬KH\ #C6Wڏi`Mf%eS%VA7]#\aN˽xaO1Qdi5)kyQƤHdOd<-h8.tV蝠pDrJ9xZߦ#ƮZ^]&axMP"fᳩY,3(nXQIcySA3ْmdy{1 !q'O?H}YCXVPwFтjZOFM1=ŇU+us ٞcRY_vzp!,Dak*2 JEIJblltAio??c,zU5񸁟Nc5U"q=>}LQZњ[3m]p\WS.9< ~w {bEN뀚l%bS碧pߌ%.~ # 0~tfIGv;ӟTt5nv\ϊW> L0t IGٴJB7Y!ʚ4Q8)HyA֏9M*UhklF<5rtv8'?Ϯ ˤq?`V7q-4N<>֐#QυC^if|K^ES@uf#GUTl1=yEn€kBB-bRWc9y{gr/sz>zZO&w{G 0WtA?_f*N>q{*ybAu@je&4|ܤ. |%p0^( rKK=iJfrwvzЕ|eL֡O LK)t w=6@`XTy, lXz>aObfGt`$תڠ_>[F$V2ZWv`|g΄^^iPZS-u G#i /tU LG=<橮lMr8ڡh[<̩ 4[4>whbtxn4ju*i S#/`ԯoì_;ؠ=d NZ(HۓggQ|z$^)|>*=BI*EY?)pH^kfD_(1m`i q$o]FWEb$k*}ȴ8_ƁpgiRbVĦwBflnp)ʢ 0*BWObSp VBrC0klo,TVɥR3Bfć_|KvuUDuuN:"szŕ;*nh:a o񈭝2~U ܔ{KE"4T} dza4&(i\ B&|H@ 2gNf&@o[v/F+6N2 ?[zpœJO/1zcI1PQ./Sj6R"XɄw}=v{߃ u=~\xH1C[f(k7܁[v% tR}̓ $NG jC s4i+UP0LV?ztCJ3]O+`/hꃷ)+8FmИNU܇#v- .Ѩ[ÎH7qm@Xcj򒕚}Jh'lo Nѧ~~4?pG_.D}(eUD-MxSP!oS賟/L]Vm,z8_iA-]12.;:!R!*[5{%>pxo6'9_d8 ie @ y^Z3rʳK,{ױǶlNx115%ɊSc8}u/}w&6_r5Q@U[2iq's';;o/_~jendstream endobj 112 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 194 >> stream xH SFSS1000K  BR3rM@vKJ%Au[ы'}}}#ԋ뇰2R`aUxf~dd ? Kendstream endobj 113 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1223 >> stream xmmLSWpUI@YZߦʼn*a HqQRKiA[@0E7{1aeF?-'4XVdal4)*4 cy7VzTYr{ E\(YmVT q%ұ@Hﴸl.5}1)(dY MǮ eF*8ɋyJ{NdpP/P:GrVV6V{ <q7ϫu =>tuCrg!s4549/m`VzD:fC&IJLSc1M/eB ;ێ:0Ax&5Q@GUyǽ_O$^i׌gf˃m{9OTMʲ\CV=SO5j$r?{TW*ԂZ>x#^ͨތFOHCTc!5 4pxuyVp䥑 D&oE6%{1^/>L%WEȴ IX~=kH~ؽ`3}w_X<(]RY{iUؗ][i4|nzt&-BsKeZ3@ ׇ~0I!C4Т|MLns!{BBh嵶fCd0 5~UeqՂ+- vNtwB2c9_endstream endobj 114 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3230 >> stream x]itu|e52ܙؒ#JĖ-ڭ͔,!%HqIl0ep`' %ZLѶko%*Nb>=N{Ӝ:9U ~߽w G y.]_~9gQޗv|Gا,}dc_qKk[{GJM߿) یmbavl[ʰwl[5c?aRT'#g.~^w6'gԎb .a܏s~4d<W ;6VDn~1\c#]zDI@5V䴢:o >$_;mgGr׶iE:¬0C*?2;'zp/rIYCZ]V HmDn?p;{LB !f+GJK׷j/?sv R&w%/'xP?2w73uYKZn"(u `υԅ#}l Djva9tȤ7>1i|ٴ) ԏu?w/l^Pf6iD`-Rs.6&6%LĮ*Mn?v]cѕ8%0,nρ$$]I@2 =^gQeHhGXbsBs e~s~ BKv*s3 #b9w0ʍE"XO:t8\A{bAJs/ȔVH&z7w4(*kpji VB *!k!:Q^,r4 TVY- f3Bc). \:v8Ig v/e}^]X_5ũ׆?"|=8'Nu6¬ᱏ`j J@'҅c=̹]y 7\+ߩٺoWdʘGn|MyU?Dfm1Э{-*Q!rcw?Nn}@gqYg^iM$VLx%>"w tUoP@n,8˝9~K‚7 3Ӥ+Xv@$MOؤ.s P|ۧ?2 06]}]O/('d.IdχK/O8 BjCA1 ACXJ+T7 _QWY"98+QcXF:i\նº$ՕVM=5u-w-//F8Rzݫ:\5/l:"<<:qEql7=؄V|\qk|,3 xlgO_ gwr:dfpn/"(B;[D|N~ࡽ)&yu'^M:'Qw 'jCӡg+遘-dR(nmHoUնԒ6$ε7v.C^gzY@Ii2Cyw~;㵠m'9Nee_qc#I'(%݄URoj:2խ;wQv"0~PD!Q^ ReU{URnw D U+뗽rh%٨LZ &ѹy5Akx_x~>'Y}v#ӊp -k_Cx$-@Ɨ!vz]JRvS 643챆$qh (ʭ*q*̞S5ݪV0U%1|pxGz?~~֖<[R|k-/[G,O4Z1<_xKl16r׶wmLBs__(ċo۬"aEV?^4ܴXxɱ&e`|}"so^Ќ!3 _0T*H~|s"ZzHyz`jCd#٢|JX`a#׉I}".\ 1 %7dZ+;g\c;y]c23U zв栨 2kjk똸2v|bPMR%6Yai/ޗ6#qS~`~ G}!؈kͱ^:{=ޫpb PN?;~{dz4wP@YUT5p<]aa^|VU(b< ?vendstream endobj 115 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 961 >> stream xUQohe雛rSw8E\2&8*d:a ,i%r潵]]rkH:]N(h1tW@o zYE <<<ۉ9=MMO80b}׭}o> >aco`/b^̇V<1oNy5a尽~x2#LĠY !EÁEY8q[$a*6[)5N%/h5:q^`uѠ~9E)(RMk,Eb %@PtWqSrh73ځRIVj/"T *ucMKP-tK(gZI=#u`+z3 MVU,f*rw!uiR*h3i}듋!#XC΍kgNZK$ LI ="\&?YH+oƿ`6R4_WPVĒD/;,03 jT!.kW];ܝ , j (l~=<s0/d;߽37%6Љ I]NtL5(Y;ONPDtȭj!7M`VKTj h mmRVm6Hb*zXmiZZd??p ǽOLc9itN3D]F?C\S)46D^DcGND(F@lw3>DbAɧ> stream xKq;SfN3KzB(4(QSMLtܝg[xT(RžZ7 h*9totoAڡ޿PN*sw3 xEY@;릨E0(ŧhJBs[vg f> stream xzxTe!#*` bK/Ҕ -!!u2NeD B`E]u}{߽ >~w{$S_~RB ())teO0v#+R8l'@[#7S7Θb%"1xxN8xXHۈ(%F E`b1xFHSyf$z$o7@Q]e@$ӊQm#J<^"'감5l ^ϲ0`A۲mKY*!!բJYI rhfZ ZEF6%qxOE:JiOLFxCeFN7e6/A|9ۚP%\ PoCR$׶4qz/x/[ JDdi4$DLӕ߼pNБRՈ"2fQ`J* [i2$WGڝvSh]cm厅p%|YX}_yqcx1pJN<J~BC!⑗_Y3LZ<H>;h~rm&h.^[۟#87{6oϟmn˼ U:f)0Dsߟ]; 0H:9+5.з^XX9K:q~S={v l8ctKT^˃yLG iGхHvtqmZZ iLwo|aIr6IInot6s'Q:^= W{RSqf]Y~U5 f۬:X8⊑Fڒ~p=mn64&rEC;"]4IPŅ ;Rq*ŕŒE" Tĸ,S2YV&C@DDĸ\S__TIY%HDEhKKRB !@+}ʸF'@bJ6h ZCdD9h+4b<¾g}31 e;@6HTfz zE#-)cJ(G=,ބ`xr~/w{+@LߐLłXIUH@qV4TE/!8D%V 85&e s=a=}{r{o]6lסgO>ۂH@,T:,JGX00(7::7 P(X)nVPH5G͌B.K]:Qru\Y)H)ӐQfOѵBаza$Fi/Hr|t!.IHH +Jlqf0!32m@ mosmmXwu@2b0BzPB?؏e@&L%A!0pm(TJ,Jr*+,E iI҆a!> J0nHh` &rI& NML*r! vN==Br;BD ݫgn-oX/ʝ$wш ¸.5^nKM1PP"Ѩkf>&d , Ұ*7ٽ?d܏/(.#P5,_1wf>+ɚSX3qP…G}`DVɇ\dfae5%Ha#HU >48c }|kƹztW +/.ngw4-ӰRX&oY6&BҠ*v})?ʂDA5nv]2t#А#MG^j$웱5J*h3 ۃ,eq[ڡjsKg1`h[N'~JV__ }Ww "`qHD27FROvRdh2 "d%; ] }wqKmN:pvv8J@2Lgvo Uohb1CҊ\$gOI '^0;0BRaTf)VE$ 'ifo&3vjR͔֧ܱ; s:D ϸrHf4W;= Cƅڥ*ڪM e"Z\No&v*:}3V m܃s4DswL? f YUbgggJ(fΒ4  ]Zjy[PWX\FGZwj wy$Bhpvz:ݝ!LT^KU%ߛccyv鐜?}}tNmM"3%cӚP].k⭡5be'=*2#a8jFf0&Sfw`]QԲ2qBNaTne_3'RO` dNTP̓@"654+ĞFt1.Y l.N3_ Zp8*عN #.t%. }}o;91 ։Wǁzh[Ě|K6_ՁOp&\ GjlyQo$[BHf3d&`2@](H4uqr2-.%R6Do>heЅ)8$5K&Sqv܁1"Ƃ Y),d~ee} '1 >y Os)4kH&"$`ƘM3Of^ <^e -qg]4IrEjT#[a5lP4Jg;X=˓2D֔J[͹p/}dXݤQ} ғ;H9Q0J MP'ji\_r*K-bXE6l1jG?u2_ 2kٵANX>WovgFްgQ,Q_nlt*7n6V7c%*spv@'<]0Z6kj<͈-㣕0C6W+6SWK=rX(Ez.ᗻ2Vo+œͣ&mӨޒfY+d2Ù#rڂ "^O*~#mmd87*Zy䬧ܳvxW.)LO `2`fqS)=оӶxh6 #A$KLec&lջIne0@C+[IS醮XE"̕x+Myu 6Ktve"GCB>xąrۋ&|Z:Z|AW'9v}Wyw=9Nޓ6 .C1^/F^սa0d >nӅo d%"76L?wwQ_~э5aGH&Tʐ?G8zg;&dԍs l3]ov[Z'+,)&>Fd U~ o<be긱qefB, (4FLF4JrV_w]T`GS?Ƭ{Tρh)*Л#B'M;u&d!ؠ)MQb$f +Rk#0wE\v- i84]O՘`5Y&覼Eݔ0ojp i;\mmmXw7K`J_RSWyzǦa90K8$&fF g+?[p"49jK|:s;}c&KO'wMKdJC)Hʲ_O;0M9PUsXiF# 3p -`!2쯆pjH5:[_ =Gn~Q@OތFrY_E4P!EJ_\C[uӍ;]n;tSyܳl|G^_47R4m"ǕB+xUOV^8=2ٺxb#U2|,pOb@:OE5ѿ;OCF81_Ο|7'z$e*\Et5^<&i-狮p$Ε潸 _zy(S(+j?;[݃F|凼AV1UHfBX NgKn·PZuj.p^82O<1I*Kxq Fh7C!I&8Tq8Er{ZG]=[bj?k7Ǜ26 K-)Zemjlt &V_qlP P;Simq}1rrQmn6YN& # Wv*Le^Yn M0o o>RVZJYZ-rvzz~Q7P,̔iִIR|WC%W*CS@`%םT13T i|nNjRhҵykiq<44J;*n`]=T-_ٞxj 黀=# Nò&BIjڦ.(o_ 1%qW3(ZO|ly};28&[lg>p l>짮4h, BؘB>*wLptv}f{¸o_pJ.69Ǽ>mH*K-_.pCI~n4E+)a<Ϻ/I s<$OdXB *ٟXq+Gd%;=RcI&2 MÌE\*дW8f$'30r7,:v; rA81Mz~w-YW/l5%M]8{Ѩ=Z^smt(1#skW"Dn^#PZ8vEXcmh{d#ΖY0p(=GͻO ⒟.uƅF26T<݇5)bV]5PqDЏ}Μo\xFn5dIL=# V6?]=q~N^~ps)RnlL*T2砠׊+K+%{FAIWX~(5`) jI؉'=<ͫmɭA#Z45Mw#NWnWsj5/ל> ;lz%XC*"X{u^R`7!yӷ򘢱%z DPp=$SCJ Llendstream endobj 118 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1718 >> stream xu[PW('QJP'k'yiL<O| c`쀍1V P $.V $$$q18mH쉈=Ij>um6i=g%.83}ۙ9|(ZE(vݲyyCnPGgUZ J+vb,"GGM<,'Kʵ?銾(~bVMu]d?蔸!_+oap!c?2JI >- )rg4'ʫtPvkUO5ߙCa;06`]d ULpzH)*pÚT7Hוcp :lƮ3F0x %{-vJ \ASFqf+>ʄ<>'.\8X!O@ S Pη/K:A!(ZNKHuWvNĂ-Jie- D q5z! X$%&J?_RXhTY; &d|`Z@"bjM>߃7~h<;('$a :z?d)y,iK ;`R6(p>HpA],|ESq, %g?᭪+6a_PeA!;`v]@RJ]hĤP_^]`{NOz~T&^2c8^GxO1`BG^ŖYhh*ZFcSew2LKvɫ 1<.#%. <=?NB n[Nz\=nšwvw 8})-*hʟKɑ;&zI\c<ךޛgUk#-gN53M1B_$,Yrz͠몪XW_}5~O+tX4 z}ϔIȲMdT %}re ^mzZKbA;l,~_ԽT]}EJ-nȯYnkJqL0 M)fn0 cao1:omn?}o|pw-'xکu8."/- o]k`hR1{ 7įqZgtgɖH'Iq c;tM~e~{1=%~eA3ږinnkknδf2Zd$~I PGA~P]ɐ?-wY Q>JŔ)]`x(n l~1cq<^k|02 G'Dߞs$܀ٹLV8>}"LA:.Q\9 ig> stream xdCMMI7`K+  ijJK(Ҫopnqnzv`~z\e~}t;_bdw揗cT(]z~ᷯpt|rMl`zK~pnpop{uh6zFVQP~xwlqpker \OK}~ſŋzk} 7 endstream endobj 120 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1251 >> stream xMS{PTe hswiLc1BTFKS .QD,,"opdDžDDP4|&`: tq|s8K)D zOTӁ,gyۊ{nW\OO&'~ޟ(wʃ8j5r(5P"$%Z%Jҏ7eeeE0;Gԝ;Bu,:?!T֔h׫ƦFPe@v~r46Wo LJѐ3*d B.PU i%@m{# BL@7mi1:\ü@(2WZlA^9ΌeUXSo5~]ǥ]uGJwo9=L#3KhĊQ6Pc|FcƗC}8N6⻍U臃t_vs`lpؘIzOsGr62,v (Z* UZe,ٮ)ҟ*+Rq2#eՒDEé2 K ]_E5w&aC[b; :Vw${{m}PhdxH W|\}.zZt u3Wޜ`Kgk cxq,V.6lU =k: ϥK]xq=[pncl$Hӌ*Ӓ@@F!_םTCeY Ѓ/ìǗdxdCAr qCu+UN8Ź1S0k DNddy&W]TSDVY)P=@ss&ȳ4.y@vYEDm&X[T6 2(@ܣEkT [%E&d7I#6)`!)#MIF1/e$Y`1sY9<$d@&l^scnFA>7XK '\Ы?]{mH}MI/ klьnp tYv Ua5,R? x`mCoɰ1D.x<z*BkǫTѦt-Ky-}GMTZSy?;86]9[l3F xRO\bG>a8`hʃ|wC'/ܸh]#b{=1A<eN|aȟ,:OF2endstream endobj 121 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 543 >> stream xM]hqz7̩%dntv} P`%E%,k^ a8ekrDj16.MjI02h5tu 8j3֋(&W@.N9uAy^o7`51SLZ31;˦9w[ F[CYIXkF{.5@ȅvjo'!9zҢ܎]fpw<2->郀?DI GG^;@3ukD ćfUEdEvlBѝYnqs"aW5 ޵w7OO&P=LCMvWe'2kSx3wEM 'B ƒ\>IߪJpԥ;i1DMA߄m:Sbs1Ó}y /V1%bh\O{C]0PSHo䲯o&;Z˴΃ƦfSy?0 .`*tMbcZ?ݔ endstream endobj 122 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 202 >> stream xcd`ab`dddwu041%faaGYS 9ĒԊv&FF|69Kv3?D.0{ϋl9xUVcISz%zZ#HwU-s,a3^"[AWW<Ke>'_L endstream endobj 123 0 obj << /Filter /FlateDecode /Length 1683 >> stream xYr6kиBmNh&Nt&xhT}R([r@8lJM ^OO~;r|GS~ˉ1ƌTy9yCh/H_)l<)?l1aWaȦ?'ߐ>C ;X\ȁÜk$g Lkk/ȋ d:CnʋSq#gG ]](@Jp4mcKkziHZ$mb- 3LąKp3#\)_Edp>K(eFDuV^hIrʚl> ѠbKhr}! we&JuICIBlڮ#>z: ~yud"e KhP猳~rS]^W USoK [Wϼ+0M^,#kRU@`(UPr *"e_Ʒ0j ?Y@1}%9iko2 f)KOaD>B v$M\Am(C0sO?p(PBc)@yE6bk;*kA\4#G|u@6{=lzZ/`!^L)f@Z+ܖBnj dSB$\0QS~<.kRq_6uiPOGD3,9ia+M.Fhf@nS MV`t@BrOhv>#$Au0ٝ cbnfy>P*=]&mf4[M";r&\<$)ҼnLO#d+9)Zڝ`(36VhؗUҹ>q=u\{AjzWEX#u`bbʏA ݞv+80`8lUnkmRCԪ#]<ӝ'k~vxAw4Cvçpç4}:Ѳ?c0"?{pa;Ɠ_M`㣖5 SkQB۠š4(`*L4 (fПL1ٴVh}q{n\Pto ۵2ʿKH&3 aeb+{)`<6 uS#= ^aRt&C(F^ :ٺdxE&itҀ*"ɳ˚ VY Jʬ> stream xcd`ab`dddwu041%^2{@1eϏ?wxqϭ?*~(~^8mfOϺ>}wsŖ՝Нmם޷G9}nu ]m%~;KVzo[RNw\wrIwX[E=3C#/mkߞm@snt*^ !cZO}-K|wjöUݏׁUjqd`mSendstream endobj 125 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 156 >> stream xcd`ab`dd v 1400q$2黲!{@Q!=?}>0c]Bs۟~}O&ђ >S{6us,]@~*}&3{ry%|r\y8T5Kendstream endobj 126 0 obj << /Filter /FlateDecode /Length 2993 >> stream xZˏԞ{[[Ԣ)mz䠱53Nl.#)+mb">SV4+wuYgofUEVb*4,Ӵ |P`"T挙Ȧj\kP,g=rwb%hY#R,V,95y2+ZWn'?WmuWo=[IKV楔s$;ՏMh+\2,SQ ^T<&sA)%4'4cy;5zn2xAH^xjQw j9ÐM|1b (ȣ7a(/mC=Z!Ɣ4'8"z*a;֟&IUȐC$PqknaU*E!,\F[4)yT:|.:T@ݦ*$Mk2WFӋ_C8(Ջ\ V2%<-G Ibڟv}Wԧm|q $(J! ~U{޾ڐnp(g~xJRGwO]A6M»eOǾ(vs@Yա|uԿ< p`e?A.bBs޹\hj˭skMS<0BOâK_PrK0` GghL@pϼ|S7sIjpB^bE,ҽ2p0d}<+RC@ℷ]YT| 'T1 ^"sD ҢZP-PHg>m׏(am o]F9+ ti2+g hn[ U0:9sλwHMc!E޸)|ַ3:7mYƼcE'zdaSl"XKT7%4i49]m$ʋT u}jb["k@#vs${'wU3Ճ1cۭ [cdx9+D8yBEQZQW.ڃmw+?l⹷V (T?.$ءVي5CEu?U30i!݌CʡZ+yq8GTY9j&{hf%gHgؿ0Gp#PInnƤ%QrH+D v *$(|e:E=E)G ր^0K5@2W"Eu=EǢ>&:39e8)RBxqBuB?mm"sqpD&q"WlĈ{TpYD= *,չ,AkEDe\j[X -~<"pKG\ 'BDT ՇOJ§GӣISpކXRe'Į6>$J;ϰYs~1\^π*[ܖ()9% f ZbI$*J r2L%ϵZD@C&i P CK Z +\ Z e>zN([S`DݞQ(8`/8J$^RՉ Z r?JKC.Prq>ű\6ia)y =kQ] 3B=*uUD qRN qZRNiP⻜+04W@Rb@aZ@RaqLIQNPJ% ]=jTGLE\=jT.AݶsB5.%\աi1XBNGa 15q,f5.%.Zj%.Kj\G~yJK):иTwLP㴌_*OhP~q>!W@% BLyGMвKqdG;Umx:,@ݛ;J;`:?ϛ~}\+:#ߝwą ]qwbkoΡEmSu{Jm;vtȴ}ܠ;j. s6_9| j~VTpN_L}T`ɷD5ͽa#W{3㣉•?MdnoJ_Tכ{nOF&E(ФEm)y=]Z%޴yWniBLnh4v&Hohljp[u oMe[r;ѱn8bj /c=_w+K]`_\voBxH q%yendstream endobj 127 0 obj << /Filter /FlateDecode /Length 3098 >> stream xZIo[c94)VV! `$0(AIhm=y.-F=0E{߫8WY<_~Qv[m~DF73+Gq%"߶ywbLDqla&>^Po/>Q!Kr]VbPnHOgxja'{ /''1'}>qbF"Os~e'psGaCZ8P.c:.9FqK>v{QzI|E0Qxwy|OaLW>1jl^y|:[}>vgs{'^ t}bЊS(&fM -E'۪Œ'Xb \2nvePC^-IJ +H RmO\/2A 'm OjcAYE>ۗAxXU8aqOJᥔMbQ۶5gMQb]ݞ]^oҢ< c|Q/bjjx{+ ^jyJRj.VZKJXtnx$,R*}~$$gjko+KnM~njiV &&/\Gf}hoi΃,IMT&orVExcHYǜTߣ bp*Y|CdUsR hg?KEq=+p[l/0){JEgyS%CԹMxɬcx}eN?e y21IHdfѺxi Hބlrp`;Lc"p49m+:uZ1Ԗ< #䛪,RK<,pخDIVȺzC6胦,ַ9iʐ%JtxsV\-)J d"ʄ=V?-ڪ"@D+~wi׏=X&q@=K[/Eӑ3׻tEȮcEvo'kDle_Û<@)S/4^-m^mt6y?cMZ uq:=G Oǃ:҆w*"jCLjD׽|g,v6  qr~3D[E&N(y:I0X,;]Xtpͽ?Az6ziJ,uІ#) 1Srda `ig= 1 Z6QZNBI"oO~/";"pt>1s};mrHxA؆շˬ 1bP]%TOOI @ΝymҶ.^GY~lړN1 mQM~=-ΦRn?mUR7Myom g10Sa)Y&qps4YW-> '.B] Ԫ-,RǗ tnkٷYZӴ$Jauߑ5 6K;XheR8/Na-5Hp)HU:.`.AlauWݰy$&KEL77`W|6(֡ ~y̏4~g IM$KS]$%IW0^ue6[u]Wg(|mɖRn}p5OF i~D[cvYl#LZdΝ6SkOgD*1-୳#e&XOYC내Rgx[6=}|v2j<‡GD-dG.@Z^?#M0XQW"8@tȄM< lfEzsبה2|!BObf k3競9CLx-|'+AL!ɀ0$}3#M P>_'Lаq`9@lE)Ρġ+?>??*24Mmɸ iG v_ NҶjÓIй p"`im ~0!0|B,mth K_XCbbHw'VmP(6MHQ:MQr%"+@B^e7->"B~&dwM~B<:pʘ"K~3O0dl#Cq?(J$5 > 9R8Iȡ/u P7rHj,;1(G[ ch_;Q$ywiMEZrz:͔b  BbwZmEl|e&w.`*ш܅&o<_M|X'hyٱS~W6}44q{qq {~Ӌ 毛RY< (͜R N73& 7[*:4JVC 1TLbCg/@%V|*Ki0Ot] %$ sW}~7Nr +Po0D02ܿ~3Ojbd0E*w ܙ?ڹgW:WW42]$X.%]}xbhtPHkeUz_edendstream endobj 128 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2759 >> stream xV{tetf cx CDP@)h%e+oQm&46͗&mҴIՖ P+ R%![AYduA/9S?{vNΜ3߽߽lDp7,ΞYCxF$7J) e㩔T8n1'dž"XSr^?}Y/ư,ۈ -6c˰-rl` D`ccTžd`șJJgbF|4#Ưarِ&'{iLbbFKJY)=6jbmDSFqD"70T ꞃSZ\QZŃ!u$N`0X I|]B p8Дj׾U۶bE3aLfFS/G+:[]99;pZor3DpirT";k%"PjRky(A4 -7"5ϕR| ^/9NR5K̥ u~pmQ8F g99xV+yCMp۾d~~V{(Ep9Qg/ڕ4z/x)ñ.(V %ފ'p>Qd }8 \V[ *ja$ځ/X+޻C`鹸T/uQ+ 6F/% :m%**IFdH"/xǢ7ۈP}u8ul͵P`g2fX:\2: nˊ% jzo^}D:2ׅm-,a*FS"10p6V7pW|@ȍ!yc)h:wf<{WV:6[  QNuR]Q\ZZX>w@ (5Z mՀ4Ƈ7*PnL8 $ָ 2e!eéh5b CuKFDӓq}s& 4"q&'h&~׌S/FY\@!N^l,B۫m.PMMu>˛"Ɠ0V{; xϢcʈʢzUM`c쏶L1@&`æOq>X"RK,*RRO\T*jA>)U5qoY^PMz+&thԂ &zBTF^gps0%ʉOs"cxxw/i4ɈD<8rL=>8\pDy@㔀|`T2n>H9'ziO-(L>un$ :*ۂM -lv6)0H(R7x_N޲Uk~ Wk5!(,*R !Fc AqLRח3׺bp^ˬ[TN1"MTQ 1naJ Ĥ_l8@SH>M5-fpи$a%FBNV x7 v)*@G'G$jkC?FmU=\a U+Mmp@R%*D^i`~ƒpHY+5١RH[u FR!V6z-JŃwm崬S@Z,%6G( 'T=uGzP_V3zPBMAEᵴ Gi'-(]W@oBIvZoo*K:;pؙUX8}F-UUhjS:ܷlm [T!.I*\~&݄\ '‰nz,,RrM ִ I]I PЏ`:'uem ckw`*x .NY+`דs]~06RDI&/8`;h ;KU;> stream xcd`ab`dd v 1400q$dbaa]R~= >r~2Ft''%'u5u6t7rTM^"c˾HLX8yq|>EUJ丘p20C".endstream endobj 130 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 176 >> stream xcd`ab`dd v 5070q$eaaX~= h Ȟ2&K??O[t;'g*{wzAgIg^gnw^7G@E}vg.HHAi魓kr9丘p208endstream endobj 131 0 obj << /Filter /FlateDecode /Length 161 >> stream x]O10 :"0~ 8ʀ0%:t8K结ϲ=(ul"-~H0Xt2qA6ٝL.Boh )jHUյvIG`ٜu*9K7SiZL!`(S!endstream endobj 132 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 134 >> stream xcd`ab`ddds 4$qq# 2sS Yl~t}e3#Gtݓ8V/Iϩn-ǵK~UI=&10-endstream endobj 133 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 186 >> stream xcd`ab`dd v 5030q$caaV~= h ȞqLI7-?މ&;i?ٻK:s:s9 o=M`of⮲n g2F."ۯ%Oy=';=endstream endobj 134 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2508 >> stream x}V{PSgbP{>Zۗm֊ZTT[*H  b ◿As(;dnmeka?W3GTrZi3lK:BU kHOnU4VXfy]ē.4!I?@OV6I~\5I7fJnUQFZGCf%m6fڗSǼ$E`=G| 'c[Aq*AAEԙs z,PaR@^͚GHFO'&QDmOhB^/8AX kp& "ؗq$< ԳZѓ@9,1<]%MװbVWv|Ά: هf3&`MS;_ǠY0r0apƢpp3[Xg}3muZ\6-x[Y3gc7]Þ)W ׉HUZ,UJj 7t՝Y1u>[H4sLK?ϬVURriUr֋SQ%%t؋<~)4w%o}1EObǿ@8- =7f_|f!,zfS]^=oȓ٠DPa ~.mE+e޾6].h/Gץw8hKkx($1=_|YK=lf[5:2GGGh 8 Z%E7@9Tتm͍ЋwZ$ $mJ4vy3>ԡqIˈ rh<ih%+5T'uR]Dթ\6z;R+04mHh҇2U1}qu~ { )w3 ,`O1|fSSA*YV"!*.; 7zn8vufI3 sՎ5'/(IC\PN7zAsQ9m#yCT`VK&`2031KW]tS& xƮ.J)ޝU adR:BOqoHF_퍳LF5pL d-ﷻ'){v; D1,Z(#B[FirvNB ;M[`PSw(VL teP 6ses4ɹюb0oendstream endobj 135 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 181 >> stream xU SFSS0800%K  5R3ebUvKJ*XʖeڜЋ;) ҋ3 }4 ? cDendstream endobj 136 0 obj << /Filter /FlateDecode /Length 1018 >> stream xUMs6WpH0>~tq4dtrHXbB2AV]A9J^::˷o>Ӑ_4 wS@n8M:ȳ0y’p 4LYR Ou<`QY54n#A?s MPӖƍe<//oҬ9γ}sdhEYLX=X>i̛e2BH"5G , U %rs &Ҿ joUC9ҍkչ@xBmW;ԋl(Ź`xKQK7q{?41.C73jO} W(`E+)ZAo}~}Vrˀl1+2Eʾ6h8ܩ~;gdLWzJt(7~VE)pAQ(wܞؤ(qs)ڞ{P=o#gթQQoV܊La@:="ᥜb2@e\^?deOq4iɘNZ ly(+P{˱0(e #5f [A ݳAv> /Filter /FlateDecode /Height 450 /Subtype /Image /Width 900 /Length 20276 >> stream xw|SP({K)-[l,{o!CA* KTd([ (R,Pʦ*=?)iI'$敓4#$#F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!FA=G:cƌǧK8 &iӦdɒFOđ...m۶5z"ԩS۸q㌞#{ٗ_~9|p7770(P^֬YfD[3z.ɓ'3g7z.J*)Rᅪ#/|||xj;~~~5j_?0(ի州qdˇ~(Fa=~8K,RңFőU\YbT^Y=GhXXX鍞ڷo_͚5}}}[je\"Fu@1bT(`GQ: FA1 bTĨQ}: Fu@v1bTĨQ!Fu@1bT(`GQ: FA1 bTĨQ}: Fu@v1bTĨQ!Fu@1bT(1bݻ~Ç#{ѕ+W)SDDD8q8s%KLFOđݾ}Ν;k8gϞ?~ܹ}sIbToE׃z]Y0W1D;1o}F/|z{sy-'`p/g/V޽-p}3m~N{ 2pN Qp ?]?\2&ãĝ;|o?I/ou'v1̙3`SBMbw?*Y.sw;tP*UV^G=!FKjg&(*FV1 lڱBB+xЩ$A(M>} FCh< Qh,1 JCQx@p("F=h@B+bVV#F1j RЈQhE;Њu( `QhE: tDB+bёЊE˜DbGB+bVpb("Fa R1 Q; bZH8%bZpaЊ=QhE VЀV(h8+V(` >ЊЊ6K("FV!F1 lQhETp("F$QիwbNHUvgÆ Z:qD2eΜ9ӳaÆ>>>SNk $}Ĩ}rJ ._3F駮]f͚nݺ7nؿJٓ&MDHb8bׯ?zhDD-F_z7oޔ)S!k&N8~ O{XBرcp̙k׮E%K{Μ9 Pּy&{3gt钋ϐ 1jw>GѶmۮ_^@J֮]{ܹ"EX`ĈQ=@v'-[ɓ'_~ꪮ9r_iӦ͛[>yȑ#֭DΝ;jѩ@=ztڵ^T)fsh߿/h>rÇ_jUǎ-JZ[5p&mڴ8,Ydwܑ$aJ9W-Z4$$#Tvk[y3hР… @a+gt ˑ#Guk޻woxxxՕF:uQOό@V$|f:tXf͍7rέܹU.^X`A1 =Ĩ݉5F#7ɿ={TDFFzxxLڵkɓ'8V1jwbgϞyzzʕ?cƌoׯߤIƎeQ@t*FڝXcT,[gϞEiѢիW}}}vؑ%KDي8v'7n\hgj՚2eJ 4(@'|ʙЊ=V( )![bZA bZgD1 Q#UFB+b!@B+b[qT%F1 ("FwIp+1 Qa%F1 SзSQhE`1 Q*z#L ̗0}y3:u@ҝya8c4<\Mq%r;Qg%N?,Ye 3S3 mz%Xy1 t̨84bZV2bZiC "FUҋa+F Fhd/-5jԩ+VܹsƍmvٳztңG+W'I¶ NS+W/_Ydɠpu_|۪U+⿺'Nl߾=13g,T. @$-U&%ZLxe̘wc8Gр6m\~}޼y~ɟ?ӧOo=pr,nݺQH 1 ؐR!F킻{hhh_lr=zqƏ=*_k޽ۻw 88J(`/  oРA\3^zիW׭['gZڴim F$YHjQhE=1 Qp4+z!F1 +Њ`a` 1 Q6WgEB+baจQhEH`غukڵc=3#F$ya1E'K6mz53gN]QBp"aB͛7^^^͚5Xbbiͤ=@!Fcg'NW֤I d̘FnQH0Ç{Q4((HYZF]v0A@bR?@¹ p &lذAjg:?1 p\Ĩ=ڷo_Q$F+uww a{ @Gɓ'~~~J|ʏ5ԪUH"6RG,H b4v/^8x(^RֻaZxqMWLJTzT S)TTe=vV4Qv%)}v3 WI1Q$CܹL"wӦM f bذaϟWWfϞqM4iذaLlt82bB%@6mZbEus"FNY1L2կ__T2FגXExx.<w=pKrQbEh"##=YZlq5Q BG4((ŋׯ_ϙ3XbRLi ,Y=z,ZEY?pΝʏiӦ]bE֭K8J(q=h׭[7rk׮ϓ'ό3ڶmWwԩ˻/XbŊwܑ޵k\א!C1͛7߲eرc;w|ƍ~]tرce˖8J((a%Fc7|ӧBԩ (3gΐ/*G=zW_}Wg͟?? @TYc777_~B M,پ}[n}۷oΝ;w 4PTTرc˒%Oh,:tf͚#FL:5橣F:uRA®]ׯ߷o߅ ʏ5k֔}Iƌ1 7o^OIVh,J,xru7<{A[.^ヒz|jS ,U%~5j$%5kxΚ!CM6ɿ:LS#hr?~…B < 1GѺulٲ]xQڷbŊN>63qo޼YfX?%o'o6},u?tUyjݗ-['ȿ6 .ܹsgzZh!Mٳtҩ/-;vU4 1ӧOWXիW:u7nҥK'N\reT9RTD:)H5k]|~A͞={޽5jPTV?444k֬X?OV1 |gUdȐʇD%K6g95`~2jpȎ/"""f̘믿9s&mڴu֝}h1ZrÇx"uY 2k֬۷7hgH@c+1j/iǝ;w֭[WWcpϟ?7?ɓnjf͚[O8q„ o_r%H8:a-Z8ٳYfaJ9T:uRJ5kߗ1Z`G=x\2XuŊ;w8 ٳG51֭k9rH7`S|0Iپ}j֬YNɌxIN8UY81ˊ+FFF=zTy=fz{{p4}>>>;v_ϓ Ib+oOB j@ӧO;;w HG=M6<0;ݧOŋ/^Ic+@ObQR|͋/_.Y={͛O6mҤIƍlժ:XbwM6ϓV1jbM/M/_K *oիW۷… 1 ЄlEB(f EuԩcǎW^?~|DD .qQ@" UQ{k6LrK(?˿XluĨ= S$@77Xkq[#FvTu("FIj߈QhE G("FN=AB+bر ("FHR4bZؖS~V(>@B+b!Ia%F1 =("FpjJB+bΊN%F1 (/F9dx+(J=+1 xNʾ>3BB+$VI)F#[01 3FG`c(rՎlЊ}{*q F1dQhET8bZI H"QhE:^sΫVZj~~~̙3===6l:ujXuFa1j/n8}tJW*UjܹO?Եk׬Y֭[ƍ{I&V"F?T@b F;k׮XO}U޼ySL)w8q,XЯ_?-GQ8vٲe߿cdɒ޽{ϙ3gʚ7odϞ=s̗.]rqq8I :1jV:w… K˫f͚ꀶmۮ_^@J֮]{ܹ"EX`$Q^#"Fʕ+tv=uezVX^lٓ'O~U0rȯzӦM͛78 ]p!1[Vޱcl!`kaIѯaÆ ː!tn¡b/)]%+L"ڨQ[ʀ ܿɓ'>}WZձcG@.\hqnJl{ۦM\\\n߾Ô4r N>F~~~XbѢECBB?~l~.5???W$W7HRHUЗaŁJ3,SL 4mVZ8Tj~%KzYv{'O\0jԨSzV όگkʽCk֬qFܹq/^X`A1 $ Ɠ \rƌdTٯWZ5M^RH)S^v-yX?Ob s#FBǎ>?~5NΛ7]]]={+W.VoҤIcǎ-1 TQp֭M[QhEJ?l3gfϞ}L9=Çr2z"L~u\tPBFO]v3eʔFOđ=x YdYf5z"իW!!!y5z"I_;c=ٳl߾}ٲey#rC~ooo?~,2a*W"E=G_O8}լYSUVF%aQ8 bTĨQ}: Fu@v1bTĨQ!Fu@1bT(`GQ: FA1 bTĨQ}: Fu@v1bTĨQ!Fu@1bT(`GQ: FA1 bTĨQ}: Fu@vd̘1W^5z"l޽u=sLѢEzꕛԩSg\Yf$F7'Ν;nܸ{=uRJٳzF%aQ8ׯ_miӦ5zY/dS/^lkI71 0 1 0 1 0 1 0 1 0 1 =zK'ܺuK~9(PkgΜٺuk@@K%; YrgÆ 5k<?~\Lٳ9r|ׯǿ[~]TVk׮)SL@sٲe˘-[رC+WܥK9r$ym۶]v-_|5j޼y'NX~%KlݺWpT 4H.݆ bCǶc#Fa|}};u$;<<<444k֬6mV?~\lדtx 0{dɒ%ҡC5kTP}(a*6ݻ"E e@xx<.](*-:|/RN5k4h`6L0A{4icTuFYEF3ftss|tLm߾e˖R/^9s7o\n]yٙ;wVZE2ƍriXcT.m'A®zjҤIӧOwqqǏ}Сp0}>>>ʗfEJQyH"ʚh1:f̘ɓ'۷zv]^ѣGWeCکRՕI^^^ܹsg S屧x捫{キ~賥ze|"##Ϝ9~=$$Dr(:j׮-=3Rn9йƨ]Nzjƍϟ?/ZxhӦoo8gŁŋ~h 2ԧF1]t˗wss[n?3ZjYvG}`~Y?@-5!C̘1|}vXXSRV;wzG۶m^~i,yTR]WǪUVٲeS-ZÇlk$Q)'.Ϳ4iҸqUNbł޽6mZtDgJJ*_|{QFg}.ZHi6XN֭[Y|\+w7yطo^!d6X(㏗/_n^^++WȍSn]yHK -;w̙Sik$Q)E3~x?/(T~?Cy]9… e6)jӧOǒV2@Ϟ=X^.]~'NPx駟Λ7O~ݻ%KEFF ڵk:2$˛7oN>n͛7K*%*o߾mdSL9r2GjF?L,5uǶ Fa/ES~f͚(QN:uի;pH81*OrTTiȐ!d?scǎJ/((Hwk8 vg%KYܹ{/UTL_WX!}cB|}}۴i#G/^;wnhh EƍZW_}ULC&W Q#yXJz*SWZ1h6l0G~B_RJcg3FMQ59hРwʲH:Frq3 On߾8}:uWl"/XHٳg:tعs(J"EÆ W^1cDQ.]=0+V/A`yP?Ҭ<ҥKW\']|Y~qÇ׮]H9ݻs玼J<8<FΗ/_\?~y\GzCǶ#F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b!F`b 22رc'N;,Y/իWSNѣG&L i F@mh"۷oիرcsɓ̙3³gҥK8s^~ݡC___Yd*V؝;w^*+wȑlٲ%QNxbcǎ7.yzaÆ~ݽ{vgB/Q`ǎ 6_~M61ըQC9RB]81 `Ajϲe˞ f>zhܹS1bDk;tPP!S~ى'Mvذa֭kqww\rժUܽ{7 (((W\uussS/[f۷f*^^ 2Xu6(G,gΜ %*=װ[n=~Xj2_|?[nϞ={Ꚙ1z Jh"e˖Mʏ)RȖ-k׮]DՑ+WE)+3eO?)5?]7n|ٳg_|L F@|:udJ}]^LQ;Mԩ2eʿȚ#F(s2%F%'K,W\=zpss۸q͛Ԋ+9r>|DpHHT7RJ=C r.9IK.\,zE=` (gʔ)GΑ#C# *!CL6EY?gΜ?ٳRĈQY(Wܾ}V믿dg̘13gΔ)S&22ɓK6?{ƌ8PD e[/ 6ouV(gӧO/_|@@s}#G ROUF ??}.\ДH1uF$G!~_W^ݶm},&M;v5nX͟?ڷ1 /<<<>~]tYrt^,Yһw5kٳǔH1*ѩ|Ux>}HqJPĉ1cUT1G]bl2FaaaӧkXHH޽{eEiҤ;t?еkh#w]^=OO[n)F$ WLd>#Q!F >.]R$YN͝;wNhhKʕ>kJ֪U+[l3%0FMvv1 @G(XPT3gμ{kLzV۴i/}ѣGjL ܹs 1 []vtRCWfMYPw*_`*TPPPWDݺu޽{/ZwLU1 `ׯ_/ 6mrN֭[?{IJe*GqzGF1ydNw}3g .l-FdMddƍŋk.1 `ϥw-iҤ)˗:w;|p|h^zO?0aBLe=z UdȐaΜ9|&qㆴɓ'/MxzzJ 1 JDzxx.\hѢYfkO>-YO5+O=U]/Ϡ .ܿvݻw߾}Ç;t|_L8QjJ=**S>ꪒHԩS9=sL&M*Vhŭ0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 xŴibO*U̙K(QR%YvjPPкu~|p 8~<<<֭+WX={l۶mW^M.]2e{dɒY9Ҧd"""͛#GX>}ܹs2e*VXҥe±Ŷɭ (`/$SeIÇ1E]ۦMe̙3Ҭ^idc5CF4i])̙3f̘G]#rGL#m޲0{F;5,,lرϏTW)St-ZbV?bcTѮ]kת?:Rs:}tժU{Hղe~Mqܸq1I.W[;w4lP6[ʓK5d>W^SM:Un'Q^h޼yk׮,=z޽{E[YX`3gNlC]KVr-G;v,P vܩyf͚RJ/e~ǡ{왬)Zh``UH[dpp-[.]*1lٲݻ+2: >52C)Btm!F{amڴ_ԓ_~9qD?;#5:ujS믿' )R3f̹s~W^yxx4lPJW̙{xH"5k̘1cYIm޽[.k֬2Zjў:m6eyȑ)SPޒ.^O&M̋iK \z5s/_|,Y 3r;\rE"ҥKrRJI%O\% rʂ\qr޸qC%ц & RK+VOOO.eY>@۷7h A#cާOeYӧOW Alܸߏ>f֯_׮]PDǏk$塨\ˬYlJtF"Ut~P.]x;/ oW^@II9ovz) ȑC.QFɓ'O0!""B]YpiӦlR]3gΜ?\YpB=V,XpժU+WVל?~OǏW1l$5ݍWlٲիzbݻ-RT"}o5kdAヒkȞ={ԨQr륥]Ҭ۴˗KxÇ+V( 3g:tRn˗5O1;wny # SLu矲Pvmenͭ@g(`/,'N:\d)FE1HO<ΝSbÇ˗vZG}zje9VڜlDՠAl:1qI@eYo\ѣG Կٳgee|̇ݿ_+!(9[l>2)ٳGHwٳ%ym;uPy1,(Z2eJeYcǎI|IY lJDbL2=}&K1 M6]zU])СCWW_UZYtR2׬Y#sС}/200UEy߼LQWދ/~'e& PS"E ijժIH_n޼Y)Ru޽"E(y' y').ZH:Oz6Isߡrܹsnf &|ʩGP,wS Q*UԩSG:%˖-S;VQ6Y^s^sO<ɜ9sϨ^ǘyƑ{P5oذ۞(ŋ2EUǏMbtڴiʧ% ,s*~&Mϯ*2dȌ3"## *tYӷo߅ *g  3_o|}ѪUWb)SdQF۷o9ʩru7oޔ'ڮٸqc-eɩ5j(;ս6Is^pAKYΐ!r(H5}T޽N:^z)/_>2))>|XXPYhtXRvshX'w,wqVlr+ 1 -1*gzKZi/1z}]צM*uzJozC˙36)*7dɢ|!&f5E}*]WZvܩ~FRXmeSԗQ2#cjڵkҤI#zk]xLRyCqӦMrbVb3'W|ur%Fwء~)GQo{!gr#NDB.]d2%KԃR)rZhQJu}.L.~Jł wҧOoig;rrmXLG۶mnݺ{J*#Fj ڵ=3eOפI{еr |xڴic!C퀴|7oٳg͛6m.](;3:i$;7 v~[2k֬6vϞ=ː!X77лw}ٲe|:R:x޽}dsժUS?kq$-uwj>cƌ:'lu+1 1ڣG^YVn5?{z3'vڹs*$ό֫WO#F gihKwU`x^z׬YSuL%{P xC>}zFD y=zT}]tiϞ=ŋoܸ`1/۞(}?F'OwyGޕaÔ7e&_ҾMEQ>5*7BO>`/^>(?nb^/wȤ$_|?+6mZ A娨T8W\-[ݺur+VLK{GEβi&Sԗ?.]P/UsPK(Wy*Ŷ[+ 1 GW^-hfTR?> stream xWmoFί@/HDӣ."8؜mNIAvg'B{B`3 _.џm:|j[?M"zSLu:P ws~l$&de9 euܜqkZfUE1(y >!m$/:+M/UoT; vܡes*f1zAT!DŽ24 TUدz&lBmrW:?y@\uueۛ^0;,[b!>k%f?_6-,]^z_x)Ua*׷c:Z)&= c^ԿWpHğ?m)qL iğXU\&sOnN<&uOo*vTpvr-O,WGT;/CsE!)64ȠUGڑJŔ /GbIJ)+2ŒR(\ =uWEXDY2Y6t P%VE2$*M\0(c(òhW&;)Wqn<KM r9t0k y ӗjrwh bp`[!]4=ʆ,χ3 66dwvT]d $'_] ǡCaQ<046kDݸk2"PI0eޠY+|"P#$endstream endobj 139 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 142 >> stream xcd`ab`dd v 5400q$baa]H~= Pׁ? 7~H/(>GhXKdiVB~FM|w> /W [ 1 3 1 ] /Info 3 0 R /Root 2 0 R /Size 141 /ID [] >> stream xcb&F~0 $8JT 3WAfl@$Y "9΁E4An D2ʀ+eHiɴD*WHvAIjfWeIFL`2Ɍo$|&Il~. 2l78׼`b@ endstream endobj startxref 102388 %%EOF Matrix/inst/doc/Introduction.pdf0000644000176200001440000021321114547724215016427 0ustar liggesusers%PDF-1.5 % 1 0 obj << /Type /ObjStm /Length 4362 /Filter /FlateDecode /N 84 /First 699 >> stream x\isƲ~ݤn}r=IMő}+h HCR~;=HrR* fztY LfLeLgdfFeֺg!gBᅌKEƍ@".Wd\gB M&EEL*r?.g(8|V_OՇ$LלzY9́vu Z8[_3tay~,//cd 85ib -tԝX Qo:d)MlX} Ōy*ŻWJ˞k;v58)?Z6884.at<(̘hPW1=X_Teъz6imTUW'@.&^s~Ec !ee ʵhhˮEU6sy^3ڭ]}vme@@qdǻGNut>(6W۹L@+! q5g,k ^̮ >DMDLʲw~^g g)}ą5qRP >?='XK0O/5NAʤ.C[,A8/.(o/Ⲹ~.b\|*@'bRLY1s\_+'CmO@)``}4K"w7'G؃m9/A[+ NQ78x<+okRSHqnբ5@U j5VԐ}}w)0B 90^Ϛ^N@lQR%ZKKKb:m x@p){ū@ﷃuq>-Mq8c QHT)\ tHLUHˋW䤇>d5Z8)]ܬCU8wZ庿yn<Ǘ!U\\mL͂ O-qhÉȑ"5҅C'*P*`L{S)^>:|´z02){0ﻞAC4!=.aXEpx6 xVciaGu.vO e\{ VbW[oU jnn[shsĺ֋Xpf;D -m%;b=_h.'ls}'.smp/4n^N⏪K.t __ۢ2}l%__Dh? aS5iO`.cFAUC uА9NeU=WH,i`Nn~(>@? Ϋ2\ [tsP=ūx}#үw/CCnƣ 娙-f7+ h.6XNëy[E(S g903-?K1!9:vҙ3=Q,\qүVcLqvL޽E4 l׏WtNsfke%]C!=$SމVEeW_ދ5u_ܤjv%Rp,~q^w3-[^㑮f|vKY>da-,Ƶ 'f]ә 177*'4_1B xXpO2t-;'1[ag18j'Yx`x3#'O>Mƴ*O~ %ǓrRuv 7/ 78=B>s5-N++<@[ G7>.f F}Fs|BW:r p/r,Psh9-%]U3^nW#Yh3i#|pJ[D8% m=Sʚt\:w,GΌjQ7J]:&X|rN^MԙTEints錇7HL^?!$W=􈇭յxE )ZVd~7TגB_}-2Y e.x45M%lђcu40AqrQwYcULA#1t،'y{7IXh LJY05ja G:+##KcOB7[2~`13QŦb+cO@5Z7rR\4*Nsq861זGw깞KTN%4[[\:y-]q) ni@0ֺtsBM:e(RqM"@JڲZ\+7KW[Vw`ǘ\h 8wJfiKaQ t98"85c` 1+d:7êJ:oLKI:$|Qa\:%d.H,4i{Iνbz0(e@c4sO; ZVJGC'8[K'r&--dl+2 6sP%Sd:|ӌ&C2V-n`-<}HSlĄ>:*hswVa[inw,sJ̻($\cn//hFF*Ʋ>kh񎝕X\KN-^^ZhD݅"Z#m&~oa=U$m;KJ !0hY(yge!ƲxtxW:afr `c '@i>>HBU)?B8%kPt3m#B ?TN^78s'u X{J?E`6|mÄ 36,IEc {E pt;L3IGQ>' Q- aE Ӧ>t{}Faike%MDXtG g޼J|Oϲɯ\= φ%7|Qg̚3}H^uFRW;hjq9qzߨG)B_\Bߦ4su endstream endobj 86 0 obj << /Subtype /XML /Type /Metadata /Length 1388 >> stream GPL Ghostscript 10.02.1 2024-01-11T09:36:28+01:00 2024-01-11T09:36:28+01:00 LaTeX with hyperref endstream endobj 87 0 obj << /Filter /FlateDecode /Length 3222 >> stream x}YKs\rrpqe3cg[ɛDB"l dק3`W0DOO*eQ_}XUJүE}(Ygi YJZSܭx,Jl-uկ~lSbrek-vԭ+X('k+,8ѯ7Z겪`1>k-}^8X;g)8US3ޮBV, /IX G ++o~\I%KLAffn]{*hoxB匪O.l##Zqu W*+G76uU#60h< Рf4-nv\P:-9Z|sloǵJY 7SN$vd\2js|dAAoI7'ZLcG&_7;mY4'y-N/[5xURז cÖֲm9HʫNJ5WU!72eEӫqA*HfexmJ) ދp*r^9/ xB-1Тq!P6@XWR.[6Z .0NԍSm0p:O]ӠbTcggg Ħ!MJ7\ Ңi}|6B-?Lf߀)=\t  Wqhssi^bO) L|:V8L.)0v`$ѣD) z8jkٝрzcɶJ]35q|'$bb 3@#hzW F%-0c[#PFtb  u<ɯƈo5<X̋o!p)F)!\F@G׍F=Wss'pP~~CGBZ=v;fj%ǫF캡Ьv4'3; QȿCd7M)^EmJE? u dVBzmp$*P߬nUkɩ c~XZQMKPh *?oP3dӛl)/T˙^D:7yeg'{ҳ̌$H4_ufی [d>f߾2rN\9?5-K0U4~ѹ`Vn 1 ¼a N!,vy3ah7($ >#fDơrJ-:#Zb'E~ی6S~~+MK dvc$"0cd ,VA<AlHw ǡ+,a%2yeOޅ QX,i0,ߠ>Z"X}(C .<."JZ*D5PWBKuz;I؛U28$d[_XbYwsR/}=W*|s} w)9\hk/oڣ!<_a9NTcUWlEngYrѺ "DFV!ԥ;(e42|T{ y/}Ӿ `,itp لW1*H%蒐 bS*9a@yDa`Sz8kQQ]OX&#Ӟ2:w=;~HÅ u\N76J$07 E)bۤ*lt ZM.;ZDf2KM b &fUTP$EV_k)p@.d5+4Dk\{@]e?*;h]%lz?p0 ʵ>Ĉ 8|DCBYHYJ#m>"+.α}߽(0X}qO@nflD#2*fT2{ZQ3*UK8b1!ͨL)wPlJe<&ڋ B]vz/y! @ld3Ɋ0P1EYx+-1%D<RX(c,oNq]QH=4j֥tuDżbK킌n%48]|I>Z) ::ZYmM(Xz= MKf%]j} b6+*>. ^ S:].S9s` SPJne{kP ǁzϹߵyX]H``%B#E#㩕GXP*j<{DN|{mAĠ8N!4TyX8WaMNɪL9.6t<y̷yh|!IMh !A)1p'&@㨕c6/DWvxV:^K>ɤMhzi*ϧi&~Ʃ)N@5H(,n32Cg tA 3i' q^KЄ^!U>CD1e2RX˒hqDTdfzv#Jů-1eB!< MI'!'T QE񴪊Wt¬ԥJauσ.^vƔ )uM Cw}DzSJ qgJbb^3w#%7R}ZՖ@՗_ "f@RBxGS\oBV'&D@V%%`ut8н >Af}&7!?4|Jz~54&Ai_lhP8*gX>CbݢgS5h\BLx"9mH6o v5uP??c ʈОͶM4`ձo4.pJrH/vdendstream endobj 88 0 obj << /Filter /FlateDecode /Length 3064 >> stream xZKoȁ%ybP9JHJҪr^pͯO?f KUwЗEE¿Ur%"-~;.$w-n>_ Z' gDi]}qTY*J2IS/.Fۦ+1m5,kIe^5S#R{ZmQa%Si':8q+TeXε8re-Z+~-xoӎ D7/G"V畔In\ܼ(JP5In4/3)\TV%xU˄)Y# Mq(Xދ{< rZERTSjqJT Pm}2Pps@yQe[ƻ㙮|X*I@@zE庢%:d]2<}[^ ~`viFf+J;E֥hвl"|]usJML΃?.=E[pv״5- "9.h$չh}>jI( /`'@{:~Jv渎Tn:Òco ~ny~[qT1mc@FR֊+MјH w(ھ YP*2&p]I$r`./2`FQ/^܀QMn]/hkjP\ࠒl&j<ŠO1%Aj6pdF&' +:IrLЬԂ)W!$+r@fS\z )v^SR~;W0%r o'qN0(x讷M6Qo;k7m,6h|a>{ђ]%}!:OPYεnD1Wj(:dxu}/u_luH/7a )GK]u}ܔCX2ZwK6}0vF2MӁHqBN?GHDgGoF!1M')mL QkJ2 3`%%dZMUB>w&;@pUY"fMJ`W0duHKTKU|G;(O> AHT-%VȑS r$-E\A!z we\(SJ ߍ@nhh5Y_w##Хښ!Ŷ`|vq6qɎ˖#`=UTeUMRCK-хV\0Ji8QiSD }Og_We9x*M<([F>3g1Rd <-~ϘB94g:Wc:Ҋ&nb MA7.2%,n@ *bķPyDi,D ,$(F lMGe)D,&tCK"hs\UCx ܇|;e\BZ ʸI1063Id$2ԧB 67,UeiA }؝CPS:B< SIou$ 1+ܨcOɢFo˞37x]ŁI(/0CEϋOȔZWĊ\26SÞ , Ӆ.%4;ѓQ ɍ[xwrOb^&F[;baC7PVu4%oq#^ uD L3q=&L`*Jl㧺Pͪ=db ˳>V-'+;cL<1csDAl[NͧC)&RvH (`Z@43u*8p(eĔDVW=s&tJ&0n0G* O|!v"@gg*Tw OqzxvM*7{b·b3pWfcL&nk]|$(w]iq]$/SC\3LK_?`0!-UBY8zkpƜD]%WYj zw?-GZ{h<$oTӉ.Od;,L&=M}_Y_վ8ir7Ӄ 6=qH :>׹h100Otv>P:s)ﻶ9"La tD wjgM:=mf'&TmDf8tJL?ټl~;'|\-- 儛 <TqL-\s1+Oܝvr裰}P - YyQ^e0NIfHi4m U |ʝ  90ҸfB?n~?GGendstream endobj 89 0 obj << /Filter /FlateDecode /Length 3249 >> stream xYKs7ڋ1<^U;.V9PJCIO?>F#]:hH t믛]Iv__߮2z{ovW)O}4׻+^]g%6FDzw$~yFZlIQOx]Q]_Qu4D7ΗUP/֥NC2QMyj;,l9WCaUy((~o6S0Me,Kn ߈ƛ LW),jCՒT{8I"`[3F}AxӰ}>O$l/}h \mфNvՠ^|1ljRn*(>ˆrtkCf ?u3iĩj*LLlSAa}f.v zfDk1J^C|Ӡړ?\;OnmUفOlDicus-ظ4e>hJPN`J$c͋Z?Gޤ qS3f֡=Y/ א (Jx'pU^8,-3`hKTBǎӳU5z@5`K`HB,K`d R[7)ZC*!db <CH{xyÑY#(AIe-@F5"UmV^7҉e,ӑ -:(露5v1i'J*XvD$1^AAW4ݠ%w+T4I~;+ ڡ>WGօ_Q0Jw HiG7GPFGRSU,GY z >zX/bA}ώ1x)8e|H/bb,#i}7a#M`ʐŠvĨ!xe !Wat4g2vќ|%[ Ѧ@:m=W- )(M/Tq$SCN ~Q}c{~q ikͮQJQ`} oPp9UC;!e+f"v: ƏK{g%Fi[`&f]rcm}rl^@_LaH؂PY%,'_YZᘓ $pZX] \8e@u*YʤrJi^t&<Z/%og(.n:8 w\:c$@|&ʈ#M>6No".lvJYTyL.牯`~D;mofjc\q䭅Kv̛ 9] vf/סj ; /<H!L8E9ִE @~r{AϜ.1t1',8kHe< }u&^R&&Z0WS/BlBz&2ݜ PGĚ PBaO a3lt ONxSP;tD3bL3" "a4ĂSv1wmaE[Q-)xCU=~ cVEͼL痮N·~At'_H4y;&^$" 8rۏ,X]5ȹ(_M?r=&-mk-E 4kr(i.BeЙBx . 50e5EYqg !9hՓ뚆LD j*gIwgmG ISosĆ﫶-|ׄsg`]mcAUs Gy [-)\_~~V61·!hú/ #EOͭv4m< i]a^@-́?c|ͦuHmp/:Iiy(NkvJstJ%"FchH 1t=TtNqaiΩPOdleS秳/]C5Ƹ0aiQU!֍,+@vjY-zc1vzB'5e:bѠ[eӏ{@S699l2y6:BGᔺtE{O_-!FBb}׌Rd P2^hD |t2In,`C{IvRK5%##H΅7> stream xV{PSg?1p7Xs޵Qֵյj*["*%$ׄKhm--Zꮶu.:ݾ~oo6Lr{y$TJ"$OMya+b_!1i(Q|H>=L^)KJחWlܣݻ/%;'7/_QHQ-V*zJ2mԫvj-zz@m6QԣC#Q PE-I9[ER:G/N1(_W~P\ӼU[bbbÏPFy!T#~ݴ`IgTxeu},NE~w9y+#ڀYĘbϫhUi;,4 zh+zcWM|2F4˸)VE7DkDKW#s'2"ɑ#??4t  _ۓs3ˊ%u<ͨ IUb}7  zL&@ތ0ĩd 1tIy]?.C qM C֧Ӣ7Qb7w- Vmm$ofr&/L?G/Y1djJow Xw3%(*ux @F[ԇH>僧ͨU6U;a9>,ؼ354Hnc>/HIj* < gFVvUl!g+F9AJ/+Џf-Be 7*z&;ݬsV^õ7,?F7 `]KI>}ӓr;Yy/WȈLkz0~vR,=>? Nͤ/7XeWIcU·PYKZ"i|gn.[SQ^i~ochyAxMv2:G, PчOE҉2J*li, T .)Smڛtf3w18KeL Z6.`i55PqwYM'-9V Tg:QBtD swAWA*kY 59`Dާ7'+N=&MyIƎ^ >όjО AQw#I69PC!&t*IeR:c 3}ٓ$cqX#|/oAr'"2z+gӧ^2r6q:3"֏}O̍{r;o+5V}GGk k O^yuum5Hor0oNC6 >GW 93l#Iw-YlGP{ 1!Ao);GY>z&ѕޑpX;* }QrQݶ1y~VngN.rf3FV ta#/Y{a:1کf΋--ծR0n9'gc7da9Ѧ:#-zYtɧbc bH>´ Bp:jAA{jҲ&QG4#ww;/^ pjYY[9Ôvo²;Nkerry=GB -6Wm8n:YD:"p^f!#44F2|UMZ]8Y.X5n o^z-ye^`wWgN0_ӣֿE)?}ʾ?p㣏IKذqK訕iWJgqٕbҩav 8v[.G.{b3DJޭ:86C>h&Dcџ26V<ʰ谼,\.W ZT pkG Uu1)s.ĭM=Y%eu=Z< @ Ҩ h;^S}52*k5rlG=.qx$!6ΖcGNzĞhi0)YliyyJ `V?>S!l\ ^ :=ȋ`[G7i\F[g\7pv糸DLK/KhB8zzNށțsrmݜ䝈#ցNI@3ޣawچk--+0(uL!f&(~\WԭNV U٨~I^cpSrqJLE"b^4xn 0t ʌ%Sd,ޱHvI"y\~.N@İ3x^\+b^WdbjNNNwh2#TȌL׺%Sҏ>yMoO^W#yw겊RuBubڅ(6IߣouUYUmpFdcc/LK!OZڧ8@҇T6+ۗ'&Pb\endstream endobj 91 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3359 >> stream xW{TSW?1h+Y9uZZ[_]Z[+Z7ZD $wB B@By>P*:k-zsXs@g?]wY6x/l[q F~D0:76F~m4=a4'9;U/ASђUksd%Ĥg5oEs b3 xJ$kDAND5:b1D $",DWA ۼcV?ӎ]2#/.2*~|G㧌׌^?aıl&&6CQ>&īPH\C-l3?CqF0K4^O=zt|ՐąT 3頱fgƜ 5FEm{2h>|<("0Տ/[?R9HB4Ym&0db .=gExlk#&eE^(Gn!U,p"a[\wTf dʼnssmQs"RJDV(G O޳~uΦ/`-ڼ ^_?poo78 8#4"wxK A[W ~TU9we{܎+(#pU̔Ql~5 m17-:seztY]pZg:o#<_uX-G{؟ql,EB7'jo2Ev#a֘3 T8HZic^ 15^]| 83EWcӑ§fh&ȬOp~o,;Ϧ fd OQ3ҼA%gh$.GܽىK{uvryAeCACB&,,.u?W!jӛz"U[YZVI9HKJ )G)MGuX-rsZ˽Jׂ=+\1Cyݛn(n<,*'?w ޺ذqa{[rNtNL O???.H.>Jr#,Fb-%T"Ju,6礦B,,Gww)Ky OOdgr eO"\M6zowJYѲݻWYlN#DzCü^~Hds%n"gY$LӂR80=$ş-xgXwl yM`w>Qƌ&*r!)kCxW|**I 7f: 'Kv<9:%Zņdٰdb&1E ;N>kB;;Vqt ɶ$&Z,&ed%vk1ge6OMݑϡ uΖs*] Mqh?.V)bcl^GFv^M pLuV&{h.-6s+3NKtz8.ukmnlJVZgKٟI[y&qIpA~2)ɔT1Pu#]TT>;:7ZSkrTx~'oB9wB>3}3nXEZ&ϑK)9Y&S̘B/+w'g|e/GΒ:uAF"Cъ8& D /a5RnW}iUTRUj}֯8:GڒHVUz^7.56 a_zkT=R»= SK[%mYW}W+| +wxd^[iXPBV ZY)w|BTJgTXָq|ϊo*endstream endobj 92 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1844 >> stream x{PTrnd{kc'v|`VTP1(D ,vYv>Xvae]D pjT0%mdLtT'14eqڮѿGϙ9g;?1-d7_pLJW![L3p4k?x- 㑺whGqIy"nc Z w쏞]-oy٦OgGP2e )nEf=j`%uM);ZN o gݫtA!AC|dld;vvB.NOa8?X\Km4.m л=rA]eR"X}.gg>庄424w -|֤A;\KfL9r-xjxPEZ˧gm(-AgWMpz7,n:~OeB# |6WKͱ/7n>t`b :a hm]Э<*5Q~CRD.C9=,̶ ‘`0&ËL>귵."G0L Dk$Z֤DCC̣ʺbJ] j=T@ޮ'6rt~6:@<:sjXG[[gUVm7{x)8= j^ij*>>Ku%ksIxDJp=UoI7[p~Kn6>-$jiCdc 6K-4D[ hm =|$cf: OEQr@L 6U+>=V,cM)Rooendstream endobj 93 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1041 >> stream x}LSgW !$.!ư87Ȩ`P@ʀ^ʥoˇmiPvvYC3زeq8 Nrߓ<IH$V_+=}cI]k81zq^`w\K@C]XZE(Q:ltQ"GкȦAuq !%)֋ W :5P&;`!=#-546'7`Ho@^(4 bZ6Z{Ln>ܘhWq:lFS`DSRY]iڀ<{RDI/"y q:p}D2[@ʘ ]JыN/Ծ^yC $t![8ji5k/=qEiwWO<ɦP C{يޥ {>ҌN3U|,IWc n8kc[& uTCVЊv576%,kc'+/0U)y%%(2y*ђ_y#ue W0uPQ)Y#b HjjRDCj@> Uxb*ٮ91uNkik|<}c1f@goG;}6qmsTDS OR`&{]z'}SV^7(9_?3{nrc9 rlE:^0C}97l]vƁ,1N/^10Ie`-[ ;.Lz:dxatI NZďF[{ iOO17 N˕V5Ԗ*0E|V'a!Ƚ5S-bPL=d v~_`X#)LN}6QsywO8syg;@$,?? !F5FYCCIIS|l?'Nu{#̊Fendstream endobj 94 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 5305 >> stream xX \TU#r#uokYk[kYߊafxσyy2a" PH-ڭt< T[]>gΝs}GEx1m;?q_/CюG#HX$MLB&W]&k_Tvu $mJޜȨ#ga)W:j:5D=EmPOS[hjb%l*zCmR˨rYjZE=O~GQQZJ@R$8j9<('o F]r|kFOo51`̙/-츦COxw➉W'|hC'ϙ|+lg)9SNL9U68;|{V 5Qyŏb ^[@BQ),JʾՐA l*NsL&u3Lc/2(-TuKЖhhK'6rյ( k[|Mb3(KƢh,:Q/}@Y}jyyok(Z8=D ~7t6!Arg}Hb 0{S1Q,VD)ͥv,̤El676JKba\'`:Sb\Gah~k0%R f]<I4g$$g?\ οa.%Rl#wn@ M ߹ʨh/\6(hDI9xI U A@=c1 \̿ ޯ}߄H?580ߔY BC't1Revz HV{}a[ATfq@RKp|:Mb%xXgÎC~S6JaǟL=zR3ss_1֬#Go{W ;|).S,%IbA3ra.ɮVy<n۔;R,㟡X_ Co4d]2UdDA1@&FX!m;M3kܦݵJiʂYvâ MuD3>Zd (J 6Oo&hIRvCsÙ1ؚn\Y1箖u?-KXtX-MK@%kZH^nBY3Dcq=ҭ̒u򭬚^lw: +r!2h8, urnw6-J(J5Mk 翇"ؙnJ S+s2.ҏL#|oVBš 4+d6=n<",P ݬ @Oa/x)A2,: ¡# :4̠.x$ UP U `ETy[u'[-"Lw?rT,U(HX-ƝU}0XoU! {k7,'`Qn+G";f*a=\.?4|iQi,.n@bufOE+$dQ:MnuDA;ih#kL?۹ $ȖH(Ƶm%ETW鷕;ˋ* ]̵$"/KbST ¢RTQgae!h0` LWPdkQ'ύ:!XE-,B_W@-cPS *fmGf'?\a {%Q-u}_ BFoWq̚jES,0_3.N8楯 7θOz1@/L6Բ(|lo椿*RQ`,ƠD`&X~[@%^KD] |$ѽ `lju{Dgt$8I JY*qFۆ7|b]X鞓N;vKC8I9y* ֨j ^FLBR) zZ?=Y?0ϫQ7`NTԤw슰ZTaN֎;׾!8A[6]1,uUuz6j` >&Y bORobѦ!}ch21]Y 7e+22DKƷ*:LEf+,e52dW !F&"67;bN;ߡ 5u={8.&a~(1-e,qތ7RIg "c<85-9m~h~T}!wVF "։2 iY^c-5A'+ARNX.KlhZ[Ѻ "W] tra{sSӔRE챔?A]kf}nUwmA A)xH!}cƆOnGicxoӅ:Sb_Xr]BX K iS<8ϻ(fQGlvǰ#Z? EMT? 7sx?H>&|CӧIC u]^β" E( |XWG:5ZuZ.k~QWKZx(h绅 B@t.h?'FaMgCg_ @P%A1L.KhڙK 2OgӮ|hdIVY3laJ>2cdc dًƅ42"Z՝q\|}}}I+'+ڤ54kFY\e_:q/QEՐ)HWNU;-KY}?el#yuq39l1,˃U8Y{es0xOICF!jZ3o i]1[t˳$0F_Wkra t ?L" LÏ$tUmfY^RV^Q{dg[]ʃJ&'S˒ Q,aCژ[_WFBjm}O'h)Vq6`%dȲo ^NT2!Ro&s>"[d"?QE504;m#ҫgK9 s< H p;7\LZ&cG8#s h2SH~<ZIV7KHvup>fBzKUpMtȃ=DdNXDN~ $@ sr~`OJ> J EB dfF0)E-4N VU 116XCo.aʎLTHZGȁÌUCDƁ0Y+GG5=((A1^#n:F4ٟ }z {p~=W,[=WB?"^6{@^ΡQ2buWa݋W[a2j vDGl4s4X<Κo~˥&y&0_᭻aݺƊ5p|NC:Km1I2ug5VM\bRdt6Xe&cC Ǐ\,endstream endobj 95 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 247 >> stream xcd`ab`dd v 640q$~L2{!{@1}ư&LV7ʮxzȃ0.-^r74nlܲq _L_:qEwNI]tp{k2wMj2oA?͓$mrޢnnTʎn[nJn}Z(dsM8丘p20dendstream endobj 96 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2197 >> stream x]Uyp_Yv8vv0thG.aJiL8e[+XӅVnB"C PH  %e:Mz% 'fI\e;3;~ Sd [[g]*FIyٻ[`*VaVl { [-Ė`-2 `c&m&kݩRs[3C`NmDkjnb~{+|Ev2[]ǘNDpQ~CAT+_%8g# NQOGR^0[$k^?c7.8{-Į z<~{e'N(Ķ8c1q3OPGiKWWOlPm5( mHOkGЄcGZLi|Q>t|!j%`79Awoedwu d1HTE[\I5 K& 7Y˜MZ]ܘwWʂ7IBpx`5[*QdȖ%k7lۂ:\KRE* d =baGdJݹkS#WqaOm)BgbGhK({UNܘV#͕joRk8gX2xdT-Z]f["SCb?䎷3۴4yihz|Th!0A4=%'Ps`WTA֓_Wk>[淥5Z{vcr}8 ?}\F~?+ Ch0 hRȘ*t:<=MdѨ]Sġ)hhl䒑`INI%͒&-p(IFf4)f 1 d}ټѢ UH1s%ul dtNfi)i8fHÉC4V3و q 2tDQ18OM\,@aBЅty`-?.qpw{r^Hd@2ҽx;mA(=ytU]]g)h?d>ī,~Ӊ_-ŖԒ9U þáR :}&q DQF=*TU'$i KaoOtffeB+`w5  XIIZs}ΡP]EVmMD(Ec[#>+>dcPr'ѡH(cw&N w@j`5mpa{N:9<Om y:SAJ=f5E|\[jɸ=GWFq ("6ؘ{3@>0}b[uߣrR3m@  VdVv -dD' kn\4-Qv?APⴻV4G50!Worry\MD9Rݷ؀+V1lm@6NZX m@CաJK\s;5 {--h T'nQh\S7_\3Gl'Z]fm"\&(8> u@_!e0zGI)"wyXUphZWQ! ' ĠR pp̓.9> stream xmU{Tg7EeHXԶk}Q[jyY| (!<BxBXRڢe]JRٺg-q'j=gOwΜ{/DD"א@oygV!ΆtiGgE9iJ_Z"#3(V-)yk+)j L-R!T(FmS?@R먕zjrʃzV"T*u_NNJRN/ eװEn` z!yP]Q;FLPݠ̭'p~cY6+vY.()x7e%PBU7԰}A@H` K C9`Y=(%}Kƻg MYt>?Qo8[|m>2UP0'm !Pb-Bʡ@1BK.5D|8q\K Usp̀\pgx]dM,D1n/U0s8,#bɡqlqTNS㼓 ad#Ok~\"С߁>X=ľLj6@{qIo>(9t8k9~gejL ,Ɠ{,^Tj)limh)hP0.!vDn`bwOLW= ;P%:D}tU>dѩ)l4{hrV/1<&my-ljhZWK+>" W޻.7kg6sOa-X-@?8vJZ:$t RYjwS/ }pCU@,CA|ٔQz68VVh54_L@RMZ\dj$@E*jXQ ㄫ0QR]1.L)^W"}_' M @Z5dGܲ*]%T"}DfqQ-JkE?&g5udZ: '+d*]فBgOMǿTTE;{[3,-LQ+iJ wwUhQڰׂ6@gЊy2yݎUOL{ {QDt%iOS-osVOjˌyzC :ҲHs1ט[Yh9hFSO7S9Qֹ1M{!Z&SDu{\ޏ98̝~@j5@3r@6ڗbܱbX.O۴ONC[ti^iZPJ%)UPXm ],G}}jwgEyY>RAqd?.t3%xW 0詏d6~*AȞC%5y UEXb> stream xzxW!@ Veg IH 11lݒ\d~՛.YrTSB'z& HHH6^le{y{s#݈.{}ȑ& h;QW$9p9>ܿ3f9Ys)/^ ea^B\E-پtDz+RV W~cq'b`n~Tu{IԔw *ף⩘=u^zm}zwLegxFGDG+{6/ҿ)-֟π|xf 2A5<g >K_r!#5֋;^l{iK#"n:?}s0Px$/[M&_  %d0+l*B'<i=jJVBidȶȋE2mI<_Y>);i@bd9&-CŋM| FQP7a!1zI?A^~k4in"b  4cId"m O+}PGD(޽*mpkF1F)1޲C@HHnȰp,&p _'wt% *5Hr<+A.mmں J+ih]Zw&;5.ভ#D^ICC' r'ln^Uh&hGX؀\VfM/WC >DOaUh.8<,tRN[!]7Yc`V@xhu`ZTC*ڞOcr8fٶΨrJ}^X6{v"ːuH%7ji8>-}ʑ3߷:5}l07;7`6}@jzuuyǻ,̕咹@CFwB2Zn3
f-˸ (|eYYV,Pg;}| J_^ |Pgu.4z۪P&l.=o(3G}gC 'Ȧ)ꭺ?z+|82ґPDPb¼%%"K R-`BX$6g,ZY ˳+囖s sl E7U Ut5EA#.֎ru!R Mr@d1cUB76+0%ժ prJ t}Ey%VT_96W`!xn; A)kRmYhK5Ɗb9d>1vr"u66oB\i ][w%9Wni ߔ%Moü`1p6&mlqaHQB_ hEi'2Fɍk5,EuVD[RPZdͤ f5er#No{xiel\nҼ^.i{JY\ 3#p.PfaM6|#ObkLZj}4~c/}Y>̘VS9Zv'RcicBh'Rs)76#N:y'?$ST;OWxod-pH1{ma)V* h(RʉWx i.pE`$kYp@0~ğˆ(ɖҴ@¡6@T<ۚE+ES,S]= L`G=f |4t?aá$jse 1TN%$31ewphL]yXL5nfJjOm'YpmP1;X|tR=흪FG*(hfayZC[Y8="h ITKSeEI2Χf$N<9l}DRo;AdcXtGTb6Y*59TaRp3lo@+lGM!Z/(MUFI] >h<p#2mNƦN6Ǡҩ\T)TUwm=dqE"\H}NMxժ>dqslj+~6 ܆a(ko߽wbƂM%3\f?eV]w1`UϮ[378as)ŗ}M+W;8B{aDA6M^ zp|9LrTWhM)̂MR|JN 9/.~4h R_EcWISh6_)ר땵 =5@"2 jZ8Z{fu /v?ïVӛq# MَbX548 .6bKja4Mͬx*CE]ITg"GppkKԕ9e LB/R` \0kèV=Ju%;1JJYn%%EҒҒ"o[.*.{`N[n&*']("E H%Lb/-{WVU92u2M ̭}eUc1(1޵sXP8U]CA>,mͦE\l\lXED> ^h>өt`:l]Y~gV7}4BY2g"EPʇ{IeC"PG'|V)kՀv7Vک8&+LƵi6ϨM8hޡ~~ޯ>b7*ŏ c|Iu.SdӖY4;eAؒ%p<ĢpZNg @IQRAK4.npX{R \ M@BpXi :0r$Ĉ"IiTnT c{n]2|!P'w]>)6j]LNr`MEe-#~y65ÿ>_i3…ߜ;Zk/zhއfiY:ujC-VXSq`5l ԤMKUͦ*Ahz%uEMcx(`*ZڸRBNj,.c{=Lf5FN}%rm޽\'#ʚvVJ]+,-+*.w$2Aכ0jڥҼřǮKdmzK3eM- R"qE?:!:s0n+J|Q'}n^E=qJfVQ Vc@?^SDp}uo1+sޗ~uQ.SF] D vgG( D)(GhLsAb$ACW͗v|VS6oη,t(ƁpخR 77N .q. "5rfꛎ׮l=z,,9IaPv&^lVBײ,O931Cdwkam!mo=ί[so D|bt ݐ.Ωxj^p}.Ǝ}QYWg03s]moME,d|2|gnhp7/vH5,jvi㭦$Tf A מe2UgBYth2 节81.xB$mq;^=׵OjbUO3jL//2V!fTK25EDܲw]:d={7b֯ud Rkg{㐒0&crNʣFAƢqx|.vzll ?vOt.w47;R ϜVf3z2'W\ `rjџ wrè dD~nvz=rzdmHބvJׇ[m{̾&ӆ$l7 =L9 ÍkBdr,. > L $;T.y">IyP Y-Y;3[6(sNA.R%>Ea E;0`bfh.BoauzNQ#A% RW RHfCf-=qY(ZM.~arcIF;^t٘ҲmVc,SUTeEr[ zz$rv-n܁a/rk0*-WBavHzQ#KH Jǡ,l|4Upcނdv8֑3 t^^"o!d9",ݙu#}ȇ#-BjPCWHpb?6rxlf{癏Ko(4p4x8z54X'vXk-]󾀆0z6<0c>qlv۵!`/ȝq~}]NefFNn MۏsqZ 6Hj* jMty \j8tp8pfLvM 0O`Hn**FgYufH7:ݢTVۙmC40O?vjb:ϐQ{$c& }Ag7 Wvf$0\Iffb4iZ^EGB{K fC] B[aF1yԛZod|5yok1O;&Q&j>!n!j'S+D1A=]h3|g_eqEqŗP pyvܛQ@a0X8 O<ѧ:zۢzHpoffΞ& O  y>՞xrF+w)2 :ǽ;|kq?({`3l#'O,v[ڐS.۝Z07}ͤYS~G ܏.G*D|d&ZF08L,Ԑ(4TY h̤2'%c3ItZIoЦu6qVkPg7W.op7ItjZ34A8= &]ƬT$j,N:=p^ipTq1NmvuOOO5( FVS)WTW 38.K * caʴPm?Zk$u) j/7pw̽Mwtzë*Gh`^ҍk_@Z{q 3*ԤڒRͮ u-#wNgHlW>PU@iXb&^@kIMk^vwap쑝[^H, B"033Ku<\>kT4 Z _BO h+| O Nha_pS4^Cgb LFikI1DFf?yUW+ȭ4 1ɸzi42%V3:"KF#p*.E] L2'TnQv(Lϴ.Ct+&%PHDqp)=˶ SzU? hxgOFRVЙ슜*iuPWgL=eF)6@3]!s s!+ad6߅$+'f]mɷ[t9QbaࣤH1y<'K_0HJ%УlF36n:B# 8Cw [^v6,0W- jDxRMDC3h> taѣZ\Mp\}߄IlpnlbUufI.7UtࣕzCk.q~Fc#>t2^{z_*!*;;ie0~]]Q9a '!a.>Sj7=\ŗu0T= Udn苓&|?8lUP[[̀;õ4@'oRnSQV0V7Fn> stream xa SFSS1000va  RS34rM@vKJ%Au[ы'}}}#ԋ뇰2R`aUxf~dd+kv8rqrypN7?o󊒊ͱǏ{iy\XV+V%.EsuFOYGEGS ? Qendstream endobj 100 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4483 >> stream xX tUsLC8UlȈ :#`@pP$$$!IwUkUw'݁ Q!EqFgQttm8 ;o{7$'UujQQQ1n…?vY(*8JQV\q-ӛ[6+U_/Pj74nhrm?sS|b4QG,$% Yb&+QN1b1CxK`,/x7 ~_z4u&б˹z3z"@p.55J>nƹyυ^{"z%nH!_#-S7gWN_2H^+#, ;_~nv3'_qԍ[p8nBn#׆~ $#[W<t":Z5IuZy7WgJ4n߮mX9& :{ݳo͝'2=9m[gw Xs_.,*TpAԆUl#sh+#_ߗ zhTk" K|~=_'>Ү)$"^Cе 9\M'COWYаtDhy#oP0N"v@1زˌ|/yg[샻NAt`?gWR@nJ6Eq,F;>$rgwM{k d1\Sƛj:jv mNLFJ1H=tJ c4@@1\o/TڍFO`|$G8` ulU{*QX痩[w3Ȁ'SYO/nlAkm1 K>B"aKl]1l Ýy=H'ٴ.$K9Fբ\]=4*_AdƞjfÀ0S⊣ .,_{dHB~ z*t 6ǀX;\Zȳ^.iAcJ-齿wj߃֐R~IW4#/?rb)ɤu%CZh1h3p\S1Yl5ɏԄrֽwC_xxބ+I|>?/, z>HoɳL[GWDfoR]fhqUr8Vvt=ȅ"R/JZv \/7GqcrP0l:nRA3T+#m ?yUdK ϔNC]gZvk |p)",jŨjZT-je4Af-mO_z9t2TƓ>Lؓ K_y8$t.aD_CήzI#E(R|YT-ްWИyED7?K]$2@RlFg16zV;5a*xg?Z&>G-!eFjSsN{q.xхoW"-T= lx]"^-ZB1_OBc!ݯgD")2jQ4fk\_sg(aƎ$ܱ;gB\<6 rR\N9q!Fa!JџV |>w22Cۼkҷ2OewQ<; 9C޼ ܙ7>[snŔ+Du(A)R>k<#/tC=?) ַ7 k;5p]5^rS8wx^//:˗>8RϪl{.+vO˂_L_~R+`Ȋ# YKN '1A] oru='0Oܨwె슍Z%TQTlO?ͪ751W,nWjwO. u.-pqv LmJN<㣮W1>#uSũw~mWb0K-iFVw`2U@IoVG8%; {'.ɔ%˻i@+ŀ3PF,=jF7$vٰ~HTyXǞ) AZVKf,B$]yvV+No1w&U(1yL}̒eUo `Jb7 y*Ъ9#uMɎ("(6>bp`@*u|ЇA< EUٞ|22gAbrh2 N$|n@Xyɕ MԍG&Nھé+_hkR3tb-6h+zPɃSal琥,À8Aoγw!1D1l+qǙ}R]&f hM^&1kFYFɑf Ԋ /抇 4̅8b\'(V'M0P ҝuu{t[_8@,vF~Ѓ*oVIΧ,%.Id|/_f~fNOoWp`+-7'7zBB+a9v1j|6"bܘ+6!0ɮ.gW-=  :T3"jQCG d߆}ePB@1Srӎ_dNaj_`#ūv>̇%g땖z:1Lte)?&L\ՌGUl3s_vd/uUqxDZtA$mH6IFC7ZMԔC6ol5k u5Z56*caduNVi2A2I&Nm]p[Я"ֈo^騔HZo'ZC7|'$h&AF4 4Mϡd#& *LNsX'K\L0ˡp~ϣq(*6Pkw0[Զx霁[vXn\wdYפoLzxMTd gΏFAGCQLBm˔َ> stream x SFRM0600f   asteriskmath*bvBwadb~}{x~x{m|}{Rr oe{x`_`}wsoqcueefĤ ~x{}~bqdoasz{sw}`_` ? xendstream endobj 102 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4215 >> stream xW xSe־$z":**e)Z)-6k4I$m'_&m$]5M.,PeDtיg_dđ/:<ߤyҧ;|=!N!bbbm]%i KDod;8#ΘZq=+гs:9<(˗) 3g8M yd}\ AAl"6 6"N$?с2xn@rz#sqѪ Zg+zʫitT+|. WPW쪲"HzH<;!Brulk߾U[ZjF^ZrU;p:s#)JvF%P̘0S_U] i n_cPP&/: ?]bzmj&,ߔ9sF>X} %(RK;39k2ڣc=0hqHJ`),!TE6qM{axvtWX˫m/&ǫ8!Kj}Cݠ+`Ű^y.k넑C"9@Py # 6${: x+/0*,@V $Lw9=+C,nY]G+y׏,_tdSP:8}7:pDw IB0ss)_OQc/ MJr2i, U_/*\JXI:1`kIGhB1> ކvA[bE=K^ i6AGvBөSMr\۴u_rS(hSSm7}}M}# /AMU&yJ6`kΤhI+آi5]¯ c$Cgj4w^SA\f&O+SW^U؋I^{\ax)Φ .#̜IrKPFz7)}4h^~ t]87 #lvU;g魜ηjcl}هO94BB˘07l¢ <9_[cqcFEub5o343,@c>zhk=J« 5.H S%=+7h|ʥ+,WC{7p*U.]Eiq\:/Vcp|C P@MYpi4GN X,eN{kOÏw` 9/p)6FZ*2M7_Nйc袟n?mn]וֹ?^b^ɬbS:\mKqKI2`4UD7樇f"v!q<IIm}wc9]e]u{!>sϔU8]ع 7.+,)IC)7o1TNEϢd^3=>Y<54wMM&¡qsz>DyyZ>P۴PGff45TΏ>en DnU@'!GmUt]hT&e_X.].3iLEchV4&<*$kk4}z5klbtpgoX,̑=ijDcL[x^?iCtnHVRޱ|+ŴZc!. v?MGvzF}nWfAۗn)aYyv^g;\x&WȳWULrT-A%XM20[fS*7KdI;)W&K3C4#κ.5|bv*N Hp~ex{SQfhͥ򸎳7ODw7jw]hgh;Q9nF^q*+UzU0!yȗf\np@= zjIeIE3 b2!/&ЗwR0ŧv,y0aQdPW$7Ŗb^E<ȣns(=P:i0cPzMw ~jp7ͭFsٺa(Zh?zنqަ Oh͠ !2a]\T&@"w3H`TǶ섛Jq&+*9V# MQx*Őư*YRSʺ0x "5Od*̅ydNB~M6Qb Vd_\=sgO9AJ'u>CVόw S&znF&Fb]t?$?uőߝ"+x .Z 5{rjWgL#2Gendstream endobj 103 0 obj << /Filter /FlateDecode /Length 2292 >> stream xXKs8>*Ua"rs'Nʤf=l1Çq~v7H j媄Ƴ_̒_U'NU5{^f'9,QϖkY|}<} v:WI" w-D_S^Uy[x?8rյ{L5ϱzXX6i]9D#$JJ#?G/'q;IUћ D `gN)}&8uy+iޞ^mk9evvSp3G4jl1,e s/<,c8^i̭I8 YU45u LkiѡP3p]YoCg(} o5]pcpݮ!Y ro?U b 0\|l1ڰ߾\,U1DKd{ֻE:͢m%%nJI"#56<;Q9d(K1Ymy];n&Fj`2K tWS{mMѷ08P\S22cZ7naiMY[ao2^uJ3,6=NvhQ`pL yoTהYX=8_Eث'=zI,X?N)&/f MI#6&.Ϩ_~)?^wJ&C~w7jCM*|Wm6KmfU$߸R3 djS" @ `4"of-trjO/nuqr ;YZ/Ic96if~"=mR MXI!| eATSD?JhJЋZ3O1RW> stream x5yTSW_wUDرT+3v{ݰc ȢKHX^K H!x%9ТjuΨhTku:ӱ 㼴wy}ߟb$ɔ k>Zd&|W Uٵd<όY9$&G0 C&`v1kH& a3Mff93Sp^*uKLz{#;:9'=YJR{z1 gIqV,)6tq،bWC(nwŏQ\DyJ:6ʯp0b=W .pf$NCR9[~@_ە}2dU:of) G-j :VS^RZJM].̀ȃo\/|zM2z5 cw)lڲ U>j|m)JpMaV\D"{+Q<#ph6)_KHdZ9ӏōk 7.>7CR&[""c l N&49!=q @ =56{ Xz2{K%&C4Y35nIQ5Uiϙ Gk*JsYpڼ`E&iᝤeeStC^{VNm%&st]VZre Nr(gJ ˜9،=KN9H~D.æ1J}UֳtF?y>8ti@wN7薿6r>ciJąpc\=T؊:w 9<Ȧ*=)):YuVbᚫ@ efJKKy>Nѐb_:M N>c-PYsΣ{mh?M?@tpr\ʼnD3/o$Al@U4+-Mu{tC~n:\d"l3TW5\Wq VT٪U_RFʸ##6Lz[!cCZ]0WKZHBxİb]HwQcpq8-g9: 9yǕn64e47 2 ӋJߕO\qO#t , WsT튈c!B)Mj*yrP69-r1ISћҞ|0H0 " pdx-%gp }ЩļHR-MI(@\v)5)~N|W`@@fTyճ]A_/&ߓ)#3'\pwi!`sྩ5++SLY;aEq6Nendstream endobj 105 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1984 >> stream xu{PSgOs ZO+uGb,VDPA E. HHyCH܅PQ٭mqݮ֢ujq=Q잙s~{>^@ )Yh…myڞ͚H[eS3ێHbuQyա'bgC)sܥ^A+ y2`>ptݍ QetsZGe@"ZUZxZ44J*JJF+ F h=`U6ǝHԋ7[9.t V`S`Wfh eP̪ Fi n{ZW:Ww2U=ͅr(T3+V|4'D$c_ߨC+ɥbJN؎A30dYBcwϴg5NyTWgR|CFgpbVl! ZYјv0ij ťd^Şf),3)+ਲY YvL:{U5b>BXθ{O:/UkV{ZA@}ERmuinM3$n WG&엀"6L~M~ícݗ Z-*RuQ]#ufV[]תI_#pk[{|Esn C ~>Kѿ8ƺ W5%&e.7L!h+|\t?ްm0z(*l{ IfG>G:yBwc-k,HInY|lAEd4 #fhy,:LP|!o#G^;:]<kDg/ ⏮@E/š|r$ g̠3(m,,cr-́e`¹e-b{ EUAMjŶK077a}Ghǚ5@/n:u΄,C2M|8@Y]~ı8ʀ'U*W-6tTg }NȧL)Y)ӓ;SOfi8N/ñ1tIgZ[No$O.%v ˵ԕ}UM'3&s l5Iᴎ<4*HKM(Vj ӡכ,rs0H)Fr*P}}t\Ve3'fQP7j-l)YJ4U<=)w;y聸E7 `<5*j3wEhݥU˖LUfiLZi.eOaWJOӒ5KjƣMϴ%IeJ 8'}쯏'&c ajQ =<=vsHp~ M[j}}}Μ v ;> stream xWyTՙMí۬+մy/*#DC 6kK+Dn譪kj߫^U7 Ѐ( aZPaQQ4f0scEs21sΜ3uϩs}QQeee떭yTyU[+&h=ӾUw}0m{gFkےKWعnOˏ}ZCj:zzZL9 ZF-j|j*hHMI:VvWY׸'u?Tx˄&X1soL>䧦,rrꬩ6&5uSĿ)aMJa=,b]}Xj`EA)i%/NX:R7㙔1`6@h 0'5}7oV8#R%Z:J3t1x>ȧ.b6/r>.'پ>_o<G[Zh"~Xe{SZ)ET9xXOBXO4K~Ⱥ`g#靡/~}E9ƞm*BEKw /<ˢ3_x?o@Ƴ?yQΌ!(G#tʟYqs{&)n߇͇ܟkbZrlV\ɔ;Uz2VV >h֬qݴOp`GM-[;÷/J|W~Qq+W2o2̮Cυ]u!::N䠅L~y_w8ҡW_ErJT!&jżXΏ_32l .)-ܳᚪw#̩?.v&d!Yqw_xR؎J@_b\lX28 n4 igrugVjVک@@IXݲ;:b3${+Vm'g ' 0RI;-nUH{T CR]1Gcirrڎ:+'&riUʘkGy҄446oް/"0)HmV@-I4q]9 ZSmc~'h !9{0ȩ*7޹+r47/ceSn#;2Ln#[E7_=s<5dZNǴG{ nؗa(I_jvoE_O2>iN!?y"sҶ=kl[8ڇ݃QP 0 ъ}^ڐcEU2N)K[3 d+F>cJۭv֤1=X8DBHwylbq[D䲴%DŽYk@wURʩ#JZXoNP*RYڜ~rq#EVSu #shh޵t f:Tq}r'X%Ȧ\NU0Ճ^*/-,M~siFbg?m?;[`#o!_~qL]! dTsʠŰS)e6KXs_n\\;3*iQm$t*U Rh.(=$EFvwUhCx}hCpاd%(2#W Fے'(*.2Ba@#;7K7unmҷk;m[N_56;^Z\B0~;ug`PHxYrv~~˾-I6~4 ⽿Ґ3y4rI[ :Bڗ%X Jf&}Iof ]9mPc@IQ}>~:5/W7 (voBfr[տw?Dx'sIdU?/s (WNPvT!G ='Ⓚpe_?&=V%^Uċ^?so:**K[.?!Zز=Xr}0}"C~Jb({Ml:%((YΌ-Ÿ}NȹG s" Xr#;- &up9]Đ"f?~J4|tUՌ%,:`8TH2M~h)?qBhSC tpBӍ 2f#Eڍļ7cSg#ʋۿ}iG>M({Xw{¤BAnFX,@wkŞ70 LN 7Ba Ҹ EB@@ɻ{ 9 -tcQ+mj^%~ _A*=^"( ]޹ bk;;}.GօҼaKG,4(P*cp%;b<Bk t0lV"e3x&s`MNɡUIΑg ~¹AoD|1.oȦq*KnPXPK|ƛߵkUmXPr2+ [E1W6KNJh;-ꈞc&ݒ,QiR$OZB<1cшj.ϒPZч#cr:YVU8AtHl.IըaSC~ 8a ; xB-Yb*P'jlm[{P#jӶ+*,([D Gc}cv_ӱ33ސ7 "*(2?5}%![$Ȉ$H7=""/%q;qcgo"sH]"ӢG:H\o!@.' -NDJ٫j <\Ҙݣgʑk ު5ZWoصkΜ ߃<|QLǒɴ.h3O{'sƕJch%aJS;]*0x'o]s Hqsru<4 > stream xywt/(Zq\b A ~3&%\k;n-%3T(R$mPf.0(hXڒ쵤(nb{>w;{Du,UIIɵ.\CWTtțje6\_ _#v[v~z&ٖ^-Կk˒ƚW-^YrǫŃ*J]WUTTUkTWS=z@^  U/~ZZzHbգUpՍKT.)*zk.ή};V։?YxݵnqOﻩ5s:կ^[vjoZ|}Ig\U2H݅o??ܢ(&%_˭uPçcpfHuw *X&ꉽpM~ z]\=w7z[}gҭVZQf9quVjFY)#d3,d u0 3 C!&Txn `Y0MD jC"Dž!SHˤrGc>Q9sr%3R98*<lk/vNxHo Zqw48܍-non #|_'NH=|y9P^-lze6굖wwrW.~oܽjmčߗ?]uQ],L#/]] z/Dn}'rsu+]'Ѳ0, ޗL b3j| JpK\)t^8X sផ >2 ߌ7+!=)i?K!"+yRhtw}5߱魯H%!{`Ld4)"c` KZ6c8[i[e{W8 (sߢ/m8 `,Uҵ.7tQZxw1~pjO Y"28x`0Xjɇ-~RNݘ,a=tzJigSG^'<m=2#<%؜p"|;Q ,u.B=2uzB!L?c28ڽzR.ɱo{ʝ#^Ր,0u'3\EH.2w˱n4݄~nզD k_e03CH8VI(9ttA7b< l rLТ`l[Gs1sˋj^K7qSԜ Yk\оq4{][ 0dM&/M0hywN0xY(ki.ĜIf8pZ2kSo".b=%]g/NJkK{K'߿Oq=Ѓe=њƞ8;~v9ܠ&-1{z(58pfO/XJK.?Ͻm=MP;gg5>_01:f*Kzج{4[ǹHdx_ [vۼbr64Bw(Ly붯Z\R; }Ϗ!.W}xIBIAnE+Wh#T7NLHOywpXTJ.ڂDZ[KmqP['@poơS<(2':w<xPRBF w2QEȥ8wi+guC47 ^ u×`6Jʂn_)-xXMiȞI|i(Ad斈C;|fWqqz`rg } Bl''QKS"VUj%uFt`72OVKBꗷ.%7}hw!~ir{a:+<>7PG>,7MTD7^5[U(w`.aK 73Hֹ FIu6: z|/'aX0-xC^uuЄ& 'g^ R樏Isф983kZҩ-ѩwGIpB+Nэp| ꦧB}o3 uvū6~)SsŒX1 N:`FgUE=礝P 5Ij?ו#?+=xV |İ$ ^_&OI|=ةL GuhܭTFi` cx,;2*vXڨM:6I ڞP,]^|e= !^! Y\nݾ[e!$zIB&0vM3Ӱpb|`<$_"ΗJ߾Imζ "~atbg΁AϿ%ǀ&&D clv|!؁"u}͝ *Ƃ[a[(¸uۺ7ZvG&N%?>9,i_̩GV9xs2 ^ߐ޾H'!Oiy1HݛBzZw}FtlU٫0vEfnFxDqczl~2l#LG2}L 6^^ks̸0Y\e}BU8>>%YH(6P]tCɥՀ?hLHcts&4(G>Gy#W A\ |o˜ӜYeJޜ+ҕAMUMJ0q.o|F,Tz+a MuZSlCGŠZB`+]jQ|xyXU͕k_g|',&J1 ҭř(ʗDu{<4f Lۙt㮐7F$#5Z7/ܮuotHQVRFݮ7ғNIe#9NLwTh̿Z5B3˄i3yA EVebQ&Vxr6< GGϤ"=V%zw>"9LLP\R9bltbjg|/^"f=X-kAA]W_;3e[↑ՂQFr hJo,9q ;ʸ++ԛ=^[!߈oGQGNZs҂<\vAݢ,}3nS3IbIUT8(qʚ_uȹK~-%:P_y_|\Q.WL57),B*y86w(H< w`Kums< 1UtF\6Cx36[ڷL&-i?%%<-_ƒIzi#D\H&,cCAqptG^:pS7"& .|& ҅\RFz JA|'x\~ɉaiɥvMW>H[F0ʽ/ yہP\O0 43qe~FH6|LjìMRRϥ)- BᏽZTvr[:jʲve\W5%: ;͊tN1t/ kVЁdkz0QRbgQa*7wdhePMW&V R0y=aCq6u]ӷR|P pAUO 9MbBb⸖HYb'/;X_R_OTf3C JQ*U#jxڲn&O ~NL$Ng4n0V7L PdkNvqv44&,T">={;a\E|(5h:]\?kMvOiԢmaCC%=QʯĄC[S+Hoa%&jpe>T.@c܄1$@i68Ve'5Mt]\&l]fݱv2NS޳FiSȦ ݭDvA>EqA"EʵZLqPةwrL) BpG9'3)zXt)Qc~ G_/#e0gq \7PsvDԁy|ç7B2l`xoZ)k|F#73c,+žv@)څ[&BXOW(nQꤖ*EōqWrDtOPpPxw^HC/LhWl=L>nOo96ac=Tv Trϛ82Pz 7Ua걠 bmB)byAR6Y.ΞRX,5G(C2>6@4A?#TTQÕ]%_Q*M^YYMz#DbLFgm~T m>!sكq> 4D2 KANYg|=ߛ>CJۃ8>H$>q˄hޣZ(~؇39 G_|LkbJVkf>W0J#\pX/-r6'Oxw9w/7l6C. m+4O0y1f E/6:ai_V-E Az^'s"sߏ*0I{__36hnєudzzhL1TyK>16܍&;&tR4_6/ ci}-Јrhady1W6OlF4תTendstream endobj 108 0 obj << /Type /XRef /Length 110 /Filter /FlateDecode /DecodeParms << /Columns 5 /Predictor 12 >> /W [ 1 3 1 ] /Info 3 0 R /Root 2 0 R /Size 109 /ID [<64d2c7308dff5d251da76bc1089da3bf>] >> stream xcb&F~0 $8J ?`Z m(yHG0m"*A${d 1Dr@'d: "M`%;09DrHmY$tJ endstream endobj startxref 70921 %%EOF Matrix/inst/doc/Design-issues.pdf0000644000176200001440000022706214547724214016500 0ustar liggesusers%PDF-1.5 % 1 0 obj << /Type /ObjStm /Length 4082 /Filter /FlateDecode /N 67 /First 546 >> stream x[Ys8~_ֈILMƖ؉G#'ę '(ra˦ }f x@iSȀ:P4E~ t#PM-4L(PɀB*?"1B1I(XC#p}3GbA`DĠR@?P%H@g0.)3J*HiӉ` Vƃ(&`}V5TH[洭׫~B^f˼'QhsqtR./bbέ`_@EX`&LM򩤈%RIbY`7¶xBߌ"]@lf;3 NVв$y/W 9ZbMɽrrC> >mN^PXE`&-NW0h} ƒ4/jH7(R1lꘌ~>EQtc1gcYuz}M@DIB!DL!O <!mL\=kIμKiҒGy$G8!$z&AC:!,y*T'iȸ$Iأa@ۍm(F<]QD9kP*O eTF)en*_v޻4HR1Byr pm8͓>nE qo$'4,K&z+E7k63̯YIx|xl3.&i wboguxPJ~JUkӆ}ڮ0@zВ,vwٴ~hlX?kJ75% 2>#a c9ULMVJ-ܸ;N D? “,LI7a~ m] ï_2̓mNC2&ԌVelRI,yܦ=;(-n#@,ρw`傪(۷953| ߻E ;<_xap؃K܅ y 0uʚ'^i&qЅ-CZkgG[bjӘ*eR,t߀^D[ 1,</K6 F @r!ye^62yzM[|[-JPOsn4+z@\*F[ 3{0.0xr <%ڰVGos7O*mHEZA3 ",j.?  U:w c(z16pm)d]o@mVc/0&r8Ƅ0FbL8flP(vh]Q_kkcZ`Ԗ6TE[&3. B3mH+kEw_I 芺ؽ ]"bCݿ ^O8=^GG+| % l|܊%bK}>&}}My3|5`Q3xox˫Gl6,i_1)싗𵋹 ?UU6N|yr ;: W纴&_dJfJAQ< CgW*w^Xku6ni^.%]]b|tty`}OȇA7Re7 Hnnf? ڳiVo3Io%G.VI>ɲ"OjLVavɹi'U ,P7Z 徱û1`nj|9~fu!z#&B|6:1ؘ1)^Ii^,r37N]I?_y]'`n fsG&,DghOvQʿ$%,WZnWZ;XגJ+ߐyS =BÞB;)84PM-2o`$g},n=GtR_D[pCijk|ItK'4% {_ևeX2@30n~MҀy軒ª;n /tTt>1G͕]Nڪ!E~xgq7P{͕ pO?~vh8S2~~ -iGZk{0jY: OԴqC dx4!u}vIwϜUwbnZ=4uo1oyQۨ$( Mk1i1>>bH<- &27]= ve txad)!K}ݡ? 3rfwV#=j: ˽- L8endstream endobj 69 0 obj << /Subtype /XML /Type /Metadata /Length 1388 >> stream GPL Ghostscript 10.02.1 2024-01-11T09:36:28+01:00 2024-01-11T09:36:28+01:00 LaTeX with hyperref endstream endobj 70 0 obj << /Filter /FlateDecode /Length 2973 >> stream xYKIs0%b1O e)*VJ`D4:R)ݳ.L.r_կW.7-d)i*l itfJpf,7[zʳҩB}H2F܇)鵵\i\CPeeiEآ,*| _qP " yXÙ8Ù`:874)6xK?t|67k99f' E)`~3 M09M&=uHl0#:mRSnĶo9dU{|8u_mәexCSTO4Iלļ{8Q횡4yII]6Jrli yJI2"pμ,l 9oVĔM`2%A&+@WMDiJϩo]ՅsMJʩ=W *UFYZ꽆{ětX)>nmkm#Y&̺:D.b|h̉"I:8uWD`D'ҡF>LQ|ܶxEɁ6z!3,Ñ Ob Sضo#O"Nb>4.qHZ8@xQDQdBU L8Or ClH`a}XW]ªJU,; \_ACFzAK1$稂 r%ɧ`e1l+Tx : Fٿ%;haH|B^^ Uv*+q̉vaY9,ARhgqZp; x(٢p-tHfzy>kCdoHU',1Jk& c~{S\ }Cr$UZ#ؘdT'!ZC5- f6Q"%HtUB\q7-v|NMKx4&0oz@INl)5Lp@EO6wЉ/A~g%իPi!0̭ =%FҠ Y^I="&b>]-`@Dsx2ǪCD|st/<%kvw%hQe@Og΍eb( GmVy:'H$iMO!a0h+VYrA 2mB[vqe^gw#*]3Rq5ԧiӴ.e|X\Hr"kMǎqvT=.)j*fGeJJ-r(Ci^&Ѵ֩4+G :I!O* 4ڄ,*WKS2SR*9o0|0X"5D1…œ`]֜ G#:mѢZJ{WzJIuN? VD!"vyQX]1 L[8d@aHK~ .Üd D0aZ)*˄BE 'x4q 9Ӆ; > eTDP)Jb!‹l|D:ҋ8W0HP8d2%/ L, a΁PGԓ@ه-0|} h}JVrPmj=BHYcTױp#h i]iæPoN;)d3 x$NRm>+L~lǢ@H{h}9C+\16Da3$#}IDJ1 $f.W7 =Oؚo ;?y*.VYEO0B1F}F3>< Xrbx<^,M]l%Mt,zg6F-X2EZȤW7j"(a5 Il[dN$%+Ѥ|t~|Th؇4’stW ^\uBvuiUMUYv' ⥸xefG7~WB(x'c-! E&kCZ`9WJUrV|6Jh,?&.Yz SF#Se*dY\]#ۘt]ߦz,rr.1ʞ 4 cx r!Oto Yendstream endobj 71 0 obj << /Filter /FlateDecode /Length 1623 >> stream xWK67`, JWE.h79M`AR[vd9!%r)|D{y3t~1jҔw%i UmP6 EoN!ZCA%#&oEw#NhN^=eϜQJB`jq<ͱ%orTWמf]5en.Rܔ/b0C!(Sh ۼ.J_ex!7Ђ,I]`.)?Gz%{>s+Tϝ)g4U7QxJn8LĬ:wHò (x']ZB로0Gx9oA&u5O8Xdߴ^NJveqguU?"3nt L򣕡)ſ)>(V=aNx!xCf>2#̓H5Mn54g,Yz l˵#@: %Hl!y' -p&'ȣ:)D1z.2 %4̋mö*1 1SPP , L>%cS$ozuF۪B慈LcQA̅gxh(X[ęA*&C< ;ӐJHL1b-oJȆ*KIh 9TY9e.aLx*R&3mEVQx4 )HPYZk9(#y=`X0vv\mM0q˩Ci!do-W",1MSg*SS*.JgR, `0GP%YGl96`,!f$f}J*}OJЖWV2-ֆ4K5p E %,y"F"M ;:cpj1 Q8k3>p)ې/Mu4b]ucmX2af^޼,qU.}*~,t2!JSc7M:~dI[ْ#;=v+(?O.Il⌭Sod Y$ؚҾ7;dTHGZRв23W#qP܈;‘( R XBey_C^?[KXdp ( z{u Bƕ0QC'B) ibM㩮\Mg$^ 'Z{ag sP/! kB@vX|jP,!&Qv~_p{Qg> stream xYKo0{i,nvL6.C8$zEil|>d:6>lvwۢ]ۋ.]ğnş?((X}+K[F\HX.X~mݞ8p0,P$4]]K/3]@~ɪ. ')[xZ}.,x:FC|[w"Z75o{a40tiC\kFcjvGIy RRAqz{Dm @ ?*`@oJR+齄c,k (K^)d 楛lHi^7\cjIyrj4 =2SNv5՟>/uǐ'x 7]WrVܫ"h,wWΛ "OA~ꭔIN]JXwמ\֦:Uu7!}םA@qCFZ#8<BZȴEqx"?~i P6RErV2QyOA:eCb 8eLEǖ9OϷ\5%2a(V}H/TQBYVwq9v2#4ҥn:$Ҩ.*s7{.@[1iQT,8k-\.C:rlYWUVF?6ڗjt,@;"g[u[:۷ xʺլx뤩e:Pn 1GG;W)aM; $6o<&e#BFT!#Unm)X#E!:T6{/1hOwivґ8 $F-}.^W]CsIQ"h nsYN g)%y*Htb _OOkᴭMΉvCL'DjL j7PvKgѱ{jjA !yQPK܌3+p "=\@za&8}ըݼ7xUt4=ΧM<\̕ -+}@.(LR 9|2y*0sp"G$3 }(s'`~~Ev,$c}0݈TF "sIIJIJN$oLo 2SwB'cט<`yKZHI!$L GvċL`S8T;\1Ϲ >8 dW$Ht#Lz >V㞰>ζ!p!r΢eW9 w9wDPQmՈ<=W fS'U > yFz;Bn=ןa=X3޴ezzM g!'?U^()\KΡFуґ5N]{ΞNTƖNM~ⵦRr)ZNotnvTO.e#Y=Rs>aTY:ۆ}󑾫K|t7oȓom6pO ${;(HЌGt-{Y=^cCnh́o^*q?kZğպ3UhN}g1> n(7ɇ8PoxW8ޟ g T[ʹAJ?RR?yh3f,jD.C1'}WZ F`7>xw;^"8r8RY gL ?.^endstream endobj 73 0 obj << /Filter /FlateDecode /Length 2086 >> stream xXr}WH zE*Z3HBA3fh,_n4HڐR,X{0P$N`su}-6wxFHJ1NxEHGG|oN?;xxy%m^{>'<1EISe<a%{޿_;9>ADC%idF!}E 4ً@M:Fn(IJv/QJJ^m^%UVZ*MjϧPujOH=? B 7ܠ,Һ; ͗1HDe-jeZ9ƩͶʢ~cW |adP::Ͱ)(O˧0x_ 2='e5E'0I!MC slNjP 9ֻm{Ȃ4?"ڹnow^zDO[#_ 1h wC0'AC0< 2|8VeX#P%_X>M&m*Ix%\8A=I~",$O:0IC|C"B $T2ls|b1ǚ]֥; #!aȅ8o1^gw -]Q6mUdj d nHeFl҄YCO+rfQGH;ܱɾ>6ݨDmHrJ"AlmC%9ź%3Mb@Ek]U3B}JTF>Sjj< ѻs1tݔl ,>cz6%m > Jbrf VG4nǛ$]gm:]SCk%C<J^բ'מԤMqeZ=J$'d%;I]0%fQI>zzʏ(^|1ˎ ~G^,.4VYmoe2d[i]H$ydy} X9W|yv?8;M+#ב^y2]8@5W$?:vxvJOf]h3Тl3YDCOv 4l«*JwW 4f#B|^t;w˼ˬ7F4 :Oa4^ 4>|̹endstream endobj 74 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2464 >> stream xVyp^Yޚ8$PKI IJ2 HH PS>eK$:}ۇ.l G@H 1i:$LR.IF4eܘ+/-J=̅lɝCwf,>J͛y6]~X3GZ𦼱IZY޼#ZRS[azl4VbE&Yl3VVak\,[1a7xisҔGҟIf<,Ђ[O3-~ 즙B)c?\.@۴dRHP>r0 [ߝo XԷԺF H ~<.W p6}{˧2IKG,/bo= O]d3\ПQJ >NsY(~𣎿~7 C<̿nP U%uUp ,j[0"&yK MCn  xUC0o44$zmO(U勣d 7\XUd[QfNO;N؉>ycl+R6b qf;0*|RI0qP?ff-]V.* ^U%T2­=T\Th)z=-a_FZqaBL " FfӶ>f3Z?/P}~dj "PO+ mpMu n ; J)GI4 OmQM>[f[:5ݭ@ Խ*\ucnB >GaeBD'Z >#E1r+l6|{ϙG{|z[6`! _b#Gdb^Gt8*qv&wQZgTq3eb`wZ=h<>~\d ݚ#"yW+B%PGim__ZZ 5x tO(3|82+Gx>FCb Z} jz@=#7ᙱ)y1`F?H {2f`oXAk/,4}8ڗKa\<м )1`8Ȝ)[8WKuLLP[>#ܺA?>2&ww_TNɂ$\y-{_ CWF'Ba@4Vi,-VYvtd79vnjvohsVXbߩ'CeSs9E߉BG&&!~qW`!dy-Kjk#Tf]4"gqZ@ooO ۨg`{?JUH8O 95( l\F9`G5aFQvհ7ٞ҆[%eB`/L8fx"uBSݩ6D RhJYMR.5 .C `r6tf~߮kY f=Ž:c-PMk}6C!sbaɄc>=t@<~П@B6aynDbAeLl9Bmz9n촍C\kQ)#ڞHhʫOG/s\t]mz59ҊJsͨ3xƠ9(qiI'm9?I:3U9Yŀ?HH:y,\_SA6~툱# ou?}-8uu_+Z+ VG= U]Ɩ}M~f ?/IҟDFJe3Y˹Se%iKvq8\v`%e%b(5p"|/Ro@|j%;1ۻzwۨPDeY$ b*+[hή7p҃d1_P,Eۃ.rH5h积% d}$ b=z(ofA#n0Z4u$RN8Z:6Un7~YVPiLA Q%;$3!L}}muykH 9%b=~x)@j)+^fNND2tIvǙс&`$ېTa VDzpN;TܟE8 p?BWH 8wJc+wj. m#p0 ;T@s߮>IkjAXu܆WP ]'jWMwxpnc}Gqlb+vAW755ʔxR~6NV](A"w G~gmHTL}\d}>Auck`>#3 *+Fa>\W)=9CU_2t,~DzL 2}'9endstream endobj 75 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3916 >> stream xWyTS׺?1UD%7O,SڪSmkꄭD"*S0$d<_$! % "RZ^U*V׵C7owZw]/s|ox8+lE x1)?>XgL=_SS(Ւ5kSB32{c6=x(,.|kbҒe}i"zL=KmޣfQV*FmP![(TWX}u)}@YYlV\rOgʡP至+xae<1o R Kg)lJx+m EnkY&{#}'.+ pӄ=8&zZ< BD"|{Njg D=Z "SE ᰭT 9 IL Qica DVtC_ el).sw=Þ_E[:V",`*x;a0 Ɩ(r 9ZqsX k:m܁gs{BLk5(YUʌfEgQi ZqnB(?pNK./q0ɋjIAmP &y^d SMG~a@I'<<d)1K4$jf}\mu'?b2kUsf Y#6s3oyDNV@%lЭO`UEOR'v-Lt:ڠpf·gW RV{FE"=C1IEI5LVb3XxT4PP+RpϬmbX `  ype_nnEt!f0lnۊp èXZV!e:˝ΎCqk 9y[ڃk' +x!@k$(+~2m O6'틡ޢ3)*CӚbUo.hޗqNob"D-|~=7Ҡ* [ JuVu~n.o8&Mwx,狙.M]YYv(p$8wvB׋BTa*;î]dgr!Tٶm@BR-d`PPeUg2;¤=ދ7]ӄ};O8O:{L=$.yNy8[*A G⺂C1t=3hT e2瘡`2olXBR[__USאU.1D(z?cF/~m|}ۃD:t22jr\uo/l@&J| "NtȐ)J>5i YvĆ >'޹݈ا7;UdpyT~?/7lSwE\b [%g92w<!M&Y+NLexg_^no 4Zbal IJ۸ʝ@': XO}l\d1E}zuX1ԗkUU W itWlp4~'_M2Gg]1msͥQUpIeqj|6|w+הbz{s+Qᨠl*y2Fxһ諃LA(WO0M`BfYSIWvG%D@,զ7|Ftw.䉕Z1pׅ elm "VSIԪ%]iQgj TOABy;]C$Z~'7o u3&Pe-Us[&wQ mnQg>@[]g*]0曬RRB!; +Kb3UA؝~4Od6omq+ . >ԔD*zedy_SA`s-_%o`̹ btK#FR9a-9\rPt { "P"%srAp4q ?/;Q?`gx{Oe!$h' [J^3Q(UȋS :1#.jX{役%ٶlZoGIl3"O?p5XZ(.}:-ݹ\&U h.@V :o3RΣ%img"E)ڼL"ie5\"mJ t.qH sO`~C~wO͒[I[qܵﯭ')..Цr9d⤴5ΜΥuA/#>o~Z2SUi^ʽ!j́dx<[r19h֬1j)X5)ƠU4_\44kOY&&.ÝL'xfw@}%8I˽Y{t`a9qBjsEpk_2! #/s [(foLp $#̈!s4OF3ǢwsPPrfo8֓} weqatHº-ב88 q(hM{q7wZ[9GrrlM\rӫ#D$,% xM$V]7/ΐ=d \Xȥ/'j[]>CIb^fVӰZ> stream xVyp_Yx!x!ݒv4I8℔+)4A%ْ:,KlYec; 8!v CI@<$h)fv Ly;}[1!DYk̚=s؍ԅ5`ߙpN:$z=c#|Lؼexe3~MZ($^"/KerJb*1LZEIE-5/'L8\N^Q%kNVyV?Jbҽ2HRPU_G`|`?C0$~ 8eI uy\rr g-asxo N b73 IN_BK_{ngIpF3,I&h"TBv<|D}yo,ovȍKl/-Z.!ba%\g{FN]lv}<3>UB"?Zbp @eu<3Y18*!KG$hB!fJkH6!%KV&E$a--ƭJi>X<2PK%vʿ-CU9é)tzXac7#(%7ؼ#xap>-Mnynol`G%-fcSڸͻ l/yRp^}{15^پ 75}lq5얖TZ66 Z*h6{>!Y.dMDshzzd&)755~MC>}LRrQU[4*oPh$l -QOs5wx}zl{.>D Bz$掻&j ~< '#vWCUZcIsH#cՔP@I*e|\zXOEyh4Q ],ZHr)IJߚ^߾4r)xDauFR(kιyn? Sea{c<3ԏy#պdz/ .Jdr bL'WSԢi"!6{ 607q,FS?L%OgP1OWk83Õo?U] ?:<oF(L3ΧDQf:KIvK\Ӿ7[C[ iQ)m3tܪkcZA^t~kmUh→M:ֻVkL"``3D޶ϟgX%ZYa+K{+ܰhk=z=i Jv"#Oގx{@}Yl(¹992X\ja\+#?ʵ{ZH}f "ZsPQ-n>UlcuoFTF09{  Ky I42b{Y%Jǔx;ꄌ:.AqV +*'S2UEY4JF5ad19Rrc}Gr\wN[K?#i*@;cMe"N܎ϓvhmB6XԚ% ƘVm hu: v1@ !-jU5~Mp5`{{ThpNxh})0zԴR…55 736bb֜#=]g: @_-o4k591a$UnL #7?H@-(_l,&,?MԥZߠ|JW8k)^C ఙ/qu.$|J@%(S(SRʡ w&Z[T% pIL8hbAA1ջendstream endobj 77 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2163 >> stream x5{TSWoɹ:n@7-:>;[ŪVex@ $$$ᑈ"H D2U[8VQcf誶:,'jR{s>QcP<o\ʍ1QsF7$\r&aXqLoy}ړ#˗N.9(j=Mf3*ZNmVR"j"DS  }=f-?`E<);@St鯼0_<S"}whW 0wnN2KY[.dd~\&xƽ^(0Y([f?,{Y3&^LhO)G=u.ۄLwkoL]fCrtSey9+,CR)}g 﫧S>6IԤ",QANix"̼³/zX۱<4N‡I#KUBrc>9Ump&@2ĕnHMH >>Vh_-_ x/|/5{œ9J1ZJ%$rYFYa8$~nYayob<}Q04SIVߚsDQ|lhJ6 NTl4HfiwqEq5x7U+;;k3`\<'r-^p^>K`ȊN tqp,h6L/LKR$gŵ+_/M)-`?4scQZ.i`B5VD~4es:Zz ,VhE;|ha.OHdž l f<r*VB xLM]?Pzڧ* ŮzFhV;'ko~KYgX \=/^Qr}e 㷋,rr*`.ԁ7 ,mQe)b-ee .xJg_iINv rIN^[Anzd`LGQ3;endstream endobj 78 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2033 >> stream xuU{PSw1ɽjD܌]N]u}շIyT (@H A/1 M :t9uo:ޙǝsCֵG :B)UIYi4R*N6VӓcX/!vn]l vPYU'ì?Q L^@aXV(~ACC4P 5מbjLz6_A^ d.a!Q+oF|8{#fAjTz*'rzN{Fb rv@mn@}~П)*gV~0 )Ɇtwf@7VbmtQѮY]Q ȨQKtBHגy fT.} WZ$Zpݦ?~digk 芪IZS+@\('hTHjPMmBEu|[3s!xy!F)z |0rxRRK6!7(T(#JY8PB[ ֆ8=#ꆙk`. )+nq[}Vq$ < I$뻑q'ml\أnpǬ%,>hD4h*YޒrkEVDHN`* 'Vlr礩<ٻgX/zws#-ҚvpҙTx߿+*0Dmۛ -; iD+MȊنtHtfL9Zfr{D]M3PW@vWAx =fl(Z mޠ3a۲2n6fn;` qH4jN\#t=`Һ H/axۧ}lڄ촅26lT TS''H9-_%LV2U:Y(;(+&;>,1:{3L 01QDQ4^ oF fN5j@"M<9^(q=x'FX*x,3HN'Q OJ̌t7dawBghO'ug!J0Dp847m΀<\R7Y^1Wikk<03cb=J5xk[5)Md%C]Yq}( ,LKi :-xkoAL3c# v߾aT/&endstream endobj 79 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4107 >> stream xW tSU>!ë@ClDg ^-oI46+6ټ4Mi'R+;>@:hѫ8xaxwZsgݵIWWo3s01o֯[\Kv͆ εL^]<V>?#mWTJG3j -/ݰzJ}`-ہva{^l²Xmb/`b[mX/X:ebRl9Fb%KcP9`Ί9eL̹ k:q)LLu_6߽`B% (O],]2%K7/ '-M:$LjK9G07; eYsL =Ƽx+pq m, vED%7*rίiy} KT $@'fOdOeЛS$yҽ荇a5·|rBws6Y*IP.Kɬ3ln pn"Oh̦X\{`,ř V" Ue z&| ݍ&̌][?f!8Yp- wq`2dUa-j@5ZO-Wco_ ާhfPdsEpt=N5nV>MfG >sKD䕃y|"\ :?IULd9_B6se{rEs5lƃdVs((Ք*&DП2Pkd<ƁkD4-&aʯ'@PP ,tSWۆc,2a%ʁToړN0L2>vOٰbė<<5-Bn#NmQ &b]d'"®oS2FMc81 X ΫqN6$TfK5.RHC Qjrm6jm6Nō$!QfH]ɬwaj{s =~JDƮ>p[#/מdx@fɝ)WF0"* {&E0 3Dt78JJ>@rYyS 'L] (vOIl<69s(-8 uO"*| u_\h|fW(Oq>a L"RKQeB Qw4[Z v8>(1 ?%&$֟:ړjU^و7z7?mh6&\먳9M&adC 'nYVe3@f=f"\2 U*3;$G\YU]v2|RQ:!zA9Ϭ45i @Fo@._Ou_yW?k>{8ņDC> %  /MY`b,vj+M\PFV׃Y"a#7Sщnʑ,BzQ~rK ')E|o3 7R~Ad Z:@x+$,W'ݹjX(O}A͍2,2htڄQpPEP /Vy01@rӈpa\j8A3[Z; jBgQѮbAAn$0?ZE@EdhI+pޖ^;1~8Y8l>sȤ2RƩVI*I.>V+0`޶&/jm/DpiLMb*oI ;%{{x[sCɥRukZAd biKe=F:r}FH7Q~\"FT(x] >.q{nj7Ny]bW6T+*;GB}h :.5x1iYHjBY%>t,(K9H$tu!ʮiz$̾Ө7DHb2Gn> xLn@h V.aD(qpNShb6IUzkQO-$&g[=K0Ls\vӭ )ye2lV$E 2y{mn=MHZ9uƧy };U -ZK5stplQqSI?áSa$L[$(=h#Z!T: }pwreaT3&9\t . [mW[T$ڐ񒹈NN]H?Жޱd z1_p[!i;\8(!1$/n^OmpL:=U!7*˵j(m(oP7E-c]G b?LH6V .}{TG/xũϷqLfXHPm,(\^. xVʱ!(!MAT1vOz~8\gŊ(|`r0Uqe#nrv>.ŋ,,J{NAD6@5BXvȳUFdYtPvI'{'YQB g TY[]}'WS{#BzI*j^bc #{96} ?2i|1]cA$k:J$uZ-2JT6H(Ud+E*8ot7N2=t:iϐjaz\}M.UυΆ.95Tm>?1pF/qh-&5h /RN[-uOf{=`kYEƽ?nn+I|uЬ iq/0q.[@UlBD¿G(;i @˩Y6EbϘ-+'O7"K7["/_S,GREqcˉ8oD[lCTR,e/JgbO-J}4OW2za'+H mmr4-rmM2 kus(Q *:/M\4aX6kW{ЙwYj)HT ?T{F9M trW\XPsnE;KbqD :lOr]|i@eOC+/#ﵰ F:S` Dz\`؞/ً|Zҋ3W;b~6!BOnu.@)WmZksdK<9"?[)Rj>౻\$s]{Z&} 8%#zC#uJe^g/ߝ{{tIJ`S oF onD L1)hgulnҮj+e8_~ _OFۃQNhPj2^}CWK&2clJ҉M~ g]BΦ҆-\zcY.YdPU#0s̷Q: V59tb_<À~ފd1QQGc)nl x=p 7 7;`. i8` x Bɬa UmԨyڮ~79ꭝR| Zh6 v:K|3IdLx7Lד a:endstream endobj 80 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1171 >> stream x5mlu6?LԬab70Db\aalFO[Owmwk{>Ok;R6"T2C0f!\/'0B?ܸЀhn&qmҪ7n:V?Qܧ7`b=VlC L7PmϚ^(7a-/VTTwԜjc#I{~&S..np̂{SL5i`q &DNc &,ĎZ5+3p1R^,;=Aڗf^BꭾAp!Ht6+܍ "Tc^ܬhؗ; O Y'2‡E;@(c{Q:Nxګ,h)>@NM9LBy bbM6nZj2$}Cqz:(dpwDq@_)s6>+ے]t'LJ1Y2qiAs]=wIʩ30 ;-e E 2$t/>;~0w+ ӗokEl?\ݫ6rcF0DqLZ&0Ago[^p{N4\ުĽ**$PLxn'<*Wc:p}Rj}/.J-BTt]6Ȟf?ԼR827|!,62RM0~Ie3%X"~&Pk Yl~|a(w>΁##ۡNuJls膔Rwkk[}mxf>Q>:+rV޵J&5> (pn떅Ҁ%oYTs}c \t&"e<ۍQDXfUKGDz.*xD |Qr! bn+)/8zj!@v:.J>5Ü9Ȣ#s]ҀZ`B-.fɔ_e9vU~&{dQ<(]}ޡ~rp 4$cL#FJl=uP}ɟ.bI>$WTq1 h`m~@g\z|VV`D ~|ecy =endstream endobj 81 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2435 >> stream xmV{Tg23TIi;Z-ֶZ(Z B[ *W KBH|y, !1RD[vUڵe֊ZYJsC?q'h=?Μ]CHihs!!+m"/DjgCxYٻya*YxJδȨ D$EDoKPbXNH D!^$‰-D  >,AA'K)!]['9"Gb u66rWe'$ap{f;]j靥ds*5S̅ Q̍2t@ ܾsʴ)ŵ3a/z+{U]9QZmfnT%Bp]'P81/Y }ġgO!srT5kgF0Nrv XmQiP"P\Efjq*JA Ny E$nxi bF:Gj:!a'`[R)AifΏc 1۷U ؗY{ ,v bnM􈻳?Dͫ'ZJw*ØfyM9"A';rz8w-CJY,3^]Um AEyH͖ eT`*0 :I%܇Ӆ(~I욚ޜo+j4 %:}1(TQC:T^SwZmj^/+ 7D*=9AEX55G ,`3(+D "r˜;BņbTDa;C,t"9Ƌ .RWY]SMҘGc-ߚ/3vT:Fͧ /J`7:9Ø"4"Y Ra9}#iK(ѥ>S?|-Jp `vMgz_n7u_NHne#_\eNџ ri=y1ȘdžN8Ol wi ,$S֟,f,(}qClon+iPs׉Qwmf'`/Y9>u ٳM,;J`A5Ȭ|Ĭki:,%*3/mn2â6&3bQ d񬫑ުV VeE6ݸ&^iGoQݺN¢'ah):JسR\G]kt \% EnO+//ts&ku v-'UXT'/EJeP~ó ) *r<-x#}=֎K$/uO=/ !; }y;.qitڍ2_,ld%M5ߨ2Vi+FbԘJk5ՉjclÏqXz1Iߨ)Wrh(z#]FI"_^0KV:-#Tj4N,:[}e7/y_gUb.HG}GN}f6~ZYO{n!OY3MLED؅ Qvd7yPϷ6鲸/y(y\5nBvo|ojXO~{V7EQ&<^o`;4A =_1y>y񣞯(d6#يT\u>k6ۗ3Wȃ܂0 @qX+oX?}Ci]j"cj4:TJ{VRH$ÛHQ@ ~x>zr`g$ > stream xytSW3zXXGHH„@z0`01`[mْ\d׫,wɒ\0lk B L !NH<>2oMY KOs{󢈾}~,]҄  OBi1`@49뱰 Ġ g ̌52ߙhNv\F>ַ4歘w98*J/_c#G 8uG>~yAh_?ɱqW?x.w d|arf>M[ qOy鿏9kgF=3Ϯ5Q w s GKy(i`Kxni5ZݠPP)fM_dU$ 'U[MB@i.,lXQ/זW?d/:i@ tzk!zc)zSdЦ%\ ?1#@,s.2r9{12'(% TOn0mpەmke`y9lLt '3 4 r:V`f"{фA)Y 1۾{:O@\ $ALNզ@A $W2 oP̕)\w}yP'$xPܽR)w+|{t/'ď*(0f*GaB{BA.]![Lq۝yvti[^ 0+ߣ~I(C&il Xw# <[4i( F}8`,_Bs;:~aR0}ܴE $@ k$l9`&X}RJ>Qƭh/Tk[k7L:W]r Puhj' 82- |8A]v/'nr]3F)&Ja 2\-%k26u*JLGҺ7]Yw)ީq7e%U a$=6u^tV7{>gsBh2Z1h|}AǘTڷJ乗&(0kZwt&xy%ޞOnSV6@'4uoj t/ъ0Eݿ KnFײ$ W,aaI϶dpFv08w[6{v< ˑul[;^PMLIc˯P=C@DŽ8#gJPamNa\"A<5=_5 QrmXd Vň8uox۔,g8'=U;=n/("i1~n\} Q['n<9 +lN Ds>("~@jD FO@I<{ivQm`:\.p8%١c_Sj1Y]n+ёAgxf0fȸI(rD Z;o{ 2>oԹ,n{P,ZnBa 쬡܈/vI,{&\|owBMok~5r/&ȟGQM .z#[X b9(eVW7-VsA.ކFN)p lHtB ( wvwօ9rPh*-ӎ{y YFHV]sSZP++B\Bɘ~eI\a޳ka&ݶd3c îRnHTj.p,8GY㮭lU8i DJئ0/}0{ ĻMU#eK S@?S3O[}V!mt8jVàIj( [)3jE~Mˆ;ؼrfa(Q.v|?sʬzl.݄)ap "|lG |r#OjLZ\jQs`0\((!zb-&B^H I;YWgV df7*.^I IrH| l4m?rse/+TA&ө1^XۘHlkt4|&耠[k %:fN1*,}zDW(!@ёS ZKTBX|?{BNc-6OQޘLMv2XVD/(b]{9#y˄%`5gRb]bF%EeUӃT^-m3$gi uEpv· *ꥦZQ 7 . (ʰ G*ej{Xġ١95ss^PrTqhQ{Zak-t +VUXeS% ʯ< 'ϖ|!XMu *$×Zx`Q2s>ix@`V *6R, M*Ҡ^&|MF]8Vs'=f) nZ8QƵP7< ;JZALHvǨIo'apwԱvF d冷V-4][- {@p/ ޠBnM]y XSI4 ]>_O96`Grˊ=EP Ta7PZYZ)+-+++-x=>RQEvYv{B炽J\DȜ M.@O#@sU6/b_b3 \:K (Kp*jYyyE F:~Ȅ&WiSX-YhUahH_A|ޥfmZm/q30(*-).eK|.2iao95@CU8 yd>5\yny4cGGjo&+p8V[x"PWx# t.%aZV~F%` U^qݎ\>sou`N?&R,qFt-r2̒ɠWcמ>-o Cr"샞\^u/ckuӷҒ%IPܠPk;}m HԠ7{<k2~.HYף)EBXܵH-2;";M^ GBNfˀVSTd2Fw HJkQ [(AAh~A'c\>jo_5'UuuH[39=t+*u^p!e z𐰢ZXQ(0Ce% ʬ̭m( Ryyqb@Ȼp~Zⰻ1K8uvL\n`R}LNI%x()ElňHOH ó(LnX6cɘ#n#uI\F WQMaN-j{U:\r.vҴiE;LUI(i$VZcz#eE8 4 [}KeO.ظߺc53 | =9 i[)W/ &1A^\>>P~SnUMK`\~4p_Y a+b6PupN_T\2Rc?S67"J (3 cԐo/mͦDE67.&"|bBpT: {N7yxގ\$ O1f"5y3Qu7a_(=eW/4EO"VjCr.7Vʩ8Ԧ*hZ* 3k΃w)׵h;;Ϣ!~$=~/^3Bv\4]ix M'Y wp8 A@ػt&0q^9 q@qJa7Emo.wK p4fjN]|Zy(fYY6mψf<$-VZ༱m]PhMvC8=eG3.=y^ilQpMG)`j\ڸgӺn@md@MYEf|EB[en6 0fb'Ijp^+,+/.)2vhAכ0jڥRܟ%Yao|B/*:/Ψ/jDJ4(/<yt_73G_t >>8ZE=,Qq U KE|9MM)Z_<! fL};/FxM5.3xhh9BopCyNvN^'_ _sveD O  6G|cc*UJ׉NyXgs1x! u_%IĠ> o/Vß^n55 j wi᭦dV'B)%2HřCښ@^̠w FaXo$ uQK!uw.hbCӌ+B9+_z2*3dkvN:NLQr-{Q̇IJם(:QeY zk($mܔjQQ&h\:v!w_zno8 87Hgy2xY+~eٴ+^v&{׹3wLP?5nG홅َX[NZցKJn/RjdP85ٶg8ihNζܞo.K{$ֱ-p']d%w]y @C*r*OaTr|BE3ea>V7Q G:ϱ~k,) ץg,aVdcffژn='G~mߜs[O#=ݘJ%Lk %$h56e7g5mr'`er+Bs@HL,F ~Y`zϢ%ђ3h*DkTX6!8w.3{7ǑӉC;o4.#V ` K…'3pal pȺhV%/]tZWe(3]$8`0x56u_ jNVV(#<\}ax1ԢTU xcΫ/FŗU1؁e%5@C%C1ͺN -*PCaNQLtb>Bd9 lf{%7jz,9=3euҚ@KՅyܻ!cF`a}6 socA ٍܟr2srӞlʏp_?:~lۑJUdPԆLT12аp`n!MvM 0O'T $y7`YtV2rtkB*S t]S{ekb`׿:5@g(J8Ӊ$ \K /øfPoڤkt5:ZZ.;݊qRbi W8KOwJ"#0-߉C n~:wa4LY ʕfeUIkj++Ň7Ơ%ET=?,_T0?1x |hH"Gբx%4IF=0Ֆ ֝;v4^)-sSt }U%%_C>uqQLF`POU@ҽE֝⸗`\&^,=Kf 糾gZt4|&Y fO9dp2f k g4Rjd ?bmvւצyc}_(qDŮ/<z 7 F^;,{USB]Ѷ@dTM _w0?G<3L2^vFjJF\9uTm!_#)60*rpGp=mh7OA2ddEćS ryIl5_h.Un+}y 6~Iad&?(Q0\[i]/`of#&JW,:@|ڒk8@@Z{I΢S*2ͬ .ʒ$S$?Dk%^‹άŰoR \!p%{<Ktx{͆>X rZT,xP+PyBy7{\ p=nP' 4h [;VcvCauؼ~yJ<8v8Lg|W4]e&4 hئ:m[0S`nz2ص/K߰v1֞6$;Ȳ6Dt+&%P2HaQȶ$zQx?q@O5 Ρyٕ9qfO)mZ)1Θ ̽'|܋)x* Ű{6(EGhL"p9t`n<"_`4BQgg4&>n ]kk%$^m)+qtzv` }n~˶hjnâυ{YGLS|D>h<}$ףD~ _;8`oS*ɭڭf?brPI;ا-H(U+f>ct`oGƨC/oG¼WIo_8moWC('_X(]Fz~,;m@?qNendstream endobj 83 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3391 >> stream xV pS׹ù0&EDBڄ B %fq1 eٲlْ}V%q!(4y#LK{Ĝ̼wdfھϢ˦hKSd~(~gssl_ф'n<8p+^K^+Ql[*5;_/3c'OyAGQuZK=CͣSRSBjF-S˩T%T!8ROhʒ5!ˑ/'?cUCCn3c }awö 3|NnN,܈SGlq>oiޙc+;&7x5&0uJNtJ#f1?si̇+=(d:!=CrI$7rw$xD2f!iPpEVL**e~Cgo)zRh&hDz_6=GAÿ;B4n+^׊uş̵_5ۜ-E~7-ܟf^K+IZI˔&1*d~]c65ښh `.-D>G3,E J"[y ?(;n8/?hCFHrQ*eʴ}C*^Mg6A[Edfn2b3Q.WQb@c=[v,^[y=jK|~$Y$GNѪw!se%īz/3Ǯ:w:9[dv#a26d:]+e 8[<|1ͯxVl JO2lY(HE {!#}Fh<=K0QgAN'{Q 3o@&uWaOql`-Vh W- >c2/r{?:Do$m)TJ^{s xa\icp¯+krZhEhbUR\Q$j< @g5^ d5 &[P֓B䰭\KQ/p4{iACgB\Mz/A& XO]bWl T-Xg7;ǡ j^9]P< 4:]Q+ڪp*yF*U$£qxox@ ƔrbNہj)TYAIީst?#R{~#1@㓟?LpD%\ko<;UTV\+>"RW$J֚&KY h ۴]%%u~d^K|{`Ŭ)ԙA#dT2f̜Ϟ'tp#w[4b!ݮhR* nntN\u%ms;XմةJ|ήQd9'>p nx+^/ 6u<~r wwңo~ U}be&# (D] `+翸5S`4X6#42K6Ι;k۵ ]@O^@ɬtrГh ÿß,Dæ{xG =L=]:p* jyv89kH1 o̙Oyx>"23@$0g7~4I)vECZB>]9 @ 7x<s(~cD붾--׹~Kb?ar*Cw ^G7{"֎!b`<+FۧV߃+/mܤVЇ697 tzdmA> h{2󈏮3HC'͈L@kC&Qix2?wT:܋(!f>ቝKNr2 h6ɴ}*w|41pIX7ĹҢeӚ2q502d -vkmͱ{ I qx4]34 DPO`.L&+U% ":̯FCW~2ߌGd MP$Ygot>`$DHH.m+#cQ[F(Hm,DK4j">O(H77gn)8Ao' wi${C~*>ADE{%;fἍxO3i-!c<-Cc LP%^z@ ]f/~c8t$ɳ4*9UWJNfg0:mQ:qf|{Z6=P jF }U>u]-4ULBB|?24A+H/_6JR¢WB# hv?e> stream xu}TTe0r/T\gQ'PKRAJ@@@AP@f7ʋˋ/jxlkC)öm庶y<ǽ3;3y~*Bp ]cҥKn@5?O8l%̞Q8cÏ3C?a}65|KdTt̶ؠ㼖"0o2L 6b|_ƏļlfV0/1[gƅᙹI2s&:;f\uʮcs!\ KHp}EjCc%e_,!O J*M=/Ы?"?E-[r/ @AOAoz~͒+~ʌ u38ʓ=N8W R܈Mka l E^O§.K`:S 6e5%wE6E9-J&DeHNmO鰜%kQ\.+?.L T{fc[xg @5e)* EY\6;/?Ss:s[(+`IWd\Otä9:fW)gˡj x{MYAۘo̓f6ʌ{ިA,?bVh W.i12l,E5EQ`o"$쬼 ȐNjmMnm>5$MͦLQ6F1$c8m"\FYC~\2yZ_ܤ,Kh\0]M8S?|RH=1{&))d|W#WTBMu9{G5;ԖՎ3ʦh G=Hki4vnc*ي}j5Cͥ0 Yʢƕ%c-c@Ɔ<ٰ'<5:Bщcի 3MY%ѣ~ 'Y: &s8:s7?(շ@'3nTaa;[wRu*v/ u. ]*~\̽)hq[5l6UDQJ)tc^.=N59җUkCΥOT\N]DyL W 2 FY]\hGDU0:~.Y ^ӵ':H0p7:IGuJUgG6acb 0vLea_]9㸥 W\c /5%5CЁÓ7fx!TOL6}\\^ZC i9aAi;@H}4[ Wky-K^W??~jC-yTTZqAUi Ӊߵ% \ę56?"60:EGl '|~tJi-yrVIJ]ƱؽqY)jh05p~!6"8 ´8*bK̪7-U} #I Ai%vyw<4r͍½Ϳm^AGAUlc ؒEvN󓘋KL{tn2K\ٹ*KJ[he\945bIfQ)\=)*PyiU58᳇t,s&F 49n^,[]KD6 Rcߴ~GBF麊+鍓?>tI)㳗qk(xkEڨaਥHW{~po01Ôa~.Dvӹ 3;9d1̢ 'E%6O,Ul%MɊ5^4BK\R{ 7GH9G˃{ I'*.Z5U[Soe/n\ʫ~~FhA&Jř,1ɦ$Hn ; ZˁԥP׷Lޞ! -j2o߻} CDa[ieZ+o|vok_*w{u&hٴb#kg;1ؠOendstream endobj 85 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 870 >> stream xoHw,!Y[vi `C95lX61h-ĘcMfܹ+su#mEa ܯ%ϻ>:P(47;a2JF}XqՁsKoQItoEg !3:9t5!XdEPv)P!U2p*ip?G|RH˧AvF6xi.s32X.ofsΖaC`*ȷ *м^߯6Wj V!IO]lފg~?@O|-|pS}YP1,2J8 4I=I SE?caj;½}(ߌ c^N_f%oDn_38qM7[^>yqϰpzr! 7OlgZ.-m-`<Ī eһdKc-=?f?>6`r])\NpVfCo"<<-`]]JB DDv^Jݾ7-ތe3I+O/u*eZU(_,.SȚԶ~AvsZ~{CX+<]t=6su|&v6"yhMt&+[4q >xؒ)OdbXqY> stream x]ype;]I(Mp5K۔I !m- 31q0p 6-ձz%vWuXdI6`jmR(I;=δΊntꯝ~{)U*))){KUK˟zBo }/W޼OR|W(UMf]K}]IdVER'*l씬4HJ$$ՒM \rdEғe+~ס/m͗//=Z{=3}E7KZ$oJ,wR%]2n?3zrG`r_80Zʡa%G)>Ό$/r=4vWյJaCj8s=~-gIڦu;6˻i\HϏd dɺ}%2/MR놇A@?:!07Q藻>zP)um6O"ؽvhOR8 -$!z"V(2IH $CӁX`Ѱ3wxev zdq gƹYu*Qwtz\Yat-ށ?EJNM[HE\װ }RI넌e:Y0 @&dZ2Hp?ƕzA!9' gci0ʚjX^8ŹɑѢ>s3l\EA34B[PUg[K bőCWDbCwL{yaw63fNKauvJfW8m9{ N)H,y㿌(]K?}p R=gbp%DRLҟ.uf]eRg NקԪ#SdLD:7U_ITO7rRo׃ DcT*E>kOG$"SL2/'b@E:V.ґj45}!s!yFF!ԭn_̀ d\ʕ2x] SEN(6tW:naD4=V_VXWOUGLTC]WW\3S,ɒ`CܸgKw TԱƷ`ܨƗC Zf҉rZ@wh >#nwםsL,\_:3ݵLx½Ŋ)qz /JHa0QpTBLǭ-_9K0O` NmpgjQ'#oKzΦdazlVb9n.t_z- J+.%s\Pw[]6]C%'8'w: X4 KUAhwj;:tЎ'q[`&>JvdG"'? dd0F|(?L~*\"C"3ƨ^I7K~{^ZkXbԭZ;ijgmMPim<Ŏ'LRF8%}$hn:K%qי"⯇팫R&uc[MXTw j5A%3n|gxd6q14%?G]%>HDVG~'@dj!Uz(<#*ؗ'?bTpqЋ,jMj ]bt[3pf.zxL9|6G%f@f8B0!O0C'ߎb3;͵knV-["7endstream endobj 87 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 8108 >> stream xzxTվ!{o{#FRH4 f53kI)&-D$ (XP.o y߻d^{׿ʚI#zG̝h3G[o}AG8 #aGܟi,R쵲*W.ʟ%^=[fk筛~wr ͢_3hܐ&>9W_1bQy9D#!eb(x% OoOoOKpb)1A,#^#Fˉ(b1NH5|`s;c~H;~wCsr6VO]y~ h$|P[c/}yלza1U+gu}&fQ&M6CQ',W+%,oȯƙnv8q *\r)~iS%ќ4:c@Yl1AE4Ri3̆1N^+(㌏3I]p&G=0E1~Pcy,)0Ts㷍9kN43+=9*1Cˊ2@I4L3h@^B0$Wy*ڋ*:wa~.$߱ ?7::sd\Sg6fSTL+ ;eBe 8*-g~2ڄf 3Iu'on5n'ݒOn)!hH7Hx_^֢9|K^y{^eE+nU5ݑIE" n Pd٪5%Qϗ5ҫ .y_f],KqE T㞖]޽{^簗qJtJ*;BVy poC(>esqw$O[Ɂx0̓ ,ZG ȧgyRo(َCuֈ2wu}磂\JPdEO$ qEFB~Ϊ{ ]BmcQ3_}3<} ?gpWLd^}k9еԾ (L+dyJQP}#'ɐa3 p[)K f#0GfQPz(lCMU ܂f]*R ʂ+I!hO:@ūB̭~dB+HA=^mzDf+̝Curxjt?)kB%J@ޮT$R<lv-.? k9-[3rQ"90MΜx4ؾ0vƂyw# /]a,ϿْfzU!;_F|;q7HWϘa9$ #L? ;N=s:3?Ip"l{> +7Z,%|?h9[-.2A+x_XC5H@E>܉Zy_X (C4z^ dMԬ!U Ћ(ب*O4AZUFѰ=lKmu'7P"152p:CĢ43fRRH<{4.,1IO#r|Dv(6)4ڍ?kߓ)TWLa*@H4Er΢WP&]͛,v&. )dJ%1 ~|cY/$TJFOm@%K&<MLaL_|N@Y*nZ}X{=[iXU3_\q]qCHJ%ﲇQ>7~auo bp1(+0{/{`UE< \]`5 ;ɸ  A6}/hRWUfaag" Z(Iٞy5~``m$X8Ǜ,A; 8)dmd,ǥNITtAc`E` ڠ+U+5'Ș7n!fc w' #h do~?yr<߭9nk1[,V@[H}M@R5!K , gRɉz1qi]C$ZoŤbe Eo櫪#G`6ڬi p&}<:5ssHD) f^1dЧt+'f;G]ddn%*3Θlz'fbwح03 "*,2v)bƷd$Z"0Ҁ㊆!`x{<4B"6ƋW;Wa߿Tu,ჸ&QVO*AC6f MFOPypny ЎY p rᱎ~r:mqKb@lzlRr*jaY܈Ssrt%(?x9۩0WSZDK%lTt!)PhQcEDCn̛1*L]TczJ( !3jVȌ"& iOa%m.ZA 5ri2HK>+ª#:J -4$J$R>ƦմkrZSt@SԒq=I(VT .{}} 7߰A[##kk\dH^,p*ɏ``l`Z'aDh\+ ++?sQ܇jLDѰ|>viS1y`%= =Q㇭au'V$Рg}zSUWw'ܙuuӻR MHd=XOsҶ[0 fQC`/lmwD՟VetǤ&}|ȫe+%قiӅMFCWF&]XlR d%NW;3&KOxa kJ@)-t*dZ[sT)+REk~w` hp Vm m $ ^O]w=y,kB;Ģg†%}n> bFnXQ1_3EҤj嘭q 93HS2Ƣ|`Fqc'oK(62oƬ +/3ʿ;DzxmAl-;Rߓu^o8թ$.oqݒ"]DA%mFlLq i2/ۚ-)oUW͇4~t7--/VۄH%Ғ|yp"ca[}4c3(R6QQؖN c#,\XƁ9Ghs?rzOepYP;4lf:vMW Byōϛ=\#-mw[0kuGCP|V/>n6R`gkm5l.XZl Ш7恗 6,7̵([Um9(X)Qe WR)a(bq?T+%2JoN^ L/XY+cQc=1Veg.`t[kϯy隝uc,dIq'Wp6H2\tILUAm2 NO•+DRPҭCN>vae6qt,?0~ Y_1/^( T*lk< {ľ2z`ÇWneڷվO;)eG0sIl4Z\s[V7۠l4WƺrU[m1@-pmwb<" icuuoD"oiZcVO p3x6P`}~E@jX76aa~î<yO1O4JX(˱4idlDotSchR>aasbS-z* aFUhk.,2SWPʕj%f铔OR -&fSTXU*걒F~ihA5^~K61_Ms~G,6 'W]?) :4ێ:~Vqʶs'ÁX5~QLdbxo[Y3ןx+ҽ]:c}ULMܰZ=gȖ`\X-0h %p+lvݖP 9Ja.!?Q@nFXz~Hl7$W %œ~Sנ@jXR*2K p awQ`ŵ9̺*أnd\q`c5]*qj z,6JKTYP `,cph.&˝TRcR&'#ݏɽH^A 5ʸJAXexSzU:5ΜF;Fab oU [d50)r8`jh]b}J1AP4,^ҨbŰ3rR&pa>]9]1=_7}jHMDhiAW,*YĒ86) *AQz3|0W1AϜ>KH\ !Vڇi`E!eS)VA{ w6e7|K[ͨtUGLt Wwh76A~ B%tbA7rNnF09kr3ɍ1W1[ڈ^AMq3rLM"H¨HD_)wsdhE3"V?+D;>C΋Anz"rӫê;DV`1kVI^p<6*$y8wImsFAȼ3 g/1QH5ZPNˆ)ʴ& ^@שG;ßL>株3bkWB5[Z'G#͟Li^^D# ZgWmO^B- FN\ٹg/٥ofГL8)I5Vc!%W$2vv. q?[aZa]}m&cGOYKkQ!XyF1 Ứ.ӷ':-5iקG臻pg.8]0]8Cw/B. /&]y*jZ 6˳--kW[ vټ+:)W,Gk*eCBL3J@5(ּ֡lik%ߚo0޻\Q˱ڣs;VJwߎ/.LNo:tbM[AtkIFo+kZŠ=Wo4Wx3,J;/>H-Y`$xKrg9 i <>6 XiPR2s_o Z}.tIB>Oiq1vS3>[p xPZCWS@Ukj.HZMfo#o&י& r[/)"&q>,j_ ܤޤ洀Lϝ]&8c| p~C\:pŜ NBѫdCJ@9@Si ȼZ.S2۫j)wc;0©tw&|8ԫ:/3i83r [ǘƽvр/I_54Cnp8) 4,|iw;K>;Ք\(t㖌]6n)' 2<z^3qʁʥt<؇>T9T9JL套]Z4ތMJO9):Q@i)eG>EC`W]FeI*7ع04uRz%jPcb6sk.Cq?Ѵ[چ=6x4ڈ% JтG_*/\RP@bMtlV~|Ǿ]{qʉĘnQ;;n{޶ZJ hN8z oꏈI Rd8ߪ3t^h Q# qp$%v,=94)WmI PϽw38Z-`3>zT-p'9m~W:v7puZYN%`*lу#>LlAkg4GQh!DݷgPeU|N&~$BY{sT<_.exͩZ=FPVCp,ېRuᨽ5G^ah)!pk-X$(-K551Ч?ف#oٵe%یtph[T}0zc qcV%q<(b݌07u.i0@IcmgV2J佒:6c.\wf)\߾zDWڕrĤCW H6ѐ:$ϸuܽ9g6xGqJLz^> > C "EAV`!)B1Wh~NS!Cɋ~g5տۭ]p't>*E4g$\8=К5@;. ])ps~ئm%UmAC0Y9kjr X{*/W@:pTjEITJ}ڨmb6$FM|ʊ7mjljlvFq@U^$$e8c_ ޒ_]ODhzמh=QYKC42 WgRzMLendstream endobj 88 0 obj << /Filter /FlateDecode /Length 1770 >> stream xXKsDrˆyk&P[a9P Kvu(3MǦuOA.k˹01&0*8v^ww/Nޝ8M #󜭵^׊Y8Plݽ,ڢE;۶nfh03}3VA IufyR0{Ъ)ʫd %  ݹlxK 1F.~?| +t_:,uߛcN8*8NJ;:\qVvԿ*P8&y;Z4"PCxѝ 0&Yʉi/!Eba9 &M"djg{F$)>`>}w}ʫ Jr 8dnUC`($ESn~ҡ6 ڢ+kQoبؾ=L?tu)mu2i |'YG]Y 7FP\q Tε3di ~gklk1"y5cr'U-!1: g -B+~rH_\Tx"(Jvc.*¾i|rG%q‹[ >`;v 򸷉&J  Ew1>ߵ0̙8 u_ChR\`/3y{̦#2 j}Č&ٓK5mV#!ۊ np! ~}5]'+{zѐ_/pʨ9Kơ9~Rem߲Ѿ?z΂>U-ⰚUx'ٮ|kߔe ғn55 3}Q6PE7m>02&Ĭb d|=m~ȯoBO2*OW MǤQH&[}E0 k9f;8`=:' ?tm9u]SYA*bgҙAWeH] G`V0/4%9@hӮJZq81-í 8' 1u/eUuՄ$:D%BҺcAհgx؋`:E #bB ,4C$C><1j@-|`X7H#e48Elў6>SI4ȤXq0' \MqYD܂@> D: -pm~]@mig)\/v넅8zfw;z.5A%/߱R\}MMX7]c}ѧ8ƱBiᇎt^Fh?%ɺ  cOvnNq%/lMpViXSO(׋_ǫyendstream endobj 89 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1344 >> stream x5mLSgo#:i:@þ,qi622Е7 "B޶CKۖp[ [u*ZTE7fd%]d{N<_s~") (ܚ %R\Wѩ뮿M9K*j|A$ =D#MX/G I tڤ=IC63lƹTTo[J/GkCՐa+caA֮͡!;vn@vAbQ1*`IL*cW su{RAgHģh9۝D]W~=VHzZ 8$x>A^aL٥8 U5hz?y?^n~ԯ7WicԴk*M0=Fs*#lx+T<;܅EW2co5ϝug)91(huqk_%/ѻ3:7BU [\~]4Ut /bάk}0UӪ }*yz\86]<:@jZD=g)eiufS6V~O`MEIV7թ-}.\+]r>_ѣH椿ͥ =qkԩ0mx7e&Tc1űj3mSM:{__]vul&@[$їR_J-L 4Rv><|3{rCjc؂•I%+O7n3 GaM5LIO9"EOSSUPkPBS YM鎄Gz.\~0gnkLzr{vGC<&ss>(uUxz$YcEG9W|O7SFu|eGꀾ:nrsN{܅t?@”m !pb4dz9γ2)[t%$zw&endstream endobj 90 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 5111 >> stream xX tTU~! |P1vkAPdM5BȾV%{խ}߷T(MPIm(.- =jێ-1gV>gz9wsrw}_EDQQQEk=RYYYBJXV1#=w^(CK&ۈԖm %/KvYS[߰y̟9O<9xG#UijĽj>b-XOL%/C"b1 XF V+ ('DqA QJ"Fc8b<1(#n' qhBQ׈'Gd-fn%* >HP*/~f{=c.7o[H6ML n^{oϞ=m&h>S+ thI* %PE!IR&|'dGLF> 9'ݧܲq{6umFh4sxVI54d'EU94^TmCy@)XTfUE9O_ݜdpIfI1p0#LwH$= e@ȰWڑqfl^.[ڮ ̴jYgha/A'.$JХa$("W0hDRtVgfA`0օv"Za~.crGQi{ҙG˚fFhjnke+c~&|$f$2 L3PؔvS@Lcx+H]jgws$=hzq$Dz z4Mu; ٺ6|쵏>bژo0Gγ PoNBT[0@ ջQyV%j:H8A/>>O(pΘ.xAUuC ˓`/MIb[e0zAgLRA٩ y(~"<ىIj;jUC3:!$s$0ܔkT| 1_* m7  jWiPz<6wE~,v]Tw<2-JMfm;-$@:HN]D*T+x/7g1 ww[w.>L&L׈7<9ӹUQ@R+oWm;I4Mtxs0$1"p]\N_)% k3t7`ghdZUoPpP4z=@N2?_,͏0It졍gfث YH@v"_w]^^R6vtU ūN\ϯLYNC0`I7wdR1Ja^Vϩ iX2AD)oo!KO|ʠg.AKuV?!*Q2([FCsA:%>3JDK)O+Tcx_L/ZҺVvvgZ0N6}e.pJrO.QY~ΙI/Qqyep "2"qHDcO3ж6R H" yÌ d/c!XfJ6ӿߗ9D1eD*Ps]Fʘ,f _$IFfND)c7ٱ:ܠL(b/#[HivTSz.pL˖{-M 7ư(Ϝ8sY"JaºN 429.LH. ҡDqprrz 1[ݘ-V`o ,#=4*GFouZO =Tvq)>ͽjXt c@7q@BHYرl)΄!ٱςn2#w ;h#'*:|MzE*J`| *БyITz X.2T&`3 ~ Cdg®r#oH2t qy.l.:. WM:$sCLʝJZaGgyVmZĂ%۳(?Gk&R2,r -KtRͥI}BkSϾZ'Dƞ~uc:bAT;~1= &2Μ HrCW_zR"ztKܱlZ;p4A< 7!5Vykʴøݴê&Ow9/9Svkb Ɉc47qѵof2nÛP7) \Q˾}[N 9TCqja&T w,.J[d&l?ޙ~>X5!H‘h\S/yuqi@;m̃S&df*H\͌ۅF o:._7y$6VIJZLx %#?QjvzޚMkZv<ߟ2kj Y] &|qhvqufҀ. [O&Ɍ# 0 ^0ݾXwhOD0CrJoеI? _tq_ӼDLƦ|+Dz|#V1Ԧ+"Yn)~ųjpjx=h=قh:t9z@Bs`8e;xKBvC'LEeU۝R!kϊ>;n^WQ&(IG)%ςendstream endobj 91 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2586 >> stream xmyPw{1b:S !h+F+)׃qAE7} h` .#h&211 lW{{6</$6je+ ,D39&a CkO|e_:/@(%uCzFy,$Mfb:1%-DJ"V("x@oPmSpڲ>^zBƾc\,& 01]4kՅIQyi$1RF?- Z񁁆4K%ZVhv NF/.9ÙCq(nre8۹U=%6QJM ӻ;{w;J$rʨ&<]0X;U+q%鿄i™nLXY sijTA%26|17ɀ zu֬d6zt4*-n#m#; D6=i(tW# 6SR8Oxwn J.YՒX6LG./.AX Un/raIn0-G<5:WDCZ2-(8~l\ޯǰaQNCW'q]-R7Qڄ̏;޺u%6@c>(cx9Bqj֮i%o?æsi@K4zˬ@TZ) 2-->*Vl)R,%zЙSuRNpYQR]zFWK/ǹԚQ/ݿU8urIO5h;Y1D8'O}..hv P `Gf!Ő?+?;l;J8Uh$,RP j: o@c(r%T*JfYv;g)7)v%JbwFA4l9Eu\:]ফI9K񜰇ʑj9ڠԦB f]g6TI1S'CdV^b_m&6cil^MfGQ E>wit4$doGZ-+/c`ckJ+KuTȇ0l3mAUUJěe cN9'旄wbJw'Kw殅hWq7z[b=eX%ޟUⶦ<_C/sŻNY ~lR.Y7z_p/o™{R-LV4WO8)M3ssL+Vʬݖ.䱻chմLt-y>ys;$]5GQ ƲƖ9V3`*Xot J3XH\ݛ,cjAi@ 9pV8̕TP26r ee}t Յ{VjJ\5ёG; Dc(r Mf=y;חۙaOOW-B)endstream endobj 92 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 156 >> stream xcd`ab`dd v 1400q$2黲!{@Q!=?}>0c]Bs۟~}O&ђ >S{6us,]@~*}&3{ry%|r\y8T5Kendstream endobj 93 0 obj << /Filter /FlateDecode /Length 2391 >> stream xXr }Wtj)+^%rݭM2Tfbσi+QKz=I]ڲ7ܒ@JX%ojӅo{XZr[iW7/ Jf+kR.Y.n\ix(e9y+FjE43Eߖ*˚[nٶ*.|w\I7Z|˅\h+VWBفYӸ=ԧqKT^S\0aBld`"I?5,D3 EAĤ|I-SgwZΔ k۸k>_X>15ii ΐ m(Nimsa bsDx[pfv(Ysgž72 c%0oaUYEwmq**=c? {嬫xYhɥQy< eߎapcg"mQ례sc8^ +;Ǥ萄'`v,K!&xD{ԗWj)k&ƴOPmjͩ%@7>c83ȹR —i-BeTd6jd1E~7F;g5\%²o wLm'(ľj, HSLx]()( tuqp;lBn{[\8rQ:w#PƟ>X tݻ-&' KGy Z{k<֣{R!rr|ӺQnN:o} dy4zc\dR9>O!z7v5naQ@cUOўتxe!P-H&fim!V(Ķ[CIZZC){NLLp@`4I0AZ & B[H渁AOpC9(3>@)\Th f=)VϧjiiA`/Zn P{{wcpjӑÙal,'@XIxN@RGJ!|L>kFkf(:3CY+"n;ⷐPe9-̭wѷYnpUw|v&)0>w ʞӮeDf'&ʫk!+輅jk|`% =w*eO vDi@uS_۵γzAM[N+S hNq8E9 C#bǯ$<9`7N607 q#i'f);[$RQiÑ⅑WB\&hk#"3-˥Ia&xij4bTr+1kԏy$%t-8Y V8"P&Es^(fGO,lw XsC .g@L=p%YX%WjMcU.}ѕ[H\㓤R@;vCXP~fL9"_! VۦWCZ6rE<2Jz͢5K4ذS]nPc`h.T/SvKzU2`ܻP1 YOold(JQO7>DBnxmѹa &S \ İ׼zE2| ϩF0&}+4 G[MV}_ 'эjP֒p4jڐ8м=k{a$LC2;hdjӜ/ {*xuЫv 3]A5ƓTU .:۾lEI}* q(<oEo[4O@ uvM6}:Ž)p- g+NxϚGm endstream endobj 94 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 146 >> stream xcd`ab`dd v 1400q$dbaa]R~= >r~2Ft''%'u5u6t7rTM^"c˾HLX8yq|>EUJ丘p20C".endstream endobj 95 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 142 >> stream xcd`ab`dd v 5400q$baa]H~= Pׁ? 7~H/(>GhXKdiVB~FM|w> /W [ 1 3 1 ] /Info 3 0 R /Root 2 0 R /Size 97 /ID [<7e63389581711d1a1326f5459200a656>] >> stream xcb&F~0 $8J ?@> m(^xH KDrٿ@$20< "9A`*d} VyDO|3"A$~Ad7l@l@]"5|7 endstream endobj startxref 76960 %%EOF Matrix/inst/doc/Comparisons.pdf0000644000176200001440000023653314547724214016256 0ustar liggesusers%PDF-1.5 % 1 0 obj << /Type /ObjStm /Length 5038 /Filter /FlateDecode /N 97 /First 816 >> stream x\[s8~?o;SSq5:ĉ8;ʃbӶvd)#ɓd )d)" tn Kd¹MT"9Ot"3Dk0O$K8c?k~.%~DUppkP%id։L"{6AfH>K69NDD1/DK2Q֊DD3hQ̺DD;J\b$%Ƣ%K$V:keJdT'Π$jt&.3Lj<ϒ0F%.Q<2[ La43@ ep =8JWD0ȹcH%M4)(Y ԋ2PY3d4d%H@ E JV"+ J y J "keRdm.P@os#4(CL6.C(2kYNDblد2dkMsfEɎ!ǝ Nd'H2%/,q ;Iu(e#0tD@cP$%)J20" 6\ b>BPƁ'<91t~5Ij$}%l].FIHO-Oxt&"7*Oy^=ss &yWuΒ~ƓY>v *2LK2t'xz_oM)`'*r%~vJ=C"7^ E7b5; 9vT0hL&n>_,!ubc~<>J\]_k%c&ÑڀPsYK҄8tMi{2eȫCV>/{PVFlW֬ˢlW㹭< Դ$Vw?g<gc&%ow˔ƚ!,Fok0. 6HM:iCrJVuТЂvS1^9:|YY&F`LOd60\| Bx[@g³xSKΙj^xkuJV1 N1/^^puXYn[{4Ӗ?O`(OEv>-R8]PjS,Ku{0F1t(~9+F4VG ={H*#ˁ@Pzc/S덒^˺|3ZH*5/M} SoZҚt6d<z룫#.IA87VѱxkgUXzCQƺTLYju&KXOXT2~d}]G4eIh"/yWC<@_$.u| hezS:/_+vdb 0{lJ~_tUشޤ7<ܼBh%m4\_倶I H׈Tv4jmTKgaS׮4Qk{;Y6ȄM$oB13&[5a7Iy;siu%JQ籋khfq-hfqY+M"wZMŵ 5Y嵡ŵKT.)U =û*&8cJq{T^|[<^n;[s[ta]+ia$Q;`drq['N)={T.TlCu<=6x_"6զHIǃ׿ klg3?Oyzأnu+?^-ZGaވkiXp\̵;{C̓!ˌe4 8f p4FA똡<|aZS6y_bwh۶𫰵=opʥ֭/|eEudr=iE ( 0niuk_i쾍8uQ:Z]k&_=?> Ȫmt>1?oЕ}fX$js-5a#oG?[\B[3:̄ 5(pam@@j=n ,}D26pZ2a% *Izf:_`WN(9pp &4P_fTZ@ Km-,+I:1) nXEkYթR|k"P3DrUTr+4TY?,]r)S̑#80LI) vFNvơA7j>~l_ߵ:J @+Ȥ*&@)%~@/^̤M+x }}@AOV) 2Q8K5PWzy7J\MK%| 1SwpsSLY.woZ/T3r/Vx[wE4-*p#" Uš)Pwv^Fᇓ _.k> exMH h5@Rt-8*b둢 eekwچ iÕ +k?ЅI[]2Z1|i7V|#vB+Kp4?JY1%M)IsW)6 JT- Qz)ZTKtsautX@+5"7\ߟ47ؤמiw }{?^=endstream endobj 99 0 obj << /Subtype /XML /Type /Metadata /Length 1388 >> stream GPL Ghostscript 10.02.1 2024-01-11T09:36:28+01:00 2024-01-11T09:36:28+01:00 LaTeX with hyperref endstream endobj 100 0 obj << /Filter /FlateDecode /Length 2668 >> stream xYKoNrr1"9iI b&}# V9fZҬ!OֿWE=!AbUWUYYK?bs.>^H:˿ٛ?f&}5ۋD"g҅z?s6:'n~6A[+6s;(xҎ8_іVNz+wK-56xs::p-ϏS~ Ĩ5s2F#jr$0^0ՏIDkݶrvB%aJ袸[w$,֛'VD%&$h\*+ѯwG~;Wi҂lSm`}$Wzw"{e{32 Yxwb]/z1ԋ^;ԋF!ܔ}b:?O\<+M,s9*:6:D ho'$O٭=)_tBdovZ 6At^U/%$6 yGD ^ka5Vma! b[`Wێ QDJnv@;;~w791 8g^Q$9(E_"vkooN9qu,1RY1PB„}.;ZB[آcd&תJ@IG[O,nwMj8/%K7c<'Do/AcK{Dx8D&H=EV7+>o@i8vY6 iKW{0̾vejvX"oGemdH'&2a s:]d2D;Wτ An[(@}ՠUw7)id45/(40%NJ EpbH^$/vE@LnF0?.KQŔ~i" M0\qខ%6z]1|6ݐcӕwt|%aj"iA /ŘFQȤeN(26ɳ㕔(i/P1w}a_d,:&C<mT*TJ&B[F=h0Hwb=>!b$K F"*F'܆ *1.D #^ Y HTpo(x.U ksZk~7X$D|-\H@䨌jKGa0$ Ǣn+$:"lc H1 QS/UTԉD!әT4q>HU0Tq b (Cn΋E>RAG\cqBVRVtd0Qq 8ј*THug@{/gu)/)݊;cΉྑdsM[0,לݪEL#k첢B^ω?b^#p*SV 0JsU*`Y:o&BՎiY гÿ9DŽ30)#x}FXe}(}=kf-k8F@~f=#G1u\kMto"L udԵ )ROة rrT7\ly;ɅƔa**s';& 5w9"H窔R%ᓥnjC@$qG5< ͔r4g 4@ o~D]Pm1g%$B1#V8\cԴhY'$ Z `M ݮ4K$WY k04kNQ~}q8, M]-i) Qi *fkAZ[':(K^ EBMBk{rK[2#nc-umJPjCu@s#?ID:?`9c.0)=vWN3qWb~TS#6?i&Dext'!^PC6zbV&w n) ׍2Z:򯆂ea|խNSq v#GzV82 =?U/E~ &࣬xMãaYҦ//QaZ`Y4!LjRXIo /tbtl$:~Lԗ݌1c'3~e5bV7ʔ$lIW`6+ GfMaaHbjPғ6iFFl )/G0ELs\>1-Yݐ՞hfљV RU9"TWys* < ~4W>V46y?0w{㲿Zgݺ/\vI줲kl&e~Nӏ(hPE!jcC;D? erl8쯧2E:(Y8Hu%o݆hċW# M=*zWͺ^$%nRHl?/ 37긱}wۊ &]¦4fhQ;ڡbpXW[>1:TC KYs4q߮.Kendstream endobj 101 0 obj << /Filter /FlateDecode /Length 2666 >> stream xY[n^}h@! 2 ,>"u\&*ZĵY,R_slErΙsůEUx~Eg,r sX _p)skh Xf ;XfҪ{˶yޖaYR^Ƕ>FYX}}ɼ(`2SV+Jip2 jQ(Vo2[t!lmM$**.}(°SytV(7yώ =N-P^ $pI9ٽ(٦jv 'fM"vd LR8*w%5cIpQ%%nPeCٷ9 E!oة{QE>Vwձ /$ݖhą]:r`3\J|n8 vGm<:pԼn@/Jcm$(p{,M `U>s~Sv -zWHr\,1PQ`(r8"h?fD<i҅'TK7|%~`{wn2IM R܀|QgpF1r(rM3C1tQce&ꦺaru^k8E1{>Եl4SBG_=u^ss_dd+ $! HeʉfPږ f:| x0ba6>"\ʕ\Z dG mL|s.SRũh:OvIla7΂\9 S/<-8%C 5Qǁ$0mSL20 >VԷh >*?Op ֻjQ`cQv@ 0ƛT gʸXdzk>UfIrnr1,\-~>,HFO#GV+r/Ynթu[ v=X Jv|Zlݿ]'N67ǚ=U8^Wd~8uhO|C 2@C/?Pjd G _0NwO78S ,q }yeO$Ml%irp3FZa+(c43ǡ?,_p9 \Xxޕ3TS>X6 ŤzLSu+71&ܥ+k^{W{ q9."јe~hf~he?M91Dw> stream xYKoAXp1' 6M3bV$$O=IJ'>{U_HH_oIg[/[ER8!I&,Q.Gv˕uRJ r/E_UMhRe0]Q(F-`ڦT_Xҹ5Z%YZEݍ\"Q6K5(f0`Y?)Pw{ QPLT G>cH8+i]RJʤVhK*W3 &b7_]".(TpKQ<21;bfhWRJ*I >7%Oy]y,m7lOC*^+$Jyb2{{ԑ~+L%R0i)? #;Dz}hˡ! ⩌K"8VlkwW`i"#pIJlO* Ud7E4%w-#}vI Wh6PZy8y=g:~e&˕3Wb%o0 m-2}db[Nk٪5쿕U\r'Z 'W4(ʇ%ikEYaۑ7rvE%uA8 %(?@EWvIAK, зL|b~#GpY$a;g)i!\3LWkE旱B&pcW]Ttfi uc’Ņ !єd/d(,g`?`%6,4Ø<Gıږ8'Tqb;$V6t8! (i%m<;KCFc"j,J]”߮5ufYL <R©W}%(/Dxiz#yXYiu7b+%]RSW zsS (bCuȑZGX|Փ]P{X (/y<J( p\ f,f0YDjy@:GjD .,pH<<`F $t;L_I@F ./اwhW.tTV4:*vhK|Z)Ey+6-B2vGΖǵհ_`GaP=eϹYh`0['8%_G D@fKƮQDPQO͠FM  (T}YZ8$6Y`-/|ԡ /լRR"9rx@SQJ;`+*ONťz J= cw":NS0Q#|@\$O\K@߮= psV.,FdtYWկo'GBǕK7BZ 1:+iffFւZ<"Hi(/l MsPy76$01@|jua '`IN!bIxs0 ۶w'䈶O0nO<=ȡPWxsγ.|EeN4|"u}hUJK| SDۃ?SU jG`dxD\A30 /SN[lk2CZDٯ+}~ aY"TqlWa$QwH۞+m;{D;Ge1؎x*va߆ib,繒ԭx˚KYQ2{.eGeD֕O-s"c2m7 &0S|/O>^(8k}q^MBEx V{g"9R#-ubivnFj*1lj ò"8|]2/#1\&KI?!-WSpuUOov5yoA75>S)Їa\ML*}9/ۇŐ7cY4HTAw @q6"MX!͘Ŏ  /К/I/xΦtzn&g"!e1pONqd.*['KrlhAޭo endstream endobj 103 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2193 >> stream xyPW{4D#Yn<*fW11ފ ʱ`f`f`7'# .xLDx \ΑBhpQ0"SQ+L,W_ Oܞ#jx*JRJj5=E|, Q=AqPZ9a;xF͐OC:DSл(+W1?[)GY 6mcn2)ByNġ+mϞ\^OsFcɦj,Ͼ!졼vYG;ú-%q&y%qڭ'*ދ.Tj*iWQd2yO$rhn2pnpוW/܋*kA)2=)?;0Bm0TCyzxFfzn l>ٳ0y[M~-'LLp D\Xfp-:G͛ʍ{@PCt`1p K v7C*uʲ"44.?S ^H%aO@jlJb^&![u) Ȩؽ$2Xл$pNSX^h/ )oeO"9ĸ,k J {0FRz.?7$V.%K9#V<}?BjK>7v Ʌ|꼷8I%ۭOl]˝,H<3], ͎^IapWG= G0;^{Ϯ&YD_ R]Н^96a'a!YQMԔqT xAÊ# mLl'.~h`3prH Vg9M& e,h92 GҎifoҞL[26 Yw\-b:d`d38+M.Y,+!QJ37e:~!(f5P?{0IcՀ'\W|GvITӥ Չo`)ݨfՠadXx}a>m5vx4(K>ĈW - ߖբu -ɘ;W&-߫K؋*Î'ɾDDIͱc~WVD0h6p妅E|P`r%oVu[>g~G7^0nMO-'ZA;ۦik=+3jp^zOo&uddYM8JkE4b()3nL5N)MAϼ#0qzy3DR$3M5@%Be-'B=},TҞ*{Lo,g2?y.1YV`EJ46մ5{7uoyo nuۑd5L7lM%(EUkzWO&;DJIxE~Bы`5>h.if[|(n*1j <9)s#H!Ro Z+9>܀Eh-is"$2kC@یV6|( /KaU+=Ũtw"MBPZysK]c-Wͧf3k3#+Yeة~rDټ u7SoDt,4fx>|gh拋 (c5]{9C: ZU{OIWL1^^ܓüoخ# +AjO=-6dZm c 'E` hUe'xv!oy ey J/H(p Dj~CR6" w<}|.&t(#ߒKU lLtW.RѰ.8)-G@AV~: xendstream endobj 104 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3094 >> stream xVkTgӠIEEID-DcbD81^Fb)n @7o4ܺrTP ((U]$f)Vcf={N{yGD D"̝\bE%ɘ`CHclg(ǧo>y)"̓E7fDfe*9+Wvb,ID1.b7"A%66BJ&&B 1_8AJ+S3"g\A;kɛ!31o~b!!!_"ڴ k&.KvT@qJRhNr(Y[ѮXcQdtw2#avQukΉ}8 L z_'~ ^o-h3%-00ST|)N!Rx¿ي kUOoke5v$׶_x)ay< IJeQ?ߓjX7?_xc M2C:ANTZhGWnC>GM՘U_D)bϢ px4GI[ēx.IKqkx6?6-p).8!FƏ!ɸZ]ZwniْA܍fTZ\hn%7 ѽ_ob~ԐIV!BhVA"c/F_.&`b腾[,+gXYUdpe/KZ7 Fݼc8_SOd(0zУts ]I.)ϴcXv30ϾExz3ⓙ R6'kjS>ߟSPm?Onb1aYϴ 7 tک_iUG%ҋX n$i~.7 ]y?"#$ZRPXTZ£C%%R,kwp0~=oȫpUs>⓷/ZЂ΢E4=-W2YT[[i[!GiR(Un$*_I{WҒevlC:[+AIڢK(=J_ȅ D=GuuE|bɚϥra>Vc$#>D F&d`p5Q7;PAQb5^X*:ӔeCZ qqmƺ~uE3zɋŝ~s6S-+ټt}oLS 3ZE[sK`i~ ӤkNa 2v21z{)[`G\n'5we#UKmUJ|O1z%)gu"{q$]E2Y !WMc8ON=HBm'l;]n@xA1@ӺyIH>/CuiRQ=C: =S hG%$ .~ڢQvsH/d{߷{ၳu#ּٸVVd4pY# [\$|_3˅`<{O|?E8/yկ?'w)莺Ƃуf4%\2 ~vendstream endobj 105 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2309 >> stream xM tU'"fS%˞UP!RZPæcjڤm;iM&MI-*`h)hW.q]Ϻ친ݝ"3̜3~wGBLBH$Mrs͟;wA&՜o.ӧL!C{?9t1yVRQQܶp=2G9&"#6+*b5XGD&f3 ZEPD3wI)zc֩^H[CP ?`9M$fܺ K ٵ$& R'J7ު0 dv1Ϲ$/n=4h`^A&K**`s43Hh___P/T?GEkZ*%$Q>SٕO+172zy.]{)߇Q(몽E5ey%*tEA}6Ν>3qka#*u"!DWni=Gkt^C].%G/s9Ġh ~ùFN7G/ESfQ^4U~f9a"껵-wњb,*AѴXO[sˍr{_XD;Ujg%;S^_}JfEM#G3hj>0xON Wm)'rFe =p-;b`M_?Vtd[Ƌy8=]vx} 'ڂU*\&c=[M^Ӵһg@ a^5e_]Y&̃5#K6[HA@ !)/&L=D Rxyf.YQeҨ5"7Bw_=|Ut1[̕ۦڮQ9zVovb*r[~_o]. 6pY67{!ho * S*9l1eG#8s8;F&.Z3+sDϚ9q)3C=O '`6Wm[jЃ*K҄$Z\qU0Z&bZ "n]e>. V{75f~971vJwXk,(x\ 聞]f}GXTVxURR0(!8>g.PX}z#"SZehP̴ }sUd*ݰJ5M}cnw,| {@j!u@Px.Xʀ9ơQ|EXE"SG,`5l)Jdd3)TZBJM~mO%MEȸ Rj(6H#^$}׆P45;dx,d+},sIGiA _נfe?xjut{rCzQSa+ o߂߷T\@ÊpΝѮˉOLr*z9!e2 Ȼm-!<2E0':m (&]()ePhSyC}E,jY3iRaendstream endobj 106 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1041 >> stream x}LSgW !$.!ư87Ȩ`P@ʀ^ʥoˇmiPvvYC3زeq8 Nrߓ<IH$V_+=}cI]k81zq^`w\K@C]XZE(Q:ltQ"GкȦAuq !%)֋ W :5P&;`!=#-546'7`Ho@^(4 bZ6Z{Ln>ܘhWq:lFS`DSRY]iڀ<{RDI/"y q:p}D2[@ʘ ]JыN/Ծ^yC $t![8ji5k/=qEiwWO<ɦP C{يޥ {>ҌN3U|,IWc n8kc[& uTCVЊv576%,kc'+/0U)y%%(2y*ђ_y#ue W0uPQ)Y#b HjjRDCj@> Uxb*ٮ91uNkik|<}c1f@goG;}6qmsTDS OR`&{]z'}SV^7(9_?3{nrc9 rlE:^0C}97l]vƁ,1N/^10Ie`-[ ;.Lz:dxatI NZďF[{ iOO17 N˕V5Ԗ*0E|V'a!Ƚ5S-bPL=d v~_`X#)LN}6QsywO8syg;@$,?? !F5FYCCIIS|l?'Nu{#̊Fendstream endobj 107 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4076 >> stream xW xU{Uh A]qeTܥ[wڦM4ޛ枓4mI ҂ *:. Ž㢫?I32;6i?6.~2"򳺔/(i,"'97/Ⱦ¢ż7< v{>b?qx8HV"F% "H"I$b 9N!JP"fs3Xs\6MN'%jE JU-,Yĸۥ\vryCbOOrIx{qe95<@02]OY<1ơd4E;ձ_u%L((\|,-5r>P#OiIpgxkN ![/~'Ɛ:|Pu hOEfSkUL<P4>عF7J`uP K˭ʃ[ak[aه GI}#5~md U뙘GH &\ϳx"b# ˬ؟.PbkdQH$NrS[`+un/ƘVA^ET]Tœ7&1@9pO'4_"]X$rJ~N{&ūe1 Aotfx"o)6<ܼb6h͒}֡wt, ~8 5DpRiV!Y7-z҃VSOg{JO_C.ɄITM`}Y?xnR>:4^I2sVK-vJ|Do~z-d?pHv0] }GdJ 9lxfv\X+Dit$&7JJ]>aQ(cuTG ɿWBMTU[U*sknqB:(ԉ駊Ǿ=G9MH\05 3QѼȯ ') aFq>d>&js"@`sgw/k46J!kX!nx7C/iL_e<'2Y=(‡~$ۥs}XG:a#?P);ćq'hu&Z,ZKo" M Z-~HޡPnH}p܍.u J5Q49J0#4S 1^kkln 2f%h!^x|<ק>e GOP2c/7E262D+ V@?yK`{o^<[' PLڰj c{ DOJ,aE.ޠõ`s4b~{iI9>d#văϫ;iDvt1/4k:r~Vd-65SX8n^~6i-\XoBN4D]z34Cglq8]́[ dj/Dxir#*td6[=g'މ\ S`i~r>v:*\(N1|[`@!qhz6WƤWۂ;5Wo\ ,3f?DĎc Gct,n#9Rbnwv]c_PrIl"E{@'ԵԶԘdcL {;<1WDmo4'CI׸cm6rSM&pe2"+kve$ev"bxq2=v1b^q>9kPUTy +|hRQUhVY~mQڡ2!)Kq:qhWzf9T:Nd2g1 UN56s >A 9zΌE.x~?؈3#y?9|w ;cM8E۸Se0BwoŊ0m྆Ilcu;0C ^H'A!%}.=ܳYʐAmlC(/V;Bw;&5"{OTX҅iuf=6X6Qυ)A4"b` 1Sen~/>#)^K/؟] oۼendstream endobj 108 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 964 >> stream x]ohu/n-,3p?`)f]+Up-8n/r4M&Y./].Q)snt*R (7!>/x|}Fi#l6s##'z{[tvԹ'g>O< 0˾! EQ<41D -kW[(K-Nツϟ:D1M{\  0VHWw〾7 ].;T)[B%JH$Lέ]LJE_1tpBscMG,mi Eh" 5Ͼ" H_ L&/ v~(Hj1O|^wk jvoan4;Di$mIC'_{ a^{lk|4P$Zh [4 P8Y5z,vfj Q)ț/7oP^K3T#@okJ|7c/v(+}?2k'g66+<.Tp[. Ӳm@_Lqٹ:@Zs Q)c1n%2"jy\U4G*H>0J9cE=д:JNb-PVV<+'2"Brol}lyI/-g ßsY3JqIL 6:>ẹIۓ38nZ𱈥T=} CZj c.{ o|9endstream endobj 109 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1745 >> stream xEU{Pvbs1ɮy51VZcl8CԊ<AE< Bx݁x|;b !4P-1Z-M֙"C̏tOt۝<~KSMʐu@b&z |<-/3}Y}e dekrrwRӢ3)jIEQT KBw0JI~A}@| Pc:,LvS^^Jy|:FRFĭo=~k,qsNqBpݝ5ps*uɹpLyq820P;UX@(*Yn/"K<ݧ K;PM&&(OI@]_M9~X\n`բɴ!!b+Ʃ Ύ>DkIkԂe 6Xj4}BJ[CCX<,".|!4@ e z68Ϥ:wj[!x$66Yy= __ 3T15ʓN* աDxRfOܬkf/t6=4?2?Vsi𣴷!%iA|_|IIE ܭ zv|gOCoB$Wԩ1XL-+/].͌a2b\)AmVYB`x^/6"o1O |c]yc6C_6]}Q}ؐ7ty }t*.VLH7e4U@9%j@V1PSg[^_jFoG YLu~mܺF񮊬Zg2_93'Ze`#RP̪"b؋lhY ]-;̲Qb>ZS>K 5'V| S-<(DVx2gkav])m 8)<LƍDO ZFqbovb\ 3dҐΟ:k~Z03FG>w|UWxLa x>],iӝ0)62;'' rZi"]}n)TZ\^Pc۽RUK'& .Kj&hmȳbȐKPfgs{scP+ iq;`K'図7| TWu`*,O<&Ƶ]]Ҙĉv {; .om ol)8,$d%{#㞃76ꡁO }9qߙ3s ka3SR:fdQ.\Hq3!Uf5 )tKnÏ]}D5_ 9r- N8t.tS̉/qwpi3[0 -]ߴfV@P+S]=Z8Sl+շ[M;܎e€ $wzL75զT*'U ݹKø~aw1 XV`gTg Rz.q1C'*J&}Q{ƐtV[a=OD⶧m،6 ucC|S’+\ʥw ٰ,iJXH yE%uoh0Z=iye|lΞHi)'`o Uomendstream endobj 110 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 8256 >> stream xy xSU-M1 x/ (RPMvJi&M%;4{Ҥ{tKֲ쫊I3?sMn~~ߍ!z bbbz-hKGf38Mߩ}cAߞ0/qpZo'Β̖ΑmH87?e^lٺ(mqc=:W'L|Æ1/_/*og%< ?q82` ';,4[Z s;V`|{#ᄵQ-VÝ,2C}[P )̃OS(@E E+T!_+b3wZH"-Y=D7GrR3VPLH <1SytHPvWC*{2 *@=򏘟optTE_LWL| BqwP8[Os>/A {q|{`܍=tHML,SH`XqBf?+:c"1X C;(:  [Ń'hE 3 @o1 am)vmP Ia3w@%T(O)Uf"? =3 =_u*((j])Uq"%I;i5kߴ$>r.JCAs z AW_glc |vb['!>OgKwAQbZ 1HP<bѣ!j'7qY]D$X0;Jn8`9%W) -Y,5߄WbOh^fyuddVf)RjVDǗ&(~D/s&/ĠRG]z9ww!ƒ`՛T*ҢIϘb &ǘ{hpȢTF@V}kr(H5TVw,Xlr{q}c;݁\ER 4$[.s0 fJ"|s,TWӰ08c޾i{=ٵ s$ƲPdղ0?$>g`~lܤҢ4pFy*yI֒+.'@k2i5L U)em%6q:Q\_aÎ/ϯ::W (w.v=Ncva@irk "~ܙ/ ^,zF:P>O;/T?&&I,j-#h2k729$PbWRnOk1>U?ݸؾDq{FסL37)+J #ob\7|FN\. &"2:40}4#F#<]:|O }$ܐ]0 SҌ[t [L4Bhré/h!wי70HC5žnLP4ak|nsq\z`vf✫BHnT֟P{pJc_\DNg0XqNa8ߊq695u«Xhi}LZܯ7NløVZ#̃25C.[}I/Fb* "o5Ԫ)!P*݄)`qu }Agd)|Ӥ1h̬jT5 p-6cX}j1 iPGe]0>5oQMno3nb$nC61m؀  En^cnm@$I{{7o4@б2E"[#BQE7Œڙ*[Q- \7W=:1J,JӅ oYiYYYi/KE2q{ҞgUAY,]@o#b {ʲ g >[i c}#T}<ЁC{8 8uڜBQ F`8zqR zvw;=q@rZUZi+ԟo7+jM3׍~ P!@I)SRZR/u{=/]VvKtTDSӰ!O<ܝQV*K;vwhJb3[ NflWBUeY<Uk0# WKCE5~6PJn1oa)N~Xq3=r2΃P<;ZuR|;_C=|hV^ƎW6dneJS6\4z@).x㐨EwY 5f_3lD+zvP;Q(DJZ!MTXuTt'sYI 3rT@P֥`E'U42[y@dNeI)WH)Aah>ʹ >xz{B'jN<ĚBB0(ab.JtSb&sNp^2K`xH1bp(|XJ &rBEeW5i'6> #/ APgym\;.C'פ*txFZCU¾rsUSOۀg1>8?FΙ_ᩈk8/y2֨!ܲѼhUdW9$b{*\x.pS2Ene!@yy&u!|p eyLYQn0>W;]P>NXH%(ߠcn._b>.0uYr5sw`C~PNy6-o zXxJZg\XfEk?IoǨ7!0, Ӷv+z޻US*0)4 ܅s6 K(5g3>:a]cI<%\hX}6득سq3Q Ye?J}lK*&ksy;Svgl?e~*اg!Wk֭7!ӹ5{[|ɰ@ ~WMUB_ewn2Vb`͢u@AKeu`ִ"Im2F fP=к 6*%U92| fBa llS!<7ydo(ךIӆxQ/: 1/LڨF$X@˫!S!Kz9=RָyPΣtaRY{?L⎕5s6-x՛a  <5ƀm?co@yJuM^%vGi6y5BZYoy|ܣ#+]UJ=s4푮k! bz5΍JcA=Tc n6Wcg]Hin(jkHn[͈!A{]dIuH(EsӠSF:G; /ޙHc/?~kLrxyYSJ8tP^8tK?WFlܔ3I٥ZZ)ר޸ku,@ &qz?[)SmW+;B sx,^r^C6ku4&u:w劣}t|+owɄq|O-֏J|JVR I6rr$ŧ=}*?O{QsNΉQJm/œz6))- ,jGG9Rܱs4 ;;HakpmkAdGr9"v. wև*<~0;5nPR2bE5Н/ UZErZc; <,R(sufdp&{V=lG/#l؃CuAtb"ړͷ:ۅ ` 9gpi8dWn¶ :^#,[h>dYE-w35t6uQ͵h(3X^E9yɋ!Xd:G}164ni{9ߍs/`v6iT-'jCXrM_ 풃X`2g&̘&P*9אszljt< 'ҧ_yg/2؊[1Wwqpcb݁#m̭P I2ek'L-{0:!/\v;Kh`,\nd6 7ϩ.,oNjн۶`w>D/02|Yi@HqSu@c&+WZ(61rE8f4ss& i=M)+qD;>oq@.o i!xa,B 3r{9yMOPV K0!::(Q0RW_m {d*XF4Y٣+ X+6T3[e &;uۃ~:˿(N.ǫdJr3jJ~*:O6Խ([_n HWj[%^vGyW)N°rs.s%{<ETX{ݎbl&yΖ<%-J)\Va:J>ÀjH"](OB6ߟdܩeJ%Dz'R09 ήG-v_v< gW| p68^vmszZbϵOƞfeMO Į2@Qt 5 I[9%U%%03w>nw0E;/埽Jψ |!޿6] 8"dpr#냆jd%KdDIC9 d zC'&QR9lqen]MuYqGLy)cVZ- ݸ%f3?a܍)|2ͼ$k vlp?^ݍ#3O&;jSu⡥FnsfjS1Ap?^w>RCN%gGЊA#;n{0ZB"9۶wW7[kv`FcV *zѨz=Fc b?~[v߱zPInJo*(v<k ,J>˹FzL.UQAVE.[?i9x"N4 j;tP_ƨyfJNZ8[1هtvĺƱI GhRqWFq/6DXSX' `Y\ *c_vwO ]0&zײhQ@rt,_y[: W^錜$eYCp>&9)Y0ng!$~2{Zw>}чGNaDF(1"*&{kf3n~ Wz`B MT65UmLTFAώ.JUNO[)g ``s;Ϥ*sHGro|y*LKuJ  =[5br&}6`K0a08= H]޸0yyޖ|{rV0^R0<狳'?ijPI´(@X,iLfzܷA_L]uendstream endobj 111 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 352 >> stream xcd`ab`dddwu041d~W8e7Bo?``fdU,H,J+L(I%)`4Pac;cc' ##Kf|?&/aivW*[mtm-Xmm`J^ZjfoদNIf:1sg{t/DZ18}OGK~O_{wL+eEq2E;{;bIn^SO}]lʔ^55ury~{t.ww߶S=UO2pendstream endobj 112 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 699 >> stream xkHSaq3j^ aa_"D("(4JQ4uMtWuy;g:9uMRXB%EE|!}x_R?є4i޸rNVJLdRfVbvȂ"C>EQlS9t%6鱈ru]dX{tRrC|[ʔ@kaAh9v0cP%wH$rPvaJ\ۀ3j0߮;bZ\l[VYqR]*:ZLV0ªstGѠFcbp HbgAݤe NorIfm 2hwg}M=lc]?\' BhφD*F[UEB}%{qFl;5U;{M8r6tC~ vx`h2鐍Ȟ֥IдJGb/߼㌾ `e*b Ǎb6>|FkBX-q$Dg-hGM^]b)N53AF{>I$'rX_JԜ큗LN:0*03sL7+H&K?>t/Mx L tP?ZUĨI:^Rendstream endobj 113 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2269 >> stream xUiXW\JY|UI&j&qDc!Q4(A4.l, -l+ h,-˰$*tQ1:Q&6y'̏5S}w9$%HdָD;9Ka}+c;d ݮ zg޻.1s˜MR'ZMq(gj 5z1XjDdjX%r;i8V/Z"Y/DG݌#cm`9X Nh׋[{&8UGsBtdԴL{I@/+g/^(\')5v=(AsA_9&4B9p*ɫ*Hm\IpMg=8}Ў&HhTB=@z.zivaoMħB Cl8b*<ȳ}8*C{.'kjrfN㝯-GZvpVK(3TYMyLB-!uKq]yE.򈮢(|p s!sm4{j(pz`~EzIt-pMmgNj`#mD0:Uv_Ck]s*э{:l ܅ERHKݱ„p R]ݎu0z{,IQ9Y~jTY*HeSKKSB2A8`f-[~aiirB1[މ@x<^8)*O*}`@Hߧe*_'O7Zyy>8Sp㣻Ǘ9]{a3?G6@&~{վΜr_x"kk媔q1цsI_;}y$Cw֔K _/y/mA: I]wlR~WA! b .L|K9D^H@B'-GjN)r@,s#8gK-2vC0H`{H>8I%89$j IwI6I@ 9d:)m@Zt 8xdZ&?Ke9a?7T"t8t wV&/WԘ$涢*|i-:xy\ [,F> ӧLFnV{_ {oG"QV$uX/UndRȵ$=&xbYbXn. KN-?WƇUJr!)ᑪ<\2w N@OBٌ >J~kM(Ekű ih2W9HvCG3|UHYb]).[`vjĀJ!=g# Oq$K<Ƿ E  ai٠QK.`Zh{kW d-PDvNem̨=i+ l+.q\Fw⢁%?:S8:uYDܳzccfXfHͭ=54sI JMfgv:i5aU|(e,gWmt+=&Tg PDT~%xS^, guP?endstream endobj 114 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 311 >> stream x,CMMIB7VdR  beta vV+W @rL!t,t^ˋQ (F-6c+}yuvymw6eiw`0O\͊}vyhveVgZTsM6򞕴ړϋ_{sy0q^ yo #endstream endobj 115 0 obj << /Filter /FlateDecode /Length 190 >> stream x]M ƶn6uӅƨghXH my34x'}DžZMyZFptpCOH՟exҭm|bu6_bғ9HQIǘ{jAٟ$bC.:&QLB^,ްU" > stream x5Ohp:@s09Ny9dA@u$ -\s G I@Y$35hɧ\rf!_B/*endstream endobj 117 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 269 >> stream xCMR7,  12Q͋oKL0bg͋§j~'eg #e'͋JiuP~>}L讧Ǻɋ !74/XWϡ=:4MFkgo0 7 nendstream endobj 118 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 507 >> stream xcd`ab`dddw441%8eҏw 0s^-?C X+ Nb5?:~iXCw!_gf~|LrfӬs'ϟ$;}% JL\8qEs&韵W;eFNo*nYj6uw4vwԴɕgGusTL]d) ǹΆQ%UrmVvvW4VVgts4NӳpܜKw?..\GUuavyo>Ζn u[޽{m<ftϟ]=i'-> stream xcd`ab`ddds $:tfaaQh `bgf/n0~?/٦wO]_Y* ~Ͽl|r\,y8 )endstream endobj 120 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 105 >> stream xcd`ab`ddds 4Ļ.>;@1012h%lw?k^ܽxIIwlE10U endstream endobj 121 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3340 >> stream xV pSW?`'i5CM )`Ccf32 xɋVj_l!-Ɩ70!$$C@ M U'줧fFUR{Q!NΙx0Cx.D"n<*yiqNn^~AatC>pF6trᾥp#O45tUok尛V}BnFQN"R!SY]?;5^GQ=(H6%'x##Ҩ!~Z~m-u(b$ fqo=6gK&,2 +˗gJ%&/#%c ؇^BTqxoyeG&z[YC|+!:H7oH^Y,v*zT(mh\k&ߗ9RS2P#TZ[s 2(=͙ Jpg!~T&C;V4 J]lfkag;-FdOlh߲Q#Ii*4bpw(eȾϑ@QNH_~3fR}^ܻ !x-Ƣ/tnc JZSUhЉg03h@ vBYZh'حvklڀ561CR!4U˴6s8QH[ /4E)FAFd$w=^BTK#?!\E53oS N(1ʭ=Î`Ʀ*̽5ͭ?k:M.̡)ZeælVmlpxI"W~@AR:Y(oYβXL>)?Β, &LL:˾H }E h~`4[[-9kxC$1 PykߐYSه=n֭uմԔendQw${Z>\Ì~^^]O+ӝ}R1יĭ+8۶A9Z;" yϦ9 EI}[Y5hXJMǡbuYNX Zgr,/C!x|v *ou5v]*~4u(eHg\ힺgDm55_ a:tNWCfQfI齉Lj Up8 dBqރ[}zh|L\T)A;. k[Z}ߙZI1Wޡ r{קfl oNEX)/ؖ17/> f-d茯~𴣁q`JRA9KM&EmVG{>ÓC8Qb-i޾8EC(d"GVo|h}Џ P4eExb<#F'4VVֳl?YuAB05?\9!Ӕ>p\$\&uz[E}eVqSV*۴5U[SiJ ';Ŗ6%d5zx ٭rmNY{2 Yl9W7DgcޞXlb%w =#On^سaYb|W])WVg^N2PJP~>f M^O+gJX*]e@?`N䑃m̡)8$hA`4:N { 'W^aQPp>CbZGNڡIFڨ?fAx0A,%%+x#l9g߾S_1^e#6ϯnqz_XRUZMg2FYg v4g&`gSw2rC';G$a&`[goo~{i^h>Q>%fwٜ[ӾBsq+b`lL6J{u-w|? rTPŒ)Z2okBmN]T\ >9&hWZԤ4+, #+ɯ_D~k+8-޺5͍, CQ/endstream endobj 122 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 8522 >> stream xzxUƐ(qM :b(" bB޳ٳ$ )*V,wx{,~s/'@23WnmS,5rH?Q&uef r+&d}wr?^Xڤ_\7~*oethLY7gjo/xeMS~fώ2t~ŏ-y|#G=$gg0g.g,gg9P΃b0CW8s^9}98sys'.N>ysvL9}۳^^ܼؓI\Hދzs_}g߱w|w߹Aw_5 n 7t}eL 82ߊxH0ݟ Q &7d0ۡC ׃<6lڰm>ܑn*|r]\К˔"O/cdir5Q: SX`Йu`_dȧhMNQtK|Ѩע;ttcDm/'z+:vx3b%xX/j0>}kyw=4Lpn< f\/k0L%4(2MPHAuc+{EBɮ\J1Ÿ@%"vza_>Z K_wCI(?tr+qDW/iւoW}pjI^̼s|pc|\]r.@.SDKl,Y:zt`[ގt2[ktkAt;33L_դA`mLao@0s'`_>` 1Lv`#μw;'4 o<$ՀX|R{r ,̇BV(Vau*&˄*Ӆ #˲yT| tkڛrŃcA}5#7"$WU$(?B[׈i[+XФ?&ЪzPVFpc!tI68nxʡ;Q3ẗ̇ܲ%˜Gqy0]` _^ ~@B1;_#_G07shE"4|kB:Epw4'n{.C`S0D(q_ڂZ?p)bx ?!׋c,)WEC3{qыc1A|4_csTh0ntuF9 ף3ta*WTcz?3}tJH[BAx!It5df3I,ޤ:2DŽ%8 "D,W).=8 M^_:';:[+vX<u w#Tk)vL$~5ڷs&=#)bOɤa!S-joIsD嫣WmLL%[ps~pyKnD_@_*y([b"JqX3 J aF|- /AEdNi]F~!X@l`'~HD`l8?ttwSN5 y`Zv@ynq{: uEh>T~\QΕx?< ϝh#>cHB8.OkRJ,lQkM#f$>E8́OtΦnt*7mdpԞd?Mbfr04L[ R.{q]0 :^ID5 8yQ<e訊2@1fhf$Styl[&HX7P$H^ CasOq®Oi"J%KJwQP# kKT̄/,@HuU :(jKݰ KV¯ql-\:`#! y+CIr?]J_&ej+]_@"f;ʔ0e1ޠAnCaozU',d eqPe懫ZAH%P ^/b }zYң2sʹ޴)؄ *D>8VF <2yxZ!Fva O Qf0Kz& LW%b"Lo2 aN!e8T^)02cӸOD$fUyٖ1mϹj=6@8Ay玟s $ Dc2ɾ*-) Z嬶W1 sLŻ.`vB[2 3fJ\Q}3 '[kD݉ąn 5.ҹ8}[!C ߯bXʴ5REzByn&N@#U]gr#֘ ᓼq4ӏZ>g:q7m-f  f߰V V%IcmF8~ba{u~ZUBҔƚHYi8}'wNQZ较D:u:[Ng, _^Wݏmn@Vja!-gyf^PEt`ٸK=#54Dtw WXyb ]Œ[N /"@bz~IiGNYD`4⊅](۵"6rvF6vj/vq/bI wvE[6kES-H RAJW^}kw~ct w" aZǖeY5q:My2Ԟ;!c͆^& (q+!\H^ű ]QD#ި5J~_-4 *0\-B Q {"n {<{e@}S4!@Ffi"clsL:UJQ\`zN~z:n""rRc`2drG?!olI+#>vg+5#36f6 ?Y%4 ^/~%SX;*:@ps&3Ӷ=` 'f8;1@$|HDs* k. FIM4bƔj6)+++>P(!Tb.Ct.)8njO={v`<Ϯ.[Q jK2yX4fmOIK$$Fj/__B$PSHI5Bі]ܚy[zL[x;Y6V>r;Kop2+4gڌKϟQ;{ M;&:0aM>_$۩U*aӢkfb;jܲy6k,Bgܭ8ːH** \9Yz}F _*!qܪG {*p{{[o{4o(v#`?@x\h DNq %X)_ƂYnOi}m,0tQ\8TPbZƝ1;;m~ >&`.5vj;+\>\ lNӾb[I4lgO:Vo/gVW[t,6g|f(g v^#;~c=n71ձGlc`Qux6)u{w{l[\Q:(< "'MWԊnN44fI؝{F!D:GÙpO7s9 R$#a?x x ,XDX=:?8Jyw,(ׄ]k1晙U;+n0Q*_K?V.8\}g#h{p.06 f ={,N*RFX/>K*FlD~YDAoMv|[ސ cC^P{4|`ui}\ eZ[Qc;B ߻se:[V:Z|ůRFl=7! 7eWl.P"X0#/TE ϛ>P%ð*XD?׆hȹcY*#ovO1Nnc:N8,S|;wcF诽 ƒǏhb-f1t\E)&w4Z vĥf46$ۑ"H*@K( cF3K8p]S -Y?Ra@DQiT醪3 XIDw%'kO7X7M j(x"F.+C@=Dw0g1<_j`.(=gH&Dp?~!u#aN<35H~8](f|U@Cb~0w.hLPJL,d|#L爊<&kY[#!-v %!0 FʧjB*2@kcV,Sdh.Ky[/|>郬Q92i8{Jb{1RԱδ($kir'<2@>ڸ?k/,Va@+1%LwZր:BWD1=ͅ<_{N| QFs|XTmm *Rxf_T[f@|{'[8a@kmXq?k! osS11JknFnv=5[9L#&ΛUTFq*^AP:J2I8.ϔf&-<HƉnI(}>q{AƏYķjxrM=R76mI%0s̺ cw(7tK/mB?vj 6B`z'4f ׍tg|Ii c/;1mN\s-zGd& s?pXNCtk[Q̡^k-:oKÜcP9 O{Ajti$*炄~aFYwr7@NhzMa7Fu_y>@xpͧӎ ,H dxW^A4@6L &GmTF5R ,3"@_TR髿rWuKjy_#'۽čY!a8w8슟{>I1G36fRMQ's)hbyסxqFM+S "bL/a}hx&G'Lt s}*k-'/ZY]fp5&Q^7Xx,O.~ԨQ|Rd;U,ĂB_-Č}h/Q^, J`M^(KK4Kp%zbwnTET2}x)`B;2C/ na 8`>w=,vA"dDF((  |FRBW`\O'M1/ɽm Ga[zO:gǁ)r3C3b./pUa7ѻ^?~dWr:928EnYdF?2f7X;hoJI=U/R#k= _ރ9tA{&QB0#CMߜ8dzս9uNzp7HKUnetM2DɔBI%~UHGȚҔz@#^+jdRB$(1Xqh{- d&2SIr 8?&]0M`c]&| bh(IZ 4-a" JNIUH*E`=amN$W)5ήfVFpmϢRFm;+8 :J$!5҅q UM~0>eY94U=d-a7pk$ C&?]3D]vbNd,9By6B;< YY]T r񈵝7u~E0c7w} QS{;;{X9ĕrT;܀%|H@d c z-&n Gzv9bZƅV%)xK*,Bk\BbYn<}hFH'{)~Y(3_^%W*9/S,av]_n7]cGNC"eQ9) 9^2CTGr\,b8?1TsIkۛ7†\ D +g +֔/7 V|-zJ.*u4dܫ>)U"v Ep[hTg& 7$J|^WkoYlOۛn,s3vq5vt{?zpqd39~Ks,TdN9[qe#|55B Չ/Cڼ#"w xk'79;ϝh"-0 J #n5 @lȓg.1œXC7"jWSh]~i:,v~(?F3@_݋N_Kwwl{xa#'188?PۖEZFIANכ_+'uendstream endobj 123 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 7334 >> stream xztGB5M0ƌݍ#L2DPhrΡ&<=QBD2Ș5Gguy[m=hÙ *ጹSRR2vU9s&Č,//+J1n7G8M-  %,n]&۶\^bڗV_xmO~SO?slwƦ@C*΋8wrVqsVspYYϙ˙y3sgg>~F989spt9E$t6rhW”)+zwX݈x_lxEֺB̽|C딇z+pvԫ=Vh4?u~ Vi%(; IMHBθ+w ^vEحיɝS!Ĕ137~4fLUQ]c冭+!1Sj+ڭ(`сaex2o?l 2" ;HހV䧁Nqӡw} Ț&*6lbI$*CS]oA=ў2%tE #0\nO2 JNfèd&2o)C`EPTEn2pt`< +7MJ=iJ?!Ẉ^W#!IZ ~RC@WU)J\ bq{v%a vS#t{zݻBݻ?x_!єRҹ4#]c}Ko|iN)VH4*[ÓH}F^M7@cѧ5IfpWP]ě̷kאun[?8 ɤVԐVp)r)w!1k7n1%#ޡ޴ak5tt]E=RSޢ:BIJ~:?uɼT|<\<ƪk-;}aM= Ʒ@N^[X{M7z$3:$''ʺD+o5(VR3j1 ˆE5_vay!afAqPྑ5h|x->_IhZğ vc7/4*+-I"|шʔ'JDI=;l.cjn`䫇par4z\XHflĬ GDHY\$y/:}N`WcXlH!)uXHuQ%x~7݀NsO9!iIu%d;u`C7{6=c>(QEwB0g 7 @Ћ5Mw2CHS ACpFCWcGC 9)fj qL tt,8~ƙvg!.avl:`&2[nHlj`tQ}TʡvDdX1AJzR0  ;[ >3KVѐQaf&_W^+ln} ͫG,7 8ZE44P_b%l4N q_}8Ԙ2q\.L4i**ʠjH!9&=&9&</x"مc_7$B C._#rpa,2P: #cuj8(+i_&"J*Jo;n Pۣ+seN5ƴa `H , 2d3M/'gt<ʃyJJL&\[Tj@zn}D,Hk8nlڠ]Y;LhmEYaGZd<@c&I官)Vq /)8c3a~Y [ZAb6KMm'fh )XR~n:Bn=n6qyB.e|,dcN+bRy ,!a ܇Je gtׁnLp Nq(~B4Βf!x1qj:Fν7FߟCgKh5 ߈ip:qwTFG9SlT]'Q+liW[UVooļ%~G|&/>P`ǔ3 dŨb#j^P4҆ڨ07bOt#C;z5*4Zކ5q7a!9gȆs>yUH&:u#[T:_'ټD{ D`q D0F#fuTG)J{qo֤)N]VtashKP'!Mљ#;tfbZ-hz7IB ON9-NLРR4FE_z_n*o(ܳ/ w8rڶڈiƕK!QUԱSoAp_6:]M6nn*E<d"S2֋~6OF>-g.*q !^/ Cb4쌘v6av1OV27ڭ2X2*Uĥ mX7$xZK,L& Ƭ:e 0'⏆ݩ_,8ŔB ƵH'evفƮ5nS upW^R+l J-XBcսNۆ Ht %n8n@Kv,xz#%|L>29܏FgUf.LY? ʑflmFs]9Ezb]֢ $R࿶>Tz qjV/0g| yۚ4'w;rbJ(JYj k*c!qC,d %l\3ϭeu @?zuUl!wu ԔK"DG+O+ "q" e(dqަPLǝʺ9΀#XƵo\IahF :'t'ɿ[ wBѡyߠMEXؔD؇yd6b~Յoʄ@,׉9AI3-iwI Au1rp۠%7fr:Rt.ݑJ'>ǍawaŒcl ogV0w>|fFfTckܽK7&Lq[ ~/=x+y_8 h ?[HA) e`i25g++-8¯hz8:Ҟ+ݏ {{{ws# Sǭ ,01SNb~kȥ$Y@noqpruomPA2^,a6[ ^ȁG :I`gP5#CF?ϥد H3fjd/^0v4^S O֝Ov[Tk6Zجl1=s:gʲͼղn{n2G\ݙIw1`҄Ds7{VKX[E솥,b/rdc^72vFF3lJ@{~`P`33l!kJqBIjUn̈́{515i{΀N?;3ܓ 'm1bY0fTNΰ'{ioGB^>%q>b1IMܢ1c!|F>7;*:flhAsq)hr)iinD}>OgpZsJM~ [w^ޅXI|G;HN)ڍ^W3ʭ9rC0Kִ4.aMAߊ1Ə VY4͑ܒw~V~0m[k* aJj9ҕ`wglmHX{JT&a?9WYQDƣõpc9\h -A[k3||]puZ V\hIUhэy%| +f59R)2BWH'8`MDMBh$HJ6V;9Kt5De3o$Vh?qKo=SGo.#L)֤lR℁3\g}D)v+Rڼo5 +>ZV+mlr]C18_x[g>xaף_x0@it  WjΨ%ίm~uW4FѦ(pa('xk?^4uH$xRP>?(IC(ET30AVVܦY[4H:"x~j'ژ{GUr|.VW|181ms0_nk{^jXٰj\ߦ"LnvA"CBcߍ>\4O<:&\TH:sڸ.)L|9+|45X_S3cRf*dnأ W )%T>Mz/qB#&B~#jvkB˂!T62>Z:0N217R&*n' chM/h6D $׈6!ހOj*xg x-.UFWDkBWU$ØR9eSYYުnP Z } 7=C[t5: +AD&=}]S2D5Q;Fv:Jg>yj l t':#bT(DTj4FՊ]~g}WD$AvF inԛ3 C+ݫb>*|[61g0Y܇e~BRˀ،vy[DF}"a1%cX?a 6K*a)JB8&n/Dװ.^0 }B5ms ¸S$jRƦkʋv%;Э|έu:Ynb +c6⃯}Mlohn[qX_]gJz[3(m:yUؐ-F?ۇw#>^./B'JdhH6Z*?6Z0݉|%ܘ!vp2j)9FPUnmsvΑZu".;υ FiN)aRL h Z}#YA Oͨx'\ ;WћtDMM}}DzޯY[,v&f0޸DB*aNknncTVt4t=6\M3huE//.v+ * `Uk܋.s*Kx<ǰmfݟ||\o}DdbT'T׮mrʈ.ξi\> stream xWnF}WAW}(( I'+4ElDY^P@I3gg_?<_<-Dt*m齑IH6Y Rg}bK2ɺZܲ_+#MʹbVыNC-9tP톉~eo*omC6riҦB[Hp2Yo8w5X X:kqkɃ&+ O`KZdb򪽊H]52jdG#sMjN3# v/r|/rlc-WE ܎Žv r)0S/̌Wl4}u"^vbpqQKp`rˉ5T<",, ZX?gMAC"y(z;ŚSvUv ʬbViK@!Y^b?ϲhREK&DV`{2NÏY CA*GaGCqBʖ4%`Km)1H-NH`z<7xokײ{(!T1'~`q&ޅ)oٹ.Nt@8#8jtg5)/ʄ#xDOgxq.KhiڰQ\C׃.k[ԝ!hZb<2Sm[ݱv wtT梨I$)ZDX총Li]9w+zޟ!J"8/ۖU[*0=SQi} ơ:;Юן NW} ڰ|3׹/ML4\v6݌'͸4/Q#OXve^5~^#} $_qS}ˏCE'@ +PX WS$z.S(pSnZ>@ꅒ ]xv.b{ָ"T-jLAQ`4`u<`KuF_y8m ,^B ѷSFnIEDu BB@p{qOU'4J5Dꈧ݊TcV~GV{~)&/:G>,t z7 vFww|QA9{/E@l:gƗ^PЪ ӹ LOf!Գ}Q&. Ʒ粤E[ 쌱#endstream endobj 125 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 364 >> stream xa SFSS1000va  RS34rM@vKJ%Au[ы'}}}#ԋ뇰2R`aUxf~dd+kv8rqrypN7?o󊒊ͱǏ{iy\XV+V%.EsuFOYGEGS ? Qendstream endobj 126 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 176 >> stream xcd`ab`dd v 5070q$eaaX~= h Ȟ2&K??O[t;'g*{wzAgIg^gnw^7G@E}vg.HHAi魓kr9丘p208endstream endobj 127 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 186 >> stream xcd`ab`dd v 5030q$caaV~= h ȞqLI7-?މ&;i?ٻK:s:s9 o=M`of⮲n g2F."ۯ%Oy=';=endstream endobj 128 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3269 >> stream xW{TSWֿɹXD6νUtaۙjE8 "P^ τGB^'g@ "*Z,bŁ:N;S۩mu\߉̬o/'$+;޿PA ][׿~rS~y7CaHP݊;ah?/~{ {-K KeR̊F]]ST<@%RIkf*Bm^QST SK)ZA`Pj  h[dAk`+hKc zC!U!!< H} vATmJ] C{[Q|83r t8|Y(0#ͼ;|肞xɻLx@TUJ,$ӯ_~VVV+tuvwtg&$V̐NΗ)SQOZ)Jq 4C=taVU`x!(Pg`շ[&1̧n!RKu %ތ5, ?8W%ѺvH vy#Π h:?}a(?Ճ:={4wmj8OOvܨ:TbmjbV@N].$h |EXZ+7k'+9 0gv'՞zKtƄ3+RZ+͕M MV kZVK#b-6ăea(`^F? g>G?De"X `M|(N=U~ߜE*L ߬>";zƃAߞ=#V7洁.6X$5V8\5ϵ x'XkL/-Cy Ԏq819͠װïS~\־ZɡyfwMYf2-<y,Ҫ(!hY[osV#@{3m3$3؍Js1<_--J&'kJ5게7otsG;'z3|h<v$fsum;a=d?11嘲j[6oY,Hl5䗦2FF rՅŻdq*]AMUs>G`zy/zUGE8R `NoIߺοXh?!I.T' @ w7~?}zMCIPĿ(x `W4=CsO/ЧhR$YHY`3MϏCAnLoj%M64:8oP3r(%%}nkeU|'xļwi𒋫6<7*$H?mއv .߂$[j dvb9 2!c,^B''#֒n+-gh~aqx+լ5L4 {7%b VC+҃R 4fk>%28S+0vU;g2LkJB-8&$W~ѦnAƙs=,p7n6F;ο~VzzPBP0YA#(t݆u~VA* }Q E#B4B'PM4u8#!\\%'JHgE4my0 L&c-Z fyYLe`Y04ǕXRίGNFXi_FljrR'Y|nA Z uUw=U"Im>#/]@\Py *)|X@9$}=,.v YfD7pn<$ʥ Yl%{) 8CIQw=XtΌW.%F4h0= ~ ga{ܷ@۾ }>>G[8s IK/EuhZVqwJߗ!}{™΃]cnjh=0i:+]CmΣN B +ԖC1-t_j-֦"5hl@3lGC93CY> stream xU}p# X SZD5bgH.}rKr\;$B X0t"`D. uF먠]v;fgv}>JɓDRZb}?/ )xZ 698gZ 4(>҇+Tj]V qAj;9} R$ кե]=h.qle.IUTi[_5W@9!ɶ{j#")C٤Ft|rH;TQ^`)A fR|_:tuxP"303Sp2/HVǭ},,F}pUP 3u迲0jNY~/B_ټv5.&#/rLW;rVa:ܶ2'}+Vi(͂?}2. jDG;zXp4{D5k0uX =FOgAϴR[TMT8A[9(㥰PdI dw#s1KPв˿9sCئf#Ch65?ZeV8AU ;9^kk $pB80L~.K~>Ԭo[s_\L|_wwt!MY}H.@ta+ MovXfJiA?&,>lwx[k=FM1sI zPcix;v7\~vVi1V\)'d\yA*NM}ƑT3b պoS/0P\$O85najXzS=5㸎Mᆜ n2CۻoZ0_0/Ha;Cq'rdڂˎOSc/OPWxOI5uo86'{kx?%^~kSLUWbYq (;AiȲ/M3hh?'N}4hX0kӤ)L%{z9ZWjld]nˉ~kMשm߿ھXlvωB˦w7w*c&$g[Af5MyОZwyC𵌆6o{l|h߾C~ ZúQްWZvTpyx(d8 b7Ȋ&V oGt$^VZ=E'"?2:vxP۩tmV[0ExF$~A;y_xoǫ/roeH%fbQB j8NzsӯۼȪZUf|}i(W`+Hd˜0lXxCȐpF"vp q<#܊xK @џ59^1[<8\f__=^jA蟀xDT娘b&zSǖTPgztk9O8S̥yH%K?0 aC1o46 Vk`*&x"N~\$zu4閔-Nwߊƻ)xc&\85U ]~'m>TL* `Ω,܂ ncm`*&2\1Οxʎ,(y3 pJ#z{uec(8a 6jYye 3PN5Q:l^ʏ8t ga.yny 7ѐsi\ƪy,sd vkCu??8<У72+VbtnZ)A endstream endobj 130 0 obj << /Filter /FlateDecode /Length 786 >> stream xmTMs0Wf[ 0&uRSLzV]ュ~}_)gMtJ0Ziҳ"y<ab G&OLHM߲GA 4Gd^kL 4u3˵Ќ}Tawg+/5, ]b1(#6b_9>M^K<>Z\$>$œ/98XO. C_.Ig^L ?{ڦ>t zPA &q>7qHj/U̐$by;#Xݕ1jM(kP9#-iTFHR[V̥rh؞nVRz`SV>gq*NT'9RTrnZMd„"|Z:ƤO9EG>LvXvd$Vʦ;\ ;Ǡ#9?!JxVQ{@>\Vwaas$9:mw҇@Ɣ.ƿ[]F9:IC9tvr!4X[˞#r-[J?:xZb5Tی&5 ~Hr6>^z?l8GQ'cPvj|>~9֢#4Д}W dn3 >,wcm7V|\R.;nf$1Ѽ˾>&ȡpߤvqfvߕQW0O۩txsYYg .A=[CgB:ʹsy]$ TZ_endstream endobj 131 0 obj << /Filter /FlateDecode /Length 1480 >> stream xWK6/(mZ% =4m92wDG!^J8ͧ7YD/nWoVe]}g#˜fN%I\"ʳ"Im z,4!Mi,eN~Lʬ)<2dG=w_7͵\ukj諻zr늱Xfߞy)ke̎}g̱kSƩM[i 1{^;5QQխ rE/d͠x#`a)6]୞ej4\OFUbYBF1=~a4EBL9Z[,\HmZ%gSY!2xslTȥ8.ÚoM ;:cޜT#j?9b+c nWxB xV+.浂ӔZ$`Cprꇃ5exMj׼p + 4z8t  {/&L.OqR奒u5Gg3Pum8v'7z11lxY#x} 8CyW O6 CоZU_[~$ya5ݤ*LVTHrd %(2AΧw)3{#z>8a|` <i36ᾨ(7fa,<ĉ'#!_Mf}l[0y8NUm.`++J0,S<G-g¥ms$` XE  (sT{1G=!CF3A @JpCC _׺)- 2X:3K'X,xdT?PtlZȳ) Ӥ`ީ h-ت1uX$׈)B-h,+Eaf[Db;?T4Ǎ/ L]Ô-;`DzA!"ȋ<(_G R el"!L8|_p҅R5`!Dr-@7_ZƎDX.G`K>jOQKTgx? Oֳz]=s#qyB='TZOp vB2$nŜT]njC+02{/GIendstream endobj 132 0 obj << /Filter /FlateDecode /Length 1664 >> stream xXKs6Wh ؘ@ ;rV~T0$-I\;SrD$>O0WzQO=ZE 01K͎ckTW#HVw4B@c.ĴA`"UqiHsv>> YWvbcTAQfd䌿؂ˋ3kku0*]<-mfdz։3c¤ǴjzFWVt_Xn輛rDoѱ#ktr2B['㫷Nu& RPz3׿V#''޴ZgQy CbD g>l}6a>isご(U=8h X}s,XW/ϻ?$$ mOf({DN&.y| Zn>P#D_%u<)C1vz?pr+endstream endobj 133 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 142 >> stream xcd`ab`dd v 5400q$baa]H~= Pׁ? 7~H/(>GhXKdiVB~FM|w> stream xMyp׵[\ v䩌JNO8N\Lq0fX@63U,gY4fFI-S ؘg Tꡚz;+Tuί3YWlY`?EM;7l{ÜS$=A~O/ojnY*-ؿ5/zb;csU ߛPJRߧ%Ng<fakg`C?&< R1]zd@R]"эmUЌ ~CיQƎs]wz#5K[V͍&h@|Drz\^"=NU6n ~PBDZ \]-[Vhw]qE]]'{N|c S@Jn>O})JtRFK/iZ1yPzdGwH+pq=E8Yy3_hTju8hR)2j-v3kEwMePN'$*(A ?ngtn-H0,ʾ+VI•"/Sh-bvZU OOMb6Qڎpy2^".í]}QZA4Am/ѝPxMo),ՋRo[K D|LB1`]a3g,z//'; esgi?s0/̸,t%փ7\>|Oz;恲F=ub#8 ZQkBmhw̎ů_(ʄ5W7Բ7>nr{bU=VgɬJQ"dwOn)W#볺P m3jrN{:<X;\Q/=fCaɹ9PZTcqPhh i0reYpf̹I(Y}G5`\{IaݸPwϡu߁'K/|ܛ&F4 ݀82IAûY J(*HnTd;0 `| hw rN|d^Ę2Εs*+?/|W''@ .<; gP2\Ҭhf)Є~C hӍ%ŀ,N?C#q#cnYخm-4նSamyIU+vЦǧ.}q.IT`%(ցkG%=a~4=qC~F_c+ׯuhxɵÙH:O . ?|"M6 9=(x1&3ChND~ |IoU :(n h[ jR+{JX.U+aMj 8Né!tFIY0#smzN4UGO]C!`xƉi4Sާ4o8S|E|rG^/tIh0hܻosz@4ӏ(=޾kS@K@/Cui>%,NX`Uu\?'>h$~Avw]d"5f[\|ͮBMGl 9|"x'Yxo{u'; U2;ȓ&I7e<;rO뛖헗Wîz kR٧sSTƶdFyŖnfO++kCuJU6A#lbz.%yw`"9E2gqzh6U9Ԑ\U|cSoa%?6K]R`osBaG}ڢĐc#ay'T$ Ec@5xԢ3Ž V x8b13`uL=gtNP?zPYf*7U@NwfW/ܺ N(wZ}T!Hۓa NgҭlNJWC^#fgٓs=kwI8g_ݺ }X e,V|}3Dxw}anvI|VPR}&Zg'DIqxQDQy쬦֠_ʞzJaHf9E`͌yX!lh =F;[Uy/Y#h}Ã!v2jԦ&J'[v:U,{&7Oz}I'A%xG7 MvR[->{?x\.6|>B1İx%mX]Ӹg:]%@X1{> } 7a0q< !!mvurXM!Pn'%n{\Snơ!^BMS|<=y4`$<@=2IL[+ךP?'<#pF>qy=-Jg@Y]9W ’lO_Gtb"ruC];aۛ!ƅVۛ5ɁÔQڡ(r|t_ԣsfڋendstream endobj 135 0 obj << /Type /XRef /Length 158 /Filter /FlateDecode /DecodeParms << /Columns 5 /Predictor 12 >> /W [ 1 3 1 ] /Info 3 0 R /Root 2 0 R /Size 136 /ID [] >> stream xcb&F~0 $8JdD٬@i{"@$SI,9 RDʁHv0D2̢`` `2,~H>R)$*UrIɫ6h&v)i/j1gV endstream endobj startxref 80811 %%EOF Matrix/inst/doc/sparseModels.R0000644000176200001440000001243314547724214016041 0ustar liggesusers### R code from vignette source 'sparseModels.Rnw' ################################################### ### code chunk number 1: preliminaries ################################################### options(width=75) library(grDevices) # for R_DEFAULT_PACKAGES=NULL library(stats) # ditto library(utils) # ditto ################################################### ### code chunk number 2: ex1 ################################################### (ff <- factor(strsplit("statistics_is_a_task", "")[[1]], levels=c("_",letters))) factor(ff) # drops the levels that do not occur f1 <- ff[, drop=TRUE] # the same, more transparently ################################################### ### code chunk number 3: ex1.2 ################################################### levels(f1)[match(c("c","k"), levels(f1))] <- "ck" library(Matrix) Matrix(contrasts(f1)) # "treatment" contrasts by default -- level "_" = baseline Matrix(contrasts(C(f1, sum))) Matrix(contrasts(C(f1, helmert)), sparse=TRUE) # S-plus default; much less sparse ################################################### ### code chunk number 4: as_factor_sparse ################################################### as(f1, "sparseMatrix") ################################################### ### code chunk number 5: contrasts_sub ################################################### printSpMatrix( t( Matrix(contrasts(f1))[as.character(f1) ,] ), col.names=TRUE) ################################################### ### code chunk number 6: ex1-model.matrix ################################################### t( Matrix(model.matrix(~ 0+ f1))) # model with*OUT* intercept ################################################### ### code chunk number 7: chickwts-ex ################################################### data(chickwts, package = "datasets") str(chickwts)# a standard R data set, 71 x 2 x.feed <- as(chickwts$feed, "sparseMatrix") x.feed[ , (1:72)[c(TRUE,FALSE,FALSE)]] ## every 3rd column: ################################################### ### code chunk number 8: warpbreaks-data ################################################### data(warpbreaks, package = "datasets") # a standard R data set str(warpbreaks) # 2 x 3 (x 9) balanced two-way with 9 replicates: xtabs(~ wool + tension, data = warpbreaks) ################################################### ### code chunk number 9: modMat-warpbreaks ################################################### tmm <- with(warpbreaks, rbind(as(tension, "sparseMatrix"), as(wool, "sparseMatrix")[-1,,drop=FALSE])) print( image(tmm) ) # print(.) the lattice object ################################################### ### code chunk number 10: morley-data ################################################### data(morley, package = "datasets") # a standard R data set morley$Expt <- factor(morley$Expt) morley$Run <- factor(morley$Run) str(morley) t.mm <- with(morley, rbind(as(Expt, "sparseMatrix"), as(Run, "sparseMatrix")[-1,])) print( image(t.mm) ) # print(.) the lattice object ################################################### ### code chunk number 11: npk_ex ################################################### data(npk, package = "MASS") npk.mf <- model.frame(yield ~ block + N*P*K, data = npk) ## str(npk.mf) # the data frame + "terms" attribute m.npk <- model.matrix(attr(npk.mf, "terms"), data = npk) class(M.npk <- Matrix(m.npk)) dim(M.npk)# 24 x 13 sparse Matrix t(M.npk) # easier to display, column names readably displayed as row.names(t(.)) ################################################### ### code chunk number 12: aov-large-ex ################################################### id <- factor(1:20) a <- factor(1:2) b <- factor(1:2) d <- factor(1:1500) aDat <- expand.grid(id=id, a=a, b=b, d=d) aDat$y <- rnorm(length(aDat[, 1])) # generate some random DV data dim(aDat) # 120'000 x 5 (120'000 = 2*2*1500 * 20 = 6000 * 20) ################################################### ### code chunk number 13: aov-ex-X-sparse ################################################### d2 <- factor(1:150) # 10 times smaller tmp2 <- expand.grid(id=id, a=a, b=b, d=d2) dim(tmp2) dim(mm <- model.matrix( ~ a*b*d, data=tmp2)) ## is 100 times smaller than original example class(smm <- Matrix(mm)) # automatically coerced to sparse round(object.size(mm) / object.size(smm), 1) ################################################### ### code chunk number 14: X-sparse-image (eval = FALSE) ################################################### ## image(t(smm), aspect = 1/3, lwd=0, col.regions = "red") ################################################### ### code chunk number 15: X-sparse-image-fake ################################################### png("sparseModels-X-sparse-image.png", width=6, height=3, units='in', res=150) print( image(t(smm), aspect = 1/3, lwd=0, col.regions = "red") ) dev.off() ################################################### ### code chunk number 16: X-sparse-mult ################################################### x <- 1:600 system.time(y <- smm %*% x) ## sparse is much faster system.time(y. <- mm %*% x) ## than dense identical(as.matrix(y), y.) ## TRUE ################################################### ### code chunk number 17: sessionInfo ################################################### toLatex(sessionInfo()) Matrix/inst/doc/Intro2Matrix.pdf0000644000176200001440000037752614547724214016333 0ustar liggesusers%PDF-1.5 % 1 0 obj << /Type /ObjStm /Length 3952 /Filter /FlateDecode /N 74 /First 614 >> stream x[r8Ҿw;[S!5q'Nb9\(2ckG<=HIlfE$F)&fR0-H.eJI5˘3))|EgʹӨY4fFwdY$ ߡkcxeXH=:i| s6LYܝG <ʃ e,΂1IzA+f 7,Zɔf,x^wSa`я[0|+Ơ`S F.=e0TA:2Q fHҐPP$A PcG/Ry|bAYe0 Z}Z# H?:((+@H"( @RB; @ ̝w> `ġehb@zL'=i'Gy1ctW7.лnZ-fyb>_/EU^׆+hnhs ꟠SmqXe>ޞJ(z7>-h/gTby 4]^/>dϯb5YNo hS"T"ft?$O,R9'y?Oi%)t"-6JLQrEAeFU'yQIR>/sPq)jzDj6Nv9A'> t9d _?K~jrcƯmc9qNěȹlʻ0v+c9?9?y޹$|t~IYrU</ sCOhҌU ]RDz?nzQ\ԁmi<a˒@U)wtK- V`Ўŷ$L B -/-u/VՄ Is"^^*ɘ&#~O'>LL0aWWvjwb(ĀHc?]wk45Mo[~V-~| c[ Ypx?-Ǔ_"UYl5Vz;Vq,wY,f-^wZ&ck=e6XYz8wzpp}efmY[fkd5R9"T;|O4:33Г@Ū<v_9 oQNl,>pֻ(1Tt: (mV& oI|8RE2 *rAId?ZD WslLdW'CvR̻|]RٗԡVkMbk2dk~w ?C(V2+l;t.]=l4)<شƒڊyh\tV[&VۓE4mg7ΎQ:&6FĆ%~p[?kw.<DtUڦn$B\}[z@g@9 9jtW0M`eK^FwzlNlqrI[ғ)F._*ƬaV/3Jm'-T;i6'-6,Хo9d6Sʻ#OqD 7KiecQvLޮ4aucy<[U5fhi zʃrxݫm0<x^,(}]r;k=5#2A0=}p{H[s*m'L5ڶ-NeU= Q޵h/%gN9jmbOԂr]SQ\Y#hJ0F\nWo aU9e:cr8˄*OeѡҁFԕpV$6}ջ?>9:E2 h~4s[mĂ sm2ZBgi/tMԁjǒ{Y4cjٶ)V:oi/MaVw&X#1vvj ijNp-vDSf~J%b&t=߮x"ֹ̄;KvdJa:8:hkaZd5tCcbT~S!"nDf6HYW|{={$-4JN⚵)k\j쟁K&"kT6urd`3zoÝ1Wpp‡뎠w:(lDWi}F -J 9p @=ٝm1wF} ٛ{8sLw JV1$Yޘ&.261;Jt:3˲$2plۺUnM;:_S:˩`C+:a&=W?H:hb9t_b:?[.v-Núãg/4 v쯛nJ9x,] a񱶍io >35R2glB^l><bC!WtUVnt}'W)7>M,C*rN2pIha!Ԯg%(&}-L$Av|=ogI޴IUHTOfO7h5o:K4e| oNDroF@!'5L_p^b欴 Hx>{߉7 6ބMRfK A:J&2e"ؐ0ADVeYԚ1K/{jn6H<>F&nJ|_Ȝ1P7J'*[E=;}ߺT{IˍRiڞS+ ȋ-E/ ]"z? aUwW@A+'*fôvñ}:9@~¿qs7i6'CطP\4eO;yȺ4nJşЖ kk֝"|(KsjdEcNӁH,RjN$Sgendstream endobj 76 0 obj << /Subtype /XML /Type /Metadata /Length 1388 >> stream GPL Ghostscript 10.02.1 2024-01-11T09:36:28+01:00 2024-01-11T09:36:28+01:00 LaTeX with hyperref endstream endobj 77 0 obj << /Type /ObjStm /Length 3848 /Filter /FlateDecode /N 74 /First 669 >> stream x[ms8~Bj [/U[T@H0aCf 3\f؅-Y~$w5dRQw%K(1(K,%;bnh͈*I(*¸0j¤!(N% J6$1 q"( "rI\a85I ,خ(9%JhL0`HQbBh"Z@..$,1 `Љ j|VB@[uR+#@ ñi 3@"a?R?HRdY8`0;X ^#)ߝ7 vc=mJ,7P"%%%$|τ)aOHP)d0E,@8|۔ pI>䙴b(AXhh?>%" 5qHC)F)CYPY+$_}[n"nAR2#9d`X>skA6e&7|Hʿ@#"89,ޒu136|-5Q J pH3iwkW>/GRKu@x-XOhXJ!I eطLCBց|狒֫P'w/z"6zvhtEÛQ 8+ӻy&EI?py^qyq3 dWTiDmj{,9[uQ'jQ 5%kPN|o#5hGe9Y^}}= >q:?~i2\  W Xz}Zc(χF&$˨d `G){ƩxI-iS5QgEku_ăsqh#XUS9(!8||aq |lT/grʾIhI([P>d65U4xC:+J0FWRCѾ5m 06B%xRvkZPHZδtQyUi.d=O=k]=w#}-˯:G=)=C0JV?gr?|?ei(鑝FNSȣmfþ,]Xߥ O-|Bg@HkCyk]7_~6?NRlyZ,?bd^ݿ3&fuk :Ͼ 3+tnqA]/ %pe  }HX*=<|M_^@_Z!}aϿO7O#G&~g~2ʋS~/2__|oX=t;ص/>?ƒmW/Et6'd^h$0_ղj9_QLo"d>]@HlXa.Q~ʅJu b02݁:Sq!`iuQ` KxFn52ZC;>Q$35qgnn/ϟfY~0xe@mW9&E:_/W0=[uV*lc5j&*5VV V^wJj'bU1kZm=vM=}UO ճ9;={ycabNbVM!)5$ !}}LxiS :r՚޵ ?dVj )"X.a(.ьBAAA1Oq3PqgxIŴ!Ĵ# Z%3Ÿ`*3^*3RqRHpcI0<3xL5>4_>^.a"d2z b,J[װb(5+<x%0 {(>(BFP*',K.h)\O>bްoykg[%a3+;1u5fL_0CcWy+O>Liwoy{l$eRb}jzp-3n#=FklJ258(T17ns4_kvش.]-ABv[5&w`Fp"mꠝ&x%jxuwUܕG$c}\bְ4ʊL!.7~Teh*e=3F_!b9)j2EM/Ebj8ƀt0Q_SLi3,팝hPvr0X>]Ҍ+YM/C~ޛ?0ލ਩LiLЭ'r%"8(PIZl]i*c7jjqX9<ԜiTX9յ6`ܽ<m9$D9TΧo߼~r(|b2;: JH@C\>[O&tw [0? A1uJ % Z?->V,=.&~`pV vzcXMt^;S/^]*wp;Ϛ7uc,|PI.m]ׂ,`oawt, 43QHnB8Ǎ9a-غ56Ӝ 9 |.&*`i~;77M{`|07Y ?k1)lƒ_'`Oo\U97cbʜMw(aTǝEkRQfuNgp4w=Z\G.]4czvzؽ;[kU':*WzzO8h*vks{P'GS &Ndִ0Hv!-a>%Q>1Nq ߙS=2tlþ}تi*޹g` }=p4 0#Vs648',sxWL10@p.3<9Tf-|͓&2V2|홇X bHF#H4t~.%~ ._b r*ߧE<v}oeendstream endobj 152 0 obj << /Filter /FlateDecode /Length 2988 >> stream xXo6Q, :<m#ov]VJ$_3CRCx)=﫲ſEzU=^^_+n Z]_+|ō.WpWׇ&֛(wRkvܭ7ˢ,6tz#LQJg5ܑpYat.lxӆaWU!9/xLWNUNxIh6{hZ 4pst߁WU74(2*kSx{DƳ}!0@)Yu6v^þ#Y/j{KȂW0W.H.۾j;4ui-,4>G)&^YVWd`cE!68D9hVZb/Si~8;?jxzmȿ?/ ZXϪ3dzԦRq X]?~[pͽGnL3{oiբ wJ:o;䫢9![-Ybù*$FuOQ\% {%S,$f>7얥+%2ub4ÞNpSc۾E:oN~;ve\XCEqQpt}̹,%ZkN3$yeq[ݕQ3IARQ]qT<pgϧnjm7ԻtPAhlGGEwpO .'PMtT/fj&Cpȹ:uU+Xz,, 5d(?h>%HQ"Ak*{9k#G m_[Ȋ ܛoX+DQ$O>ERX" ͡vFEFIi߻"P\8WDl}lK@K!Hsd '}T/PS*T%eJ؟[ /_y-|Vl Ru*zTPAğ$DQ}*(Ȭ`o*D&v2AifZkK Tu!L9yn[E\2ǔ2>OD(\6Hiy,2 F8`y.IQ{GS űEiz|^Cl sA?G!OF*:$h@(/;&a/C U} fb2˴TeT#b@5(@Odh5`F)MGLV Hkخp ZAY%}dt|Zk&HkP ӟ`Yi~lB':pT&iԻI6\IcZh($<էS[΢Y1F/ޒr!{Ȫ fUhq4H"7/$l0~ \'TȊk']** KgS" {!fr2߾zϻ,'&PH51World *5c*BB+v) E!)B`TFVw:)6cmB efCc 2f!!X ? 9@MXK-(>@BϏtEm@1CPPT!s1 frއG56$ȏ' H);L~,ܑ~1`ia'ѩ*6ɹR]ʿj >o[']}TbMF2X2! PC2aٗfE=4%!/0R ,- hdLє{C@a(x(a&]x<=Zq <` e8,N0V㶉Ot+9A4) lq̵ < ;+ Ug<l){GL\ED3D,"ZST2ek2_B2 "̩qJ3ܐ 71nS\> stream x[sܸ{NTxsz7}w+R9rf(k)_1Gzg@u7"MEË~_]H֪D^"iBDn2Mud_śrO-,4yQ>EVN'E* kf"Z >BLl"M prOs:*J5긆sR@k3)F c;+zӺ뇗~-Ho8Ԉx"gBO|w*1i %tNġU[|5C׬PQ`{2 Nl$9CF4KylIi~j.jR0̲A[R8)I?Qܨp,9 mͦxB˝9iAdꛅf`Nơ'՗V[P&m5zw{*t.z EY%dyFеe7gD5NT&yG"/n6~ "\@{8.:C8kvxij9qt8G),8-l[2üS^W4#вs0'q :wT`P#l4:p'jđ j'zB7jx 'J$\ywG!uA`$@uM uq/<#5lyNIP0Df]P8t}G Y0NxZmR3+ޖd08 NcS*dF18Ap 洵\ C8g_C`d3炃c +,ıQ<Q2-&N%Qn bL׵?, UEQX[xnW5x#?Nz W8!'7ry"R\6Q" oF{u :zABNt UEy!E7*@3yPwg]"%y30ףkCo4פ脴6 UnҔpcWm-b9'~vcft'8 eu Ϡ7,bVMu[^O(4h,hKgCendd&A:bOr6|@ E#\\ɋYEn|p y}O`M`NkƁb 1> jW&bܱ,5AV2 kM7e?(j@civKCKi$B S aP Q-0t +!+enChK9=jw$S!\x_s$zN'2]0c>6c .~ 7XБG Z'°V6&N9qQ&(<8_+C*̃_Ə;\@9@O|:@"̍U<65t0}EX Pv^bȳ5א~ :Jv60E|>%S6DYxss{s|dphnJl8"pr\sN,Kl9%$Yf kA~gLfRq:Vh t^4;1#'gw#f9pFiā"tfxD cDz <[ YΨ75bnH~3}NA"bgdmAz,"ӹ4{Ng$b3/CLYr[F\cQK4A< CDŁE,sPzMCC1T5ݼQpӎ 2WL~?ǿfGH 5V˳ľ!95򌴚C| ^7eT̼Rr9GZ( lΙfŝ7MeEվnyDf  > (Y!9 =?g a2(wA"!cڹ]HjtoLE=tah_tx4hmY rjvWXL |l JSԣǺFCx̋\ތ`V',Re|GQy6W&;h} |𚈛,>O3!Y_$x ^?T;qK܍6Wtlx ظo(LjrpOS] <9̿ntrϭO$ 3}nijd)/7G%^~(#J]1iZ-1^[_]EƹD`B9(wY[!q\(ƔU2&bIDˑyk n3ɽ>.Fiq&޾:cv*v\!zy)Mw$MMX>7K&N.'Դb~AJs{+sq^C8wqrm?_lF咋q!zvES@y4`}]%nh+*E90pV7"yn^N_YD?b#u-uJgO}&*bБʰĈi_,hZ1Ъs"N YޱHᦂn*KYm,!lTa?*LʱpZE OkŐS0@ڟ'66%J%9&JK)lUQ$)b|Nx.Q}z<- |jPc'Ft$JW츓A3omnh?xaOFs4ɥA=p9û NrpumT/Qy f(u'"12voܽUV?Z觛/YjL[Ep3 {;ML'RV[,琰VV98pW@7CXR0V,5Q&  U&Z3܁Qd9Wd-ɾzjxtNm⦄FtjFS*D]w+$+b99 \}S!QJ=uI3PgG7WhyHfƈB3K pY79!98as&a?s-$,.#-N` M9[p2!!EOlBNM`9sAG- =Ss.2>|z!D56HX`yW)ί-s/1|2br!m|z#|1T1_{|Ն:q"H5~|*Ր`\Opf;QA:b{[=sD@8'Z‘y! `zGr/~D?B'P/My ֗A+ed6u.@l釈uRIEx|w+1V}MuĠ :B[Ly@fV .6PWz9Ds6@T xTǾ5 Y dݽq%wgn;O{!_fǪo=hoAOۺIFmyZxn6)*܅>N$}J1F eW-66XBgbv+fO?+YcrΪlC̃^`}Z}Θ)jMdzoyU:آ /b?wEՖ/N"ױM?F)o!6BܗۮZj%aOج[/Z>yJ"ĄԜy,F+'@Áa6WrO|ѳyĿA_{ Vd'+:anTI `Ӯwwx̺/ITlxyר*?hΉ0:S=\5@:-=IVzfӓw4~Q3y.BNԋi2FHOI'zXƋ5?XfUSA;3z}5 הi6Y&E|.~Sd4YJ0wg+CaI q9P>,u Ԗ= }HKwo{B;8Ylh\-"Ӈ'<S( cId#Qޱ]G8IAAeCg%MOVvkLQ9'> E\sG?z\endstream endobj 154 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3540 >> stream xWiTTgETR䖍&8DLhQT`D(f-&(jTb,h3!1J|=e廅~VZuWo}W@P=>>?X08c܃1'RK웲S! \!.(!gḱ?X@Qkutj=DmϩRj KQse\ʟZNP H*<)5ʗD1T2D.] K/\jw[O?3,f߹?bGN(jTOEDQk>\|Ç~rVN?,wq$ȇ]?!&kX k bt'ʍFj_KK#DqsW#>9 )gTgŽlN-K֧&2cOyWg\!(r&zP)=5 2pWn:ȹ|ܛU]v{YyGe}/98]-)KhMASB`U< `@S[XZTdLFh;$hnuw-AE7pыOc*n!4$$Om Z~[nIQ z8li訝L T6'(xP-IgwMؗҸ_ ༵n.I2Jlh2nF$!ruĚFͽ}P!3X~uN]Sq酯X.CEm'.t3'ֆu8C}(sč&S}ޒ8$Rx_:}zJ7u9i;]dHWZr<^vLD?"F[}ms]ެJ n$~̪-!8ѯ[?CQMOOxg]PX/eJ3@蕆"@WYeaZEdWNf6 ) 8t%q R4أ=IȊImҔ[Y6w11WUtC^Riv I" "e^kO.'sr9lVK+ȫU8gu^J)כvz,OzSbCxK\*65ot~WngѷQ ?n/N͐E|8ȡ]qM^W,)b,T+S"BC`S_\2.K{|)6>I_׫WƢIxd2mRs-i*Uk+ /C-!;1H UbdH3CckLgΩÃ<[p7 x` q:<]7A2;xcnvgy|܍6N/)=k)4dR\jPv(. ݆cCZxq2Wc#m^YDWхkC԰8(t ?\\lwL=Qfkk>l '[eRe^qfOq;f;]%C,X8mϴtIf|X^čueNힼ4Q ޙ0ÚlSEWk$Ch(/_"]"ŏ~ 7ބGCN0 ]=AP@g+G'7 WԆFܧJ}jXKWf@J\ȤwTUZ XxÍxmomqd@'DsĢ6WubS2c^|ۢ_V͋IdqӠW78[{Gw9>3š4"ܖM цزD_:VC+A);FnPWiY[KX3RvmXjLZRXM GLω^S8҆6!pԠlT*P@EaԲ%>8ԵȾ^8f^]#!=Z)Y[Uq_  s))kC&.փ pW 2ThVΕ1;Sf6b]ϙ1ҕ9rgY1](cЫ}Iޖ:u:>*snVf< ޹VnG[87IZ>>8SnFOWmܰ>hZB61b[} 2 d~L=s0Ȣ $kkjH~#CZ={k:cSu;ō=|mOX˿A`~y2 dLIA9#J&$EO^Φ=NǴx̓挦#R+NMN8o?]panDtjݮ'JF|Db9n|(wy .endstream endobj 155 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 9622 >> stream xzx׶c +z%3BZ(1w ؖ%7]&lM%$$@B r;gl'7ݼ }^k}FtFX>wY[GfyAog^t} )kfnv-o޶0'6&7nQKv,ݹ,ay⊤Uɫǎ{aw&4yk}>m#^{sԖo=fA &!b L %ˉ׈JbxXM '3Zb1XG&$sQ\b41xxxO!chbOE;/BLD|џN /@0DbыH&z)D*чK ^ " .bs /$jܭ.|PߍHDr1D}2uz>4 ^xy{e/QFma?h~`_:Lf^r! C>{e+xuk׹#q j؁7OFF[Xtu:a µFqX}=OA2 l+24eqy z  9$*} x t23Θ(S8Y ,+J4Ek5UpXἀ:ƞ@'҈wcehh1_ܩIf`w@EO p(,lo`P--ոƟ/ sfF7p>w TdB^@wdpҭ L%A1.mMF,*^Lq=)OÂaOdT3Q߬errK̶- s332rXv@ 2H%mY"a **.o8T@*4r#2[?z﫥ߨ]ZIH9*ẃ]撪ҠoPAU$INNU$riأGYՠRw8SB=A823)ۺ Pj̳ IL@N U+}~#pз($Lrn;pTA(>ؘ=eq;>㝷 3 Ol9[[>;#-{ IF,&EXhc`C ֗ D4A)4ǾRe*ې 58>8g-{U]m}=B!0S_J6ȑ| PIi6,C{VHJ4,!w +BvMAvY#IHL@>$8${ j$mB#(;&J(f0Sَ88//^ *@͢08?źq͔jR&ev꜔9zVi`5^]!PVLz {TN".{a8|>e8C4gd7oؕI[`VVnv]VU C0;y!mơc #Kl:#3NZ;ܪs&rK~![~PxPzxq[RْoϷN◮._S* (uW\(!k- 57IE_*B,h+u@֥̋z+KM0mJ2* jjsy*UZҚ*i97uluW5vH&?rG~QT=/l+ĮfG$zwbTsw(=#oގv5S2֐im$jN&; K}7; Lm)쪚emVI  ޫ$~l|`D} :R) wqQqqqQ%efgF_oCᒙJUgrt9B TVK?_Ѣ-pi]?z2NZ'3rVjuF=nX 7Ύzu;h9^BCPT5÷*֮Tz⹛GayA2[QZX^TXP{n )e|֡j*Oi!sAIqdEm;۔|VaX-Rq)`774 N]lg Š `f 4HnZb2aΘB.-v]G17›(* [fk&\|.8J%RӳI|i2 FygzEJ~v)-2B\qr4@&^MeApH-(G`nqH=O;q" Y˹?~(\* CpxJ1T[=|qg˨Os``OcA%ɖL)=3H @PNʠI$X%e7^_3"C߻vvoք&tJaKgU䜥M{e 7N&$sBA`/4ߡpa8\L}9[+γT@g r2gjPƒ{9dCPQG'~T(5@Y8bkuɂq aj:c`;HU_g(׾Oi{q{q`SeGb BUSY4;iE8%p'\yp!; F#֨=+!$+a$/S~=ps+sR4&_'14̅$7%RþIWa8Fܻ]NB>iIXqL2K!'z(d˕BIgk9 J/ϭ*+Z6z7ְٶQ߭.$qgp믺)$$ct5 }̓ATXm)pɰ{Ce%;-Kk~Mp*#9.x{9Y37 HJR]Hri%vSgp%JBkPh/- n0OzpUvJYuk-%aРi0<N#Zl?ߜ^?rcXs(4g ge9 =sW+!fB9{cӾXG7]Bn7a*(y(+sx+8\w!gլ3NYN^˄Se*Z5&8coyaYaאwz64@~0Xx'p? `<93}t0] +3Sqrܞߟȷߌ4;1F?~&fHJ3\P* em98ڊf2͌ڢȖyz!1KB '_/ tT4˼$w| p> nvmk #h0 kV#O>?Yn3^6 PpJL9\JFʬĸfjgRkI3jMmlقutl>`YԷw YtߝrnVǎ#M2pQHm,-}CSnl{8ѫ3HfJz1Ѩ.j&i_\iÿ mzVFkrsM==Ey~nJNoNYcTk8t>c hћz߸wGL[6YޢJ/\P5p{ѶI,'ň_ ě `8#"9(ÝWW-hFp$\>'8Ѵ_{aXxD @^vh{b&KN#?ޜHHctq`x*(;"ɮH2NlN`0X$| GSn]p/ݪ}l׷Ḫ( ,+Uc!)dwE_d= {?*d85* p;^]UW8|[B47v<_$ =L%@6 lh@;SSh:O2A;TC=O?֫AJendstream endobj 156 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 9255 >> stream xz xUo@U(%BqCpAAd"@dO>t$;d "paQqqQOs;d}y{9Ur8{qO]ѣGπD٭fޮF.{JeoZ3vjݴҙUīg5gܵ֕-X_\pâW<;>¸xKL|ǖ=O5)p8rrqqYySYy(ucŜ%I'8K99#9op^<əř͙y3 γ1Y89spx{98|N!94 <N@˜8ws 89\=8@xy^]>q Cm;~ŀw;.x`5⚹Wȋ[vAAYr(~߰?fz}c M?zװ.?4sß~#8G^DGy،N>?{ sgTe _vt@k/SD~eV;]fWQ?c1Ӛn{,4Lt̗+E ZW4,H:|Np-'UAP_܀FA#zIL<o7 XFTss,)pa y8.ȸ&TC?Ke* >,& DR'8h qO,/?{P4.#*>3xgɐ7QxT+{2 q&Yԝ-Y<_5y(JI;aP~F?Pynv;u˟9U7!_~ge粳KT>W  &[WIԪb[& p[\n,dRK\ӕe7eZ3-_ڝ*@@HP.2Wӏ܀Aop\Ohж<W I_ pqOכ EjtDL+->~*(nDɺ3y;󳣲Z@ǣ=Kq=&~;խqVUb@t 8 $3gq}Ph MXP 1LQxj8\-yn]` D[/ q|z3ZJ-   tWIb=h6OʒWjZc~3㿨Ss}OM3s,rO\oȝ g1 ZKdj0jb.e_ hjĠ*p,,y6;^|ʋI\%1F}XL0cD%ʴUeIJ"Q?wÁkܶAI8PvPW|rΙ]5/~oBS* V[wuec1"Wp%jz}µP/>sG`(c$g>,KP܍i%UU4Ÿ1R|"G]t3p_&6ӓB,94 Q2(Wb2CԌ|O>qI[B-=5Ͼ1da0=zU@Goh*K@ÞCchTtk/oLb38POa z";7S*E0oPpM:V).\bT:ry ]p~* d4ikƝgįFIuޮ ,aj7,åj*t&Ag{zLpIgX=oL[8Fo5&ESe ,Y`O-YNL 83 a!~A$r%B7UBw־аL4|hUA>jD摇M "`$a a" DBʠ.K~e͋Eپlf$~:q>.ƸWˌ zۍMNA`TE/4m}]o%r{~o?dZA@Xă!*qNz}QP oÿܚ*]UV47\|_;,aK`yz]7N2#pbŵBDȓLJܸ!pbUJ0lj%†` jPV*J+Clj?GE|v"V|~H`nɂ#P.yQ[܊ U;vη=jJ8@P0lRw@5yCQF#r`!,Zc &2 _&euRW&%XɆ)s$wߌWKKg&Eov6Spl7M綰- G6Rt ,$GҬ b. &ohlr.GrJ d(~KzC6BN7Ա9ZN 2)ƚp>PJ(:B4r+4$do`_1X]6}|ۋ jhR0KE^6Q0RW)/U睰4r3 ;")TlmIC<-WpJ]cNm#">xR0CّHyndPO w2@c7&65l,P/y=(KX;7vJⅩMAG\/l8QUGTIB\\ȟZ?M0ͨ6jDӪMڔhtZ yD=s_t,FgBǩv:Y'zܐZ[gBQGa/ 6`o|VJFr+>e#9 W,:X /\_4K~+ z''/]AcgMj T%PRN9ať:"G n$e6P&3F?+Jg qIt݈܍=W{dvxzZH0scFr%yCvdGzB7Ÿ*PŰ?|v; }!.D"h}Wv|'n">ÞBEt%XO$w]0f ޴`Z0>"LYNbt]dOi,Sk9h|C XJ$gYxPo miߵ-$x|P۩=,.ޏ!m$9ښ훣-D; umY`>`.xvlq gU~UaAv W9`u E{P%QY/+Z{5f0sh.eGww%tvCD4GիϮ~5+9L7vnH1C&,/Jg,8 ~G\2!5IoȃF8As ʨ!Rgd+.( 1ϓ5am,vmgdË1YrE\LrwP8ܦq#8x vi^".]YoO bOM.߻no>n!+ѐca߆7yDA;}O1>* \7旴Î\B&WHAe?B7Tu_`u&" Bm:j:@1 d؃O ȴP | y! A#?aCfcM!6w*ihC%|c5VA={ vG27bK--'V̯ި3J9fx6kge[} M~7k1fR!Jm%RBtkv@]90}/.fu18tEÝz@Ju5BQC{}x ߡޥ4µvt | 6~][뗏K rN TLu46=7=F"N/!ؿ"jrњ714+o?Cn]T04KKΞP8MfV|Ld˳`3D M@͢TUGٓ+&IK-c>#! I/Ph=\ST/1ICcomښ3{a ?ͪM/~R{sY|鄯&N4{tO`L\T[|޶кʺʾZ_P-QMr8.ҘEfܛKp,m%ӶRkRg}yQܳ'7 qd uæZ>tcArj]z |Nmi^Iկn\hZTw=+ˇuXIyen enF !׺&)+ |vqMDu@\dׂ? h)hrJC7F8I~C%5W76bȳ2@՚tǣ&&n7YiOtॠ"3bB&ATҙ0Quc Jk9YN.n'3=>F#Nzd!w8y|6'0E:sT<4ȵr24~ՕpEš`UX𻂖>wWLrd2›OEMcsNR]Iu7oV XL-JM8}Q~:Fy]6>}1nk^S*00f,GT;MI nƗ ݝŀ-U "aLeAVaxg%C7|ʁ< 7HRaEH"WuJ9(^W Vh R&M*I9Ŀ, 0üθ u˞ρBi.@e$}}:q$wdJڟ).zsI'0'wH=S7mf ,\RtU݃M8^RtǮ]Qѥɯy2ײrjis'dT* -)[Qvxi-ۢ4ke.EX J@ToK:}1|Q*{T]``[`[*nFɲ.In_HsN: {!UPbeF|̨fK$ !v <z{w“<))r%/1n) Z٥Y$g~;ۏ{}KJI mH\YzKڀ:yقk1\InQ {5T0JB:у]x `("q)wra!*&`6ҷ0֜/CQ?xFhněq~z@ǬQ 4$WX V `RYxƊxb,j"D2hcculQz`KztsXۖ4J&#?@q磻g\)2{]~?8t*IB"d3 ϊy пo0sg´ 6ȑ!]fʼnCca} _>v,}/v9K5zRRG*Ux=}]s;rmaŖd Fߜ9Bk6= =H19Hu^Elc"K+ǝI%UX4˚MҴzQIղBNQ C lqmB =UX$V=F߄ív_]#7A56S?UY55U˓.VX˯0 )Pjpϻap,ژkIGPX`0>_cZ}_詝9-*JUDqܺxN-6D:q@^)W*9I@DLx"t{߃:F4n",J̉[0@7܁1v-K4^|ͅOn vb8 =X@u cMmMe'~UnA0I W)1}WLhL<ߵ|TNj4d/$k*ڨvBP\ɦ"'DB%Z|NWmB"` ElwCm1w`ɩ)sg:waMg U6v"laڄ".I㛌lM6c&/;]<&N|#9 ]P^1ʫ≦45¾H WV~Wg6lPP&j@=U4i=.b6Ʉ>Z%n;S{pdg!:u/YDˬ3LRHZDMP; W׎Ҳ_odL6.:Ibں[83} ؏} u/;5c@C'|?sdDkZShѻ;~r8=!endstream endobj 157 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 364 >> stream xa SFSS1000va  RS34rM@vKJ%Au[ы'}}}#ԋ뇰2R`aUxf~dd+kv8rqrypN7?o󊒊ͱǏ{iy\XV+V%.EsuFOYGEGS ? Qendstream endobj 158 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 7378 >> stream xy tTU!) *F'pT,!!SUja1X@H,$tb11XB,%b<1eD11('q'A41EL"F1ijXbq+QJۈgT _$,:SM^o#/< gI#oԤQGS:nfl-q{md]x=!ʝP6LzOq;+rDz!}y"=m◓6Lro51v৭=ݟ$*E<3݃9wKнsw (I b)τB*$zx2$=?~tw[;IKP b-*3j3JAX)4jBMd3CRP2Kք!F =]S4'%#h&3f& O}_d2esA%! ΦPiL1 x/YD XRgh4$BxTѕvwr×2$`GRMdD)7 | l+IP qEPBo+H%(k{EYW]WśѧEߞG;OK8 Gy/32ӏ=FSA8h8W~dn~fq3WL?9dzv+j{k~&m󜚎Ky2YefbCeFS?vPN3e?ͮ)rmr<vU$jL; 9^{n:pppprSdSB%S9:ZQ0h$z`Y))OM`.NWcMH y6ӵ˼kZ*/"C%ݻ7fh{4NΜ/uQcv#eIU@"6K2C:vM ɹ W4M3a=^GT{{ޖ/oY͵jM!QU$M79TՏn[P}psU,*ʪ"լOԜS7'.[%<(֕76=B? DςxّP44pgux̊VoTs:E ˞<*Miu?/^GT4 M<} l%g^?7OI8^1g@2ICIrhk9O&A^xCR 0PԭԬ4T555*BRZ =6|нcSzrW}u#!3$+"WШDRtV `" K4Dr#53tǘ0?j`ǫ%{A&O%~=SzM_&W i!B%Avmxz-0t2׽_r]C $VTBScɀ/hŅx~݆':'‰=nJtmcThG@M2 Z*s5;>yǥܥ>k I/àݛ!]2F1L+)9 {=ƞ2S־n:YFSkEG} Q43Ur0M tfY~'mO:3|Ch3ڌ5UM2cMLg7^:㍽.\ ,9dX;F)J;VtAypqW!*&H~,')HqfGS\o^\ͫ=|;y;SkKNa{kz  Ө Hz:*ɲ6@WWYH1\4`xA‚H in%$>5%)vb|ALaA٩ (>"m\ىUjjնf HfIHXzmA"P ~[ҪW UUb(,/iv:ri;5FV#[޷\]CF>dB6deBS)VhM/FP#$z! *2]Ng*>C^IIhB" @@2 hf>RaT;Lnniarui\7f¨5YdFԺiR `SʈZv^Ugˁ_їRG3hFkؕDv0 %RJfvUhyɞW 3va۹s1%Hnxr uM͌`dƓLو8wnW>u0'ijO ͺfHȥ]C2eʪSEhbčS)$V/ɤ/<nԹʼ/y_l:.8/+ qπysC/Dz暸 A66Tp6 6([fdž3puǵǴ5'7e&H.bZ$-Pz[Ȟ<fFث"fԲ/$SRwYqwBibRG)Λ2*7{G>o iI=HB' (Iql= N|{uCC@-X-BfX2 X4*KŮH)& ;Y{2'+\3}u1{'E w9/QX=4^ 0*k{(>GLisOWUv_xGbu=VsP7 [s϶p(cJBg>8~!$,KRh( [!9hD@̅! 鯄 Z.*Bfܻ9}8)! XBSۨ;4320K DL5imf,䚵@Q@ <%~'І>4?Nbg@ Q~"~z  c#@$b7L@FO ի_}3 Q0p!)$R׷j4fd1MZ'E86R |)b#&;f\S *$(v2}jxrwO 0 fY[W- Jp ++W UUu䑓!fgZК)(:1Wr* "HZpsidr(FyɹM/əӽӵu$Bd~6GOPi2BpP 94A,R-;]fG167PwhPsBL0 @+^+c ;T~8ĶJ9HSnyM^N̨6pdl2&1rz!7O yyO 4ee1G },tV-Xd/rNR! 1O= QF4 }}>$ZqhagyQsbOAU$PKhP.qP,ȡ %p$G%+LrYkZ-AO4}ȟA ~l9hp+La$ٮ^ᑕjۚ(vX-!XO#?'Vg9(Sp)w -p-x$N ,ۓě(ɵG\!r zjm-Vp+W._?\1Mk֜5JN*I/ } Ma!uMyU"zJ-+t#* &Q33k1jJ=\G#vź{!5k=6{j &1Dj 4qCw~*3jfuDXTyi}ƥoYOF`VVԪUPjkKagdgǩ{^`*p\<&X[ ۻyO!{? wxv;vaZdkzѦyGԂ$ǴewЅou+sSΌdV43PBIPvm{{+;p  QPӏ@ESN_3-'Q}:3ԧm/=^wiלiל9MI5V oǫOQZQ r.ّ/nfPjE8  *3c|jg K/~x{kP{P[ S9oGߙ=gz>-3゘ *DoaYgt-6U7XuƘ'Q;ם y1e1Z/d2n_(\d򽎭83|ӅhZ?̯L, I6t.L+Yj\ӴZQb1`7$QFŸdl7;no)78+b,wb¼e.'>DS1ɨ"*U*4z5n~-漦+Y&^AN/~ʯjB#Ѹԧ/.:b4 C6^p=Ų ݚʑuJ 13n(_ #Fu.f+cWmjyZFA{w!C44AigʧU:>Y4_ IR.Ǵa-}v㹗mjKג:kkzh1s;d ~=S0)<*¿@TM6 z^QePj@yKPN G(,ZTByH]Z= N̓21wΔk("Z>4,^ ,=*وX&֭*gpR[}ʻh8Gy~̤{^zs -̊gv7%CPhɾ^pgO.QVEߌX?[>Ct̝p&C9ycX\`[ p]|˜toccFVWjAx]x֘ګ*lDbQ[VS9yVڮ U,mUnsjc =n?/ߛ2kj Y]&߱rvvvKsvi@V#D2H4/ };bn" ϔTzHꄎ.>wWxcCƕ~VFenj0nL2^;(䠢kwT F ]\%s*:c.WO>?kPhnL,a3fgg,Dk\[3 y_)`fIU&%eÞ覂 p"d9RY"+ALG UHj̔ɢl6Rb5bQo\WQ&(Ħ͍ ) v+Lx8z\ED;F;Ẅ #tx`I>4%>ΐ45a܅#EKx9\.<pq8S{ԁ bD˵T5ZRh3&i I6oiNq8q_Dl˥^yōނ x{:{g:b|a3)5-]aN UI 0u\6@fLK=Fa `?54l%g˜#}=k[8Y12 WKB%9;= I7\'/[/3 n23 Iq@NO'|&z ảmm V÷>$5UxnH?vendstream endobj 159 0 obj << /Filter /FlateDecode /Length 2168 >> stream xXK4лLM`;:=vkc[s=MYa#gOeSΗ ]ObȾhK[:A ƒ'Qfc+P7ђgͩC<(EET9'q[\ 3aafNR@$P6&KyuVtuӋF-)RMb 6aѢRh\3My~̥6dtc6BdK(3&[exm[Pcd7: {48tIWǣ4̂C 2#K6t8)H,]oe&iԜMsm}('Sř*Iׇ BKp fcՒ4lM? or!)N^) Ĥ؟6 RP .|Z}jjo%{Iql''M>]oeCf8},fs?$*2Rq@wq Xug)ͧ!jػO0)͙9o\>w9qa D&J`§T!0BUnFmH\R8|-8=AiS"  !Ve )QGpoVB[M1`p~xZt#)o狩z.!E.mn _H#˱PnԗVy$TφLVͤs(:XfPȟWcR*| ^ ڟęƁG$_Dc 6J7FMo(~}?aطۑ^:cFا- JT*(CC5l+`Q7(h~(\^1’RI:.kB#%hx9a) B>zV"*94ҋ}f 5p`& 8vCZ&QK]^IlIn3*tTa3ZxHH2oMp]ߥXЧEV~qGY}/7\CνhaZyMo{$(Mbl%L\5I*{AM =`I38|ja' ؐ*qq]p~@}qpw#EWǑ{=", ȟh~/eJ1^zLfM >QZl+A$iw螲_:4E䡄p\LA oᦶVACRmt_((m -Mpj8-o񔸐ׯ~mcG/~yiPBs Ӯdz(hQ2-Ə m0Pwhho j|}5O:ӂu=hXh@̨ ωUݼL †ZAHWM1VXʳsP^lc#q.flffh>6 -_cl5R e"m:X-NDDh:8u>in\]M~QG|]I$*MDŽ^AnKDE {5 Yة6z{~5/"۵3,ӌfN3Ʃɭ3 +O/j)kkPXƘ̙Vh_ʹ eՌlsRqcMtܔoDžKC80C)wo _A&|_kv'|Xr>| )35ҿ@o6}X M دO8@*m>uֹҒyd?:Jʈ%KUXը8y3%i!@}1:iI5TnƒM74nO~ό! `(*-].;%/ + _E+|F-sA-( eF8FψgQendstream endobj 160 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 786 >> stream x5QkLY3wa!aj?EB4Q#"$l)Eږ  m?ˣ%*XRqWG|] &*zDk$眜à),bfFӆ уC96 $Liݝqm_7h/H[f"Qqġ*f)Φ05Q6sjBTutd$%LJdsuu#E3ǿW \* ;5p0B٨*tsՙy~nT畠 (P3⾧:#Jqʿuw& M2 |+ulgTe'VRv5I?@BscQG'wF ?d/M/vz:K esW|dD\m'l ē^2ѩ,ٴ`sWHdU~m`\CYe\0sBCs>V x}1|٫rN@ŗSb\HjvB2w>Pϸ2 `tHddܼs#Q(FG,oo(t.du1xM7gU,Uc uK8NLjº!.}O.?UG8uJ؅YL.~M Hu?(67t`~t3 x:mw,?\jvZ _GSnҔN~ű*9h::䈽7(ki಄}5>\Vendstream endobj 161 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 9995 >> stream xztUa<,D+1;@JX@һǽ[ջ4;hԭn[q I i@XBjxl{ޕwNv{Ⱥ/S YAAx|Pzqk_+]T^C7Ȥ瞫{ /4<%[m]v;W,\zeM퍷~s. M%2Ų;dKdwʖʦɖɦ˖VfV#[-)[#{^vl엲dd/^= +{P6O%˲Gdef"[$k]!+*H*eje~!]/{F6E 2w5ѝPljvgE'ꏯ}_^O8:ugy9[+nc%[7l!#N;o[uۇ;;=8]3]O56g~=_|tf{|-(M2]jؖ˯onPWs+PQjq+f1uVGۼ-bI-G`l|vlw~G㷸| S (Pm,F.nR6o/]05,h×J Ez@CaL륽%N/ӂQSۅh3ډJq~#im>Y{ ak>< hwwm"xǀۊ@VA\7@3nc|G'ǿ)bŽ5sZ^&&Ѐ֍|p=E>צqV\qFQHdCɓoN2\'Omܹb {eLE #Ͽfh~+Gf# $C9>Cg|ZBg޸7p 6xo+xlujOk_.^ )_Sr~O1xkx O#Ή ^n)o}v̙:#cd̜ۛg{bhTo$ [d}xϗ -o.]}EOx#.x;| *a ~3\1svڦqW_ CW䮮A0tlкu$tہ( <0pV+ِ7 li/il$&!@ S7u n8XS_TP)3`C`5[\Y-_ĕΟ,xWٗ{͖MͶ fZp5fslG`(1H ^F9Tj ˳%yp 7x`qMB;ԃDy(H;zz3pPA]fR!ަm7zNWnxus$3ߙh:fofI=(f51S_>~'ï+ .A=; 4"<$ش(wmE:4Ur3Y],IkF.n2otdAL՘i$@:s4F1c lQ+6U!)["XT23[3yrFAX HžPa/E>^WWE5 dAuy$w+TN}Pڠ.ݛv0Tqv¶g xm݂)ы'hKvE$*w(ycv5WQQq+Ї,Qp Sw\ 튘O\+N):S٤>VGϾY/ɷsqDž"mswp U*F Zp}nv_ڵv3ps/ݱ6یPO'*S~2Bp5_l)&Ю\ @Ҽ`6-fP* vu~ݦk]:ҺQU[]cuTօ/ n7B`v 6rSZZ fmCm~c^v)X2o#,L Ou"1 >_BN)\ZWT8uJڡvqg οzP`D)Ҽ$[+b XaR pP54 1a88+>D%M(ѭSC} \ͶfGzqR4l.=)o>B>Z ǒ 呔]Ah=m k0Q$A2#p^B>!(89[m-j [18K,VJG f.]Rf@ŸQ}/Ms),Ob҆X 艣BrB[0#-6IҋRܭvU.WW )XmCͱ Gt A,LG?=VH 1MhTzlKU/w SlxG^re8E7YH+4trr\h_0'Ƚ_gtGMA}]Nciيe(6;Ig(G n54t4 `cUnہ4]p@нXh}}\G mzΎݒ̰'}Ty j$v`.Z8V7b3f5NcG^c_CY7.L#J(<y,D3jb.>Iȑ,|N/2 kj A@P$JKtz)DrPnnE5 `߂brǷ7?;Od&)0:س`۽5EmG(IwDxWoPx-uC:tJG4˻_c\ x4]*I_L _^Xw^Ee"֎ m[+^:`\KR0A}XP$)jeGVѪyjr#p)#(2~Z(hݍփeJ,xՃ-...0/I{5:>xɐ,510_GG.puK&6bKmFmOWHnv!/ap nTFa]]b'L4/4qPl)Us7:emw{]O l[tz S$Lʗd#^"<9χMfVECΏ w Lj;L*~KѾ9հ/cWyz&̛ p=%E ͧ[ЁPdxе5ʩ xAN_ڬ_ւWRO7~~ndt&PZmC+PeIϐwKd]̄ZTTlmQϠ2)omlۘZd͂@sCFa7#$#KL sl< %13x l`I926Ž{ Q*xHI@H)?<ͷ_Þ 5)H0"&FHݬM$hި~驗f\NKdl 9&$QC}]ʩ *-q47^"Rp7(eMNphsHw| MҸ5*/Bjyy>0k%xxIwfUH,՛ԛ]n48rpQYCvO7lPf xqe`) 4T\b\0hn? *+o4btgհn]zw?| vF>)=y~\"FJ@5-۴V\j~[d;ҍ݈ztB"5&l'"o@tujK#ٲv.[zj? VϷJ3B.+ZZ[#Do:wle*6J}]$HYz>@`6o޺v1@Ĺg8&fϟ $}I=PPIL@4 ƮVrⴐ8]hB(p"̰PnTʹ2ðv!/Hbz<)zR%~?>V PBY1D7)%ߟ!Ӂ<Вd.N*v4}TRgU^3!ލY,ȫ.U/v&ɖ݇(KAG#hHMs4t=8?ЂX~flྷ9 >7ŕ6 **׈Aб"m; (uz](F803eU`3p=;X|yEs c8/lcQꗂ-KMS= Q @F;njM`"yS>l ׁUvG`'I #m ="E[7)pQpmІ[b]6mU:ոnuTzĥl(Lh=x@{ű)MV-ҘywbO'2!D'&Oѡ * \8`I#f~*z/H: x!i8Gq#7 yN)H. $%d4pVʨ2ЌV3K}` tv-eyQt] s.VxFxfxkt)K”SЕ7;D@2T1w.Q֧ ; C7?混fH6|.*,Vlw."qp,p2ii~x5)BIJ;% wƎ}Iɮښ;ę<)CT'-u~5J!6O nwqxsU̕kw7J)fS|sJw  x q~K7 rxg8pśHɒG+ mA)x84 >Kl Ԥه =̭v]jXlnv/7!7@Kn< i5u[Fw}*'5D=Hk<7! ǰA`0̝ j XZj 4ڐ#fweW3+>9K.x2W0 (2K>ƞqCD.Yd'̸ Zkot\m{ީ:D pfFH:Nڏ' p :KtbpVI[@ۥH~1%ĺg7=m|e%%Z'@2;O{MmRZ[ʤn.8gO^8 lD~j!i5ԁ**2X7"`$&mn1OH.&= z-PV./iԼ |s)xA mvSZRvGG }K9::z`nA /x{8Mp[E}^ ~;#^\{vcɤ[1 mV4ƐHc~pSݨ"l4hXI j`yp:yVLtL䰒K33^ǎ~b~rjAEmdU"La/[ѯ r|BDKԬӔj֙UߖvaϢc'D{ wd|,q0>>ڲkqV)ZVC4}#IO' 6B~JdDT;PwƒeVE| o3^{Luxii \)K7po_pn9hA.5{D#EEN'ܶwx6ҹ 7Ekk5Q[;>P܂6 HM'z |cq8h$[c8l2)W Y{GM S9DqA.'' {BVB\bn[ Qq=X tN[6fVq>adU5N^(*Jxt:,.t̬5 c@M.4 *dt 5tTe@_8TNv4;<6P nZqǑC҈^ܥR5wy";t04>X<)T}7z}o8wGt'L~萘FglnynX<EϻPz +oq!$EmDyf`.Iq6`|J&M~7CByvVT\5y]1Ci2r_>8W%ٴ;r}\*@=n)o[~Rg5Ȼ=W v6qLN5.*x8FAQ_'];,}af"W^%RÕ?%U7BLբP x ډ=v˞lC[+j+ڎXB [&M٫L*@WeqV(54wjR!R Z\?b|(K7(}]QG7]}݃ٶ4?7C7T.5'"y*Ci*i -Ql?ʠK&ͩ'Q_q [Z׮?Sd $ۉѱxS:LhC٦.m4uзn"B~:vDq*.t-&)+{C?m6m"`:Vnw+NoWr4aY%: z%Xx;ѱGWjΜzK}(ZVذjƻwʑd6n kTZcDgHP8F*!RǣR P,jmZݭ=}N!#E[GGҪ97We7з5c8o[Q76i†4aCnЇHٱśa5`R!綶Ho?Ya;>}uXcn )l<k*04M-&]@A?u WB]\ّD?02-*8RH:dXj?Km8je.*\'7;{ƆO_ჺlUemmeMʜDž`rC?@RC?W+R}8ix`]J\Z ^)Ěm6Yj[BNk<@;9'a%SSgMx*B y}{*> 5Q㼗B.{9a=N"Ϲ'?୰C<!Ժ2h3tɤ+A6?=VC34p32ζ_po.-#kjTnKt׎H/Q F+aP5Ic6|Ƴ?|+8h{W4,CPALWn"/ޣ+]-᎐/w)2zT aEEKr*A߷ "bYY'("q $,@ ~BIuL/cFV#-VE`_-z;4NqEqucm[xuxm[wXۈg fT&im2ܼ''e'Rhmt4W+)HK=m; oo 5$"&MrN%y6N DŽ=Ma9١nq5xW4v˂ƕ[MKm N&H$'q FZH#+4h[(5 Io ~4FVB9ӣB[SlH-t).g3mmHGKCإAX0{DKN+'T&ΤA.\tI+WoR.ۉ09-`AOl0wCNѾc/egS)~]ˠ?VO? ^=L:T 3sg5^QT*x}5׫'j7Հ'7 ڤZč^=1SNTp'\ l {"ۘL<4 z#!?DŽR D6f󛑛ViZ䏺 ;6*jp5;Zf\4`롃`OK Uyq.ӝ> Y$l#\-ՂO!) ιj?endstream endobj 162 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 798 >> stream x-{LSgƿC9|bkͤL39/xcy[@jiz /s}yp ɵ&F'2$,1[ce;IX ><ϓ0(>1 -wSyXNXHAR2KL͋LdB鑀 .xtd.}?P\\4%Qғg S7cg9.Y+:8e,",ld5l? _\hn$DiѫF+e+^N3hZRfY n U~UQߤ oI7DBmUee%l?dY  W3=|Xj>=?C)1A \˹kUzRc|U$>N$>L|A \|WNk?V}ξ ;uJ7:3kcڟ dP } ~wP+٠PRi`I' ˤ c^\S$A)Yu FFO> stream xX XSWھɹZ5uf.LWZZk(hm\ؒ$@6''d#@X`.cZuCu:N[m۱3'gN;3? y9y~wIDTTAo\AP$;x DɟxĻ[6ff?*+TD6I\*N-TPiVB2Gh\Y..-)6767Kڲmzߦt F?Ci1w9a~BK ]h? u*EIu;UU;Q#5IYW}&ط;v\pRCs㺎!U{x/:y^$lC'П1\r-;Sȓ:=_5UVYIS_;OAީ.Rٚ2&pkhuc_vh=\(ܶcz(TͰz'K.WN;aw f J-j,2O}~[3l%GJCϾ\9VmIVQ"p-4./ Mva Bɦȷy(a8PUsUZ%G+8A)m 5X.Rql7 v2J<'2wiS-/;R@LwaN+Hx ݦ`6=9l'@f$}L u:<3,nqhA*| sZHŢTqJaH[.w}'{>1: 尜k}R}D#g>glQ>Iv89-w/^lSU&mGXB qrx_lX/9Ql/lx [_W6B2Ȯ-Y &IƤ&\}IXpΚpa->-Fo s;2Tjm5j| RT/Qt Nc8 81dl2rs'/@-h?n$}{<@CY@RPʳ35O}w[ wwWVCGS;@~_nݘ nCo<F0e_.wZmƔ%K eFH#0 ZN J[ܡpT;lԈ $QgtGnmj|oN9( mUbT)3k4bM,uIմ%& Έ*ƯI$F#g!?jlst1q] _ z[L[6ێZ,Yؿ>6w3ZH G,kUxXW}Eӭz#\M^%#. V? M \NgNf߲`a'޻v䊏X-V|˵NԘTSwm0ş?,3Aʫ8QW-J,S^P ZU?O}i5n&ߔC'] ]dg 8W{ E4bXBR$-m5MZehݹRܒSޏBxwÝhҟТoѽ쬺y܌n,n{+c"CgMgvꔯi ab{5OmPXߟQ$-&^q0@Sk#S&]źW wq~@~n>`4#D4+#4m=vC$/i󙅛~Z"F(& 7arxpd}.^ÇdvS?= gv+S'7r-tbN?ο>1?^8%h>DI6צZb?aNv׶#8$uǠF1(Y QnCR|a5 u6, p,_Mt- jfϋZ++;#%+Lu\ 莚4HT*6le7@YȾ|݈v5nwzjK D+!z}h%:nrMk2C2H.]d*5h; O@vy<6ZiRkחeJlKShDϒl7GIDmM+' 0vt?E]Wsg69B, 9-"Q隀m:Fe =oGtEB1*Ⱦ ~/ȸVK,%5nE%Xu;ߪu_(aIF1)w*J.ᶘoc>wn!>bhC0|n:{g\ZPW/E!(0$:Ģa;Df$X#& k`Y;t 3n5訒g1l넔|lwmL2#}k+#t42GRNoK-K}I=𷐝W$zcERtqyZ.PB!jns:=%rFendstream endobj 164 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3594 >> stream xW xSe>õch59#ZPTt @AGlRBs;4I$mMNB[" U -e7YgfVg{xfOKggwr{<]{ѣ1֯/|0Ex60>:9'Κo&aDe2LU۶{|zlOŰil-6+cMK؛2)Uil%6{b46M&bd, #Y]Vcl8v49 6d1;r0h¾&j&~BI(&}:fἁ,E pρ8We=PG[ta2ui#n52D%/SDpʃfkl&}ux` 4~ C]{wO+E)&O]KRЋpVi8C9nƩ2V)ZODQ}Plkp}v /*#$UF4\d\<wo%uZK+\)JDp@Axz eKeúJO^<wϥ|^)uzPG^쿜зX 4vy=OZ=x7YJ[TA7Ÿ&@JT5x3Q/U _ ӋlW1ɯ6.[ W\|'|V`qX{u=7 8yߤ`^jj= Oߤ HE0K5;7:.(U-{N k T(RŢWp;Cv( V]-U|DPux9g6IFߥdԗ,ViQ~/L1OMPh퐅) .+& '*y}d:RԠ ԻBdv oʘ%ZWw(._)%d~H)}? kda#jx2*S K0@: K΂R7f!,$Za!V8k@8OEvaS /1 7F ~|Jp߱KS]rO -쬏q9Y .vG+?`Vͨai;!)|.W0s_CMf*lN %: <Xz#_ǫ|-b MbHA2"RDej֩hvU(M:L9(F'^Wxwr$ 6t=|66*Lp&PU؀.7>R}UTnJեo N@KtL&I(ѠT6lN=uj&_+pa @A]6Bwv:`ܱdS`Q>uqAsyb)Ïe_o` 8jd :*FS)DYܻЯr  mE1Y{KkETbbb[WF~Cwwv>vet*oxN5.cS[{H1kԪi^4IChcH'5.#2xNOxSsmC' 4;,i8;LW]/1e#;|,\S RN\݊7Z|1fA8lV[M%+`+=Jb[ 4HLeɚ1v& Gtbҁ[)KeNBUH /⮋eY(Y.%^$`4 qq&&V~g!2Yq̷8jՙ.~0REƊH%j8:sQoE3[^Ӈ4%ܺG$-ۑQz+׎(@E+.|鑉j;8 dWa\+xGC8~{O?SƓT8a>{jxa ]DM\aA9p* Uh k.3 T=vg{w3 Ҿ8zsB2!mq7@HǏW-e`]mg$5޾vWɪ̻.:*N2rν$S>GOΤM6Y֟,! ؟s)߹MH/䆽mty2GhJg ^~Q+jxob14 fYx+h&B;H)wb;=$j;ڥ-"^ VmY}`ׅl8Sл$ }N<[2yf|v'w #몋%[t!Ĭ`-ڣWՋ| @Wg.=Z|ZtXW7[[lq{`jk~kg h]Z@tHX8zPFP:P# )T\N julŕr5]ϝp2: JBHt],?2APC2!Or uُ;b< J0pЌTeRjw" mM"jUwrY@mmhh =tB /I]Ȱ9A P%(~e1gl_{ %C$Ʃ!~zDZա-fz/䀵K֯kA 1kp N/qCslh<0:v,RRroڏ NS@双2M9sy3Gm='P۫@Cꤻ 4+D86T.Nnv`wE v aOٟYpɕ_jt#AVKDW>dS0 Ffƕ7 $sa>>oAlv;p$\D꼒Gn45F-e2Zr$^mhck ?]p: FMUP%5w;VfX k]lvڬ Z<#ΖWUR^V!~]#ԃ+́NTSU44܇ 6|w1|^Z,bAcԿ 8ֳEG)5t> stream xYo/7?%@" d՞wES}O%ԝ~p){u>E ?xIfӌlF/_nlusogr;菱jg7g͌.lV2ZPQ.gW5FPLvk kNC?XrS}}/Ym5tͲ#$n9\ׁǔ Y[dS^z7waZҐM_G9T]3,;@w`h' &{y iKM鉏R{b|~#3 ]H_EqyT1Sőz#ĸ:a=1W d!?RKVd_u.}k ar`J1/zh!E\A{A]2RB%zZ2Ql[T)揥0e#S|aB1΢ᡌSF<ݣ^~EXσ$b(Z].h0*ȫ!^5eѿJ_&[8rZ"  :1ܦI~a 糯6:02iބoV>1AmVcR=sqp&jsŞMI׸.'o̸O;6ebO:|>wO/6QM≮IIWnVp܍r:T~rӮe5~{ܷ[3渽muHWT%tbp$ :jT:^,֠(j)ƭS)~2BۑPHj2zC*=-|4pd]"(qzi|HU) ThT(u]qڞ ) ;~@0x F_J)šwRH qj llۮDY6Uwk!vB92zo5.46/iii]N:eclSY!J]MP=:Q) fz#HW!vpT5rdl\R YI1)2<,Ǥ"aQB6SLqCa-Z|lneۀ]A_T"bp!'ڤB!ߏ*0<+Y?Bǰ}v[,Tg>ʄb$pPi{~UpA UNeI8wI"tVkXF9@*fSİNahM;x /]Q|4KI CH"LO4`ALKҷ<."e?Fƨ,8chBq☘Ϗ{ŚӗMR'癓RwrH+DPHӖ'>65D)X,dztї/?ଐj4CȾ (O,p+:9(I+AL'9hk_*q{Zz (@`ɤ.Lʉv&?y┏p"He"9ؓS0"NaszJ )e#R᧨m>.ٴVIsG?18plqNG.*S*IrU&GxaĉKq>h9=k Z``ݳV"p6P$,^J&3{U0iX 8VΛA>UQ)sݵ f5̑Y=`Q8ęMLqpW#ԓQWI ށg*aL:,Gu g>Ov&Q] Ql HanQo+]]ZWoZC(*du{GGJx|}롤KVO'e N+1mI.J0=f=ͩ*C 䑲l ,F]m,x?R EB^)#'1ae .L7Rn`Dgu{\#QWcq ׹$G+ ?LJw]ȸvKNNm*m7p9.uGT MkCv0hSiBAG ҦV{ urDAa;a!W3-a'(8^ŻE]́&̹OP`<\Dz0Q`_^~G&endstream endobj 166 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 714 >> stream xkHSa])c)Dh(j! ib:ia"`5' ms源3fkF" ay4E>Os"#ܟ@ "ais@OӵU;#@G!P "|ŭ:yQ֟qZ0w JN@ T%q򓦛p܍wtv"U N F^3)V8 $"=+:*,G ϤⷿvZPImFmșMӒHo3 E1n_^[YbK~ڙn %!QbwzN{'?;1p-^y,c;X8J `AE=!4Y&bPA&3ƾJf r9S'$00S>)k/ H>~*!BbsÄG{&d./=c-S0Me설gaFx.,Hj=?"Zoendstream endobj 167 0 obj << /Filter /FlateDecode /Length 192 >> stream x]M `OҰ.4FaQ ]x{ajqH>73O5 ͮ;,T;h!<$=ɺ @o|d7Tx6r#^*>y.Z;=7à*8g\D<T*"+X+6Y{46j )1EZX~w>hy_endstream endobj 168 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 568 >> stream xEkQkv(@Wq x<MmlJ[!&M6fvLI6llŃ_W_P<'o^|{0Ho3of~qcc<QxXypw󀏫gOFS+Kӵpb=,qVW"P<6Bz8G_B|dypAՈC>C' +.v1#19< 6ڪDtF<0}%2USv@-.CI%@XQSs8˂I~7_U@PTU!,l]0@K[F"N:$uP\&n$$x* [[ؕ&ic{>x(l,e<ᰫK5BFd.xg;+@ZHdV"lf'sR9ԪifZHw$*TSuVݭc\w efendstream endobj 169 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 216 >> stream xcd`ab`dddw441%2{@ΖAA%GϹ) ~xw+DM<{z >SnRgwG7GCSSCӄ֙-?ĵ-mM SvO!w߂_g3FtŒiMSZZ:Z;~V8oҜr|r\,y8"Yendstream endobj 170 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2916 >> stream xuV XS>sp_$+6+ʴD,(M40L:(_6c$>U0@_z񠡕7R,+խ-q>{}sΞ0~cD26:r3"""|?BkRs>swgw 3ksvPo֤Ĥ~|Jf(fƼD31fe™EL$YbV0+Pf,12fs-sU11fi#Qa]82hHvlu'3>}CR8cL cROKlld%W5rOZv[Ҕ4'Ta>D-p@ֿM7D"pUڝӖ.rK`eD6bEb.1>.INJ &o|a91Ĕ0E{CtqI|/IJzݻ;Y5֓4Kc2Iu펶~s7C:/)젓8-Xv5RN'TVQ0m=)>§HW×( laY4rǗSfqIT| M,_h\\ͺmW,dnKu"~J`-lmʆe@dg ް[5>'MȁriO&YzmVr]i"uP)N^OUJ;ܼ mdf+@;> D#y୼r "XhDQXP NRZuvv5.jŠtIxcxC;DYza`0DS$Lv'C20LlPTTsIִRvu@ lniQrPl+*%v4Ɨ[r{]@. 5 a(oM¡/nR6]j G Ő/#Gή .dADV%`y;z|v"!}vYbڐoq컃WjPT%Iuơ lɜLdDG|{:p,nF ]=-=@eLVn瞃i/'%Ш!L{r;FERkY{`er7(eWa$`&.dz&9m@Sh",MXu_NW*m5Pm2Vr r\>K!=6$8.#`HIiwdk3 灨pe: {?A _\aKbܕ}*+Zjv&ì'@οW`o-M<ZP,njQк:PiO:b0RJLX:oNl\SeU34Yf[WrQM[Wٸ ATlwR ̇oa/GG>Q/Š`} *Nt4s,4Y!~ z )[˚6ъʝ?bg3B&u֝)px'9Nvʨ2dM~AxHbxp^o7ù/y8ܺnGh u'E/WoJ Hs)]Isv!4pJ'k&ޯyP};eG9 v+ ;^)? q IݧpM6|No6el\ 3@{8C5p~"L̐l]j/XIMZ KaeS眃pqo]Pm.(P+LѭqYu#Nw-_RjKT'6goeQ*DRXҷ&qIuˮ>᜿ĮܞpNݜp?hȡM8Z.砽]ߚ9½^%(Q:9`1,Iދ\Fg(6)LA߻x7[a )yždRWT99!%Ui5z3dYA١~|p!E!;D@i<њ\y}AޠAFy8~7VB+gʳkm:bUݜe]*VFk ~>9.)^i˛ jZ7oݺTj. 0t±:wKk'<{N6c6n Kh$Ҫc濒!0endstream endobj 171 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 156 >> stream xcd`ab`dd v 1400q$2黲!{@Q!=?}>0c]Bs۟~}O&ђ >S{6us,]@~*}&3{ry%|r\y8T5Kendstream endobj 172 0 obj << /Filter /FlateDecode /Length 5194 >> stream x\K9rscwŚЌ=;ucფCY.=,r$;*zEP$L$c5˲,\>,~YP׺ [|Zҥ-bjyqtRӲ(^od(KN^=0 k yKt|*Vw> gV^X?up~E7觪>PmRZkj T(Fͥm:oI?9?^=KBT.rM՚i\VjaTMX !Ж<T2E:QiCjws]xa%d39k~DsΝN [.ARLf{Sw/~QG}}z=b$ WľMi5;[|&]|aRrM3[7WﵟTYFˆ%Qn zhNRpTėf).x2ieqBEi3"m]V @X]H\tv_X;1~gx0 [2>ǐ¨5,$KaG_jDk^+|h {IM%[~C<,_0=^k eśR% /FB%x262₱PlII mRЂRR!i4Pe jRBTpѮhz a`X@D-Wgh2)Q0 ݳa"[`D(tBϚ&Q,L-)057d06n8Հ8=%~2PVS+_:3PX qn9 I*hS'd .vKyctFS^=UU+,mH55ZA6'Ftw iπХ, ($K%Z0K:a:y*!wxΩJJ3u T_ΦvNQ9Fj {4Asz8Ϫ<.cs6@S>SLluS>7s* J)"uÒQN Дg(IJ~(p,S>JM(53 z,~.-ДB[g~RB7fZ"3WIXH%9cy۷Ϸ/'ȳl?@>k(up_C =/"0!sc!@S=7t GE2T8JM>&j 9E3zsC<[HY!! uƲrӈgmp s޸:9.춎荓猺8Wg %Js&zR<7<0γ >|1A3 ✵h@~uV`5E3zqΪϧμZ5Aoԍ)Q>:x>yu=p8g Sg^ O&guGEOɳ*;(5Α[QKpގ#(r۴J%9#EKQP=X;J?n&W<;攱B :QpVd#s 9]B3R)5Hu7'$}yr[G3O%~o"¸b,"|`  :@|ą{5=}N.k}&]+0Rn~?iaia@ 5CVnb""yc T: q,hk諯UnGtJvLw!HYG2!A7nQk tz@?w鐁eLHH`4bwpŝmPkJm_H޶ Ң5O vrғRߠғҰ/ThIYfD*/a׆IŖky*ZzRcKO Xoe.) YÚg40&Vֵj("Vt@2)d~ woS읈S$oa~UuO/c}zg:5H-jESu>DIT]0L𠯍Zɒs@xV8(X) ҝuoË=j?39K jXYӰ&?g-JjӚއ1:T~- G)C)`5O@=|ڞtt_'x>T_ cxpWkK{v2!_Bh*]T*[J#3r xv0W1&r>cR%`I7!kjHsfyB'ep#?? f ]EBR%a'i )LHj³hH=s(l7˺BuRϭ0ഘXNa3f[R[M !# e X%n#=V?;.4'C#li~ةŽZaPJNa\>'$jve?]NJwӚCn/f#m|6r`C'rw2)(.6*OOBxm b}x=;T=O%!cVA[IqWzPu7NMHvW k#8[(!0ʸ%&\47+JRАk-]Oo{oPqٓ)=@mnA^%LmA3#ݣS:n xrS7? ,}ҤyуKr #7ȩKt{IA'W3B9}}'$ ]î^SndWփ9c;0y?`ON'X28i`F2!H?[YJwp$q|Wo sBA%"tJ\Zxoa.n! ۗ'YK\wN<4\+}^:9dwXթtrY?!E'|4Յʯ+)1%ՀCC}YXO``<|Q^6A+``䤹,Z YXߤw!זJ8("Hl׊f{ԟ<\o#| q#q8se5y6a`Į32oQB 2e@s(p~waf'7֤WCf^uwM. HmC˝]pVk#Ұb\X6CY[SnNZ0\ %( PC{ indLHG 3"ذŚ}6N-cz H4 +|V0X* a{ǝyS56ߔo&ϾI-}78 4];{h-}iIH'nr}M]XfnͽM[Uf,I&ܥ?WQ /"<6n"{=$0_6j燛X$2o4ի2$Yev]tmmw%ϰJ}8(s|@NRo;_NcF1lwLX6&J#,X&v5RCPDᅂ _:l/ܺz{eiI- @I}w"ֵ|-m%]"aaqQendstream endobj 173 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 359 >> stream x\CMTI10VN  opPQZ-P4"&$M"'dfӽȻ_P`u$kOnTX^ZV,-Oldx #}X&zb ()OOZ`gin^rgwt{mxc~Pўn{ot‹Rkap nKr`EXQ 7 endstream endobj 174 0 obj << /Filter /FlateDecode /Length 2162 >> stream xXrFkT*iLt{GI.DzdkD:L4 l@+gϽ@Jf1*@sOIIeyL'Pu[tctxusiFS0BR2R,4Ml:%6u4e*NUK] bF^\!ؔO4>"-*kppF0Et*]ʬ"T(HLU؀rR RdcVQ"]uvy\Re-^Kpy36usMYJdXN:JjHp :ۈ2MM8S0ug"P*q\KAw Bf-㑀0+dq}m fkUY2M[WU`_h֤y:Qɦ~-چI EnV\]wl_VWir;D 3'M{?MhڻƘ ML2 }\!/ǐX+ Bc-lb˼BafT)ؖgyZyۉ\E.׍ZS>*48̷Q$)22R0rv2yT--wbe&,f2 2I[`-pi>G 1Nf5xmVEW H(,:6i:Y+E(J0+ e9TgO7.q 0T] ~+J4U|k(bSoM4:[0P/)~ѱx(`,WC%䖺EdpswW :q 9Ħ\<6uHޜ=??ˢ59%j֘0YJ6g.g~ pZoӁaؓ;C^dFõgI9Whxȍ̤l$M C~($"(lyׇ5HQcM@@ncCXBzOϣgp փy3% H%mDrr06 ZuJ_Ы5;ܓ~tGY 8O{*]$1% 2D%ր>Rc-^g) N1IR&4fVC(x87xN_dftǒ2KӖn*쐒k4cge0< { ĹkreL8nl|h>xb >dWHL;90-ZKĂӑ`&9o\!Ut4SNS@Ꞥi0#ֹO2B=L9ZYyYtif7ͻ=]{m!ő=JՁIypE4̄)2@Ov.iB̑[Sܣ/Uu0ql\ř![7.:JQit/Tb [ۙ5M. 1GJK+quAr6lRLߗ[)> }o`;^[#[z7RKV"B?SwV;d|YY[:Gdġi.,?F 56_{c=Kdp_XCW3=C Ci-&].ɗM XB+hKQ[/E5]љOBp8Э^"gif.0ҾlcپW*̂,)duEً7grh=E 3l&~w>-|,gsz΃<2Y-EjQv@n `:@e(JQ]YvOw ;.8F(=۶TAgUaBZ6ȷUWM  1Iڔ[ |q56/zo'1ޘ||aUqXwAUp"Ɏϋ|$_B)d}➄dcRN<2ݶxf}w(窵-/8K&# bcT8.N %endstream endobj 175 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 142 >> stream xcd`ab`dd v 5400q$baa]H~= Pׁ? 7~H/(>GhXKdiVB~FM|w> stream xZϏFvr"8X0bU D gWA@8 nM%d-!X^Տ,U wǛlx㍢ͿMNݻBm )Tfy;$gX֖mrye^'}SCoo%}]Ie#N4m|vmGm[]L0v}Xo~{n僝!sE_E>iуeҵ-*tr]tlo Q8JxDHtC36Hj]1d- ɾmیQb A޼T%cZ :Dzqg!m ljUq춷*`?z&YfB2ܖ_a ݆Yy V9C-dwv^F(xLeZ*r?wM ,#G"X+lR׭,T.%" xSd$'Iu: |eNv?ef7FPxr11Z{}ÎK 65p'y*9ciecd9-,R ^ QM؜ͮYrCh mcaw+.`w|EisMwTt?Ⱥ^*syI+b0jͧq돲sue¤+55*B8a̭q*Z&%yz{d2 B(=r o7[ +5ֶRm^h$&kɻj@\^_ iEyd^Oh׿@4@N/WZSw=I=$ElZ+;{!%eИ9jr@$)Qz1}3 d$(I Jhy(g2X|մqH 4T0!nKd-5mU(?֞/e8Nq8΀e|GTԬT[ʧ/JYo3/4*O*Y) ?>5\&A Anee/9e U_O/uz@ٴ$CA`loV#4 bB{7߮e2n*gg*ɡ{l*.8+v94en.2}y{F;bZyͅ)gTT*oN9 dd KϚ@: =`WF}T{,^ar.uF[șZE, X'?l@pI!^l=C5CY|s3 ˪s.f P Ha"c}j/Ưd-F!z 6|+$YC@IX1v[M;aw՛~ +^ޒI  CF1B1X'. U#D pUJ9h⸜4Vmg?s5TBX:W)[ ֔9gYiSbbU /ō,0 YLXy[bg層Ky,Su<L34W^yHnkQuSZ ;]O(M.lR,PDwa(fF̫5I~fjEki!LBƤfNvopC>HP`ϧZڢ'$"MXP${hQKv'fti5[ǖ/ӛ  ݽν:8zܥ:Ӏ|) M߇p*-mdd[TnuRCݎ3Z2}<:= Ѕ"DG^Ts!MER aAFBۜZ 'ÆWqA0DqST({/yiŠ {~DOx^z_2IG#Tf/CtQ2w"FD֡IynsVg\Y Oa3 DbB"> D T$5g(Nި3 =!1Pxfb<ڑg)*`g3έ3C,$ Y`ˮէL tIuwP` ԡ=3m )рt:,WMEʩ=φ{!k*|>F>],!K~$R|߯w-fE(#5Hg t̵F1-9`:AJyG|G9sI El8SkWt-'?DL'u=אLH,W~ bK9 5֠Aw fK 4VZ;͹y/ zOpna'VΈ@gFG.ibA:ڙ^uB`Wmi/r :BNq.l,ei \tV8W& Qdi11&@9DS cȈtEĦ(- #&T 0\c/nLx4ѠxJ0uz] ҳ;qvƫ,'J)W𮖧Y;#]J9\\kl”k^iu<(6~ lgJ%,\y_˲+kT&KA/O=cĩᕶɏA5rT6_h~Z8 5 /i(pyP;omtƾ2vwoTګsǺdtISS^ Ū$C 5P0c Ni7x/E5tex dQ3 |oC8bK'Tkf% a@|j%0~~Mkz;rP:Ġ`)>1Sz#gxwbUT;unU *۝\>mM%i1KG_/3Ty4Gz2W[ӆ1ǜʗ wRSh/U%]6wZ'‚7'/ q|xm2;|s1o7o^vfcX\H!5,eu myE,nWxe -pv?횺=<쮆po3QQӨ7HnenOpZ@QJZ.@)9Z+aG:Gڙ&0('@(B՜UVP.ˑ.yĞn .e:'?}HX;ZTU[0 1筑[WImVaR~,d]v]}DZ?a#;^8-U ^ 7F݄^_17 :NUcz0ʅJ#GUsks_!ГN !23 +.[35F4pi}/]ħ@aFPx%ľGz|SAZxXb9*һgЗB7AIyp~f hs$DmZ+ ?jv}M/pU #á^U!f5]kȚ./nه$ʪΦ7Z_W/Wbr*)%Qɾ#endstream endobj 177 0 obj << /Filter /FlateDecode /Length 3219 >> stream xYM6\K-!>٭l%N8Ī9({u( ةJaH@7kiiNr;ɧ&Gr;z1>V$S֗Y^b;y!~qʈ5K\WƋoټP&eI/ g.=2E!&O7~d^[#n][〲JCج ܗ$@| Z}"T,WjU ZK[?\=9Xwۼxfئ_mp-nEsx+DkphUͲN+P,|L⮾^I/{?dݛV*?M9np[I/Wy. tSCӫf>oh[Aql3Qju˫*\*l3C=\c(ȕeطuǾ&g,WRgqs*٠Qȋj+9G)|vL'Jh P<3e q?%x?z#P."foPc/#]n]F:^X(]@ f9f 9#@1,=eU^Mz맔̍㊏Q?$.ast})uH1לV qtM+Бv7Z_*/V1.S~$` Qu3S9P@4>KRZ`Zz_:`W*ifU-Tjj eаi{Ci{eyTVBIE'#%ƐwGl^*N\‰JbG (5>4먁4VA<qKN $w%}P.On6Y~j3Sd3+-a=nZs峂-2)Ӗ ,[Rf__iX^?-):H?R 5e$dIc$<fvNfjV1b;*IRlxǓ+At颛cpDKU)m*JRM}?ӦN rH+\aQ1~FI9Jnmanf"(TEWF‚IR0׻Pmz.ӦZӕE!AL+rA#_jo)pJBΔ4ETaO\i O`B!;2UiR0nOETH z׻: xY7VQ7Q{`ӺM{zTbYՈ ͚6JܠLIOBӮjA!"'הцS]d]/#ؑUG钾8j޶=A3vӑ-9pH!mN2bLQFr(})Dφw- |rk17-O1cT )zuv0s|WVSY*[`9"S)2+ 7ECjh(,#0^Ȃ0Ɯ'gJAd??aǜ%avმfݱ9y)GyeWxZ? T:pMΤ*pt xW@f7PD-^M(@?6flJ=pi?@M)鮿 ' =Nꊌ3K~,ugߎugr:#۪K@&z^ 8TaHͬ>~uLJͻ7Ֆtb?f4؍^:9mb3WOoJI>ĩ|*T3NT!#?"1ǹe CJ YO̦/.%+ɦR*)bZÜމX]AMX~K=" ŮTKNeg8` ~r$Aw(.~5 _3e1T9Z05ݷXhjp%,"`[岢ٿod MA/ %v[5@TČy"y"')鶛 od#mw 1C,ӵ*E"dҤna6s T`]2 L*&c(;Bӹ29r䂰7$?Xߓ~K )ɰKځ8LR+.փ rqH5״) J3r6@w̃H`aenfB9Ԑ^2Cn5!c~j[!eBmv /W@xoZ(14 [>O=ןR;G |Wϣ<"s Ǿs`ΐb!Hw jqo}fʡ_~(‘['endstream endobj 178 0 obj << /Filter /FlateDecode /Length 3272 >> stream xYKs SғPnW6)<^+lG65Cic>diA~v~1HIe6|0? <=|@хd*P17 zÄAȓoi[?W"H'rY/gsxRJK"H|@4n2ន-*YeERI R)H4u uWSThf)ѻ"kT6ͅ҈,7ycYy* qY@Q i1ؐgsqEYs.9"j* ޖ sϛjJ"I~PpT/|տִ[#ѶU~p34r/ l~c qphoRLdp>ܗ%i7ٰ+Tup]5Msx^t+Yłph#<`L ̷YkP5X) K Q^HxKGÁ/12Gy$c Kcv9ta҅2{v6?M h2G/䘴iy[4!:IHI|;cTfP i뿼;/Wy^2NUq"ƪ hglz_c g?~]Lm GKp-`80Oe ˙Ę?\>o=e}-0슴v.pP7(`G @V]$$.s>1`O6&{ĠEN(#x~}|պzerS9%B$-\&E>A+ JnuDR:yg@{sGq}O=u1pNiE 'coT*bBd0bPӳuDwde#[DMq>J aʻn0IU,?RYG&@84!Yg ^bOK޷\Ԇ2Kjv4ܕ+Qg^aunQLk\o`Lt;mVoum XI:P֮|{I-R;"6C[Gi;W7mV}1_uCtڈ÷ɷ9Фq !`3D ,1~1:˴45MkubUMI QC e%`P @L^: ̅1tz}M¿GBݧ[-Wܻ3̣Ո #o!`E &bNk|9(DDh1&LJTe"7R$l2# r0!Eu $ec_%%=UP؇MFo*c#^T Uw]{/]o۹9y觫J>`1"D0)bOwKQ0('4X.64Qސ5 d#$IW9&i>`EE_1L2 9|"8hGWGp?[,<4AL9{ŋ>"謘Y ,?~$ Kb?`~ ǗUq׳4[7Sja*jڸQ|R!5W/{JNh +!GC\/n;PӼ|BwNy*xi`4߿ !CLLȂCIAG!LƆgC ŵА-qPU@z,tm5Hk6 l\U(ꣵ )\P<ߙ< YIW:٘M .MGLdA< ٞ77`~>h`XDaG=:iP#N~ny2lsʧ=mz5֏Ä[u,dDȱn1oFCɼ|llY/MANKMeEA8mA/^ {h3d[<-o*M ,#Ak$pj?vC8\6xڦ?"RyHaޡQTNw]߽|yo6 Yq|n*Ss"{5e d5s[/'˟>,_g >.5Hrˉ>"CƜb}<_\|2 -Og//5 0>G2q%U7㋟:) '~0`27ٺ3,xkka-7Г=_$Y@>PDn:Ǎ? 쮻U":IC?嫩XuG4[m>8z}Twcck J.PiZؠ  2b,&'kj)oկa44+$i@ߚ)4Ǧ&> endstream endobj 179 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2227 >> stream xU{pSU!m-Wcs/3DgTDQ[ }ePH$M$6ihަ-B(-* Tquta{;ވ3;s9wCD$!D"QJΪ̧'Y+Y2>U\tO mxT^_ po՜,}asͿ^.}E[G;&cבB{H3q"|9B: llCbb6abrJFN!U>qaOp[|Ekď͓~5V _=,߽lOY"kF_̨ާm2uB;qH" ^?>:WG(Y[3 *NUY i[%?k|Hxߔ9YRmӨpV/SΝ;N7Fnq.#-.JaKQh@ݨm]; .W9|sl]x_XCw]O"N_XŦVs譊ƏvF(/BF8~$~t?kot_QfVpJ.瀏>T''1k ٓg!YPS@=ND! Pؓ;/O)c9HzqR 6͆d~r%ZtQpT;LG;/n-̠vU&;*,C::Ɇd W~9| }/zLDޒF5iܰ]x##&Ε1H]kC%:A-\ymK~sfHN*i.a̒+#;ݯ5SWL4oas4(Vd- *Z5rA\. 6І ZƣR2+ nh).e~4ql$~ًgxe3-j[ơ_ /Q^&S?L"5b!5smB=~TqmRS+UV48PfZ8aI'=W~rr/Xإzᙇ>žpwDQ8L"▗RS?3 hendstream endobj 180 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3789 >> stream xWyTמ@~WE\2h~ֽuV\ >"*H{B7{ l$$"P[ŭOSZxmَ^t~A_{3̙9WNr~gQv | bz0T !| M8a~i&P:mMzD$+[oܦG&DmKNyY--V]jEmj5Pk;Bw"5jLP㨉z;ES2ӣ"F G ~wI>7fܱjCԇ􏓄N ;~ 彽 u'xEQC9Hq*Neѩs7}[Ť>K.H03XFC3{41cwe,}eH[> ;24HC>3&aq?ՆC+E-tKU㒵T|A ̮u>ֈ)s*Џ3>/VH ri7r)TN>ᩂJ2T7_^0o ҋˎ0\ 1 tK7#aMnɞFq诼ae|i` GU: ᐯbZǑ)bՆ *bX}Ǒp5ׄC[n}J~s(vC|LfAy<,OKС2\?Egk @dy"]<;*om9j,Ζ*,IZq Xb.o^5 BoiK_ ^n }d3ꬪMZ+NۣVŔ'!>Q\I -|1u.dw<>18 'I;\q5Q4%+WisŬKi`9/ʏ$m(fԷ#zO/B)T–f6)uJQ9ndu߁뵽=$Ax59(:RV D%~RJR l7U4eP- P-Rpn_\:"XŠ`Ǡx?>jIb+PJJpJ@9uk7 ve-X:_̇2/uyBMl{vilGVV6}ΞޗޗvCg̴G>1)> פxߵ~dٟA"oii@D3ID(uW\k a~XBG)h9n>>EjbT348 @_/:%Sk^gm]}NDP4س!"~gӇ_}~f\\id+M  _uc[9EGm,wzŞH™˜-A(bX|'W"nMl8^I/ Cg캂GyIb:%@^t7es2ks=u#w7o ^#K'\rґ gZu;M?mB-O2 `3^-Ք}}{J3)K=ך;2ut:CF Ͳ*Nֿ?%d3ٌv0(1('k%щv VO4YYGYDddp{^@eQvLt"ֻ9I~2kO{ݙ:O焓G? .Wl!2M:rٞ]bnVb F]<ߟ A\h۷d yZؽ/:EI :c0`FESI/T3$EC<$%qk{#d~+ Oĺq{lp;d>_=;Y8g+XdL:VHmL%z*}yWBC|xZ-ĺNLJ{/Eي{Añ"ܧ3L+hbFrUjTJ(Fŕeb 9%pI-jC?4HEe#b<,߷ ~w㦽%˖o:{a$9cs50| m8I?\TͰ|+G*`_2%s| _d23|P"r y%2'ISJ@fElk\8+/1 o&3YcVXгOKVHq'7-]Tָ8V9 FYoQ[w}F튏w33<9 Q!s =Վ~\iD 2r1|>P d5yՄU [:,뎹[=mT%{YE*CSR HH/RGOay=ǹ_X6c0kHdJVD S@cЀ)A^-(1:i\/;=go~?#<ۄp̴2qYW_WPfaT+BFSc2endstream endobj 181 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2233 >> stream xVyp_Yx!x!ݒv4I8℔+)4A%ْ:,KlYec; 8!v CI@<$h)fv Ly;}[1!DYk̚=s؍ԅ5`ߙpN:$z=c#|Lؼexe3~MZ($^"/KerJb*1LZEIE-5/'L8\N^Q%kNVyV?Jbҽ2HRPU_G`|`?C0$~ 8eI uy\rr g-asxo N b73 IN_BK_{ngIpF3,I&h"TBv<|D}yo,ovȍKl/-Z.!ba%\g{FN]lv}<3>UB"?Zbp @eu<3Y18*!KG$hB!fJkH6!%KV&E$a--ƭJi>X<2PK%vʿ-CU9é)tzXac7#(%7ؼ#xap>-Mnynol`G%-fcSڸͻ l/yRp^}{15^پ 75}lq5얖TZ66 Z*h6{>!Y.dMDshzzd&)755~MC>}LRrQU[4*oPh$l -QOs5wx}zl{.>D Bz$掻&j ~< '#vWCUZcIsH#cՔP@I*e|\zXOEyh4Q ],ZHr)IJߚ^߾4r)xDauFR(kιyn? Sea{c<3ԏy#պdz/ .Jdr bL'WSԢi"!6{ 607q,FS?L%OgP1OWk83Õo?U] ?:<oF(L3ΧDQf:KIvK\Ӿ7[C[ iQ)m3tܪkcZA^t~kmUh→M:ֻVkL"``3D޶ϟgX%ZYa+K{+ܰhk=z=i Jv"#Oގx{@}Yl(¹992X\ja\+#?ʵ{ZH}f "ZsPQ-n>UlcuoFTF09{  Ky I42b{Y%Jǔx;ꄌ:.AqV +*'S2UEY4JF5ad19Rrc}Gr\wN[K?#i*@;cMe"N܎ϓvhmB6XԚ% ƘVm hu: v1@ !-jU5~Mp5`{{ThpNxh})0zԴR…55 736bb֜#=]g: @_-o4k591a$UnL #7?H@-(_l,&,?MԥZߠ|JW8k)^C ఙ/qu.$|J@%(S(SRʡ w&Z[T% pIL8hbAA1ջendstream endobj 182 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2163 >> stream x5{TSWoɹ:n@7-:>;[ŪVex@ $$$ᑈ"H D2U[8VQcf誶:,'jR{s>QcP<o\ʍ1QsF7$\r&aXqLoy}ړ#˗N.9(j=Mf3*ZNmVR"j"DS  }=f-?`E<);@St鯼0_<S"}whW 0wnN2KY[.dd~\&xƽ^(0Y([f?,{Y3&^LhO)G=u.ۄLwkoL]fCrtSey9+,CR)}g 﫧S>6IԤ",QANix"̼³/zX۱<4N‡I#KUBrc>9Ump&@2ĕnHMH >>Vh_-_ x/|/5{œ9J1ZJ%$rYFYa8$~nYayob<}Q04SIVߚsDQ|lhJ6 NTl4HfiwqEq5x7U+;;k3`\<'r-^p^>K`ȊN tqp,h6L/LKR$gŵ+_/M)-`?4scQZ.i`B5VD~4es:Zz ,VhE;|ha.OHdž l f<r*VB xLM]?Pzڧ* ŮzFhV;'ko~KYgX \=/^Qr}e 㷋,rr*`.ԁ7 ,mQe)b-ee .xJg_iINv rIN^[Anzd`LGQ3;endstream endobj 183 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1041 >> stream x}LSgW !$.!ư87Ȩ`P@ʀ^ʥoˇmiPvvYC3زeq8 Nrߓ<IH$V_+=}cI]k81zq^`w\K@C]XZE(Q:ltQ"GкȦAuq !%)֋ W :5P&;`!=#-546'7`Ho@^(4 bZ6Z{Ln>ܘhWq:lFS`DSRY]iڀ<{RDI/"y q:p}D2[@ʘ ]JыN/Ծ^yC $t![8ji5k/=qEiwWO<ɦP C{يޥ {>ҌN3U|,IWc n8kc[& uTCVЊv576%,kc'+/0U)y%%(2y*ђ_y#ue W0uPQ)Y#b HjjRDCj@> Uxb*ٮ91uNkik|<}c1f@goG;}6qmsTDS OR`&{]z'}SV^7(9_?3{nrc9 rlE:^0C}97l]vƁ,1N/^10Ie`-[ ;.Lz:dxatI NZďF[{ iOO17 N˕V5Ԗ*0E|V'a!Ƚ5S-bPL=d v~_`X#)LN}6QsywO8syg;@$,?? !F5FYCCIIS|l?'Nu{#̊Fendstream endobj 184 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 5003 >> stream xX XSWھ.1Bk{ֱ.cU[wEqW"@H +[B ZqmQg_3Ls3O\}~wYQŊغjKܼ,8 F;k'qb$"5k)`y HF"MZw .?9ecj2yY|1f\ #6ӉMį b+NH ≝2"XN!\b%G&kX5bkb=Gl 8D1OL & pNzuŰѩON)FTD|7:{aqj+_xnRԤKWMDd'O55)r{51Qr.ã,0O*ʸ 5jm-ve&\:kfx) $@T(+*hkp{7Zֻ Eڂ hvZ3Z>I ?q/16nO~VJ| G:L.𪨖a5SI9 [̣mx/$_h=ąkw:S 7f0p`H`.[:PJSsa/,āIͦn %R<(]Ɖ)r@hC-Ծ4S #' {=%3ʫmVfwbIpiG6_b}|@t"+AoX:h*t7qahFSIv8 ҷO_bJ a؜_K.HγEMXNe=IHX= jap} Zi%A7*Gp.[p0 \'erh@5WCf,Cc `1X| k7~sOPx- +)2z]YtqNRS"?{_Čm|Ga(ɖpjwHH%e] dЊ՞vT܏7;@U8Mٚ(JN^`=rv?cOp 0sWC/Xo%lAJ6;羉b{V4gGH6T7 pwZWp5Mi$@6>33<WHq-0;TRe*iTcjIv[]n5pCXK8jbEGb؇ZѲ񾛯|-a.\D9.|&JB:ۛ6t%ynHܹUΰaJJ/R]d)Xb߿iRtMN~2p>vج*ca5;h8r\B(#)صiiU3Wܞ9DzFFE.8UV\ġѪ,m'e[`,?8јbAJ.Fyg}rs(5{UomڮppF̀qԿTw ;ZX/aAd`_,E&]\XP/ð 7YHLک~.RzA&@0i =7uE51%JJ@_OPyjLwx ʲrB웼 *jE66ybp58p 6a8VmhJv,:9X&RyyJcV4+Z &,uJR8eA]*ZS]\mtI7#+s9cSZ*t eVqtM~[REIKVXrZވ?D.MaSb/!+J,6w#}Sn}s7yT)  GvPŗlm/z'p#*WN*]eEk-HVe(R#o4w>ᮦNsȉB'< /3r?NFs|]rkjfȤ`U|0'$oYfƙԐAө^A%Ц2=u }9vGvA=hVm4LC/pfR7b]K_1#6-~TI9^amNhΩZڴ{@SXl8~RfӖJPTVU{< lZg1PBiq\*yŁ޴MU'$x e"/˕Jh#):&4ZLV` \sdF#XaÝE+f,C_SCw&ONf=qGq 9]$$ĝn|r(gSDxQB4~aaEU6~TLV~]>n0:ju%~K33z}>!"^jUEwgM:іbgX^$)ѹ{x@MnU/PPOd|z z> yT%B-NVs7'~7rn>lǖvȐ 2Iqd"[28߷+:Ѩ9)4)W.sK6{|S&\Oj75>aO33Oú.tG.uRk7kbP8[jve.ShYy4Ѷ"[31[lWpuu+I"(K)AUC4UZo|)OtQOM09 #߇6coi*ghGM\BeU1it4Qw5q(2>n12q*)0ՔP+bWE:FG $ZQH߫ I!l},])ρ'2 '/,?=Zb+ًLYr#ڟO/!=jݴczgIg_&dw!my'"?vxU^u+3_si NF n35Ʈ۝HƾpC8 @> Ǿlu$+ku]1+XI)R1 %a!qoUHcup 7ygIi?L˶vsu9u7JF)(V<%Tv6_g7l&7pU~,f۹(;8&J&SȨHm۝Gv×~myǡI3tv?; CZ@ߺsnGQA=L7Z X%_!z*jxzJ(5:vH* W3WjN[y1R9ts_JSྮt9^CexE{!:[~ƀ?~Ŗ-Ro>SPk|OfT8la:6O';B$Pf;!34f (M-㗧dZm)lU &WYOB) \GG |OZ٦/Y*; 6\T*x jad~YԐ7z}1 =Uk>@;pͽq%"Ⱦ2:ǞmW$5qS׾tم'7;EJѪjrױ=9}98/s'z}֝5KZf0L.beRV/s2R h_{ 1P.a# H kcV9lZ^PK7DFbC~.c#I큏2"j.l)-q˰! _9]mS%x$} ƃƝt@VTd*&XK&'[t?Pe?ʴUw#ӚQIc %#M\""r1z YLkl*l.geYEeUisvKtA7D|kbST#IO~7a춦辣gN&>iԃOKWoƶJP_-cae l6&~yP;G+(-tE )>lO/:bq\OyNmXwԗc7X>M~%I<=J1^wȤLjLɶ8e;½00#*ӻE[(|"riX 5cB8!TQor0x#*h2-m ܊8ޮڎXU3B_p%'mN:h&#EB%h=P6pZ5UNjjZc&Jjp8ua":֦x`4#AoIY]8Vbc=&w]B^ e@< 5eLcWIpV]ܔ% 1?ٗ@=, ;U,784&뤐B" > S+h;M#0.{,2BW"ޭYV5K+pvO@L r,\@Q?2wgq (]q2aTk cI U'k:kOv@@ @H{rj%@bRw1#[R=M݃ƪ* 9( uwןRQ rªtm:DCO`ƄA 5endstream endobj 185 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 247 >> stream xcd`ab`dd v 640q$~L2{!{@1}ư&LV7ʮxzȃ0.-^r74nlܲq _L_:qEwNI]tp{k2wMj2oA?͓$mrޢnnTʎn[nJn}Z(dsM8丘p20dendstream endobj 186 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1892 >> stream xuUklWMIi jvghjKK6cA-joWOdExNu2˸BMRKX?ۮ \n䂓'0N]-_b;-,<ʊF'dW+"s7xa'9.7[w[8khGF:sLEYt>u"ɓ˝Gk]{8NVki'/JxIeRȗIaG 4`4VhOc"<:T%|iqYz,-[F#Q7t40:/>ď\~釙QIp 3e,3aw2I[ ('xp$ ~70|GL&1c%(܋,"WW2<-;8'jVp2+opK"DPZqLHWipP\}aiPգF*k_2TkKe5uѳ;a3LO+ƉJ/#8\Kj<ͺz{|eFϗzu晁3qC@8b7s]-K /z9>2{gEy >%ϐ %ǖKWgs'IEvYji؅*t\}.s;\K^Y,>tMf|'{:o:БHJ#6E }H_=^oGhmF@uhGHP^!RZj4+#s.0v)YɺeC٠Qa\=*eﮕ( R,'5Vs>Uo3nZ$޸' n۾RwLsLlv[svH6Y>e>9tnc=ڪXjg_䳼xڱ\ȅ#7t.yZg:>bA̤8!1IZd=  k(iIcҰN)IH0AU mst^nBB/+/Лc!Հ,ЀA0m<iuZhZ"H8u(@[9. eFC׏)q X`1KuRuᅇiq!TkFWj`簏QDendstream endobj 187 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 837 >> stream xoLSgK 6ݜb2mL$ё8u'H *T"B{[޶ R@@-,xN0Z.SFML5s>/s~JMAEnٳINIjl{[߮ ͹=,,p`ӎjJh* b"A.UA=J@ pNCj. vA2pb2 !~fՈOug&:|\wKafhNj=vtɻ ~xX+Cic]{,UQ^pgzWm᷃LaV䏧?*iwEF!f)dC)P߈la/B~EP "* `ӛFWE^U=g~m0y[=41{'w _`S[yxf[N ݌kJmf2L^{2Rþ`[xqc`DvI :DPgaVdnOѵfc@$]Y)qy+Mx7"n,zlmk7wVDƱ9X+.7n3?;j"X OcOCwӒ넏&UVj2!w܃;PxCjfձ2:,, &]anzR3%{9+6\0Y$6Ú|E @C2·$@`q2rpv}mm]>lHC=X|endstream endobj 188 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2173 >> stream x-UkTg[lvg=VZϱG-EDrk!@nF @@Dڭu [ѮVu/p֝ο9s{y?b6.z?3_B8քɢ_޸qfz"/(,Yk̬ 6` &,[%c+\,VaqBlX T?N8nP 3;,9 -Ka/Ŵ}A/@GH*N$RwK` qB}of/U٥;N!!f Gj=eX^QV-zf`\"wxHopXB8etyQόb$ƠωH$ #:Tfcgk+9'@ C=}@É֨ڠfAtaFy;~-d"1&~@p jn`qm!z;JupC S2U7NƟoHƴ#F'<++|Xݞ[*#n6RLk; xV-g?2jkH u^pܣi}5> w$_l[Z<==~4IV xYLx B*@Ce&E.3M5_@;=z`QTt'#{/&c 2!הېߑzQuH7~g^/ԓm^]!?Q8A,`OI_ԁ&pI=E&c ț|b4{'AsV@qikd}_VPg@i=V-l{m6*.#Ml?pmtݦ#7%6}:JX^"/V]^ @JP"Kd[*m׭g?pa%ztP zQr8_S/[6 \< >Ox:%I.[[aa,$ޒ'~"^$z}b)14isYCYhWOvмv$̨Gjڲ5JI=Ɉgt\>e~PRʩĐR_-K"s)$E2]GPUMAm(Bݤm!FL!t%>T'DĨwϗ 0[X `a k1fJ$*={dROW#MkkW!I#~TJEH8Z|p'c$; x^[9=ݻHc gU9]EhJkiCqt;ݘ|{~Kc'.^Bcw~ VƬ7`mq֚k5hVzR,jKW0lT'= zimoⅵ|vYF⧞*$zN\y L5\:DhPhi:9};{>Fx$5$E͌')▫_nq [-A#5GǷR`QLR AfC(Zt-Ekb{h4:xz.57izٵAPwH/iS;5؛ׁۛAOG{ ]xO"AxNW,Twh :!\9ney077Z`$e@ v)b9m@q+Ԫ3Go]yOy!&ӝitI-R̝$@n_?sK}Xg@a;JWKɗ4U*\i5P rgm^=g*54Sׄe'`Pendstream endobj 189 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2978 >> stream xuVyTw23ؖ<<ډxumv}գh"" (7$HrBD !Gt]m^*u[ۥܵ[[q_wo߾n^d~?W@M Axg/Z1;solj`&9DO:0Lɍ+(,*NMۖ=s]>YXOl qD<@Al"^"bBJ%bgWW׈׉H!~CL CKp` Bj+aDr?*ʦg8qsO:2y/Ĕ_&@p/0Q[PŌ˚(Rט-P̘T :sx諧vLM,wW5Mʞ9`-L-13 D\.N&>AFb}0IR8YZN qáᤏ\qCކ3pV>-tj5@sS;{>͎ r3r2T!z }p0HOE5;$>l,"k$8IehEfŘ#ruq`d3S<ެ!|> { 's!-TOHvQjs8f1"%OZGz[UC՘uzԸ6:=R$841͘UQ+r4$kgSP ZܼyԀ`#xoZUv5{ukk}=bM{}j{$>5_ Rkxp[R|ǝX:pѵ@bj. Pz*.Rz$Z)8S~Ng'{ڳj 5z)ЁΠKKMH{[ fwt`|7x/ xkwzn%l+ݱE)5-l {] vW"M,Os䭦@itwծ/[@U MNIDC:`xc='[w pxKZo7/*U ==޾3k,^VO=.uK}6E[(׉3**Ml\XwTR(53C>E;&J[fh55$1l̗.p&-h65{7tYʄ\M`2$*:+`}6{ƌffܻ[ zTQI *^YHс!y]qZ}b{}њ>h 1Rll Ů[B'|*0x e!|h~@]<$W9J6k;c^TUgPjY\YVK^r_A]b\C0 6؎rWu>0Y3`'SR 6!čynܞs  9)/Hsw+$f.dVfNquNs[X qWK|}/@CmdU& T1({ڸyaޡw8 ES;VQ(: Ϊr - n'Ga*> -(~WvpWB_$c g>۱ڤ7Xu|!y\L}ʮcUI/ZOɊk[;R՚RC 63NPj3#q8{Ȥn+B=ͷ/|JڪQYh+N}> Eg/g,DaoP5endstream endobj 190 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 881 >> stream x}hun9coq,"u(m'9CYo״Yվ%wiI.IvK3 eRa8u(c ˗,&@g_W[[\$l=Yxۊ̨̒(luby'(yvσ"N31]5o1; j%Y[l[I'vNjbˡ߅z#ϩ$"#Dq#v |Kz8f.Yױb:!Xg`CN&8ZI-zI5o2"^j1{:rqȇpx ӸyU/Nh(sY<;Yl%؆J[\+IAԵݵn8<*bؗF:?*/oF?c@|@V%'i!3RHpcbl=_+_꽜M]7àu̸~|sUqұDo,sFxK%d;w Nh >"w3馅M1& Qjf}Sw`Qv-6!'.'D400KrH(Φ榾Viyi*#QɈRu'sdqu|[y,6_ĦJ]K8.5ްsQusxX!#a}TЍ~^;RHǔXwo*>'~Zmnz+ك= Y7x?> stream xcd`ab`dd vsv6400q$~baaciC{@%?%Ċ!AQ |_ʸTԶ-++="۟wB} e6mmjm{LW˿~X2wJn )͝)_QUۭ>!EY3;gq-bYZvYWw tQ5W.H#Ȟߙ#WW=M8gΜ9@{o}w.]෉ʮJտ׉vk[ttsxMX&C}qrk&N0gvGDn tk?d VKYﻼnݚ5vvslf[+KZFRRX˾jQ:Ml',ї֗α{)+FXe? }*.|'Ѣ"y-_JNxr:::`ASJuwq1Od`rendstream endobj 192 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 188 >> stream xNCMR7,  <2p͋JiuP~>}L讧Ǻɋ !74/XWϡ=:4MFkgo0 7 LHsendstream endobj 193 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 900 >> stream x%oLEǯг2҇Ȓi D7mƦXYkVu@RRǎ#(cHF ! %LdqKaGWwo{]o> VBd|O{*\>+׮Ϳ4[o Ԃ=K& 3|*ה+wu/͖btϞa1&Y    &endstream endobj 194 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 212 >> stream x6CMR8vz-  T3vťbڽQ"DfVT@htkpozc,MI%ڧϋ1# :Q?f{ku؎׃$Ena}{mltNx~} 7 ZSendstream endobj 195 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 188 >> stream xcd`ab`ddds $[~gaa)_pN`db`XR繖?r3~71{'tO8Aw*}O-YX>Q{td]]g[wdݴSMT=wބ%gL6}r[w|&ߍCs10=NGendstream endobj 196 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1025 >> stream xekLUrB*KFᗙcY"l+1@nZz~Жb/ ֱ2k`dɲ1FL?zIN{7o>Qi)H$PzeS@jtL4?IeoqZJm5us[{oU&d ARpŸeZ␴bNl r 4{B871#lLlU_a9.Fy]=eP/7vrw Z-LK~?KVr>X+nIH ~0pzxHjunp 9 :L %=v*8 vs.ưpBr1g+>iJ1ʹ p;{edӪqғ'ymNg;-y«]YV/2b] +,b:μ!cŅ,Z!_6^Te\滵د~~8dlqZf9ŤTW[P5Gٓ5jڢ7;!>XNPtcK2!Oq:mrIet\= vFsgThbkyCnfF|<̰چr^A>4k0c$"eC?1MU A݇VC Bo`S(t,aش}U:6FeNhl!{HKh%1bÓwVS .. WKXqIX+/#uendstream endobj 197 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1037 >> stream xKLW1 P@NLi=}ڍ.B[UR%ET( jOc{ۘ8<&UEռHVU!]nDQuEY=wUN|䰹l޼j[ZAm%V_!]%JψfB=CǺ+~,V=%6*j[MܽV72K05+}:z):nH8)F!Rv2\pz}!gon`c@%Ȉ?J.Š@)0elXrc0׃$hieČAX \UDvd,)l4&g$ZqB|m)GCMg)fp33ٱɋZ2㭶67m=l!Dˑw>+b0 qE\!W}H#l&I@9/HJ|3h5dfN`ک',M&tȯ?6iӸ8 $eaLo[rI1G`YH44"h")R8ʲ<dr)$/% qYHr#534X?4 5i4O}X ؜nmuo}\}\=}o V`QL#8D=%bQ~&Dy5D<wɒR_y[T%)~pX|6_V@%2~{=FfGEkmkXy Ttzzs7x+B[u?R< ^(Qcx_k 65Y0#]9A+ijtr3ieE >4!{HO#0 ks顐_3u Os@WI^nY؂|xHݧ^|ʽ۔$ɲ󂞗i8=#;qJ(G*,:;jmcT]9Iv endstream endobj 198 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 342 >> stream xcd`ab`ddds$eaa~=;@1 QG/?302}n7uީ֜پf5wsl_[Z'RXZP/VՒQ2yYӧO8yH@Lygњ5{vm?ͱ~AYLHohŽ ]n0cjs_K}gKc\Ebjj7GuE&/D~ٻs\ _'|{nxwl_us1EeU1QݝM'_:InǶvs,XTZVќ%\^[K|r\,y8ȗUendstream endobj 199 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 377 >> stream xnCMMI6`d,  ijJK#Qئytpnqnr|OYY%Zu~tw|Wn~i~m~zXgy}x{XbOXy`٫ds{krlsvxi1x@PXQoq}pmufV YKExÿ‹rr~} 7 zͦHendstream endobj 200 0 obj << /Type /XRef /Length 210 /Filter /FlateDecode /DecodeParms << /Columns 5 /Predictor 12 >> /W [ 1 3 1 ] /Info 3 0 R /Root 2 0 R /Size 201 /ID [<167418ad82bb48cf1a65a1bd7f73cfdc>] >> stream xѿP{oKTMl6E"Ht0<6ş00H, lRhޓ%))M?B!c#f "k5MG :+h5` T{XAc>,w>N>= options(width=75) library(utils) # for R_DEFAULT_PACKAGES=NULL library(Matrix) @ \section{The Matrix class structures} \label{sec:classes} Take Martin's DSC 2007 talk to depict the Matrix class hierarchy; available from {\small \url{https://stat.ethz.ch/~maechler/R/DSC-2007_MatrixClassHierarchies.pdf}} . % ~/R/Meetings-Kurse-etc/2007-DSC/talk.tex Matrix-classes.Rnw --- --- --- %% \hrule[1pt]{\textwidth} From far, there are \textbf{three} separate class hierarchies, and every \pkg{Matrix} package matrix has an actual (or ``factual'') class inside these three hierarchies: % ~/R/Meetings-Kurse-etc/2007-DSC/Matrix-classes.Rnw More formally, we have three (\ 3 \ ) main ``class classifications'' for our Matrices, i.e.,\\ three ``orthogonal'' partitions of ``Matrix space'', and every Matrix object's class corresponds to an \emph{intersection} of these three partitions; i.e., in R's S4 class system: We have three independent inheritance schemes for every Matrix, and each such Matrix class is simply defined to \texttt{contain} three \emph{virtual} classes (one from each partitioning scheme), e.g, The three partioning schemes are \begin{enumerate} \item Content \texttt{type}: Classes \code{dMatrix}, \code{lMatrix}, \code{nMatrix}, (\code{iMatrix}, \code{zMatrix}) for entries of type \textbf{d}ouble, \textbf{l}ogical, patter\textbf{n} (and not yet \textbf{i}nteger and complex) Matrices. \code{nMatrix} only stores the \emph{location} of non-zero matrix entries (where as logical Matrices can also have \code{NA} entries!) \item structure: general, triangular, symmetric, diagonal Matrices \item sparsity: \code{denseMatrix}, \code{sparseMatrix} \end{enumerate} For example in the most used sparseMatrix class, \code{"dgCMatrix"}, the three initial letters \code{dgC} each codes for one of the three hierarchies: \begin{description} \item{d: } \textbf{d}ouble \item{g: } \textbf{g}eneral \item{C: } \textbf{C}sparseMatrix, where \textbf{C} is for \textbf{C}olumn-compressed. \end{description} Part of this is visible from printing \code{getClass("\emph{}")}: <>= getClass("dgCMatrix") @ Another example is the \code{"nsTMatrix"} class, where \code{nsT} stands for \begin{description} \item{n: } \textbf{n} is for ``patter\textbf{n}'', boolean content where only the \emph{locations} of the non-zeros need to be stored. \item{t: } \textbf{t}riangular matrix; either \textbf{U}pper, or \textbf{L}ower. \item{T: } \textbf{T}sparseMatrix, where \textbf{T} is for \textbf{T}riplet, the simplest but least efficient way to store a sparse matrix. \end{description} From R itself, via \code{getClass(.)}: <>= getClass("ntTMatrix") @ \subsection{Diagonal Matrices} \label{ssec:diagMat} The class of diagonal matrices is worth mentioning for several reasons. First, we have wanted such a class, because \emph{multiplication} methods are particularly simple with diagonal matrices. The typical constructor is \Rfun{Diagonal} whereas the accessor (as for traditional matrices), \Rfun{diag} simply returns the \emph{vector} of diagonal entries: <>= (D4 <- Diagonal(4, 10*(1:4))) str(D4) diag(D4) @ We can \emph{modify} the diagonal in the traditional way (via method definition for \Rfun{diag<-}): <>= diag(D4) <- diag(D4) + 1:4 D4 @ Note that \textbf{unit-diagonal} matrices (the identity matrices of linear algebra) with slot \code{diag = "U"} can have an empty \code{x} slot, very analogously to the unit-diagonal triangular matrices: <>= str(I3 <- Diagonal(3)) ## empty 'x' slot getClass("diagonalMatrix") ## extending "sparseMatrix" @ Originally, we had implemented diagonal matrices as \emph{dense} rather than sparse matrices. After several years it became clear that this had not been helpful really both from a user and programmer point of view. So now, indeed the \code{"diagonalMatrix"} class does also extend \code{"sparseMatrix"}, i.e., is a subclass of it. However, we do \emph{not} store explicitly where the non-zero entries are, and the class does \emph{not} extend any of the typical sparse matrix classes, \code{"CsparseMatrix"}, \code{"TsparseMatrix"}, or \code{"RsparseMatrix"}. Rather, the \code{diag()}onal (vector) is the basic part of such a matrix, and this is simply the \code{x} slot unless the \code{diag} slot is \code{"U"}, the unit-diagonal case, which is the identity matrix. Further note, e.g., from the \code{?$\,$Diagonal} help page, that we provide (low level) utility function \code{.sparseDiagonal()} with wrappers \code{.symDiagonal()} and \code{.trDiagonal()} which will provide diagonal matrices inheriting from \code{"CsparseMatrix"} which may be advantageous in \emph{some cases}, but less efficient in others, see the help page. \section{Matrix Transformations} \label{sec:trafos} \subsection{Coercions between Matrix classes} \label{ssec:coerce} You may need to transform Matrix objects into specific shape (triangular, symmetric), content type (double, logical, \dots) or storage structure (dense or sparse). Every useR should use \code{as(x, )} to this end, where \code{} is a \emph{virtual} Matrix super class, such as \code{"triangularMatrix"} \code{"dMatrix"}, or \code{"sparseMatrix"}. In other words, the user should \emph{not} coerce directly to a specific desired class such as \code{"dtCMatrix"}, even though that may occasionally work as well. Here is a set of rules to which the Matrix developers and the users should typically adhere: \begin{description} \item[Rule~1]: \code{as(M, "matrix")} should work for \textbf{all} Matrix objects \code{M}. \item[Rule~2]: \code{Matrix(x)} should also work for matrix like objects \code{x} and always return a ``classed'' Matrix. Applied to a \code{"matrix"} object \code{m}, \code{M. <- Matrix(m)} can be considered a kind of inverse of \code{m <- as(M, "matrix")}. For sparse matrices however, \code{M.} well be a \code{CsparseMatrix}, and it is often ``more structured'' than \code{M}, e.g., <>= (M <- spMatrix(4,4, i=1:4, j=c(3:1,4), x=c(4,1,4,8))) # dgTMatrix m <- as(M, "matrix") (M. <- Matrix(m)) # dsCMatrix (i.e. *symmetric*) @ \item[Rule~3]: All the following coercions to \emph{virtual} matrix classes should work:\\ \begin{enumerate} \item \code{as(m, "dMatrix")} \item \code{as(m, "lMatrix")} \item \code{as(m, "nMatrix")} \item \code{as(m, "denseMatrix")} \item \code{as(m, "sparseMatrix")} \item \code{as(m, "generalMatrix")} \end{enumerate} whereas the next ones should work under some assumptions: \begin{enumerate} \item \code{as(m1, "triangularMatrix")} \\ should work when \code{m1} is a triangular matrix, i.e. the upper or lower triangle of \code{m1} contains only zeros. \item \code{as(m2, "symmetricMatrix")} should work when \code{m2} is a symmetric matrix in the sense of \code{isSymmetric(m2)} returning \code{TRUE}. Note that this is typically equivalent to something like \code{isTRUE(all.equal(m2, t(m2)))}, i.e., the lower and upper triangle of the matrix have to be equal \emph{up to small numeric fuzz}. \end{enumerate} \end{description} \section{Session Info} <>= toLatex(sessionInfo()) @ %not yet %\bibliography{Matrix} \end{document} Matrix/inst/doc/Introduction.R0000644000176200001440000000032714547724202016055 0ustar liggesusers### R code from vignette source 'Introduction.Rnw' ################################################### ### code chunk number 1: preliminaries ################################################### options(width=75) Matrix/inst/doc/Design-issues.R0000644000176200001440000000314314547724151016120 0ustar liggesusers### R code from vignette source 'Design-issues.Rnw' ################################################### ### code chunk number 1: preliminaries ################################################### options(width=75) library(utils) # for R_DEFAULT_PACKAGES=NULL library(Matrix) ################################################### ### code chunk number 2: dgC-ex ################################################### getClass("dgCMatrix") ################################################### ### code chunk number 3: dgC-ex ################################################### getClass("ntTMatrix") ################################################### ### code chunk number 4: diag-class ################################################### (D4 <- Diagonal(4, 10*(1:4))) str(D4) diag(D4) ################################################### ### code chunk number 5: diag-2 ################################################### diag(D4) <- diag(D4) + 1:4 D4 ################################################### ### code chunk number 6: unit-diag ################################################### str(I3 <- Diagonal(3)) ## empty 'x' slot getClass("diagonalMatrix") ## extending "sparseMatrix" ################################################### ### code chunk number 7: Matrix-ex ################################################### (M <- spMatrix(4,4, i=1:4, j=c(3:1,4), x=c(4,1,4,8))) # dgTMatrix m <- as(M, "matrix") (M. <- Matrix(m)) # dsCMatrix (i.e. *symmetric*) ################################################### ### code chunk number 8: sessionInfo ################################################### toLatex(sessionInfo()) Matrix/inst/doc/Intro2Matrix.Rnw0000644000176200001440000004461614444514070016310 0ustar liggesusers\documentclass{article} % \usepackage{myVignette} \usepackage{fullpage}% save trees ;-) \usepackage[authoryear,round]{natbib} \bibliographystyle{plainnat} \newcommand{\noFootnote}[1]{{\small (\textit{#1})}} \newcommand{\myOp}[1]{{$\left\langle\ensuremath{#1}\right\rangle$}} % %%\VignetteIndexEntry{2nd Introduction to the Matrix Package} %%\VignetteDepends{Matrix,utils} \SweaveOpts{engine=R,eps=FALSE,pdf=TRUE,width=7,height=4,strip.white=true,keep.source=TRUE} % ^^^^^^^^^^^^^^^^ \title{2nd Introduction to the Matrix package} \author{Martin Maechler and Douglas Bates\\ R Core Development Team \\\email{maechler@stat.math.ethz.ch}, \email{bates@r-project.org}} \date{September 2006 ({\tiny typeset on \tiny\today})} % \begin{document} \maketitle \begin{abstract} % \emph{\Large Why should you want to work with this package and what % does it do for you?} Linear algebra is at the core of many areas of statistical computing and from its inception the \Slang{} has supported numerical linear algebra via a matrix data type and several functions and operators, such as \code{\%*\%}, \code{qr}, \code{chol}, and \code{solve}. However, these data types and functions do not provide direct access to all of the facilities for efficient manipulation of dense matrices, as provided by the Lapack subroutines, and they do not provide for manipulation of sparse matrices. The \pkg{Matrix} package provides a set of S4 classes for dense and sparse matrices that extend the basic matrix data type. Methods for a wide variety of functions and operators applied to objects from these classes provide efficient access to BLAS (Basic Linear Algebra Subroutines), Lapack (dense matrix), CHOLMOD including AMD and COLAMD and \code{Csparse} (sparse matrix) routines. One notable characteristic of the package is that whenever a matrix is factored, the factorization is stored as part of the original matrix so that further operations on the matrix can reuse this factorization. \end{abstract} %% Note: These are explained in '?RweaveLatex' : <>= options(width=75) library(utils) # for R_DEFAULT_PACKAGES=NULL @ \section{Introduction} \label{sec:Intro} The most automatic way to use the \pkg{Matrix} package is via the \Rfun{Matrix} function which is very similar to the standard \RR\ function \Rfun{matrix}, @ <>= library(Matrix) M <- Matrix(10 + 1:28, 4, 7) M tM <- t(M) @ %def Such a matrix can be appended to (using \Rfun{cbind} or \Rfun{rbind}) or indexed, <>= (M2 <- cbind(-1, M)) M[2, 1] M[4, ] @ where the last two statements show customary matrix indexing, returning a simple numeric vector each\footnote{because there's an additional default argument to indexing, \code{drop = TRUE}. If you add \hbox{``\code{\ ,\ drop = FALSE}\ ''} you will get submatrices instead of simple vectors.}. We assign 0 to some columns and rows to ``sparsify'' it, and some \code{NA}s (typically ``missing values'' in data analysis) in order to demonstrate how they are dealt with; note how we can \emph{``subassign''} as usual, for classical \RR{} matrices (i.e., single entries or whole slices at once), @ <>= M2[, c(2,4:6)] <- 0 M2[2, ] <- 0 M2 <- rbind(0, M2, 0) M2[1:2,2] <- M2[3,4:5] <- NA @ and then coerce it to a sparse matrix, @ <>= sM <- as(M2, "sparseMatrix") 10 * sM identical(sM * 2, sM + sM) is(sM / 10 + M2 %/% 2, "sparseMatrix") @ %def where the last three calls show that multiplication by a scalar keeps sparcity, as does other arithmetic, but addition to a ``dense'' object does not, as you might have expected after some thought about ``sensible'' behavior: @ <>= sM + 10 @ %def Operations on our classed matrices include (componentwise) arithmetic ($+$, $-$, $*$, $/$, etc) as partly seen above, comparison ($>$, $\le$, etc), e.g., <>= Mg2 <- (sM > 2) Mg2 @ returning a logical sparse matrix. When interested in the internal \textbf{str}ucture, \Rfun{str} comes handy, and we have been using it ourselves more regulary than \Rfun{print}ing (or \Rfun{show}ing as it happens) our matrices; alternatively, \Rfun{summary} gives output similar to Matlab's printing of sparse matrices. @ <>= str(Mg2) summary(Mg2) @ As you see from both of these, \code{Mg2} contains ``extra zero'' (here \code{FALSE}) entries; such sparse matrices may be created for different reasons, and you can use \Rfun{drop0} to remove (``drop'') these extra zeros. This should \emph{never} matter for functionality, and does not even show differently for logical sparse matrices, but the internal structure is more compact: <>= Mg2 <- drop0(Mg2) str(Mg2@x) # length 13, was 16 @ For large sparse matrices, visualization (of the sparsity pattern) is important, and we provide \Rfun{image} methods for that, e.g., <>= data(CAex, package = "Matrix") print(image(CAex, main = "image(CAex)")) # print(.) needed for Sweave @ \smallskip Further, i.e., in addition to the above implicitly mentioned \code{"Ops"} operators (\code{+}, \code{*},\dots, \code{<=},\code{>},\dots, \code{\&} which all work with our matrices, notably in conjunction with scalars and traditional matrices), the \code{"Math"}-operations (such as \Rfun{exp}, \Rfun{sin} or \Rfun{gamma}) and \code{"Math2"} (\Rfun{round} etc) and the \code{"Summary"} group of functions, \Rfun{min}, \Rfun{range}, \Rfun{sum}, all work on our matrices as they should. Note that all these are implemented via so called \emph{group methods}, see e.g., \code{?Arith} in \RR. The intention is that sparse matrices remain sparse whenever sensible, given the matrix \emph{classes} and operators involved, but not content specifically. E.g., + gives even for the rare cases where it would be advantageous to get a result. These classed matrices can be ``indexed'' (more technically ``subset'') as traditional \Slang{} (and hence \RR) matrices, as partly seen above. This also includes the idiom \code{M [ M \myOp{\mathit{op}} \myOp{\mathrm{num}}~]} which returns simple vectors, @ <>= sM[sM > 2] sml <- sM[sM <= 2] sml @ %def and \emph{``subassign''}ment similarly works in the same generality as for traditional \Slang{} matrices. %% We have seen that already above! %% This was the 2005 - Introduction vignette's first section: \subsection{\pkg{Matrix} package for numerical linear algebra} \label{ssec:intro-linalg} Linear algebra is at the core of many statistical computing techniques and, from its inception, the \Slang{} has supported numerical linear algebra via a matrix data type and several functions and operators, such as \code{\%*\%}, \code{qr}, \code{chol}, and \code{solve}. %% Initially the numerical linear algebra functions in \RR{} called underlying Fortran routines from the Linpack~\citep{Linpack} and Eispack~\citep{Eispack} libraries but over the years most of these functions have been switched to use routines from the Lapack~\citep{Lapack} library which is the state-of-the-art implementation of numerical dense linear algebra. %% Furthermore, \RR{} can be configured to use accelerated BLAS (Basic Linear Algebra Subroutines), such as those from the Atlas~\citep{Atlas} project or other ones, see the \RR~manual ``Installation and Administration''. Lapack provides routines for operating on several special forms of matrices, such as triangular matrices and symmetric matrices. Furthermore, matrix decompositions like the QR decompositions produce multiple output components that should be regarded as parts of a single object. There is some support in \RR{} for operations on special forms of matrices (e.g. the \code{backsolve}, \code{forwardsolve} and \code{chol2inv} functions) and for special structures (e.g. a QR structure is implicitly defined as a list by the \code{qr}, \code{qr.qy}, \code{qr.qty}, and related functions) but it is not as fully developed as it could be. Also there is no direct support for sparse matrices in \RR{} although \citet{koen:ng:2003} have developed the \pkg{SparseM} package for sparse matrices based on SparseKit. The \pkg{Matrix} package provides S4 classes and methods for dense and sparse matrices. The methods for dense matrices use Lapack and BLAS. The sparse matrix methods use CHOLMOD~\citep{Cholmod}, CSparse~\citep{Csparse} and other parts (AMD, COLAMD) of Tim Davis' ``SuiteSparse'' collection of sparse matrix libraries, many of which also use BLAS. \TODO{\Rfun{triu}, \Rfun{tril}, \Rfun{diag}, ... and \command{as(.,.)} , but of course only when they've seen a few different ones.} \TODO{matrix operators include \code{\%*\%}, \Rfun{crossprod}, \Rfun{tcrossprod}, \Rfun{solve}} \TODO{\Rfun{expm} is the matrix exponential ... ...} \TODO{\Rfun{symmpart} and \Rfun{skewpart} compute the symmetric part, \code{(x + t(x))/2} and the skew-symmetric part, \code{(x - t(x))/2} of a matrix \code{x}.} \TODO{factorizations include \Rfun{Cholesky} (or \Rfun{chol}), \Rfun{lu}, \Rfun{qr} (not yet for dense)} \TODO{Although generally the result of an operation on dense matrices is a dgeMatrix, certain operations return matrices of special types.} \TODO{E.g. show the distinction between \code{t(mm) \%*\% mm} and \code{crossprod(mm)}.} % \bigskip % ... ... ... The following is the old \file{Introduction.Rnw} ... FIXME ... ... \bigskip \section{Matrix Classes} The \pkg{Matrix} package provides classes for real (stored as double precision), logical and so-called ``pattern'' (binary) dense and sparse matrices. There are provisions to also provide integer and complex (stored as double precision complex) matrices. Note that in \RR, \code{logical} means entries \code{TRUE}, \code{FALSE}, or \code{NA}. To store just the non-zero pattern for typical sparse matrix algorithms, the pattern matrices are \emph{binary}, i.e., conceptually just \code{TRUE} or \code{FALSE}. In \pkg{Matrix}, the pattern matrices all have class names starting with \code{"n"} (patter\textbf{n}). \subsection{Classes for dense matrices} \label{ssec:DenseClasses} For the sake of brevity, we restrict ourselves to the \emph{real} (\textbf{d}ouble) classes, but they are paralleled by \textbf{l}ogical and patter\textbf{n} matrices for all but the positive definite ones. \begin{description} \item[dgeMatrix] Real matrices in general storage mode \item[dsyMatrix] Symmetric real matrices in non-packed storage \item[dspMatrix] Symmetric real matrices in packed storage (one triangle only) \item[dtrMatrix] Triangular real matrices in non-packed storage \item[dtpMatrix] Triangular real matrices in packed storage (triangle only) \item[dpoMatrix] Positive semi-definite symmetric real matrices in non-packed storage \item[dppMatrix] \ \ ditto \ \ in packed storage \end{description} Methods for these classes include coercion between these classes, when appropriate, and coercion to the \code{matrix} class; methods for matrix multiplication (\code{\%*\%}); cross products (\code{crossprod}), matrix norm (\code{norm}); reciprocal condition number (\code{rcond}); LU factorization (\code{lu}) or, for the \code{poMatrix} class, the Cholesky decomposition (\code{chol}); and solutions of linear systems of equations (\code{solve}). %-- mentioned above already: % Further, group methods have been defined for the \code{Arith} (basic % arithmetic, including with scalar numbers) and the \code{Math} (basic % mathematical functions) group.. Whenever a factorization or a decomposition is calculated it is preserved as a (list) element in the \code{factors} slot of the original object. In this way a sequence of operations, such as determining the condition number of a matrix then solving a linear system based on the matrix, do not require multiple factorizations of the same matrix nor do they require the user to store the intermediate results. \subsection{Classes for sparse matrices} \label{sec:SparseClasses} Used for large matrices in which most of the elements are known to be zero (or \code{FALSE} for logical and binary (``pattern'') matrices). Sparse matrices are automatically built from \Rfun{Matrix} whenever the majority of entries is zero (or \code{FALSE} respectively). Alternatively, \Rfun{sparseMatrix} builds sparse matrices from their non-zero entries and is typically recommended to construct large sparse matrices, rather than direct calls of \Rfun{new}. \TODO{E.g. model matrices created from factors with a large number of levels} \TODO{ or from spline basis functions (e.g. COBS, package \pkg{cobs}), etc.} \TODO{Other uses include representations of graphs. indeed; good you mentioned it! particularly since we still have the interface to the \pkg{graph} package. I think I'd like to draw one graph in that article --- maybe the undirected graph corresponding to a crossprod() result of dimension ca. $50^2$} \TODO{Specialized algorithms can give substantial savings in amount of storage used and execution time of operations.} \TODO{Our implementation is based on the CHOLMOD and CSparse libraries by Tim Davis.} \subsection{Representations of sparse matrices} \label{ssec:SparseReps} \subsubsection{Triplet representation (\class{TsparseMatrix})} Conceptually, the simplest representation of a sparse matrix is as a triplet of an integer vector \code{i} giving the row numbers, an integer vector \code{j} giving the column numbers, and a numeric vector \code{x} giving the non-zero values in the matrix.\footnote{For efficiency reasons, we use ``zero-based'' indexing in the \pkg{Matrix} package, i.e., the row indices \code{i} are in \code{0:(nrow(.)-1)} and the column indices \code{j} accordingly.} In \pkg{Matrix}, the \class{TsparseMatrix} class is the virtual class of all sparse matrices in triplet representation. Its main use is for easy input or transfer to other classes. As for the dense matrices, the class of the \code{x} slot may vary, and the subclasses may be triangular, symmetric or unspecified (``general''), such that the \class{TsparseMatrix} class has several\footnote{the $3 \times 3$ actual subclasses of \class{TsparseMatrix} are the three structural kinds, namely \textbf{t}riangular, \textbf{s}ymmetric and \textbf{g}eneral, times three entry classes, \textbf{d}ouble, \textbf{l}ogical, and patter\textbf{n}.} `actual'' subclasses, the most typical (numeric, general) is \class{dgTMatrix}: <>= getClass("TsparseMatrix") # (i,j, Dim, Dimnames) slots are common to all getClass("dgTMatrix") @ Note that the \emph{order} of the entries in the \code{(i,j,x)} vectors does not matter; consequently, such matrices are not unique in their representation. \footnote{ Furthermore, there can be \emph{repeated} \code{(i,j)} entries with the customary convention that the corresponding \code{x} entries are \emph{added} to form the matrix element $m_{ij}$. } %% The triplet representation is row-oriented if elements in the same row %% were adjacent and column-oriented if elements in the same column were %% adjacent. \subsubsection{Compressed representations: \class{CsparseMatrix} and \class{RsparseMatrix}} For most sparse operations we use the compressed column-oriented representation (virtual class \class{CsparseMatrix}) (also known as ``csc'', ``compressed sparse column''). Here, instead of storing all column indices \code{j}, only the \emph{start} index of every column is stored. Analogously, there is also a compressed sparse row (csr) representation, which e.g. is used in in the \pkg{SparseM} package, and we provide the \class{RsparseMatrix} for compatibility and completeness purposes, in addition to basic coercion (\code({as(., \textit{})} between the classes. %% (column-oriented triplet) except that \code{i} (\code{j}) just stores %% the index of the first element in the row (column). (There are a %% couple of other details but that is the gist of it.) These compressed representations remove the redundant row (column) indices and provide faster access to a given location in the matrix because you only need to check one row (column). There are certain advantages \footnote{routines can make use of high-level (``level-3'') BLAS in certain sparse matrix computations} to csc in systems like \RR{}, Octave and Matlab where dense matrices are stored in column-major order, therefore it is used in sparse matrix libraries such as CHOLMOD or CSparse of which we make use. For this reason, the \class{CsparseMatrix} class and subclasses are the principal classes for sparse matrices in the \pkg{Matrix} package. The Matrix package provides the following classes for sparse matrices \FIXME{many more --- maybe explain naming scheme?} \begin{description} \item[dgTMatrix] general, numeric, sparse matrices in (a possibly redundant) triplet form. This can be a convenient form in which to construct sparse matrices. \item[dgCMatrix] general, numeric, sparse matrices in the (sorted) compressed sparse column format. \item[dsCMatrix] symmetric, real, sparse matrices in the (sorted) compressed sparse column format. Only the upper or the lower triangle is stored. Although there is provision for both forms, the lower triangle form works best with TAUCS. \item[dtCMatrix] triangular, real, sparse matrices in the (sorted) compressed sparse column format. \end{description} \TODO{Can also read and write the Matrix Market and read the Harwell-Boeing representations.} \TODO{Can convert from a dense matrix to a sparse matrix (or use the Matrix function) but going through an intermediate dense matrix may cause problems with the amount of memory required.} \TODO{similar range of operations as for the dense matrix classes.} \section{More detailed examples of ``Matrix'' operations} Have seen \texttt{drop0()} above, %(p.3); only with logical showe a nice double example (where you see ``.'' and ``0''). Show the use of \code{dim<-} for \emph{resizing} a (sparse) matrix. Maybe mention \Rfun{nearPD}. \TODO{Solve a sparse least squares problem and demonstrate memory / speed gain} \TODO{mention \code{lme4} and \Rfun{lmer}, maybe use one example to show the matrix sizes.} \section{Notes about S4 classes and methods implementation} Maybe we could % even here (for R News, not only for JSS) give some glimpses of implementations at least on the \RR{} level ones? \TODO{The class hierarchy: a non-trivial tree where only the leaves are ``actual'' classes.} \TODO{The main advantage of the multi-level hierarchy is that methods can often be defined on a higher (virtual class) level which ensures consistency [and saves from ``cut \& paste'' and forgetting things]} \TODO{Using Group Methods} \section{Session Info} <>= toLatex(sessionInfo()) @ \bibliography{Matrix} \end{document} Matrix/inst/doc/Introduction.Rnw0000644000176200001440000001753412070262574016430 0ustar liggesusers\documentclass{article} \usepackage{myVignette} \usepackage[authoryear,round]{natbib} \bibliographystyle{plainnat} %%\VignetteIndexEntry{Introduction to the Matrix Package} %%\VignetteDepends{Matrix} \SweaveOpts{engine=R,eps=FALSE,pdf=TRUE,width=5,height=3,strip.white=true,keep.source=TRUE} \title{Introduction to the Matrix package --- as of Feb.~2005\footnote{ There's an unfinished ``2nd Introduction to the Matrix package'' which contains partly newer information, but is not at all self-contained. Eventually that will replace this one.}} \author{Douglas Bates\\R Core Development Group\\\email{bates@r-project.org}} \date{\today} \begin{document} \maketitle \begin{abstract} Linear algebra is at the core of many areas of statistical computing and from its inception the \Slang{} has supported numerical linear algebra via a matrix data type and several functions and operators, such as \code{\%*\%}, \code{qr}, \code{chol}, and \code{solve}. However, these data types and functions do not provide direct access to all of the facilities for efficient manipulation of dense matrices, as provided by the Lapack subroutines, and they do not provide for manipulation of sparse matrices. The \code{Matrix} package provides a set of S4 classes for dense and sparse matrices that extend the basic matrix data type. Methods for a wide variety of functions and operators applied to objects from these classes provide efficient access to BLAS (Basic Linear Algebra Subroutines), Lapack (dense matrix), TAUCS (sparse matrix) and UMFPACK (sparse matrix) routines. One notable characteristic of the package is that whenever a matrix is factored, the factorization is stored as part of the original matrix so that further operations on the matrix can reuse this factorization. \end{abstract} <>= options(width=75) @ \section{Introduction} \label{sec:Intro} Linear algebra is at the core of many statistical computing techniques and, from its inception, the \Slang{} has supported numerical linear algebra via a matrix data type and several functions and operators, such as \code{\%*\%}, \code{qr}, \code{chol}, and \code{solve}. Initially the numerical linear algebra functions in \RR{} called underlying Fortran routines from the Linpack~\citep{Linpack} and Eispack~\cite{Eispack} libraries but over the years most of these functions have been switched to use routines from the Lapack~\cite{Lapack} library. Furthermore, \RR{} can be configured to use accelerated BLAS (Basic Linear Algebra Subroutines), such as those from the Atlas~\cite{Atlas} project or Goto's BLAS~\cite{GotosBLAS}. Lapack provides routines for operating on several special forms of matrices, such as triangular matrices and symmetric matrices. Furthermore,matrix decompositions like the QR decompositions produce multiple output components that should be regarded as parts of a single object. There is some support in R for operations on special forms of matrices (e.g. the \code{backsolve}, \code{forwardsolve} and \code{chol2inv} functions) and for special structures (e.g. a QR structure is implicitly defined as a list by the \code{qr}, \code{qr.qy}, \code{qr.qty}, and related functions) but it is not as fully developed as it could be. Also there is no direct support for sparse matrices in R although \citet{koen:ng:2003} have developed a contributed package for sparse matrices based on SparseKit. The \code{Matrix} package provides S4 classes and methods for dense and sparse matrices. The methods for dense matrices use Lapack and BLAS. The sparse matrix methods use TAUCS~\citep{Taucs}, UMFPACK~\citep{Umfpack}, and Metis~\citep{Metis}. \section{Classes for dense matrices} \label{sec:DenseClasses} The \code{Matrix} package will provide classes for real (stored as double precision) and complex (stored as double precision complex) dense matrices. At present only the real classes have been implemented. These classes are \begin{description} \item[dgeMatrix] Real matrices in general storage mode \item[dsyMatrix] Symmetric real matrices in non-packed storage \item[dspMatrix] Symmetric real matrices in packed storage (one triangle only) \item[dtrMatrix] Triangular real matrices in non-packed storage \item[dtpMatrix] Triangular real matrices in packed storage (triangle only) \item[dpoMatrix] Positive semi-definite symmetric real matrices in non-packed storage \item[dppMatrix] \ \ ditto \ \ in packed storage \end{description} Methods for these classes include coercion between these classes, when appropriate, and coercion to the \code{matrix} class; methods for matrix multiplication (\code{\%*\%}); cross products (\code{crossprod}), matrix norm (\code{norm}); reciprocal condition number (\code{rcond}); LU factorization (\code{lu}) or, for the \code{poMatrix} class, the Cholesky decomposition (\code{chol}); and solutions of linear systems of equations (\code{solve}). Further, group methods have been defined for the \code{Arith} (basic arithmetic, including with scalar numbers) and the \code{Math} (basic mathematical functions) group.. Whenever a factorization or a decomposition is calculated it is preserved as a (list) element in the \code{factors} slot of the original object. In this way a sequence of operations, such as determining the condition number of a matrix then solving a linear system based on the matrix, do not require multiple factorizations of the same matrix nor do they require the user to store the intermediate results. \section{Classes for sparse matrices} \label{sec:SparseClasses} \subsection{Representations of sparse matrices} \label{ssec:SparseReps} Conceptually, the simplest representation of a sparse matrix is as a triplet of an integer vector \code{i} giving the row numbers, an integer vector \code{j} giving the column numbers, and a numeric vector \code{x} giving the non-zero values in the matrix. An S4 class definition might be \begin{Schunk} \begin{Sinput} setClass("dgTMatrix", representation(i = "integer", j = "integer", x = "numeric", Dim = "integer")) \end{Sinput} \end{Schunk} The triplet representation is row-oriented if elements in the same row were adjacent and column-oriented if elements in the same column were adjacent. The compressed sparse row (csr) (or compressed sparse column - csc) representation is similar to row-oriented triplet (column-oriented triplet) except that \code{i} (\code{j}) just stores the index of the first element in the row (column). (There are a couple of other details but that is the gist of it.) These compressed representations remove the redundant row (column) indices and provide faster access to a given location in the matrix because you only need to check one row (column). The preferred representation of sparse matrices in the SparseM package is csr. Matlab uses csc. We hope that Octave will also use this representation. There are certain advantages to csc in systems like R and Matlab where dense matrices are stored in column-major order. For example, Sivan Toledo's TAUCS~\cite{Taucs} library and Tim Davis's UMFPACK~\cite{Umfpack} library are both based on csc and can both use level-3 BLAS in certain sparse matrix computations. The Matrix package provides the following classes for sparse matrices \begin{description} \item[dgTMatrix] general, numeric, sparse matrices in (a possibly redundant) triplet form. This can be a convenient form in which to construct sparse matrices. \item[dgCMatrix] general, numeric, sparse matrices in the (sorted) compressed sparse column format. \item[dsCMatrix] symmetric, real, sparse matrices in the (sorted) compressed sparse column format. Only the upper or the lower triangle is stored. Although there is provision for both forms, the lower triangle form works best with TAUCS. \item[dtCMatrix] triangular, real, sparse matrices in the (sorted) compressed sparse column format. \end{description} \bibliography{Matrix} \end{document} Matrix/inst/doc/sparseModels.Rnw0000644000176200001440000002553414444514070016405 0ustar liggesusers\documentclass{article} % \usepackage{fullpage} \usepackage{myVignette} \usepackage[authoryear,round]{natbib} \bibliographystyle{plainnat} \newcommand{\noFootnote}[1]{{\small (\textit{#1})}} \newcommand{\myOp}[1]{{$\left\langle\ensuremath{#1}\right\rangle$}} %%\VignetteIndexEntry{Sparse Model Matrices} %%\VignetteDepends{Matrix,MASS,datasets,grDevices,stats,utils} \title{Sparse Model Matrices} \author{Martin Maechler\\ R Core Development Team \\\email{maechler@R-project.org}} \date{July 2007, 2008 ({\tiny typeset on \tiny\today})} % \begin{document} \maketitle \SweaveOpts{engine=R, keep.source=TRUE} \SweaveOpts{eps=FALSE, pdf=TRUE, width=8, height=5.5, strip.white=true} \setkeys{Gin}{width=\textwidth} % \begin{abstract} % ............................ FIXME % \end{abstract} %% Note: These are explained in '?RweaveLatex' : <>= options(width=75) library(grDevices) # for R_DEFAULT_PACKAGES=NULL library(stats) # ditto library(utils) # ditto @ \section*{Introduction} Model matrices in the very widely used (generalized) linear models of statistics, (typically fit via \Rfun{lm} or \Rfun{glm} in \RR) are often practically sparse --- whenever categorical predictors, \code{factor}s in \RR, are used. %% FIXME: Introduce lm.fit.sparse() or not ? We show for a few classes of such linear models how to construct sparse model matrices using sparse matrix (S4) objects from the \pkg{Matrix} package, and typically \emph{without} using dense matrices in intermediate steps. %% only the latter is really novel, since "SparseM" (and others) %% have used the equivalent of %% as( model.matrix(.....), "sparseMatrix") \section{One factor: \texttt{y $\sim$ f1}} Let's start with an artifical small example: <>= (ff <- factor(strsplit("statistics_is_a_task", "")[[1]], levels=c("_",letters))) factor(ff) # drops the levels that do not occur f1 <- ff[, drop=TRUE] # the same, more transparently @ and now assume a model $$y_i = \mu + \alpha_{j(i)} + E_i,$$ for $i=1,\dots,n =$~\code{length(f1)}$= 20$, and $\alpha_{j(i)}$ with a constraint such as $\sum_j \alpha_j = 0$ (``sum'') or $\alpha_1 = 0$ (``treatment'') and $j(i) =$\code{as.numeric(f1[i])} being the level number of the $i$-th observation. For such a ``design'', the model is only estimable if the levels \code{c} and \code{k} are merged, and <>= levels(f1)[match(c("c","k"), levels(f1))] <- "ck" library(Matrix) Matrix(contrasts(f1)) # "treatment" contrasts by default -- level "_" = baseline Matrix(contrasts(C(f1, sum))) Matrix(contrasts(C(f1, helmert)), sparse=TRUE) # S-plus default; much less sparse @ where \Rfun{contrasts} is (conceptually) just one major ingredient in the well-known \Rfun{model.matrix} function to build the linear model matrix $\mathbf{X}$ of so-called ``dummy variables''. %% Since 2007, the \pkg{Matrix} package has been providing coercion from a \code{factor} object to a \code{sparseMatrix} one to produce the transpose of the model matrix corresponding to a model with that factor as predictor (and no intercept): <>= as(f1, "sparseMatrix") @ which is really almost the transpose of using the above sparsification of \Rfun{contrasts} (and arranging for nice printing), <>= printSpMatrix( t( Matrix(contrasts(f1))[as.character(f1) ,] ), col.names=TRUE) @ and that is the same as the ``sparsification'' of \Rfun{model.matrix}, apart from the column names (here transposed), <>= t( Matrix(model.matrix(~ 0+ f1))) # model with*OUT* intercept @ A more realistic small example is the \code{chickwts} data set, <>= data(chickwts, package = "datasets") str(chickwts)# a standard R data set, 71 x 2 x.feed <- as(chickwts$feed, "sparseMatrix") x.feed[ , (1:72)[c(TRUE,FALSE,FALSE)]] ## every 3rd column: @ % FIXME: Move this to ../../../MatrixModels/inst/doc/ ??? % ## Provisional (hence unexported) sparse lm.fit(): % Matrix:::lm.fit.sparse(x = t(x.feed), y = chickwts[,1]) %- for emacs: $ \section{One factor, one continuous: \texttt{y $\sim$ f1 + x}} To create the model matrix for the case of one factor and one continuous predictor---called ``analysis of covariance'' in the historical literature--- we can adopt the following simple scheme. %% Possible examples: %% - Puromycin %% - ToothGrowth %--- FIXME --- The final model matrix is the concatenation of: 1) create the sparse 0-1 matrix \code{m1} from the f1 main-effect 2) the single row/column 'x' == 'x' main-effect 3) replacing the values 1 in \code{m1@x} (the x-slot of the factor model matrix), by the values of \code{x} (our continuous predictor). \section{Two (or more) factors, main effects only: \texttt{y $\sim$ f1 + f2}} %% FIXME: 'warpbreaks' is smaller and more natural as fixed effect model! Let us consider the \code{warpbreaks} data set of 54 observations, <>= data(warpbreaks, package = "datasets") # a standard R data set str(warpbreaks) # 2 x 3 (x 9) balanced two-way with 9 replicates: xtabs(~ wool + tension, data = warpbreaks) @ %It is \emph{not} statistically sensible to assume that \code{Run} is a %fixed effect, however the example is handy to depict how a model matrix This example depicts how a model matrix would be built for the model \code{breaks ~ wool + tension}. Since this is a main effects model (no interactions), the desired model matrix is simply the concatenation of the model matrices of the main effects. There are two here, but the principle applies to general main effects of factors. The most sparse matrix is reached by \emph{not} using an intercept, (which would give an all-1-column) but rather have one factor fully coded (aka ``swallow'' the intercept), and all others being at \code{"treatment"} contrast, i.e., here, the \emph{transposed} model matrix, \code{tmm}, is <>= tmm <- with(warpbreaks, rbind(as(tension, "sparseMatrix"), as(wool, "sparseMatrix")[-1,,drop=FALSE])) print( image(tmm) ) # print(.) the lattice object @ \\ The matrices are even sparser when the factors have more than just two or three levels, e.g., for the morley data set, <>= data(morley, package = "datasets") # a standard R data set morley$Expt <- factor(morley$Expt) morley$Run <- factor(morley$Run) str(morley) t.mm <- with(morley, rbind(as(Expt, "sparseMatrix"), as(Run, "sparseMatrix")[-1,])) print( image(t.mm) ) # print(.) the lattice object @ %% Also see Doug's E-mail to R-help % From: "Douglas Bates" % Subject: Re: [R] Large number of dummy variables % Date: Mon, 21 Jul 2008 18:07:26 -0500 \section{Interactions of two (or more) factors,.....} %% Of course, this is *the* interesting part %% To form interactions, we would have to ``outer-multiply'' %% the single-factor model-matrices (after "[, -1]") In situations with more than one factor, particularly with interactions, the model matrix is currently not directly available via \pkg{Matrix} functions --- but we still show to build them carefully. The easiest---but not at memory resources efficient---way is to go via the dense \Rfun{model.matrix} result: <>= data(npk, package = "MASS") npk.mf <- model.frame(yield ~ block + N*P*K, data = npk) ## str(npk.mf) # the data frame + "terms" attribute m.npk <- model.matrix(attr(npk.mf, "terms"), data = npk) class(M.npk <- Matrix(m.npk)) dim(M.npk)# 24 x 13 sparse Matrix t(M.npk) # easier to display, column names readably displayed as row.names(t(.)) @ %% printSpMatrix(M.npk, col.names = "abb1") Another example was reported by a user on R-help (July 15, 2008, {\small \url{https://stat.ethz.ch/pipermail/r-help/2008-July/167772.html}}) about an ``aov error with large data set''. \begin{citation} % RAS: in my PDF, I don't see the first character I I'm looking to analyze a large data set: a within-Ss 2*2*1500 design with 20 Ss. However, aov() gives me an error. %, reproducible as follows: \end{citation} And gave the following code example (slightly edited): <>= id <- factor(1:20) a <- factor(1:2) b <- factor(1:2) d <- factor(1:1500) aDat <- expand.grid(id=id, a=a, b=b, d=d) aDat$y <- rnorm(length(aDat[, 1])) # generate some random DV data dim(aDat) # 120'000 x 5 (120'000 = 2*2*1500 * 20 = 6000 * 20) @ %% ^^^^^^^ MM: "fix" and generate much more interesting data and then continued with \begin{Sinput} m.aov <- aov(y ~ a*b*d + Error(id/(a*b*d)), data=aDat) \end{Sinput} \begin{citation}\sffamily which yields the following error:\\ \ttfamily Error in model.matrix.default(mt, mf, contrasts) :\\ allocMatrix: too many elements specified\\ \end{citation} to which he got the explanation by Peter Dalgaard that the formal model matrix involved was much too large in this case, and that PD assumed, \pkg{lme4} would be able to solve the problem. However, currently there would still be a big problem with using \pkg{lme4}, because of the many levels of \emph{fixed} effects: Specifically\footnote{the following is not run in \RR\ on purpose, rather just displayed here}, \begin{Sinput} dim(model.matrix( ~ a*b*d, data = aDat)) # 120'000 x 6000 \end{Sinput} where we note that $120'000 \times 6000 = 720 \textrm{mio}$, which is $720'000'000 * 8 / 2^{20} \approx 5500$ Megabytes. \emph{Unfortunately} \pkg{lme4} does \emph{not} use a sparse $X$-matrix for the fixed effects (yet), it just uses sparse matrices for the $Z$-matrix of random effects and sparse matrix operations for computations related to $Z$. Let us use a smaller factor \code{d} in order to investigate how sparse the $X$ matrix would be: <>= d2 <- factor(1:150) # 10 times smaller tmp2 <- expand.grid(id=id, a=a, b=b, d=d2) dim(tmp2) dim(mm <- model.matrix( ~ a*b*d, data=tmp2)) ## is 100 times smaller than original example class(smm <- Matrix(mm)) # automatically coerced to sparse round(object.size(mm) / object.size(smm), 1) @ shows that even for the small \code{d} here, the memory reduction would be more than an order of magnitude. \\ %% Reasons to fake here: %% 1) print() is needed for lattice -- but looks ugly, %% 2) the resulting pdf file is too large -- use png instead: <>= image(t(smm), aspect = 1/3, lwd=0, col.regions = "red") <>= png("sparseModels-X-sparse-image.png", width=6, height=3, units='in', res=150) print( <> ) dev.off() @ %%--NB: 'keep.source=FALSE' above is workaround-a-bug-in-R-devel-(2.13.x)--- \par\vspace*{-1ex} \centerline{% \includegraphics[width=1.1\textwidth]{sparseModels-X-sparse-image.png}} and working with the sparse instead of the dense model matrix is considerably faster as well, <>= x <- 1:600 system.time(y <- smm %*% x) ## sparse is much faster system.time(y. <- mm %*% x) ## than dense identical(as.matrix(y), y.) ## TRUE @ <>= toLatex(sessionInfo()) @ \end{document} Matrix/inst/doc/Intro2Matrix.R0000644000176200001440000000500014547724165015737 0ustar liggesusers### R code from vignette source 'Intro2Matrix.Rnw' ################################################### ### code chunk number 1: preliminaries ################################################### options(width=75) library(utils) # for R_DEFAULT_PACKAGES=NULL ################################################### ### code chunk number 2: ex1 ################################################### library(Matrix) M <- Matrix(10 + 1:28, 4, 7) M tM <- t(M) ################################################### ### code chunk number 3: ex2 ################################################### (M2 <- cbind(-1, M)) M[2, 1] M[4, ] ################################################### ### code chunk number 4: set0 ################################################### M2[, c(2,4:6)] <- 0 M2[2, ] <- 0 M2 <- rbind(0, M2, 0) M2[1:2,2] <- M2[3,4:5] <- NA ################################################### ### code chunk number 5: asSparse ################################################### sM <- as(M2, "sparseMatrix") 10 * sM identical(sM * 2, sM + sM) is(sM / 10 + M2 %/% 2, "sparseMatrix") ################################################### ### code chunk number 6: add1 ################################################### sM + 10 ################################################### ### code chunk number 7: Comp1 ################################################### Mg2 <- (sM > 2) Mg2 ################################################### ### code chunk number 8: str_mat ################################################### str(Mg2) summary(Mg2) ################################################### ### code chunk number 9: drop0 ################################################### Mg2 <- drop0(Mg2) str(Mg2@x) # length 13, was 16 ################################################### ### code chunk number 10: image ################################################### data(CAex, package = "Matrix") print(image(CAex, main = "image(CAex)")) # print(.) needed for Sweave ################################################### ### code chunk number 11: sub_logi ################################################### sM[sM > 2] sml <- sM[sM <= 2] sml ################################################### ### code chunk number 12: Tsparse-class ################################################### getClass("TsparseMatrix") # (i,j, Dim, Dimnames) slots are common to all getClass("dgTMatrix") ################################################### ### code chunk number 13: sessionInfo ################################################### toLatex(sessionInfo()) Matrix/inst/doc/SuiteSparse/0000755000176200001440000000000014547723665015532 5ustar liggesusersMatrix/inst/doc/SuiteSparse/SPQR.txt0000644000176200001440000000434311072415476017050 0ustar liggesusersSuiteSparseQR version 1.1.0, Sept 20, 2008, Copyright (c) 2008, Timothy A. Davis SuiteSparseQR is a a multithread, multifrontal, rank-revealing sparse QR factorization method. QUICK START FOR MATLAB USERS (on Windows, Linux, Solaris, or the Mac OS): To compile and test the MATLAB mexFunctions, do this in the MATLAB command window: cd SuiteSparse/SPQR/MATLAB spqr_install spqr_demo FOR MORE DETAILS: please see the User Guide in Doc/spqr_user_guide.pdf. FOR LINUX/UNIX/Mac USERS who want to use the C++ callable library: To compile the C++ library and run a short demo, just type "make" in the Unix shell. To compile the SuiteSparseQR C++ library, in the Unix shell, do: cd Lib ; make To compile and test an exhaustive test, edit the Tcov/Makefile to select the LAPACK and BLAS libraries, and then do (in the Unix shell): cd Tcov ; make Compilation options in UFconfig/UFconfig.mk, SPQR/*/Makefile, or SPQR/MATLAB/spqr_make.m: -DNPARTITION to compile without METIS (default is to use METIS) -DNEXPERT to compile without the min 2-norm solution option (default is to include the Expert routines) -DHAVE_TBB to compile with Intel's Threading Building Blocks (default is to not use Intel TBB) -DTIMING to compile with timing and exact flop counts enabled (default is to not compile with timing and flop counts) -------------------------------------------------------------------------------- SuiteSparseQR 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 2 of the License, or (at your option) any later version. SuiteSparseQR 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 Module; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Matrix/inst/doc/SuiteSparse/SuiteSparse_config.txt0000644000176200001440000000455314211636445022061 0ustar liggesusersSuiteSparse_config, 2021, Timothy A. Davis, http://www.suitesparse.com (formerly the UFconfig package) This directory contains a default SuiteSparse_config.mk file. It tries to detect your system (Linux, SunOS, or Mac), which compiler to use (icc or cc), which BLAS and LAPACK library to use (Intel MKL is strongly preferred), and whether or not to compile with CUDA. For alternatives, see the comments in the SuiteSparse_config.mk file. License: No licensing restrictions apply to this file or to the SuiteSparse_config directory. -------------------------------------------------------------------------------- SuiteSparse_config contains configuration settings for all many of the software packages that I develop or co-author. Note that older versions of some of these packages do not require SuiteSparse_config. Package Description ------- ----------- AMD approximate minimum degree ordering CAMD constrained AMD COLAMD column approximate minimum degree ordering CCOLAMD constrained approximate minimum degree ordering UMFPACK sparse LU factorization, with the BLAS CXSparse int/long/real/complex version of CSparse CHOLMOD sparse Cholesky factorization, update/downdate KLU sparse LU factorization, BLAS-free BTF permutation to block triangular form LDL concise sparse LDL' LPDASA LP Dual Active Set Algorithm RBio read/write files in Rutherford/Boeing format SPQR sparse QR factorization (full name: SuiteSparseQR) SLIP_LU sparse left-looking integer-preserving LU factorization SuiteSparse_config is not required by these packages: CSparse a Concise Sparse matrix package MATLAB_Tools toolboxes for use in MATLAB GraphBLAS graph algorithms in the language of linear algebra In addition, the xerbla/ directory contains Fortan and C versions of the BLAS/LAPACK xerbla routine, which is called when an invalid input is passed to the BLAS or LAPACK. The xerbla provided here does not print any message, so the entire Fortran I/O library does not need to be linked into a C application. Most versions of the BLAS contain xerbla, but those from K. Goto do not. Use this if you need too. If you edit this directory (SuiteSparse_config.mk in particular) then you must do "make purge ; make" in the parent directory to recompile all of SuiteSparse. Otherwise, the changes will not necessarily be applied. Matrix/inst/doc/SuiteSparse/CHOLMOD.txt0000644000176200001440000000614313652535054017351 0ustar liggesusersCHOLMOD: a sparse CHOLesky MODification package, Copyright (c) 2005-2020. http://www.suitesparse.com ----------------------------------------------- CHOLMOD is a set of routines for factorizing sparse symmetric positive definite matrices of the form A or AA', updating/downdating a sparse Cholesky factorization, solving linear systems, updating/downdating the solution to the triangular system Lx=b, and many other sparse matrix functions for both symmetric and unsymmetric matrices. Its supernodal Cholesky factorization relies on LAPACK and the Level-3 BLAS, and obtains a substantial fraction of the peak performance of the BLAS. Both real and complex matrices are supported. CHOLMOD is written in ANSI/ISO C, with both C and MATLAB interfaces. This code works on Microsoft Windows and many versions of Unix and Linux. Some Modules of CHOLMOD are copyrighted by the University of Florida (the Core and Partition Modules). The rest are copyrighted by the authors: Timothy A. Davis (all of them), and William W. Hager (the Modify Module). CHOLMOD relies on several other packages: AMD, CAMD, COLAMD, CCOLAMD, SuiteSparse_config, METIS, the BLAS, and LAPACK. All but METIS, the BLAS, and LAPACK are part of SuiteSparse. AMD is authored by T. Davis, Iain Duff, and Patrick Amestoy. COLAMD is authored by T. Davis and Stefan Larimore, with algorithmic design in collaboration with John Gilbert and Esmond Ng. CCOLAMD is authored by T. Davis and Siva Rajamanickam. CAMD is authored by T. Davis and Y. Chen. LAPACK and the BLAS are authored by Jack Dongarra and many others. LAPACK is available at http://www.netlib.org/lapack METIS 5.1.0 is authored by George Karypis, Univ. of Minnesota. Its use in CHOLMOD is optional. A copy is in SuiteSparse/metis-5.1.0. If you do not wish to use METIS, you must edit SuiteSparse_config and change the line: CHOLMOD_CONFIG = to CHOLMOD_CONFIG = -DNPARTITION The CHOLMOD, AMD, COLAMD, CCOLAMD, and SuiteSparse)config directories must all reside in a common parent directory. To compile all these libraries, edit SuiteSparse)config/SuiteSparse)config.mk to reflect your environment (C compiler, location of the BLAS, and so on) and then type "make" in either the CHOLMOD directory or in the parent directory of CHOLMOD. See each package for more details on how to compile them. For use in MATLAB (on any system, including Windows): start MATLAB, cd to the CHOLMOD/MATLAB directory, and type cholmod_make in the MATLAB Command Window. This is the best way to compile CHOLMOD for MATLAB; it provides a workaround for a METIS design feature, in which METIS terminates your program (and thus MATLAB) if it runs out of memory. Using cholmod_make also ensures your mexFunctions are compiled with -fexceptions, so that exceptions are handled properly (when hitting control-C in the MATLAB command window, for example). Acknowledgements: this work was supported in part by the National Science Foundation (NFS CCR-0203270 and DMS-9803599), and a grant from Sandia National Laboratories (Dept. of Energy) which supported the development of CHOLMOD's Partition Module. Matrix/inst/doc/SuiteSparse/COLAMD.txt0000644000176200001440000001236413652535054017225 0ustar liggesusersCOLAMD, Copyright 1998-2016, Timothy A. Davis. http://www.suitesparse.com ------------------------------------------------------------------------------- The COLAMD column approximate minimum degree ordering algorithm computes a permutation vector P such that the LU factorization of A (:,P) tends to be sparser than that of A. The Cholesky factorization of (A (:,P))'*(A (:,P)) will also tend to be sparser than that of A'*A. SYMAMD is a symmetric minimum degree ordering method based on COLAMD, available as a MATLAB-callable function. It constructs a matrix M such that M'*M has the same pattern as A, and then uses COLAMD to compute a column ordering of M. Colamd and symamd tend to be faster and generate better orderings than their MATLAB counterparts, colmmd and symmmd. To compile and test the colamd m-files and mexFunctions, just unpack the COLAMD/ directory from the COLAMD.tar.gz file, and run MATLAB from within that directory. Next, type colamd_test to compile and test colamd and symamd. This will work on any computer with MATLAB (Unix, PC, or Mac). Alternatively, type "make" (in Unix) to compile and run a simple example C code, without using MATLAB. To compile and install the colamd m-files and mexFunctions, just cd to COLAMD/MATLAB and type colamd_install in the MATLAB command window. A short demo will run. Optionally, type colamd_test to run an extensive tests. Type "make" in Unix in the COLAMD directory to compile the C-callable library and to run a short demo. Colamd is a built-in routine in MATLAB, available from The Mathworks, Inc. Under most cases, the compiled COLAMD from Versions 2.0 to the current version do not differ. Colamd Versions 2.2 and 2.3 differ only in their mexFunction interaces to MATLAB. v2.4 fixes a bug in the symamd routine in v2.3. The bug (in v2.3 and earlier) has no effect on the MATLAB symamd mexFunction. v2.5 adds additional checks for integer overflow, so that the "int" version can be safely used with 64-bit pointers. Refer to the ChangeLog for more details. Other "make" targets: make library compiles a C-callable library containing colamd make clean removes all files not in the distribution, but keeps the compiled libraries. make distclean removes all files not in the distribution make install installs the library in /usr/local/lib and /usr/local/include make uninstall uninstalls the library from /usr/local/lib and /usr/local/include To use colamd and symamd within an application written in C, all you need are colamd.c, and colamd.h, which are the C-callable colamd/symamd codes. See colamd.c for more information on how to call colamd from a C program. Requires SuiteSparse_config, in the ../SuiteSparse_config directory relative to this directory. See COLAMD/Doc/License.txt for the License. Related papers: T. A. Davis, J. R. Gilbert, S. Larimore, E. Ng, An approximate column minimum degree ordering algorithm, ACM Transactions on Mathematical Software, vol. 30, no. 3., pp. 353-376, 2004. T. A. Davis, J. R. Gilbert, S. Larimore, E. Ng, Algorithm 836: COLAMD, an approximate column minimum degree ordering algorithm, ACM Transactions on Mathematical Software, vol. 30, no. 3., pp. 377-380, 2004. "An approximate minimum degree column ordering algorithm", S. I. Larimore, MS Thesis, Dept. of Computer and Information Science and Engineering, University of Florida, Gainesville, FL, 1998. CISE Tech Report TR-98-016. Approximate Deficiency for Ordering the Columns of a Matrix, J. L. Kern, Senior Thesis, Dept. of Computer and Information Science and Engineering, University of Florida, Gainesville, FL, 1999. Authors: Stefan I. Larimore and Timothy A. Davis, in collaboration with John Gilbert, Xerox PARC (now at UC Santa Barbara), and Esmong Ng, Lawrence Berkeley National Laboratory (much of this work he did while at Oak Ridge National Laboratory). COLAMD files: Demo simple demo Doc additional documentation (see colamd.c for more) Include include file Lib compiled C-callable library Makefile primary Unix Makefile MATLAB MATLAB functions README.txt this file Source C source code ./Demo: colamd_example.c simple example colamd_example.out output of colamd_example.c colamd_l_example.c simple example, long integers colamd_l_example.out output of colamd_l_example.c Makefile Makefile for C demos ./Doc: ChangeLog change log License.txt license ./Include: colamd.h include file ./Lib: Makefile Makefile for C-callable library ./MATLAB: colamd2.m MATLAB interface for colamd2 colamd_demo.m simple demo colamd_install.m compile and install colamd2 and symamd2 colamd_make.m compile colamd2 and symamd2 colamdmex.ca MATLAB mexFunction for colamd2 colamd_test.m extensive test colamdtestmex.c test function for colamd Contents.m contents of the MATLAB directory luflops.m test code Makefile Makefile for MATLAB functions symamd2.m MATLAB interface for symamd2 symamdmex.c MATLAB mexFunction for symamd2 symamdtestmex.c test function for symamd ./Source: colamd.c primary source code Matrix/inst/doc/SuiteSparse/AMD.txt0000644000176200001440000001612113652535054016662 0ustar liggesusersAMD, Copyright (c) 2009-2013 by Timothy A. Davis (http://www.suitesparse.com), Patrick R. Amestoy, and Iain S. Duff. All Rights Reserved. AMD is available under alternate licences; contact T. Davis for details. AMD: a set of routines for permuting sparse matrices prior to factorization. Includes a version in C, a version in Fortran, and a MATLAB mexFunction. Requires SuiteSparse_config, in the ../SuiteSparse_config directory relative to this directory. Quick start (Unix, or Windows with Cygwin): To compile, test, and install AMD, you may wish to first configure the installation by editting the ../SuiteSparse_config/SuiteSparse_config.mk file. Next, cd to this directory (AMD) and type "make" (or "make lib" if you do not have MATLAB). To compile and run a demo program for the Fortran version, type "make fortran". When done, type "make clean" to remove unused *.o files (keeps the compiled libraries and demo programs). See the User Guide (Doc/AMD_UserGuide.pdf), or ../SuiteSparse_config/SuiteSparse_config.mk for more details. To install do "make install" Quick start (for MATLAB users); To compile, test, and install the AMD mexFunction, cd to the AMD/MATLAB directory and type amd_make at the MATLAB prompt. ------------------------------------------------------------------------------- AMD License: refer to the AMD/Doc/License.txt file for the license. Availability: http://www.suitesparse.com ------------------------------------------------------------------------------- This is the AMD README file. It is a terse overview of AMD. Refer to the User Guide (Doc/AMD_UserGuide.pdf) for how to install and use AMD. Description: AMD is a set of routines for pre-ordering sparse matrices prior to Cholesky or LU factorization, using the approximate minimum degree ordering algorithm. Written in ANSI/ISO C with a MATLAB interface, and in Fortran 77. Authors: Timothy A. Davis (DrTimothyAldenDavis@gmail.com) Patrick R. Amestory, ENSEEIHT, Toulouse, France. Iain S. Duff, Rutherford Appleton Laboratory, UK. Acknowledgements: This work was supported by the National Science Foundation, under grants DMS-9504974, DMS-9803599, and CCR-0203270. Portions of this work were done while on sabbatical at Stanford University and Lawrence Berkeley National Laboratory (with funding from the SciDAC program). I would like to thank Gene Golub, Esmond Ng, and Horst Simon for making this sabbatical possible. ------------------------------------------------------------------------------- Files and directories in the AMD distribution: ------------------------------------------------------------------------------- --------------------------------------------------------------------------- Subdirectories of the AMD directory: --------------------------------------------------------------------------- Doc documentation Source primary source code Include include file for use in your code that calls AMD Demo demo programs. also serves as test of the AMD installation. MATLAB AMD mexFunction for MATLAB, and supporting m-files Lib where the compiled C-callable and Fortran-callable AMD libraries placed. --------------------------------------------------------------------------- Files in the AMD directory: --------------------------------------------------------------------------- Makefile top-level Makefile Windows users would require Cygwin to use "make" README.txt this file --------------------------------------------------------------------------- Doc directory: documentation --------------------------------------------------------------------------- ChangeLog change log License.txt the AMD License Makefile for creating the documentation AMD_UserGuide.bib AMD User Guide (references) AMD_UserGuide.tex AMD User Guide (LaTeX) AMD_UserGuide.pdf AMD User Guide (PDF) --------------------------------------------------------------------------- Source directory: --------------------------------------------------------------------------- amd_order.c user-callable, primary AMD ordering routine amd_control.c user-callable, prints the control parameters amd_defaults.c user-callable, sets default control parameters amd_info.c user-callable, prints the statistics from AMD amd_1.c non-user-callable, construct A+A' amd_2.c user-callable, primary ordering kernel (a C version of amd.f and amdbar.f, with post-ordering added) amd_aat.c non-user-callable, computes nnz (A+A') amd_dump.c non-user-callable, debugging routines amd_postorder.c non-user-callable, postorder amd_post_tree.c non-user-callable, postorder just one tree amd_valid.c non-user-callable, verifies a matrix amd_preprocess.c non-user-callable, computes A', removes duplic amd.f user-callable Fortran 77 version amdbar.f user-callable Fortran 77 version --------------------------------------------------------------------------- Include directory: --------------------------------------------------------------------------- amd.h include file for C programs that use AMD amd_internal.h non-user-callable, include file for AMD --------------------------------------------------------------------------- Demo directory: --------------------------------------------------------------------------- Makefile to compile the demos amd_demo.c C demo program for AMD amd_demo.out output of amd_demo.c amd_demo2.c C demo program for AMD, jumbled matrix amd_demo2.out output of amd_demo2.c amd_l_demo.c C demo program for AMD (long integer version) amd_l_demo.out output of amd_l_demo.c amd_simple.c simple C demo program for AMD amd_simple.out output of amd_simple.c amd_f77demo.f Fortran 77 demo program for AMD amd_f77demo.out output of amd_f77demo.f amd_f77simple.c simple Fortran 77 demo program for AMD amd_f77simple.out output of amd_f77simple.f amd_f77cross.f Fortran 77 demo, calls the C version of AMD amd_f77cross.out output of amd_f77cross.f amd_f77wrapper.c Fortran-callable wrapper for C version of AMD --------------------------------------------------------------------------- MATLAB directory: --------------------------------------------------------------------------- Contents.m for "help amd2" listing of toolbox contents amd2.m MATLAB help file for AMD amd_make.m MATLAB m-file for compiling AMD mexFunction amd_install.m compile and install the AMD mexFunction amd_mex.c AMD mexFunction for MATLAB amd_demo.m MATLAB demo for AMD amd_demo.m.out diary output of amd_demo.m can_24.mat input file for AMD demo --------------------------------------------------------------------------- Lib directory: libamd.a and libamd.so library placed here --------------------------------------------------------------------------- Makefile Makefile for both shared and static libraries Matrix/inst/test-tools-Matrix.R0000644000176200001440000007540314542730653016217 0ustar liggesusers#### Tools for Package Testing --- in Matrix, sourced by ./test-tools.R #### ------------------------- ### ------- Part III -- "Matrix" (classes) specific ---------------------- ## lower.tri() and upper.tri() -- masking base definitions ## R/src/library/base/R/lower.tri.R ## R/src/library/base/R/upper.tri.R ## but we do __not__ want to coerce to "base R" 'matrix' via as.matrix(): ## lower.tri <- function(x, diag = FALSE) if(diag) row(x) >= col(x) else row(x) > col(x) upper.tri <- function(x, diag = FALSE) if(diag) row(x) <= col(x) else row(x) < col(x) lsM <- function(...) { for(n in ls(..., envir=parent.frame())) if(is((. <- get(n)),"Matrix")) cat(sprintf("%5s: '%s' [%d x %d]\n",n,class(.), nrow(.),ncol(.))) } asD <- function(m) { ## as "Dense" if(canCoerce(m, "denseMatrix")) as(m, "denseMatrix") else if(canCoerce(m, (cl <- paste(.M.kind(m), "denseMatrix", sep='')))) as(m, cl) else if(canCoerce(m, "dgeMatrix")) as(m, "dgeMatrix") else stop("cannot coerce to a typical dense Matrix") } ## "normal" sparse Matrix: Csparse, no diag="U" asCsp <- function(x) diagU2N(as(x, "CsparseMatrix")) ##' @title quasi-identical dimnames Qidentical.DN <- function(dx, dy) { stopifnot(is.list(dx) || is.null(dx), is.list(dy) || is.null(dy)) ## "empty" (is.null.DN(dx) && is.null.DN(dy)) || identical(dx, dy) } ##' quasi-identical() for 'Matrix' matrices Qidentical <- function(x,y, strictClass = TRUE) { if(!identical(class(x), cy <- class(y))) { if(strictClass || !is(x, cy)) return(FALSE) ## else try further } slts <- slotNames(x) ## MJ: should be slotNames(y), since is(x, class(y)) ?? if("Dimnames" %in% slts) { ## always (or we have no 'Matrix') slts <- slts[slts != "Dimnames"] if(!Qidentical.DN(x@Dimnames, y@Dimnames) && ## allow for "completion" of (NULL, ) dimnames of symmetricMatrix: !Qidentical.DN(dimnames(x), dimnames(y))) return(FALSE) } if("factors" %in% slts) { ## allow one empty and one non-empty 'factors' slts <- slts[slts != "factors"] ## if both are not empty, they must be the same: if(length(xf <- x@factors) && length(yf <- y@factors)) if(!identical(xf, yf)) return(FALSE) } for(sl in slts) if(!identical(slot(x,sl), slot(y,sl))) return(FALSE) TRUE } ## MJ: It seems intuitive to allow either of is(x, class(y)) ## and is(y, class(x)) when strictClass=FALSE ... .MJ.Qidentical <- function(x, y, strictClass = TRUE, skipSlots = NULL) { isxy <- identical(cx <- class(x), cy <- class(y)) if (!isxy) { if (strictClass) return(FALSE) isxy <- is(x, cy) if (!(isxy || is(y, cx))) return(FALSE) ## else try further } slts <- slotNames(if (isxy) y else x) if (length(skipSlots)) slts <- setdiff(slts, skipSlots) if ("Dimnames" %in% slts) { ## always, or we have no "Matrix" ## allow symmetrization of 'Dimnames' for "symmetricMatrix" : slts <- slts[slts != "Dimnames"] if(!Qidentical.DN(x@Dimnames, y@Dimnames) && !Qidentical.DN(dimnames(x), dimnames(y))) return(FALSE) } if ("factors" %in% slts) { ## allow one empty and one non-empty 'factors' : slts <- slts[slts != "factors"] ## if both are not empty, they must be the same: if (length(xf <- x@factors) && length(yf <- y@factors) && !identical(xf, yf)) return(FALSE) } for (slt in slts) if (!identical(slot(x, slt), slot(y, slt))) return(FALSE) TRUE } ##' quasi-identical() for traditional ('matrix') matrices mQidentical <- function(x,y, strictClass = TRUE) { if(!identical(class(x), cy <- class(y))) { if(strictClass || !is(x, cy)) return(FALSE) ## else try further } if(!Qidentical.DN(dimnames(x), dimnames(y))) return(FALSE) identical(unname(x), unname(y)) } Q.C.identical <- function(x,y, sparse = is(x,"sparseMatrix"), checkClass = TRUE, strictClass = TRUE) { if(checkClass && class(x) != class(y)) { if(strictClass || !is(x, class(y))) return(FALSE) ## else try further } if(sparse) Qidentical(as(x,"CsparseMatrix"), as(y,"CsparseMatrix"), strictClass=strictClass) else Qidentical(x,y, strictClass=strictClass) } ##' ##' ##'

##' @title Quasi-equal for 'Matrix' matrices ##' @param x Matrix ##' @param y Matrix ##' @param superclasses x and y must coincide in (not) extending these; set to empty, ##' if no class/inheritance checks should happen. ##' @param dimnames.check logical indicating if dimnames(.) much match ##' @param tol NA (--> use "==") or numerical tolerance for all.equal() ##' @return logical: Are x and y (quasi) equal ? Q.eq <- function(x, y, superclasses = c("sparseMatrix", "denseMatrix", "dMatrix", "lMatrix", "nMatrix"), dimnames.check = TRUE, tol = NA) { ## quasi-equal - for 'Matrix' matrices if(any(dim(x) != dim(y))) return(FALSE) if(dimnames.check && !identical(dimnames(x), dimnames(y))) return(FALSE) xcl <- getClassDef(class(x)) ycl <- getClassDef(class(y)) for(SC in superclasses) { if( extends(xcl, SC) && !extends(ycl, SC)) return(FALSE) } asC <- ## asCommon if((isDense <- extends(xcl,"denseMatrix"))) function(m) as(m, "matrix") else function(m) as(as(as(m,"CsparseMatrix"), "dMatrix"), "generalMatrix") # => "dgC" if(is.na(tol)) { if(isDense) all(x == y | (is.na(x) & is.na(y))) else ## 'x == y' blows up for large sparse matrices: isTRUE(all.equal(asC(x), asC(y), tolerance = 0., check.attributes = dimnames.check)) } else if(is.numeric(tol) && tol >= 0) { isTRUE(all.equal(asC(x), asC(y), tolerance = tol, check.attributes = dimnames.check)) } else stop("'tol' must be NA or non-negative number") } Q.eq2 <- function(x, y, superclasses = c("sparseMatrix", "denseMatrix"), dimnames.check = FALSE, tol = NA) Q.eq(x,y, superclasses=superclasses, dimnames.check=dimnames.check, tol=tol) ##' ##' ##'
##' @title Quasi-equality of symmpart(m) + skewpart(m) with m ##' @param m Matrix ##' @param tol numerical tolerance for all.equal() ##' @return logical ##' @author Martin Maechler Q.eq.symmpart <- function(m, tol = 8 * .Machine$double.eps) { ss <- symmpart(m) + skewpart(m) if(hasNA <- any(iNA <- is.na(ss))) { ## ss has the NA's symmetrically, but typically m has *not* iiNA <- which(iNA) # <- useful! -- this tests which() methods! ## assign NA's too -- using correct kind of NA: m[iiNA] <- as(NA, Matrix:::.type.kind[Matrix:::.M.kind(m)]) } Q.eq2(m, ss, tol = tol) } ##' sample.int(n, size, replace=FALSE) for really large n: sampleL <- function(n, size) { if(n < .Machine$integer.max) sample.int(n, size) else { i <- unique(round(n * runif(1.8 * size))) while(length(i) < size) { i <- unique(c(i, round(n * runif(size)))) } i[seq_len(size)] } } ## Useful Matrix constructors for testing: ##' @title Random Sparse Matrix ##' @param n ##' @param m number of columns; default (=n) ==> square matrix ##' @param density the desired sparseness density: ##' @param nnz number of non-zero entries; default from \code{density} ##' @param repr character string specifying the sparseness kind of the result. ##' @param giveCsparse *deprecated* logical specifying if result should be CsparseMatrix ##' @return a [CTR]sparseMatrix, n x m ##' @author Martin Maechler, Mar 2008; July 2020 ('repr' instead og 'giveCsparse') rspMat <- function(n, m = n, density = 1/4, nnz = round(density * n*m), repr = c("C","T","R"), giveCsparse) { stopifnot(length(n) == 1, n == as.integer(n), length(m) == 1, m == as.integer(m), 0 <= density, density <= 1, 0 <= nnz, nnz <= (N <- n*m)) in0 <- sampleL(N, nnz) x <- sparseVector(i = in0, x = as.numeric(1L + seq_along(in0)), length = N) dim(x) <- c(n,m)#-> sparseMatrix ## silent, back compatible (not yet warning about 'giveCsparse' deprecation): repr <- if(missing(repr) && !missing(giveCsparse)) if(giveCsparse) "C" else "T" else match.arg(repr) switch(repr, "C" = as(x, "CsparseMatrix"), "T" = x,# TsparseMatrix "R" = as(x, "RsparseMatrix")) } ## __DEPRECATED__ !! rSparseMatrix <- function(nrow, ncol, nnz, rand.x = function(n) round(rnorm(nnz), 2), ...) { stopifnot((nnz <- as.integer(nnz)) >= 0, nrow >= 0, ncol >= 0, nnz <= nrow * ncol) .Deprecated("rsparsematrix") ##========= sparseMatrix(i = sample(nrow, nnz, replace = TRUE), j = sample(ncol, nnz, replace = TRUE), x = rand.x(nnz), dims = c(nrow, ncol), ...) } rUnitTri <- function(n, upper = TRUE, ...) { ## Purpose: random unit-triangular sparse Matrix .. built from rspMat() ## ---------------------------------------------------------------------- ## Arguments: n: matrix dimension ## upper: logical indicating if upper or lower triangular ## ... : further arguments passed to rspMat(), eg. 'density' ## ---------------------------------------------------------------------- ## Author: Martin Maechler, Date: 5 Mar 2008, 11:35 r <- (if(upper) triu else tril)(rspMat(n, ...)) ## make sure the diagonal is empty diag(r) <- 0 r <- drop0(r) r@diag <- "U" r } ##' Construct a nice (with exact numbers) random artificial \eqn{A = L D L'} ##' decomposition with a sparse \eqn{n \times n}{n x n} matrix \code{A} of ##' density \code{density} and square root \eqn{D} determined by \code{d0}. ##' ##' If one of \code{rcond} or \code{condest} is true, \code{A} must be ##' non-singular, both use an \eqn{LU} decomposition requiring ##' non-singularity. ##' @title Make Nice Artificial A = L D L' (With Exact Numbers) Decomposition ##' @param n matrix dimension \eqn{n \times n}{n x n} ##' @param density ratio of number of non-zero entries to total number ##' @param d0 The sqrt of the diagonal entries of D default \code{10}, to be ##' \dQuote{different} from \code{L} entries. More generally these can be negative ##' @param rcond logical indicating if \code{\link{rcond}(A, useInv=TRUE)} ##' should be returned which requires non-singular A and D. ##' @param condest logical indicating if \code{\link{condest}(A)$est} ##' should be returned which requires non-singular A and D. ##' @return list with entries A, L, d.half, D, ..., where A inherits from ##' class \code{"\linkS4class{symmetricMatrix}"} and should be equal to ##' \code{as(L \%*\% D \%*\% t(L), "symmetricMatrix")}. ##' @author Martin Maechler, Date: 15 Mar 2008 mkLDL <- function(n, density = 1/3, d0 = 10, d.half = d0 * sample.int(n), # random permutation rcond = (n < 99), condest = (n >= 100)) { stopifnot(n == round(n), density <= 1) n <- as.integer(n) stopifnot(n >= 1, is.numeric(d.half), length(d.half) == n)# no longer (2023-05-24): d.half >= 0 L <- Matrix(0, n,n) nnz <- round(density * n*n) L[sample(n*n, nnz)] <- seq_len(nnz) L <- tril(L, -1L) diag(L) <- 1 ### FIXME: allow *negative* d.half[] entries! dh2 <- d.half^2 non.sing <- sum(dh2 > 0) == n D <- Diagonal(x = dh2) A <- tcrossprod(L * rep(d.half, each=n)) ## = as(L %*% D %*% t(L), "symmetricMatrix") list(A = A, L = L, d.half = d.half, D = D, rcond.A = if (rcond && non.sing) rcond(A, useInv=TRUE), cond.A = if(condest && non.sing) condest(A)$est) } eqDeterminant <- function(m1, m2, NA.Inf.ok=FALSE, tol=.Machine$double.eps^0.5, ...) { d1 <- determinant(m1) ## logarithm = TRUE d2 <- determinant(m2) d1m <- as.vector(d1$modulus)# dropping attribute d2m <- as.vector(d2$modulus) if((identical(d1m, -Inf) && identical(d2m, -Inf)) || ## <==> det(m1) == det(m2) == 0, then 'sign' may even differ ! (is.na(d1m) && is.na(d2m))) ## if both are NaN or NA, we "declare" that's fine here return(TRUE) else if(NA.Inf.ok && ## first can be NA, second infinite: ## wanted: base::determinant.matrix() sometimes gives -Inf instead ## of NA,e.g. for matrix(c(0,NA,0,0,NA,NA,0,NA,0,0,1,0,0,NA,0,1), 4,4)) is.na(d1m) && is.infinite(d2m)) return(TRUE) ## else if(is.infinite(d1m)) d1$modulus <- sign(d1m)* .Machine$double.xmax if(is.infinite(d2m)) d2$modulus <- sign(d2m)* .Machine$double.xmax ## now they are finite or *one* of them is NA/NaN, and all.equal() will tell so: all.equal(d1, d2, tolerance=tol, ...) } ##' @param A a non-negative definite sparseMatrix, typically "dsCMatrix" ##' ##' @return a list with components resulting from calling ##' Cholesky(., perm = .P., LDL = .L., super = .S.) ##' ##' for all 2*2*3 combinations of (.P., .L., .S.) allCholesky <- function(A, verbose = FALSE, silentTry = FALSE) { ## Author: Martin Maechler, Date: 16 Jul 2009 ##' @param r list of CHMfactor objects, typically with names() as '. | .' ##' ##' @return an is(perm,LDL,super) matrix with interesting and *named* rownames CHM_to_pLs <- function(r) { is.perm <- function(.) if(inherits(., "try-error")) NA else .@type[1L] != 0L is.LDL <- function(.)if(inherits(., "try-error")) NA else isLDL(.) r.st <- cbind(perm = sapply(r, is.perm), LDL = sapply(r, is.LDL), super = sapply(r, class) == "dCHMsuper") names(dimnames(r.st)) <- list(" p L s", "") r.st } my.Cholesky <- { if(verbose) function (A, perm = TRUE, LDL = !super, super = FALSE, Imult = 0, ...) { cat(sprintf("Chol..(*, perm= %1d, LDL= %1d, super=%1d):", perm, LDL, super)) r <- Cholesky(A, perm=perm, LDL=LDL, super=super, Imult=Imult, ...) cat(" [Ok]\n") r } else Cholesky } logi <- c(FALSE, TRUE) d12 <- expand.grid(perm = logi, LDL = logi, super = c(logi,NA), KEEP.OUT.ATTRS = FALSE) r1 <- lapply(seq_len(nrow(d12)), function(i) try(do.call(my.Cholesky, c(list(A = A), as.list(d12[i,]))), silent=silentTry)) names(r1) <- apply(d12, 1, function(.) paste(symnum(.), collapse=" ")) dup.r1 <- duplicated(r1) r.all <- CHM_to_pLs(r1) if(!identical(dup.r1, duplicated(r.all))) warning("duplicated( ) differs from duplicated( )", immediate. = TRUE) list(Chol.A = r1, dup.r.all = dup.r1, r.all = r.all, r.uniq = CHM_to_pLs(r1[ ! dup.r1])) } ##' Cheap Boolean Arithmetic Matrix product ##' Should be equivalent to %&% which is faster [not for large dense!]. ##' Consequently mainly used in checkMatrix() ## The first version (up to Aug.2022) -- possibly what we should use for dense case (!?) boolProd0 <- function(x,y) as((abs(x) %*% abs(y)) > 0, "nMatrix") ## New since Aug.13, 2022, ensuring that zeros are dropped isCRT <- function(x, cl = getClass(class(x))) extends(cl, "CsparseMatrix") || extends(cl, "TsparseMatrix") || extends(cl, "RsparseMatrix") boolProd <- function(x,y) { ## treat x & y, drop0() & coercing to "n" -- this treats NA <==> 1 (!) x <- if(isCRT(x)) .sparse2kind(x, kind="n", drop0=TRUE) else as(drop0(x), "nMatrix") y <- if(isCRT(y)) .sparse2kind(y, kind="n", drop0=TRUE) else as(drop0(y), "nMatrix") r <- (abs(x) %*% abs(y)) > 0 if(isCRT(r)) .sparse2kind(r, kind="n", drop0=TRUE) else # also for "sparseMatrix" cases "indMatrix" (incl "pMatrix") or "diagonalMatrix" ## NB: "diagonalMatrix already *does* drop0(.) when coerced to "nMatrix" as(r, "nMatrix") } .sparse2kind <- Matrix:::.sparse2kind # (FIXME -- a version of this should be exported!) ###----- Checking a "Matrix" ----------------------------------------- ##' Check the compatibility of \pkg{Matrix} package Matrix with a ##' \dQuote{traditional} \R matrix and perform a host of internal consistency ##' checks. ##' ##' @title Check Compatibility of Matrix Package Matrix with Traditional R Matrices ##' ##' @param m a "Matrix" ##' @param m.m as(m, "matrix") {if 'do.matrix' } ##' @param do.matrix logical indicating if as(m, "matrix") should be applied; ##' typically false for large sparse matrices ##' @param do.t logical: is t(m) "feasible" ? ##' @param doNorm ##' @param doOps ##' @param doSummary ##' @param doCoerce ##' @param doCoerce2 ##' @param do.prod ##' @param verbose logical indicating if "progress output" is produced. ##' @param catFUN (when 'verbose' is TRUE): function to be used as generalized cat() ##' @return TRUE (invisibly), unless an error is signalled ##' @author Martin Maechler, since 11 Apr 2008 checkMatrix <- function(m, m.m = if(do.matrix) as(m, "matrix"), do.matrix = !isSparse || prod(dim(m)) < 1e6, do.t = TRUE, doNorm = TRUE, doOps = TRUE, doSummary = TRUE, doCoerce = TRUE, doCoerce2 = doCoerce && !isRsp, doDet = do.matrix, do.prod = do.t && do.matrix && !isRsp, verbose = TRUE, catFUN = cat, MSG = if(interactive() || capabilities("long.double") || isTRUE(get0("doExtras"))) message else function(...) {} ) { ## is also called from dotestMat() in ../tests/Class+Meth.R stopifnot(is(m, "Matrix")) validObject(m) # or error(....) clNam <- class(m) cld <- getClassDef(clNam) ## extends(cld, FOO) is faster than is(m, FOO) isGen <- extends(cld, "generalMatrix") isSym <- extends(cld, "symmetricMatrix") isTri <- extends(cld, "triangularMatrix") isCor <- isSym && (extends(cld, "corMatrix") || extends(cld, "pcorMatrix")) if(isSparse <- extends(cld, "sparseMatrix")) { # also true for these isCsp <- extends(cld, "CsparseMatrix") isRsp <- extends(cld, "RsparseMatrix") isTsp <- extends(cld, "TsparseMatrix") isDiag <- extends(cld, "diagonalMatrix") isInd <- extends(cld, "indMatrix") isPerm <- extends(cld, "pMatrix") } else isCsp <- isRsp <- isTsp <- isDiag <- isInd <- isPerm <- FALSE is.n <- extends(cld, "nMatrix") nonMatr <- clNam != (Mcl <- MatrixClass(clNam, cld)) Cat <- function(...) if(verbose) cat(...) CatF <- function(...) if(verbose) catFUN(...) ## warnNow <- function(...) warning(..., call. = FALSE, immediate. = TRUE) DO.m <- function(expr) if(do.matrix) eval(expr) else TRUE vec <- function(x) { dim(x) <- c(length(x), 1L) dimnames(x) <- list(NULL,NULL) x } eps16 <- 16 * .Machine$double.eps ina <- is.na(m) if(do.matrix) { stopifnot(all(ina == is.na(m.m)), all(is.nan(m) == is.nan(m.m)), all(is.finite(m) == is.finite(m.m)), all(is.infinite(m) == is.infinite(m.m)), all(m == m | ina), ## check all() , "==" [Compare], "|" [Logic] if(ncol(m) > 0) identical3(unname(m[,1]), unname(m.m[,1]), as(m[,1,drop=FALSE], "vector")) else identical(as(m, "vector"), as.vector(m.m))) if(any(m != m & !ina)) stop(" any (m != m) should not be true") } else { if(any(m != m)) stop(" any (m != m) should not be true") if(ncol(m) > 0) stopifnot(identical(unname(m[,1]), as(m[,1,drop=FALSE], "vector"))) else stopifnot(identical(as(m, "vector"), as.vector(as(m, "matrix")))) } if(do.t) { tm <- t(m) if(isSym) ## check that t() swaps 'uplo' L <--> U : stopifnot(c("L","U") == sort(c(m@uplo, tm@uplo))) ttm <- t(tm) ## notInd: "pMatrix" ok, but others inheriting from "indMatrix" are not notInd <- (!isInd || isPerm) if(notInd && (isCsp || isGen || isDiag)) stopifnot(Qidentical(m, ttm, strictClass = !nonMatr)) else if(do.matrix) { if(notInd) stopifnot(nonMatr || class(ttm) == clNam) stopifnot(all(m == ttm | ina)) ## else : not testing } ## crossprod() %*% etc if(do.prod) { c.m <- crossprod(m, boolArith = FALSE) tcm <- tcrossprod(m, boolArith = FALSE) tolQ <- if(isSparse) NA else eps16 stopifnot(dim(c.m) == rep.int(ncol(m), 2), dim(tcm) == rep.int(nrow(m), 2), ## FIXME: %*% drops dimnames Q.eq2(c.m, tm %*% m, tol = tolQ), Q.eq2(tcm, m %*% tm, tol = tolQ), ## should work with dimnames: Q.eq(m %&% tm, boolProd(m, tm), superclasses=NULL, tol = 0) , Q.eq(tm %&% m, boolProd(tm, m), superclasses=NULL, tol = 0) ) } } if(!do.matrix) { CatF(" will *not* coerce to 'matrix' since do.matrix is FALSE\n") } else if(doNorm) { CatF(sprintf(" norm(m [%d x %d]) :", nrow(m), ncol(m))) for(typ in c("1","I","F","M")) { Cat('', typ, '') stopifnot(all.equal(norm(m,typ), norm(m.m,typ))) } Cat(" ok\n") } if(do.matrix && doSummary) { summList <- lapply(getGroupMembers("Summary"), get, envir = asNamespace("Matrix")) CatF(" Summary: ") for(f in summList) { ## suppressWarnings(): e.g. any() would warn here: r <- suppressWarnings(identical(f(m), f(m.m))) if(!isTRUE(r)) { ## typically for prod() f.nam <- sub("..$", '', sub("^\\.Primitive..", '', format(f))) ## sum() and prod() are sensitive to order of f. p. operations ## particularly on systems where sizeof(long double) == sizeof(double) (if(any(f.nam == c("sum", "prod"))) MSG else stop)( sprintf("%s(m) [= %g] differs from %s(m.m) [= %g]", f.nam, f(m), f.nam, f(m.m))) } } if(verbose) cat(" ok\n") } ## and test 'dim()' as well: d <- dim(m) isSqr <- d[1] == d[2] if(do.t) stopifnot(identical(diag(m), diag(t(m)))) ## TODO: also === diag(band(m,0,0)) if(prod(d) < .Machine$integer.max && !extends(cld, "modelMatrix")) { vm <- vec(m) stopifnot(is(vm, "Matrix"), validObject(vm), dim(vm) == c(d[1]*d[2], 1)) } if(!isInd) m.d <- local({ m. <- m diag(m.) <- diag(m) ## << *assigning* to 'm.' now typically annihilates @factor if(.hasSlot(m, "factors") && length(f <- m@factors)) m.@factors <- f m. }) if(do.matrix) stopifnot(identical(dim(m.m), dim(m)), ## now that "pMatrix" subsetting gives *LOGICAL* ## if(isPerm) { ## identical(as.integer(unname(diag(m))), unname(diag(m.m))) ## } else identical(diag(m), # base:: *and* Matrix diag() now keep names diag(m.m)),## not for NA: diag(m) == diag(m.m), identical(nnzero(m), sum(m.m != 0)), identical(nnzero(m, na.counted = FALSE), sum(m.m != 0, na.rm = TRUE)), identical(nnzero(m, na.counted = TRUE), sum(m.m != 0 | is.na(m.m))) ) if(isSparse) { n0m <- drop0(m) #==> n0m is Csparse has0 <- !Qidentical(n0m, as(m,"CsparseMatrix")) } if(isDiag) stopifnot(exprs = { .MJ.Qidentical(m, m.d, strictClass = FALSE, skipSlots = if(m@diag != "N") c("diag", "x")) m@diag == "N" || (m.d@diag == "N" && identical(m.d@x, diag(m, names = FALSE))) }) else if(isTri && m@diag != "N") stopifnot(exprs = { is(m.d, "triangularMatrix") && m.d@diag == "N" .MJ.Qidentical(m, m.d, strictClass = FALSE, skipSlots = c("diag", "p", "i", "j", "x")) isSparse || all(m == m.d) }) else if(!isInd) stopifnot(.MJ.Qidentical(m, m.d, strictClass = FALSE, skipSlots = if(((isCsp || isRsp) && has0) || isTsp) c("p", "i", "j", "x"))) ## use non-square matrix when "allowed": ## m12: sparse and may have 0s even if this is not: if(isSparse && has0) m12 <- as(as( m, "lMatrix"),"CsparseMatrix") m12 <- drop0(m12) if(do.matrix) { ## "!" should work (via as(*, "l...")) : m11 <- as(as(!!m,"CsparseMatrix"), "lMatrix") if(!Qidentical(m11, m12)) stopifnot(Qidentical(as(m11, "generalMatrix"), as(m12, "generalMatrix"))) } if(isSparse && !isDiag && !is.n) { ## ensure that as(., "nMatrix") gives nz-pattern CatF("as(., \"nMatrix\") giving full nonzero-pattern: ") n1 <- as(m, "nMatrix") ns <- as(m, "nsparseMatrix") stopifnot(identical(n1,ns), ## only testing [CR]sparseMatrix and indMatrix here ... ## sum() excludes duplicated (i,j) pairs whereas ## length(diagU2N(<[^n].T>)) includes them ... isTsp || (if(isSym) length(if(.hasSlot(n1, "i")) n1@i else n1@j) else sum(n1)) == length(if(isInd) m@perm else diagU2N(m)@x)) Cat("ok\n") } if(doOps) { ## makes sense with non-trivial m (!) CatF("2*m =?= m+m: ") if(identical(2*m, m+m)) Cat("identical\n") else if(do.matrix) { eq <- as(2*m,"matrix") == as(m+m, "matrix") # but work for NA's: stopifnot(all(eq | (is.na(m) & is.na(eq)))) Cat("ok\n") } else {# !do.matrix stopifnot(identical(as(2*m, "CsparseMatrix"), as(m+m, "CsparseMatrix"))) Cat("ok\n") } if(do.matrix) { ## m == m etc, now for all, see above CatF("m >= m for all: "); stopifnot(all(m >= m | ina)); Cat("ok\n") } if(prod(d) > 0) { CatF("m < m for none: ") mlm <- m < m if(!any(ina)) stopifnot(!any(mlm)) else if(do.matrix) stopifnot(!any(mlm & !ina)) else { ## !do.matrix & any(ina) : !ina can *not* be used mlm[ina] <- FALSE stopifnot(!any(mlm)) } Cat("ok\n") } if(isSqr) { if(do.matrix) { ## determinant() "fails" for triangular with NA such as ## (m <- matrix(c(1:0,NA,1), 2)) CatF("symmpart(m) + skewpart(m) == m: ") Q.eq.symmpart(m) CatF("ok; determinant(): ") if(!doDet) Cat(" skipped (!doDet): ") else if(any(is.na(m.m)) && isTri) Cat(" skipped: is triang. and has NA: ") else stopifnot(eqDeterminant(m, m.m, NA.Inf.ok=TRUE)) Cat("ok\n") } } else assertError(determinant(m)) }# end{doOps} if(doCoerce && do.matrix && canCoerce("matrix", clNam)) { CatF("as(, ",clNam,"): ", sep='') m3 <- as(m.m, clNam) Cat("valid:", validObject(m3), "\n") ## m3 should ``ideally'' be identical to 'm' } if(doCoerce2 && do.matrix) { ## not for large m: !m will be dense if(is.n) { mM <- if(nonMatr) as(m, Mcl) else m stopifnot(identical(mM, as(as(m, "dMatrix"),"nMatrix")), identical(mM, as(as(m, "lMatrix"),"nMatrix")), identical(which(m), which(m.m))) } else if(extends(cld, "lMatrix")) { ## should fulfill even with NA: stopifnot(all(m | !m | ina), !any(!m & m & !ina)) if(isTsp) # allow modify, since at end here m <- asUniqueT(m, isT = TRUE) stopifnot(identical(m, m & TRUE), identical(m, FALSE | m)) ## also check the coercions to [dln]Matrix m. <- if(isSparse && has0) n0m else m m1. <- m. # replace NA by 1 in m1. , carefully not changing class: if(any(ina)) m1.@x[is.na(m1.@x)] <- TRUE stopifnot(identical(m. , as(as(m. , "dMatrix"),"lMatrix")), clNam == "ldiMatrix" || # <- there's no "ndiMatrix" ## coercion to n* and back: only identical when no extra 0s: identical(m1., as(as(m1., "nMatrix"),"lMatrix")), identical(which(m), which(m.m))) } else if(extends(cld, "dMatrix")) { m. <- if(isSparse && has0) n0m else m m1 <- m1. <- (m. != 0)*1 ## replace NA by 1 in m1. , carefully not changing class: if(any(ina)) m1.@x[is.na(m1.@x)] <- 1 ## coercion to n* (nz-pattern!) and back: only identical when no extra 0s and no NAs: stopifnot(Q.C.identical(m1., as(as(m., "nMatrix"),"dMatrix"), isSparse, checkClass = FALSE), Q.C.identical(m1 , as(as(m., "lMatrix"),"dMatrix"), isSparse, checkClass = FALSE)) } maybeDense <- if(isSparse) identity else function(.) as(., "denseMatrix") if(isTri) { mm. <- m i0 <- if(m@uplo == "L") upper.tri(mm.) else lower.tri(mm.) n.catchWarn <- if(is.n) suppressWarnings else identity n.catchWarn( mm.[i0] <- 0 ) # ideally, mm. remained triangular, but can be dge* ## Aug.2022 - Coercion deprecations: No longer do as(*, clNam): CatF("as(mm., \"triangularMatrix\"): ") tm <- as(mm., "triangularMatrix") Cat("valid:", validObject(tm), "\n") if(m@uplo == tm@uplo) { ## otherwise, the matrix effectively was *diagonal* if(!isSparse && Matrix:::.isPacked(m)) m <- unpack(m) # to match tm ## note that diagU2N() |-> dtC, now dtT: stopifnot(Qidentical(tm, maybeDense(diagU2N(m)))) } } else if(isDiag) { ## TODO } else { ## TODO } }# end {doCoerce2 && ..} if(doCoerce && isSparse) { ## coerce to sparseVector and back : v <- as(m, "sparseVector") stopifnot(length(v) == prod(d)) dim(v) <- d stopifnot(Q.eq2(m, v)) } invisible(TRUE) } ## {checkMatrix} ### --- These use ##' Check QR-consistency of dense and sparse chk.qr.D.S <- function(d., s., y, Y = Matrix(y), force = FALSE, tol = 1e-10) { stopifnot(is.qr(d.), is(s., "sparseQR")) cc <- qr.coef(d.,y) rank.def <- any(is.na(cc)) && d.$rank < length(d.$pivot) if(rank.def && force) cc <- mkNA.0(cc) ## set NA's to 0 .. ok, in some case ## when system is rank deficient, have differing cases, not always just NA <-> 0 coef ## FIXME though: resid & fitted should be well determined if(force || !rank.def) stopifnot( is.all.equal3( cc , qr.coef (s.,y), drop(qr.coef (s.,Y)), tol=tol), is.all.equal3(qr.resid (d.,y), qr.resid (s.,y), drop(qr.resid (s.,Y)), tol=tol), is.all.equal3(qr.fitted(d.,y), qr.fitted(s.,y), drop(qr.fitted(s.,Y)), tol=tol) ) } ##' "Combi" calling chkQR() on both "(sparse)Matrix" and 'traditional' version ##' ------ and combine the two qr decompositions using chk.qr.D.S() ##' [ chkQR() def. in >>>>> ./test-tools-1.R <<<<< ] ##' ##' @title check QR-decomposition, and compare sparse and dense one ##' @param A a 'Matrix' , typically 'sparseMatrix' ##' @param Qinv.chk ##' @param QtQ.chk ##' @param quiet ##' @return list with 'qA' (sparse QR) and 'qa' (traditional (dense) QR) ##' @author Martin Maechler checkQR.DS.both <- function(A, Qinv.chk, QtQ.chk=NA, quiet=FALSE, giveRE=TRUE, tol = 1e-13) { stopifnot(is(A,"Matrix")) if(!quiet) cat("classical: ") qa <- chkQR(as(A, "matrix"), Qinv.chk=TRUE, QtQ.chk=TRUE, tol=tol, giveRE=giveRE)# works always if(!quiet) cat("[Ok] --- sparse: ") qA <- chkQR(A, Qinv.chk=Qinv.chk, QtQ.chk=QtQ.chk, tol=tol, giveRE=giveRE) validObject(qA) if(!quiet) cat("[Ok]\n") chk.qr.D.S(qa, qA, y = 10 + 1:nrow(A), tol = 256*tol)# ok [not done in rank deficient case!] invisible(list(qA=qA, qa=qa)) } non0.ij <- function(M) Matrix:::non0.i(as(M, "sparseMatrix")) triuChk <- function(x, k) { ans <- triu(x, k) ij <- non0.ij(ans) stopifnot(identical(dim(x), dim(ans)), (ij %*% c(-1,1)) >= k) ans } trilChk <- function(x, k) { ans <- tril(x, k) ij <- non0.ij(ans) stopifnot(identical(dim(x), dim(ans)), (ij %*% c(-1,1)) <= k) ans } Matrix/inst/include/0000755000176200001440000000000014547723665014141 5ustar liggesusersMatrix/inst/include/Matrix.h0000644000176200001440000000030314513651320015527 0ustar liggesusers/* For backwards compatibility only. Packages should start using */ /* LinkingTo: Matrix (>= 1.6-2) and #include . */ #include #include "Matrix/Matrix.h" Matrix/inst/include/cholmod.h0000644000176200001440000000024614511307715015722 0ustar liggesusers/* For backwards compatibility only. Packages should start using */ /* LinkingTo: Matrix (>= 1.6-2) and #include . */ #include "Matrix/cholmod.h" Matrix/inst/include/Matrix/0000755000176200001440000000000014550025127015363 5ustar liggesusersMatrix/inst/include/Matrix/Matrix.h0000644000176200001440000000046314515651531017010 0ustar liggesusers#ifndef R_MATRIX_MATRIX_H #define R_MATRIX_MATRIX_H #include "version.h" #include "cholmod.h" #ifndef R_MATRIX_NO_CHOLMOD_UTILS # include "cholmod-utils.h" #endif #ifndef R_MATRIX_NO_ALLOCA # include "alloca.h" #endif #ifndef R_MATRIX_NO_REMAP # include "remap.h" #endif #endif /* R_MATRIX_MATRIX_H */ Matrix/inst/include/Matrix/stubs.c0000644000176200001440000004346514533275321016707 0ustar liggesusers#include #include #include #include #ifndef R_MATRIX_INLINE # define R_MATRIX_INLINE #endif /* ==== cholmod.h =================================================== */ #include "cholmod.h" #ifdef __cplusplus extern "C" { #endif R_MATRIX_INLINE CHM_SP attribute_hidden R_MATRIX_CHOLMOD(aat)(CHM_SP A, int *fset, size_t fsize, int mode, CHM_CM Common) { static CHM_SP (*fn)(CHM_SP, int *, size_t, int, CHM_CM) = NULL; if (!fn) fn = (CHM_SP (*)(CHM_SP, int *, size_t, int, CHM_CM)) R_GetCCallable("Matrix", "cholmod_aat"); return fn(A, fset, fsize, mode, Common); } R_MATRIX_INLINE CHM_SP attribute_hidden R_MATRIX_CHOLMOD(add)(CHM_SP A, CHM_SP B, double alpha[2], double beta[2], int values, int sorted, CHM_CM Common) { static CHM_SP (*fn)(CHM_SP, CHM_SP, double[2], double[2], int, int, CHM_CM) = NULL; if (!fn) fn = (CHM_SP (*)(CHM_SP, CHM_SP, double[2], double[2], int, int, CHM_CM)) R_GetCCallable("Matrix", "cholmod_add"); return fn(A, B, alpha, beta, values, sorted, Common); } R_MATRIX_INLINE CHM_DN attribute_hidden R_MATRIX_CHOLMOD(allocate_dense)(size_t nrow, size_t ncol, size_t d, int xtype, CHM_CM Common) { static CHM_DN (*fn)(size_t, size_t, size_t, int, CHM_CM) = NULL; if (!fn) fn = (CHM_DN (*)(size_t, size_t, size_t, int, CHM_CM)) R_GetCCallable("Matrix", "cholmod_allocate_dense"); return fn(nrow, ncol, d, xtype, Common); } R_MATRIX_INLINE CHM_SP attribute_hidden R_MATRIX_CHOLMOD(allocate_sparse)(size_t nrow, size_t ncol, size_t nzmax, int sorted, int packed, int stype, int xtype, CHM_CM Common) { static CHM_SP (*fn)(size_t, size_t, size_t, int, int, int, int, CHM_CM) = NULL; if (!fn) fn = (CHM_SP (*)(size_t, size_t, size_t, int, int, int, int, CHM_CM)) R_GetCCallable("Matrix", "cholmod_allocate_sparse"); return fn(nrow, ncol, nzmax, sorted, packed, stype, xtype, Common); } R_MATRIX_INLINE CHM_TR attribute_hidden R_MATRIX_CHOLMOD(allocate_triplet)(size_t nrow, size_t ncol, size_t nzmax, int stype, int xtype, CHM_CM Common) { static CHM_TR (*fn)(size_t, size_t, size_t, int, int, CHM_CM) = NULL; if (!fn) fn = (CHM_TR (*)(size_t, size_t, size_t, int, int, CHM_CM)) R_GetCCallable("Matrix", "cholmod_allocate_triplet"); return fn(nrow, ncol, nzmax, stype, xtype, Common); } R_MATRIX_INLINE CHM_FR attribute_hidden R_MATRIX_CHOLMOD(analyze)(CHM_SP A, CHM_CM Common) { static CHM_FR (*fn)(CHM_SP, CHM_CM) = NULL; if (!fn) fn = (CHM_FR (*)(CHM_SP,CHM_CM)) R_GetCCallable("Matrix", "cholmod_analyze"); return fn(A, Common); } R_MATRIX_INLINE CHM_FR attribute_hidden R_MATRIX_CHOLMOD(analyze_p)(CHM_SP A, int *Perm, int *fset, size_t fsize, CHM_CM Common) { static CHM_FR (*fn)(CHM_SP, int *, int *, size_t, CHM_CM) = NULL; if (!fn) fn = (CHM_FR (*)(CHM_SP, int *, int *, size_t, CHM_CM)) R_GetCCallable("Matrix", "cholmod_analyze_p"); return fn(A, Perm, fset, fsize, Common); } R_MATRIX_INLINE int attribute_hidden R_MATRIX_CHOLMOD(band_inplace)(int k1, int k2, int mode, CHM_SP A, CHM_CM Common) { static int (*fn)(int, int, int, CHM_SP, CHM_CM) = NULL; if (!fn) fn = (int (*)(int, int, int, CHM_SP, CHM_CM)) R_GetCCallable("Matrix", "cholmod_band_inplace"); return fn(k1, k2, mode, A, Common); } R_MATRIX_INLINE int attribute_hidden R_MATRIX_CHOLMOD(change_factor)(int to_xtype, int to_ll, int to_super, int to_packed, int to_monotonic, CHM_FR L, CHM_CM Common) { static int (*fn)(int, int, int, int, int, CHM_FR, CHM_CM) = NULL; if (!fn) fn = (int (*)(int, int, int, int, int, CHM_FR, CHM_CM)) R_GetCCallable("Matrix", "cholmod_change_factor"); return fn(to_xtype, to_ll, to_super, to_packed, to_monotonic, L, Common); } R_MATRIX_INLINE CHM_SP attribute_hidden R_MATRIX_CHOLMOD(copy)(CHM_SP A, int stype, int mode, CHM_CM Common) { static CHM_SP (*fn)(CHM_SP, int, int, CHM_CM) = NULL; if (!fn) fn = (CHM_SP (*)(CHM_SP, int, int, CHM_CM)) R_GetCCallable("Matrix", "cholmod_copy"); return fn(A, stype, mode, Common); } R_MATRIX_INLINE CHM_DN attribute_hidden R_MATRIX_CHOLMOD(copy_dense)(CHM_DN A, CHM_CM Common) { static CHM_DN (*fn)(CHM_DN, CHM_CM) = NULL; if (!fn) fn = (CHM_DN (*)(CHM_DN, CHM_CM)) R_GetCCallable("Matrix", "cholmod_copy_dense"); return fn(A, Common); } R_MATRIX_INLINE CHM_FR attribute_hidden R_MATRIX_CHOLMOD(copy_factor)(CHM_FR L, CHM_CM Common) { static CHM_FR (*fn)(CHM_FR, CHM_CM) = NULL; if (!fn) fn = (CHM_FR (*)(CHM_FR, CHM_CM)) R_GetCCallable("Matrix", "cholmod_copy_factor"); return fn(L, Common); } R_MATRIX_INLINE CHM_SP attribute_hidden R_MATRIX_CHOLMOD(copy_sparse)(CHM_SP A, CHM_CM Common) { static CHM_SP (*fn)(CHM_SP, CHM_CM) = NULL; if (!fn) fn = (CHM_SP (*)(CHM_SP, CHM_CM)) R_GetCCallable("Matrix", "cholmod_copy_sparse"); return fn(A, Common); } R_MATRIX_INLINE int attribute_hidden R_MATRIX_CHOLMOD(defaults)(CHM_CM Common) { static int (*fn)(CHM_CM) = NULL; if (!fn) fn = (int (*)(CHM_CM)) R_GetCCallable("Matrix", "cholmod_defaults"); return fn(Common); } R_MATRIX_INLINE CHM_SP attribute_hidden R_MATRIX_CHOLMOD(dense_to_sparse)(CHM_DN X, int values, CHM_CM Common) { static CHM_SP (*fn)(CHM_DN, int, CHM_CM) = NULL; if (!fn) fn = (CHM_SP (*)(CHM_DN, int, CHM_CM)) R_GetCCallable("Matrix", "cholmod_dense_to_sparse"); return fn(X, values, Common); } R_MATRIX_INLINE CHM_SP attribute_hidden R_MATRIX_CHOLMOD(factor_to_sparse)(CHM_FR L, CHM_CM Common) { static CHM_SP (*fn)(CHM_FR, CHM_CM) = NULL; if (!fn) fn = (CHM_SP (*)(CHM_FR, CHM_CM)) R_GetCCallable("Matrix", "cholmod_factor_to_sparse"); return fn(L, Common); } R_MATRIX_INLINE int attribute_hidden R_MATRIX_CHOLMOD(factorize)(CHM_SP A, CHM_FR L, CHM_CM Common) { static int (*fn)(CHM_SP, CHM_FR, CHM_CM) = NULL; if (!fn) fn = (int (*)(CHM_SP, CHM_FR, CHM_CM)) R_GetCCallable("Matrix", "cholmod_factorize"); return fn(A, L, Common); } R_MATRIX_INLINE int attribute_hidden R_MATRIX_CHOLMOD(factorize_p)(CHM_SP A, double beta[2], int *fset, size_t fsize, CHM_FR L, CHM_CM Common) { static int (*fn)(CHM_SP, double[2], int *, size_t, CHM_FR, CHM_CM) = NULL; if (!fn) fn = (int (*)(CHM_SP, double[2], int *, size_t, CHM_FR, CHM_CM)) R_GetCCallable("Matrix", "cholmod_factorize_p"); return fn(A, beta, fset, fsize, L, Common); } R_MATRIX_INLINE int attribute_hidden R_MATRIX_CHOLMOD(finish)(CHM_CM Common) { static int (*fn)(CHM_CM) = NULL; if (!fn) fn = (int (*)(CHM_CM)) R_GetCCallable("Matrix", "cholmod_finish"); return fn(Common); } R_MATRIX_INLINE int attribute_hidden R_MATRIX_CHOLMOD(free_dense)(CHM_DN *A, CHM_CM Common) { static int (*fn)(CHM_DN *, CHM_CM) = NULL; if (!fn) fn = (int (*)(CHM_DN *,CHM_CM)) R_GetCCallable("Matrix", "cholmod_free_dense"); return fn(A, Common); } R_MATRIX_INLINE int attribute_hidden R_MATRIX_CHOLMOD(free_factor)(CHM_FR *L, CHM_CM Common) { static int (*fn)(CHM_FR *,CHM_CM) = NULL; if (!fn) fn = (int (*)(CHM_FR *, CHM_CM)) R_GetCCallable("Matrix", "cholmod_free_factor"); return fn(L, Common); } R_MATRIX_INLINE int attribute_hidden R_MATRIX_CHOLMOD(free_sparse)(CHM_SP *A, CHM_CM Common) { static int (*fn)(CHM_SP *, CHM_CM) = NULL; if (!fn) fn = (int (*)(CHM_SP *, CHM_CM)) R_GetCCallable("Matrix", "cholmod_free_sparse"); return fn(A, Common); } R_MATRIX_INLINE int attribute_hidden R_MATRIX_CHOLMOD(free_triplet)(CHM_TR *T, CHM_CM Common) { static int (*fn)(CHM_TR *, CHM_CM) = NULL; if (!fn) fn = (int (*)(CHM_TR *,CHM_CM)) R_GetCCallable("Matrix", "cholmod_free_triplet"); return fn(T, Common); } R_MATRIX_INLINE int attribute_hidden R_MATRIX_CHOLMOD(nnz)(CHM_SP A, CHM_CM Common) { static int (*fn)(CHM_SP, CHM_CM) = NULL; if (!fn) fn = (int (*)(CHM_SP, CHM_CM)) R_GetCCallable("Matrix", "cholmod_nnz"); return fn(A, Common); } R_MATRIX_INLINE int attribute_hidden R_MATRIX_CHOLMOD(scale)(CHM_DN S, int scale, CHM_SP A, CHM_CM Common) { static int (*fn)(CHM_DN, int, CHM_SP, CHM_CM) = NULL; if (!fn) fn = (int (*)(CHM_DN, int, CHM_SP, CHM_CM)) R_GetCCallable("Matrix", "cholmod_scale"); return fn(S, scale, A, Common); } R_MATRIX_INLINE int attribute_hidden R_MATRIX_CHOLMOD(sdmult)(CHM_SP A, int transpose, double alpha[2], double beta[2], CHM_DN X, CHM_DN Y, CHM_CM Common) { static int (*fn)(CHM_SP, int, double[2], double[2], CHM_DN, CHM_DN, CHM_CM) = NULL; if (!fn) fn = (int (*)(CHM_SP, int, double[2], double[2], CHM_DN, CHM_DN, CHM_CM)) R_GetCCallable("Matrix", "cholmod_sdmult"); return fn(A, transpose, alpha, beta, X, Y, Common); } R_MATRIX_INLINE CHM_DN attribute_hidden R_MATRIX_CHOLMOD(solve)(int sys, CHM_FR L, CHM_DN B, CHM_CM Common) { static CHM_DN (*fn)(int, CHM_FR, CHM_DN, CHM_CM) = NULL; if (!fn) fn = (CHM_DN (*)(int, CHM_FR, CHM_DN, CHM_CM)) R_GetCCallable("Matrix", "cholmod_solve"); return fn(sys, L, B, Common); } R_MATRIX_INLINE int attribute_hidden R_MATRIX_CHOLMOD(solve2)(int sys, CHM_FR L, CHM_DN B, CHM_DN *X_Handle, CHM_DN *Y_Handle, CHM_DN *E_Handle, CHM_CM Common) { static int (*fn)(int, CHM_FR, CHM_DN, CHM_SP, CHM_DN *, CHM_SP *, CHM_DN *, CHM_DN *, CHM_CM) = NULL; if (!fn) fn = (int (*)(int, CHM_FR, CHM_DN, CHM_SP, CHM_DN *, CHM_SP *, CHM_DN *, CHM_DN *, CHM_CM)) R_GetCCallable("Matrix", "cholmod_solve2"); return fn(sys, L, B, NULL, X_Handle, NULL, Y_Handle, E_Handle, Common); } R_MATRIX_INLINE int attribute_hidden R_MATRIX_CHOLMOD(sort)(CHM_SP A, CHM_CM Common) { static int (*fn)(CHM_SP, CHM_CM) = NULL; if (!fn) fn = (int (*)(CHM_SP, CHM_CM)) R_GetCCallable("Matrix", "cholmod_sort"); return fn(A, Common); } R_MATRIX_INLINE CHM_DN attribute_hidden R_MATRIX_CHOLMOD(sparse_to_dense)(CHM_SP A, CHM_CM Common) { static CHM_DN (*fn)(CHM_SP, CHM_CM) = NULL; if (!fn) fn = (CHM_DN (*)(CHM_SP, CHM_CM)) R_GetCCallable("Matrix", "cholmod_sparse_to_dense"); return fn(A, Common); } R_MATRIX_INLINE CHM_TR attribute_hidden R_MATRIX_CHOLMOD(sparse_to_triplet)(CHM_SP A, CHM_CM Common) { static CHM_TR (*fn)(CHM_SP, CHM_CM) = NULL; if (!fn) fn = (CHM_TR (*)(CHM_SP, CHM_CM)) R_GetCCallable("Matrix", "cholmod_sparse_to_triplet"); return fn(A, Common); } R_MATRIX_INLINE CHM_SP attribute_hidden R_MATRIX_CHOLMOD(speye)(size_t nrow, size_t ncol, int xtype, CHM_CM Common) { static CHM_SP (*fn)(size_t, size_t, int, CHM_CM) = NULL; if (!fn) fn = (CHM_SP (*)(size_t, size_t, int, CHM_CM)) R_GetCCallable("Matrix", "cholmod_speye"); return fn(nrow, ncol, xtype, Common); } R_MATRIX_INLINE CHM_SP attribute_hidden R_MATRIX_CHOLMOD(spsolve)(int sys, CHM_FR L, CHM_SP B, CHM_CM Common) { static CHM_SP (*fn)(int, CHM_FR, CHM_SP, CHM_CM) = NULL; if (!fn) fn = (CHM_SP (*)(int,CHM_FR, CHM_SP, CHM_CM)) R_GetCCallable("Matrix", "cholmod_spsolve"); return fn(sys, L, B, Common); } R_MATRIX_INLINE CHM_SP attribute_hidden R_MATRIX_CHOLMOD(ssmult)(CHM_SP A, CHM_SP B, int stype, int values, int sorted, CHM_CM Common) { static CHM_SP (*fn)(CHM_SP, CHM_SP, int, int, int, CHM_CM) = NULL; if (!fn) fn = (CHM_SP (*)(CHM_SP, CHM_SP, int, int, int, CHM_CM)) R_GetCCallable("Matrix", "cholmod_ssmult"); return fn(A, B, stype, values, sorted, Common); } R_MATRIX_INLINE CHM_SP attribute_hidden R_MATRIX_CHOLMOD(submatrix)(CHM_SP A, int *rset, int rsize, int *cset, int csize, int values, int sorted, CHM_CM Common) { static CHM_SP (*fn)(CHM_SP, int *, int, int *, int, int, int, CHM_CM) = NULL; if (!fn) fn = (CHM_SP (*)(CHM_SP, int *, int, int *, int, int, int, CHM_CM)) R_GetCCallable("Matrix", "cholmod_submatrix"); return fn(A, rset, rsize, cset, csize, values, sorted, Common); } R_MATRIX_INLINE CHM_SP attribute_hidden R_MATRIX_CHOLMOD(transpose)(CHM_SP A, int values, CHM_CM Common) { static CHM_SP (*fn)(CHM_SP, int, CHM_CM) = NULL; if (!fn) fn = (CHM_SP (*)(CHM_SP, int, CHM_CM)) R_GetCCallable("Matrix", "cholmod_transpose"); return fn(A, values, Common); } R_MATRIX_INLINE CHM_SP attribute_hidden R_MATRIX_CHOLMOD(triplet_to_sparse)(CHM_TR T, int nzmax, CHM_CM Common) { static CHM_SP (*fn)(CHM_TR, int, CHM_CM) = NULL; if (!fn) fn = (CHM_SP (*)(CHM_TR, int, CHM_CM)) R_GetCCallable("Matrix", "cholmod_triplet_to_sparse"); return fn(T, nzmax, Common); } R_MATRIX_INLINE int attribute_hidden R_MATRIX_CHOLMOD(updown)(int update, CHM_SP C, CHM_FR L, CHM_CM Common) { static int (*fn)(int, CHM_SP, CHM_FR, CHM_CM) = NULL; if (!fn) fn = (int (*)(int, CHM_SP, CHM_FR, CHM_CM)) R_GetCCallable("Matrix", "cholmod_updown"); return fn(update, C, L, Common); } R_MATRIX_INLINE CHM_SP attribute_hidden R_MATRIX_CHOLMOD(vertcat)(CHM_SP A, CHM_SP B, int values, CHM_CM Common) { static CHM_SP (*fn)(CHM_SP, CHM_SP, int, CHM_CM) = NULL; if (!fn) fn = (CHM_SP (*)(CHM_SP, CHM_SP, int, CHM_CM)) R_GetCCallable("Matrix", "cholmod_vertcat"); return fn(A, B, values, Common); } /* ---- cholmod_start ----------------------------------------------- */ /* NB: keep synchronized with analogues in ../../src/chm_common.c */ R_MATRIX_INLINE void attribute_hidden R_MATRIX_CHOLMOD(error_handler)(int status, const char *file, int line, const char *message) { /* NB: Matrix itself uses cholmod_common_env(ini|set|get) to preserve settings through error calls. Consider defining *your* own error handler and restoring the instance of cholmod_common that *you* use. */ if (status < 0) Rf_error("CHOLMOD error '%s' at file '%s', line %d", message, file, line); else Rf_warning("CHOLMOD warning '%s' at file '%s', line %d", message, file, line); } R_MATRIX_INLINE int attribute_hidden R_MATRIX_CHOLMOD(start)(CHM_CM Common) { static int (*fn)(CHM_CM) = NULL; if (!fn) fn = (int (*)(CHM_CM)) R_GetCCallable("Matrix", "cholmod_start"); int ans = fn(Common); Common->error_handler = R_MATRIX_CHOLMOD(error_handler); return ans; } #ifdef __cplusplus } #endif /* ==== cholmod-utils.h ============================================= */ #ifndef R_MATRIX_NO_CHOLMOD_UTILS #include "cholmod-utils.h" #ifdef __cplusplus extern "C" { #endif R_MATRIX_INLINE CHM_FR attribute_hidden M_sexp_as_cholmod_factor(CHM_FR L, SEXP from) { static CHM_FR (*fn)(CHM_FR, SEXP) = NULL; if (!fn) fn = (CHM_FR (*)(CHM_FR, SEXP)) R_GetCCallable("Matrix", "sexp_as_cholmod_factor"); return fn(L, from); } R_MATRIX_INLINE CHM_SP attribute_hidden M_sexp_as_cholmod_sparse(CHM_SP A, SEXP from, Rboolean checkUnit, Rboolean sortInPlace) { static CHM_SP (*fn)(CHM_SP, SEXP, Rboolean, Rboolean) = NULL; if (!fn) fn = (CHM_SP (*)(CHM_SP, SEXP, Rboolean, Rboolean)) R_GetCCallable("Matrix", "sexp_as_cholmod_sparse"); return fn(A, from, checkUnit, sortInPlace); } R_MATRIX_INLINE CHM_TR attribute_hidden M_sexp_as_cholmod_triplet(CHM_TR A, SEXP from, Rboolean checkUnit) { static CHM_TR (*fn)(CHM_TR, SEXP, Rboolean) = NULL; if (!fn) fn = (CHM_TR (*)(CHM_TR, SEXP, Rboolean)) R_GetCCallable("Matrix", "sexp_as_cholmod_triplet"); return fn(A, from, checkUnit); } R_MATRIX_INLINE CHM_DN attribute_hidden M_sexp_as_cholmod_dense(CHM_DN A, SEXP from) { static CHM_DN (*fn)(CHM_DN, SEXP) = NULL; if (!fn) fn = (CHM_DN (*)(CHM_DN, SEXP)) R_GetCCallable("Matrix", "sexp_as_cholmod_dense"); return fn(A, from); } R_MATRIX_INLINE CHM_DN attribute_hidden M_numeric_as_cholmod_dense(CHM_DN A, double *data, int nrow, int ncol) { static CHM_DN (*fn)(CHM_DN, double *, int, int) = NULL; if (!fn) fn = (CHM_DN (*)(CHM_DN, double *, int, int)) R_GetCCallable("Matrix", "numeric_as_cholmod_dense"); return fn(A, data, nrow, ncol); } R_MATRIX_INLINE SEXP attribute_hidden M_cholmod_factor_as_sexp(CHM_FR L, int doFree) { static SEXP (*fn)(CHM_FR, int) = NULL; if (!fn) fn = (SEXP (*)(CHM_FR, int)) R_GetCCallable("Matrix", "cholmod_factor_as_sexp"); return fn(L, doFree); } R_MATRIX_INLINE SEXP attribute_hidden M_cholmod_sparse_as_sexp(CHM_SP A, int doFree, int ttype, int doLogic, const char *diagString, SEXP dimnames) { static SEXP (*fn)(CHM_SP, int, int, int, const char *, SEXP) = NULL; if (!fn) fn = (SEXP (*)(CHM_SP, int, int, int, const char *, SEXP)) R_GetCCallable("Matrix", "cholmod_sparse_as_sexp"); return fn(A, doFree, ttype, doLogic, diagString, dimnames); } R_MATRIX_INLINE SEXP attribute_hidden M_cholmod_triplet_as_sexp(CHM_TR A, int doFree, int ttype, int doLogic, const char *diagString, SEXP dimnames) { static SEXP (*fn)(CHM_TR, int, int, int, const char *, SEXP) = NULL; if (!fn) fn = (SEXP (*)(CHM_TR, int, int, int, const char *, SEXP)) R_GetCCallable("Matrix", "cholmod_triplet_as_sexp"); return fn(A, doFree, ttype, doLogic, diagString, dimnames); } R_MATRIX_INLINE SEXP attribute_hidden M_cholmod_dense_as_sexp(CHM_DN A, int doFree) { static SEXP (*fn)(CHM_DN, int) = NULL; if (!fn) fn = (SEXP (*)(CHM_DN, int)) R_GetCCallable("Matrix", "cholmod_dense_as_sexp"); return fn(A, doFree); } R_MATRIX_INLINE double attribute_hidden M_cholmod_factor_ldetA(CHM_FR L) { static double (*fn)(CHM_FR) = NULL; if (!fn) fn = (double (*)(CHM_FR)) R_GetCCallable("Matrix", "cholmod_factor_ldetA"); return fn(L); } R_MATRIX_INLINE CHM_FR attribute_hidden M_cholmod_factor_update(CHM_FR L, CHM_SP A, double beta) { static CHM_FR (*fn)(CHM_FR, CHM_SP, double) = NULL; if (!fn) fn = (CHM_FR (*)(CHM_FR, CHM_SP, double)) R_GetCCallable("Matrix", "cholmod_factor_update"); return fn(L, A, beta); } #ifdef __cplusplus } #endif #endif /* !defined(R_MATRIX_NO_CHOLMOD_UTILS) */ Matrix/inst/include/Matrix/cholmod.h0000644000176200001440000014511114510651525017167 0ustar liggesusers#ifndef R_MATRIX_CHOLMOD_H #define R_MATRIX_CHOLMOD_H #include /* size_t */ #include /* LONG_MAX */ #include /* PRI */ #ifdef __cplusplus extern "C" { #endif /* <<<< from ../../src/SuiteSparse_config/SuiteSparse_config.h <<<<<< */ #ifndef SuiteSparse_long # if !defined(_WIN64) || defined(_UCRT) # define SuiteSparse_long long # define SuiteSparse_long_max LONG_MAX # define SuiteSparse_long_idd "ld" # else // defined(_WIN64) && !defined(_UCRT) # define SuiteSparse_long __int64 # define SuiteSparse_long_max _I64_MAX # define SuiteSparse_long_idd PRId64 # endif /* #define SuiteSparse_long int64_t */ /* // typically long (but on WIN64) */ /* #define SuiteSparse_long_max 9223372036854775801 */ /* // typically LONG_MAX (but ..) */ /* #define SuiteSparse_long_idd PRId64 */ /* // typically "ld" */ # define SuiteSparse_long_id "%" SuiteSparse_long_idd #endif /* <<<< from ../../src/CHOLMOD/Include/cholmod_core.h:244 <<<<<<<<<<< */ #define CHOLMOD_HAS_VERSION_FUNCTION #define CHOLMOD_DATE "Oct 22, 2019" #define CHOLMOD_VER_CODE(main,sub) ((main) * 1000 + (sub)) #define CHOLMOD_MAIN_VERSION 3 #define CHOLMOD_SUB_VERSION 0 #define CHOLMOD_SUBSUB_VERSION 14 #define CHOLMOD_VERSION \ CHOLMOD_VER_CODE(CHOLMOD_MAIN_VERSION,CHOLMOD_SUB_VERSION) /* <<<< from ../../src/CHOLMOD/Include/cholmod_cholesky.h:178 <<<<<<< */ #define CHOLMOD_A 0 /* solve Ax=b */ #define CHOLMOD_LDLt 1 /* solve LDL'x=b */ #define CHOLMOD_LD 2 /* solve LDx=b */ #define CHOLMOD_DLt 3 /* solve DL'x=b */ #define CHOLMOD_L 4 /* solve Lx=b */ #define CHOLMOD_Lt 5 /* solve L'x=b */ #define CHOLMOD_D 6 /* solve Dx=b */ #define CHOLMOD_P 7 /* permute x=Px */ #define CHOLMOD_Pt 8 /* permute x=P'x */ /* from ../../src/CHOLMOD/Include/cholmod_matrixops.h:104 <<<<<<<<<<< */ #define CHOLMOD_SCALAR 0 /* A = s*A */ #define CHOLMOD_ROW 1 /* A = diag(s)*A */ #define CHOLMOD_COL 2 /* A = A*diag(s) */ #define CHOLMOD_SYM 3 /* A = diag(s)*A*diag(s) */ /* ========================================================================== */ /* === CUDA BLAS for the GPU ================================================ */ /* ========================================================================== */ /* The number of OMP threads should typically be set to the number of cores */ /* per socket inthe machine being used. This maximizes memory performance. */ #ifndef CHOLMOD_OMP_NUM_THREADS #define CHOLMOD_OMP_NUM_THREADS 4 #endif /* Define buffering parameters for GPU processing */ #ifndef SUITESPARSE_GPU_EXTERN_ON #ifdef GPU_BLAS #include #endif #endif #define CHOLMOD_DEVICE_SUPERNODE_BUFFERS 6 #define CHOLMOD_HOST_SUPERNODE_BUFFERS 8 #define CHOLMOD_DEVICE_STREAMS 2 // from ../../src/CHOLMOD/Include/cholmod_core.h - line 295 : <<<<< /* Each CHOLMOD object has its own type code. */ #define CHOLMOD_COMMON 0 #define CHOLMOD_SPARSE 1 #define CHOLMOD_FACTOR 2 #define CHOLMOD_DENSE 3 #define CHOLMOD_TRIPLET 4 /* ========================================================================== */ /* === CHOLMOD Common ======================================================= */ /* ========================================================================== */ /* itype defines the types of integer used: */ #define CHOLMOD_INT 0 /* all integer arrays are int */ #define CHOLMOD_INTLONG 1 /* most are int, some are SuiteSparse_long */ #define CHOLMOD_LONG 2 /* all integer arrays are SuiteSparse_long */ /* The itype of all parameters for all CHOLMOD routines must match. * FUTURE WORK: CHOLMOD_INTLONG is not yet supported. */ /* dtype defines what the numerical type is (double or float): */ #define CHOLMOD_DOUBLE 0 /* all numerical values are double */ #define CHOLMOD_SINGLE 1 /* all numerical values are float */ /* The dtype of all parameters for all CHOLMOD routines must match. * * Scalar floating-point values are always passed as double arrays of size 2 * (for the real and imaginary parts). They are typecast to float as needed. * FUTURE WORK: the float case is not supported yet. */ /* xtype defines the kind of numerical values used: */ #define CHOLMOD_PATTERN 0 /* pattern only, no numerical values */ #define CHOLMOD_REAL 1 /* a real matrix */ #define CHOLMOD_COMPLEX 2 /* a complex matrix (ANSI C99 compatible) */ #define CHOLMOD_ZOMPLEX 3 /* a complex matrix (MATLAB compatible) */ /* Definitions for cholmod_common: */ #define CHOLMOD_MAXMETHODS 9 /* maximum number of different methods that */ /* cholmod_analyze can try. Must be >= 9. */ /* Common->status values. zero means success, negative means a fatal error, * positive is a warning. */ #define CHOLMOD_OK 0 /* success */ #define CHOLMOD_NOT_INSTALLED (-1) /* failure: method not installed */ #define CHOLMOD_OUT_OF_MEMORY (-2) /* failure: out of memory */ #define CHOLMOD_TOO_LARGE (-3) /* failure: integer overflow occured */ #define CHOLMOD_INVALID (-4) /* failure: invalid input */ #define CHOLMOD_GPU_PROBLEM (-5) /* failure: GPU fatal error */ #define CHOLMOD_NOT_POSDEF (1) /* warning: matrix not pos. def. */ #define CHOLMOD_DSMALL (2) /* warning: D for LDL' or diag(L) or */ /* LL' has tiny absolute value */ /* ordering method (also used for L->ordering) */ #define CHOLMOD_NATURAL 0 /* use natural ordering */ #define CHOLMOD_GIVEN 1 /* use given permutation */ #define CHOLMOD_AMD 2 /* use minimum degree (AMD) */ #define CHOLMOD_METIS 3 /* use METIS' nested dissection */ #define CHOLMOD_NESDIS 4 /* use CHOLMOD's version of nested dissection:*/ /* node bisector applied recursively, followed * by constrained minimum degree (CSYMAMD or * CCOLAMD) */ #define CHOLMOD_COLAMD 5 /* use AMD for A, COLAMD for A*A' */ /* POSTORDERED is not a method, but a result of natural ordering followed by a * weighted postorder. It is used for L->ordering, not method [ ].ordering. */ #define CHOLMOD_POSTORDERED 6 /* natural ordering, postordered. */ /* supernodal strategy (for Common->supernodal) */ #define CHOLMOD_SIMPLICIAL 0 /* always do simplicial */ #define CHOLMOD_AUTO 1 /* select simpl/super depending on matrix */ #define CHOLMOD_SUPERNODAL 2 /* always do supernodal */ typedef struct cholmod_common_struct { /* ---------------------------------------------------------------------- */ /* parameters for symbolic/numeric factorization and update/downdate */ /* ---------------------------------------------------------------------- */ double dbound ; /* Smallest absolute value of diagonal entries of D * for LDL' factorization and update/downdate/rowadd/ * rowdel, or the diagonal of L for an LL' factorization. * Entries in the range 0 to dbound are replaced with dbound. * Entries in the range -dbound to 0 are replaced with -dbound. No * changes are made to the diagonal if dbound <= 0. Default: zero */ double grow0 ; /* For a simplicial factorization, L->i and L->x can * grow if necessary. grow0 is the factor by which * it grows. For the initial space, L is of size MAX (1,grow0) times * the required space. If L runs out of space, the new size of L is * MAX(1.2,grow0) times the new required space. If you do not plan on * modifying the LDL' factorization in the Modify module, set grow0 to * zero (or set grow2 to 0, see below). Default: 1.2 */ double grow1 ; size_t grow2 ; /* For a simplicial factorization, each column j of L * is initialized with space equal to * grow1*L->ColCount[j] + grow2. If grow0 < 1, grow1 < 1, or grow2 == 0, * then the space allocated is exactly equal to L->ColCount[j]. If the * column j runs out of space, it increases to grow1*need + grow2 in * size, where need is the total # of nonzeros in that column. If you do * not plan on modifying the factorization in the Modify module, set * grow2 to zero. Default: grow1 = 1.2, grow2 = 5. */ size_t maxrank ; /* rank of maximum update/downdate. Valid values: * 2, 4, or 8. A value < 2 is set to 2, and a * value > 8 is set to 8. It is then rounded up to the next highest * power of 2, if not already a power of 2. Workspace (Xwork, below) of * size nrow-by-maxrank double's is allocated for the update/downdate. * If an update/downdate of rank-k is requested, with k > maxrank, * it is done in steps of maxrank. Default: 8, which is fastest. * Memory usage can be reduced by setting maxrank to 2 or 4. */ double supernodal_switch ; /* supernodal vs simplicial factorization */ int supernodal ; /* If Common->supernodal <= CHOLMOD_SIMPLICIAL * (0) then cholmod_analyze performs a * simplicial analysis. If >= CHOLMOD_SUPERNODAL (2), then a supernodal * analysis is performed. If == CHOLMOD_AUTO (1) and * flop/nnz(L) < Common->supernodal_switch, then a simplicial analysis * is done. A supernodal analysis done otherwise. * Default: CHOLMOD_AUTO. Default supernodal_switch = 40 */ int final_asis ; /* If TRUE, then ignore the other final_* parameters * (except for final_pack). * The factor is left as-is when done. Default: TRUE.*/ int final_super ; /* If TRUE, leave a factor in supernodal form when * supernodal factorization is finished. If FALSE, * then convert to a simplicial factor when done. * Default: TRUE */ int final_ll ; /* If TRUE, leave factor in LL' form when done. * Otherwise, leave in LDL' form. Default: FALSE */ int final_pack ; /* If TRUE, pack the columns when done. If TRUE, and * cholmod_factorize is called with a symbolic L, L is * allocated with exactly the space required, using L->ColCount. If you * plan on modifying the factorization, set Common->final_pack to FALSE, * and each column will be given a little extra slack space for future * growth in fill-in due to updates. Default: TRUE */ int final_monotonic ; /* If TRUE, ensure columns are monotonic when done. * Default: TRUE */ int final_resymbol ;/* if cholmod_factorize performed a supernodal * factorization, final_resymbol is true, and * final_super is FALSE (convert a simplicial numeric factorization), * then numerically zero entries that resulted from relaxed supernodal * amalgamation are removed. This does not remove entries that are zero * due to exact numeric cancellation, since doing so would break the * update/downdate rowadd/rowdel routines. Default: FALSE. */ /* supernodal relaxed amalgamation parameters: */ double zrelax [3] ; size_t nrelax [3] ; /* Let ns be the total number of columns in two adjacent supernodes. * Let z be the fraction of zero entries in the two supernodes if they * are merged (z includes zero entries from prior amalgamations). The * two supernodes are merged if: * (ns <= nrelax [0]) || (no new zero entries added) || * (ns <= nrelax [1] && z < zrelax [0]) || * (ns <= nrelax [2] && z < zrelax [1]) || (z < zrelax [2]) * * Default parameters result in the following rule: * (ns <= 4) || (no new zero entries added) || * (ns <= 16 && z < 0.8) || (ns <= 48 && z < 0.1) || (z < 0.05) */ int prefer_zomplex ; /* X = cholmod_solve (sys, L, B, Common) computes * x=A\b or solves a related system. If L and B are * both real, then X is real. Otherwise, X is returned as * CHOLMOD_COMPLEX if Common->prefer_zomplex is FALSE, or * CHOLMOD_ZOMPLEX if Common->prefer_zomplex is TRUE. This parameter * is needed because there is no supernodal zomplex L. Suppose the * caller wants all complex matrices to be stored in zomplex form * (MATLAB, for example). A supernodal L is returned in complex form * if A is zomplex. B can be real, and thus X = cholmod_solve (L,B) * should return X as zomplex. This cannot be inferred from the input * arguments L and B. Default: FALSE, since all data types are * supported in CHOLMOD_COMPLEX form and since this is the native type * of LAPACK and the BLAS. Note that the MATLAB/cholmod.c mexFunction * sets this parameter to TRUE, since MATLAB matrices are in * CHOLMOD_ZOMPLEX form. */ int prefer_upper ; /* cholmod_analyze and cholmod_factorize work * fastest when a symmetric matrix is stored in * upper triangular form when a fill-reducing ordering is used. In * MATLAB, this corresponds to how x=A\b works. When the matrix is * ordered as-is, they work fastest when a symmetric matrix is in lower * triangular form. In MATLAB, R=chol(A) does the opposite. This * parameter affects only how cholmod_read returns a symmetric matrix. * If TRUE (the default case), a symmetric matrix is always returned in * upper-triangular form (A->stype = 1). */ int quick_return_if_not_posdef ; /* if TRUE, the supernodal numeric * factorization will return quickly if * the matrix is not positive definite. Default: FALSE. */ int prefer_binary ; /* cholmod_read_triplet converts a symmetric * pattern-only matrix into a real matrix. If * prefer_binary is FALSE, the diagonal entries are set to 1 + the degree * of the row/column, and off-diagonal entries are set to -1 (resulting * in a positive definite matrix if the diagonal is zero-free). Most * symmetric patterns are the pattern a positive definite matrix. If * this parameter is TRUE, then the matrix is returned with a 1 in each * entry, instead. Default: FALSE. Added in v1.3. */ /* ---------------------------------------------------------------------- */ /* printing and error handling options */ /* ---------------------------------------------------------------------- */ int print ; /* print level. Default: 3 */ int precise ; /* if TRUE, print 16 digits. Otherwise print 5 */ /* CHOLMOD print_function replaced with SuiteSparse_config.print_func */ int try_catch ; /* if TRUE, then ignore errors; CHOLMOD is in the middle * of a try/catch block. No error message is printed * and the Common->error_handler function is not called. */ void (*error_handler) (int status, const char *file, int line, const char *message) ; /* Common->error_handler is the user's error handling routine. If not * NULL, this routine is called if an error occurs in CHOLMOD. status * can be CHOLMOD_OK (0), negative for a fatal error, and positive for * a warning. file is a string containing the name of the source code * file where the error occured, and line is the line number in that * file. message is a string describing the error in more detail. */ /* ---------------------------------------------------------------------- */ /* ordering options */ /* ---------------------------------------------------------------------- */ /* The cholmod_analyze routine can try many different orderings and select * the best one. It can also try one ordering method multiple times, with * different parameter settings. The default is to use three orderings, * the user's permutation (if provided), AMD which is the fastest ordering * and generally gives good fill-in, and METIS. CHOLMOD's nested dissection * (METIS with a constrained AMD) usually gives a better ordering than METIS * alone (by about 5% to 10%) but it takes more time. * * If you know the method that is best for your matrix, set Common->nmethods * to 1 and set Common->method [0] to the set of parameters for that method. * If you set it to 1 and do not provide a permutation, then only AMD will * be called. * * If METIS is not available, the default # of methods tried is 2 (the user * permutation, if any, and AMD). * * To try other methods, set Common->nmethods to the number of methods you * want to try. The suite of default methods and their parameters is * described in the cholmod_defaults routine, and summarized here: * * Common->method [i]: * i = 0: user-provided ordering (cholmod_analyze_p only) * i = 1: AMD (for both A and A*A') * i = 2: METIS * i = 3: CHOLMOD's nested dissection (NESDIS), default parameters * i = 4: natural * i = 5: NESDIS with nd_small = 20000 * i = 6: NESDIS with nd_small = 4, no constrained minimum degree * i = 7: NESDIS with no dense node removal * i = 8: AMD for A, COLAMD for A*A' * * You can modify the suite of methods you wish to try by modifying * Common.method [...] after calling cholmod_start or cholmod_defaults. * * For example, to use AMD, followed by a weighted postordering: * * Common->nmethods = 1 ; * Common->method [0].ordering = CHOLMOD_AMD ; * Common->postorder = TRUE ; * * To use the natural ordering (with no postordering): * * Common->nmethods = 1 ; * Common->method [0].ordering = CHOLMOD_NATURAL ; * Common->postorder = FALSE ; * * If you are going to factorize hundreds or more matrices with the same * nonzero pattern, you may wish to spend a great deal of time finding a * good permutation. In this case, try setting Common->nmethods to 9. * The time spent in cholmod_analysis will be very high, but you need to * call it only once. * * cholmod_analyze sets Common->current to a value between 0 and nmethods-1. * Each ordering method uses the set of options defined by this parameter. */ int nmethods ; /* The number of ordering methods to try. Default: 0. * nmethods = 0 is a special case. cholmod_analyze * will try the user-provided ordering (if given) and AMD. Let fl and * lnz be the flop count and nonzeros in L from AMD's ordering. Let * anz be the number of nonzeros in the upper or lower triangular part * of the symmetric matrix A. If fl/lnz < 500 or lnz/anz < 5, then this * is a good ordering, and METIS is not attempted. Otherwise, METIS is * tried. The best ordering found is used. If nmethods > 0, the * methods used are given in the method[ ] array, below. The first * three methods in the default suite of orderings is (1) use the given * permutation (if provided), (2) use AMD, and (3) use METIS. Maximum * allowed value is CHOLMOD_MAXMETHODS. */ int current ; /* The current method being tried. Default: 0. Valid * range is 0 to nmethods-1. */ int selected ; /* The best method found. */ /* The suite of ordering methods and parameters: */ struct cholmod_method_struct { /* statistics for this method */ double lnz ; /* nnz(L) excl. zeros from supernodal amalgamation, * for a "pure" L */ double fl ; /* flop count for a "pure", real simplicial LL' * factorization, with no extra work due to * amalgamation. Subtract n to get the LDL' flop count. Multiply * by about 4 if the matrix is complex or zomplex. */ /* ordering method parameters */ double prune_dense ;/* dense row/col control for AMD, SYMAMD, CSYMAMD, * and NESDIS (cholmod_nested_dissection). For a * symmetric n-by-n matrix, rows/columns with more than * MAX (16, prune_dense * sqrt (n)) entries are removed prior to * ordering. They appear at the end of the re-ordered matrix. * * If prune_dense < 0, only completely dense rows/cols are removed. * * This paramater is also the dense column control for COLAMD and * CCOLAMD. For an m-by-n matrix, columns with more than * MAX (16, prune_dense * sqrt (MIN (m,n))) entries are removed prior * to ordering. They appear at the end of the re-ordered matrix. * CHOLMOD factorizes A*A', so it calls COLAMD and CCOLAMD with A', * not A. Thus, this parameter affects the dense *row* control for * CHOLMOD's matrix, and the dense *column* control for COLAMD and * CCOLAMD. * * Removing dense rows and columns improves the run-time of the * ordering methods. It has some impact on ordering quality * (usually minimal, sometimes good, sometimes bad). * * Default: 10. */ double prune_dense2 ;/* dense row control for COLAMD and CCOLAMD. * Rows with more than MAX (16, dense2 * sqrt (n)) * for an m-by-n matrix are removed prior to ordering. CHOLMOD's * matrix is transposed before ordering it with COLAMD or CCOLAMD, * so this controls the dense *columns* of CHOLMOD's matrix, and * the dense *rows* of COLAMD's or CCOLAMD's matrix. * * If prune_dense2 < 0, only completely dense rows/cols are removed. * * Default: -1. Note that this is not the default for COLAMD and * CCOLAMD. -1 is best for Cholesky. 10 is best for LU. */ double nd_oksep ; /* in NESDIS, when a node separator is computed, it * discarded if nsep >= nd_oksep*n, where nsep is * the number of nodes in the separator, and n is the size of the * graph being cut. Valid range is 0 to 1. If 1 or greater, the * separator is discarded if it consists of the entire graph. * Default: 1 */ double other_1 [4] ; /* future expansion */ size_t nd_small ; /* do not partition graphs with fewer nodes than * nd_small, in NESDIS. Default: 200 (same as * METIS) */ size_t other_2 [4] ; /* future expansion */ int aggressive ; /* Aggresive absorption in AMD, COLAMD, SYMAMD, * CCOLAMD, and CSYMAMD. Default: TRUE */ int order_for_lu ; /* CCOLAMD can be optimized to produce an ordering * for LU or Cholesky factorization. CHOLMOD only * performs a Cholesky factorization. However, you may wish to use * CHOLMOD as an interface for CCOLAMD but use it for your own LU * factorization. In this case, order_for_lu should be set to FALSE. * When factorizing in CHOLMOD itself, you should *** NEVER *** set * this parameter FALSE. Default: TRUE. */ int nd_compress ; /* If TRUE, compress the graph and subgraphs before * partitioning them in NESDIS. Default: TRUE */ int nd_camd ; /* If 1, follow the nested dissection ordering * with a constrained minimum degree ordering that * respects the partitioning just found (using CAMD). If 2, use * CSYMAMD instead. If you set nd_small very small, you may not need * this ordering, and can save time by setting it to zero (no * constrained minimum degree ordering). Default: 1. */ int nd_components ; /* The nested dissection ordering finds a node * separator that splits the graph into two parts, * which may be unconnected. If nd_components is TRUE, each of * these connected components is split independently. If FALSE, * each part is split as a whole, even if it consists of more than * one connected component. Default: FALSE */ /* fill-reducing ordering to use */ int ordering ; size_t other_3 [4] ; /* future expansion */ } method [CHOLMOD_MAXMETHODS + 1] ; int postorder ; /* If TRUE, cholmod_analyze follows the ordering with a * weighted postorder of the elimination tree. Improves * supernode amalgamation. Does not affect fundamental nnz(L) and * flop count. Default: TRUE. */ int default_nesdis ; /* Default: FALSE. If FALSE, then the default * ordering strategy (when Common->nmethods == 0) * is to try the given ordering (if present), AMD, and then METIS if AMD * reports high fill-in. If Common->default_nesdis is TRUE then NESDIS * is used instead in the default strategy. */ /* ---------------------------------------------------------------------- */ /* memory management, complex divide, and hypot function pointers moved */ /* ---------------------------------------------------------------------- */ /* Function pointers moved from here (in CHOLMOD 2.2.0) to SuiteSparse_config.[ch]. See CHOLMOD/Include/cholmod_back.h for a set of macros that can be #include'd or copied into your application to define these function pointers on any version of CHOLMOD. */ /* ---------------------------------------------------------------------- */ /* METIS workarounds */ /* ---------------------------------------------------------------------- */ /* These workarounds were put into place for METIS 4.0.1. They are safe to use with METIS 5.1.0, but they might not longer be necessary. */ double metis_memory ; /* This is a parameter for CHOLMOD's interface to * METIS, not a parameter to METIS itself. METIS * uses an amount of memory that is difficult to estimate precisely * beforehand. If it runs out of memory, it terminates your program. * All routines in CHOLMOD except for CHOLMOD's interface to METIS * return an error status and safely return to your program if they run * out of memory. To mitigate this problem, the CHOLMOD interface * can allocate a single block of memory equal in size to an empirical * upper bound of METIS's memory usage times the Common->metis_memory * parameter, and then immediately free it. It then calls METIS. If * this pre-allocation fails, it is possible that METIS will fail as * well, and so CHOLMOD returns with an out-of-memory condition without * calling METIS. * * METIS_NodeND (used in the CHOLMOD_METIS ordering option) with its * default parameter settings typically uses about (4*nz+40n+4096) * times sizeof(int) memory, where nz is equal to the number of entries * in A for the symmetric case or AA' if an unsymmetric matrix is * being ordered (where nz includes both the upper and lower parts * of A or AA'). The observed "upper bound" (with 2 exceptions), * measured in an instrumented copy of METIS 4.0.1 on thousands of * matrices, is (10*nz+50*n+4096) * sizeof(int). Two large matrices * exceeded this bound, one by almost a factor of 2 (Gupta/gupta2). * * If your program is terminated by METIS, try setting metis_memory to * 2.0, or even higher if needed. By default, CHOLMOD assumes that METIS * does not have this problem (so that CHOLMOD will work correctly when * this issue is fixed in METIS). Thus, the default value is zero. * This work-around is not guaranteed anyway. * * If a matrix exceeds this predicted memory usage, AMD is attempted * instead. It, too, may run out of memory, but if it does so it will * not terminate your program. */ double metis_dswitch ; /* METIS_NodeND in METIS 4.0.1 gives a seg */ size_t metis_nswitch ; /* fault with one matrix of order n = 3005 and * nz = 6,036,025. This is a very dense graph. * The workaround is to use AMD instead of METIS for matrices of dimension * greater than Common->metis_nswitch (default 3000) or more and with * density of Common->metis_dswitch (default 0.66) or more. * cholmod_nested_dissection has no problems with the same matrix, even * though it uses METIS_ComputeVertexSeparator on this matrix. If this * seg fault does not affect you, set metis_nswitch to zero or less, * and CHOLMOD will not switch to AMD based just on the density of the * matrix (it will still switch to AMD if the metis_memory parameter * causes the switch). */ /* ---------------------------------------------------------------------- */ /* workspace */ /* ---------------------------------------------------------------------- */ /* CHOLMOD has several routines that take less time than the size of * workspace they require. Allocating and initializing the workspace would * dominate the run time, unless workspace is allocated and initialized * just once. CHOLMOD allocates this space when needed, and holds it here * between calls to CHOLMOD. cholmod_start sets these pointers to NULL * (which is why it must be the first routine called in CHOLMOD). * cholmod_finish frees the workspace (which is why it must be the last * call to CHOLMOD). */ size_t nrow ; /* size of Flag and Head */ SuiteSparse_long mark ; /* mark value for Flag array */ size_t iworksize ; /* size of Iwork. Upper bound: 6*nrow+ncol */ size_t xworksize ; /* size of Xwork, in bytes. * maxrank*nrow*sizeof(double) for update/downdate. * 2*nrow*sizeof(double) otherwise */ /* initialized workspace: contents needed between calls to CHOLMOD */ void *Flag ; /* size nrow, an integer array. Kept cleared between * calls to cholmod rouines (Flag [i] < mark) */ void *Head ; /* size nrow+1, an integer array. Kept cleared between * calls to cholmod routines (Head [i] = EMPTY) */ void *Xwork ; /* a double array. Its size varies. It is nrow for * most routines (cholmod_rowfac, cholmod_add, * cholmod_aat, cholmod_norm, cholmod_ssmult) for the real case, twice * that when the input matrices are complex or zomplex. It is of size * 2*nrow for cholmod_rowadd and cholmod_rowdel. For cholmod_updown, * its size is maxrank*nrow where maxrank is 2, 4, or 8. Kept cleared * between calls to cholmod (set to zero). */ /* uninitialized workspace, contents not needed between calls to CHOLMOD */ void *Iwork ; /* size iworksize, 2*nrow+ncol for most routines, * up to 6*nrow+ncol for cholmod_analyze. */ int itype ; /* If CHOLMOD_LONG, Flag, Head, and Iwork are * SuiteSparse_long. Otherwise all three are int. */ int dtype ; /* double or float */ /* Common->itype and Common->dtype are used to define the types of all * sparse matrices, triplet matrices, dense matrices, and factors * created using this Common struct. The itypes and dtypes of all * parameters to all CHOLMOD routines must match. */ int no_workspace_reallocate ; /* this is an internal flag, used as a * precaution by cholmod_analyze. It is normally false. If true, * cholmod_allocate_work is not allowed to reallocate any workspace; * they must use the existing workspace in Common (Iwork, Flag, Head, * and Xwork). Added for CHOLMOD v1.1 */ /* ---------------------------------------------------------------------- */ /* statistics */ /* ---------------------------------------------------------------------- */ /* fl and lnz are set only in cholmod_analyze and cholmod_rowcolcounts, * in the Cholesky modudle. modfl is set only in the Modify module. */ int status ; /* error code */ double fl ; /* LL' flop count from most recent analysis */ double lnz ; /* fundamental nz in L */ double anz ; /* nonzeros in tril(A) if A is symmetric/lower, * triu(A) if symmetric/upper, or tril(A*A') if * unsymmetric, in last call to cholmod_analyze. */ double modfl ; /* flop count from most recent update/downdate/ * rowadd/rowdel (excluding flops to modify the * solution to Lx=b, if computed) */ size_t malloc_count ; /* # of objects malloc'ed minus the # free'd*/ size_t memory_usage ; /* peak memory usage in bytes */ size_t memory_inuse ; /* current memory usage in bytes */ double nrealloc_col ; /* # of column reallocations */ double nrealloc_factor ;/* # of factor reallocations due to col. reallocs */ double ndbounds_hit ; /* # of times diagonal modified by dbound */ double rowfacfl ; /* # of flops in last call to cholmod_rowfac */ double aatfl ; /* # of flops to compute A(:,f)*A(:,f)' */ int called_nd ; /* TRUE if the last call to * cholmod_analyze called NESDIS or METIS. */ int blas_ok ; /* FALSE if BLAS int overflow; TRUE otherwise */ /* ---------------------------------------------------------------------- */ /* SuiteSparseQR control parameters: */ /* ---------------------------------------------------------------------- */ double SPQR_grain ; /* task size is >= max (total flops / grain) */ double SPQR_small ; /* task size is >= small */ int SPQR_shrink ; /* controls stack realloc method */ int SPQR_nthreads ; /* number of TBB threads, 0 = auto */ /* ---------------------------------------------------------------------- */ /* SuiteSparseQR statistics */ /* ---------------------------------------------------------------------- */ /* was other1 [0:3] */ double SPQR_flopcount ; /* flop count for SPQR */ double SPQR_analyze_time ; /* analysis time in seconds for SPQR */ double SPQR_factorize_time ; /* factorize time in seconds for SPQR */ double SPQR_solve_time ; /* backsolve time in seconds */ /* was SPQR_xstat [0:3] */ double SPQR_flopcount_bound ; /* upper bound on flop count */ double SPQR_tol_used ; /* tolerance used */ double SPQR_norm_E_fro ; /* Frobenius norm of dropped entries */ /* was SPQR_istat [0:9] */ SuiteSparse_long SPQR_istat [10] ; /* ---------------------------------------------------------------------- */ /* GPU configuration and statistics */ /* ---------------------------------------------------------------------- */ /* useGPU: 1 if gpu-acceleration is requested */ /* 0 if gpu-acceleration is prohibited */ /* -1 if gpu-acceleration is undefined in which case the */ /* environment CHOLMOD_USE_GPU will be queried and used. */ /* useGPU=-1 is only used by CHOLMOD and treated as 0 by SPQR */ int useGPU; /* for CHOLMOD: */ size_t maxGpuMemBytes; double maxGpuMemFraction; /* for SPQR: */ size_t gpuMemorySize; /* Amount of memory in bytes on the GPU */ double gpuKernelTime; /* Time taken by GPU kernels */ SuiteSparse_long gpuFlops; /* Number of flops performed by the GPU */ int gpuNumKernelLaunches; /* Number of GPU kernel launches */ /* If not using the GPU, these items are not used, but they should be present so that the CHOLMOD Common has the same size whether the GPU is used or not. This way, all packages will agree on the size of the CHOLMOD Common, regardless of whether or not they are compiled with the GPU libraries or not */ #ifdef GPU_BLAS /* in CUDA, these three types are pointers */ #define CHOLMOD_CUBLAS_HANDLE cublasHandle_t #define CHOLMOD_CUDASTREAM cudaStream_t #define CHOLMOD_CUDAEVENT cudaEvent_t #else /* ... so make them void * pointers if the GPU is not being used */ #define CHOLMOD_CUBLAS_HANDLE void * #define CHOLMOD_CUDASTREAM void * #define CHOLMOD_CUDAEVENT void * #endif CHOLMOD_CUBLAS_HANDLE cublasHandle ; /* a set of streams for general use */ CHOLMOD_CUDASTREAM gpuStream[CHOLMOD_HOST_SUPERNODE_BUFFERS]; CHOLMOD_CUDAEVENT cublasEventPotrf [3] ; CHOLMOD_CUDAEVENT updateCKernelsComplete; CHOLMOD_CUDAEVENT updateCBuffersFree[CHOLMOD_HOST_SUPERNODE_BUFFERS]; void *dev_mempool; /* pointer to single allocation of device memory */ size_t dev_mempool_size; void *host_pinned_mempool; /* pointer to single allocation of pinned mem */ size_t host_pinned_mempool_size; size_t devBuffSize; int ibuffer; double syrkStart ; /* time syrk started */ /* run times of the different parts of CHOLMOD (GPU and CPU) */ double cholmod_cpu_gemm_time ; double cholmod_cpu_syrk_time ; double cholmod_cpu_trsm_time ; double cholmod_cpu_potrf_time ; double cholmod_gpu_gemm_time ; double cholmod_gpu_syrk_time ; double cholmod_gpu_trsm_time ; double cholmod_gpu_potrf_time ; double cholmod_assemble_time ; double cholmod_assemble_time2 ; /* number of times the BLAS are called on the CPU and the GPU */ size_t cholmod_cpu_gemm_calls ; size_t cholmod_cpu_syrk_calls ; size_t cholmod_cpu_trsm_calls ; size_t cholmod_cpu_potrf_calls ; size_t cholmod_gpu_gemm_calls ; size_t cholmod_gpu_syrk_calls ; size_t cholmod_gpu_trsm_calls ; size_t cholmod_gpu_potrf_calls ; } cholmod_common ; // in ../../src/CHOLMOD/Include/cholmod_core.h skip forward to - line 1212 : <<<<< /* A sparse matrix stored in compressed-column form. */ typedef struct cholmod_sparse_struct { size_t nrow ; /* the matrix is nrow-by-ncol */ size_t ncol ; size_t nzmax ; /* maximum number of entries in the matrix */ /* pointers to int or SuiteSparse_long: */ void *p ; /* p [0..ncol], the column pointers */ void *i ; /* i [0..nzmax-1], the row indices */ /* for unpacked matrices only: */ void *nz ; /* nz [0..ncol-1], the # of nonzeros in each col. In * packed form, the nonzero pattern of column j is in * A->i [A->p [j] ... A->p [j+1]-1]. In unpacked form, column j is in * A->i [A->p [j] ... A->p [j]+A->nz[j]-1] instead. In both cases, the * numerical values (if present) are in the corresponding locations in * the array x (or z if A->xtype is CHOLMOD_ZOMPLEX). */ /* pointers to double or float: */ void *x ; /* size nzmax or 2*nzmax, if present */ void *z ; /* size nzmax, if present */ int stype ; /* Describes what parts of the matrix are considered: * * 0: matrix is "unsymmetric": use both upper and lower triangular parts * (the matrix may actually be symmetric in pattern and value, but * both parts are explicitly stored and used). May be square or * rectangular. * >0: matrix is square and symmetric, use upper triangular part. * Entries in the lower triangular part are ignored. * <0: matrix is square and symmetric, use lower triangular part. * Entries in the upper triangular part are ignored. * * Note that stype>0 and stype<0 are different for cholmod_sparse and * cholmod_triplet. See the cholmod_triplet data structure for more * details. */ int itype ; /* CHOLMOD_INT: p, i, and nz are int. * CHOLMOD_INTLONG: p is SuiteSparse_long, * i and nz are int. * CHOLMOD_LONG: p, i, and nz are SuiteSparse_long */ int xtype ; /* pattern, real, complex, or zomplex */ int dtype ; /* x and z are double or float */ int sorted ; /* TRUE if columns are sorted, FALSE otherwise */ int packed ; /* TRUE if packed (nz ignored), FALSE if unpacked * (nz is required) */ } cholmod_sparse ; // in ../../src/CHOLMOD/Include/cholmod_core.h skip forward to - line 1606 : <<<<< /* A symbolic and numeric factorization, either simplicial or supernodal. * In all cases, the row indices in the columns of L are kept sorted. */ typedef struct cholmod_factor_struct { /* ---------------------------------------------------------------------- */ /* for both simplicial and supernodal factorizations */ /* ---------------------------------------------------------------------- */ size_t n ; /* L is n-by-n */ size_t minor ; /* If the factorization failed, L->minor is the column * at which it failed (in the range 0 to n-1). A value * of n means the factorization was successful or * the matrix has not yet been factorized. */ /* ---------------------------------------------------------------------- */ /* symbolic ordering and analysis */ /* ---------------------------------------------------------------------- */ void *Perm ; /* size n, permutation used */ void *ColCount ; /* size n, column counts for simplicial L */ void *IPerm ; /* size n, inverse permutation. Only created by * cholmod_solve2 if Bset is used. */ /* ---------------------------------------------------------------------- */ /* simplicial factorization */ /* ---------------------------------------------------------------------- */ size_t nzmax ; /* size of i and x */ void *p ; /* p [0..ncol], the column pointers */ void *i ; /* i [0..nzmax-1], the row indices */ void *x ; /* x [0..nzmax-1], the numerical values */ void *z ; void *nz ; /* nz [0..ncol-1], the # of nonzeros in each column. * i [p [j] ... p [j]+nz[j]-1] contains the row indices, * and the numerical values are in the same locatins * in x. The value of i [p [k]] is always k. */ void *next ; /* size ncol+2. next [j] is the next column in i/x */ void *prev ; /* size ncol+2. prev [j] is the prior column in i/x. * head of the list is ncol+1, and the tail is ncol. */ /* ---------------------------------------------------------------------- */ /* supernodal factorization */ /* ---------------------------------------------------------------------- */ /* Note that L->x is shared with the simplicial data structure. L->x has * size L->nzmax for a simplicial factor, and size L->xsize for a supernodal * factor. */ size_t nsuper ; /* number of supernodes */ size_t ssize ; /* size of s, integer part of supernodes */ size_t xsize ; /* size of x, real part of supernodes */ size_t maxcsize ; /* size of largest update matrix */ size_t maxesize ; /* max # of rows in supernodes, excl. triangular part */ void *super ; /* size nsuper+1, first col in each supernode */ void *pi ; /* size nsuper+1, pointers to integer patterns */ void *px ; /* size nsuper+1, pointers to real parts */ void *s ; /* size ssize, integer part of supernodes */ /* ---------------------------------------------------------------------- */ /* factorization type */ /* ---------------------------------------------------------------------- */ int ordering ; /* ordering method used */ int is_ll ; /* TRUE if LL', FALSE if LDL' */ int is_super ; /* TRUE if supernodal, FALSE if simplicial */ int is_monotonic ; /* TRUE if columns of L appear in order 0..n-1. * Only applicable to simplicial numeric types. */ /* There are 8 types of factor objects that cholmod_factor can represent * (only 6 are used): * * Numeric types (xtype is not CHOLMOD_PATTERN) * -------------------------------------------- * * simplicial LDL': (is_ll FALSE, is_super FALSE). Stored in compressed * column form, using the simplicial components above (nzmax, p, i, * x, z, nz, next, and prev). The unit diagonal of L is not stored, * and D is stored in its place. There are no supernodes. * * simplicial LL': (is_ll TRUE, is_super FALSE). Uses the same storage * scheme as the simplicial LDL', except that D does not appear. * The first entry of each column of L is the diagonal entry of * that column of L. * * supernodal LDL': (is_ll FALSE, is_super TRUE). Not used. * FUTURE WORK: add support for supernodal LDL' * * supernodal LL': (is_ll TRUE, is_super TRUE). A supernodal factor, * using the supernodal components described above (nsuper, ssize, * xsize, maxcsize, maxesize, super, pi, px, s, x, and z). * * * Symbolic types (xtype is CHOLMOD_PATTERN) * ----------------------------------------- * * simplicial LDL': (is_ll FALSE, is_super FALSE). Nothing is present * except Perm and ColCount. * * simplicial LL': (is_ll TRUE, is_super FALSE). Identical to the * simplicial LDL', except for the is_ll flag. * * supernodal LDL': (is_ll FALSE, is_super TRUE). Not used. * FUTURE WORK: add support for supernodal LDL' * * supernodal LL': (is_ll TRUE, is_super TRUE). A supernodal symbolic * factorization. The simplicial symbolic information is present * (Perm and ColCount), as is all of the supernodal factorization * except for the numerical values (x and z). */ int itype ; /* The integer arrays are Perm, ColCount, p, i, nz, * next, prev, super, pi, px, and s. If itype is * CHOLMOD_INT, all of these are int arrays. * CHOLMOD_INTLONG: p, pi, px are SuiteSparse_long, others int. * CHOLMOD_LONG: all integer arrays are SuiteSparse_long. */ int xtype ; /* pattern, real, complex, or zomplex */ int dtype ; /* x and z double or float */ int useGPU; /* Indicates the symbolic factorization supports * GPU acceleration */ } cholmod_factor ; // in ../../src/CHOLMOD/Include/cholmod_core.h skip forward to - line 1890 : <<<<< /* A dense matrix in column-oriented form. It has no itype since it contains * no integers. Entry in row i and column j is located in x [i+j*d]. */ typedef struct cholmod_dense_struct { size_t nrow ; /* the matrix is nrow-by-ncol */ size_t ncol ; size_t nzmax ; /* maximum number of entries in the matrix */ size_t d ; /* leading dimension (d >= nrow must hold) */ void *x ; /* size nzmax or 2*nzmax, if present */ void *z ; /* size nzmax, if present */ int xtype ; /* pattern, real, complex, or zomplex */ int dtype ; /* x and z double or float */ } cholmod_dense ; // in ../../src/CHOLMOD/Include/cholmod_core.h skip forward to - line 2089 : <<<<< /* A sparse matrix stored in triplet form. */ typedef struct cholmod_triplet_struct { size_t nrow ; /* the matrix is nrow-by-ncol */ size_t ncol ; size_t nzmax ; /* maximum number of entries in the matrix */ size_t nnz ; /* number of nonzeros in the matrix */ void *i ; /* i [0..nzmax-1], the row indices */ void *j ; /* j [0..nzmax-1], the column indices */ void *x ; /* size nzmax or 2*nzmax, if present */ void *z ; /* size nzmax, if present */ int stype ; /* Describes what parts of the matrix are considered: * * 0: matrix is "unsymmetric": use both upper and lower triangular parts * (the matrix may actually be symmetric in pattern and value, but * both parts are explicitly stored and used). May be square or * rectangular. * >0: matrix is square and symmetric. Entries in the lower triangular * part are transposed and added to the upper triangular part when * the matrix is converted to cholmod_sparse form. * <0: matrix is square and symmetric. Entries in the upper triangular * part are transposed and added to the lower triangular part when * the matrix is converted to cholmod_sparse form. * * Note that stype>0 and stype<0 are different for cholmod_sparse and * cholmod_triplet. The reason is simple. You can permute a symmetric * triplet matrix by simply replacing a row and column index with their * new row and column indices, via an inverse permutation. Suppose * P = L->Perm is your permutation, and Pinv is an array of size n. * Suppose a symmetric matrix A is represent by a triplet matrix T, with * entries only in the upper triangular part. Then the following code: * * Ti = T->i ; * Tj = T->j ; * for (k = 0 ; k < n ; k++) Pinv [P [k]] = k ; * for (k = 0 ; k < nz ; k++) Ti [k] = Pinv [Ti [k]] ; * for (k = 0 ; k < nz ; k++) Tj [k] = Pinv [Tj [k]] ; * * creates the triplet form of C=P*A*P'. However, if T initially * contains just the upper triangular entries (T->stype = 1), after * permutation it has entries in both the upper and lower triangular * parts. These entries should be transposed when constructing the * cholmod_sparse form of A, which is what cholmod_triplet_to_sparse * does. Thus: * * C = cholmod_triplet_to_sparse (T, 0, &Common) ; * * will return the matrix C = P*A*P'. * * Since the triplet matrix T is so simple to generate, it's quite easy * to remove entries that you do not want, prior to converting T to the * cholmod_sparse form. So if you include these entries in T, CHOLMOD * assumes that there must be a reason (such as the one above). Thus, * no entry in a triplet matrix is ever ignored. */ int itype ; /* CHOLMOD_LONG: i and j are SuiteSparse_long. Otherwise int */ int xtype ; /* pattern, real, complex, or zomplex */ int dtype ; /* x and z are double or float */ } cholmod_triplet ; /* <<<< Matrix <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ typedef cholmod_common * CHM_CM; typedef cholmod_factor * CHM_FR; typedef cholmod_sparse * CHM_SP; typedef cholmod_triplet * CHM_TR; typedef cholmod_dense * CHM_DN; #define R_MATRIX_CHOLMOD(_NAME_) M_cholmod_ ## _NAME_ #ifndef R_MATRIX_INLINE # define R_MATRIX_INLINE #endif R_MATRIX_INLINE CHM_SP R_MATRIX_CHOLMOD(aat)( CHM_SP, int *, size_t, int, CHM_CM); R_MATRIX_INLINE CHM_SP R_MATRIX_CHOLMOD(add)( CHM_SP, CHM_SP, double[2], double[2], int, int, CHM_CM); R_MATRIX_INLINE CHM_DN R_MATRIX_CHOLMOD(allocate_dense)( size_t, size_t, size_t, int, CHM_CM); R_MATRIX_INLINE CHM_SP R_MATRIX_CHOLMOD(allocate_sparse)( size_t, size_t, size_t, int, int, int, int, CHM_CM); R_MATRIX_INLINE CHM_TR R_MATRIX_CHOLMOD(allocate_triplet)( size_t, size_t, size_t, int, int, CHM_CM); R_MATRIX_INLINE CHM_FR R_MATRIX_CHOLMOD(analyze)( CHM_SP, CHM_CM); R_MATRIX_INLINE CHM_FR R_MATRIX_CHOLMOD(analyze_p)( CHM_SP, int *, int *, size_t, CHM_CM); R_MATRIX_INLINE int R_MATRIX_CHOLMOD(band_inplace)( int, int, int, CHM_SP, CHM_CM); R_MATRIX_INLINE int R_MATRIX_CHOLMOD(change_factor)( int, int, int, int, int, CHM_FR, CHM_CM); R_MATRIX_INLINE CHM_SP R_MATRIX_CHOLMOD(copy)( CHM_SP, int, int, CHM_CM); R_MATRIX_INLINE CHM_DN R_MATRIX_CHOLMOD(copy_dense)( CHM_DN, CHM_CM); R_MATRIX_INLINE CHM_FR R_MATRIX_CHOLMOD(copy_factor)( CHM_FR, CHM_CM); R_MATRIX_INLINE CHM_SP R_MATRIX_CHOLMOD(copy_sparse)( CHM_SP, CHM_CM); R_MATRIX_INLINE int R_MATRIX_CHOLMOD(defaults)( CHM_CM); R_MATRIX_INLINE CHM_SP R_MATRIX_CHOLMOD(dense_to_sparse)( CHM_DN, int, CHM_CM); R_MATRIX_INLINE void R_MATRIX_CHOLMOD(error_handler)( int, const char *, int, const char *); R_MATRIX_INLINE CHM_SP R_MATRIX_CHOLMOD(factor_to_sparse )( CHM_FR, CHM_CM); R_MATRIX_INLINE int R_MATRIX_CHOLMOD(factorize)( CHM_SP, CHM_FR, CHM_CM); R_MATRIX_INLINE int R_MATRIX_CHOLMOD(factorize_p)( CHM_SP, double[2], int *, size_t, CHM_FR, CHM_CM); R_MATRIX_INLINE int R_MATRIX_CHOLMOD(finish)( CHM_CM); R_MATRIX_INLINE int R_MATRIX_CHOLMOD(free_dense)( CHM_DN *, CHM_CM); R_MATRIX_INLINE int R_MATRIX_CHOLMOD(free_factor)( CHM_FR *, CHM_CM); R_MATRIX_INLINE int R_MATRIX_CHOLMOD(free_sparse)( CHM_SP *, CHM_CM); R_MATRIX_INLINE int R_MATRIX_CHOLMOD(free_triplet)( CHM_TR *, CHM_CM); R_MATRIX_INLINE int R_MATRIX_CHOLMOD(nnz)( CHM_SP, CHM_CM); R_MATRIX_INLINE int R_MATRIX_CHOLMOD(scale)( CHM_DN, int, CHM_SP, CHM_CM); R_MATRIX_INLINE int R_MATRIX_CHOLMOD(sdmult)( CHM_SP, int, double[2], double[2], CHM_DN, CHM_DN, CHM_CM); R_MATRIX_INLINE CHM_DN R_MATRIX_CHOLMOD(solve)( int, CHM_FR, CHM_DN, CHM_CM); R_MATRIX_INLINE int R_MATRIX_CHOLMOD(solve2)( int, CHM_FR, CHM_DN, CHM_DN *, CHM_DN *, CHM_DN *, CHM_CM); R_MATRIX_INLINE int R_MATRIX_CHOLMOD(sort)( CHM_SP, CHM_CM); R_MATRIX_INLINE CHM_DN R_MATRIX_CHOLMOD(sparse_to_dense)( CHM_SP, CHM_CM); R_MATRIX_INLINE CHM_TR R_MATRIX_CHOLMOD(sparse_to_triplet)( CHM_SP, CHM_CM); R_MATRIX_INLINE CHM_SP R_MATRIX_CHOLMOD(speye)( size_t, size_t, int, CHM_CM); R_MATRIX_INLINE CHM_SP R_MATRIX_CHOLMOD(spsolve)( int, CHM_FR, CHM_SP, CHM_CM); R_MATRIX_INLINE CHM_SP R_MATRIX_CHOLMOD(ssmult)( CHM_SP, CHM_SP, int, int, int, CHM_CM); R_MATRIX_INLINE int R_MATRIX_CHOLMOD(start)( CHM_CM); R_MATRIX_INLINE CHM_SP R_MATRIX_CHOLMOD(submatrix)( CHM_SP, int *, int, int *, int, int, int, CHM_CM); R_MATRIX_INLINE CHM_SP R_MATRIX_CHOLMOD(transpose)( CHM_SP, int, CHM_CM); R_MATRIX_INLINE CHM_SP R_MATRIX_CHOLMOD(triplet_to_sparse)( CHM_TR, int, CHM_CM); R_MATRIX_INLINE int R_MATRIX_CHOLMOD(updown)( int, CHM_SP, CHM_FR, CHM_CM); R_MATRIX_INLINE CHM_SP R_MATRIX_CHOLMOD(vertcat)( CHM_SP, CHM_SP, int, CHM_CM); /* <<<< Matrix <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ #ifdef __cplusplus } #endif #endif /* R_MATRIX_CHOLMOD_H */ Matrix/inst/include/Matrix/version.h0000644000176200001440000000123614532153466017233 0ustar liggesusers#ifndef R_MATRIX_VERSION_H #define R_MATRIX_VERSION_H /* Users wanting to do version comparison will include Rversion.h then do, */ /* e.g., R_MATRIX_PACKAGE_VERSION R_version(major, minor, patch) : */ /* (version)_{10} = (major minor patch)_{256} */ #define R_MATRIX_PACKAGE_VERSION 67077 #define R_MATRIX_PACKAGE_MAJOR 1 #define R_MATRIX_PACKAGE_MINOR 6 #define R_MATRIX_PACKAGE_PATCH 5 #define R_MATRIX_ABI_VERSION 1 /* (version)_{10} = (major minor patch)_{256} */ #define R_MATRIX_SUITESPARSE_VERSION 330241 #define R_MATRIX_SUITESPARSE_MAJOR 5 #define R_MATRIX_SUITESPARSE_MINOR 10 #define R_MATRIX_SUITESPARSE_PATCH 1 #endif /* R_MATRIX_VERSION_H */ Matrix/inst/include/Matrix/cholmod-utils.h0000644000176200001440000000211214531175657020330 0ustar liggesusers#ifndef R_MATRIX_CHOLMOD_UTILS_H #define R_MATRIX_CHOLMOD_UTILS_H #include #include "cholmod.h" #ifdef __cplusplus extern "C" { #endif #ifndef R_MATRIX_INLINE # define R_MATRIX_INLINE #endif R_MATRIX_INLINE CHM_FR M_sexp_as_cholmod_factor( CHM_FR, SEXP); R_MATRIX_INLINE CHM_SP M_sexp_as_cholmod_sparse( CHM_SP, SEXP, Rboolean, Rboolean); R_MATRIX_INLINE CHM_TR M_sexp_as_cholmod_triplet( CHM_TR, SEXP, Rboolean); R_MATRIX_INLINE CHM_DN M_sexp_as_cholmod_dense( CHM_DN, SEXP); R_MATRIX_INLINE CHM_DN M_numeric_as_cholmod_dense( CHM_DN, double *, int, int); R_MATRIX_INLINE SEXP M_cholmod_factor_as_sexp( CHM_FR, int); R_MATRIX_INLINE SEXP M_cholmod_sparse_as_sexp( CHM_SP, int, int, int, const char *, SEXP); R_MATRIX_INLINE SEXP M_cholmod_triplet_as_sexp( CHM_TR, int, int, int, const char *, SEXP); R_MATRIX_INLINE SEXP M_cholmod_dense_as_sexp( CHM_DN, int); R_MATRIX_INLINE double M_cholmod_factor_ldetA( CHM_FR); R_MATRIX_INLINE CHM_FR M_cholmod_factor_update( CHM_FR, CHM_SP, double); #ifdef __cplusplus } #endif #endif /* R_MATRIX_CHOLMOD_UTILS_H */ Matrix/inst/include/Matrix/remap.h0000644000176200001440000000115314531175657016655 0ustar liggesusers#ifndef R_MATRIX_REMAP_H #define R_MATRIX_REMAP_H /* MJ: backwards compatibility with Matrix < 1.6-2 */ #define M_as_cholmod_sparse M_sexp_as_cholmod_sparse #define M_as_cholmod_dense M_sexp_as_cholmod_dense #define M_chm_factor_to_SEXP M_cholmod_factor_as_sexp #define M_chm_sparse_to_SEXP M_cholmod_sparse_as_sexp #define M_chm_triplet_to_SEXP M_cholmod_triplet_as_sexp #define M_chm_factor_ldetL2 M_cholmod_factor_ldetA #define M_chm_factor_update M_cholmod_factor_update #define M_R_cholmod_error M_cholmod_error_handler #define M_R_cholmod_start M_cholmod_start #endif /* R_MATRIX_REMAP_H */ Matrix/inst/include/Matrix/alloca.h0000644000176200001440000000240714510651525016775 0ustar liggesusers#ifndef R_MATRIX_ALLOCA_H #define R_MATRIX_ALLOCA_H /* MJ: alloca-using macros (currently opt-out, eventually opt-in) */ /* Copy and paste from Defn.h : */ /* 'alloca' is neither C99 nor POSIX */ #ifdef __GNUC__ /* This covers GNU, Clang and Intel compilers */ /* #undef needed in case some other header, e.g. malloc.h, already did this */ # undef alloca # define alloca(x) __builtin_alloca((x)) #else # ifdef HAVE_ALLOCA_H /* This covers native compilers on Solaris and AIX */ # include # endif /* It might have been defined via some other standard header, e.g. stdlib.h */ # if !HAVE_DECL_ALLOCA extern void *alloca(size_t); # endif #endif #define AS_CHM_FR(x) \ M_sexp_as_cholmod_factor((CHM_FR) alloca(sizeof(cholmod_factor)), x) #define AS_CHM_SP(x) \ M_sexp_as_cholmod_sparse((CHM_SP) alloca(sizeof(cholmod_sparse)), x, \ (Rboolean) 1, (Rboolean) 0) #define AS_CHM_SP__(x) \ M_sexp_as_cholmod_sparse((CHM_SP) alloca(sizeof(cholmod_sparse)), x, \ (Rboolean) 0, (Rboolean) 0) #define AS_CHM_DN(x) \ M_sexp_as_cholmod_dense ((CHM_DN) alloca(sizeof(cholmod_dense )), x) #define N_AS_CHM_DN(x, m, n) \ M_numeric_as_cholmod_dense((CHM_DN) alloca(sizeof(cholmod_dense)), x, m, n) #endif /* R_MATRIX_ALLOCA_H */ Matrix/inst/include/Matrix_stubs.c0000644000176200001440000000033114511523670016747 0ustar liggesusers/* For backwards compatibility only. Packages should start using */ /* LinkingTo: Matrix (>= 1.6-2) and #include . */ #include "Matrix/alloca.h" #include "Matrix/remap.h" #include "Matrix/stubs.c" Matrix/inst/external/0000755000176200001440000000000014547723665014340 5ustar liggesusersMatrix/inst/external/utm300.rua0000644000176200001440000024553510275433311016073 0ustar liggesusersUTM300 UTM300 1290 16 122 1052 100 RUA 300 300 3155 1 (20I4) (26I3) (3D21.15) (3D21.15) FNN 1 1 3 9 13 17 20 22 28 32 36 44 46 52 56 60 68 69 70 72 74 82 83 84 86 88 96 97 98 100 102 110 111 112 114 116 124 126 132 136 140 148 150 156 160 164 172 174 178 182 186 189 191 196 201 208 217 225 242 257 279 297 306 324 339 355 374 382 399 415 431 451 458 475 491 511 531 538 555 571 591 611 619 637 653 669 689 697 714 729 744 763 771 775 790 812 831 833 837 842 849 858 860 865 870 877 886 895 912 928 950 970 979 9971013103110511060107710931111 11311140115711731195121512241241125712791299130813261342136013801389140614221440 14601469147314891511153115331537154215491558156015651570157715861594161116271649 16691677169417101732175217611778179418161836184518621878190019201929194619621984 20042013203020462068208820972114213021522172218021842200222222422244224822532260 22692271227622812288229723052322233723592379238724042419244124612470248725022524 25442553257025852607262726362653266826902710271927362751277327922800281728322854 28742883288729022924294329452949295429612970297229782980298229852987299329952997 30053007301330153017302530273033303530373045304730533055305730653067307330753077 30853087309330953097310431063112311431163124312631323134313631433145314931513153 3156 1 51 1 2 6 51 52 56 1 3 51 53 1 4 51 54 5 10 55 6 56 6 7 11 56 57 61 6 8 56 58 6 9 56 59 6 8 9 10 56 58 59 60 11 61 11 12 36 61 62 86 11 13 61 63 11 14 61 64 11 13 14 15 61 63 64 65 16 17 16 18 16 19 16 18 19 20 66 68 69 70 21 22 21 23 21 24 21 23 24 25 71 73 74 75 26 27 26 28 26 29 26 28 29 30 76 78 79 80 31 32 31 33 31 34 31 33 34 35 81 83 84 85 36 86 36 37 41 86 87 91 36 38 86 88 36 39 86 89 36 38 39 40 86 88 89 90 41 91 41 42 46 91 92 96 41 43 91 93 41 44 91 94 41 43 44 45 91 93 94 95 46 96 46 47 96 97 46 48 96 98 46 49 96 99 45 50100 51 56 51 52 53 54 56 51 52 53 56 58 51 52 54 56 57 59 61 51 52 53 54 55 56 58 59 60 6 51 52 56 57 58 60106 6 7 11 51 52 56 57 58 59 61 62 63 64 86106107111 6 8 51 52 53 56 57 58 59 60 61 63106108109 1 2 6 7 9 11 51 52 54 56 57 58 59 60 61 64101102106107109111 6 9 10 51 54 55 56 58 59 60 61 63 64 65106108109110 11 56 57 61 62 63 65 86111 11 12 36 56 57 61 62 63 64 86 87 88 89 91111112116136 11 13 56 57 58 61 62 63 64 65 86 88111113114 6 7 11 14 56 57 59 61 62 63 64 65 86 89111114 11 14 15 56 58 59 60 61 63 64 65 86 88 89 90111113114115 16 66 67 68 70 81 82116 16 17 21 66 67 68 69 71 72 73 74 76 81 82116117121 16 18 19 66 67 68 69 70 71 73 81 82 83116118119 16 17 19 32 66 67 68 69 70 71 74 81 82 84116119 16 18 19 20 66 68 69 70 71 73 74 75 81 83 84 85116118119120 21 67 71 72 73 75121 21 22 26 66 67 71 72 73 74 76 77 78 79 81121122126 21 23 24 66 67 68 71 72 73 74 75 76 78121123124 17 21 22 24 66 67 69 71 72 73 74 75 76 79116117121122124126 21 23 24 25 66 68 69 70 71 73 74 75 76 78 79 80121123124125 26 72 76 77 78 80126 26 27 31 66 71 72 76 77 78 79 81 82 83 84126127131 26 28 29 71 72 73 76 77 78 79 80 81 83126128129 22 26 27 29 71 72 74 76 77 78 79 80 81 84121122126127129131 26 28 29 30 71 73 74 75 76 78 79 80 81 83 84 85126128129130 31 66 77 81 82 83 85131 16 31 32 66 67 68 69 71 76 77 81 82 83 84116131132136 31 33 34 66 68 76 77 78 81 82 83 84 85131 133134 27 31 32 34 66 69 76 77 79 81 82 83 84 85131134 31 33 34 35 66 68 69 70 76 78 79 80 81 83 84 85131133134135 36 61 62 86 87 88 90136 36 37 41 61 62 86 87 88 89 91 92 93 94 96136137141 36 38 61 62 63 86 87 88 89 90 91 93136138139 36 37 39 61 62 64 86 87 88 89 90 91 94136139 36 39 40 61 63 64 65 86 88 89 90 91 93 94 95136138139140 41 86 87 91 92 93 95141 91 92 96 97 41 43 86 87 88 91 92 93 94 95 96 98141143144 36 37 41 42 44 46 86 87 89 91 92 93 94 95 96 99136 137141142144146 41 44 45 86 88 89 90 91 93 94 95 96 98 99100141143144145 91 96 96 97 98 99 91 92 93 96 98 86 87 91 92 94 96 99 91 92 93 94 95 96 98 99100101 106101102103104106101102103106108101102104106107109111101102103104105106108109 110 56101102106107108110111156 56 57 61101102106107108109111112113114116156157 161 56 58 59101102103106107108109110111113156158159 51 52 56 57 59 61101102104 106107108109110111114151152156157159161 56 58 59 60101103104105106108109110111 113114115156158159160 61106107111112113115116161 61 62 86106107111112113114116 117118119121136161162166 61 63 64106107108111112113114115116118161163164 61 64 106107109111112113114115116119156157161162164166 61 63 64 65106108109110111113 114115116118119120161163164165 66111112116117118120121166 66 67 71111112116117 118119121122123124126166167171 66 68 69111112113116117118119120121123166168169 66 69111112114116117118119120121124161162166167169171 66 68 69 70111113114115 116118119120121123124125166168169170 71116117121122123125126171 71 72 76116117 121122123124126127128129131171172176 71 73 74116117118121122123124125126128171 173174 66 67 71 72 74 76116117119121122123124125126129166167171172174176 71 73 74 75116118119120121123124125126128129130171173174175 76121122126127128130131 176 76 77 81121122126127128129131132133134136176177181 76 78 79121122123126127 128129130131133176178179 71 72 76 77 79 81121122124126127128129130131134171172 176177179181 76 78 79 80121123124125126128129130131133134135176178179180 81126 127131132133135136181 66 81 82116126127131132133134136137138139141181182186 81 83 84126127128131132133134135136138181183184 81 84126127129131132133134135136 139176177181182184186 81 83 84 85126128129130131133134135136138139140181183184 185 86131132136137138140141186 86 87 91131132136137138139141142143144146186187 191 86 88 89131132133136137138139140141143186188189 86 89131132134136137138139 140141144181182186187189191 86 88 89 90131133134135136138139140141143144145186 188189190 91136137141142143145146191141142146147 91 93 94136137138141142143144 145146148191193194 86 87 91 92 94 96136137139141142143144145146149186187191192 194196 91 93 94 95136138139140141143144145146148149150191193194195141146146147 148149141142143146148136137141142144146149141142143144145146148149150151156151 152153154156151152153156158151152154156157159161151152153154155156158159160106 151152156157158160206106107111151152156157158159161162163164166206207211106108 109151152153156157158159160161163206208209101102106107109111151152154156157158 159160161164201202206207209211106108109110151153154155156158159160161163164165 206208209210111157161162163165166211111112116156157161162163164166167168169171 211212216111113114156157158161162163164165166168211213214106107111112114116156 157159161162163164165166169206207211212214216111113114115156158159160161163164 165166168169170211213214215116161162166167168170171216116117121161162166167168 169171172173174176216217221116118119161162163166167168169170171173216218219111 112116117119121161162164166167168169170171174211212216217219221116118119120161 163164165166168169170171173174175216218219220121166167171172173175176221121122 126166167171172173174176177178179181221222226121123124166167168171172173174175 176178221223224116117121122124126166167169171172173174175176179216217221222224 226121123124125166168169170171173174175176178179180221223224225126171172176177 178180181226126127131171172176177178179181182183184186226227231126128129171172 173176177178179180181183226228229121122126127129131171172174176177178179180181 184221222226227229231126128129130171173174175176178179180181183184185226228229 230131176177181182183185186231131132136176177181182183184186187188189191231232 236131133134176177178181182183184185186188231233234126127131132134136176177179 181182183184185186189226227231232234236131133134135176178179180181183184185186 188189190231233234235136181182186187188190191236136137141181182186187188189191 192193194196236237241136138139181182183186187188189190191193236238239131132136 137139141181182184186187188189190191194231232236237239241136138139140181183184 185186188189190191193194195236238239240141186187191192193195241191192196197141 143144186187188191192193194195196198241243244136137141142144146186187189191192 193194195196199236237241242244246141143144145186188189190191193194195196198199 200241243244245191196196197198199191192193196198186187191192194196199191192193 194195196198199200201206201202203204206201202203206208201202204206207209211201 202203204205206208209210156202206207208210211256156157161201202206207208209211 212213214216256257261156158159201202203206207208209210211213256258151152156157 159161201202204206207208209210211214251252256257259261156158159160201203204205 206208209210211213214215256258259260161207211212213215216261161162166206207211 212213214216217218219221261262266161163164206207208211212213214215216218261263 156157161162164166206207209211212213214215216219256257261262264266161163164165 206208209210211213214215216218219220261263264265166211212216217218220221266166 167171211212216217218219221222223224226266267271166168169211212213216217218219 220221223266268161162166167169171211212214216217218219220221224261262266267269 271166168169170211213214215216218219220221223224225266268269270171216217221222 223225226271171172176216217221222223224226227228229231271272276171173174216217 218221222223224225226228271273166167171172174176216217219221222223224225226229 266267271272274276171173174175216218219220221223224225226228229230271273274275 176221222226227228230231276176177181221222226227228229231232233234236276277281 176178179221222223226227228229230231233276278171172176177179181221222224226227 228229230231234271272276277279281176178179180221223224225226228229230231233234 235276278279280181226227231232233235236281181182186226227231232233234236237238 239241281282286181183184226227228231232233234235236238281283176177181182184186 226227229231232233234235236239276277281282284286181183184185226228229230231233 234235236238239240281284285186231232236237238240286186187191231232236237238239 241242243244246286287291186188189231232233236237238239240241243286288181182186 187189191231232234236237238239240241244281282286287289291186188189190231233234 235236238239240241243244245286288289290191236237241242243245246291241242246247 191193194236237238241242243244245246248291293186187191192194196236237239241242 243244245246249286287291292294296191193194195236238239240241243244245246248249 250291294295241246246247248249241242243246248236237241242244246249241242243244 245246248249250201251201202206251252256251253251254205255260206256206207211256 257261256258256259206208209210256258259260211261211212216261262266261263261264 211213214215261263264265216266216217221266267271266268266269216218219220266268 269270221271221222226271272276271273271274221223224225271273274275226276226227 231276277281276278276279226228229230276278279280231281231232236281282286281283 281284231233234235281284285236286236237241286287291286288286289236238239240286 288289290241291241242246291292296291293291294241243244245291294295246296246247 296297296298296299250295300 -.707106816579618E+000.707106745793467E+00-.844334130890272E-01 -.696951911168316E+00-.844334130890552E-010.844333971430866E-01 0.696951959550198E+000.844333971430866E-010.169379293548785E-01 -.706903887803993E+00-.169379269811943E-010.706903887799719E+00 0.245538507221060E-01-.706680324381466E+00-.245538469074249E-01 0.706680363494609E+00-.816418512372678E+000.416234647777442E+00 0.400261827613855E+00-.707106816579739E+000.707106745793357E+00 -.692246657276026E-01-.700297003669988E+00-.692246686484270E-01 0.692246561667109E-010.700297003664129E+000.692246429669856E-01 0.201259425073776E-01-.706820307066788E+00-.201259404946509E-01 0.706820307062134E+000.247547275541103E-01-.706673335798275E+00 -.247547250784765E-010.706673335793667E+000.244951179721711E-01 0.141798045683355E-19-.699515386900931E+00-.100390257306135E+00 -.244951125432383E-010.403797585699602E-130.699515399846145E+00 0.100390257306048E+00-.707106840518851E+000.707106721854245E+00 -.132398684210425E-02-.707104302076665E+00-.132398682112846E-02 0.132398661033321E-020.707104302222497E+000.132398652689601E-02 0.251871166539414E-01-.706658056811822E+00-.251871127758866E-01 0.706658056805146E+000.264048027660490E-01-.706613622993380E+00 -.264047987662912E-010.706613586618012E+000.250107227346610E-01 0.259324348882091E-18-.669582765977545E+00-.225905619309715E+00 -.250107188007798E-010.166054197615496E-120.669582814615445E+00 0.225905627940471E+00-.999999999999996E+00-.100000000000000E+01 0.707106751263410E+00-.707106811109693E+000.707106751263400E+00 -.707106811109696E+000.594184615923025E-04-.522534802243499E-12 -.594354881940039E-04-.764126330976698E+00-.654895649435869E-04 -.555850754291422E-100.775951072359707E-040.645066611238772E+00 -.999999999999996E+00-.100000000000000E+010.707106751263410E+00 -.707106811109693E+000.707106751263407E+00-.707106811109700E+00 0.265041818209181E-04-.508541053041430E-12-.265118042346652E-04 -.757862392871900E+00-.311410747072004E-04-.431724688636464E-10 0.361816791523382E-040.652414431007056E+00-.999999999999996E+00 -.100000000000000E+010.707106751263410E+00-.707106811109693E+00 0.707106794782394E+00-.707106767590709E+000.247298538585594E-04 0.173057137779142E-12-.247369664563574E-04-.758133034802306E+00 -.288203567500599E-04-.373198365066270E-100.335135601768647E-04 0.652099914402839E+00-.999999999999996E+00-.100000000000000E+01 0.707106751263410E+00-.707106811109693E+000.707106773022893E+00 -.707106789350199E+000.526001426328733E-04-.686257777907160E-12 -.526151918089806E-04-.763904838719903E+00-.579153207211495E-04 -.480634147895882E-100.685730564085902E-040.645328895826580E+00 -.707106816579021E+000.707106745794075E+000.907453690126752E-01 -.695363616933204E+000.907453584845728E-01-.907453530938325E-01 0.695363616931083E+00-.907453541634382E-010.388412996851262E-01 -.706039176488765E+00-.388412958008106E-010.706039225852471E+00 0.405384669021764E-01-.705943788823106E+00-.405384601326821E-01 0.705943788819880E+000.374910477226837E-010.836910668696327E-19 -.653009130497729E+00-.268651354886250E+00-.374910441557599E-01 0.139197855810201E-120.653009053988256E+000.268651341635424E+00 -.707106816577767E+000.707106745795336E+000.110699028877342E+00 -.689558863568468E+000.110699028877342E+00-.110699023342189E+00 0.689558899694259E+00-.110699023342207E+000.353901421432703E-01 -.706220615039452E+00-.353901386042155E-010.706220587934077E+00 0.400455576932894E-01-.705971921162636E+00-.400455536886817E-01 0.705971921161698E+000.397033469335430E-010.518711104785870E-19 -.700067560303143E+00-.912639778518622E-01-.397033514193168E-01 0.669670689866494E-130.700067476628409E+000.912639778518489E-01 -.707106816577706E+000.707106745795397E+000.216163600604371E+00 -.673255732353994E+00-.216163567662612E+000.673255767625957E+00 0.343171978221466E-01-.706273565834579E+00-.343171943903884E-01 0.706273537877586E+000.384789098875664E-01-.706059044020112E+00 -.384789060396264E-010.706059044019181E+000.428340687803781E+00 -.816002001388647E+000.388155882219383E+00-.707106781186546E+00 0.707106781186546E+000.919164088258896E-12-.323903147050126E+00 -.668411207904565E+00-.668411136933422E+00-.392397821342358E-01 0.126741961371568E-010.848341585451701E-02-.686488249101334E+00 -.164737403383030E-010.726794259837522E+000.253811998949423E-01 0.427304877010395E-02-.713017416797165E+00-.242972297547323E-01 -.379326587583946E-020.700241968358579E+00-.374966055507997E-03 0.244954510496371E-01-.107305914771803E-020.854576884136081E-09 -.704999716109445E+00-.101177314154959E+00-.240417637527367E-01 0.106896353468138E-020.693652910717219E+000.101999329282549E+00 0.369802367784965E-02-.998478946766033E-080.628213615438288E+00 -.111695501554557E-01-.639775962557707E+000.441805243310407E+00 0.264916681259199E-010.150179388402961E-02-.323621717853948E-03 0.878267323059556E-020.250020432185017E-03-.492283767812116E-02 -.406353565923736E-010.234750587315863E-02-.173455232422632E+00 0.500624797585161E+000.467986775089445E+00-.171309845650195E-01 0.108659111149954E+00-.500624772325725E+00-.485548310627230E+00 0.203453546805473E-030.924723892346221E-040.596021551608855E-02 0.144977252778252E-030.727990528604067E-040.170446169406913E-02 -.713900928598815E-020.219802264290567E-010.370608562041904E+00 0.207893595583177E-01-.258848244250827E-01-.903242099366874E+00 0.922248994905455E-01-.305257817801369E-02-.700818827730815E-02 0.191302757843644E+000.148579185954640E-040.171121650781410E-02 0.486934889722714E-030.150620182701511E-040.124328766057256E-03 0.239016721169981E-030.115323810912666E-030.404520413743159E-02 0.113998101983268E-04-.207057801906026E-020.590390599498483E-01 0.229989382973123E+000.126638864121696E-01-.636607683510642E-01 0.320190435990360E+00-.860187903320348E+000.144893930539319E-02 -.120356442673852E-010.311102756171715E+00-.160900125595186E-05 -.788680156986552E-05-.220582013341250E-04-.808877643315356E-05 0.290559263145904E-02-.124362898928145E-05-.455696078386797E-02 0.130134687021089E+000.186761496719130E-01-.209760100786787E-01 0.603707240598609E+000.866404279134079E-010.268410288213005E-01 -.160761288050858E-02-.771455917360623E+00-.118795008750806E+00 0.233433259368892E-030.357198977531906E-020.125468663142325E-01 0.105518298214813E-01-.219409073721873E-03-.516770485999043E-03 0.155737420002396E-020.475170697294222E-020.375437524196078E-02 0.125599035320910E-080.160955314931229E+00-.223800543931700E-01 -.167424614451373E+000.958946814478864E+000.161130765277663E+00 0.196534771283384E-030.229515992283831E-020.576258431242573E-05 0.123745953025444E-01-.106995672755502E-04-.451052406900802E-04 -.456298622807265E-03-.275196027305474E-03-.305282850369034E+00 0.519423576775914E+000.505241937641198E+00-.130908849130573E-01 0.201635085589468E-01-.519423633116087E+00-.333293227117524E+00 -.263134929283539E-020.118328199171819E-030.104150622740462E-01 0.193141117505181E-03-.154345791282011E-030.173868931704905E-03 0.325208290050746E-02-.373216687782401E-030.149265726829690E-01 0.635804228599679E-010.820369767656903E-02-.212632332341540E-01 -.863649530175426E+000.489006964790317E+00-.348933539662262E-01 -.515727866020910E-020.944324418994364E-010.774875938152194E-04 0.482971314170869E-020.112759618007829E-020.222168874154256E-11 -.469066568608033E-100.220035735034216E-030.392555412688333E-02 0.141255360917606E-030.174989934363485E-010.515531740150388E-01 -.461588326613025E-03-.250983472579693E-010.684732202756503E+00 -.726228124582573E+000.842387322611238E-02-.317841553099293E-03 0.582455539039689E-02-.217823676656004E-040.446878338884266E-02 -.200617977872690E-010.537091052490130E+000.181205202614563E+00 -.379058590472633E-02-.114631325054326E-020.100346775148016E+00 0.271648560515299E-010.259196853345346E-01-.272445450180131E-01 -.728159919978982E+00-.314123286436018E+00-.938624176704406E-02 -.362203896936131E-020.153775041043447E+000.781378322348654E-01 0.426720954014265E-030.112760204809835E-02-.167938108847192E-02 0.854993026183699E-010.457577468747559E-03-.644980511474331E-03 -.215375382943762E-020.354875964291731E-050.999992692546311E+00 0.164898274978811E-070.304934046331858E-020.228760962681150E-03 -.247128995183060E-100.118007080764899E+00-.123564497591530E-09 0.162728422837746E-01-.819861260960444E+000.141941206609466E+00 0.125775224074353E+000.393535557751079E-020.178021559472064E+00 -.141941215640452E+00-.147146706681122E+000.753144190049640E-03 0.236859750590249E-020.447439294418169E+000.359129436315990E-02 0.627754930398190E-01-.139244701906877E-020.214783034756772E-03 0.131512191293389E-030.124438240310255E-040.487697648747908E+00 -.148174054632193E-02-.535785553537011E+000.309890918116741E-03 -.688115252161152E-01-.283340125674097E-010.310257496437506E-01 -.461205326885983E+000.191293743934847E-020.505833990447865E+00 0.750983511657879E-040.705267092317584E-04-.786060719406271E-05 0.565417053429881E-020.369600487362671E-040.443122584382949E-02 0.369600487362671E-040.389809678124690E+00-.480919973513487E-01 0.104050264453308E-01-.489891790728507E+000.512175326664710E+00 -.251878239510859E-010.293966079442228E-01-.374941991066111E+00 0.641782125495638E-010.443884509856657E+000.415631588510590E-02 0.291724739467156E-02-.315602200752062E-040.276258179505761E-12 0.315692669405107E-040.405867061011481E+000.378690131926348E-04 -.918882285479390E-06-.585087468913459E-04-.901978941696008E+00 0.113474779210659E-090.132088859541395E-090.452016593238905E-08 0.153981616917685E-03-.187604508266648E-060.449094630629618E-09 0.238044864556349E-060.236695170296057E-02-.429542502073789E-04 -.134103249836867E-040.103819281934490E-030.147310120826308E+00 0.289572954091881E-010.166544091372661E-01-.414623249348314E-01 -.271830205766233E-01-.834413463006351E-060.998136392031476E+00 0.122395916553052E-010.632739099986892E-090.212633687143486E+00 0.632739099986892E-09-.110266703181475E-030.137411102806595E+00 -.541373056555355E-02-.813199727026674E+000.185364035933384E+00 0.189529013238867E+000.865340666265890E-020.342605965282138E+00 -.185364035366044E+00-.194177150813847E+000.294623504846971E-02 -.481686497086705E-030.121545876488085E+00-.530804639167663E-03 0.456286581451462E-020.286575521807902E-020.404296415827950E-03 -.687084666871018E-010.346805266614458E-020.753574515516031E-01 0.505627623174092E+00-.574252270940695E-02-.564511679616764E+00 -.357473139901688E-04-.231037907805869E-01-.434238694510366E+00 0.475492620831160E+000.115770063050651E-020.134140728510668E-02 -.263260049701307E-030.105471222881001E-020.116593856850648E+00 0.105471222881001E-020.922493324714324E-01-.579437302697594E-01 0.121570291545597E+000.685873943808266E-010.273378233184083E+00 -.204837707484476E+000.360576001215734E-02-.677988803582434E+00 0.173174484916547E+00-.380656063886276E+000.442368547231428E+00 -.558513583720547E-04-.823757328985934E-030.669330729666884E-01 -.959833802074539E-030.601389213056274E-010.962184060000759E-05 -.187827323783031E-040.360387968584401E-120.187881360370489E-04 0.537074764821504E+00-.241847150836626E-08-.239399430153665E-10 0.201204711161572E-080.245123711639579E-040.343859473382981E-04 0.142820901368339E-07-.395427510919049E-04-.803141296002529E+00 -.308798916471791E-080.372565513480860E-110.372134699667619E-08 0.695751722977721E-04-.206823361952197E-04-.867594640014316E-07 0.320490380387678E-040.257904527488446E+000.251527713105688E-01 0.160670486494815E-01-.359427383128825E-01-.208315603223150E-01 -.106749103877009E-050.998634620717329E+000.105947158447703E-01 0.786357166775589E-090.644554062825855E-010.147441968768947E-09 0.283415543445799E-020.685059169690794E-030.161928254063469E+00 -.734658112367259E-02-.795436981644603E+000.112005113951728E+00 0.116112410074604E+00-.122748344137133E-010.535385505713645E+00 -.112005114710728E+00-.101694000626255E+000.376112318286562E-03 0.337223222160585E-01-.160461773121821E-020.572257030714030E-02 0.358983271090535E-020.483648722770236E-03-.374378469350919E+00 0.491681099797348E-020.409889093974485E+000.530964917213129E+00 -.627250620485439E-02-.595098741464305E+00-.241170615534876E-04 -.334285861829879E-01-.157354286153396E+000.172548982335806E+00 0.149808311102240E-020.164824307470865E-02-.307153539074260E-03 -.106756314785166E-020.139626387190351E+00-.106756314785166E-02 0.110156897634196E+00-.309911159440874E+000.167408292491309E+00 0.360213501196167E+000.241963975861273E+00-.208694806147609E+00 0.493267448076731E-02-.709971239067276E+000.237100559219863E+00 -.131217716617825E+000.154290771975884E+00-.959074851003528E-05 0.956731538415544E-030.794297126275660E-010.783541617392965E-03 0.693456870140263E-01-.453325254228497E-04-.176585350383745E-04 -.123562725125358E-120.176636156078052E-040.541350527616704E+00 -.240773125362821E-08-.233457660732528E-110.271455532902927E-08 0.477531482574202E-040.318748202945685E-040.168773004647976E-07 -.366100077933934E-04-.802382883088274E+00-.189243713536815E-08 -.175937555189488E-100.161357154454997E-080.220750984082187E-04 -.182827311837541E-04-.810192048052132E-070.287394278084876E-04 0.251239543599436E+000.460154655563629E-030.109020541892817E-07 0.301020760096669E-02-.676020538863894E-03-.201397582313553E-02 0.265255685432536E-050.999993076694352E+000.245686508966199E-03 0.528725086162795E-100.528725086162795E-100.139137638304773E-01 -.931476122820135E-020.187667088561186E+00-.806168464489319E-01 -.741318518217202E-01-.150594948497854E-030.496927937442151E-02 0.577857814421090E+000.106703220081005E-01-.779133836752166E+00 0.806168453826879E-010.695241882699640E-01-.515203579148082E-04 -.229418112929880E-030.809403648149187E-02-.283211984912348E-03 0.309218219416329E-030.189421944285213E-030.177162332103893E-04 -.436862641845423E+000.479152582846512E+00-.712381219969140E-01 0.294435744654024E-020.780917998203279E-010.502921115640390E+00 -.181070913767124E-02-.552926222784265E+000.443750531523610E-03 -.985965310703518E-010.118852928374641E-030.109862679157740E-03 -.109006539468286E-040.144672961940265E-030.716786890076843E-02 0.144672961940265E-030.561128618870810E-02-.311695309851634E+00 0.369140461343607E+00-.564818818963682E-010.843996016463362E-01 0.683479449787785E-010.353180746937538E+00-.525397161080030E-01 0.131036844385976E-01-.456640065049356E+000.644420456556119E+00 0.559396888735261E-020.394650581663461E-02-.276030758828090E-04 0.359262044720999E-120.276109760275352E-040.400875800538385E+00 -.153565440406287E-06-.284270058405151E-090.171772862729932E-06 0.153454876917201E-02-.233754388154802E-090.978810924525225E-10 0.373622626632746E-080.130985708337576E-030.345983153605038E-04 -.692008542158418E-06-.515924281953249E-04-.901011303111012E+00 -.327069748284931E-04-.724156296312873E-050.719917974521585E-04 0.165755363482073E+000.474803594620760E-020.116474496930673E-03 0.161427927008894E+00-.319233613834862E-01-.199249049476415E+00 0.943952542138753E+000.205279273142504E+000.363324353033546E-02 -.108482676139213E-020.157536226523168E-010.130255045013827E-02 0.301913162646137E-030.161243332301578E+000.606695718965107E-01 -.397526540444055E+000.554748860175678E+000.383966542560385E+00 -.236530864243820E-010.493155556414269E-01-.554748767500591E+00 -.214301755749183E+00-.791692179238457E-02-.552245530472999E-03 0.117804913038090E-010.534077055607152E-040.359651953275203E-03 0.435838693521165E-020.413002012631367E-030.215005754443115E-01 -.121296060755018E-010.287291230583004E-01-.295083695975163E-01 -.936024399941001E+000.150963209808127E+00-.471083210162908E-01 -.930017973181041E-020.310435446284620E+000.200383312665818E-03 0.797662512256087E-020.202677154721335E-020.821695118252034E-03 0.185995596284431E-090.953942751065062E-020.579222037124909E-04 0.419784017723221E-01-.482975532332040E-030.904470811910962E-02 -.574430934800443E-010.451700983218531E+00-.847632099722912E+00 0.206216564248354E-01-.952089249595826E-030.267683914514290E+00 -.442089263297538E-040.130227346463139E-01-.334575236633050E-01 0.582754336569465E+000.239748154997497E+00-.232703116519158E-02 0.632586030004597E-030.656015033332231E-010.269019293740100E-01 0.372932091845224E-01-.227602290610941E-01-.680109638438260E+00 -.349237624883250E+00-.320426217305454E-02-.232449893005120E-02 0.496936332823237E-010.161945477273113E-010.379014284144202E-03 0.396327632422365E-03-.858744763106854E-030.871345710795191E-01 0.870146384175541E-020.110748991451490E-070.647459393211122E+00 -.211020858629368E-01-.655608719224489E+000.387108539259607E+00 0.241779008380115E-010.386469431151273E-020.112081023309811E+00 -.698167490986286E+00-.112081012101691E+000.698167490986229E+00 0.609105524539040E-040.810324884139280E-03-.604954208771893E-02 0.822458556079886E-020.108535292536380E+000.377476685106857E-01 -.774936024964465E-02-.787880717753179E+000.225369702812543E-02 -.562892718869109E-03-.285497312308102E-010.604196076303872E+00 0.134876218565383E-040.885850836022477E-030.240861803747173E-03 0.320725483445566E-04-.245765498175867E-030.518563563274593E-03 -.258064430088833E-030.523073530082049E-020.414286362962317E-04 -.134296280739007E-010.454147960865441E-010.246095955438665E+00 0.381810162664600E-01-.458578109756278E-010.309247721541881E-01 -.840168641477295E+000.726706384663128E-03-.200805330145389E-01 0.475756927113320E+00-.348987049372346E-050.163014746453075E-04 -.406433530604126E-040.174811555826052E-040.416347324487490E-02 -.503900886600453E-05-.243879091555047E-010.430018804227158E+00 0.560591961221790E-010.114237883088519E-020.652452798290859E-02 -.245918402416141E-020.608972012498249E-020.461425942228189E-01 -.102539319935843E-02-.815026724296231E+00-.117156972700854E+00 -.195325680784950E-010.236697927830689E-080.358408016308951E+00 0.467236881616071E-01-.528487928757052E-03-.344478060267522E-03 0.327754210659766E-020.101409566262696E-010.707106781186500E+00 -.707106781186603E+000.662262870273973E-01-.412532285002360E+00 0.642429494386874E+000.642429402719959E+00-.339222881485481E-01 -.440624356497263E-020.721314558783405E+000.318354889292678E-01 -.691029429413945E+00-.298330170970555E-020.228604569444274E-01 -.372782349555383E-01-.271115201819383E-010.688164533706434E+00 0.441086820619143E-01-.722376492423855E+00-.383619480806987E-01 0.123858524819484E-020.211675332716350E-020.682478888494490E+00 0.970441548327741E-010.390369360953282E-01-.238759561039506E-08 -.716298578374737E+00-.933799186770630E-01-.707106781186575E+00 0.707106781186525E+00-.167263560147883E-07-.497215731964989E+00 -.609297473009121E+00-.609297508136205E+00-.101437921164760E+00 0.396808464685394E-010.145837777501628E-01-.681042143793224E+00 -.504664615069257E-010.729278738542803E+000.681269617691656E-01 0.666444114418943E-02-.712408745146810E+00-.648638844371203E-01 -.636842463844503E-020.695369860658179E+00-.979129339670780E-03 0.300892878154688E-01-.298674746023331E-010.482956299067998E-07 -.322605724633322E+00-.646186912478413E+00-.121318406636933E-01 0.582015570576082E-010.215407605396003E+000.653173445595279E+00 0.570507474805564E-030.942716646294706E-080.298476109835370E+00 -.229767996041610E-01-.303221070862048E+000.602037576303353E+00 0.675266720258527E+000.245053547811273E-020.585960686889018E-03 0.513031006915004E-030.865194342723113E-020.787352240189772E-03 -.123009456216638E-01-.602952293381838E-010.100813384569477E-01 -.235623029749862E+000.486151508253275E+000.442775079628557E+00 -.405512246939388E-010.216904069577573E+00-.486151536353640E+00 -.472136317138705E+000.126301180815325E-010.792403668237731E-04 0.413297540850655E-020.352171169359473E-03-.329573224578663E-04 0.652940718111332E-03-.256262482273700E-03-.234114335976204E-01 0.337110002433409E-010.381021013468887E+000.601463636725532E-01 -.545256280105584E-01-.868532468572194E+000.679937091073461E-01 -.847858651657671E-01-.411597864503930E-010.280521986517897E+00 0.105879134718726E-040.416765143704468E-03-.123099030948993E-03 0.301756375767690E-040.249083843067110E-030.209120900143790E-03 0.231043094154576E-030.257036870345741E-020.228387047244176E-04 -.574755821099979E-020.974467519929338E-010.236333894525561E+00 0.396680034546653E-01-.132253076018475E+000.265114915419996E+00 -.853424947855451E+000.479397847921161E-01-.427817436974369E-01 0.335850084444527E+00-.148408460429058E-04-.748161136435617E-04 0.110753604160756E-03-.706119611472251E-040.152624617518191E-02 -.110951858901099E-04-.644113284807349E-020.650828991401486E-02 0.228749967414610E+000.600635730865104E-01-.223553067564437E-01 -.358150776105921E-070.239684957296783E+000.480094650288983E+00 0.192145309729517E-01-.836123635137684E-01-.225899275367096E+00 -.765138432844402E+000.313411371419374E-020.742995638243971E-02 -.136119349521726E-010.825709237069057E-01-.389328976578801E-02 0.308727616620548E-020.502762790374560E-010.457631940177901E-01 0.210671082150144E-030.136670157899477E-030.177999280509586E-01 -.174707401413546E-02-.146934442009727E-010.371048542182972E-01 0.999042801658376E+000.917293575579656E-030.136933469979301E-03 0.442668224180858E-030.123494540316625E-010.557234391914227E-04 -.570137556406672E-02-.370827223466650E-01-.472433665133362E-02 -.278122948398114E+000.410144945494006E+000.397557322797068E+00 0.448319999663166E-030.493871784844263E+00-.410144933519769E+00 -.425418904107767E+000.334848699759163E-010.127375877370595E-03 0.110532019406746E-020.237091582126644E-01-.113844312723035E-03 -.380925034819731E-040.158908676155912E-02-.494574442295410E-03 -.136516243012434E-020.289433905657649E-010.514912248937955E-01 -.303914167730759E-02-.422251074843907E-01-.203227767720065E+00 0.153753347019584E+00-.917153830215156E+00-.763258755002147E-01 0.287706323687985E+000.216506567822838E-040.829796579240233E-03 -.283433609785619E-030.559390318691268E-030.633501377261939E-02 0.131319120514597E-020.701963998257549E-010.905217459477781E-01 0.357923735038388E-01-.123891945774251E+000.395903508691244E+00 -.702671794969916E+000.557691797337480E+00-.205098607153493E-01 0.909184509497725E-01-.190654151029481E-04-.121336165082983E-03 0.328915099482047E-03-.149272779124686E-030.338462654696031E-02 -.112851204297636E-04-.445463552536016E-02-.835576313571940E-02 0.752932544467666E-010.137534847523132E+00-.259114738485208E-03 -.563852731001187E-030.190774804903477E-020.242779688270085E-01 -.194309000886799E-02-.285769460002899E-010.895054924400790E-02 -.983116941827859E+000.212645158251803E-030.125707197364705E-03 -.350836204080841E-030.430592564883796E-01-.853469359816533E-03 -.777078218862946E-030.742620013435782E-020.734967290854320E-01 0.381446313628261E-030.124845056146456E-030.414383331747861E-02 -.940271526508416E-03-.404221951901942E-020.644204016897479E-03 0.999982450334638E+000.102526910708690E-030.342667220082544E-03 0.539407713885730E-030.112182650588275E+000.291963953692846E-02 0.243306172940037E-020.417843161548503E-01-.339945353959363E-01 -.797488637176752E+000.274980044994610E+000.286636867608651E+00 -.136712222555940E+000.267568964966806E+00-.274980025426080E+00 -.117859587300834E+00-.268224051763144E-020.846984655215149E-02 0.104013252256216E+00-.706725077066978E-020.221871308732617E-02 0.219868236428274E-020.201981444706414E-030.458618437592934E-02 0.126809928213090E-01-.320380956077024E-010.204506522896203E-01 -.148582793941879E-01-.113780442017961E+000.374335203551583E-01 -.990721098034612E+00-.210726169380195E-010.426373790397174E-01 0.136555208806411E-030.224198476974885E-02-.571391145031755E-03 0.566586344120537E-020.959780379361985E-020.318911180367516E-02 0.620827710669931E-01-.568901108942749E-02-.180691343789712E-01 -.740521161628900E-010.209179385162360E+00-.195609548916247E+00 0.952445669749881E+00-.250646268674595E-010.131476157327279E-01 -.369071287024797E-04-.488185333132813E-030.346924020436468E-02 -.801030241372621E-030.135234270359219E-01-.699427244703543E-04 -.227371817304806E-040.305526739861381E-070.280327128925278E-04 0.499079983149445E+00-.678543881782044E-05-.141311621891559E-04 0.323882026853012E-040.296376197095334E-020.557320090650802E-05 -.203285194749962E-03-.242749015745857E-03-.829871103648760E+00 0.275295157139778E-080.407862664671703E-080.240492921342678E-07 0.447132367465700E-03-.196841317648305E-03-.835445317130868E-04 0.803921598880989E-030.249446072407021E+000.188844328303154E-01 0.538455289838268E-030.291708523636470E-01-.372703108642742E-01 -.496393478982733E-010.254758647814956E-050.997313376037241E+00 0.179944080258892E-040.174653471249788E-01-.387280835249212E-03 0.135120879213858E+00-.332591407056297E-030.839200840958193E-02 0.123774549670626E+000.710355862613081E-01-.816903955833649E+00 0.259111769955954E+000.169922195433962E+00-.967589717675854E-01 0.295181562913193E+00-.259111775222573E+00-.121879896040359E+00 -.170780062460303E-01-.456215445186038E-030.138493391082666E+00 -.756584484839288E-030.462615585354142E-020.747070123653290E-02 0.121523955801067E-020.121318890601466E-020.855595803629244E-02 -.618607852540523E-020.306525760240591E+00-.136562251008736E-01 -.673592315256137E+000.589580615384586E-03-.573566359288367E-01 -.288004951243023E+000.604707526771186E+000.152712274111098E-02 0.506016895702041E-02-.105440009914927E-02-.424305489168350E-06 0.528751207416300E-030.254336715238593E-010.543992283805514E-03 0.769918527154085E-010.230146570594166E-050.776291852346123E-02 0.118061461199013E+00-.143472302037430E-010.270617786854460E+00 -.198234957495660E+000.136950886553168E-01-.726560688324639E+00 0.141188296603900E+00-.294523042192644E+000.472157830749985E+00 -.110872557472870E-03-.126978546655609E-020.577296043463924E-01 -.144384353054288E-020.752577368093954E-010.243418539483478E-04 -.142888328684564E-04-.114490935915299E-070.161979153767801E-04 0.390904820917777E+00-.107263660415500E-07-.465323015112817E-08 0.223347461190187E-070.281951787649733E-040.642263470427003E-04 0.343724131105744E-06-.989576291726829E-04-.832242768277343E+00 -.120177009576371E-070.103799950061146E-090.199722827564297E-07 0.126564714211728E-03-.692324238576580E-04-.138592840130219E-05 0.152324103553164E-030.393147982873812E+000.154917438959898E-01 0.104654297961220E-040.278259108674488E-01-.303490991488291E-01 -.354216368215474E-01-.374358936472513E-060.998306540843242E+00 0.583345098154626E-030.139166982303768E-01-.219188756453223E-02 0.757662900455562E-01-.152524631871661E-03-.321278040358060E-02 0.320493204006391E+000.101985556245574E+00-.783316817911260E+00 0.276533341997327E+000.164610994180330E+000.186915934215290E-01 0.109466950808409E+00-.276533344763605E+00-.262128799339971E+00 -.711582411610634E-020.316741118718987E-020.798075059151104E-01 -.549305914149587E-020.680591161936855E-020.103957194354297E-01 0.165449572551216E-02-.297305272856413E+000.133512169424708E-01 0.620313041634109E+000.288681103087594E+00-.177630992643315E-01 -.657895338706556E+000.101100937639440E-02-.995075900155844E-01 0.378031371560238E-03-.715073997670865E-020.226932302359274E-02 0.680513181941886E-02-.134886288914828E-02-.489664457071443E-05 -.115741943188504E-020.340181330921379E-01-.112000827068954E-02 0.949249299187529E-01-.963143805549435E-05-.279314130074537E+00 0.159118172145863E+000.440690486502383E+000.219264647394360E+00 -.223531848223986E+000.209613224177962E-01-.730529530601576E+00 0.216119903392971E+000.149639207047947E-01-.229194735289877E-01 -.501177261368179E-040.297277225627281E-020.694032145798862E-01 0.257686371432962E-020.885479588062585E-01-.207970163074130E-03 -.138923090909384E-04-.127238716380106E-070.157058480423797E-04 0.409492189251564E+00-.102996885080796E-07-.678584712436506E-10 0.157848450480880E-070.936451399983214E-040.583579087160737E-04 0.356385494683888E-06-.910641984638006E-04-.829776111590451E+00 -.749823348792695E-08-.249102776330744E-080.140200580837383E-07 0.281551872354774E-04-.595312905301544E-04-.125463596060752E-05 0.134246582370566E-030.379193497185602E+000.426249993318591E-03 0.138136677625042E-030.600027532935093E-02-.104715937420707E-02 -.410412425692858E-020.360816358907135E-030.999972748532237E+00 0.815344840941258E-040.470003277126032E-03-.975581912704339E-03 -.758387765641282E-030.311201162620555E-010.163127700276862E-03 -.379406664406015E-010.655778353245633E+000.196424421346421E-01 -.478876541054886E+000.310326047253723E+000.286814367728409E+00 0.475138107439813E-02-.411328427070017E-01-.310326040307785E+00 -.244615833492320E+000.880585133137490E-02-.212605409102574E-02 0.364624809606826E-01-.259201452975158E-020.224527879066681E-02 0.209234382545644E-020.156319489577705E-03-.307758905489842E-01 0.220261326059213E-010.671643419853845E-010.118321296739216E+00 -.103277528307138E-01-.428144170934312E+000.286625510817101E-01 -.869306495280380E+00-.510672066662528E-010.193647111457262E+00 -.378647105337771E-040.317666846458886E-02-.835552638858626E-03 0.701619192360112E-020.105374907692704E-01-.522925349009331E-01 0.132709858923520E+000.526721064437783E-01-.202405945294266E-01 -.725368516726221E-010.194688239718319E+00-.189260055568609E+00 0.946300940701786E+000.792544711088228E-02-.355764043826012E-01 -.246135745872575E-030.304975551354759E-020.420239640621067E-02 0.261040112096898E-020.218379335165771E-01-.341978135298371E-03 -.172457015309441E-040.431356008346286E-070.219590871210806E-04 0.442659543701007E+000.620442416979269E-090.258920030491552E-08 0.168861954232395E-070.306596243662881E-030.323138773456644E-04 -.960348097112365E-04-.218166081265305E-03-.838067704175618E+00 -.589914917310024E-05-.416409183798882E-050.216992518203371E-04 0.171734903009034E-02-.172262703654395E-03-.255366933603604E-04 0.588840143324276E-030.318891160231964E+000.323051769754980E-03 0.527812440603705E-030.184483412376782E-010.172904899351989E-02 -.209517265408227E-010.158263229092178E-010.999483262596492E+00 0.789622357502747E-090.215857232441392E-03-.225609164740967E-02 0.149823816969244E-01-.499062773662014E-03-.236548692000563E-01 0.363896924656256E+000.107483034761124E+00-.391270672966822E+00 0.502192301820578E+000.405412180298002E+00-.678056199914652E-01 -.960614884631456E-02-.502192338841198E+00-.169129058584629E+00 0.276901186419182E-02-.169243266660495E-020.927155007066666E-02 0.145412623807367E-030.264674993738985E-040.763553538678154E-03 -.274044971065333E-03-.206553196141291E+000.192544222065392E-01 0.710409976253818E+000.130366138371823E+00-.228795553119039E-01 -.549279079167324E+000.144877887368590E-01-.339041201676814E+00 -.242405803695270E-010.131562971065629E+00-.258376806382172E-05 0.656278446202110E-03-.236769424458550E-030.141355471070267E-02 0.105244043606728E-01-.660332708148621E-010.210625908749795E+00 0.206019596480891E+000.666155188911710E-01-.131785375279779E+00 0.629358709986443E-01-.579139160435087E+000.687848108070714E+00 0.249885689824524E-020.272623878087522E+00-.189083942331165E-03 0.144332387792429E-02-.964970276958600E-040.142997186912260E-02 0.905906105727050E-02-.335003383098555E-03-.761567012733616E-02 -.106277964677985E-010.104274987796965E+000.200717863329688E+00 0.167157754026795E-030.800103307358312E-04-.239487412514881E-03 0.288613812865254E-01-.280311412689388E-02-.102833078885913E-01 -.246652115998060E-02-.958907097949439E+00-.199282635800055E-03 -.133451307121677E-030.122389068203788E-020.121150111192682E-01 -.553097739420755E-02-.738697421077239E-030.291299759234546E-01 0.164877272058817E+000.176933543460421E-020.636048637279320E-08 0.386389399803415E+000.837523572201287E-02-.392389715572957E+00 0.177968659061121E+000.815465158463628E+000.145621272878538E-07 0.199985867714712E-020.195851833059782E+00-.679442478235078E+00 -.195851722041146E+000.679442478235217E+00-.357201584439584E-05 0.104508299723225E-03-.430429753409975E-04-.161992044701792E-01 0.665913332291113E-020.627943984135420E-010.158766162588137E+00 -.580681991929644E-02-.725442566426469E+000.389377340629332E-03 -.543997834523727E-02-.141418550919330E+000.651316976488143E+00 0.103704333512308E-040.760162068660251E-04-.215295048130131E-04 0.814462510058118E-04-.624103587955855E-030.512727498773690E-03 -.655337427526513E-030.405937494843178E-020.105205018006757E-03 -.430493797466982E-010.888089058101809E-010.296501401773398E+00 0.820849426591335E-01-.704003772035664E-010.934683955500087E-02 -.849557747276744E+000.299284353890857E-01-.307351278117629E-01 0.408597009486543E+00-.477326696952231E-040.203748305369640E-03 0.145051551564250E-030.213311096242107E-030.268327332614296E-02 -.611874011102725E-04-.337262668853664E-010.924166207019878E-02 0.621949633428841E+000.161210309761146E+000.165557847623496E-02 0.133402559164063E-02-.540323718323402E-020.349527344820291E-01 0.158972038010233E-01-.191896754436189E-01-.167295225035774E+00 -.680665052123196E+00-.120576509551053E-01-.194282041054332E-07 0.106218810781638E+000.201171754213052E+00-.152846247993426E-01 0.126495382860975E-020.105728483537333E+000.171716077268080E+00 0.707106781186532E+00-.707106781186564E+000.179199321427276E+00 -.621672299758036E+000.539171163068275E+000.539171226818681E+00 -.150859012548334E+00-.346779801559453E-020.696421358249040E+00 0.147705689688260E+00-.685864311448068E+00-.549676070744279E-02 0.256758327647866E-01-.750726041803840E-01-.317246623417171E-01 0.668536882366567E+000.938655702018445E-01-.732745439276634E+00 0.170870172221987E-010.583898068138768E-010.619301667958476E-01 0.600138230146652E-010.677664207154702E+000.385190232285779E-01 0.619119497642184E-07-.339323566159786E+00-.642657517212704E+00 -.707106781186557E+000.707106781186543E+00-.245736663857741E-07 -.487017594237811E+00-.613791894359277E+00-.613791883445462E+00 -.966069207569462E-010.429174371243619E-010.113832073170950E-01 -.678381985760620E+00-.504298591343777E-010.731630526211845E+00 0.635386735290795E-010.125742853429528E-01-.716745907330516E+00 -.583613871779776E-01-.110212329091957E-010.691772730437950E+00 -.173175445674593E-020.383841621124299E-01-.110416382473008E-01 0.256741288464596E-07-.453880443429687E+00-.554991234753238E+00 -.318174114684711E-010.218019157967283E-010.404853975196401E+00 0.564789870930429E+000.102068503593475E-020.285623013061450E-07 0.492754819127494E+00-.203842046987441E-01-.499362468921001E+00 0.587824361647918E+000.402336839078275E+000.918169007117501E-03 0.700012494926306E-040.377013393139683E-020.158061746585615E-03 -.923345838286210E-02-.465479735545722E-010.161317275038019E-01 -.241725710157609E+000.498377849088563E+000.419438718550452E+00 -.424078491233497E-010.210523737367770E+00-.498377789898282E+00 -.469006127421801E+000.159157362192407E-010.971442723612329E-04 0.370429343061676E-020.185402222885231E-030.140361401801025E-04 0.454359178768059E-030.828774296805545E-04-.312157931261559E-01 0.221644959830577E-010.467147250894710E+000.605956757459247E-01 -.286080598138955E-01-.839766996204144E+000.216291917452147E-01 -.219985152720672E-01-.281124096984636E-010.262424344259733E+00 0.116417805123626E-040.267635114197098E-03-.672215219544455E-04 -.813735173184751E-06-.398866592646904E-050.204362284917030E-04 -.409081302153415E-050.158462400066490E-02-.628949975187434E-06 -.111533654039953E-010.945756611763469E-010.309305220492670E+00 0.491707927664971E-01-.110293923293886E+000.131202023612183E+00 -.859274284355457E+000.187676429483093E-01-.364156143118406E-01 0.351325562001735E+000.302673825658693E-050.179685592317993E-04 0.140441788487869E-030.172457286836458E-040.142844320681775E-02 0.256541507301178E-05-.135974180846842E-02-.135228523273871E-02 0.124160279154033E-010.226781889854867E-01-.333271203637093E-01 -.223082863493948E-070.394082533781187E+000.481872165055281E+00 0.354794598302177E-01-.290941802402022E-01-.430896016118760E+00 -.640798137718591E+000.185037448827823E-020.962525823705057E-02 -.494931284124744E-020.815259078185888E-01-.366652507262709E-02 0.308654674398379E-020.634740521082287E-010.386973240214517E-01 0.920203922416232E-030.108629350498719E+00-.143184031301651E-01 -.103310610340044E+000.268157434783449E+000.951507667518300E+00 0.667459177312360E-020.957709173457184E-030.603352690579251E-03 0.211234307770364E-01-.913404167729270E-04-.490567395888047E-02 -.312206895692159E-01-.377826865054100E-02-.253367241251457E+00 0.457238405489630E+000.431443403923000E+00-.580916488736549E-02 0.327729924464284E+00-.457238455836453E+00-.470035771580013E+00 0.286160495778913E-010.162251095002671E-020.295291942973934E-01 -.510593888156111E-030.133176045858044E-030.288550864294607E-02 0.326671120515064E-03-.119940694302481E-010.493611977238944E-01 0.200835967502284E+000.375222748159743E-01-.763181518223535E-01 -.607170442032405E+000.141924071866228E+00-.357268263812569E+00 -.111584072433367E+000.648806072874006E+000.101939051155568E-03 0.200605309319850E-02-.579965588212036E-030.258630208821450E-05 0.168217775562306E-040.144330153595768E-030.232887229287876E-04 0.675044602369196E-020.135607924906647E-05-.512253262244723E-03 0.115533485002037E+000.143965680843651E+000.283648332042478E-01 -.214797768570874E+000.391457522572237E+00-.810085558883003E+00 0.188501006513896E+00-.442767460955475E-010.268178435111368E+00 -.134851379999611E-04-.906524042141700E-040.706947400427236E-03 -.102644794357619E-030.682221155305948E-02-.107940584113467E-04 0.116235358609001E-030.166025085883410E-020.156776146399450E-02 0.189682979375326E+00-.361695504819792E-02-.346080365688096E-02 0.364161680538411E-010.123107662892829E+000.479565835504608E-02 -.696332330928824E-01-.557688540661065E-01-.907343267826924E+00 0.167427784956671E-020.249525019706888E-02-.429288818316120E-02 0.715872231770214E-01-.122267448202732E-01-.590040106779471E-02 0.156528369965063E+000.293967791211871E+000.175081783184165E-02 0.771184964438607E-030.221373065832482E-01-.621763107712101E-02 -.194592641016047E-010.714969543950864E-020.999514994545450E+00 0.597860704577673E-030.269402465479075E-020.515023791883851E-02 0.121292326773534E+00-.392528020472177E-020.118992126450666E-02 0.157395445789034E-01-.394082381129670E-01-.733003478782031E+00 0.337599559770288E+000.349142686729564E+00-.139463400368514E+00 0.227145186540549E+00-.337599510291875E+00-.916649623724561E-01 -.382942486348092E-020.925240648625014E-020.129158226356516E+00 -.853888047471263E-020.140096596740043E-020.126071176579125E-01 0.124720535117440E-020.303634316616343E-020.377300486494654E-01 -.294767602556083E-010.567360891048372E-01-.465498595571141E-01 -.420230611207414E+000.880228217424541E-01-.881922252676869E+00 -.505991235370717E-010.165262464703570E+000.146288106742103E-02 0.119437537909616E-01-.215022129020119E-020.937096633811036E-05 0.160932871380580E-030.293463833607639E-020.286155735433417E-03 0.429322788825650E-010.194015643940606E-040.838523134684283E-02 0.161717170334286E+00-.203051876371348E-02-.246917146462747E-01 -.230101940514772E+000.430203686138714E+00-.518676737549693E+00 0.666606010923658E+00-.696498178573828E-010.109439876538281E+00 -.849241779494426E-04-.807577859098053E-030.152659284083099E-01 -.110538323322089E-020.532650783719748E-01-.106908413345438E-03 0.521037564689083E-050.395491098356925E-040.916942038480008E-04 0.267445501897429E+00-.146929108520377E-04-.414381105364060E-04 0.883752978684304E-040.203583744031505E-020.552720532282201E-03 -.353106948059371E-03-.268158909150081E-02-.877321689364557E+00 0.129483762335851E-060.943389430578574E-07-.520801832045056E-07 0.542619061617278E-03-.897761281568731E-03-.531645372045277E-03 0.721153625769991E-020.398389736428573E+000.339439726157846E-01 0.127008998561281E-020.558849142773434E-01-.700047885835571E-01 -.972864026383786E-010.120387721105454E-030.990042699494239E+00 0.104923379909149E-030.342517600102390E-01-.374697094457425E-03 0.152312877545830E+00-.478817790311942E-030.872860861790242E-02 0.999657868488493E-010.761029238391244E-01-.789918683778005E+00 0.312925273563142E+000.179124695926111E+00-.106456692876792E+00 0.254396861436815E+00-.312925287652934E+00-.969397708740387E-01 -.205315405806358E-010.172023645205085E-030.152210304270155E+00 -.330338109710651E-030.459563407489116E-020.143990070124588E-01 0.222644377622351E-020.800563370830329E-030.104489137273485E-01 -.602561369632559E-020.201418904467542E+00-.171281646426121E-01 -.737384008805705E+000.102553883472058E-02-.588018158817250E-01 -.181397584082343E+000.615273770267933E+000.216302320816593E-02 0.949387888312259E-02-.138702989735942E-020.152795495644916E-04 0.225359384945996E-030.225891473319397E-010.262583707734798E-03 0.105723087052347E+00-.263236897139808E-050.655669812546020E-02 0.110649523915327E+00-.129806789078049E-010.165077126998700E+00 -.192799365643284E+000.282186057827035E-01-.807718334950653E+00 0.102142581525374E+00-.192428566915823E+000.444747023264972E+00 -.548606964381622E-04-.567233548395388E-030.635340804994158E-01 -.626317548109333E-030.945045541747214E-010.789273378979099E-05 -.288979693703195E-04-.182319839053481E-060.443515421301361E-04 0.379919944695107E+00-.409896592504587E-07-.502833020468807E-07 0.120494589988032E-060.308036843749235E-040.140521908879047E-03 0.816277654525576E-05-.295259341239829E-03-.861438578734898E+00 -.277471726737075E-070.876533127563630E-090.662575211226712E-07 0.129028505756325E-03-.126377308405864E-03-.370449666662370E-04 0.550391609228765E-030.337022199602707E+000.254458699117238E-01 0.592584625065294E-040.514303172879869E-01-.512809050778411E-01 -.660648944428663E-010.951604713061685E-040.994540487621631E+00 0.100924642958156E-020.245217454649157E-010.184864876070133E-02 0.884721194989155E-01-.324244362088066E-02-.510930961910458E-02 0.303062330901710E+000.112878700333972E+00-.734565742176333E+00 0.347055364976695E+000.162412105382276E+00-.955021556489723E-03 0.848583542242443E-01-.347055368580516E+00-.250105923935497E+00 -.111169531807995E-010.355726590647559E-020.103808638914381E+00 -.419452883677787E-020.629179201941255E-020.186690274364628E-01 0.284594451775678E-02-.187651556580809E+000.162329962057502E-01 0.630915974421175E+000.187697560444679E+00-.210296554317769E-01 -.720224407521837E+000.223339360929664E-02-.104660843730164E+00 -.610626897833574E-020.229830867380655E-010.282458435792497E-02 0.118792023957512E-01-.170210445347221E-020.280196207015836E-05 -.279505004776387E-030.277071634101624E-01-.228909652598038E-03 0.119275380848415E+000.132437572800541E-04-.187601509624841E+00 0.141896128311551E+000.422365578665326E+000.128760036033913E+00 -.204838957235195E+000.434078772092150E-01-.806694510076191E+00 0.157787515993729E+000.591835161997387E-020.747010198847334E-02 -.805107391111651E-050.638873231222047E-030.680896813628902E-01 0.535850756882113E-030.102376722309374E+00-.412953070633613E-04 -.276931733144833E-04-.197474903775786E-060.430124026148356E-04 0.398149815745455E+00-.263184149901006E-07-.620746678004172E-09 0.576570088020053E-070.103875521776964E-030.125421883145019E-03 0.739661812433390E-05-.270405853635920E-03-.857409440491406E+00 -.277976071921764E-07-.193794904133083E-070.662509931437069E-07 0.348154383702452E-04-.110067008670377E-03-.330352097595245E-04 0.493295101362000E-030.326075781848338E+000.261637800500639E-02 0.593341606111460E-030.314880806247675E-01-.856875384808786E-02 -.235422243388757E-010.258747526082075E-020.999168100504882E+00 0.319275874645435E-030.547296896534694E-02-.116992826176418E-02 0.338370513154134E-01-.142777025302056E-02-.406778354377311E-01 0.504020403061023E+000.882092418045004E-01-.541496381623848E+00 0.411585398853575E+000.256567719316976E+00-.245588779787715E-01 0.823411976718524E-02-.411585419791624E+00-.183646426853795E+00 -.192903059548171E-020.123785362328905E-030.558759547771277E-01 -.250818717172438E-020.733379618122733E-030.955412980135956E-02 0.892865110995397E-03-.540490019218027E-010.372660426311295E-01 0.185501518436011E+000.158352234759734E+00-.216219089020215E-01 -.753414549089406E+000.241909096941899E-01-.408978751559392E+00 -.892679382602970E-010.438255593031304E+000.202475991596905E-02 0.108697778577146E-01-.151558617647810E-020.158189155579921E-04 -.273419002779876E-030.226951112635693E-02-.192207014371830E-03 0.576369410134945E-010.124942742956545E-04-.131329073179166E+00 0.305611774621079E+000.254739263535127E+000.552445048191232E-01 -.164344958886550E+000.206564820276684E+00-.662834178384440E+00 0.544315066876567E+00-.396148205477567E-020.698461846680987E-01 -.954984862955493E-040.123919551849472E-020.329652662042095E-01 0.103982753519749E-020.824191920632282E-01-.137575992812755E-03 -.118262824998473E-040.123526003258420E-040.707450826197362E-04 0.199578367733588E+000.363708976451750E-070.321899201930129E-07 -.250041569150016E-080.225985817010339E-030.399465008189380E-03 -.383274536444598E-04-.146616509322618E-02-.883662801063188E+00 -.664010684521299E-05-.735402308780296E-050.216923907460852E-04 0.824256599274688E-03-.523153796336422E-03-.266383346326575E-03 0.361288604263049E-020.423428960439017E+000.173851036205211E-02 0.222870073788660E-020.147323973899202E+00-.145602763087638E-02 -.153553351053440E+000.124330762289657E+000.969144432517211E+00 -.670088769709058E-080.279928963613627E-02-.535336505050603E-03 0.571786431162824E-020.501111613013933E-04-.375294159509387E-01 0.286470981196203E+000.189845534980769E+00-.635875367893217E+00 0.398691041336605E+000.186217324361401E+00-.114177856312955E+00 0.244995441534964E+00-.398691042678259E+000.213291086621552E+00 -.702759278074976E-01-.285865195571977E-030.607323396528475E-02 0.177522666938543E-030.232624905150071E-040.871528520081471E-03 0.104242811764133E-03-.117190708001031E+000.172804418631202E-01 0.531354146114651E+000.147827925084915E+00-.173568415846287E-01 -.754028144632404E+000.362393328445694E-02-.504753734217587E-01 -.606045340700605E-010.326623017330199E+000.140948202581589E-03 0.702783387652478E-03-.107036079108171E-030.590209447893790E-07 -.908741189140752E-06-.537857176299051E-04-.821800159702671E-06 0.742259477778545E-020.175891555799017E-06-.127575373639961E+00 0.173884621836369E+000.488642885545859E+000.101063732588886E+00 -.130420282060893E+000.415306618536464E-01-.760148095701464E+00 0.976580937993439E-01-.254359609712527E-010.312471985413515E+00 -.574123283391161E-060.433910605356674E-050.205862756366894E-02 0.430410468022567E-050.783406586305063E-02-.778456164311075E-06 -.423214058359036E-030.919140921167062E-030.661874120526856E-02 0.117109755045484E+000.562189141098998E-030.519894877621451E-03 -.109887397286355E-020.184158676355906E-010.128559805126469E-01 -.985063481572301E-02-.793770939849137E-01-.885499725592162E+00 -.183772385564369E-02-.887523056274150E-030.105538790154888E-01 0.403343983135072E-01-.178576536206106E-01-.109963830700987E-01 0.165007678884550E+000.407206303906568E+000.306348529486999E-02 0.239930764984804E-070.601420059751685E+00-.141146313644592E-02 -.605225595551520E+000.230075880325225E+000.468016488374206E+00 0.318887906876394E-020.194968143237539E+00-.679696569745449E+00 -.194968123740749E+000.679696569745495E+000.433921650703326E-05 0.686239809673315E-040.134914310172025E-04-.158714965443381E-01 0.332719906827371E-020.784843725910340E-010.139678381750007E+00 -.317681035662774E-02-.734092568722168E+000.988288218555025E-04 -.128106164851903E-02-.122669376425973E+000.648163369247435E+00 0.894069909141543E-050.405720798599522E-04-.531085987799746E-05 -.171919591025308E-050.803049222354254E-050.130444794348500E-04 0.861156968395583E-050.110231449582210E-02-.248231645536447E-05 -.375937616255964E-010.355819759338922E-010.229692292043488E+00 0.108667338908260E+00-.264758743157882E-010.393712049859257E-02 -.813756878731386E+000.512266270133843E-02-.668002364102831E-01 0.515117604605447E+000.492260750079268E-05-.272219895394282E-04 0.208694217366870E-03-.283952525261720E-040.917376031998474E-03 0.581122815426736E-05-.455060985419248E-02-.919535789492620E-03 0.349190607723191E-010.763767596648188E-010.265591381650204E-02 0.521301039994967E-02-.401859423332637E-020.732525315960548E-01 0.535241281320955E-01-.115977550287200E-01-.375723852306493E+00 -.771464840486708E+00-.315965957352218E-01-.143459287868964E-07 0.227393868069098E+000.322787116054316E+00-.215711586956064E-01 0.108257024347966E-020.242983985741911E+000.178264096966029E+00 0.707106766183749E+00-.707106796189347E+000.177843854234752E+00 -.619997921177283E+000.540358273709987E+000.540358286028759E+00 -.131869994779899E+00-.196304501085975E-020.698246561864295E+00 0.130169226789683E+00-.691457997403106E+00-.128013211249068E-01 0.546427753459058E-01-.934052075111080E-01-.664941001276631E-01 0.678859335665877E+000.119191372805422E+00-.713195424947486E+00 -.404938617540185E-010.181062659918079E-010.232791185547601E-01 0.321138225103363E+000.619279730616487E+000.570137931646475E-01 0.258785337293530E-07-.410315942496114E+00-.582446223508185E+00 -.707106781186560E+000.707106781186535E+00-.721341536320415E-08 -.428989822532113E+00-.636689094459996E+00-.636689104237412E+00 -.722614261203267E-010.282343743720400E-010.938364903717614E-02 -.678889534403801E+00-.334569836275536E-010.732874066643181E+00 0.490057224614373E-010.139296369817684E-01-.713288124764123E+00 -.453244904721617E-01-.128587843097479E-010.697424647376202E+00 -.191282821385874E-020.400397255563485E-01-.392330176179403E-02 0.585593361868326E-08-.614848650012675E+00-.364459981119449E+00 -.378769195029760E-010.669732104564358E-020.591610797545009E+00 0.368820602608620E+000.123195855168806E-020.621112322271792E+00 -.142906888883486E-01-.629115104083898E+000.451903369348001E+00 0.118349072475903E+00-.110429569969675E-070.218385917379393E-02 0.474020131646410E-040.341856293650974E-020.106540652945231E-03 -.645360819374788E-02-.383127542619521E-010.125973858299685E-01 -.215314667589504E+000.493886045857771E+000.440903158857425E+00 -.363141787614656E-010.220456050264233E+00-.493886011421948E+00 -.468226459066813E+000.231829628021786E-01-.362744711248249E-04 0.492042069801937E-020.330696552912518E-040.202644371713308E-04 0.496659907643311E-030.736840121878654E-04-.198191879706170E-01 0.183303009260840E-010.449742417866469E+000.410829172385245E-01 -.221035301005096E-01-.845083570129830E+000.229988122217302E-01 -.633862858502668E-02-.190597419343020E-010.282360542508567E+00 -.915253709884024E-050.467860617318541E-03-.936082013898601E-06 -.471900999515919E-050.360154552581113E-04-.445382936066878E-05 0.161761440053278E-02-.699826636234017E-06-.100518297978727E-01 0.813344640279481E-010.322240982462986E+000.365348966340719E-01 -.898377311847809E-010.138505009350467E+00-.847528994615232E+00 0.484822858208514E-02-.286713955100532E-010.376428436355344E+00 0.305214288653784E-050.181194673226224E-040.148033919232344E-03 0.173905350410810E-040.178925671284225E-020.258695791232144E-05 -.135493060354600E-02-.135066372724518E-020.135603142952304E-01 0.185868253362159E-01-.352836497074884E-01-.511901396462545E-08 0.541814512743478E+000.321167993263074E+000.399514083113646E-01 -.879433456844653E-02-.619330290540681E+00-.454991628886887E+00 -.105596987591205E-020.705649764873231E-020.285295653675024E-01 0.585189397982255E-01-.120981119976275E-02-.164054205324875E-07 0.605748606344640E-010.359064075394220E-010.286188393180971E-02 0.302723797596224E+00-.393634811399195E-01-.303819324099225E+00 0.770938930261185E+000.468969096158830E+000.138220192540853E-01 0.495490516333219E-020.992452014486792E-030.282067170458185E-01 -.526320537210620E-03-.626140892699711E-02-.420916642531304E-01 -.372664848981284E-02-.271564230509885E+000.464750601983194E+00 0.441452754120364E+00-.154463635706786E-010.286305584915958E+00 -.464750603183541E+00-.459710281950070E+000.276903753399330E-01 0.164107973795033E-020.494331015087113E-01-.288169856338215E-02 0.181384528842341E-030.371596182844276E-020.528440319457944E-03 -.941885934972875E-020.370997823273176E-010.231848896187434E+00 0.366243340421597E-01-.532260858845199E-01-.799048803738820E+00 0.134190051866849E+00-.785968234612202E-01-.524280946553506E-01 0.524565851490170E+00-.969902988985165E-040.332166998097683E-02 0.178393887634442E-050.113533332194821E-040.181974060923368E-03 0.139673311333751E-040.748922993006937E-020.105594089085603E-05 -.125119713273718E-020.902096536931047E-010.147246951099762E+00 0.149737886688360E-01-.133913301824410E+000.418936033466391E+00 -.811341515728799E+000.369333524141069E-01-.333282371384749E-01 0.340069402844183E+00-.681313090765745E-05-.458006071986632E-04 0.684063550008274E-03-.518596031454553E-040.780440694537957E-02 -.545350364764260E-05-.188819474609356E-020.169410258829227E-02 0.212175769390214E-010.173958315025131E+00-.797638722213490E-02 -.293947799718114E-020.113587530023477E+000.109694252187022E+00 0.142919996767946E-01-.337701654742926E-01-.209384087697011E+00 -.845567642095652E+000.201133506974394E-020.616308901856066E-02 -.971356627744613E-020.292603070320401E-01-.560758539688166E-02 -.946440555507977E-070.280843258259704E+000.322810651789196E+00 0.100624941112454E-010.259672364681204E-020.817713789100689E-01 -.378487363357314E-01-.713365278141413E-010.523743917330373E-01 0.991717031383619E+000.197738512819566E-020.208413168788660E-01 0.650446596813922E-020.135072660963680E+00-.621746918612862E-02 -.966281355133967E-03-.918875977233796E-02-.289501236543810E-01 -.685382822420014E+000.361708105505221E+000.357137550448023E+00 -.266613412827571E-010.782040935170842E-01-.361708121793891E+00 -.239799476892995E+00-.985520373764162E-030.124217593525461E-01 0.238575082904427E+00-.196146477726306E-010.488773826113334E-02 0.349527507620209E-010.379484360472854E-02-.190335388122274E-02 0.447950884527639E-010.432841152042769E-010.388755048096654E-01 -.538304662046303E-01-.789807137487042E+000.235705022604824E+00 -.513957403747273E+00-.370616288007413E-010.209032049105300E+00 -.288368196965015E-020.432040578288786E-010.127521601121691E-04 0.168677884713730E-030.617877501892261E-020.276772111811215E-03 0.600611597756269E-010.241666265834041E-040.303528049568012E-02 0.942997003617236E-010.379042102331497E-01-.330454305947829E-01 -.128113287104398E+000.555973181880454E+00-.775895571131535E+00 0.198144727494078E+00-.310709714778411E-010.100592357864689E+00 -.672609772397682E-04-.639611891632221E-030.104051260731826E-01 -.875477524731695E-030.832817668969010E-01-.846727903271358E-04 -.207408821420728E-030.486560668082637E-050.979491912068454E-03 0.277397787870578E+00-.138842323987768E-04-.406202819318755E-04 0.110309257668976E-030.939959189060195E-030.569551259786794E-03 -.294882488065178E-03-.498973942338665E-02-.880817149857464E+00 0.187425605060980E-060.501129676429758E-06-.300671605978139E-06 0.241872213478973E-03-.255178043170943E-03-.120288168640803E-07 0.127780982294317E-010.383433180051282E+000.725838932670944E-01 0.252083195843648E-020.117006173486548E+00-.223393012118206E+00 -.208342404872242E+000.234209847200587E-020.930605964661460E+00 0.173828081375503E-030.147277990800831E+000.181434246890757E-03 0.170536287384264E+00-.309107241232440E-030.259166691097343E-02 0.267966291631130E-010.188199924025729E-01-.669691184768908E+00 0.369388402445399E+000.298437454764436E+00-.279860191285971E-01 0.602660083184696E-01-.369388385141567E+00-.248022967896360E+00 -.464439367770653E-020.500024221342130E-030.305677755406208E+00 -.444449132690379E-030.124526942124952E-010.412389063954632E-01 0.477962868100348E-020.121324350674267E-030.172316413671693E-01 0.206626091962812E-020.826042674682101E-01-.291949989074805E-01 -.807935585115537E+000.719562126724321E-02-.844418266345479E-01 -.865202850613294E-010.565496269575906E+00-.854734894082898E-02 0.534551683245710E-010.248113583813972E-040.284156083985196E-03 0.468661828942036E-010.323108007624496E-030.188307985273998E+00 -.544725160151694E-050.322850342593503E-020.113497207464359E+00 0.155469184155135E-01-.196939954403634E+00-.194657514389626E+00 0.969404504569904E-01-.859164413239739E+000.872264017923245E-01 -.388952182996452E-010.189593190383465E+00-.795671796675343E-04 -.822688558144623E-030.606453458049934E-01-.908377415704067E-03 0.276089968873254E+000.114472964265622E-04-.488773078956015E-04 -.396188336235372E-050.999659673670207E-040.310777183676489E+00 -.571298251501996E-07-.143066131598022E-060.317328824163547E-06 0.183060084594285E-040.886359900474387E-040.190300654410858E-04 -.393117861683414E-03-.877646247157486E+00-.373857766313145E-07 0.404625131158292E-080.185231894502927E-060.706529209549547E-04 -.204895952319792E-04-.194471437864013E-080.102610554232600E-02 0.364901867847999E+000.517095658659024E-010.980626985835659E-04 0.109751994430230E+00-.156570782738845E+00-.139532788543006E+00 0.213245059817445E-020.964892906217063E+000.251687159024994E-02 0.101329163413399E+000.277117162597201E-020.118636768143132E+00 -.352176514804628E-02-.151217924652192E-020.119996119063301E+00 0.301941926097845E-01-.609479618054216E+000.407610676820285E+00 0.303999762041851E+000.761324043901745E-020.710147150771023E-02 -.407610668100491E+00-.356147653325360E+00-.939570530183214E-03 0.763317786414497E-020.217680817050759E+00-.493762301165418E-02 0.146000447120399E-010.479479620035907E-010.566504813998350E-02 -.844499638835638E-010.256283929519846E-010.544801062552938E+00 0.737368671651306E-01-.326618131262042E-01-.812123287123367E+00 0.154297518539648E-01-.144246520083369E+00-.462193369264405E-02 0.445557502386635E-01-.935867171427351E-020.605927338092271E-01 -.336190661502138E-050.199412672691505E-030.450587704881531E-01 0.172855825862255E-030.183127683802625E+00-.139506417990564E-04 -.371032128812401E-010.136441962315432E+000.173292355829121E+00 -.191031363946136E+00-.181314220103855E+000.140001406724419E+00 -.858012964858887E+000.124946578064121E+000.319424061996110E-02 0.399157810449760E-010.690865516433771E-05-.548226189109581E-03 0.563223050755544E-01-.459820360442181E-030.262427675882098E+00 0.354360602071234E-04-.450936989333873E-04-.377667649549115E-05 0.945332035517973E-040.319025562226798E+00-.368743805844936E-07 -.308404229414676E-080.169494334962014E-060.602269526486935E-04 0.812755972306230E-040.174914793561078E-04-.370843264734492E-03 -.875757998566261E+00-.335945798006633E-07-.675440572999075E-07 0.170899586778266E-060.198556153617846E-04-.186285422087375E-04 -.200657120064962E-080.932994787873637E-030.362311452102434E+00 0.191936222893093E-010.258518345891082E-020.109774305627631E+00 -.678956495743090E-01-.847535774245336E-010.232392489249417E-01 0.986521218946578E+000.106117819809660E-020.449024629045529E-01 0.124017224428534E-030.574386556615052E-01-.199965617249553E-02 -.247780638305697E-010.321522084088771E+000.379770340137811E-01 -.428306904638573E+000.454704028913566E+000.379204249645586E+00 -.148852886838934E-02-.367461131823450E-01-.454704049118167E+00 -.369132510355556E+000.664495198760334E-020.334719861886340E-02 0.113293303776695E+00-.281077382106382E-020.819596959668489E-02 0.379111551975742E-010.321568225388857E-02-.459084942734722E-01 0.541417868140426E-010.284992838760775E+000.576708222071649E-01 -.319166382924372E-01-.850884680215138E+000.981709154419468E-01 -.314558014739248E+00-.238292299646862E-010.267247900942539E+00 -.476409274846684E-020.572696388851242E-01-.253434325420875E-05 0.314019523401166E-040.175619612277255E-010.268781992242801E-04 0.102137732079325E+00-.352118389928833E-05-.431151846300100E-01 0.194195952369355E+000.171383771689655E+00-.727889707064056E-01 -.105037796330727E+000.373070405104482E+00-.832876291198495E+00 0.185201328324870E+00-.210719287242549E-020.883704590081362E-01 0.759148616038630E-05-.985068757445580E-040.241611227450762E-01 -.826584349992673E-040.168592324349136E+000.109363536546192E-04 -.140286296725473E-03-.128215836815657E-040.494558244488533E-03 0.280847654126040E+000.321515679088376E-070.120434247248497E-06 -.156044392922250E-070.887469968549317E-040.309083310171081E-03 -.137384777211738E-04-.226540409047954E-02-.880128001169638E+00 -.382651653993193E-05-.108131101348007E-040.233963836825757E-04 0.270492489874145E-03-.122252666299678E-030.612356227618477E-02 0.382695975727179E+000.732428021226023E-020.547713996664140E-02 0.396049984501415E+00-.481141822977436E-01-.405642629586525E+00 0.635749564952352E+000.521347508869209E+000.148024935841334E-01 -.301295407799686E-030.723544959371664E-020.207642865415858E-03 -.348694792387385E-010.263550631173699E+000.889595566279424E-01 -.418984214602752E+000.500266357695299E+000.408119429597393E+00 -.363233885356471E-010.804413318688337E-01-.500266373002098E+00 -.265517664767941E+00-.164627094124487E-01-.292271209593851E-03 0.124794323490641E-010.336449804275239E-030.498076969884902E-03 0.271691736959086E-020.231277279264080E-03-.567655532785492E-01 0.271848648436447E-010.503661384603298E+000.655366565640398E-01 -.243230693129746E-01-.789632788520066E+000.183179034548534E-01 -.311651765431028E-01-.255025625534976E-010.334633855693646E+00 -.190063900887600E-030.353945762482508E-02-.977710956462515E-05 0.746309618330485E-040.131595722141013E-020.739405964402529E-04 0.119008502370693E-01-.173222930707446E-04-.555999356456072E-01 0.142824249504943E+000.430859451845448E+000.458944077528358E-01 -.115195465102762E+000.132957232431433E+00-.828429389734122E+00 0.298427846700954E-01-.960653777292320E-020.264770324901898E+00 0.294775292625976E-04-.222797414239782E-030.199648632405749E-02 -.221026344617562E-030.169463786498493E-010.399691019732668E-04 -.412776023938866E-020.252572320635840E-030.233873710864906E-01 0.259719891251546E+000.415140740182975E-030.113529818985204E-02 -.174804710873652E-020.578214115132270E-020.122117368574587E-01 -.751426870967600E-02-.124904020763724E+00-.845228958797211E+00 -.212620236485092E-02-.168622369330729E-020.211514253839871E-01 0.215369670240951E-01-.534820692965796E-02-.144346899834284E-06 0.267863054400291E+000.359203496211911E+000.331086374854943E-02 -.845474757581534E-080.632504086378518E+00-.235118751978227E-01 -.638143102372112E+000.422974828693201E+000.114871343439142E+00 0.183672600439000E-070.671269422302639E-020.141774326820363E+00 -.692748182182047E+00-.141774300990027E+000.692748182182314E+00 0.481957392698951E-040.270388157735588E-030.258091963527867E-04 -.154613472923139E-010.788913409868525E-020.166281063480095E+00 0.631548573348084E-01-.719098717124253E-02-.783605853008467E+00 0.133352995840027E-02-.155351765852490E-02-.469231283040379E-01 0.593097595003567E+00-.145124296629042E-040.363129440721168E-03 -.755130544285567E-050.322329789563514E-040.162865732101339E-03 0.337458039242355E-040.188676716333058E-02-.967983875236429E-05 -.280294852982924E-010.560451599699661E-010.283514625914695E+00 0.623656558031793E-01-.513514652564355E-010.206258387156799E-01 -.826238746166489E+000.239687498883366E-02-.329344008682935E-01 0.474308373685584E+000.161872833336829E-04-.895145426991688E-04 0.315360387518861E-03-.933730942829438E-040.280130679481694E-02 0.191092696904015E-04-.835451218901018E-02-.224824288339140E-02 0.516928270523294E-010.109704348827131E+000.108269387812490E-02 0.107731305293616E-010.427800356853278E-020.368562069578784E-01 0.485484135495873E-01-.102507986038446E-01-.552216485696899E+00 -.594260620325315E+00-.316691755671850E-01-.132825140699132E-07 0.364597166754599E+000.174700089420081E+00-.717406486290489E-02 0.359222945921040E+000.172123612118179E+000.707106781186543E+00 -.707106781186557E+000.101992154740172E+00-.498361637024495E+00 0.608782920354223E+000.608782912866900E+00-.563724703278934E-01 -.438434828311532E-020.716766147603742E+000.537258122841962E-01 -.692937766919190E+00-.627170199294769E-020.346820800292373E-01 -.597760582014308E-01-.390085053120361E-010.691950856253261E+00 0.704045963162265E-01-.714079956171652E+00-.518737623309080E-01 0.761022812732684E-020.159550167655143E-010.604843345813386E+00 0.321896613542082E+000.567209593954754E-010.237137403293247E-07 -.653010405795925E+00-.312895948443595E+000.707106728865803E+00 -.707106833507286E+000.115866760025710E+000.687858841009181E+00 0.115866760025706E+00-.115866777390875E+00-.687858841015537E+00 -.115866765820121E+000.199959993541363E-01-.999800060016923E+00 0.199959993541364E-01-.999800060016920E+000.591447559760272E+00 -.774079952713837E+000.225809678402336E+000.707106745792210E+00 -.707106816580882E+000.102933637605961E+000.691960495020240E+00 0.102933654691574E+00-.102933654674223E+00-.691960495026485E+00 -.102933660046180E+000.199959993541364E-01-.999800060016920E+00 0.199960012762684E-01-.999800059978472E+00-.127452310568665E-01 -.132034018886979E-060.193643357350621E+000.641757529728320E+00 0.127452468624267E-010.175461378776522E-06-.638150377049360E+00 -.378270719499168E+000.707106745792551E+00-.707106816580538E+00 0.735498311658631E-010.699414631300659E+000.735498231523910E-01 -.735498255093039E-01-.699414659275387E+00-.735498261761447E-01 0.199960012762683E-01-.999800059978476E+000.199960003152027E-01 -.999800059997703E+00-.793687288626499E-02-.801466233668395E-07 0.109332282606681E+000.788133320380449E+000.793689353370808E-02 0.133933796941923E-06-.397501359005163E+00-.456901524012506E+00 0.707106745794469E+00-.707106816578630E+000.677577761723365E-01 0.700583874311953E+000.677577840360550E-01-.677577956934772E-01 -.700583874313761E+00-.677577869993615E-010.199960022373348E-01 -.999800059959256E+000.199960012762687E-01-.999800059978472E+00 -.319883555175909E-03-.118986023366735E-070.281838347380330E-02 0.876754646848632E+000.319884871920509E-030.150806759592284E-07 -.160183057271965E-01-.480662620945026E+000.707106745795564E+00 -.707106816577532E+00-.890947474946424E-020.706994528505650E+00 -.890947463346475E-020.890947671897219E-02-.706994499014701E+00 0.890947653156449E-020.199960022373347E-01-.999800059959259E+00 0.199960012762683E-01-.999800059978472E+00-.260858972545533E-04 -.191844269302226E-080.122620469735823E-030.885535385661900E+00 0.260860624298151E-040.247588712962808E-08-.130637283259506E-02 -.464570078388519E+000.707106732355502E+00-.707106830017597E+00 -.541723283909854E-010.702944338249317E+00-.541723317379545E-01 0.541723443718538E-01-.702944299891371E+000.541723452463965E-01 0.199960003152022E-01-.999800059997696E+000.199959993541364E-01 -.999800060016920E+00-.239127687416373E-04-.151460465105004E-08 0.115672896862657E-030.885262435736919E+000.239129677845735E-04 0.257585781747041E-08-.119766065837865E-02-.465090282588456E+00 0.707106725206366E+00-.707106837166720E+00-.919589760709782E-01 0.695044669841039E+00-.919589734520017E-010.919589804407779E-01 -.695044669843202E+000.919589782786625E-010.199960022373347E-01 -.999800059959252E+000.199960022373348E-01-.999800059959256E+00 -.151924628664646E-03-.510312341108572E-080.114456686280757E-02 0.879637007792521E+000.151925412556267E-03-.760985148748386E-02 -.475583292900870E+000.707106745794441E+00-.707106816578655E+00 -.123882094148375E+000.685059468109205E+00-.123882083877434E+00 0.123882100598866E+00-.685059436248697E+000.123882101836301E+00 0.199960012762683E-01-.999800059978476E+000.199960012762682E-01 -.999800059978480E+00-.678767592186647E-02-.117643398718500E-06 0.687172030420897E-010.819622591650248E+000.678770879243693E-02 0.183330445795151E-06-.339959963271509E+00-.455885765406123E+00 0.707106745794739E+00-.707106816578357E+00-.139007785337744E+00 0.679230170872582E+00-.139007785337747E+000.139007815139815E+00 -.679230226703378E+000.139007815139786E+000.199960003152020E-01 -.999800059997686E+000.199960003152021E-01-.999800059997696E+00 -.141044682813303E-01-.262174622790849E-060.157938172071501E+00 0.601128701028703E+000.141045167897438E-01-.706247527620910E+00 -.338402681597202E+000.707106745794821E+00-.707106816578275E+00 -.267856550417132E+000.654410317897785E+000.267856566195439E+00 -.654410317899671E+000.199960012762682E-01-.999800059978476E+00 0.199960012762681E-01-.999800059978476E+000.593949158047806E+00 0.223352700169129E+00-.772876425427416E+00 0.202394105899437E-120.274823389968666E-14-.554892366794151E-15 -.819274160312709E-15-.668810055472496E-160.212241558104048E-12 0.526299506130443E-14-.489385623532121E-15-.677032376568762E-15 -.451623379287585E-150.374666605049989E-120.222425138831361E-13 -.181544572943050E-14-.147988975572570E-14-.186104552378963E-14 0.000000000000000E+000.000000000000000E+000.435189840959789E-14 -.382967060044728E-130.505291153767714E-160.000000000000000E+00 0.000000000000000E+000.435189840959789E-14-.226298717299133E-13 0.121146683837838E-140.000000000000000E+000.000000000000000E+00 0.435189840959789E-140.130556952287927E-130.445674391403092E-14 0.000000000000000E+000.000000000000000E+000.435189840959789E-14 -.783341737833116E-140.234227328474855E-140.108206124046458E-12 -.215883859283577E-14-.403946870939676E-15-.686616926286516E-15 -.862012111631899E-150.303533244284811E-130.138010344467711E-14 -.404018824222715E-15-.286385196638407E-15-.390704401891710E-15 0.273411624622911E-13-.765610157434584E-15-.268141684612874E-15 -.132194093079351E-15-.601621965854667E-150.000000000000000E+00 0.384762796083885E-13-.193731562836694E-15-.413645768293773E-14 -.114278485295537E-050.807508878162117E-13-.380818779406990E-13 0.223648500602427E-14-.909889585701067E-140.331562834926780E-05 0.285043306029678E-12-.207058352673703E-13-.636970533077854E-14 0.524252010357629E-140.269297853105648E-050.171627453082871E-14 0.717975632069722E-14-.527448437137286E-140.464287948246645E-13 0.771098257180396E-080.234809096656618E-14-.359395808792810E-14 0.665552106043155E-140.757280959611803E-140.143718570281886E-11 0.222572869532307E-14-.139716009607018E-130.780446860517369E-15 0.362157028369366E-130.536540168957500E-100.307875265929601E-14 -.705504318733115E-140.337799402074240E-140.500401555294291E-13 0.426280731858752E-080.913287848754867E-130.103614716445489E-13 -.522859350784418E-140.499148370186354E-140.478624017132153E-05 0.121456366975691E-130.101624213254850E-140.216701101200512E-14 -.345271197980365E-140.110880789697911E-050.301216196618491E-14 -.540428228214019E-14-.222140164388316E-140.434955330079947E-15 -.160601989555048E-050.157559231112031E-130.420001628718037E-12 0.150572252957974E-13-.606223423353496E-13-.281774303279372E-03 -.161762764929301E-12-.342092744508673E-120.108249355143259E-12 -.615731698119600E-120.114252946436998E-030.846620542762694E-13 -.152621157809399E-12-.109809342763844E-12-.217943874621490E-12 0.797723962847499E-050.180888084740301E-130.122644376958020E-12 0.888551767886481E-130.204169584974151E-120.639904466172473E-07 0.102694065070745E-130.185542222646612E-13-.980356568716921E-14 0.213689007015383E-130.148657983204524E-100.938171534597355E-14 0.386707150480676E-130.185686924559307E-130.629279530815653E-13 0.178538186267594E-090.303591605636916E-130.247507485473141E-12 0.601948765785340E-130.259328208787118E-130.825012119453497E-07 0.165489865824259E-130.126909717971805E-12-.809972621173125E-15 0.260221066762617E-120.440673145488575E-04-.577391192374903E-13 -.141685739715840E-13-.898379506962308E-14-.587589075806416E-13 0.854336895419281E-040.695114309023588E-14-.183400756501765E-12 -.351268034790456E-13-.212800439402798E-13-.786196346629773E-03 0.231704757800883E-140.428729786047385E-12-.921006657969298E-13 -.722393149668797E-13-.500822403978593E-04-.114151854183011E-12 -.219912598762636E-120.126673756206235E-12-.382620831589828E-12 0.297225488674877E-040.234508048410960E-12-.218856288176897E-12 -.406403766139363E-12-.198463290029409E-120.217128723459237E-04 0.756454004598282E-130.728205498076627E-130.218097882502026E-12 0.166565512837028E-120.194699855455599E-060.325953303999443E-13 0.141059018716547E-120.163148755045124E-140.168350227066847E-13 0.364655761535216E-100.318693236147873E-130.629300865896806E-12 0.832072227609808E-130.104391586556431E-120.219566882979375E-08 0.966294840559207E-130.105322792611619E-120.154817975688185E-11 -.129150687222302E-120.159284559755380E-060.255359618793750E-12 -.669568573719880E-12-.140319512989452E-11-.148808193119654E-11 0.174243935653877E-040.235964900478605E-13-.158921691210278E-14 0.427286687073893E-13-.383875253964354E-130.209458122839295E-04 0.695114255617233E-15-.778936609739444E-12-.555263495967613E-13 0.178057460686566E-12-.931728111057866E-040.162193337546363E-14 0.192082021351027E-12-.338830504552759E-13-.259959064560709E-13 -.102908168635522E-040.119780901141838E-12-.705626182733349E-13 0.477777856036666E-13-.122188353215107E-120.628204494195552E-05 0.360502341905674E-12-.158458353411481E-12-.107460877005768E-12 -.543852067739607E-130.999832651169842E-050.223928511470390E-12 0.219031617335137E-130.683930191759728E-130.993011534250549E-13 0.421065904949251E-070.795593192526987E-130.200393330802057E-14 -.544643938855520E-14-.129085088280889E-130.307220157212393E-10 0.769647462983260E-13-.708645844756138E-130.190209280278036E-13 0.140249871726619E-15-.129729632851381E-080.200188825456105E-12 0.416378030603160E-130.430348021674659E-13-.704010864682257E-14 0.216263094106671E-080.146886604283455E-120.841533706518667E-13 -.661595658689806E-13-.941058011231196E-140.391430381205002E-05 -.756476598943381E-13-.606765392737815E-140.229242559524678E-13 -.319044605764485E-130.548350629631716E-050.695114303103693E-15 -.146061553715816E-12-.276900163448222E-130.327090370418689E-14 -.241110654148327E-040.497470124823223E-120.178190122707317E-13 -.335610877544072E-150.269804823123547E-15-.754610311602206E-14 0.504652984537124E-120.132811426043152E-130.276385428565550E-15 0.171095749713042E-15-.565706170888985E-090.495616483348267E-12 0.270460386923519E-140.213967823565366E-160.114116167083434E-15 -.307378214952379E-090.148059343055948E-120.704938251717327E-15 0.796554343080852E-160.134418545397471E-15-.214702302708836E-10 0.264143427774681E-13-.393383383587686E-15-.224429000369457E-15 -.166387009518229E-15-.956414562064006E-130.275728664863706E-13 -.252625379126553E-140.290067003721533E-16-.372943254642494E-16 -.292904363272568E-110.108669533011201E-12-.373828633891879E-14 -.135252686834076E-150.811516121004296E-16-.248539101337132E-10 0.179802895868020E-12-.101106161740470E-13-.776828549128017E-16 -.185243730945928E-15-.969762553748463E-090.132071717589703E-12 -.156903353468787E-14-.269565415329845E-15-.275066750336520E-16 -.168359295253083E-080.123035231649352E-12-.239352379930970E-14 -.225554746116851E-150.935226996093998E-16-.392547043891108E-14 Matrix/inst/external/lund_a.mtx0000644000176200001440000010575510275502035016325 0ustar liggesusers%%MatrixMarket matrix coordinate real symmetric 147 147 1298 1 1 7.5000000000000e+07 2 1 9.6153881000000e+05 8 1 -1.2179486000000e+07 9 1 -2.6175210000000e+06 10 1 2.8846144000000e+07 11 1 5.7692300000000e+06 2 2 7.5000000000000e+07 3 2 9.6153869000000e+05 9 2 -7.4786312000000e+04 10 2 9.6153840000000e+06 11 2 -1.2179486000000e+07 12 2 -2.6175210000000e+06 13 2 2.8846144000000e+07 14 2 5.7692300000000e+06 3 3 7.5000000000000e+07 4 3 9.6153844000000e+05 12 3 -7.4786375000000e+04 13 3 9.6153840000000e+06 14 3 -1.2179486000000e+07 15 3 -2.6175210000000e+06 16 3 2.8846144000000e+07 17 3 5.7692310000000e+06 4 4 7.5000000000000e+07 5 4 9.6153869000000e+05 15 4 -7.4786312000000e+04 16 4 9.6153840000000e+06 17 4 -1.2179487000000e+07 18 4 -2.6175210000000e+06 19 4 2.8846144000000e+07 20 4 5.7692300000000e+06 5 5 7.5000000000000e+07 6 5 9.6153894000000e+05 18 5 -7.4786375000000e+04 19 5 9.6153840000000e+06 20 5 -1.2179486000000e+07 21 5 -2.6175210000000e+06 22 5 2.8846160000000e+07 23 5 5.7692310000000e+06 6 6 7.5000000000000e+07 7 6 9.6153894000000e+05 21 6 -7.4786312000000e+04 22 6 9.6153850000000e+06 23 6 -1.2179488000000e+07 24 6 -2.6175220000000e+06 25 6 2.8846160000000e+07 26 6 5.7692310000000e+06 7 7 4.4230768000000e+07 24 7 -7.4786312000000e+04 25 7 9.6153850000000e+06 26 7 -1.2179488000000e+07 27 7 -1.5405980000000e+06 28 7 1.4423078000000e+07 8 8 7.5000000000000e+07 9 8 2.6175210000000e+06 10 8 5.7692300000000e+06 11 8 2.8846144000000e+07 29 8 9.6153831000000e+05 9 9 5.0256406000000e+05 10 9 7.8125000000000e-03 11 9 7.8125000000000e-03 12 9 -1.2564100000000e+05 13 9 7.4786312000000e+04 14 9 -2.6175210000000e+06 29 9 7.4786312000000e+04 30 9 -1.2564100000000e+05 31 9 2.6175210000000e+06 32 9 -7.4786312000000e+04 10 10 1.4999998000000e+08 11 10 1.2820510000000e+06 12 10 -7.4786312000000e+04 13 10 1.9230770000000e+06 14 10 5.7692310000000e+06 29 10 -1.2179486000000e+07 30 10 -2.6175210000000e+06 31 10 2.8846144000000e+07 32 10 5.7692300000000e+06 11 11 1.4999998000000e+08 12 11 2.6175210000000e+06 13 11 5.7692300000000e+06 14 11 2.8846144000000e+07 29 11 9.6153840000000e+06 30 11 7.4786312000000e+04 31 11 5.7692300000000e+06 32 11 1.9230770000000e+06 12 12 5.0256406000000e+05 13 12 -1.0937500000000e-01 14 12 5.4687500000000e-02 15 12 -1.2564100000000e+05 16 12 7.4786312000000e+04 17 12 -2.6175210000000e+06 30 12 -2.4414062000000e-04 31 12 7.4786375000000e+04 32 12 7.4786312000000e+04 33 12 -1.2564100000000e+05 34 12 2.6175210000000e+06 35 12 -7.4786250000000e+04 13 13 1.4999998000000e+08 14 13 1.2820520000000e+06 15 13 -7.4786312000000e+04 16 13 1.9230770000000e+06 17 13 5.7692300000000e+06 30 13 -7.4786312000000e+04 31 13 9.6153840000000e+06 32 13 -1.2179487000000e+07 33 13 -2.6175210000000e+06 34 13 2.8846144000000e+07 35 13 5.7692300000000e+06 14 14 1.4999998000000e+08 15 14 2.6175210000000e+06 16 14 5.7692300000000e+06 17 14 2.8846144000000e+07 30 14 -7.4786375000000e+04 31 14 -1.2179486000000e+07 32 14 9.6153840000000e+06 33 14 7.4786312000000e+04 34 14 5.7692310000000e+06 35 14 1.9230770000000e+06 15 15 5.0256406000000e+05 16 15 1.4843750000000e-01 17 15 -1.1718750000000e-01 18 15 -1.2564100000000e+05 19 15 7.4786312000000e+04 20 15 -2.6175210000000e+06 33 15 -3.6621094000000e-04 34 15 7.4786375000000e+04 35 15 7.4786250000000e+04 36 15 -1.2564100000000e+05 37 15 2.6175210000000e+06 38 15 -7.4786312000000e+04 16 16 1.4999998000000e+08 17 16 1.2820510000000e+06 18 16 -7.4786312000000e+04 19 16 1.9230770000000e+06 20 16 5.7692310000000e+06 33 16 -7.4786250000000e+04 34 16 9.6153840000000e+06 35 16 -1.2179488000000e+07 36 16 -2.6175210000000e+06 37 16 2.8846160000000e+07 38 16 5.7692310000000e+06 17 17 1.4999998000000e+08 18 17 2.6175210000000e+06 19 17 5.7692310000000e+06 20 17 2.8846144000000e+07 33 17 -7.4786375000000e+04 34 17 -1.2179485000000e+07 35 17 9.6153830000000e+06 36 17 7.4786375000000e+04 37 17 5.7692300000000e+06 38 17 1.9230770000000e+06 18 18 5.0256406000000e+05 19 18 -1.3281250000000e-01 20 18 1.7187500000000e-01 21 18 -1.2564100000000e+05 22 18 7.4786312000000e+04 23 18 -2.6175210000000e+06 36 18 4.8828125000000e-04 37 18 7.4786312000000e+04 38 18 7.4786312000000e+04 39 18 -1.2564100000000e+05 40 18 2.6175210000000e+06 41 18 -7.4786250000000e+04 19 19 1.4999998000000e+08 20 19 1.2820510000000e+06 21 19 -7.4786375000000e+04 22 19 1.9230770000000e+06 23 19 5.7692300000000e+06 36 19 -7.4786250000000e+04 37 19 9.6153840000000e+06 38 19 -1.2179488000000e+07 39 19 -2.6175210000000e+06 40 19 2.8846144000000e+07 41 19 5.7692300000000e+06 20 20 1.4999998000000e+08 21 20 2.6175210000000e+06 22 20 5.7692300000000e+06 23 20 2.8846144000000e+07 36 20 -7.4786375000000e+04 37 20 -1.2179487000000e+07 38 20 9.6153850000000e+06 39 20 7.4786375000000e+04 40 20 5.7692310000000e+06 41 20 1.9230760000000e+06 21 21 5.0256412000000e+05 22 21 3.2031250000000e-01 23 21 -6.8750000000000e-01 24 21 -1.2564106000000e+05 25 21 7.4786375000000e+04 26 21 -2.6175220000000e+06 39 21 -1.2207031000000e-04 40 21 7.4786437000000e+04 41 21 7.4786187000000e+04 42 21 -1.2564106000000e+05 43 21 2.6175220000000e+06 44 21 -7.4786375000000e+04 22 22 1.5000002000000e+08 23 22 1.2820520000000e+06 24 22 -7.4786312000000e+04 25 22 1.9230770000000e+06 26 22 5.7692320000000e+06 39 22 -7.4786250000000e+04 40 22 9.6153840000000e+06 41 22 -1.2179490000000e+07 42 22 -2.6175220000000e+06 43 22 2.8846160000000e+07 44 22 5.7692320000000e+06 23 23 1.5000000000000e+08 24 23 2.6175220000000e+06 25 23 5.7692320000000e+06 26 23 2.8846160000000e+07 39 23 -7.4786437000000e+04 40 23 -1.2179483000000e+07 41 23 9.6153830000000e+06 42 23 7.4786312000000e+04 43 23 5.7692320000000e+06 44 23 1.9230770000000e+06 24 24 5.0256419000000e+05 25 24 4.1406250000000e-01 26 24 8.5937500000000e-02 27 24 -1.2564106000000e+05 28 24 7.4786375000000e+04 42 24 3.6621094000000e-04 43 24 7.4786312000000e+04 44 24 7.4786375000000e+04 45 24 -1.2564106000000e+05 46 24 2.6175220000000e+06 47 24 -7.4786375000000e+04 25 25 1.5000002000000e+08 26 25 1.2820510000000e+06 27 25 -7.4786312000000e+04 28 25 1.9230770000000e+06 42 25 -7.4786312000000e+04 43 25 9.6153860000000e+06 44 25 -1.2179491000000e+07 45 25 -2.6175220000000e+06 46 25 2.8846160000000e+07 47 25 5.7692320000000e+06 26 26 1.5000002000000e+08 27 26 2.6175220000000e+06 28 26 5.7692320000000e+06 42 26 -7.4786375000000e+04 43 26 -1.2179491000000e+07 44 26 9.6153880000000e+06 45 26 7.4786375000000e+04 46 26 5.7692320000000e+06 47 26 1.9230770000000e+06 27 27 2.5128206000000e+05 28 27 4.6367550000000e+05 45 27 3.6621094000000e-04 46 27 7.4786312000000e+04 47 27 7.4786375000000e+04 48 27 -6.2820531000000e+04 49 27 1.0769230000000e+06 28 28 7.5000016000000e+07 45 28 -7.4786312000000e+04 46 28 9.6153860000000e+06 47 28 -1.2179491000000e+07 48 28 -1.5405990000000e+06 49 28 1.4423080000000e+07 29 29 7.5000000000000e+07 30 29 2.6175210000000e+06 31 29 5.7692300000000e+06 32 29 2.8846144000000e+07 50 29 9.6153831000000e+05 30 30 5.0256406000000e+05 31 30 -1.0937500000000e-01 32 30 5.4687500000000e-02 33 30 -1.2564100000000e+05 34 30 7.4786250000000e+04 35 30 -2.6175210000000e+06 50 30 7.4786312000000e+04 51 30 -1.2564100000000e+05 52 30 2.6175210000000e+06 53 30 -7.4786312000000e+04 31 31 1.4999998000000e+08 32 31 1.2820520000000e+06 33 31 -7.4786312000000e+04 34 31 1.9230770000000e+06 35 31 5.7692310000000e+06 50 31 -1.2179486000000e+07 51 31 -2.6175210000000e+06 52 31 2.8846144000000e+07 53 31 5.7692300000000e+06 32 32 1.4999998000000e+08 33 32 2.6175210000000e+06 34 32 5.7692300000000e+06 35 32 2.8846144000000e+07 50 32 9.6153840000000e+06 51 32 7.4786312000000e+04 52 32 5.7692300000000e+06 53 32 1.9230770000000e+06 33 33 5.0256412000000e+05 34 33 2.4218750000000e-01 35 33 -3.8281250000000e-01 36 33 -1.2564106000000e+05 37 33 7.4786375000000e+04 38 33 -2.6175220000000e+06 51 33 -4.8828125000000e-04 52 33 7.4786312000000e+04 53 33 7.4786312000000e+04 54 33 -1.2564100000000e+05 55 33 2.6175210000000e+06 56 33 -7.4786375000000e+04 34 34 1.4999998000000e+08 35 34 1.2820510000000e+06 36 34 -7.4786312000000e+04 37 34 1.9230770000000e+06 38 34 5.7692310000000e+06 51 34 -7.4786250000000e+04 52 34 9.6153820000000e+06 53 34 -1.2179487000000e+07 54 34 -2.6175210000000e+06 55 34 2.8846160000000e+07 56 34 5.7692300000000e+06 35 35 1.4999998000000e+08 36 35 2.6175220000000e+06 37 35 5.7692310000000e+06 38 35 2.8846160000000e+07 51 35 -7.4786375000000e+04 52 35 -1.2179485000000e+07 53 35 9.6153840000000e+06 54 35 7.4786312000000e+04 55 35 5.7692310000000e+06 56 35 1.9230770000000e+06 36 36 5.0256412000000e+05 37 36 -2.3437500000000e-02 38 36 3.4375000000000e-01 39 36 -1.2564100000000e+05 40 36 7.4786250000000e+04 41 36 -2.6175210000000e+06 54 36 2.4414062000000e-04 55 36 7.4786312000000e+04 56 36 7.4786312000000e+04 57 36 -1.2564100000000e+05 58 36 2.6175210000000e+06 59 36 -7.4786312000000e+04 37 37 1.5000000000000e+08 38 37 1.2820520000000e+06 39 37 -7.4786312000000e+04 40 37 1.9230770000000e+06 41 37 5.7692310000000e+06 54 37 -7.4786312000000e+04 55 37 9.6153850000000e+06 56 37 -1.2179488000000e+07 57 37 -2.6175210000000e+06 58 37 2.8846144000000e+07 59 37 5.7692300000000e+06 38 38 1.5000000000000e+08 39 38 2.6175210000000e+06 40 38 5.7692310000000e+06 41 38 2.8846144000000e+07 54 38 -7.4786312000000e+04 55 38 -1.2179488000000e+07 56 38 9.6153850000000e+06 57 38 7.4786375000000e+04 58 38 5.7692300000000e+06 59 38 1.9230770000000e+06 39 39 5.0256406000000e+05 40 39 1.9531250000000e-01 41 39 -2.7343750000000e-01 42 39 -1.2564100000000e+05 43 39 7.4786312000000e+04 44 39 -2.6175210000000e+06 57 39 4.8828125000000e-04 58 39 7.4786312000000e+04 59 39 7.4786250000000e+04 60 39 -1.2564100000000e+05 61 39 2.6175210000000e+06 62 39 -7.4786312000000e+04 40 40 1.4999998000000e+08 41 40 1.2820510000000e+06 42 40 -7.4786375000000e+04 43 40 1.9230770000000e+06 44 40 5.7692310000000e+06 57 40 -7.4786250000000e+04 58 40 9.6153820000000e+06 59 40 -1.2179488000000e+07 60 40 -2.6175210000000e+06 61 40 2.8846144000000e+07 62 40 5.7692300000000e+06 41 41 1.4999998000000e+08 42 41 2.6175210000000e+06 43 41 5.7692300000000e+06 44 41 2.8846160000000e+07 57 41 -7.4786375000000e+04 58 41 -1.2179485000000e+07 59 41 9.6153850000000e+06 60 41 7.4786375000000e+04 61 41 5.7692310000000e+06 62 41 1.9230770000000e+06 42 42 5.0256412000000e+05 43 42 -5.5468750000000e-01 44 42 -3.2812500000000e-01 45 42 -1.2564106000000e+05 46 42 7.4786250000000e+04 47 42 -2.6175220000000e+06 60 42 -2.4414062000000e-04 61 42 7.4786312000000e+04 62 42 7.4786312000000e+04 63 42 -1.2564100000000e+05 64 42 2.6175210000000e+06 65 42 -7.4786375000000e+04 43 43 1.5000002000000e+08 44 43 1.2820510000000e+06 45 43 -7.4786375000000e+04 46 43 1.9230770000000e+06 47 43 5.7692320000000e+06 60 43 -7.4786312000000e+04 61 43 9.6153830000000e+06 62 43 -1.2179486000000e+07 63 43 -2.6175210000000e+06 64 43 2.8846144000000e+07 65 43 5.7692310000000e+06 44 44 1.5000002000000e+08 45 44 2.6175220000000e+06 46 44 5.7692320000000e+06 47 44 2.8846160000000e+07 60 44 -7.4786312000000e+04 61 44 -1.2179486000000e+07 62 44 9.6153830000000e+06 63 44 7.4786312000000e+04 64 44 5.7692300000000e+06 65 44 1.9230760000000e+06 45 45 5.0256419000000e+05 46 45 5.3906250000000e-01 47 45 1.5625000000000e-02 48 45 -1.2564106000000e+05 49 45 7.4786250000000e+04 63 45 -7.3242187000000e-04 64 45 7.4786562000000e+04 65 45 7.4786125000000e+04 66 45 -1.2564106000000e+05 67 45 2.6175220000000e+06 68 45 -7.4786250000000e+04 46 46 1.5000005000000e+08 47 46 1.2820520000000e+06 48 46 -7.4786375000000e+04 49 46 1.9230770000000e+06 63 46 -7.4786125000000e+04 64 46 9.6153870000000e+06 65 46 -1.2179498000000e+07 66 46 -2.6175230000000e+06 67 46 2.8846160000000e+07 68 46 5.7692320000000e+06 47 47 1.5000002000000e+08 48 47 2.6175220000000e+06 49 47 5.7692320000000e+06 63 47 -7.4786625000000e+04 64 47 -1.2179486000000e+07 65 47 9.6153900000000e+06 66 47 7.4786500000000e+04 67 47 5.7692330000000e+06 68 47 1.9230770000000e+06 48 48 2.5128206000000e+05 49 48 4.6367500000000e+05 66 48 -6.1035156000000e-04 67 48 7.4786312000000e+04 68 48 7.4786375000000e+04 69 48 -6.2820516000000e+04 70 48 1.0769230000000e+06 49 49 7.5000000000000e+07 66 49 -7.4786312000000e+04 67 49 9.6153830000000e+06 68 49 -1.2179487000000e+07 69 49 -1.5405980000000e+06 70 49 1.4423077000000e+07 50 50 7.5000000000000e+07 51 50 2.6175210000000e+06 52 50 5.7692310000000e+06 53 50 2.8846144000000e+07 71 50 9.6153856000000e+05 51 51 5.0256406000000e+05 52 51 1.8750000000000e-01 53 51 2.3437500000000e-02 54 51 -1.2564100000000e+05 55 51 7.4786312000000e+04 56 51 -2.6175210000000e+06 71 51 7.4786312000000e+04 72 51 -1.2564100000000e+05 73 51 2.6175210000000e+06 74 51 -7.4786312000000e+04 52 52 1.4999998000000e+08 53 52 1.2820510000000e+06 54 52 -7.4786312000000e+04 55 52 1.9230770000000e+06 56 52 5.7692300000000e+06 71 52 -1.2179487000000e+07 72 52 -2.6175210000000e+06 73 52 2.8846160000000e+07 74 52 5.7692310000000e+06 53 53 1.4999998000000e+08 54 53 2.6175210000000e+06 55 53 5.7692310000000e+06 56 53 2.8846144000000e+07 71 53 9.6153830000000e+06 72 53 7.4786312000000e+04 73 53 5.7692310000000e+06 74 53 1.9230770000000e+06 54 54 5.0256406000000e+05 55 54 -2.4218750000000e-01 56 54 -6.2500000000000e-02 57 54 -1.2564100000000e+05 58 54 7.4786250000000e+04 59 54 -2.6175210000000e+06 73 54 7.4786375000000e+04 74 54 7.4786250000000e+04 75 54 -1.2564100000000e+05 76 54 2.6175210000000e+06 77 54 -7.4786250000000e+04 55 55 1.5000000000000e+08 56 55 1.2820510000000e+06 57 55 -7.4786437000000e+04 58 55 1.9230760000000e+06 59 55 5.7692290000000e+06 72 55 -7.4786312000000e+04 73 55 9.6153850000000e+06 74 55 -1.2179488000000e+07 75 55 -2.6175210000000e+06 76 55 2.8846144000000e+07 77 55 5.7692300000000e+06 56 56 1.4999998000000e+08 57 56 2.6175210000000e+06 58 56 5.7692300000000e+06 59 56 2.8846144000000e+07 72 56 -7.4786375000000e+04 73 56 -1.2179487000000e+07 74 56 9.6153840000000e+06 75 56 7.4786375000000e+04 76 56 5.7692310000000e+06 77 56 1.9230770000000e+06 57 57 5.0256412000000e+05 58 57 2.0312500000000e-01 59 57 -2.4218750000000e-01 60 57 -1.2564100000000e+05 61 57 7.4786312000000e+04 62 57 -2.6175210000000e+06 75 57 8.5449219000000e-04 76 57 7.4786375000000e+04 77 57 7.4786250000000e+04 78 57 -1.2564100000000e+05 79 57 2.6175210000000e+06 80 57 -7.4786312000000e+04 58 58 1.4999998000000e+08 59 58 1.2820510000000e+06 60 58 -7.4786312000000e+04 61 58 1.9230770000000e+06 62 58 5.7692310000000e+06 75 58 -7.4786250000000e+04 76 58 9.6153850000000e+06 77 58 -1.2179488000000e+07 78 58 -2.6175210000000e+06 79 58 2.8846160000000e+07 80 58 5.7692320000000e+06 59 59 1.5000000000000e+08 60 59 2.6175210000000e+06 61 59 5.7692320000000e+06 62 59 2.8846160000000e+07 75 59 -7.4786312000000e+04 76 59 -1.2179485000000e+07 77 59 9.6153820000000e+06 78 59 7.4786312000000e+04 79 59 5.7692310000000e+06 80 59 1.9230770000000e+06 60 60 5.0256412000000e+05 61 60 2.2656250000000e-01 62 60 2.5000000000000e-01 63 60 -1.2564100000000e+05 64 60 7.4786375000000e+04 65 60 -2.6175210000000e+06 78 60 2.4414062000000e-04 79 60 7.4786312000000e+04 80 60 7.4786312000000e+04 81 60 -1.2564100000000e+05 82 60 2.6175210000000e+06 83 60 -7.4786312000000e+04 61 61 1.5000000000000e+08 62 61 1.2820510000000e+06 63 61 -7.4786312000000e+04 64 61 1.9230770000000e+06 65 61 5.7692300000000e+06 78 61 -7.4786312000000e+04 79 61 9.6153850000000e+06 80 61 -1.2179489000000e+07 81 61 -2.6175210000000e+06 82 61 2.8846160000000e+07 83 61 5.7692310000000e+06 62 62 1.5000000000000e+08 63 62 2.6175210000000e+06 64 62 5.7692310000000e+06 65 62 2.8846144000000e+07 78 62 -7.4786312000000e+04 79 62 -1.2179489000000e+07 80 62 9.6153860000000e+06 81 62 7.4786312000000e+04 82 62 5.7692320000000e+06 83 62 1.9230770000000e+06 63 63 5.0256412000000e+05 64 63 1.8750000000000e-01 65 63 -8.2031250000000e-01 66 63 -1.2564106000000e+05 67 63 7.4786125000000e+04 68 63 -2.6175220000000e+06 81 63 3.6621094000000e-04 82 63 7.4786500000000e+04 83 63 7.4786187000000e+04 84 63 -1.2564100000000e+05 85 63 2.6175210000000e+06 86 63 -7.4786187000000e+04 64 64 1.5000002000000e+08 65 64 1.2820520000000e+06 66 64 -7.4786500000000e+04 67 64 1.9230780000000e+06 68 64 5.7692330000000e+06 81 64 -7.4786250000000e+04 82 64 9.6153880000000e+06 83 64 -1.2179493000000e+07 84 64 -2.6175220000000e+06 85 64 2.8846160000000e+07 86 64 5.7692310000000e+06 65 65 1.5000002000000e+08 66 65 2.6175220000000e+06 67 65 5.7692330000000e+06 68 65 2.8846160000000e+07 81 65 -7.4786437000000e+04 82 65 -1.2179487000000e+07 83 65 9.6153850000000e+06 84 65 7.4786437000000e+04 85 65 5.7692310000000e+06 86 65 1.9230770000000e+06 66 66 5.0256425000000e+05 67 66 -6.9531250000000e-01 68 66 -1.5625000000000e-01 69 66 -1.2564106000000e+05 70 66 7.4786437000000e+04 84 66 -8.5449219000000e-04 85 66 7.4786312000000e+04 86 66 7.4786312000000e+04 87 66 -1.2564106000000e+05 88 66 2.6175220000000e+06 89 66 -7.4786500000000e+04 67 67 1.5000003000000e+08 68 67 1.2820520000000e+06 69 67 -7.4786250000000e+04 70 67 1.9230770000000e+06 84 67 -7.4786312000000e+04 85 67 9.6153820000000e+06 86 67 -1.2179484000000e+07 87 67 -2.6175210000000e+06 88 67 2.8846160000000e+07 89 67 5.7692320000000e+06 68 68 1.5000003000000e+08 69 68 2.6175220000000e+06 70 68 5.7692330000000e+06 84 68 -7.4786312000000e+04 85 68 -1.2179484000000e+07 86 68 9.6153820000000e+06 87 68 7.4786187000000e+04 88 68 5.7692310000000e+06 89 68 1.9230770000000e+06 69 69 2.5128212000000e+05 70 69 4.6367594000000e+05 87 69 9.7656250000000e-04 88 69 7.4786375000000e+04 89 69 7.4786375000000e+04 90 69 -6.2820547000000e+04 91 69 1.0769240000000e+06 70 70 7.5000016000000e+07 87 70 -7.4786375000000e+04 88 70 9.6153890000000e+06 89 70 -1.2179494000000e+07 90 70 -1.5405990000000e+06 91 70 1.4423084000000e+07 71 71 7.5000000000000e+07 72 71 2.6175210000000e+06 73 71 5.7692300000000e+06 74 71 2.8846144000000e+07 92 71 9.6153831000000e+05 72 72 5.0256406000000e+05 73 72 -1.5625000000000e-01 74 72 7.0312500000000e-02 75 72 -1.2564100000000e+05 76 72 7.4786250000000e+04 77 72 -2.6175210000000e+06 92 72 7.4786312000000e+04 93 72 -1.2564100000000e+05 94 72 2.6175210000000e+06 95 72 -7.4786312000000e+04 73 73 1.4999998000000e+08 74 73 1.2820520000000e+06 75 73 -7.4786375000000e+04 76 73 1.9230770000000e+06 77 73 5.7692310000000e+06 92 73 -1.2179486000000e+07 93 73 -2.6175210000000e+06 94 73 2.8846144000000e+07 95 73 5.7692300000000e+06 74 74 1.4999998000000e+08 75 74 2.6175210000000e+06 76 74 5.7692300000000e+06 77 74 2.8846144000000e+07 92 74 9.6153840000000e+06 93 74 7.4786375000000e+04 94 74 5.7692300000000e+06 95 74 1.9230760000000e+06 75 75 5.0256406000000e+05 76 75 7.0312500000000e-02 77 75 -1.4843750000000e-01 78 75 -1.2564100000000e+05 79 75 7.4786312000000e+04 80 75 -2.6175210000000e+06 93 75 -8.5449219000000e-04 94 75 7.4786375000000e+04 95 75 7.4786250000000e+04 96 75 -1.2564100000000e+05 97 75 2.6175210000000e+06 98 75 -7.4786312000000e+04 76 76 1.4999998000000e+08 77 76 1.2820510000000e+06 78 76 -7.4786375000000e+04 79 76 1.9230770000000e+06 80 76 5.7692310000000e+06 93 76 -7.4786250000000e+04 94 76 9.6153820000000e+06 95 76 -1.2179487000000e+07 96 76 -2.6175210000000e+06 97 76 2.8846144000000e+07 98 76 5.7692300000000e+06 77 77 1.4999998000000e+08 78 77 2.6175210000000e+06 79 77 5.7692300000000e+06 80 77 2.8846144000000e+07 93 77 -7.4786375000000e+04 94 77 -1.2179484000000e+07 95 77 9.6153830000000e+06 96 77 7.4786312000000e+04 97 77 5.7692300000000e+06 98 77 1.9230770000000e+06 78 78 5.0256412000000e+05 79 78 -2.4218750000000e-01 80 78 -2.5000000000000e-01 81 78 -1.2564100000000e+05 82 78 7.4786312000000e+04 83 78 -2.6175210000000e+06 96 78 -2.4414062000000e-04 97 78 7.4786312000000e+04 98 78 7.4786312000000e+04 99 78 -1.2564100000000e+05 100 78 2.6175210000000e+06 101 78 -7.4786375000000e+04 79 79 1.5000000000000e+08 80 79 1.2820510000000e+06 81 79 -7.4786312000000e+04 82 79 1.9230770000000e+06 83 79 5.7692320000000e+06 96 79 -7.4786312000000e+04 97 79 9.6153830000000e+06 98 79 -1.2179486000000e+07 99 79 -2.6175210000000e+06 100 79 2.8846144000000e+07 101 79 5.7692310000000e+06 80 80 1.5000000000000e+08 81 80 2.6175210000000e+06 82 80 5.7692310000000e+06 83 80 2.8846160000000e+07 96 80 -7.4786312000000e+04 97 80 -1.2179486000000e+07 98 80 9.6153830000000e+06 99 80 7.4786312000000e+04 100 80 5.7692300000000e+06 101 80 1.9230760000000e+06 81 81 5.0256419000000e+05 82 81 5.9375000000000e-01 83 81 -6.0937500000000e-01 84 81 -1.2564106000000e+05 85 81 7.4786375000000e+04 86 81 -2.6175220000000e+06 99 81 -7.3242187000000e-04 100 81 7.4786437000000e+04 101 81 7.4786250000000e+04 102 81 -1.2564106000000e+05 103 81 2.6175220000000e+06 104 81 -7.4786312000000e+04 82 82 1.5000003000000e+08 83 82 1.2820520000000e+06 84 82 -7.4786375000000e+04 85 82 1.9230770000000e+06 86 82 5.7692330000000e+06 99 82 -7.4786187000000e+04 100 82 9.6153850000000e+06 101 82 -1.2179493000000e+07 102 82 -2.6175220000000e+06 103 82 2.8846160000000e+07 104 82 5.7692320000000e+06 83 83 1.5000003000000e+08 84 83 2.6175220000000e+06 85 83 5.7692320000000e+06 86 83 2.8846160000000e+07 99 83 -7.4786500000000e+04 100 83 -1.2179487000000e+07 101 83 9.6153880000000e+06 102 83 7.4786375000000e+04 103 83 5.7692330000000e+06 104 83 1.9230770000000e+06 84 84 5.0256412000000e+05 85 84 8.5937500000000e-02 86 84 1.5781250000000e+00 87 84 -1.2564100000000e+05 88 84 7.4786250000000e+04 89 84 -2.6175200000000e+06 103 84 7.4786312000000e+04 104 84 7.4786312000000e+04 105 84 -1.2564100000000e+05 106 84 2.6175210000000e+06 107 84 -7.4786187000000e+04 85 85 1.5000000000000e+08 86 85 1.2820520000000e+06 87 85 -7.4786312000000e+04 88 85 1.9230770000000e+06 89 85 5.7692300000000e+06 102 85 -7.4786375000000e+04 103 85 9.6153870000000e+06 104 85 -1.2179490000000e+07 105 85 -2.6175210000000e+06 106 85 2.8846144000000e+07 107 85 5.7692300000000e+06 86 86 1.5000000000000e+08 87 86 2.6175200000000e+06 88 86 5.7692290000000e+06 89 86 2.8846144000000e+07 102 86 -7.4786375000000e+04 103 86 -1.2179490000000e+07 104 86 9.6153870000000e+06 105 86 7.4786437000000e+04 106 86 5.7692300000000e+06 107 86 1.9230770000000e+06 87 87 5.0256400000000e+05 88 87 -1.2890625000000e+00 89 87 -1.1250000000000e+00 90 87 -1.2564100000000e+05 91 87 7.4786187000000e+04 105 87 -8.5449219000000e-04 106 87 7.4786250000000e+04 107 87 7.4786312000000e+04 108 87 -1.2564100000000e+05 109 87 2.6175200000000e+06 110 87 -7.4786312000000e+04 88 88 1.4999998000000e+08 89 88 1.2820510000000e+06 90 88 -7.4786437000000e+04 91 88 1.9230770000000e+06 105 88 -7.4786312000000e+04 106 88 9.6153800000000e+06 107 88 -1.2179482000000e+07 108 88 -2.6175200000000e+06 109 88 2.8846144000000e+07 110 88 5.7692280000000e+06 89 89 1.4999998000000e+08 90 89 2.6175220000000e+06 91 89 5.7692310000000e+06 105 89 -7.4786375000000e+04 106 89 -1.2179482000000e+07 107 89 9.6153820000000e+06 108 89 7.4786312000000e+04 109 89 5.7692280000000e+06 110 89 1.9230760000000e+06 90 90 2.5128206000000e+05 91 90 4.6367419000000e+05 108 90 -8.5449219000000e-04 109 90 7.4786250000000e+04 110 90 7.4786312000000e+04 111 90 -6.2820488000000e+04 112 90 1.0769230000000e+06 91 91 7.5000000000000e+07 108 91 -7.4786312000000e+04 109 91 9.6153800000000e+06 110 91 -1.2179482000000e+07 111 91 -1.5405980000000e+06 112 91 1.4423071000000e+07 92 92 7.5000000000000e+07 93 92 2.6175210000000e+06 94 92 5.7692310000000e+06 95 92 2.8846160000000e+07 113 92 9.6153850000000e+05 93 93 5.0256412000000e+05 94 93 7.0312500000000e-01 95 93 -1.3281250000000e-01 96 93 -1.2564106000000e+05 97 93 7.4786375000000e+04 98 93 -2.6175220000000e+06 113 93 7.4786312000000e+04 114 93 -1.2564106000000e+05 115 93 2.6175220000000e+06 116 93 -7.4786375000000e+04 94 94 1.5000000000000e+08 95 94 1.2820510000000e+06 96 94 -7.4786250000000e+04 97 94 1.9230770000000e+06 98 94 5.7692310000000e+06 113 94 -1.2179488000000e+07 114 94 -2.6175220000000e+06 115 94 2.8846160000000e+07 116 94 5.7692320000000e+06 95 95 1.5000000000000e+08 96 95 2.6175220000000e+06 97 95 5.7692320000000e+06 98 95 2.8846160000000e+07 113 95 9.6153840000000e+06 114 95 7.4786250000000e+04 115 95 5.7692320000000e+06 116 95 1.9230770000000e+06 96 96 5.0256412000000e+05 97 96 2.8906250000000e-01 98 96 3.9843750000000e-01 99 96 -1.2564100000000e+05 100 96 7.4786375000000e+04 101 96 -2.6175210000000e+06 114 96 2.4414062000000e-04 115 96 7.4786250000000e+04 116 96 7.4786375000000e+04 117 96 -1.2564100000000e+05 118 96 2.6175210000000e+06 119 96 -7.4786312000000e+04 97 97 1.5000000000000e+08 98 97 1.2820510000000e+06 99 97 -7.4786312000000e+04 100 97 1.9230770000000e+06 101 97 5.7692300000000e+06 114 97 -7.4786437000000e+04 115 97 9.6153870000000e+06 116 97 -1.2179488000000e+07 117 97 -2.6175210000000e+06 118 97 2.8846160000000e+07 119 97 5.7692310000000e+06 98 98 1.5000000000000e+08 99 98 2.6175210000000e+06 100 98 5.7692310000000e+06 101 98 2.8846144000000e+07 114 98 -7.4786250000000e+04 115 98 -1.2179491000000e+07 116 98 9.6153850000000e+06 117 98 7.4786312000000e+04 118 98 5.7692310000000e+06 119 98 1.9230770000000e+06 99 99 5.0256412000000e+05 100 99 2.5000000000000e-01 101 99 -2.7343750000000e-01 102 99 -1.2564100000000e+05 103 99 7.4786187000000e+04 104 99 -2.6175210000000e+06 117 99 3.6621094000000e-04 118 99 7.4786500000000e+04 119 99 7.4786187000000e+04 120 99 -1.2564100000000e+05 121 99 2.6175210000000e+06 122 99 -7.4786187000000e+04 100 100 1.5000000000000e+08 101 100 1.2820520000000e+06 102 100 -7.4786437000000e+04 103 100 1.9230780000000e+06 104 100 5.7692310000000e+06 117 100 -7.4786250000000e+04 118 100 9.6153880000000e+06 119 100 -1.2179493000000e+07 120 100 -2.6175220000000e+06 121 100 2.8846160000000e+07 122 100 5.7692310000000e+06 101 101 1.5000000000000e+08 102 101 2.6175220000000e+06 103 101 5.7692320000000e+06 104 101 2.8846160000000e+07 117 101 -7.4786437000000e+04 118 101 -1.2179487000000e+07 119 101 9.6153850000000e+06 120 101 7.4786437000000e+04 121 101 5.7692310000000e+06 122 101 1.9230770000000e+06 102 102 5.0256412000000e+05 103 102 -1.5234375000000e+00 104 102 -7.8125000000000e-02 105 102 -1.2564100000000e+05 106 102 7.4786250000000e+04 107 102 -2.6175210000000e+06 120 102 -8.5449219000000e-04 121 102 7.4786312000000e+04 122 102 7.4786312000000e+04 123 102 -1.2564100000000e+05 124 102 2.6175200000000e+06 125 102 -7.4786250000000e+04 103 103 1.5000000000000e+08 104 103 1.2820520000000e+06 105 103 -7.4786437000000e+04 106 103 1.9230770000000e+06 107 103 5.7692300000000e+06 120 103 -7.4786312000000e+04 121 103 9.6153820000000e+06 122 103 -1.2179484000000e+07 123 103 -2.6175200000000e+06 124 103 2.8846144000000e+07 125 103 5.7692280000000e+06 104 104 1.5000000000000e+08 105 104 2.6175210000000e+06 106 104 5.7692300000000e+06 107 104 2.8846144000000e+07 120 104 -7.4786312000000e+04 121 104 -1.2179484000000e+07 122 104 9.6153820000000e+06 123 104 7.4786312000000e+04 124 104 5.7692300000000e+06 125 104 1.9230760000000e+06 105 105 5.0256419000000e+05 106 105 9.4531250000000e-01 107 105 -1.0156250000000e+00 108 105 -1.2564106000000e+05 109 105 7.4786625000000e+04 110 105 -2.6175230000000e+06 123 105 -1.2207031000000e-04 124 105 7.4786312000000e+04 125 105 7.4786250000000e+04 126 105 -1.2564106000000e+05 127 105 2.6175230000000e+06 128 105 -7.4786625000000e+04 106 106 1.5000002000000e+08 107 106 1.2820510000000e+06 108 106 -7.4786062000000e+04 109 106 1.9230780000000e+06 110 106 5.7692330000000e+06 123 106 -7.4786312000000e+04 124 106 9.6153820000000e+06 125 106 -1.2179482000000e+07 126 106 -2.6175220000000e+06 127 106 2.8846160000000e+07 128 106 5.7692340000000e+06 107 107 1.5000002000000e+08 108 107 2.6175220000000e+06 109 107 5.7692350000000e+06 110 107 2.8846160000000e+07 123 107 -7.4786250000000e+04 124 107 -1.2179482000000e+07 125 107 9.6153790000000e+06 126 107 7.4786062000000e+04 127 107 5.7692330000000e+06 128 107 1.9230780000000e+06 108 108 5.0256425000000e+05 109 108 4.2109375000000e+00 110 108 1.6250000000000e+00 111 108 -1.2564100000000e+05 112 108 7.4786500000000e+04 127 108 7.4786687000000e+04 128 108 7.4786250000000e+04 129 108 -1.2564119000000e+05 130 108 2.6175240000000e+06 131 108 -7.4786125000000e+04 109 109 1.5000006000000e+08 110 109 1.2820520000000e+06 111 109 -7.4786187000000e+04 112 109 1.9230770000000e+06 126 109 -7.4786250000000e+04 127 109 9.6154010000000e+06 128 109 -1.2179514000000e+07 129 109 -2.6175250000000e+06 130 109 2.8846192000000e+07 131 109 5.7692380000000e+06 110 110 1.5000005000000e+08 111 110 2.6175210000000e+06 112 110 5.7692320000000e+06 126 110 -7.4786687000000e+04 127 110 -1.2179502000000e+07 128 110 9.6154010000000e+06 129 110 7.4786687000000e+04 130 110 5.7692390000000e+06 131 110 1.9230790000000e+06 111 111 2.5128194000000e+05 112 111 4.6367419000000e+05 129 111 9.7656250000000e-04 130 111 7.4785812000000e+04 131 111 7.4786750000000e+04 132 111 -6.2820441000000e+04 133 111 1.0769220000000e+06 112 112 7.4999952000000e+07 129 112 -7.4786750000000e+04 130 112 9.6153810000000e+06 131 112 -1.2179472000000e+07 132 112 -1.5405970000000e+06 133 112 1.4423061000000e+07 113 113 7.5000000000000e+07 114 113 2.6175220000000e+06 115 113 5.7692310000000e+06 116 113 2.8846160000000e+07 134 113 9.6153850000000e+05 114 114 5.0256419000000e+05 115 114 -4.6875000000000e-02 116 114 -2.1093750000000e-01 117 114 -1.2564106000000e+05 118 114 7.4786375000000e+04 119 114 -2.6175220000000e+06 134 114 7.4786312000000e+04 135 114 -1.2564106000000e+05 136 114 -7.4786375000000e+04 115 115 1.5000002000000e+08 116 115 1.2820510000000e+06 117 115 -7.4786312000000e+04 118 115 1.9230770000000e+06 119 115 5.7692310000000e+06 134 115 -1.2179488000000e+07 135 115 -2.6175220000000e+06 136 115 5.7692320000000e+06 116 116 1.5000002000000e+08 117 116 2.6175220000000e+06 118 116 5.7692320000000e+06 119 116 2.8846160000000e+07 134 116 9.6153840000000e+06 135 116 7.4786250000000e+04 136 116 1.9230770000000e+06 117 117 5.0256419000000e+05 118 117 7.8125000000000e-03 119 117 -1.4843750000000e-01 120 117 -1.2564106000000e+05 121 117 7.4786312000000e+04 122 117 -2.6175220000000e+06 135 117 2.4414062000000e-04 136 117 7.4786375000000e+04 137 117 -1.2564100000000e+05 138 117 -7.4786312000000e+04 118 118 1.5000002000000e+08 119 118 1.2820510000000e+06 120 118 -7.4786437000000e+04 121 118 1.9230770000000e+06 122 118 5.7692310000000e+06 135 118 -7.4786437000000e+04 136 118 -1.2179488000000e+07 137 118 -2.6175210000000e+06 138 118 5.7692310000000e+06 119 119 1.5000002000000e+08 120 119 2.6175220000000e+06 121 119 5.7692310000000e+06 122 119 2.8846160000000e+07 135 119 -7.4786250000000e+04 136 119 9.6153850000000e+06 137 119 7.4786312000000e+04 138 119 1.9230770000000e+06 120 120 5.0256412000000e+05 121 120 2.3437500000000e-02 122 120 2.8125000000000e-01 123 120 -1.2564106000000e+05 124 120 7.4786500000000e+04 125 120 -2.6175220000000e+06 137 120 2.4414062000000e-04 138 120 7.4786375000000e+04 139 120 -1.2564100000000e+05 140 120 -7.4786500000000e+04 121 121 1.5000000000000e+08 122 121 1.2820510000000e+06 123 121 -7.4786187000000e+04 124 121 1.9230770000000e+06 125 121 5.7692310000000e+06 137 121 -7.4786437000000e+04 138 121 -1.2179482000000e+07 139 121 -2.6175210000000e+06 140 121 5.7692320000000e+06 122 122 1.5000002000000e+08 123 122 2.6175210000000e+06 124 122 5.7692320000000e+06 125 122 2.8846160000000e+07 137 122 -7.4786125000000e+04 138 122 9.6153810000000e+06 139 122 7.4786187000000e+04 140 122 1.9230770000000e+06 123 123 5.0256400000000e+05 124 123 1.1640625000000e+00 125 123 1.3359375000000e+00 126 123 -1.2564100000000e+05 127 123 7.4786312000000e+04 128 123 -2.6175200000000e+06 139 123 9.7656250000000e-04 140 123 7.4786375000000e+04 141 123 -1.2564100000000e+05 142 123 -7.4786187000000e+04 124 124 1.4999998000000e+08 125 124 1.2820510000000e+06 126 124 -7.4786312000000e+04 127 124 1.9230760000000e+06 128 124 5.7692280000000e+06 139 124 -7.4786375000000e+04 140 124 -1.2179494000000e+07 141 124 -2.6175220000000e+06 142 124 5.7692310000000e+06 125 125 1.4999998000000e+08 126 125 2.6175200000000e+06 127 125 5.7692280000000e+06 128 125 2.8846144000000e+07 139 125 -7.4786312000000e+04 140 125 9.6153890000000e+06 141 125 7.4786500000000e+04 142 125 1.9230770000000e+06 126 126 5.0256406000000e+05 127 126 -3.1093750000000e+00 128 126 -2.7187500000000e+00 129 126 -1.2564106000000e+05 130 126 7.4785812000000e+04 131 126 -2.6175220000000e+06 141 126 -1.2207031000000e-04 142 126 7.4786250000000e+04 143 126 -1.2564094000000e+05 144 126 -7.4786125000000e+04 127 127 1.5000000000000e+08 128 127 1.2820520000000e+06 129 127 -7.4786937000000e+04 130 127 1.9230780000000e+06 131 127 5.7692350000000e+06 141 127 -7.4786312000000e+04 142 127 -1.2179482000000e+07 143 127 -2.6175190000000e+06 144 127 5.7692270000000e+06 128 128 1.5000002000000e+08 129 128 2.6175230000000e+06 130 128 5.7692330000000e+06 131 128 2.8846160000000e+07 141 128 -7.4786250000000e+04 142 128 9.6153790000000e+06 143 128 7.4786375000000e+04 144 128 1.9230750000000e+06 129 129 5.0256425000000e+05 130 129 -3.5390625000000e+00 131 129 1.3046875000000e+00 132 129 -1.2564100000000e+05 133 129 7.4786562000000e+04 143 129 7.3242187000000e-04 144 129 7.4786250000000e+04 145 129 -1.2564100000000e+05 146 129 -7.4786562000000e+04 130 130 1.5000005000000e+08 131 130 1.2820500000000e+06 132 130 -7.4786062000000e+04 133 130 1.9230760000000e+06 143 130 -7.4786250000000e+04 144 130 -1.2179474000000e+07 145 130 -2.6175200000000e+06 146 130 5.7692300000000e+06 131 131 1.5000000000000e+08 132 131 2.6175200000000e+06 133 131 5.7692300000000e+06 143 131 -7.4786250000000e+04 144 131 9.6153740000000e+06 145 131 7.4786000000000e+04 146 131 1.9230760000000e+06 132 132 2.5128200000000e+05 133 132 4.6367700000000e+05 145 132 9.7656250000000e-04 146 132 7.4786375000000e+04 147 132 -6.2820547000000e+04 133 133 7.4999984000000e+07 145 133 -7.4786375000000e+04 146 133 -1.2179494000000e+07 147 133 -1.5405990000000e+06 134 134 4.4230768000000e+07 135 134 1.5405980000000e+06 136 134 1.4423078000000e+07 135 135 2.5128206000000e+05 136 135 -4.6367525000000e+05 137 135 -6.2820520000000e+04 138 135 -1.0769230000000e+06 136 136 7.5000000000000e+07 137 136 1.5405980000000e+06 138 136 1.4423078000000e+07 137 137 2.5128206000000e+05 138 137 -4.6367462000000e+05 139 137 -6.2820488000000e+04 140 137 -1.0769230000000e+06 138 138 7.4999984000000e+07 139 138 1.5405980000000e+06 140 138 1.4423071000000e+07 139 139 2.5128206000000e+05 140 139 -4.6367625000000e+05 141 139 -6.2820543000000e+04 142 139 -1.0769240000000e+06 140 140 7.5000016000000e+07 141 140 1.5405990000000e+06 142 140 1.4423084000000e+07 141 141 2.5128206000000e+05 142 141 -4.6367419000000e+05 143 141 -6.2820488000000e+04 144 141 -1.0769230000000e+06 142 142 7.5000000000000e+07 143 142 1.5405980000000e+06 144 142 1.4423071000000e+07 143 143 2.5128187000000e+05 144 143 -4.6367400000000e+05 145 143 -6.2820441000000e+04 146 143 -1.0769220000000e+06 144 144 7.4999936000000e+07 145 144 1.5405970000000e+06 146 144 1.4423061000000e+07 145 145 2.5128200000000e+05 146 145 -4.6367694000000e+05 147 145 -6.2820543000000e+04 146 146 7.4999984000000e+07 147 146 1.5405990000000e+06 147 147 1.2564106000000e+05 Matrix/inst/external/CAex_slots.rda0000644000176200001440000000321010464427703017054 0ustar liggesuserskXi:P I$9)PɤR%+l$eqQE(.j)PH'9r_w~uz};9@Y2~SsG_7EZ(x񸟫_m lk AcQod EH CNH !g-j8rA8@&2A5DHBnH""34CHtrGXI?B4Y#$B6h2F#}pkI:u Ѐ߃s0`=?.cs>h*Gh6 B(-BKP8@+*C(%$3@P ڇtteLNlt")GW5TQ HEkT͚~),? 3&vnX=z;HD_ߋ4s`yVw #/8h28hwdA=@'8I7,惽`FiKSQHrک7䑎̺.:n~?#a0Lޣ9P[hmͽu+p5z^lV=O´ּы-vh8,Xu+m0u`ˍ?pt$0Mg)* aJ]8!S?A⍟ƮyeJe'|[SUV8ڵe,XEtS.jtL8w57ulsEu#=:sbCI{l73(7zQ,Zr؉]1V<*ߎ7ܰBG>T9>nZurÊծ [)7vmeIwC(7 f{sC [kZұrJ_Nˬ Z]k)N(7DM) D_Ga"֍z5kSnXygPS`Q50rnX VK UKܰ2hזB͠O 3Iv#lj1T-&SnX빬owfHa'4A2kܸfŌ4Nhx^faYMatJٞ; N}CaE'J0&o(7Lqru,0a{c- 冽g~= y*^QPnlEx |srd' J^jSPn,Aկ ?2M}Ca^kRPnlX|9 0 4jQPn|}A7&SSk99ދrM>7nLɍsZ7$1=rӝOo(7L%|p7I T)N{+ s1 Matrix/inst/external/USCounties_slots.rda0000644000176200001440000007321310770571602020305 0ustar liggesusers},=On!&@$ <[p@[m՛oUWW̬/FQ9t% Ր+.1*jIΧa"6)[8*1rYP]ռ߮$#/x{Ȼwu =^I18ȣB}Q,LPk9ڗ ~<>uK$(mY|m/u|)ӓ+yEs:z#r' 6M#+"]+"ö:y?`GVvS>tէ^G Ę P.18BB#M%f~#NKowy.4ab6Cy!?C>^~9_̒ƉY1x!KLg= ye)^'\_ qQbQ_KKyG%V\Rlsl\[̦,^Z_%XڔcIKUk1u=$ZzLkPV؉yxɻ&ۼWe=Rw /jebw5)ŲJr:Nobb6,'a|O`O?!q)K捠w77K IHWb/˵dRqMbwx1NbON̂WB@,=bzM_~7lړ؟Gx_xH;.#CmdڼAǁNμrǘ8m=e13c{t ą ^D3xO>kOy`w^]aPOYϼsS&}9nCނ `*Xb1q(徎zZٳXϿԋx"q6v]##$Kb؈`<s\Gr8ۅ%x%qޤyzp8mQ$9חg]϶ODЕxulStr*y Ǩ?YLR)ƞ=3OkMذء=>?_&~WcYȁج{/;BlYŞ/Uu /׉׉Lr-}|c];ዘ/>Mw>]Y}8pajlGllXlqΟahhdlETUCʟMS-Oщ_~H},)냔S|'bgԩg3w,$$a1ke4*%N{ݠ~\<1+MP^>HYkO^Ϭ\«I^Ιog6~ƙ.ђے{0*(Oow 1Wq\r߈'+1b$bCϒ듫,45XUra \e%1_Rfy]m:\Mxˋ?f]{sk9\i?%{{)Թ딲\~L-b,/va{:َ/Lٷbg'.pr۲ϣM8`JESy][v"_ޞ^1I"&OnF,v`_F;Yëg_o1b ܃299m{|L~{ zXK;"~t-yE ֥KcuvicֱaGb&XDV$Ls8!I& [QfF~!iԱXjfY?zݚv`NaLbHblLG9GDؖ8DܒĸD X<|Og0A뿌]I9YןV"򹊲9z\H~z|$N6aEk{uqwKK]w{ŷ ^Q]k-rv;y oɇ`umԱQ?AG_X^=l{r򈭒!Nc36-r"Ƨy:;em KgXXz=?;Yd}>!>OFL\߹"b䳔Ip|xg]zm<=zO3&Kw;~BܙyYw*#bVė!FM%kG<|Āc[SCmhR]-88%1Z;|MO}z.#=SW1榳^/ȜX, |]O=E:iM= Qgȴ{C-q=g]N?]x FZ=Ӵlt@z2u1pOQg_uKJX#փyOp1uZ~Kc%߈?Ә3C'|&mYR_M|1ye]2j䱴Յ<2Wc)~r]${qli˺<ڠ/B^k, oI{-ݩ;.n](ԳZ1Ʀ&Nk3jӥm<0F˦#n{2:%^'Oˆ{\u9]I{7'i{z-uu+Yf wimJ]9qCcJz?4}x<&yg++d~kuy MbBJ=q̧҇zO`{-{9Gl^K۴1}>¦ ckr5}:KIceZZl {nq\qV`qhqat3ϳ^Q̹kiĤiĚiYGXM%Vø$k+Aõ1}=ӯ1u*濌en&t)@4ƌ]w1Va._ͺe ݻ~/yJn'vKf0n?"ߍ~r>sw9׆xd8~XAY%ƹ bb|a=3l,^ >U^YNHvԱ 'ü.u;_~L^[Kl˳ś1fgu1Õ)]ޓIʃ/3W43wM"-adg#.D=>-b,(g%#3:i),2v̬Nf؂<2KSco #,|O8"e'K.yوƴ^AY+2ۺ "yGoըc?^[Vڶlڹg梎k50Z=!O+P"t?;D6m{Ư23ۣg2,ĕ`Q^]F$mێ<$^;2]:ynn[ޔ weeB93gxq2-l,'G{2S,]m;$#F̖,3Kܶ+ycfО` ume0،o@|!K;aڵ7lF0[w%;KL|^Vi㦖u=OnG0eܟ6e!1OObt ~fehA9ޓɾqk1ށE?N GrLn}G[{6Bx߅+s@~Q#\"~ `N.<*Oh6,/ene224sl^G\2mkxwdJ9gĹW뭲_r%mqf5#󼇭AyfdE{3W3/Y;{m=:0ϱA|yu^um%u(F|KϞg^7S_יwt0a[ټػ-^"t|{?^ d>:}Rt1۳Wj3}Gv^L'w-_\KDϣ hGO7g3QgAٔg7Snνr/o~ inףل+ܶCkr%}_x~+9NJh_Fc'wUlofwc5dضf+6I0ExײAά rgg1f7bӘ>afǘ?f1|`ym5fw鈿s++簉˔}sF3l^^.+!t.i[l9ʚ$kdo䘽˔yNg'O}o7{1s-M>ļ˲G=~Oxe$?Wq{Ҟe>8Ҽc%{"̾z|/Y뒞EELg%io2c"Li_X#&.yauk/?g!2{=!GryPTu\0 1u9׹A]g]=|7̃ri0A[ʍ`_*#-7μ^YxiB>fI[ o9e=<=m,|d+I!F(/bĩ6&LE-Qe}Rn!꧟(^FY-&f,9cCNGR?Ƨb2<^ݞY;~w,u;w2M~#N˝ubxcգN[^V'FǃND{%8"I܇9oۓX/+"&!!!]jf״~by~%\k7bܟ49L+t =M޿m,W kswz^7yzt6t1"gMOr<;8.Rޗ1yb*󼢔A|5'eOd˝voIb˼.u[g{o8 )&0?!!>OR.Y[wiD=>SsyD%7YW e^(rA|mg6Oxgʲ+rK{XVλyH>oui0vX~)#yLk\+P_'/Z[26/_^ߦK~הu|:72?7o#,2=֦sʢ XZ^;І߇<O>km  Ɍ8 L_'M6!o3c]0ɽ!5y]~[ܓ}ϓe9{-;^u=1mX@,ߒ2msW~gY;`݊ v yoPVti u&zl?1ْ^>umyw߂eXʷ]'m{[_9F~3qyy><9GܬkGe KNy',+,~c?a{dsv+f<d^Ўy̧1~<~˜#m0iSP>Ke>"q)oe]P[/%ϬΉVo)1^ y6O!i2u!53'SlZ!ө^x-YffJ5s B ԽӼUM%fwM'w=|lqnaz|(K3K?esbP@(lߗ cRYݷSUw~!osf0=02O?߳o<s!@K~[KA8k#n,4lZaܢ0ofeyٳM9(!EI.VƯyda~::.1}^a@[++uGAa ֍Xur18u{6;Sgʳ e²V2L[ڦ;;0 ^[:p:V vnB6=(u';/hy(sŨId2rήf\2OLszCšxi ?`%w۬3`-M]ᱜ0x坟8JWr5X-kIb['d ]X^6GeDt/`Sږ-l4#dAGZ@Yݨv̏]#*~ߖy=A{Q#;oMݛ2rt,uݟʴ: RϾy Q&OCw,۷ Gq ?dwޏ1ޔwӮ3G+{xf~^~#m[Qތl'PW@xU؇uI=G|SqW}wuM7v Qؽg 2Fwg6~DXY{*ake3B‰kg穴؞<ŤcQ83j6=N؎iQ66gt>}a<3"jeጨA$ 暅ChQ>){6o7ŸyMƵ 䵗A<FI+/ -\L{gki{ؒ m32O_b.\82tUJd ➂p3d/mBX-0o+`SDA{ͼWB9- kd~ >k:nb9,h0)`.XYs3u< /Ŭ}8>Sܦp'!>i#o1]bl준yKeY ۶ k[YdM2 ^!oGy+<2f?2WO,&23mJzb[\;>r5ͽbQFPO1CE^oY~vi?ߓ:]y]BekźՃë_e }CL0*|E<`T%a1߱3SNaJal)|ѓ`PU8k@RwUx>[8'ՠLyGVDl\O>آnb7c)9غQ3utou16Oq1VRwq {B*.no_N;Y%Opzacbyi>"&b;8k1&:/'<>c!Nv FN^/IQۧ^:>M"rʺپ"bl;DVeqg{%k9?>(1ť;0x2_\ (Cw%5 )6̊Ul_)9TQkO}|{Q]M.оe?GiI<`ͩe=)˄}o!cKі$NNёK+bnUͿO~ ;`E_pY;2'$ӷ_v3]bUKhٻ+bSڻGRǏ@?`l=+`m7+[1W*JM"wqQGY/78")biߖkXht~TD]܏vY?ދoC/llBӷ|Q-kSLwd-D~mc1mv;2P7`}ag޽=MⲶmFҶCN<[1}K^V'2v~%v+b?h@;=_DWZƺ[)ӲVQ[_'H"khwbˋ㴁٭΋|'<Zu>n`""X~~ 脨=$o [\^ۏC;E F3[R>}O)/.uF؈;ֶWXȳc_s0~3WM|饙1}$siSGlE3x#cՈd\mǟEQ|y2["pųy݉֊''xM13<^yB{DۓE\GyC.䛒&zG,t`=/dK+wumc滖_[{~j6u[::ne7Tmum7l7:m#v]'/Xba0rr\wfWw00ɺYW YSٺJ'?!\+-oVtʋN%{e}P%ћ\$1y)elwsnxlfOf]d_>޻6m1k+5~h1(mFS4QF4szz8~@Vn)S)b<-=|A/yr`L. } J]H/ؤ5,k0iQy u&::y^~N[K)Lm*Sw<|,21re;sKfU¸W^J=܅ǜؑǮ~eq4u!+~B 6,M˛6/h1(-չ41ճ9HZ3v.7ؔ) iCܤ E[N)mal՝>"GG}<d:KK%̗Jkv:R%Xf'#&)!m!>,=_Wk/;;&~6t :Od[GͲGo5YǯY}X^7h7bp2xnYM;wuƲ{NNS:i[^`4G:;lۆ)b>x* s-[)yJ?X^?׍&|^ q~XI,֏%L^Ky 'kS˜Eߕf?w})]\ηy_'%{agߖi1wמӬFƄ_ٗ*T+G~.b]a+Z(.`"^@lNaڅ^~(]ѩ o[W,oӴ3tJ_t[c u-[mzH{%nXSUt(]as/uRlNtgY[0 1x3))xH'}ge,R'Mx1+' 39W]g3o2dplfiɜXvە{OIt/}Ⱦq\㵺~ʡ7u&yIe !oL ?f=w噧 Gٮ=yk2߿2<u;qu3oiJae}>+[:ʳEῄdĠ%t]p;w'š rZy/=v̷8|} 6шGĨ}o7hi&,|c.^y}̷wB?;ǵa =ol@B_1B1E144FIb^-3gNm`&**֩#}d|T#y=LЋtc¸c%HE_Dg,elMI.~'ަ$g ߏwço§oAVds9B/曆#AAݏ-AW\wlO?hoEHAbNhv|MPB;kGEE=Iз&ک$A 2;~))7o̷.!%yl|o|>< o 8p||O| z4(B?4ߓ̷0^oɞ5M=w'|/Hqxg;۽p/'@d1|e9ޛDjse~?4߄A?2Ɯ=~uKTmמҧEz|42-F7 $nG,]wcsvw=ΰS$ڸКueٷ1+YHo_1x`Osdߕ L̻uNnئy5p1XwT -s.nө E`M*Ⱦ/ZӼfposԧH_Oo]!杰2ǁ̻J0d`=I]I杷gKk fw"bܖwfks cM!_Gy:6\ƣYذyO$'2 }wA{w2ă~{נ6جyC:ɞnݲЇy5~Hxt+6nW$d<#vG7ͻ0_c~0 ~*'"{e;X|W9#,H r@CYx qjN1yRQD=,'; OռcGryٓ,iO{eߪywC9lރ!On'A>s`H{5rcj 4ͻw(84;dY<;d 4$\?K󬼬3;]y fSE3yЗ}!3}AlR$F<$ٛqO7ϓIItψ)"Ϝ!{?aTG {耱oٗ-{e le}>b ]8?j._=jsWvÐ= =A0|ǑrSy^QE9&_6,= r?HɺG77&侗sK${Kg*{̷̞">EHj~ٗ ?ny 7{G>/H>=!Ї }E$Ec>@@>ٟb=}`s}/-kS.,&eH=ar?oWɽ?%QJ| ~%`P%]^'3ڛ /{(例ܳ{V*VK ~X?lָd_ֳO"Y5nY5Evm1YGaֹ[Y[kcs =u&$kٵ|E%oiЮy[.L[-N˲q8 {,˺0./lx ;,˲[,ʰ2tQ-8WƜد 6YF<\]a=H?S $ {-^˿Wt"Q$ R=2|LESIsH_TF|S2A:-Ce6ee| s2Dz.#,_7ʈW_?[]e!e2Ɛ224eYxх1 AX}. eڅ҅ k!K.. ꂎwtt4˻#@8޵ }kwEa\|MӅVUtttO8uA/]Gi$. z_}tuA]W0>tA]At0Nwou.]#uBL؅إ 8w!nBO `\AlRA`|Wq}>S_Wg*' RqiS6'T+O*' IXW' TuVG*V?`_\A?T*VA ExW* \Wkv^W``ZAS<<q6\[V* b WUgquS\U*{co6[VecdZVaUiUU_xU!ۑKTwTOu0**IT`U*&WxUC*l ܪ *|}1b ܪU*&**b*첊إ ,U*l9KqdYUfxVUh3ݘt#/ ;ݰ {7nh7|A7nh7vWwn_7Xuc< u#6h7ލvw^uh_7֍uF1ucF\֍yB{nOI&_k8mA[{_`ۃ~փv=Zϧ$WWU/ Ջ~ E[{=C/ދv֋N#zE/b^7zaszas藽eHˑkDZz{acy/p]ًs^-Oz+{{{{1{awzac,&C:t v׋@/|^/Ɗ^\/|@U$_/|_/t{G7`^.t ы1p/Ɨ^YƗ^^Ezau:v]QzCu袎_AY_[h:CguK+:lzCOuꈏ#Oڐ֡:F}sN}x1_m}~SG

T_1ա:Y_G#OGg:Cu};S}7u:SG_C/uu}>CzN0V-=Z#>>z胟>>z>`sIƾ>`ۇxx!}X!CЇ~,eNFn}}E}>vlcB`}z_ՇXE }o)}}?>}+3Cgg'OO~1D?~}~a|V?X~~ԏح~~`Ǹُqڏ9^???i?ƾ~f?ƹ~ڏ>T?b~~a?b~ OBz#ՏmbwAF?|? sma~e 7ƽ6OBoqlzf>s7}0- ^t }ls9m.пpn6`n `7ЇUG inЀ_EH$404 +i> 1i~o@@|hyc{|iؗ6?#cH O |j>Ҁ_m4[c4bƕ   Ħ Kh j Nm4? Dxx@Հ/-Bϣ(8 1 ]BGGF(]txQĚF(ơQ7gQ`6~0}xbE> ; F(((O.csQĚ`}bEGF_ݣh} 6;cc1lk mC팡ch16=sla >r Ц1~ }| :О1xcht;=Achƈ1a l ~l AocM~ڄcM&{M&Dj ͹IЦ&MD_i}M&zlMD_hBMŚ_cqCvބޚ[mlMM 55&M̷kMvzlMyƇ&l LS$&&NH`GI0N4M&C \&m">nKBDhbhҨ?-LDkvZO˜B|Y zhZ/-`BiR ~j쪅r >ӂMgZ7Zpoam!^ka--%-ނOin|H cH \[/-`f-N-ƑpjZ;-Ľ-`Ղ^alm/0[ cM 1J ص] J cO J _K0fgq̍ǁ8xxq8{81>Lx1>0|m8LOx{aǍq8!qZ$`v?ݏC}1\d{:?tG8t2>?~G㈥?O_ïc/3_ߏcG?hq86]CGqc};?1ǁ0zN`Lscp:ۜ]NO fXM$h1p9?8qs1F$}& `8 '`pb| rN ~o1OF/;'0vN b 7xsv?_2?211 '&`os 7&`Ӏ44`6 M-N;: }zj94AiЯoOn0^LNӀ42 41 }{i`44;qmgtƅx~:^%{\i{efoպn\nqo+vq6,~OΧsѥ߼LǬ<&wWն^];Γߤzuswt|.N^-Cu{Ck$;QZO:}rk i,ӏnwHICvʷq'^MU!{sG]_CImq(ݾS!td[[,g'Ofp_kǚGοsw|C?׸9Z?Zm\^ߐrr$$_vUh\ yH>ߴCT9~Oq*58'$~Ƶֶ#Luĵ_O˫>5.q94NOCqj8Jo\qW q#hsyG=y}=PcÕw͓NNw œݮ^w]厮~>둏;>,4}m'Bۭ;WG˥ehN5JZO!pqyN[ yT}hϵs8F۝g-҉ uqrL?~I/'o;ɧNo'=.yֿrN/:PҷύFk\W^q_ˣn{zoɣPA'34'[u|P\n<1Oz)</<uMӖ*Nи P|g<^pw^rG7}hlÃk~U}tVr_WqrG'gh].Qm:^rTOq\tzwq^G~N7y_i; Aߵ׵>٩8qJۛ:iߓ1߸xKnvмYۇwh?_;y9Nτ/U]w~U+~ߖ[us(}1nfR|i=jz~wC/eS}CB 5qG;;uGk`'Ou>ݹ_yDh~7Bߴyth 3Bq7K^qv~Rкr( ʇ'wj?ߠq?nqSzT}h%4؇1>5:>C6t_JB _C.n}_A#4^t<w=[ˡ}1z[?n էOcrqܡЍ:~UǛ=}j!BVxBQ=/ ݷ{qz]oǸ}5q5qACv2}'q'tzbh܎'ǁq;nJ۟r=w^׊/ 5[ ; 5dRtx8;&4._q,Ws}rq:~S5x_w~-B?wIԸ}!?磓8ZW7CshouvSMzh?ohiz\ymq|s:~hhߡ^xCZ(ɡ}vh7ƭCi'ွw}GZz<\wンP<:JS=]['q Ow ko)ԟ:PkyBOsaqg[hꧡC oIL1^BrpBAJum=kzvzߏήܡq G(dߡCNރߏ󐪧3^_jOH]`j>i ͅPܬ7}[rsO{h#BSG/qMu]y@A;Lڗ oCgU߉о2W.}C{cռIsSgup ww=zv=q5^__[珩qBCgu⣟ ţqwCݞ`K:;Oϗu\zv!|IzUC\珓/v=^}䯺яvgn^ g~[7;k14ǝi}~zOׯ~hX>~ޜ ==9Bu=.n\U/OGbuh;I^:f z=NcHq+[w}'4GL=S]N92>I=~➃׭&//H_t{Bϻ=ZlCTwch}<. o1#u=\./8?^+ޱ~Pyܸ4UŽn?}A'Ouqv1v=ZOyZpqG^mz<~jo!Bz.n|`~u딺|p '=?3PǍ[q<-4$.㈋CqTCGjy|Z\;>}_qGyC\KBTW뺥9~J({Bz>Eyn~Bb٩8oOu'ƽMǍqvS==ƭLu}$n[߸uIk%?&n$4NAzghH[ w10Ԕ׏z y7~7kqr١>4;řQC9Nb^qdh 1=/O;&3)wg_cz__r*q5nVg8fv{G}\'Wgh?'BCW:_m7^_G~ISۗ~/.W軦EtpN_OǫZql{١uu^U; unۇU=uMravyz߼],=}Bq뵁 ݟxcw:~>8?g4`/4)qw׮2hҺt!yB|:Y/V7Z o+敺ŽaҼ(6i~4ygz]#=tS}ڎB>קB*߅_M47Bq{q;^\; CϕIvx>m}cܺI}mq&׍9RXwGe:%֯~=Vƴ|:>=w 7^wyr/?{coq_?al#_XqzqpN}N|է5yu8Τ~;vi? =O/_i=CS#~NWOBrG= Gv:;}?0Lz(0tѸs3_VwjlRoG'y{hJoz'n^ˍj}AĽO4.8;1w?0<7C.ڟyB>|MG~Jic?K<Nf>=;eywϓl(>1GU{7{v?rϥ_>w +B|'t6byGPzfLg7NGW>kw߼"l>?=kyMl3?+zޟj8%Xyf&ך1?iAhZy_6ƯN2Y1{ۼ%pF=xW[Mޤޏz|uQN&J6O( SxXslL>Ӿ1dGqM_8FOfWO;eu Z^ho- 3G~~?7l[ĵx>n"sח krI>[P30z> 0_Շox/2ʟ2L1oy]8jܟN(c4Q:tozO;m"G_^sԟ{-/80zopIE \ֹ-}H2.h\r`[OkW~:)v:a yOL&͏~xv؟~,z6XD[_go_`4:*8/īLd啙jrfw0/, pVubwœ-ږC|,d8ɭ} }l= G;g19.Cfu_Yf0~ԎS}avZ{k Os+<\ }~6O:5Dqɢ_9.Fw-z/睖7N|C<=^ )G>¦o⼲/Iփ֝:-S-v>gdp ͮE.weݨ嗘dYϽ IƝB/|EOwuۯ~ZB}i֏|sY[ ^/k Ȱ>Ēg-v>G0cÝ_j7]l~8qGJ;}>2ߏaܑ3S~$^a_p'[(W|?=_ pS!by7cH;a]-LW}-٥Kޓі{'GvKz̑|D>ҏѽ~T^oMA-Z\)z'C:G x~J$j?J>WnujhS`7?e/$}|-jr g27xXaمYZ<)4U%ϧi0~cYeی޴||Ym/_q}[Ȗ?v~ߢUϑ>HӼS]/xh~^I,}/br0;t??YoZ%ϫ͏?,n#I: VtFMatrix/inst/external/test3comp.rda0000644000176200001440000001062110463734405016734 0ustar liggesusers{XL7SMM3SMRL(DH%d$%$"$"GŦrcKJR)Jݕ~ح>;9<;5k^ߵg}grwS(F*2h*z:uҥkVQ(tjo;n1"ex P%o:/L v}O\>ZtUo3}-YZ/[~], 1o^y=?xLΘei)].KevӾ{I*?M]-UK:ua//\Im5m9֫yҹ45Ch]V䌒kDcfIwMk APpBb`X(hڋa6Mа=nx{s<3 Ll{\\tN?pNcn?+zbRiBỊ|^raCdw[}w5 :/ vrqb=`ԭm_a]MCe,N٤ЛS^tNbqtky)I47^h~̶UQIS-d cB&niv@t2Hh;bZ n1aԂ[37њC -5d25 4$Gd!TIۀγBj`ymI{%ExoGH8{nGD 7˶cʈfo`o RiǨ>iYI@8C$4<07V{ ,b+O,@-,䘇HT SkH;%_#wyX7#v%0J'_ >N˕ty.n[Q0㪇ȹpVR?p#'4VB[if|-J0dӃ"-{<Lʋ~N@7uű;/rA.;" Բ?Q6fi͟rp~'Wc|zw`-~П DsaZ`au. m_2a 2Xt_+'޻f FjN6Sҹq_M`Hm&3pyVXk_HXOR}GJrwx21{rgNyC}eHg!X һXMB^&୴So1ʀv-{;ֹvFٶp&Xֈl>k Syg sf8zbԭ4,e9X}qąV/USdk^os/┿^;k'aܮDN{r-V Ws.m=c%9ᙩĜ]Tӧ7% fÁSVkTZ'Xb.0&!R8`Zd;QQ؇:]Wz#%: ׿]U'5/Vf"k}xk|'k OEMפ1R/@bE6W7!qCG#vҀG}cog:ؖb-BV^˝}K'NMY Ozђjz ڬ6e9PLqb fkLUVX.Yg+\7w9 NfܯStKφ\E'0WT\hوWnDuŵiV(;rbfmQ|~46yb(֪^T|{["t{$:RsMq@;U4Vgͳ#ioჱ"xK .K ϷmXE7L|mտFFy6i%{֜𔂝 1xЫ̢zld6@!RhZ?VpλXClniO!Uz_!@:yIl6Ķ?s,Gl 26IZnڄWM`>?nr!-Q ו'bXWX\^m9X[&uP,rdLÉOu |gGpۀi> h&Fl unbg\syYFs a//gIggZt@Ga`h9]Ou+|GnU,]j;߼6V8ڊļt>KWTi=m v}=W{=Wv{Koߝ,~>^}\<.&H?5y`}Al%DIN$+")$aHCB0$!! aHCBR0!% )aH CJR0d!# aCF20d!' 9a CNr0!' 9aXaXaXaXaXa(CA P0 a(CAJP0$ %a( CIJP5aX5aX5aX5aX5aXt%dQJFd"J2Ĥ&&51IMLjbRĤ&!5 IHMBjR$&!5 IIMJjRRԤ&%5)IIMJj2RdHMFj2R&'59IMNjrRԾ2uUIoO˫7!Matrix/inst/external/pores_1.mtx0000644000176200001440000001131210275433311016414 0ustar liggesusers%%MatrixMarket matrix coordinate real general 30 30 180 1 1 -9.4810113490000e+02 2 1 -7.1785016460000e+06 3 1 4.7312729960000e+00 4 1 3.5742618540000e+04 11 1 9.4625459920000e+02 12 1 7.1341308750000e+06 1 2 2.3349693090000e+04 2 2 -2.4613410870000e+07 3 2 -3.0051645960000e+03 4 2 1.2934346290000e+07 11 2 -3.6807151210000e+03 12 2 6.1495431850000e+06 1 3 4.7312729960000e+00 2 3 3.5670210950000e+04 3 3 -3.1208606780000e+03 4 3 -3.2500820450000e+06 5 3 1.5522075550000e+01 6 3 1.6287803340000e+04 13 3 3.1044151100000e+03 14 3 3.1914882100000e+06 3 4 2.9953986350000e+04 4 4 -1.0035133800000e+07 5 4 -7.8658863460000e+03 6 4 6.3330904920000e+06 13 4 -5.2284380090000e+03 14 4 -1.1610330070000e+06 3 5 1.5522075550000e+01 4 5 1.5956339430000e+04 5 5 -5.9720828860000e+03 6 5 -1.6395834630000e+06 7 5 2.9661271480000e+01 8 5 8.7000917550000e+03 15 5 5.9322542970000e+03 16 5 1.6097273710000e+06 5 6 1.7473258330000e+04 6 6 -4.1182170880000e+06 7 6 -2.7076007450000e+02 8 6 -7.3466724480000e+04 15 6 -4.0817635000000e+01 16 6 -1.1075258970000e+04 5 7 2.9661271480000e+01 6 7 8.0481454440000e+03 7 7 -5.9475459880000e+03 8 7 -1.3740635160000e+06 9 7 2.9419951740000e+01 10 7 6.7909579670000e+03 17 7 5.8839903490000e+03 18 7 1.3581915900000e+06 7 8 1.1788389530000e+01 8 8 -6.0472270900000e+03 10 8 7.0730320960000e+02 18 8 7.7968763160000e+01 7 9 2.9419951740000e+01 8 9 6.7909579510000e+03 9 9 -5.9713573530000e+03 10 9 -1.3323692060000e+06 19 9 5.9491819500000e+03 20 9 1.3189422360000e+06 9 10 1.8213815350000e+04 10 10 -2.5059847620000e+06 19 10 -2.4969274700000e+02 20 10 -5.5328319620000e+04 1 11 9.4625459920000e+02 2 11 7.1340421910000e+06 11 11 -2.7807437790000e+03 12 11 -7.7182097420000e+06 13 11 4.4060542710000e+00 14 11 1.4480734490000e+03 21 11 1.8358559460000e+03 22 11 5.7572487430000e+05 11 12 2.5797297290000e+04 12 12 -9.2407184210000e+06 13 12 -1.1588958390000e+02 14 12 2.3027380050000e+05 21 12 -6.8657039450000e+02 22 12 7.1253609460000e+05 3 13 3.1044151100000e+03 4 13 3.1912678870000e+06 11 13 4.4060542710000e+00 12 13 1.3807829320000e+03 13 13 -4.7848602210000e+03 14 13 -3.5808334290000e+06 15 13 3.9963378410000e+00 16 13 9.2558550540000e+02 23 13 1.6651407670000e+03 24 13 3.8566062220000e+05 13 14 1.8139423920000e+01 14 14 -8.4585448840000e+03 16 14 1.0738622860000e+02 24 14 2.6158080350000e+02 5 15 5.9322542970000e+03 6 15 1.6096290890000e+06 13 15 3.9963378410000e+00 14 15 9.2558549330000e+02 15 15 -7.6610458140000e+03 16 15 -2.0016469780000e+06 17 15 4.1131980110000e+00 18 15 9.3265571700000e+02 25 15 1.7138325050000e+03 26 15 3.8860654870000e+05 15 16 1.8316189080000e+01 16 16 -8.4066950400000e+03 18 16 1.0674546920000e+02 26 16 8.0723176430000e+01 7 17 5.8839903490000e+03 8 17 1.3581915900000e+06 15 17 4.1131980110000e+00 16 17 9.3265571690000e+02 17 17 -7.6966204670000e+03 18 17 -1.7682272950000e+06 19 17 4.3138675330000e+00 20 17 9.7583624590000e+02 27 17 1.7974448050000e+03 28 17 4.0659843580000e+05 17 18 1.8104876340000e+01 18 18 -8.2868969120000e+03 20 18 1.0561495530000e+02 28 18 5.1700319220000e+01 9 19 5.9491819500000e+03 10 19 1.3182531100000e+06 17 19 4.3138675330000e+00 18 19 9.7583624590000e+02 19 19 -7.8034482760000e+03 20 19 -1.7423949200000e+06 29 19 1.8608642830000e+03 30 19 4.1338216070000e+05 19 20 2.7213686810000e+04 20 20 -3.7862462010000e+06 29 20 -2.7268589770000e+02 30 20 -6.0465513710000e+04 11 21 1.8358559460000e+03 12 21 5.7532622180000e+05 21 21 -1.8730197800000e+03 22 21 -5.8390768360000e+05 23 21 2.5519125110000e+01 24 21 5.8925928100000e+03 21 22 3.0689873960000e+01 22 22 -1.4220855320000e+04 24 22 5.2041902550000e+02 13 23 1.6651407670000e+03 14 23 3.8566062220000e+05 21 23 2.5519125110000e+01 22 23 5.8925927520000e+03 23 23 -1.7282309830000e+03 24 23 -4.0006143080000e+05 25 23 2.5979289500000e+01 26 23 5.8831777310000e+03 23 24 3.1037943720000e+01 24 24 -1.4640445490000e+04 26 24 7.0608811070000e+02 15 25 1.7138325050000e+03 16 25 3.8860654870000e+05 23 25 2.5979289500000e+01 24 25 5.8831777300000e+03 25 25 -1.7785733520000e+03 26 25 -4.0325726390000e+05 27 25 2.7334717910000e+01 28 25 6.1828826750000e+03 25 26 3.0617826380000e+01 26 26 -1.4459345430000e+04 28 26 7.1015603570000e+02 17 27 1.7974448050000e+03 18 27 4.0659843580000e+05 25 27 2.7334717910000e+01 26 27 6.1828826750000e+03 27 27 -1.8647846840000e+03 28 27 -4.2182964720000e+05 29 27 2.8739153910000e+01 30 27 6.5001941810000e+03 27 28 3.0184152090000e+01 28 28 -1.4268956760000e+04 30 28 7.1493041500000e+02 19 29 1.8608642830000e+03 20 29 4.1262902020000e+05 27 29 2.8739153910000e+01 28 29 6.5001941810000e+03 29 29 -1.8714356470000e+03 30 29 -4.3693045430000e+05 29 30 4.4912526670000e+04 30 30 -6.3991790180000e+06 Matrix/inst/external/symW.rda0000644000176200001440000000251012214433704015742 0ustar liggesusersV PTe]ayc\ Dh9B#:?Fc>AN} O$y21F.Ð#6T&iTSE%b**$SOJ5#TjrJ=nBsY$gۃG ! bMKd w@~̞5u,HHб<\>& zqh{dG=]+ eߪ$mgGWZI`ud}/BzE~qbx'PW]tˀW5jp> `GxegO>R~EhX}9T2x]Z>4G5pݾ 0WwP!ylDF Ծw'/dG}(\,6@6lrn 4ku s_RdvfTNf3KZgwr=M< )>~c6ATsv1alSR7Mi7c)bޜѧLij/K)fr Matrix/inst/external/KNex_slots.rda0000644000176200001440000015620010464427703017111 0ustar liggesusers}XT:TFc/c9b{E#슢+v{=* b8$by;̝k3}ft:% "GLolpN]!G|hѶG{_ө+n3 M5~ E{po4 s\hxxߥ='8^K4+<zk4O^4;4\/g=s-Km5Z~h0( \p/^Eh=%J~ Zrxh*9 \+UB5V D_:Z 4셮6ZFh5jAchњ5go{w]zhߣzn Z3x/o؁5Z[x= '6h:R^ 3ZW~ '.hzx ߫yuG 7Z_c>h 븇c hCц C6m$ڏhSO9 m Xxcc&MD suzړIhS~B6gh3pƢfBs{6h:ƫ'mh<Жu.tжvB[`m=BTFݫ.=ulRY up_m=7;*=0m#&-6SJ}->`z‰/hvAۋC"?0U=*U GuOc4U{' D;vZ Y|z0݋Q0^@>X=a0Qh'NB;>TshhahE}v -cmu:520!/*lL% _C> Ld`GTآJD'& X8% 쩰_~S0e`H^dQ&|͓7tc|*:||=D\` @NTF;ȀaK:qC #D( uyˣwaF!谟:6:؈Cau1lG@ g1D@غ§ ⊀X`L >*| _! 3& vdKC*|" * $  *(79*I/qE@[6- &` PZ+{R`O*bU~]WTSOw~O| } N!{*⺊Ǹ~D/!. K@PuqJ@!^I' "SFd`Lƽep )dO*|x& Sb8%`^⛀&2,c}d`HdCuTTM@|@ 5XW1~Vk̻\H@ e}a20"X_@FqMl[dy!2A+iL|u11~v&Þdؓ {SdG'segY>2 ('i2|\)_"9|"' .Ⰰ8, &JaO24g.cme&#>2 b$`Z<(#Ȱ#Snq)ne+/[w lXF̒a{2Q˴OɰMlf0'S'S^;W26yɰ9lIXG,Q/*fe"1B =Sy=P~!g G*NOoG;J؈(/X{~Ph`TvT#ؼ`lW-*a b}gv*lPmW)O*DO؍x/!~Obk|=*^SlK Xo'!^֒ ' ~ *'HqZ@<`'!Is☄#!H|/KoabKc#;ؼ8. bx- @ ~C%/!KX# k*/Jb-!^Kb-!>Kb (<|5>p8 (xOx!zpۖ`SlJ I+ v$v$؃{Pz= XCc0.s  ؑ qF&$4 >MKo -H v.l]mKw +f%ئ`lWBH ^BL%` WB(/ )buM\6$y) =UC [wFA?T` % H> c(?R)\r 3A^HATQA!◄%!Hۗ?HD10"#|D8|P,`C{1 % 8 .a%zuzYV. (/  "⻈$ C/<= "M"ⰈBD~!"ÖE\$"ö{[&u^w<="0 —XKs19 0> "&-"DD BD1dzG~+ L(iW5"P&.c1n)zi[wD_"Q?{'b?dW_9z[ua#"!-R!_Ly|cz"YD."r8*R*0"<9\AM E"V~IX;v`h>ZV H;DD'"'"v" CDbNyѺ"K 1EDlD4lb D$`@"\ 戰cFX=PEVD lP"_쩈*<@_Hq &a/%3mWf*>ѓ"."ǒR^a"|KD~%$⧀'=I]"| "p"5"bH G=H#F(*qwzD' ՓƵ"bx#"(LGO~E\+"1fHy lQ%WEq?1w~@D$6%_C"HĺX_%ʏU_qY$_(/F\WE;"rQCB#"Oytz_ĸDK8 o*⹈{>yI{"(>A`D/#gг,QEQ1"G)GnTC"rz"lG=ϑ@n %>*8?"6PUJ,n)czw} gx`/UJy<ݛJ~*!H+u_XHc$ /H F,!HDO?O%R P/O%C T_W%C ~U[U؆%Y ~]lzϕ$ov%{ UB<$1 VB<$`2^c{+c}j=U=*CE,RWTGY*| KOy3|DN%rSlR)O%Lp*;2VƞXw(eآĹNYvb}U쇊U*q9`TJEk!/2lS  [8za*]%^{bOTW'*@=@L J'HLKS `a$;d؁Ɉ2bLZq2 !{d)#ʈ2 .Ï2| .2rrC&nBgnA_eZZkOd_ndlY*cV b)`. @!ؤ߫`< \K(W1^P Ư T)Y b*[v ~) Q! ` 8%`n `. RA^ F*XsS+)Xk3'lRORzN\( bB5 L)qvPL؉x`_0 F( Q("N* I916 p V*g  bؠ ) ( b;VHׂRzn"E_R_T](EQ9 SAS( 8bTQ\ cWw Q1WR*UPwĜU=PDzX7yQ1n4"HazG⑉[GIմF#D1,BI3tP I tC 1fH醤Ni/VAi9VD:郤FHl0K$1M$ tAI$-4?MBH34? II3胤 i}އ<ɠG|XcGrGZ|!~gizƳ<`6K#tEb`.EiښE:ԚH7BҎRuȠD:AkԄH!G{H!GwH1:hZ8F&K!}C'm"ҍ4%қ ZiVYS-*M!8G/퐆c~H/#r,=tNtCZ,ocI!M8c┉w&mgI!tbH{\BI=; QHC!-tEHKѴ<Azi^AYY@qԽt4⻉s4&@>qaO=oII4hk<4xM$x@  'GII??#8@ oF\S3` # 7p`wY\ q^ciY8,⦀?Eoঈo'~ 'oF|qS"> 7pR9/E3Y\qLg"^ 'n)^8-x,~$?O"7GY|q?gD=!~x!xe,n8d#7L\2o 47N7oII0pIq<C<q=gx?7?q8^87c!N$ \'C< 2čC| ŻD ,ע+ąǢc?qdx?k!N7*ğxQ$^܈Ɖh<ƍo8?$bg]3%~ǛbGRȍ4#I< oىG&_H#L<1q'O<8i ?qK<0ħfI%o+4-q.ij'8)|'ħJY~IZQO}_8#s7"N##g : w?1jc'7īS]ĥWjG8sƉ&N8pʼn'tYYM5ɤGi3FM6iS̀+T/ +? IS 4&fAiA@:՗i&T/E5UTsF5pTFuT7HZ=1S>30tޅδY:#BgK tփu;ΠgvFgt7 TGMj5jyz}fi3Tm IFN1vzvgjaXa8#@g*GF].Q+` 5"t: GqQ(e9M5uF٨sT1j&ՌH .BG-RǨ0BH.B:KcԨ47j*PTɡ7t4IZkU\Ig%UwZXzZfl 32tδzP=Sjjl0۠TK*o8@Lй:@tj9:Bgg3itδYC}=xQfP:pP ,T_Kzz :Q.jZ$֏jڨNM;2zC%TbcPK@=S \NP@T/A5ZՉP- ՊPzP]iꤣS}WP OTA+T[B#ZmՂO;tPePBP]P݀HA"ꩀCMoZRΊj^j.HZɡZC͞]Q R=%Lj-9R]#իR-աR.S2R4OSDw%lOt49E:sHg|UsMt΃Y1:GF5TSNutL;FsZ3G93G8s}3G7s}3Gfmh9fmh9fmh9fmh9iDtH#K[uRrf/jzi!ݗ=YMI3%ߊ%UX׺>`I{tWt_Io%tRCuyJz咞C߷w\I` KI&mXӅ)>P|%M4bMR%bM'E#';F6?mTyH$M٨%B%-t`)٦;J1ƤqZwq%F!7Fu7FI#%-t|3lOi~;T)ϧ:Mקg\7B@gݺZwAցjH$/;?ӜCn>{T_A1eR1`ȎC 1j[>j9^o|R~PLݯ)owR͇VO;TB+TB*'TժP a4f[z78Fj8ؤ ǤmмhݨV3i4vj/A\.3%/3VA19xMMRL&aj^%'Wj(EzZQ ab c}^jꗨFC$/&%3;񼔣_8_W^_H&-tdҐI;&ݘ4c҉!H!ޗt`H!텞kYMh4.!'4kҫItjҨI&-th#ލ8fz蹕4h(>6u Mc~_y$9I$)9SB\\ιs%9JrΕ+9Ws$wrΖ-9[s9[9[s$lI]]ْ%9gKrΖ-γ%8H$͒4IIW$ݐBI$=H#mt9Hk#M3H#݋-ҲH"݊4*ҢHo"$ҎH'"mtF8ZaHW!-=H !Hs }4'ޞyW_YU˪4y(#h䫍s8b⃉%XW3%Gg\dv8~"ȣEq`=/EN1?D=B| #e#[bʉ9{9_陓#y9yYfVUANY!ʘ0mʭ)\eʉ)Xc#)gܐr>(_l1,-CtP16'79=]! ?B P@qb1_(.Q<3V}F5F}7c#>5? e>׽5(kg3~?[z|=ƮsAW=c9qTOgTu=WOL\TJæc|zj=O`L_M06ز 0d?dq G1L&;"&  c3 ~ n V`M0F kl5M&k`c5XM& j}7MOL?L^+1ŸMMMMMShSeS)j<))(SNXkSy))ly))1-"W0ŚbNS6l l"VŽMM)1El4|Laf)f a}0>03333rE3fr>3 h71ͰfXO3` {olç#&cGaSK.a0Cn37hnUnm7; @zX-&X r =X ءcX` , `>Z`%k{ZbΖ=KľY,Z%|%UK>Y".,a{;K&,oY˖ KKvK`6e |ZV'+| oXa`3V Bkϵ½Z!Ya`VVw+غ 6aoWY=yƽa)Xk5g YVso?56j1Xc_5P|w`#0\k5 bblmžm+l"Nl1v[ر-1y-|cg0;vka '0;ثv;; ; vX;;v#;ر;*;;|ݫwe]=={{=8{=a7=>ص>?;U{ت=e=:F`#Upȃ9`l68 q;9#lcwsĞ;;a1fG%GXGV[GTG`pD>|pwq<1G%G{w>9a`kNrV':'` 6A'؆9' 'B'ؘ QN9' w0'l q:?/?V) rӂcAB OX ÖE_E΂zSǻO}iҲ̡&6^SW6晗?g|>nu֎>8?Fuu>5{?>?ucӧvl?>O#;n:gP@On:?)=savq}}),]]:*S?')އ_u=u.{X]ȮC'Cjgwv>~i>§F?Tq8R*OǎS[?Z?}|sŗ?d|nи?ȇϽ>>|>>s_\|K]Z/f:SO5Zs?]גw}T\ޗOn_J'eJ7Tvnj+^OpdOߗ>W/}S\RR<ǭL9D8|p.9}N/FY/s}@Ԡ=9Hbs~r?>ux8tFy9}N9}Ngϯlwa?r#Rlz;£}f_/*;U 51ێkoV,"DnxK7%Oo>UFes4!cK.s {xɳNpdAbU.ڥ+]ͻ?o::o}]"?jC.<kaJKCc%T{sK<9~\ExMz.3+/|~ymS y+[p>ٹ~klXXAyigYԽc<iI_H7b;sm=j%n/q璘*迢< n{Vˋ=;"xڌxꂨq#x|y ]ްQvy9[˅S͞uG,\o8ZYm̷ Ìf7O+{ԴQt|f:.xz)13.gR]kgjỹv>?֝cƟ݄G;,.?Xk%2[QEH-z]v,r+ξ.8ыExͬY#`IvÆ6:ƛUl=ĩ"z_hǎw.ᦓVWe-srعlgWhpI5ؕ[Wns]-J.֎Ùuf%{#NIB{+p_|hzZTUf6ݿYؽ~Y7Eu_Źw}&K_zo}C9xbJ7~#;m7<ж/ٶ>5A`Qd,ͣ,G/w 2}#u}/ŽF%F󀄾b6Z[NխZ:u>,ZA-ɓ dR£N.gvdZ2^ٕ>O_'oQ1Oj_fT嶴5iQeYc;߭q+}ѬVDzw孝"VשssKnJZ7]g?-cܘR)h ,F8Qij4ѽ2b O[^!Zm~ժbIzyعO *l\l݁_ΩQPο`vء[Wݮ6.Zz;{'߷sV2ry%KL=Oo%!<; ug2i@լ~]ɽkPv46BbksjE\{q?>W{K~,ЧW"c!FYlM- \4g&wkq00j#ʲw;:۴yt׋VU<-BO/b5aaңoc/|鷘]r/3|?2K[`Ğ,zc~mk?VX*(?N < co#.)P&=&<Ү^`^ӥCbg'S\wig׋XC~5tEؖq7xxʱW;zv4n,c^<ÿ.~_/;V" sߜVp]*{UFe4z1c yNykDɁ=Yi1\"4?+`?~j!AֱI6^{MϗEݹ?ڄk5t32j<-e^<~bcqRmّX&yHc7 ߶2ٰ]wvGOfuڷn)rF~YwIcQB,/oy)#n6pYvġBf>_~uCF#ZcV0A0zqϔ"?ݠ+{|I<Vfǔ\x{^VL"Ktdrv)cO%c].HX6ka0wth|߅ѡޓytdaWa+xYxaSƶ.^3#mx}YBN1b+)dVz*Oye[ =??,QVydjuncZ[gz :E9dm;iXr7RZ ;yFMjW\nIFHcԎ+S};cީ↡,n.5[6H}3l |N{ܚM kGzݪR흹'mO _\;O ?)i`~5GŶ>m0ym3,c#65ژ9v]~l<ȷ4?ш} C'=>?(=ҟ]pWvl:֎oѤB|S|t7y2eEN|FIws-Iԗ=T wµ̲姉no6X 8< 3ىwuv-Z?"ltUlJSw:}lܳykJWbëEflGN*1*;-`k:ve/[,ʸMإ %ǞˎԶqvɛE;#;}c~1϶&;t;zLvRYԹ;6p_ةRaɂk/XhԀOV >pp~,bggfu&2~Psaœ-$aׯ{oSwΎ[Y&r jlAalBxfҞi8~,:pttO἟Xc >ԇqUe|'g~IloؽaW a, ;>URwْ8;5q2 z]6s!mRXXrkJbnd> _WZw"r6cs,Ǹ v\cZw:bx1Fٵ>aNN8cj>uY-C;20EXގb{gs{gB^!(sZPbzmxgvMf#Ѐq3'*{N/Nfg&5 :;Seכ_Bu.;v)ZnaO{=yb~Z1)~j'I lp@!U5Nwsby~}Arp*8||OY}~Wo's1_oZ򛛾׆əy2B3=]/1eK]NڕfΡֳy޶"zls &]öa5;fvٍG6[]7~A5R D-/1/'C.b'ܨ /x# 4V,yU#O mP8~)d}ހpEug8laZtrk_U޶ ?Њ{z}X]콼z b,YӐGuMrxTg}Z(!W2Ct/ӊUޅo7SoOW)m:/Z G3Y y"Z|lzzcsYۏ,x"Z q-M6Ve #+n/Mh.?|`Q=j 'ȬO5]bqw~ ;c}|NBNMĥU2mQM}5per؅nv?]5%XHkT75ռ_$nL=~1t/mw4|{j1~.@\ڊT Rঞb+V:&~U{Ӊֱ\T}8?[v iձlkuq>E/~ưcsխf;^jqw/޽7f`SJ+βզsws|{LU;xv<]|hwv)n?pq~,q7XԴ m>]>BSU>3,֏ X]4zwυOu{j}ljͿ͕g ai߲}޵ {<eG\Y.RCVvG|去Ž$x>v_Bɽ>tOK]kF"ܻZ/{l~|} g JyngMkT.7[>В'sBQ-vT,I;a llYO-;'>{׬w^-X^Yo>{]uJWrtʷhY lG>0< u|Fcu泤>g6IiV;Yᇉ8q%3rϺ|FdG%e %'X3wӡ&w*'빾!w-vInkYn[C:z*[)݊l0kw,>kE>!ɮB8~nftMF%խ˧]̳V#رq|ZaŃf|j#'U˧,D;SzK);*3)þ1^O4Ѫ|19[ɵ/N_q1ړŏ}h,~WnFX:d?jZ?cHԺX|,~nj!k~a^,ߢ[æ-~1j23'qwaUukEA1@ B@AD2(P.Utt# b"b}w?ܗǽw]c9kXZk6Xݩ(ٻ_y.ⱡ2?,ȱg6.X8ȡ:BAg-DF<+{Ҕ9cLH0/W;ƈna k0|7V)a=U41x %פ`Kk1Tpc9?aڣEB&MIigQ+bܝяͿ!}kZ'գC/xk}rЋG;ofBA/wT6(=t&?"l8e/7@ڡ~&\1" ء#N%)o,]2.gwǐa)8tx3ڹS d͠6NԦhʴPSjT*O⁨acT M,+)qETxTe‹r'=nUWٛxy=-ofO؎9S}X\!s̀Ű@rJ="3 P/!mcO X_=L(搈p zpuY.QR'y"ܙ.~J8 l,{ rU½ %tLJ`UK4r C~rG͍:0.~_] |8 GYIVֈ<>ڻa _/3}_+`KR.x0^i^e(xo׃uB( 7C )9k(JM @!0itlOfz~A'LvX]} AjbTAn1YCPm 3 d9 dp}tC< Xv}|)S9}b)^m?D~+63.kQ}0L(Sz|y^֦Uة8Tx C 7 LA[R3q^=ɖZ>A#_;;*YR s֬]E {ߧKoD_#lJ:utK'E@| :v@ 8RAR`ȭRH-]IcWNC%A ѐuRnT27d#{_pvM}H8Cs1$ȪĸBY;~H~{W{V Ͷ6md ꒐Ð6tfh[%M;fBڦG }whjqU$ҥbVC5NMԐnl%!9%%=Q=tHZwK#1z(2;xU!C{a{Ȱ4yuԕ Mٱo(|_!%8 Du5jb M@t0r:Dެ@msb2]m) &V;oWAr*dSnCޙk@ɨurCG 9.q5֫>yWn&@vʕkg(Rk4wzA< &R| &TE:A~~^ b`=tlm :2&󴐜o$xb'g\),؇-TOܻAئ!Vb.nH=yXOȆE<.h!ܩn3᳏E%dm;G䊃ko[,g@d4 ba{\@ `ٜ4 .G틡kQ,Dhx%k4Ik˒A iL1\387v{\o]v1W.J\$ۏϤ}F6Sst`f4j ʼn<©Wi ^ 8\.[C9v%*o[/+H>~i- ͥj=Y|d-eбC6}!6Qf]DӱXt/66wm¦Th@f8t\<|^$7bc, g^xEoR E|.e5H1C]^l؞scj/)W&cV͠>L8 [8\_Ae:vykyD\9L܇ahc}HR'D~|;kX ~Րvm{d'd+6U iK7Tj^ ZWeƗ@aBʲPBlȳPͦ`z:窹Pr)P!D)Th|7[?u@圂2IR\ǐ 5 4B-o6JR1BC_dZz]\N^䤷`'Fpw1:̟~r: ZM$_|/95Jg#]^: ;a>qWg_6XwyozϯOSbs `ZmkaΦBt-P"v)bnPʝkM7Pe^]:-ېjZJ)W ŸwHXyk4RZ@r gyH>"&g|Gs{>dg%H]CIODBa}UH!X4 #n(aXS)lߵ2̶XЊ|[/)Mի9ftl1#\_a;#%x!f1dH `vq RYs{~#cI;f^so[ү YBUɬbŶ3tԳz5KL*9ኘPw\Pw!`d~aD%&-ä5;vϞγX%)Mr]PJ՘Dǹ U ,Gd1A"LyTJ?jgQ0dGƻ5XxS7Ka<_.Tl3utR}=RqaдSY;mKɭt8.k™w;:5a[ivyagx7.0Ks1l U=m~ڳ najCULM08};MWASAJcXMbQ7lHT8uH4#\Z)v %hi/hsݫlopg'JЌ-OZ *mwD44wz/"Y|$R\ՍƝeߡJ2k6j&3&$jڮK P!煿;뽭 ٛP80bo^f*\{[rY<,6 áVox#~*U:3ͽ!$|?w3E劂wGq>o"'{P `d<C`"^}ywvqF8!*}Z!pNCԦ};k fni'Īn gKhJ$ GK1Q;qs2|Uwg.LdQOy@s$Tcv8"킄@+m*exnR|x'@jO- v ]6i^+t jV*9>9>t&4?7_}x]ldNW.yR `GwG Lׅo2F[ p(sW%"HQ mɪ Wa,n6 Gjj.2m= $kMWMڔHN=S@}Kmt2PO e_ 2+ϳل#Y 4!ѩ-w06ttuǁܲF}VȣK B&NmZի вLrBn̕"/ $yK-VZSzm!TGU,}[7m~+-%O"QKk9s ]V\EA߂X5!oνJ(j(]!umt}Alw7n1BΠm0(wiR ]BmNYL>'=r߽|Nݫ߼ Z3#(O{-xo-imӕ|OqKwDI_ ]z6}qZ!7 b}ɴG$[[Yu\',b$[T?GmJ-sLW< VُG4Jh.헶Q:~wǫxn9ܡ < JO -kJ?kd4ufAk^eì{_Q_oc K_ z6g_R􏭲9si*jlZ.LJƆboSzwaۺ bWk%TꍬPb{W+**OŮ#3nej۶,ua7ŞڲLo+oZ>?׿%ZdJ(HѡFqumVe0x#uZ> [{k;+:\.qXBIۊܠ./mb04n_soP6>ȭg(AQբ]yoc[* #,ϡ`{7џ5W uH z*?z!bډ_ =,RV9VhƉ O>ٿqۯ*xQ'AڂXpXٟ o&^1[8{AN} yt3T3{?ZB}[̫&^\(u ,q-:ܼiKc Qmny|; OeRxw_@wш$U߅򡥏mo٦ɒq? _4i=mNt|ƛh{lՏ80quBYݑAEJ>\aAq2+p S3tF;proLJѿZ>u?hgqYe?Éx+>M'J(j[~V*a|VXO;WN1::d[G@eŮ{# ׸|g1[,ܺ v0W퉹;]r_/s֯6W+ ;qɬY![wpeVC G55cXU  O_4k#Q_T( a4Wr<[[#SwWbFS6~%rI_.D}Ms%;m_.=u~'ԮW I#D7^OkʇڼV? с+? 5kx ([{b&wbW{mscbvi*grï=a,z[j:֕UTOן]xn%*JW7df\Ξ{$ML^a?:<1/_IƵ/]%4pT3Ƨ #~IR7WBMLIbpM|^6>] 3i?40wLsBs$sAb$tTR`{?_O/G).څ9'u=ћrE;&Zp~Kg5Kf@v@ggV +]6KI`ߢwWXoz.7t9۟[wG]>xUКRwUS{3O^[sK~i~dN堁CBiz&R*^Yem/FWsLWh-P?6ʽtHI u"V%cK Ӛw^p况NCTQtiH7< g91umKF<~~h#G.]~$nϑ}KN\͓;$-z6_qPeG/V N!ΝHamq ~=px~FWcAnbMzfR`W]Vu!;CvZld \0n|F !?o4P\B sE ­=[Jդ]r[W3]On[B'gOCB)壾2B3o J=o6$w|}^vHZh#nb[_u?wBI !BnBm ?,e^,UQpB&OBz,4W_(Ww)AQTmrg/|Gw)gUey{(Ty+:uO>&xyIW?Y73"}]T?GYs' G|kʽ9+~S$1uá6;^HvM5TbsfSi-)ڥ'0GE9#\umb,y)*ckL_BdBuH-Lzr"  ZTNNLSyp i4vY`Bcơې=n{ҟ_J0c3h^K3ƙϯ|Iݳ>^Ÿ[UW.ƩUJ]ѳ5xGRW}{ =֦,+B^{We@liRiha)Ė-qڀmoR|s$?x(I>{wb:KwS$$7IVnpnJ;t GנNT 7c?I ='0:̊am8`}сK=4>cMG7j) J|};SE|1#Nŀ[^aJ{i]4_B , u7JM3+~J-Ђ$`ШK䩊:[ڔ_A ;ɪXSbGG!P^}Pqbzdܥg%^g-A{H~C Kq trOs/Bcu,KGOɹoRy@b{f-||"U1De8!?r޼CN.H\}L*k 0KPru.)-Đ<}KdU. ,PԐڮ:[(X=E3r8%`R-~@o , vKvDr=\= X~jӄ eh}ӧXS`A3fSIo6>:GzŒ lޛ|4_:bӳt$ 24#]ڲ?/lCb?4X"5dP95?❛(lOPb?իs[DN&t{TEd P$n~8Ϣ|p? ,ӯDڵg$7hV W + q"YpT;uT'``bke䟩.\H2 H\3d,w:а"F;'5F2H ډvM} Zĭ0A/;5&N^z_kI;uS G8zSB;drbw<3 ^s7N=BE+ @^rB;u>AE^,̒G KO2xC^[b%[6lw/(`e,l畇i%B!n9 (,n@1[W_랗>(P]&{P,nh_,y@BGmylW^yV=Mz{gN:BBvϼV *[tr!>,0 xuJp16R261c gu! yuw[f06ޚ~naގ!M!~N8HXXI$!a7+RsnۮzLU.xWm1հ1։ ?>b{ծ6>!#p0L \ /~q;sp+j`֚ s]SgC+twрۼy/ضkN+3 1[^^w),YR#ePLC/oB#[+42əH1$FYy/Rnq-N[OZb'c0!oؽ=!jޙ#tn;8p+ 3eR :M@*(b1`hǕ |ypҠ_|)lE & ' S|(dM17ի yӚt&fi+ }%wYA]|*mc>pdLj(71R8{ɟ6V|!EO x@RrmLp?|xC:#h"M%T]|͌,$JuCKF7,uڳs+{f]'8|zѲ$F *5yA:=R'19+GY.2=(Y~ @-b6c:8=z _ WJ E>%mC]'BB'7Π E>a YD? /\Ld:HB{Dڐ`u:>\l/<Gb3+e@fy=Fv1)\:皳K) .2g!$Nv-*CRQN-3u([{@a/*bNۉɧA07kKٹÂ1PAҼ7*C iHs%r6bgH>i mỶXW!ݚתbHKhu8~L'±,}2' xPKvI#eX=t^_,#n}`R. d=_@d8LQfsH2>1NkS%>]Be˻ӫR}^^IVKAs7)Ȼŵ`b)?NxߊxkcT># Q/w?SH}5 W?\cׯipNF#LI]x2D_bAI*gO3mCyw(M2"R1@6Yrp $yUkr $nktM!jϣu,5k!XmH/+k?mxyUFwjɷ WNPO.Ę+/oρBTᘴKȨڪ2u{#b?8IyGGW!]zիYHM-^*ŌoKC =ܮ&99tqٷtoڧ^E´{Ksr5wL X[ h͙pMe##7O 1Fx:@dJUP @+UZY& n^}sgFh첡=` Oe1+s-#`z44fyθ cvDDϊ'1]˻  RZVF46]1ygoЯRo,n۠?'eE frz;Odɲ4'!͓{d/$>δT(|K#6ar D.|GR5ܦVK0i1a-Ks>äaMfX8ȶ/+ɟ.xO.yY=gy̺L^Ƌ9dCf7{k^E d_v UfۃM܋q=;ܤ }lu?GM0} ]c?܎l]zI)A?Sco smM6'G^k ݲj&Nv:$wFEh[ehi!+>hGK||o;M དྷCkӦ%+#4j8Z/x5) =6oGJ4À7KjY84JY,r;]1njL4_~+^j޽c3 @[g7atqtR?U\5㾸G>:v,x221fZw cHaܣg:lw<ڎ=БO/rc WOIc,n}G8󬟽| hݽw|<;NR"Io$y 44*c7^W)sG~+:P%?^ĤUZhfƓ +=Nؤb'F(T|g;v̱3 DzLc9BwQr2h˜ؚF E9fGl_8*6)x>"&$Hʓ< }\/Cu3+C~ĤFW ` TVO֯NŤcH,Z&GJ -F$ kSC{!C}i󶣐|F .o^'*2.oBG ӊ(]S~|40o׀.]TL!$3H9 a W7E"a>|#,B4+X,aO˓־j2`[3 4w鈦P{N9ٜ5Rant#lRkn4oad\gF ()עw3_:$ClA˜qqvW?bq{NW1PIev|Jt %Ǐtc<.Wn|c?,ٛ1_G‘g!%3L)0Ny֒p|hSu:%FBm^w-;``Ѹ܇+C}1Ŏ5 ~礰c-7MC_ele;ߙStcǙu)ۜni]MKPg͉-V OFQXY 2CW(fTΞI8xdv<ř|^T{PI}ehޏ_9g-K ]x4xs8WeM%K+lLP|z!J0x 5߆漍^Bu*;Tj&Rqco] y_\FWA!2~'4Rb (|*U կ?>T#5q˯'RzJs=6,w]( ˶T=Pڹ۸%~%4lt"2J_d>ٗ PVPu: UIZkv]~ik#uRS̏pa&#,炲kW(tt'Fn®41߱+˰+aKFY3MhYW]?):{>Ѷ9!,6u zVbSr#P^5P򸄅nI9 _Iw%Y.,B| t9_p!kWuD(>rK&||[^*#TVm{*;Yy4Z(R$K>yO r2BQDZ*X#݉ĈH #,jO}k8|Br'H.^)h _˥ٸ뫿Aܑks|)e&Hnr-^UDXBrCrkh$wy@kK ?h9vzr0 _Ǟ_ >TBP5VCq"&mnA@r-m,YvȘ}џ9jT~EɧdOxP4"і ǜ.\G캻c|ۯkՏrI0[uN)!cIO>{⢱Ac׬6X9M#{֟X}RbGϷ-EeA(Me lar=15Ƀ,#B}_6Ym>9 [ٴGWf~7!c+͋a٦^E>{"E'zޢ dQ]tH>@}b!B99 ~ztLSUo^gx'mK~#NpݏѸ3Tg[,5t\+EBwf-A3[cB35ދCX뵨HEPne.Dl^+ξGAN]Wa~UĕyG&_cZYfJ_V,/QYs//=;v KP"aR~9CQ֝CLc8.ݕMQ~aA)[3z dA :XЃmRҽ*sr׀$HX"72w 1炪Li3 w?¸6az7uMVL=F5$x +B/c Aנ-fFL6c\RmQ2x~=UõyH>GJf|vBx GJQ%H9X=7S,総_d';rvTK̡4i%̌k>Q>Jod0B~݋EH!CYԕ05J>pj>,2:Ec"fa^A{uqz?vaݣPbg 6ԁ߬VO\rs{~pnW);:lgnnp$)#헑wd+ȖMV2|PJ %$ZF~_q>9}~Xص[B͖X^ę󰲻Ňb[Z |UX6Xyʠ,]$km|'hk<[pU8_Vn|C`Uo~*M]W^Xi,E05cj?] %]c1rS}L%S^fRxTKQVb,ϊQ`3.A-9 5p`^I`zzMXㅴm=Xťo~c&?*-gCv2}][O6~@k%')D <bɄIMc<-ʓv X%X곩汯;1mݰVkG`vkjLm-حIn اX>g' Rj)QM) ej Xܑ@\MVM,!p)Z3QOb?Ӛs~hg}w:ԝT>ݜ`]W&-e18WॎTX!,ۈ)Yn9͇v=3`%oΩ3bWvӮ7 ~Xc:|MK$!jwvSh vj=f],J׳8,8x\%4,]v+,%XsP~<t|k`(|W/3~M]ȴbX c_,}X輑smL9 Ƽy4ۇ nRRV<1 .ళ,UY-^v@e,I ?U,),`edURVt3^ӑ߼]OpW2?YۅW*8)!:=Rhg:~ҮQV@F],?ZMP$2X8yEsd[cQz-5?'ߺ[9o>y+klKVHX뺍r {އ}_fX~tE6 U]XO}Ex^R |'q^C}%u1k[$aCIse3<-hҐs%s]gMPi,R=wa-;B>(Nx?n-Nu_ q|+P_1':%p}HEoH+896סf0~ E6⒗ńg_ .KggWr)|kĉ?g㊌Yp?vo[K*^uoFy>ZW}}b656pL kh/N|x4X#KEtb.k[>OV=yMTkI P] qC^=wt/،ڇE %tmcw?&؝ n9Ny?I$VIsWe"/ޤ1G 7~YIH">ͱ4__ V&]v6prCIr`]Bk &Sa#ܾ 4]nI38gO4E"If`OS"굊^kF tx' פe44*OF~˯xl0e)\Tcӄ ~_KgV. P8"쎍ȥҴ|A?e6Av`﫰 Yu^WA;y'4-ުSQPڡJ`hǺ =FV~eU]U\7ϗM攇E[G/b=^5Hzt=*Njo>~.G0\%{.G7ߤidkZ-7+_9 {~oK(⹊oz3fV<ËB?>5F%xQTYqoo~5VPM&9۬ ۬%jMvZߢH.6<#{:pT^.fuXMH,I6TezW6db~Ӗ/cƛs/L7+(y20Pf`aɧ0.sѴ5/cqOڟN 'NOzR+ 2Kύ_K+ƍǨq72^Oy*C ixEٓg;CJuR)!rK/x _]x~tXj)vyR38Eڨ^ƻ`G37ԑuڼߌ)"zX[_ݫ:rX=b64^_ou>#~ r;OrVkc9JGadkc/LnbtݜvXeJC.>/5%U$A}oZT*mؙ~)7ҿ[(r-+wӎ͑6$wx5B zG!o-!22Jy0kI_`Ne {%旭w}c&J}0QSQJcz< pRnr\`HqJG`륧7N]q)y 4 Xu{duwuFA̸HEI|&@{pcwwM%|)/Hlg9,z?`mw|I~}-Y0=خR@&y~: EGN$7q |/.xF0y;] M0y3W;w}_m:4n)[WćSA2P 4O0Qn!`*l:҃ \Po Xzp~G5["%~W{@۹GrGKǁdGz^'Yܼ-%3@o(#AaAUB$(xr0vjv TULH)SU Rl>KWIwhLI\`4~80sg;ӇyACj?w8?A[[Р;;;ÉA*`W"nayLh].\(fyL?t/X$tӂ:UB{w^ Ews9Y1d`>G-ƂD~UUMh\EFtr n'UJ|@cNh% 489l4A ~Wc5zФ4 eS{yHn_! Z /+k׏S- .Wܟ1f*N{!f#a g: PYGשO$LC~gv[.0|񙥸w ߾n"uG~C/KjZrU(lebS)'ރҥ{eI |Z|OC.~doGFs`IhhO˶]V ڹT"fL`01Yf^clo:"e㺇\pbw%HyWH\7Y 6/BZh9U&if5¢FN_gw 78-UP^/`k׃ NL(pFF6=q:3p^XFv 4l<4xï^w{̣xV zv.{ˠJzQl~bAȨ߉S$- \:cB@Iɺ ()3gAC#n0nk%ŀ.t[o! r㨸xSPgE1 Ew ynj Mz )g{؎J.$vwcTdj1|̕^P(xh9 rAu4|Фjj+:%A I)Q~k GP;dRk˂ۖ1`Z /4 PDqH<HڞtR ҆E-KM{oiSn@ե(E;q|.OƢ@>*e->;,kԖܯ =8$#p; [RAM$Pod_RFUq83h>4-ZvAK@EO_K492O:jT͹r`XGu^VTpkު? "`}|r)%j^ϑ{UP[%Z#5]3KF pXpD~$ ۫Ak\ˠzx#gi9,LL3|R  Z`ty0J\wk='Gho)ߏ@Mf~RH? eܺ\+K0ĿHKDh'nFՖ3@"F' aV1S0p: ] p/Z& s`Fi5 dkyj(NdS&Lٗsq)V4TxL疳6sK|?]y|?tM?eu4 F0"9u<+,چz'&x/XGh> A 0zli'KTi>j]kD5&aM8)_9ځ癹'Ekř]ТuĦA+7/w̍E(G􎛉SgimTؘ0j{HQ!]:^ w)>`@XN-0yy`1~D' <Wҁjh&ARz+$M9/q+޾FWA̵䓂`)(?ꈁAA{l OjH])B;wD|P> b]6)L8{zͣi觾K  ֮5$ҡ.p62R{g_Xcs !SNh)KQnK78RJk)|,^rEzI qXKPd%κLhoG>78{ +0ulz@T|j[Mv΂w%<+8LLkܼ&K{X]-AyQO꣋Qd7@ŵ PcߕA| ؜;vc1﷪5Uˑj@[7op4Edt]mlHց*4?EFm0#SMHbzn^߫U!&P%zL}ι`~ʁs0ge\g/q-? exJ[2LjPC>P\: ͝ҠcDS0-fr癯Ҟ0"6ؼCuSPG+YL/mVg~`lȹ?>ˡgP1|h 2Rڴt@i/8Yf2nj>3KD롋}a>YLט :Gw&Κwc~0M)ZvCBs"hp,H*wkf :7^#zlTT78\3ѿHxhF=ָ#\\͏Q00~UbTwy8G#˚G?ҀS]*&8&LOK7I~@ꎷo!P-|xpnL^uZ> ~ Ѩ2lqO#YVBuW}1`2ofѻlkR:T`I@g3?ޯJX\`7d/bK^6+ϔJO AGLJk|Χ&(P$7 UU?"AsJTwd(A崃O/40 %!ꏟ1 Ni{Obw)'hQj/kpk&B_=Z-?S]SYvM0|ySO(S7 r 4h7T0a09&3FryJ#As`ud6h*|ȥpS\k2%dm}*[L{>tIm,@QߌףD~qUʗ1@q?A]kL'Z}AEku0U A\ɠ3Gt6itE$ \8p( t?:YwzV~u %FŘzڂt XM )MvA=$It1S>0`N0Lq򳀮\R &h, ]`U0;qrX$XD̃鰠*#WPI .(]~jm)Y%)y?&y{dAw7[ /4?ƫ@>HQ>G#t9K%#ow-|c+ABֶ3C hgĝ  MPF4 cy6vʹ%;h:> s^Mo `U"g[F*Qdːd?O]qO`3 G`xmgSW?o{c?Wʘ4oh .; "^Ŷ*FWߍ< LߡQ9 7pzwglFsc ``z'Yj %+:dPw ?S"=SKu2Vem`Jw3*$mu*Ztɳy灷5ӓr z2ȌٜgU= 7~nP%18KT#{d\9=0 f=kRZۜ  sѮ/&MopɹLhbj)ɉPuTMl`P hXXsF_ *\62 p`{h-U+0{a8K pl#4µS>N|i^}AC:3m]*db3!:XE0ZȭEh(I3[gf5YWL,L\韃lSR<Ӊii3-WƖ!4J԰Qﯽ) v.Wׁ!om+c.:K~Z 1fP] @1x#0r̨O_Brjv6="7v2@^:fwK%'+@3iN:C ]U'%6@:s?(3|T&&ojmT88Aɽns¾N/Rq{i/zp(a ipH-uO`wHZ~?D SkGrND 鼼ʢ$ʦ)tS:^ QotP6+]P6}|>lVuU4Ch&xupq+]B+#3gwaCwUP΁@W"x۫C򚜽/>`!{@s(ip"J.*gFܢʨx};V_OsʧĜh m1x!}o?!D%p4z=6G!KS".?Mg ~A ޶f#*slm1E~PFy"tgt*2!@t(% f'{(?<:°5axHª#!\NSv*u!z r;9iB?Oۦ<(o[<^慐ۋfֿhشs |W}dzZ̐bt  2{=FyJhO;+-]Fٳ7y <0|,E*Uo`y&#e52O`nӴ#Q ^:/Ͻ/gJA~+^꺳h?/}~$gAN?BzOfJKHBOмݝF$#4{KﲂO[ǣ~Z)e=ovp4<7KpcA8t4 G}CNQ:F{5A=8_D% .3\EupijAr/eG\)<}q{n3~a$8ɺ<ټ@(Qh,ZUiW끨L$DVQco8t莥 Kfsp!Zni.>hD\>0 S6/|\ #mU~q}` .cEGy<{}'}>p~J:~[]<̀99@ruq?k˯G[ .aq./$G<" ZlF\]o 0W 5w55pzWqEBP0и :t3nH]! *0GDցJ#g>F p9t=6:[\AL'nceK!^R q|MvWmP^38הœM"BNęϬ*mֽǾ26F nL*N ܒ> dp}VbqP0,TkA6(d;k6o_4/lOk]= Cz*QVshۮmk4m"vm.dzzp?)͝ uAfTF/(s=+Z; M8}L5 YF9euz^Z b [ @C3'Z'zr0=%\[xrҼ fqĚT`(ܫy#ttW-R1p i:4n6Z󟖂x%3jJӿWH2^ r=a>,K``P Cͯl@øΆK aplAM0 "d(,m7'۪pT%ЯnGk#o2#tz'6}׾}FۛxxS: 1{}{ s^IJ߀M1mLӘ06Sib<+hb,^k /mFZu9䩯x#=.D0)h.{am4OUi=&J@l]#xw^N﹍0vr qa.#(a(>-'J"j>aFHeS̽z@>WA>|:O{"dIk ;|v[Ȁٳ6F?(^374kjS v3.dc,w=l30&Ýw`2"hJ;;zg]6o͂w|DfSV3S<5 Aj/b ? RvVld)`JgwJX1{.~5" _4cA®) HgϙE=@ =Yf*q̲y*!r_/!E}3!4:T5Mn&H F}dIZ4 )5?;Ce6sXe5w |aSJ@v?ׄ/}!B$H)B8ꍄpVJ>k/՛A 5Voڷj<7mu2^ԃrjjo]fFgGq8թsȟ!8XnOSDHJǷ#7|*{[#aöBqF_N(mНF`ARP@9uk~~?PTvaqr~. KOHY y_m!(LzQGOG/, _]A*ҫlRB2-X+Xh)_]<5>BeE'G ɵSI^?$HR#RzIj4* i*6t 287'HBqSUOG?kҷK8v]~n,.i@y?yys"?ǷN#$kKpTq 8&T4 BMi:Ğ޻yat瑮 bO%; K&u?B=A ϱޏ&GhU=owozU@P;FȓVOȓ&vk= ʧW&%+k nR˥5F? mMBi ! %H-YvN>+4J*%>,f#^ t١:} 4&8%EopV'6гL+8GT@v m%FmqYB-鏉J;!_Y.8O ȱ< .a>傺V瞲^)2ȍ 9F;Sr@MÔD] -wy,MzCd|YW5I~w ^f nao>< ZvzVtUgToZL°X:x~z]s{4Z5r<<4K&/7>4pa*_e;V"zerlK_JMu^g 4oPw-”^a \}]m׵4d#9%1.W36WrV|5B3 LKJ~׿ aڳ# p0G%  S|]WѾlY[村iR/YH Cakuc2)dMA=`Fx՞_tK@ҙRI;Ԟ3!qHvb2XC ٛfB3xQ+d}s=8 Q;b]k0uxl5?=dQwKcĿȞ!7Z 1vR~%k;ܕj.;5g$YEppVAby5*F|HoԷܼSU|w!J8>;"ƜɃ{I@yzK+9}Fҡ(xjY wҊ#xoJopbMĦ5|sގOs!r:kO'fe>( AztO P{+ Lx- B,Arތ/(/lS׸*BʇAp.+Zv@ .0 AGVbN7 p:Ş >—fm|nQG|f&,Ȯn&#be2%gdE%oœ9mBy!pŏN"oʏܣgsqG9NuN!wV}ϊVz(.aRCP6fWZ-58Mww$Br']Ap$B|qHn89Gf0 EvBỎtoPX(&5FphX5b V\ Xx#yf>ȫաyMj${ɇJ{d-"~?ɢ!jOZZf"$,s~ܻmcEKB/ҿ!WKDQ-_#3/ѿSԁW~ }xzKT&>Fuvi[ ,ӌwaw, ’?ޫ[88+ߝ >#$Q O\OtJIqx3( B+iA6MTNruקD\ B yj&x#!O9:u)#LESLxԭN%a}NC! ۘ %?8'"q{g  .ք= |jA@7aӝ@XS̮$U ك i*Uf'C5#0c VL&cg ;CGݩ+8abtqlD35 fhvF5K8#k;Oz&Ҧx|4'7aNDlלŽ+K ҄=M{0an '{)5gnp/(6?Xي {|sׄcd핒+D^YB\7ۍ^gm9QiGXS˽6GXjO )!]R &ؙ^Ί汣]~ːtksž~wa&ȷg&pq+ф;K0wӳ:LO}+ʎ}#wGG;Ym‘7v > yOұ4]0IC&<AIASWxpc%lFFΔUjkC/cNZ0|cZLDL+"O$|*y@l7d8="<>DB~Ҫ%<ζ{!~ٔXygPЉ<ꯣZ0'n ,v>^>ZB>% h1c}h_w?jӗz!иo(X4;/>7)W6K֥zLҁ7 QxJ(TPbK.O%hXRI(g$LJt^IHVjxg&$2JfFZ-ZQJMc7D i05$$>z9y~9PŢ ݠ\H$-캊_šEΚوy! }5Oes"\i,Vi]~ W UG|`X:B!"QN4kKEEg4';kȱ~j^m~%6mht;KιN0fs):!p=fq E7` X@p I:k@MzfOXެ9rC#aMIS{3Á!o\R^ 8^wNG)Bk ;<ie;crjP uF4ˆ- cZ`==Yp"w^m׸V[1nI1),ᗚA< JL3qLwa.PA}6ۙN@|Y4psHN-iW% $o[%6>\*nn9/DJqEP&S4lMe~*/')#{)?>^538_TdA8?}h3a"ڗ9O1FgbfN!}޲;˜;% p+V[YHnVs] I@6P|onsnB^f_{tH{z@ʴqpLB늶VH[~LA8lRc)H{)Qߦ !V4Q=^/|= q}֌уCsA*8 Ʌ5m㑇 , *w}*v#lGѫ?^!B@<%Y/;!oi2hvaaV?9O4GV|08k̩sc΃[3F~|^X5BӱkDҎHj%+u0؇991wmHcfwq>bhy4 Y8NU8ʃ"Z|rY-|rdFW~I#%R_$j'h{u<_c6OhQ?sR[Ʃroϣ %?; Y^E _"7o lamĩt[`u;4om\XIsgd}(QTo4r{6寅lS3q^QձϮu\=Q}?,Cfg($qк5[#<?/(Ł,n}9@PU&J&V|vt&x,T /UA@Matrix/inst/external/jgl009.mtx0000644000176200001440000000040014037532666016062 0ustar liggesusers%%MatrixMarket matrix coordinate pattern general 9 9 50 1 1 2 1 4 1 5 1 6 1 7 1 8 1 9 1 2 2 3 2 8 2 9 2 2 3 3 3 4 3 5 3 6 3 7 3 8 3 9 3 4 4 5 4 6 4 7 4 8 4 9 4 4 5 5 5 6 5 7 5 8 5 9 5 4 6 5 6 6 6 7 6 8 6 9 6 1 7 2 7 3 7 8 7 9 7 8 8 9 8 1 9 2 9 3 9 8 9 9 9 Matrix/inst/external/symA.rda0000644000176200001440000000153712215114135015717 0ustar liggesusersmTiHTa}3c˨9-:iP RI%{n)ea4樥6e9DDK4HRAd?ȐH2"Z{{̢䠢 EQ̊bR>,LbqQ1 QS ֢gB|ϜalW_sP Ն ͕s"µo~ >Q9Y۪t˜vEj%f/m_LEH2zp,XM΍3p\΋o <4ǰX Q(lRm.l"a&udVղ<QY9lE݄E;H; tLHԶ$ j'3DTۘ?<|7ID-՟ꞟxY=)+b/ <v>B-n"u YO&?0_}?.7 Բ6HO3𦾢} Ro=50s#ÚMOD?[iǹQ~ ov'źQ?eƼCg-^xL hw;ꎡ18xW:h0`2x*PM~x1zzT_J{u&&huc/WSPp]ѬӄnȀ:z}'r3 G<7o?!0k{r}ں{Nr}G>G{OУ^4uI~[ A:~ù=E>ו L/sp_dfWM꿗@ 8,ko~=j"i77f9Z\βjg~P/Q<vMatrix/inst/external/lund_a.rsa0000644000176200001440000007024410275502035016274 0ustar liggesusers1SYMMETRIC MATRIX A OF LUND EIGENVALUE PROBLEM, MAY 1974 LUND A 352 10 82 260 0 RSA 147 147 1298 0 (16I5) (16I5) (5E16.8) 1 7 15 23 31 39 47 53 58 68 77 85 97 108 118 130 141 151 163 174 184 196 207 217 228 238 247 254 260 265 275 284 292 304 315 325 337 348 358 370 381 391 403 414 424 435 445 454 461 467 472 482 491 499 510 521 531 543 554 564 576 587 597 609 620 630 641 651 660 667 673 678 688 697 705 717 728 738 750 761 771 783 794 804 815 826 836 847 857 866 873 879 884 894 903 911 923 934 944 956 967 977 989 1000 1010 1022 1033 1043 1053 1063 1072 1079 1085 1090 1099 1107 1114 1124 1133 1141 1151 1160 1168 1178 1187 1195 1205 1214 1222 1231 1239 1246 1251 1255 1258 1262 1265 1269 1272 1276 1279 1283 1286 1290 1293 1296 1298 1299 1 2 8 9 10 11 2 3 9 10 11 12 13 14 3 4 12 13 14 15 16 17 4 5 15 16 17 18 19 20 5 6 18 19 20 21 22 23 6 7 21 22 23 24 25 26 7 24 25 26 27 28 8 9 10 11 29 9 10 11 12 13 14 29 30 31 32 10 11 12 13 14 29 30 31 32 11 12 13 14 29 30 31 32 12 13 14 15 16 17 30 31 32 33 34 35 13 14 15 16 17 30 31 32 33 34 35 14 15 16 17 30 31 32 33 34 35 15 16 17 18 19 20 33 34 35 36 37 38 16 17 18 19 20 33 34 35 36 37 38 17 18 19 20 33 34 35 36 37 38 18 19 20 21 22 23 36 37 38 39 40 41 19 20 21 22 23 36 37 38 39 40 41 20 21 22 23 36 37 38 39 40 41 21 22 23 24 25 26 39 40 41 42 43 44 22 23 24 25 26 39 40 41 42 43 44 23 24 25 26 39 40 41 42 43 44 24 25 26 27 28 42 43 44 45 46 47 25 26 27 28 42 43 44 45 46 47 26 27 28 42 43 44 45 46 47 27 28 45 46 47 48 49 28 45 46 47 48 49 29 30 31 32 50 30 31 32 33 34 35 50 51 52 53 31 32 33 34 35 50 51 52 53 32 33 34 35 50 51 52 53 33 34 35 36 37 38 51 52 53 54 55 56 34 35 36 37 38 51 52 53 54 55 56 35 36 37 38 51 52 53 54 55 56 36 37 38 39 40 41 54 55 56 57 58 59 37 38 39 40 41 54 55 56 57 58 59 38 39 40 41 54 55 56 57 58 59 39 40 41 42 43 44 57 58 59 60 61 62 40 41 42 43 44 57 58 59 60 61 62 41 42 43 44 57 58 59 60 61 62 42 43 44 45 46 47 60 61 62 63 64 65 43 44 45 46 47 60 61 62 63 64 65 44 45 46 47 60 61 62 63 64 65 45 46 47 48 49 63 64 65 66 67 68 46 47 48 49 63 64 65 66 67 68 47 48 49 63 64 65 66 67 68 48 49 66 67 68 69 70 49 66 67 68 69 70 50 51 52 53 71 51 52 53 54 55 56 71 72 73 74 52 53 54 55 56 71 72 73 74 53 54 55 56 71 72 73 74 54 55 56 57 58 59 73 74 75 76 77 55 56 57 58 59 72 73 74 75 76 77 56 57 58 59 72 73 74 75 76 77 57 58 59 60 61 62 75 76 77 78 79 80 58 59 60 61 62 75 76 77 78 79 80 59 60 61 62 75 76 77 78 79 80 60 61 62 63 64 65 78 79 80 81 82 83 61 62 63 64 65 78 79 80 81 82 83 62 63 64 65 78 79 80 81 82 83 63 64 65 66 67 68 81 82 83 84 85 86 64 65 66 67 68 81 82 83 84 85 86 65 66 67 68 81 82 83 84 85 86 66 67 68 69 70 84 85 86 87 88 89 67 68 69 70 84 85 86 87 88 89 68 69 70 84 85 86 87 88 89 69 70 87 88 89 90 91 70 87 88 89 90 91 71 72 73 74 92 72 73 74 75 76 77 92 93 94 95 73 74 75 76 77 92 93 94 95 74 75 76 77 92 93 94 95 75 76 77 78 79 80 93 94 95 96 97 98 76 77 78 79 80 93 94 95 96 97 98 77 78 79 80 93 94 95 96 97 98 78 79 80 81 82 83 96 97 98 99 100 101 79 80 81 82 83 96 97 98 99 100 101 80 81 82 83 96 97 98 99 100 101 81 82 83 84 85 86 99 100 101 102 103 104 82 83 84 85 86 99 100 101 102 103 104 83 84 85 86 99 100 101 102 103 104 84 85 86 87 88 89 103 104 105 106 107 85 86 87 88 89 102 103 104 105 106 107 86 87 88 89 102 103 104 105 106 107 87 88 89 90 91 105 106 107 108 109 110 88 89 90 91 105 106 107 108 109 110 89 90 91 105 106 107 108 109 110 90 91 108 109 110 111 112 91 108 109 110 111 112 92 93 94 95 113 93 94 95 96 97 98 113 114 115 116 94 95 96 97 98 113 114 115 116 95 96 97 98 113 114 115 116 96 97 98 99 100 101 114 115 116 117 118 119 97 98 99 100 101 114 115 116 117 118 119 98 99 100 101 114 115 116 117 118 119 99 100 101 102 103 104 117 118 119 120 121 122 100 101 102 103 104 117 118 119 120 121 122 101 102 103 104 117 118 119 120 121 122 102 103 104 105 106 107 120 121 122 123 124 125 103 104 105 106 107 120 121 122 123 124 125 104 105 106 107 120 121 122 123 124 125 105 106 107 108 109 110 123 124 125 126 127 128 106 107 108 109 110 123 124 125 126 127 128 107 108 109 110 123 124 125 126 127 128 108 109 110 111 112 127 128 129 130 131 109 110 111 112 126 127 128 129 130 131 110 111 112 126 127 128 129 130 131 111 112 129 130 131 132 133 112 129 130 131 132 133 113 114 115 116 134 114 115 116 117 118 119 134 135 136 115 116 117 118 119 134 135 136 116 117 118 119 134 135 136 117 118 119 120 121 122 135 136 137 138 118 119 120 121 122 135 136 137 138 119 120 121 122 135 136 137 138 120 121 122 123 124 125 137 138 139 140 121 122 123 124 125 137 138 139 140 122 123 124 125 137 138 139 140 123 124 125 126 127 128 139 140 141 142 124 125 126 127 128 139 140 141 142 125 126 127 128 139 140 141 142 126 127 128 129 130 131 141 142 143 144 127 128 129 130 131 141 142 143 144 128 129 130 131 141 142 143 144 129 130 131 132 133 143 144 145 146 130 131 132 133 143 144 145 146 131 132 133 143 144 145 146 132 133 145 146 147 133 145 146 147 134 135 136 135 136 137 138 136 137 138 137 138 139 140 138 139 140 139 140 141 142 140 141 142 141 142 143 144 142 143 144 143 144 145 146 144 145 146 145 146 147 146 147 147 0.75000000E+08 0.96153881E+06 -0.12179486E+08 -0.26175210E+07 0.28846144E+08 0.57692300E+07 0.75000000E+08 0.96153869E+06 -0.74786312E+05 0.96153840E+07 -0.12179486E+08 -0.26175210E+07 0.28846144E+08 0.57692300E+07 0.75000000E+08 0.96153844E+06 -0.74786375E+05 0.96153840E+07 -0.12179486E+08 -0.26175210E+07 0.28846144E+08 0.57692310E+07 0.75000000E+08 0.96153869E+06 -0.74786312E+05 0.96153840E+07 -0.12179487E+08 -0.26175210E+07 0.28846144E+08 0.57692300E+07 0.75000000E+08 0.96153894E+06 -0.74786375E+05 0.96153840E+07 -0.12179486E+08 -0.26175210E+07 0.28846160E+08 0.57692310E+07 0.75000000E+08 0.96153894E+06 -0.74786312E+05 0.96153850E+07 -0.12179488E+08 -0.26175220E+07 0.28846160E+08 0.57692310E+07 0.44230768E+08 -0.74786312E+05 0.96153850E+07 -0.12179488E+08 -0.15405980E+07 0.14423078E+08 0.75000000E+08 0.26175210E+07 0.57692300E+07 0.28846144E+08 0.96153831E+06 0.50256406E+06 0.78125000E-02 0.78125000E-02 -0.12564100E+06 0.74786312E+05 -0.26175210E+07 0.74786312E+05 -0.12564100E+06 0.26175210E+07 -0.74786312E+05 0.14999998E+09 0.12820510E+07 -0.74786312E+05 0.19230770E+07 0.57692310E+07 -0.12179486E+08 -0.26175210E+07 0.28846144E+08 0.57692300E+07 0.14999998E+09 0.26175210E+07 0.57692300E+07 0.28846144E+08 0.96153840E+07 0.74786312E+05 0.57692300E+07 0.19230770E+07 0.50256406E+06 -0.10937500E+00 0.54687500E-01 -0.12564100E+06 0.74786312E+05 -0.26175210E+07 -0.24414062E-03 0.74786375E+05 0.74786312E+05 -0.12564100E+06 0.26175210E+07 -0.74786250E+05 0.14999998E+09 0.12820520E+07 -0.74786312E+05 0.19230770E+07 0.57692300E+07 -0.74786312E+05 0.96153840E+07 -0.12179487E+08 -0.26175210E+07 0.28846144E+08 0.57692300E+07 0.14999998E+09 0.26175210E+07 0.57692300E+07 0.28846144E+08 -0.74786375E+05 -0.12179486E+08 0.96153840E+07 0.74786312E+05 0.57692310E+07 0.19230770E+07 0.50256406E+06 0.14843750E+00 -0.11718750E+00 -0.12564100E+06 0.74786312E+05 -0.26175210E+07 -0.36621094E-03 0.74786375E+05 0.74786250E+05 -0.12564100E+06 0.26175210E+07 -0.74786312E+05 0.14999998E+09 0.12820510E+07 -0.74786312E+05 0.19230770E+07 0.57692310E+07 -0.74786250E+05 0.96153840E+07 -0.12179488E+08 -0.26175210E+07 0.28846160E+08 0.57692310E+07 0.14999998E+09 0.26175210E+07 0.57692310E+07 0.28846144E+08 -0.74786375E+05 -0.12179485E+08 0.96153830E+07 0.74786375E+05 0.57692300E+07 0.19230770E+07 0.50256406E+06 -0.13281250E+00 0.17187500E+00 -0.12564100E+06 0.74786312E+05 -0.26175210E+07 0.48828125E-03 0.74786312E+05 0.74786312E+05 -0.12564100E+06 0.26175210E+07 -0.74786250E+05 0.14999998E+09 0.12820510E+07 -0.74786375E+05 0.19230770E+07 0.57692300E+07 -0.74786250E+05 0.96153840E+07 -0.12179488E+08 -0.26175210E+07 0.28846144E+08 0.57692300E+07 0.14999998E+09 0.26175210E+07 0.57692300E+07 0.28846144E+08 -0.74786375E+05 -0.12179487E+08 0.96153850E+07 0.74786375E+05 0.57692310E+07 0.19230760E+07 0.50256412E+06 0.32031250E+00 -0.68750000E+00 -0.12564106E+06 0.74786375E+05 -0.26175220E+07 -0.12207031E-03 0.74786437E+05 0.74786187E+05 -0.12564106E+06 0.26175220E+07 -0.74786375E+05 0.15000002E+09 0.12820520E+07 -0.74786312E+05 0.19230770E+07 0.57692320E+07 -0.74786250E+05 0.96153840E+07 -0.12179490E+08 -0.26175220E+07 0.28846160E+08 0.57692320E+07 0.15000000E+09 0.26175220E+07 0.57692320E+07 0.28846160E+08 -0.74786437E+05 -0.12179483E+08 0.96153830E+07 0.74786312E+05 0.57692320E+07 0.19230770E+07 0.50256419E+06 0.41406250E+00 0.85937500E-01 -0.12564106E+06 0.74786375E+05 0.36621094E-03 0.74786312E+05 0.74786375E+05 -0.12564106E+06 0.26175220E+07 -0.74786375E+05 0.15000002E+09 0.12820510E+07 -0.74786312E+05 0.19230770E+07 -0.74786312E+05 0.96153860E+07 -0.12179491E+08 -0.26175220E+07 0.28846160E+08 0.57692320E+07 0.15000002E+09 0.26175220E+07 0.57692320E+07 -0.74786375E+05 -0.12179491E+08 0.96153880E+07 0.74786375E+05 0.57692320E+07 0.19230770E+07 0.25128206E+06 0.46367550E+06 0.36621094E-03 0.74786312E+05 0.74786375E+05 -0.62820531E+05 0.10769230E+07 0.75000016E+08 -0.74786312E+05 0.96153860E+07 -0.12179491E+08 -0.15405990E+07 0.14423080E+08 0.75000000E+08 0.26175210E+07 0.57692300E+07 0.28846144E+08 0.96153831E+06 0.50256406E+06 -0.10937500E+00 0.54687500E-01 -0.12564100E+06 0.74786250E+05 -0.26175210E+07 0.74786312E+05 -0.12564100E+06 0.26175210E+07 -0.74786312E+05 0.14999998E+09 0.12820520E+07 -0.74786312E+05 0.19230770E+07 0.57692310E+07 -0.12179486E+08 -0.26175210E+07 0.28846144E+08 0.57692300E+07 0.14999998E+09 0.26175210E+07 0.57692300E+07 0.28846144E+08 0.96153840E+07 0.74786312E+05 0.57692300E+07 0.19230770E+07 0.50256412E+06 0.24218750E+00 -0.38281250E+00 -0.12564106E+06 0.74786375E+05 -0.26175220E+07 -0.48828125E-03 0.74786312E+05 0.74786312E+05 -0.12564100E+06 0.26175210E+07 -0.74786375E+05 0.14999998E+09 0.12820510E+07 -0.74786312E+05 0.19230770E+07 0.57692310E+07 -0.74786250E+05 0.96153820E+07 -0.12179487E+08 -0.26175210E+07 0.28846160E+08 0.57692300E+07 0.14999998E+09 0.26175220E+07 0.57692310E+07 0.28846160E+08 -0.74786375E+05 -0.12179485E+08 0.96153840E+07 0.74786312E+05 0.57692310E+07 0.19230770E+07 0.50256412E+06 -0.23437500E-01 0.34375000E+00 -0.12564100E+06 0.74786250E+05 -0.26175210E+07 0.24414062E-03 0.74786312E+05 0.74786312E+05 -0.12564100E+06 0.26175210E+07 -0.74786312E+05 0.15000000E+09 0.12820520E+07 -0.74786312E+05 0.19230770E+07 0.57692310E+07 -0.74786312E+05 0.96153850E+07 -0.12179488E+08 -0.26175210E+07 0.28846144E+08 0.57692300E+07 0.15000000E+09 0.26175210E+07 0.57692310E+07 0.28846144E+08 -0.74786312E+05 -0.12179488E+08 0.96153850E+07 0.74786375E+05 0.57692300E+07 0.19230770E+07 0.50256406E+06 0.19531250E+00 -0.27343750E+00 -0.12564100E+06 0.74786312E+05 -0.26175210E+07 0.48828125E-03 0.74786312E+05 0.74786250E+05 -0.12564100E+06 0.26175210E+07 -0.74786312E+05 0.14999998E+09 0.12820510E+07 -0.74786375E+05 0.19230770E+07 0.57692310E+07 -0.74786250E+05 0.96153820E+07 -0.12179488E+08 -0.26175210E+07 0.28846144E+08 0.57692300E+07 0.14999998E+09 0.26175210E+07 0.57692300E+07 0.28846160E+08 -0.74786375E+05 -0.12179485E+08 0.96153850E+07 0.74786375E+05 0.57692310E+07 0.19230770E+07 0.50256412E+06 -0.55468750E+00 -0.32812500E+00 -0.12564106E+06 0.74786250E+05 -0.26175220E+07 -0.24414062E-03 0.74786312E+05 0.74786312E+05 -0.12564100E+06 0.26175210E+07 -0.74786375E+05 0.15000002E+09 0.12820510E+07 -0.74786375E+05 0.19230770E+07 0.57692320E+07 -0.74786312E+05 0.96153830E+07 -0.12179486E+08 -0.26175210E+07 0.28846144E+08 0.57692310E+07 0.15000002E+09 0.26175220E+07 0.57692320E+07 0.28846160E+08 -0.74786312E+05 -0.12179486E+08 0.96153830E+07 0.74786312E+05 0.57692300E+07 0.19230760E+07 0.50256419E+06 0.53906250E+00 0.15625000E-01 -0.12564106E+06 0.74786250E+05 -0.73242187E-03 0.74786562E+05 0.74786125E+05 -0.12564106E+06 0.26175220E+07 -0.74786250E+05 0.15000005E+09 0.12820520E+07 -0.74786375E+05 0.19230770E+07 -0.74786125E+05 0.96153870E+07 -0.12179498E+08 -0.26175230E+07 0.28846160E+08 0.57692320E+07 0.15000002E+09 0.26175220E+07 0.57692320E+07 -0.74786625E+05 -0.12179486E+08 0.96153900E+07 0.74786500E+05 0.57692330E+07 0.19230770E+07 0.25128206E+06 0.46367500E+06 -0.61035156E-03 0.74786312E+05 0.74786375E+05 -0.62820516E+05 0.10769230E+07 0.75000000E+08 -0.74786312E+05 0.96153830E+07 -0.12179487E+08 -0.15405980E+07 0.14423077E+08 0.75000000E+08 0.26175210E+07 0.57692310E+07 0.28846144E+08 0.96153856E+06 0.50256406E+06 0.18750000E+00 0.23437500E-01 -0.12564100E+06 0.74786312E+05 -0.26175210E+07 0.74786312E+05 -0.12564100E+06 0.26175210E+07 -0.74786312E+05 0.14999998E+09 0.12820510E+07 -0.74786312E+05 0.19230770E+07 0.57692300E+07 -0.12179487E+08 -0.26175210E+07 0.28846160E+08 0.57692310E+07 0.14999998E+09 0.26175210E+07 0.57692310E+07 0.28846144E+08 0.96153830E+07 0.74786312E+05 0.57692310E+07 0.19230770E+07 0.50256406E+06 -0.24218750E+00 -0.62500000E-01 -0.12564100E+06 0.74786250E+05 -0.26175210E+07 0.74786375E+05 0.74786250E+05 -0.12564100E+06 0.26175210E+07 -0.74786250E+05 0.15000000E+09 0.12820510E+07 -0.74786437E+05 0.19230760E+07 0.57692290E+07 -0.74786312E+05 0.96153850E+07 -0.12179488E+08 -0.26175210E+07 0.28846144E+08 0.57692300E+07 0.14999998E+09 0.26175210E+07 0.57692300E+07 0.28846144E+08 -0.74786375E+05 -0.12179487E+08 0.96153840E+07 0.74786375E+05 0.57692310E+07 0.19230770E+07 0.50256412E+06 0.20312500E+00 -0.24218750E+00 -0.12564100E+06 0.74786312E+05 -0.26175210E+07 0.85449219E-03 0.74786375E+05 0.74786250E+05 -0.12564100E+06 0.26175210E+07 -0.74786312E+05 0.14999998E+09 0.12820510E+07 -0.74786312E+05 0.19230770E+07 0.57692310E+07 -0.74786250E+05 0.96153850E+07 -0.12179488E+08 -0.26175210E+07 0.28846160E+08 0.57692320E+07 0.15000000E+09 0.26175210E+07 0.57692320E+07 0.28846160E+08 -0.74786312E+05 -0.12179485E+08 0.96153820E+07 0.74786312E+05 0.57692310E+07 0.19230770E+07 0.50256412E+06 0.22656250E+00 0.25000000E+00 -0.12564100E+06 0.74786375E+05 -0.26175210E+07 0.24414062E-03 0.74786312E+05 0.74786312E+05 -0.12564100E+06 0.26175210E+07 -0.74786312E+05 0.15000000E+09 0.12820510E+07 -0.74786312E+05 0.19230770E+07 0.57692300E+07 -0.74786312E+05 0.96153850E+07 -0.12179489E+08 -0.26175210E+07 0.28846160E+08 0.57692310E+07 0.15000000E+09 0.26175210E+07 0.57692310E+07 0.28846144E+08 -0.74786312E+05 -0.12179489E+08 0.96153860E+07 0.74786312E+05 0.57692320E+07 0.19230770E+07 0.50256412E+06 0.18750000E+00 -0.82031250E+00 -0.12564106E+06 0.74786125E+05 -0.26175220E+07 0.36621094E-03 0.74786500E+05 0.74786187E+05 -0.12564100E+06 0.26175210E+07 -0.74786187E+05 0.15000002E+09 0.12820520E+07 -0.74786500E+05 0.19230780E+07 0.57692330E+07 -0.74786250E+05 0.96153880E+07 -0.12179493E+08 -0.26175220E+07 0.28846160E+08 0.57692310E+07 0.15000002E+09 0.26175220E+07 0.57692330E+07 0.28846160E+08 -0.74786437E+05 -0.12179487E+08 0.96153850E+07 0.74786437E+05 0.57692310E+07 0.19230770E+07 0.50256425E+06 -0.69531250E+00 -0.15625000E+00 -0.12564106E+06 0.74786437E+05 -0.85449219E-03 0.74786312E+05 0.74786312E+05 -0.12564106E+06 0.26175220E+07 -0.74786500E+05 0.15000003E+09 0.12820520E+07 -0.74786250E+05 0.19230770E+07 -0.74786312E+05 0.96153820E+07 -0.12179484E+08 -0.26175210E+07 0.28846160E+08 0.57692320E+07 0.15000003E+09 0.26175220E+07 0.57692330E+07 -0.74786312E+05 -0.12179484E+08 0.96153820E+07 0.74786187E+05 0.57692310E+07 0.19230770E+07 0.25128212E+06 0.46367594E+06 0.97656250E-03 0.74786375E+05 0.74786375E+05 -0.62820547E+05 0.10769240E+07 0.75000016E+08 -0.74786375E+05 0.96153890E+07 -0.12179494E+08 -0.15405990E+07 0.14423084E+08 0.75000000E+08 0.26175210E+07 0.57692300E+07 0.28846144E+08 0.96153831E+06 0.50256406E+06 -0.15625000E+00 0.70312500E-01 -0.12564100E+06 0.74786250E+05 -0.26175210E+07 0.74786312E+05 -0.12564100E+06 0.26175210E+07 -0.74786312E+05 0.14999998E+09 0.12820520E+07 -0.74786375E+05 0.19230770E+07 0.57692310E+07 -0.12179486E+08 -0.26175210E+07 0.28846144E+08 0.57692300E+07 0.14999998E+09 0.26175210E+07 0.57692300E+07 0.28846144E+08 0.96153840E+07 0.74786375E+05 0.57692300E+07 0.19230760E+07 0.50256406E+06 0.70312500E-01 -0.14843750E+00 -0.12564100E+06 0.74786312E+05 -0.26175210E+07 -0.85449219E-03 0.74786375E+05 0.74786250E+05 -0.12564100E+06 0.26175210E+07 -0.74786312E+05 0.14999998E+09 0.12820510E+07 -0.74786375E+05 0.19230770E+07 0.57692310E+07 -0.74786250E+05 0.96153820E+07 -0.12179487E+08 -0.26175210E+07 0.28846144E+08 0.57692300E+07 0.14999998E+09 0.26175210E+07 0.57692300E+07 0.28846144E+08 -0.74786375E+05 -0.12179484E+08 0.96153830E+07 0.74786312E+05 0.57692300E+07 0.19230770E+07 0.50256412E+06 -0.24218750E+00 -0.25000000E+00 -0.12564100E+06 0.74786312E+05 -0.26175210E+07 -0.24414062E-03 0.74786312E+05 0.74786312E+05 -0.12564100E+06 0.26175210E+07 -0.74786375E+05 0.15000000E+09 0.12820510E+07 -0.74786312E+05 0.19230770E+07 0.57692320E+07 -0.74786312E+05 0.96153830E+07 -0.12179486E+08 -0.26175210E+07 0.28846144E+08 0.57692310E+07 0.15000000E+09 0.26175210E+07 0.57692310E+07 0.28846160E+08 -0.74786312E+05 -0.12179486E+08 0.96153830E+07 0.74786312E+05 0.57692300E+07 0.19230760E+07 0.50256419E+06 0.59375000E+00 -0.60937500E+00 -0.12564106E+06 0.74786375E+05 -0.26175220E+07 -0.73242187E-03 0.74786437E+05 0.74786250E+05 -0.12564106E+06 0.26175220E+07 -0.74786312E+05 0.15000003E+09 0.12820520E+07 -0.74786375E+05 0.19230770E+07 0.57692330E+07 -0.74786187E+05 0.96153850E+07 -0.12179493E+08 -0.26175220E+07 0.28846160E+08 0.57692320E+07 0.15000003E+09 0.26175220E+07 0.57692320E+07 0.28846160E+08 -0.74786500E+05 -0.12179487E+08 0.96153880E+07 0.74786375E+05 0.57692330E+07 0.19230770E+07 0.50256412E+06 0.85937500E-01 0.15781250E+01 -0.12564100E+06 0.74786250E+05 -0.26175200E+07 0.74786312E+05 0.74786312E+05 -0.12564100E+06 0.26175210E+07 -0.74786187E+05 0.15000000E+09 0.12820520E+07 -0.74786312E+05 0.19230770E+07 0.57692300E+07 -0.74786375E+05 0.96153870E+07 -0.12179490E+08 -0.26175210E+07 0.28846144E+08 0.57692300E+07 0.15000000E+09 0.26175200E+07 0.57692290E+07 0.28846144E+08 -0.74786375E+05 -0.12179490E+08 0.96153870E+07 0.74786437E+05 0.57692300E+07 0.19230770E+07 0.50256400E+06 -0.12890625E+01 -0.11250000E+01 -0.12564100E+06 0.74786187E+05 -0.85449219E-03 0.74786250E+05 0.74786312E+05 -0.12564100E+06 0.26175200E+07 -0.74786312E+05 0.14999998E+09 0.12820510E+07 -0.74786437E+05 0.19230770E+07 -0.74786312E+05 0.96153800E+07 -0.12179482E+08 -0.26175200E+07 0.28846144E+08 0.57692280E+07 0.14999998E+09 0.26175220E+07 0.57692310E+07 -0.74786375E+05 -0.12179482E+08 0.96153820E+07 0.74786312E+05 0.57692280E+07 0.19230760E+07 0.25128206E+06 0.46367419E+06 -0.85449219E-03 0.74786250E+05 0.74786312E+05 -0.62820488E+05 0.10769230E+07 0.75000000E+08 -0.74786312E+05 0.96153800E+07 -0.12179482E+08 -0.15405980E+07 0.14423071E+08 0.75000000E+08 0.26175210E+07 0.57692310E+07 0.28846160E+08 0.96153850E+06 0.50256412E+06 0.70312500E+00 -0.13281250E+00 -0.12564106E+06 0.74786375E+05 -0.26175220E+07 0.74786312E+05 -0.12564106E+06 0.26175220E+07 -0.74786375E+05 0.15000000E+09 0.12820510E+07 -0.74786250E+05 0.19230770E+07 0.57692310E+07 -0.12179488E+08 -0.26175220E+07 0.28846160E+08 0.57692320E+07 0.15000000E+09 0.26175220E+07 0.57692320E+07 0.28846160E+08 0.96153840E+07 0.74786250E+05 0.57692320E+07 0.19230770E+07 0.50256412E+06 0.28906250E+00 0.39843750E+00 -0.12564100E+06 0.74786375E+05 -0.26175210E+07 0.24414062E-03 0.74786250E+05 0.74786375E+05 -0.12564100E+06 0.26175210E+07 -0.74786312E+05 0.15000000E+09 0.12820510E+07 -0.74786312E+05 0.19230770E+07 0.57692300E+07 -0.74786437E+05 0.96153870E+07 -0.12179488E+08 -0.26175210E+07 0.28846160E+08 0.57692310E+07 0.15000000E+09 0.26175210E+07 0.57692310E+07 0.28846144E+08 -0.74786250E+05 -0.12179491E+08 0.96153850E+07 0.74786312E+05 0.57692310E+07 0.19230770E+07 0.50256412E+06 0.25000000E+00 -0.27343750E+00 -0.12564100E+06 0.74786187E+05 -0.26175210E+07 0.36621094E-03 0.74786500E+05 0.74786187E+05 -0.12564100E+06 0.26175210E+07 -0.74786187E+05 0.15000000E+09 0.12820520E+07 -0.74786437E+05 0.19230780E+07 0.57692310E+07 -0.74786250E+05 0.96153880E+07 -0.12179493E+08 -0.26175220E+07 0.28846160E+08 0.57692310E+07 0.15000000E+09 0.26175220E+07 0.57692320E+07 0.28846160E+08 -0.74786437E+05 -0.12179487E+08 0.96153850E+07 0.74786437E+05 0.57692310E+07 0.19230770E+07 0.50256412E+06 -0.15234375E+01 -0.78125000E-01 -0.12564100E+06 0.74786250E+05 -0.26175210E+07 -0.85449219E-03 0.74786312E+05 0.74786312E+05 -0.12564100E+06 0.26175200E+07 -0.74786250E+05 0.15000000E+09 0.12820520E+07 -0.74786437E+05 0.19230770E+07 0.57692300E+07 -0.74786312E+05 0.96153820E+07 -0.12179484E+08 -0.26175200E+07 0.28846144E+08 0.57692280E+07 0.15000000E+09 0.26175210E+07 0.57692300E+07 0.28846144E+08 -0.74786312E+05 -0.12179484E+08 0.96153820E+07 0.74786312E+05 0.57692300E+07 0.19230760E+07 0.50256419E+06 0.94531250E+00 -0.10156250E+01 -0.12564106E+06 0.74786625E+05 -0.26175230E+07 -0.12207031E-03 0.74786312E+05 0.74786250E+05 -0.12564106E+06 0.26175230E+07 -0.74786625E+05 0.15000002E+09 0.12820510E+07 -0.74786062E+05 0.19230780E+07 0.57692330E+07 -0.74786312E+05 0.96153820E+07 -0.12179482E+08 -0.26175220E+07 0.28846160E+08 0.57692340E+07 0.15000002E+09 0.26175220E+07 0.57692350E+07 0.28846160E+08 -0.74786250E+05 -0.12179482E+08 0.96153790E+07 0.74786062E+05 0.57692330E+07 0.19230780E+07 0.50256425E+06 0.42109375E+01 0.16250000E+01 -0.12564100E+06 0.74786500E+05 0.74786687E+05 0.74786250E+05 -0.12564119E+06 0.26175240E+07 -0.74786125E+05 0.15000006E+09 0.12820520E+07 -0.74786187E+05 0.19230770E+07 -0.74786250E+05 0.96154010E+07 -0.12179514E+08 -0.26175250E+07 0.28846192E+08 0.57692380E+07 0.15000005E+09 0.26175210E+07 0.57692320E+07 -0.74786687E+05 -0.12179502E+08 0.96154010E+07 0.74786687E+05 0.57692390E+07 0.19230790E+07 0.25128194E+06 0.46367419E+06 0.97656250E-03 0.74785812E+05 0.74786750E+05 -0.62820441E+05 0.10769220E+07 0.74999952E+08 -0.74786750E+05 0.96153810E+07 -0.12179472E+08 -0.15405970E+07 0.14423061E+08 0.75000000E+08 0.26175220E+07 0.57692310E+07 0.28846160E+08 0.96153850E+06 0.50256419E+06 -0.46875000E-01 -0.21093750E+00 -0.12564106E+06 0.74786375E+05 -0.26175220E+07 0.74786312E+05 -0.12564106E+06 -0.74786375E+05 0.15000002E+09 0.12820510E+07 -0.74786312E+05 0.19230770E+07 0.57692310E+07 -0.12179488E+08 -0.26175220E+07 0.57692320E+07 0.15000002E+09 0.26175220E+07 0.57692320E+07 0.28846160E+08 0.96153840E+07 0.74786250E+05 0.19230770E+07 0.50256419E+06 0.78125000E-02 -0.14843750E+00 -0.12564106E+06 0.74786312E+05 -0.26175220E+07 0.24414062E-03 0.74786375E+05 -0.12564100E+06 -0.74786312E+05 0.15000002E+09 0.12820510E+07 -0.74786437E+05 0.19230770E+07 0.57692310E+07 -0.74786437E+05 -0.12179488E+08 -0.26175210E+07 0.57692310E+07 0.15000002E+09 0.26175220E+07 0.57692310E+07 0.28846160E+08 -0.74786250E+05 0.96153850E+07 0.74786312E+05 0.19230770E+07 0.50256412E+06 0.23437500E-01 0.28125000E+00 -0.12564106E+06 0.74786500E+05 -0.26175220E+07 0.24414062E-03 0.74786375E+05 -0.12564100E+06 -0.74786500E+05 0.15000000E+09 0.12820510E+07 -0.74786187E+05 0.19230770E+07 0.57692310E+07 -0.74786437E+05 -0.12179482E+08 -0.26175210E+07 0.57692320E+07 0.15000002E+09 0.26175210E+07 0.57692320E+07 0.28846160E+08 -0.74786125E+05 0.96153810E+07 0.74786187E+05 0.19230770E+07 0.50256400E+06 0.11640625E+01 0.13359375E+01 -0.12564100E+06 0.74786312E+05 -0.26175200E+07 0.97656250E-03 0.74786375E+05 -0.12564100E+06 -0.74786187E+05 0.14999998E+09 0.12820510E+07 -0.74786312E+05 0.19230760E+07 0.57692280E+07 -0.74786375E+05 -0.12179494E+08 -0.26175220E+07 0.57692310E+07 0.14999998E+09 0.26175200E+07 0.57692280E+07 0.28846144E+08 -0.74786312E+05 0.96153890E+07 0.74786500E+05 0.19230770E+07 0.50256406E+06 -0.31093750E+01 -0.27187500E+01 -0.12564106E+06 0.74785812E+05 -0.26175220E+07 -0.12207031E-03 0.74786250E+05 -0.12564094E+06 -0.74786125E+05 0.15000000E+09 0.12820520E+07 -0.74786937E+05 0.19230780E+07 0.57692350E+07 -0.74786312E+05 -0.12179482E+08 -0.26175190E+07 0.57692270E+07 0.15000002E+09 0.26175230E+07 0.57692330E+07 0.28846160E+08 -0.74786250E+05 0.96153790E+07 0.74786375E+05 0.19230750E+07 0.50256425E+06 -0.35390625E+01 0.13046875E+01 -0.12564100E+06 0.74786562E+05 0.73242187E-03 0.74786250E+05 -0.12564100E+06 -0.74786562E+05 0.15000005E+09 0.12820500E+07 -0.74786062E+05 0.19230760E+07 -0.74786250E+05 -0.12179474E+08 -0.26175200E+07 0.57692300E+07 0.15000000E+09 0.26175200E+07 0.57692300E+07 -0.74786250E+05 0.96153740E+07 0.74786000E+05 0.19230760E+07 0.25128200E+06 0.46367700E+06 0.97656250E-03 0.74786375E+05 -0.62820547E+05 0.74999984E+08 -0.74786375E+05 -0.12179494E+08 -0.15405990E+07 0.44230768E+08 0.15405980E+07 0.14423078E+08 0.25128206E+06 -0.46367525E+06 -0.62820520E+05 -0.10769230E+07 0.75000000E+08 0.15405980E+07 0.14423078E+08 0.25128206E+06 -0.46367462E+06 -0.62820488E+05 -0.10769230E+07 0.74999984E+08 0.15405980E+07 0.14423071E+08 0.25128206E+06 -0.46367625E+06 -0.62820543E+05 -0.10769240E+07 0.75000016E+08 0.15405990E+07 0.14423084E+08 0.25128206E+06 -0.46367419E+06 -0.62820488E+05 -0.10769230E+07 0.75000000E+08 0.15405980E+07 0.14423071E+08 0.25128187E+06 -0.46367400E+06 -0.62820441E+05 -0.10769220E+07 0.74999936E+08 0.15405970E+07 0.14423061E+08 0.25128200E+06 -0.46367694E+06 -0.62820543E+05 0.74999984E+08 0.15405990E+07 0.12564106E+06 Matrix/inst/external/Z_NA_rnk.rds0000644000176200001440000001303013507406613016472 0ustar liggesusersUFww'wN$H2;33;38{_.=럵޼SյKns)FIO0Y[O#6rށѨ^Fvo4!j<<Ƌa̶B4x&ǘφxN0x.2k‹ 72^OϱxA֟xQx %9vaRIc_`DkKOh<:Ӱ023Ƌ|Jcmx9xFᙌY6013^0@xUyX|k m<;'+_m\6?5x|#cklxܘk1nckwכ_s41kŇk1cA}cS9Wos/7c̹hbܹ^ecƖƌU͗3V5e|2V4?벽 ~va o`cF^/1> xce,x#?a|<˷4>xjh^fgÍ/Yr]_?_ xu 4'd||1aC;/8Ɨ{_ l||;m|k6ߘχ)_81σ816Nc̱_ c\?sK/3f 7x錹_Ϸ81Zј{)d̹3soYlda\ߚ?e}<-7zksŵ9q#͍0[/p=]πw5>͘/ne|4ɘ{?3ގ;so{/D-{wN5f<_n|=|D}ˏ4>&ƌhK}K~ƌ%qccx1g<*.Xr8Xc8cxmg[3& bИX)\dL.6& ? _n|]}]wçltcbp Ħcbp1uΘX<\o*|kg? m|cbp1J՘&fNj|$g;n̳*aL4~ܘ,&O?i31_˘\*mL1~x4ƿ{?7&w +2 ~wy;S1^rxix"^2&/Og]G~>7 ˜<|iLl2ژ|8bL^5& ׍gMcqm<T7[cbx;|o<6x[ÏK'cջ~ xA4^2^xQxcW1Vs곿쭒^ 83^xxbeIɵs=sp05&'7/grqAcr1P\٘\(bL.W5&ՍE"qMc~k qcr1`\̘\0.ṉKťqCcb1KԘ&nbL76&ufǍ;_N2& obՌ9aec򽰃1Q8e (6Ɩa cbpUĮPcr0Ҙ\$lL,FA2a1P8֘cw?r0И?W8ژ\3ḵ C¶cr1MØX>fLFݍÉBa/cbp1pXxxEcrp1HcƧz63ޅ9͟bƌga~c]5=,j̵4w˘s5\̘Y01~k/,\a6'5sœƜ˰D_0]x|Ϙ~372fh>kܹS5m7ɘ\ >h'wKoĖE[Nnr>}=^۞rmorxO_5&+"[X_=ac5o̶y]\$>bLn/6&7sƣGuƸӌɍ?߇1VPȎ=\akGQͪ/`̵ך?_۞G~ձm ?ܞO:f1؟|U̘sX[}M:F n*V(y>mw6c,ƚ/zxpjVdƚXƊ&7޺}~kVnk.kNcŲ`1VVbu5W7rEu-niar-{oocF +X: +V[Xuo 6V컖bemks1cvkXf-64Vl1Z+Yz2V.6Xƺ?ھkV쾹rdwucb+w[X 6V켐ru`+)[X:۵LJ5jd cBkkdnS}^mVmibi;1js>56XύOƪ=6UyfC}c|֬Z]o{ǻxYU[Me^j3&ǟOjƪ Nlz''c}elxD;^Y4mޥ/ԼS^z>5֎wxd~OPc%۷~|Y]Wt5w7|5녙4J0t5^ j׋"z9B/袗?^ЋzA/$%yP * *ΪўHQ *W5IZ*\ P\ ךQԀ&*52YI AjQ#i԰O5B /jBQ@&5~B jJĽ&5!I^Mkr\ܚd_jUS5Y OM"j"PeӤ&4aI:M|i2K jTc &J5"O rjrS㞚Ԡ/UVADErT"K +QCIQ%Jd)S2^E%J@hFk߾&ҍS zhAZ" T*Pp@A/=*R N7 2zi@tTd׋"zYE/^ы` [ЋKzJ/84᠗x4q4$“&הi]ajV5+5%Mi2H/5kIj8SӠl85qLdj IDjRԌ5D$jQW, jBBo%>D[W-JoMkGEA߫ RUt{( VЍY{ÿW>=TĿW^{ſWB*H߫[%5ѭ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))~{o|t=F1fĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿĿWWW@\TOIO9żz}?;o;z_ˈzF!J˯1xԈخ4x(bOpdMAMatrix/inst/external/wrong.mtx0000644000176200001440000000010311204272304016170 0ustar liggesusers%%MatrixMarket matrix coordinate integer general 2 3 2 0 1 1 1 3 4 Matrix/inst/external/wrld_1deg_slots.rda0000644000176200001440000035070210770571602020115 0ustar liggesusers\lՕ޸ !xp%wwwww^U|s7!vz|,li:kؿ[:a]1w)~[Z?oٓ~Ҟʞڞƞ{3ƴg,{ƶg{Ƶg<{Ʒg{&Y?'2ᆴ)~5N3ԃu{g:{g{fg&{fg{ך}1Xganw?ysw?~ ~ ~a,wޖ}M8xO,cϲg=+س=ٳ`]ybϟY՞Yݞ5Zu{r^{Nj_+u|c=g>;dž|F6r泲3?Ck 5ڤ59۴5۬5ۼ5YyV{tʞm֞ޞўŞ]=ٳ[y3:[Lg_|&p33ɽgog>8י~|&| .eAl!Ж>??n fh ~l j v}3cg>85'Nl I왓78wNuf:ݙ=t3{LgYs3{gйC;.pf]ș=t3{gХ˜C;pڞ+W횖ݵ=x]kx?^ޛ7s=;Þ;˞{מߞyGiϣΏ yž'yʞyƞg[3ޙə3g-C^~ݙ_g7o9vf/^~י3{}g9?vf/^ԙ3{sgΧ3{+go:sf/^3{'g_˿:_gr-vOf/eu;Xf=Nex;mf:̓nfncϲOs~mڻmf6>n-2{=̞n/2{=̞nO,^_׶msYf_mfmS42=nO' 2=n$3,2=n&۳2=n%s<2=n'ew{^Pfew{^Tfew{ g[K:ۿr^wOζ8n/{wԶ;nlJζ+;n<׶kWfc{vc:}^b/>> >퍝}s>M>͝>->>m>>>;翽}ۻ8翽}p{7gwg>r3=og>8י~|w3g9jV櫶Tm6;m^jیԶ9mO敶5o{gc>ڼѶ=s`e\~ԙr3rg+/W9_vf\~֙r3zg /79_nvf~ՙr3vg;/w9_vf~יr3~g/9_vf<~yԙ3qg'/O9_vf<~y֙=3{YY`i`e7X{;>pf~̞5??n OZ5?wi`eaaava^aFa.a9ݞ3/3o[{惎1~N)챹=o>tWޯm뛎n=[fwƑqexg<=_fw& exg"=ޙXfw&Iex2{3L.;SΔ2{3L-;δ2{3L/;3Ό2{3,;ά2{3.;sΜ2{3-:8;Xmls!ζ;:>lsοmwp}9ҙ9Qζ;G;>lsqζ;;>ls 5낎uAfw9ͽ}mб>Xtl|߱cso/nfڽn>\X׭9s9p3Μw9s9p3Μ9s93Μ9s<93Μ9s<93ΜO9s<93Μ9s<93Μ/9s9`}p6X5:ǜܻܭܧܡ;^kxߙ3g΍97>rؙsg΍O97>sܙs g΍/97rڙsg΍o97sޙsg΍97~rٙsgί2cVvtk 5@fyԍ[R7i QTeΜjҵZtm.Ztζud1X7ccmѵkJcg`wB;̹؝5tFv'i I[Cggs;ܹ~=搮]76ctm2;ܝ5zwg;ۯgve2̶;G)wsݝ5twm ]{[O.5FW:=>{;+w{tunbK+wѻ{uo*[]YWk{jcjwVFgkMa[Y[S9>X]۝vWknl۽Ǚ;85vut{c݇>lXQgǺ9=}vut{cݧ>lXYgǺ9=} vu_t{cݗlXUgǺ9=ֵ3xrgq/qm0xcC+wwwڧѻqϝ~l\KgW7vqǍvuuo~l[Ggߺ?9/vuu޹b?s2K3[+sz2[/z֋d^,soL~2[z֫d^-s7"sƐzcod2[o7O~/s&zod2[o;7]ܵM<`{cٛjN=Xc9{+wfo:c>_K{3ܥYdެ2jo6;7{k{{s]\sVwzv~ٽҳgE=#zv/y߳3gz=lݯ-+ss{ܹdފrZʃ2 Z{ V;{ܽ7ڰ[G+s֓{ͽ dކ2so#;ܵ~oZ`ye~حvW{սmev2wuo{]Q$sW.sWv{ս]e?dn2wu2wuow/]S%wkqrZGVN{F!rZwa3;C=;F+w-{9s}:x(s#sN{'Sdީr׺wywFe)3 Βzgsdf޹2@gz;,{fރ6 rYG u ǝmf=lCIg!zO9,{f36[umlFEg5z/9۬{f+6k^uYםmי gf7[[Nkxfy5<eo 5g}{97|V|s`~߹cѹ,XSf> ֒ӂe/2s[+3o2s\Ll(u76 -g`+{7|&hh8ڜ"]_+#jb{eNd6]m. =e`/1[fF }ef`?1_fF ef 18XfF Cef018\fF -3#G̈23bp̌-3#̈23bp̌/3#'̈23b18IfF NSdfT18MfF N3dfL18KfF Ζsdf\18OfF Η dfB1HfF .KdfR1LfF .+dfJ1JfF kdfZ1NfF dfF1IfF n[dfV1MfF n;dfN1KfF {df^1OfF dfA1xHfF GdQ1xLYs;?_/'[sfܳv~fwj <7XٜWZCkrkh ^i ʹ6x54=ko V~6#WY9f#gmV>qY9f3g/;ۼ|33WylMkx5 `2 >$`2 >"`2 >&a2->!c2=>%d2m>#h2>'l2 o2$o2"o2&o2 W7d.|5x[ ߖw5ah=ݴ8n ?c ?S ?s K k [ { G g WV[2]uZCu[Cd1 d1 e:2dz2e2Jd2Je2d2e2*d2*e2d2e2jd2h ƌƔih,n 5h4LFh4LFˡp46&ꯡΓ Vk4s'M1XG#4֍7#k2J~+M"{G:_hڟlMIg-iCV>icV>iSV>isViKVik^[k t`#ňF{̭}m^;2wez9rrrrrrrrr\r\r\r\rr<"2)X2-82+x2/2O(D2O,$2O*dz9Lez9Bcc|O-ӻ42O+ӽt2O/ 2=jx&9;yJ/dzW9M[C-xPcsz;5<m 5y<J W=^Pd=^XEd=^TȾxq%+m/_x)t=MO/+r2// 2վxeU_L u.=xվx fהix-fזi/2#2'2o 2o$2Uɑ}1 c_kLǛɴ|L[ȴ|L[ɴ|Lȴ|L35Ѳվx{.wxG.wrd_G.Z1?'.xhx6ix/6ix6ix?6i6i 6i6i06i2m!2m%GG;_|`iAzW:>>Ie:>>ESe:>>Me:>>C3e:>>Ke:>>Gse:>>Oe:>@ e:>He:>DKe:>Le:>B+e:>Je:>Fke:>Ne:>Ae:>Ie:>E[e:>Me:>C;e:>Ke:>G{e:>Oe:>~@e:>~He:>~DGe:>~Le:>~B'e:>~Je:>~Fge:>~Ne:>~Ae:>~Ie:>~EWe:>~Me:>Lot|Lot|Lt|Lt|Lt|Lt|Lǟt|Lǟt|L_t|L_t|Lt|Lt|L?t|L?t|Lǿt|L'-O2td:>t|ғ$$$4<>$2-OP'lIJ gk:/KξdJ'ct2L't2L't2L't2L't2L't2L'd2O&d Od*OdOd:OdOfd&OfdOfd6OfdOd.Od9U2|Zj?dOd!OdOd1Od wɒ2d$K˼H$ YF@;d9w2d$+ʼHVy,> YE}@gɪ2d$˼H֐y)N YK@v~{sXέ}'ɴ~L'ȱ}ɆW?'=uV:Md=Tߓd=\ߓ-d=Rߓd=Zߓmd=M91^L„Ftו&?eZ<]œɴxL'{ʴxL'{vkp׻L'wrL'wrL'˴xr[':6XZ~6ɑvOihOXOxONDO#I2,)2*i2.2)Y2-92+y2/2-\(E2M\,%2}\*e2͟\.2ݟ\)U2ݟ\-52ݟ\+u2ݟ\/ 2ݟ(M2ݟ,-2ݟ*m2ݟ.2ݟ)]2ݟ-=2ݟ+}2ݟ/2ݟ<(C2ݟ<,#2ݟ<*c2ݟ<.2ݟ<)S2ݟ<-32ݟ<+s2ݟi#O>iO>i3O>i Oi+OiOi;OiO~i'O~iO~i%i[ӎL]O{222F22&22f2222V22624~:Lc4~:Lc4~:L4~:^izZGWRwtbO'itJޣ}-d2ݝN.2ݝN)T2ݝN-42ݝN+t2ݝN/ 2ݝ(L2ݝ,,2ݝ*l2ݝ.2ݝ)\2ݝ-<2ݝ+|2ݝ/e;]@e;]HӅe;]DEe;]Le<]BNkKt^jZlyLee<]Ne<]Ae<]Iӕe<]E?tyLtyLktyLktyLt.Oוt=.Oחt.O7t#.O72]Mt9%yҗԚ1NL SkZ߭};tzL;zw9#yJz|/ j_oLtNOt/NOt9A35=5遭Oj ~zpkCľPgz[{O-2)Q2-12+'t} OO?2$2"2& =]]@z#=J&= =WAz̻|w2 eɼ;H/yw^" TAz̻rw2+eWɼ;Hyw^# VAz̻zw 2e7ɼ;Hoyw" UAz̻vw2;ewɼ;Hyw# WAz̻~w2eɼ;Hyw>" }TA̻qw2'eOɼ;Hyw># }VA̻yw 2e/ɼ;H_yw" }UA̻uweoȼ;Hߔyw% }[A̻]w{2eȼ;H?yw~$ XA̻Swg2e_ȼ;Hyw~% ZA̻[ww2e?ȼ;Hyw$'Lv!!kɼCh0~n>ul'> dd,y2D}@ʼ2Y.> +ddy2F}@6"> C}@6l,2qddʼƓy/> @}@6l"2Iddʼ > L}@6l ٔ2ddS˼ȦyM+> N}@6l9U6L5Y6`eҏ|oվlv~lN~ln~l^~l~~(2-(B2-,"2-*b2-.2-)R2--ٟd=[F߳ee=[N߳e=[A߳e=[I߳e=[E߳?{Lg4|Lgkt}Lgk4~Lgil֕il=֗il6il#6i2Mil6il36il ϶il+϶il϶il;϶ilvil'huk٭e֓475/-ilil/ilil?SsF_Ґt5afkJ'ZeW:8;\3g:8s3g:8s3|Nˎi8͎ig6ZtZe'lvLfȴmvLftnvLfgtnvLfgtnvLftnvLftnvLftnvLftnvLftnvLftnvLfWtnvLfWtnvLftnvLftnvLf7tnvLf7tnvLftnvLftnvLfwtnvLfwtnvLftnvLftnvLftnLftnLftnLftnLfOtnLfOtnLftnLftnLf/tnLf/tnLftnLftnLf ޔ-ޖޕ=ޗ>#>>3> ;+;;i;;w~p~t~ryvu[ޒi߼-ӾyG}L=C#cS3s K+kGd7C}1e7K}e7G}qe7O}e7@} e7H}e7D}I+K뎮րd2O.ӹ2O)ӹT2O-ӹ42O+ӻt2ݛO/ӿ rf <`៥ +]!2]%2]#2]'2]Qd8_Pd8_XEd8_Td8_\%d8_Rd8_Z?tqLtqLtqL+tqL+tqL|U.W|u.א|M.ג|m.":2]+z2]/2]o(F2]o,_e8L'&2]o*f2]o.2]o)V2]o-62]o+v2]o/2](N2]]ά{w.ݛӿiGWk|w%ӳ2=)ӳ^2==5ڲ|i@i`iP9su6?Bm#:8?Jg'6?Nme6?Ame6Oki:6?YcSd:6?Ucd:6?]c3d:6?Scd:6?[csd:6?Wcd:6?_c d:6Pcd:6XcKd:6Tcd:6\c+d:6Rcd:6Zckd:6Vcd:6^cd:6Qcd:6Yc[d:6Ucd:6]c;d:6Scd:6[c{d:6Wcd:6_cd:6Pcd:6XcGd:6Tcd:6\c'd:6Rcd:6Zcgd:6Vcd:6^cd:6Qcd:6YcWd:6Ucd:6]ctlLotlLotlLtlLtlLtlLtlLtlLtlL_tlL_4mY౮Ϳwptrvqu-Z2][etmѕڢ'ӵE ӵE(ӵE$ӵE,ӵE"ӵE*ӵE&ӵE.ӵE!ӵE)ӵE%ӵE-ӵE#ӵňLY40;[Q vc-Z#ӢŸ2-Z'Ӣ2-ZL Ӣń2-ZL$Ӣ_Ϭў,&2mYL&Ӗ2mYL!ӖŔ2mYL%Ӗ2mYL#ӖŴ2mYL'Ӗ2mY ӖŌ2mY$Ӗ2mY"ӖŬ2mY&Ӗ2mY!ӖŜ2mY%Ӗ2mY#Ӗż2mY'Ӗ2mYQ-dڲXP-dڲXX-EdڲXT-dڲX\-%dڲXR-dڲXZ-?ɴeL[ʴeL[˴eL[+ʴeL[,HqZbUN,VbuN,֐bMN,֒bmN,"Ӊ:2X+Ӊz2X/Ӊ2Xl(ӉF2Xl,ӌuva?~&?~&|t!=8Z [ʴ`L [˹ud3'[ezAezI`L`Lskb7V~G kb6,b/N,skbg~֌t"-H'i-گ8}A2W,}!2W*}a2W.}ſe8B#e8Je8Fce8Ne8AeL't_qLt_qLt_qLgt_qLgt_qLt_qLt_qLt_qLt_qLt_qLt_qLWt_qLWt_qLt_qLt_qL7t_qL7t_qLt_qLt_qLwt_qLwt_qLt_qLt_qLt_Lt_Lt_Lt_LOt_LOt_Lt_Lt_L/t_L/t_Lt_Lt_zxCέ'7t_vwdxWdx_dٚٚٚٚٚٚٚٚҙʙڙƙ֙Ιޙљəٙřg5ె+2 Wvd4\ٓi2i2i}Fce"ce*ce&ce.ce!ce)ce%ce-ce#cLcWZ]ʱdګRZtNZWtU9LWtU9LWtU9LWtU9LWtU*'rr*rJ*rj*rZ*rz*grF*grf*grV*grv,psߙV9Oye:Oe:Lg tVLg tVLgtVLgtVLgKtVLgKtVLg ӒkrP˷ڬ\A.EW]n;Z35wp5VLck4VLckW]ʿTLSʴU\Xo;3-iHkZؿV~3믴RL/RL/RL/[RL/[RL/RL/RL/;RL/rg^*wrW^*!Kn2TSezL/{RL/{RL/RL/RL/RyL/RyL/RyL/RyL/^*(^*J+GQyL˴QyL'ʴQ6*Oid6*OiT6*Oit6*ϐiL6*ϒil6*ϑi\6*ϓi|6*/iB6*/ib6*/iR6*/ir6*iJ6*ij6*iZ6*iz6*oiF6*oif6*oiV,osIF*.V*^*>^*^*!^*^*1^* ^*)^*^*9^*^*_쯿n6*_igȒτ5R߽ MB _*t)r)v)q)u)sέ?hf}f#gˏm/?q>u>s>wžpžtžržvžqžužsžwGg'ggg_m/ujU[f:2Օi'U U(U$U,U"U*U&U.U!U)U%U-U#ՈLTc4@5LTcɥZ58z]mƓe@ eH.ɪmT|i5j5_M)Z{kڬ_M#3Wt2~}S8XLۼ__YdjVfijvijNijnij^ij~(2-P-(B2-P-,"2-P-*b2-P-.2-P-)R2-P--՟dZZFeeZZNeZZAeZZIeZZE?˴@L Tɴ@L Tkȴ@L Tkɴ@L Tij֕ij=֗ij6tި&*+=@6Wզ2_m.3W[Ֆ2_m-3Wն2_m/3W;Վ2_]fv]djW_&3We_2_)3W{2_+3W2u_(3W2uLTt@uL T˴@oiHihiXixNiD#I2-P,)2-P*i2-PWlޮ쯥5U~`Nf6~ϭ6 WȥuNu3ٗyS|[]_mpͲE2lu,[]"3V̲e2lu,[]!3VW̲U2lu,[]#3V̲u6V;,[lluͲM6V7;,[lluͲm6VVc]GW[;mnrg&{mnsg[mnrzg]Gǵ1gx)g_m~qz9gf睭_/c[YU+`fWUfMg-gXVf=g]mv>pٵf#g]iOiOiϜiϝi/i/iiioioiiiiiii_i_mv[2kݖ]Zwef׺'3ցZ2k̮u,3։Z2k̮u.3օZ2k]̮u-3֍Z̮2k=Z%3c̮82k=Z'3̯23l=[O$3˕u^=Ce'gez yRfgezyVfgezyQfggezyUfggezySf璙gezyWf瓙ge2l<[/(3 ̳2l<[/*3֋̳2l<[/)3K̳2l'y^Ffgdzyy^AfWgdzey^Ef,3̳֫j2l<[!3k̳Z2l\Y՜'6Wz=ޫw`rNЄt F]VC̡ddz9Tf7Cez 9RfCez9VfCez9QfwC˕uX.޵2Gd2h\f-3G̦2sj}\b>[_edfx~Op>q߰^ee}ۭ֜μyg ln}ve֭ϑusef_f֭/u ef"YXf֭/uKef2Y\f֭u+ef*YZf֭ukef:Y^f֭ouef&gu뛝m֭oqYf6gu۝m֭pYf.gu뻝m֭qYf>gum֭pY~f!gF뇝m֭qY~f1guǝm֭pY~f)gu망m֭qY~f9gum֭_pY~f%gw뗝m_q~5g{םmlsoͽ6o9[lsoͽ69[lsoͽ69[lsoͽ6֟9[lsoͽ6_9[lsoͽ69[lsoͽ6?9[lsoͽ66-i̽MGfm2soӓ{@fmBd&{DfmRd&{BfmJdަ{FfmFdf Sfmƒ{eކbc3o3ی/36̿̈́rmL̹`ܰigzjn3̬L.36S̺͔2n3̬L-36̺ʹ2n3̬L/363̺͌2n3̬,36̺ͬ2n3̼.36s̽͜2so3-36̽ͼ2so3/36{dfAYHfm{EdfQYLfm%dfInr^zrepLܬ 37+J23qLܬ"37Uef5Y]f>n֐5eff-nvs)Zu+{FO<6G7Yll,3;7&2sl&3;72sl%3;7[62sl'3;72s$3;7effٹUfvn!3;7?effwٹ!3;7{^2s#3;7~2s 3;7A2ss"3;7a2ss[fvn#ef(ٹ9Zfvncef8ٹ9^fvnNef?2ssܜ,3;7ͩ2ssܜ.3;7g͙2ssܜ-3;7͹2ssܜ/3;7ͅ2ss\,3;7ͥ2ss\.3;7W͕2ss\-3;7͵2ss\/3;77͍2ss,3;78lss6;7w8lss6;78lss6;78:}ukg7o9[wNl>:}ugg/_9[~wNd:=MӃe:=CӃ1e:=KӃe:=GӃqe:=OӃe:=@Ӄ e:=HӃe:=DӃIe:=LӃLLLLLLLLLLLLLLLLL#d:=\Ӄ)d:=RӃd:=ZӃid:=VӃd:=^Ӄd:=QӃd:=L3tz0LtzWNf`vN`NNo2-<2]Ӄye:=OӃe:=X@Ӄe:=XHӃe:=XDӃEe:=XLئy?>2},%2},#2},'2} 2}$2}"2}&2}!2}%2}#2}'2}l l:c]w1]ݵn6` vkl-62l+v2l/2(N2,.2*n2.2)^2->2+~2/2(A2,!2*a2>޷k)Q2-12+q2/ 2(I2 <NSi|giw1wՃ3eZ=8KՃeZ=8GՃseZ=8OՃeZ=@Ճ eZ=HՃeZ=DՃKeZ=LՃez=Bۃ+e>J~vf{Шnol7;2|w.{e!shVnӆӞӶd6H $2$xDf1]<.K2$xBfO)]<-KgdvI. %2$xvI%g%ζKWm:. ^s]l$xvI-g%ζKwm:. s]l$vI#g%|l$vIsg%ζK/m_9. v]|l$vI{g%ζKm?9. ~v]l$vIwg%. G%2$Cfcp,]-KqdvI8. Ǔ%2$@fp"]N,KIdvI8. '%@f. C]F2$evI0%a&K\f. K]V2$evI쒰%a'~e]N.K)dvI8. %2$Ffp:]N/KdvI8. g%_dvI8. g%2$. g%2$Cfsp.]Mfslp]fi iDŽiӄ i߄ ʁp!Gw.];!!6{[wmKp).-_edK~ /2%\Af+p%,_UdK~ W/2%\Cfkp--_udK~ ד/2%@fr`;:ș]}Ulpcn"UMeJV 7*2[%Rf[lpkn#Wm6v37YN w)N2;%YfpW&SevJN )^2;%[fp_'SevJxN *A2%#ge6Pmyg@ ζm/9 _v l(|6Pmug@ζ7mo9 v l(|6Pm}g@ζm9?Tmg@ζϜm; p ~l(6Pmg@ζm; N G l? _;ζw_տ:sfWl{';h2{']fDchL%weN4މƕ;x2{'_fDhBM$weN4މ&;d2{'(;Q(wHfDމ2{'d6Ol3y ݈m̨k[&jeLl2-M.e)dL4̖22[&FfDlh:-M/edL4̖f2_dL4̖f2Ѭ2[&̖f22[&CfDsh.9-ygyeL4̞32{&ZPfD ha=-"gEeL̞4rh:ZywkeevM̮5 2&ZQfD+he]"kUevM̮V52&ZSfDkhm]#kuevM̮֗6rh9Й8766owvI&6$f2$\fD[lhKMm%Ie6I&$v2$^fD;lhGM$Ie6I&v$n2$]fD{lhOM%Ie6I&$~2$_fDl@M$Ie6It&$a2$:\fDGlHM%Ie6It&$q2$:^fD'lDM$Ie6It&N$i2$:]fDglLM%Ie6It&Ε$y2$:_fDlBM]$Ie6It&.$e2$\fDWlJM]%Ie6It&$u2$^fD7lFM$Ie6It&n$m2$]fDwlNM%Ie6It&$}2$_fDl?2$zPfDlaM="IGp×m#/[%zBfDOl)=-UgmD:Vs=l[%zٶJm%g*ζUWmD:V^sl[%zٶJm-g*ζUwmD:Vsl[%ٶJE9V>v}l[%ٶJmsg__Y?>K";g!ζCmD?:~rl;$ř-3[7gζC!&CevH<ǔ!X2;$[fx\'CevH<'!D2[$XfēȑmxRF^6J<y'q OPfđ>c}'2$NeI8'q!ORfĕ>k72[%nvs9×xO!])eKHfl*Qd6J|F(2%>JfGl+Qd6J|FO(2%>If'l*Qd6J|Fϐ(2;%>Kfg+]dK|v/.2%Hfl_*]dK|v.2%JfWl_+]dK|vo.2%If7l*]dK|v.2%Kfwl+_d6L|پp{Ow=󽻶_GF?OV*2[%V'U'mO:Vr?l[%~ٶJm9g*ζUm/:V_rl[%~ٶJm5g*ζU7mo:^rl%~vK=gwl%vKcg-'ζ[Omğ9n?wl%vKmkg07ζeom9۞w=l{&Lgg3/ζg_߿9w= d4=.gIHyx2;#_fg$dBL$3evF2H&d2;#$I(3Hfg$H2;#dvF쌤I)3Jfg$H2;#dvFdH&2;#Rfg$SdjL#3ievF2H 2;#Qfg$3/2;#Yfg$dVUfg$dv!39evF2H&3evF2H.3yevF2H2;#YPfg$ da,"3EevFH2;#YRfg$Kdi,#3eevFH 2;#YQfg$+de"3UevFHV2;#YSfg$kdm#3uevFH֗2;#Pfg$F2;#H%3dcl"3MevFH62;#Rfg$[dkl#3mevFH2;#Qfg$;dg"3]evFHv2;#Sfg${do#3}evFH2;#9Pfg$`"3CevFrH2;#9Rfg$Gh#3ceFrfNw=]_wmG$4.#3dvDr̎HΒ2;"9GfG$</# dvDr̎H.2;"DfG$2\.#+dvDr̎H2;"FfG$:\/#dvDr̎Hn2;"EfG$䶑 񕻶;d6CrfH 2!Gf3$l>͐/d6C͐<(d6Cmg ɣζǜm3$1?7X _30|mo$/:H^rl{#yF5gζ77mo$o:Hrl{#yF=gGMw|l{#Fcg'ζ7Omo$9H>w|l{#Fkg7ζ7omo$9Hwl{#Fgg/ζ7_mo$9wt4.71dF:Hǒ2{#Gfotl->l->l->l->l0s K+k[;:uӏӏٞ8=?uf{~ܙ3KgWlϯٞ8=uf{~ޙ3GgOlϟٞ8=uf{ٺ;l4Fl Ɣl,Ɩlƕl<Ɨl&l"&l&l22ݝ2ݝ2ݝE2ݝ2ݝ%2ݝ2ݝe2ݝ2ݝrj3+ꑗZ:z9;ٚkM)T2M-42M+t2M/ 2(L2Eez;EYez;Logv6Logsv6Logsv7l.ټ2'2- ق2-$!y[?dc͝-!ْ2͝-%2͝-#ٲ2͝-'2͝ ي2͝$2͝"٪2흭&2!E5=?ٜk-'2-m ن2-CdZ:LKgi2-m,&2-m*f2-m.2-m)V2-m-62-m+v2-m/2-(N2-,.2-*n2-.O3٫lܵw8G}e8Oe8;@e8;H3ֺ١2&Ӻ2!Ӻ4.]ֱ2#ӱٱ2'ӱ2 ӱى2$ӱ2"ӱ٩rj;3;yLΒlΑ\Γ|.B.b.R.rͮJͮjͮZͮznFg&gfggVg6gvggNg.gngg^g>g~gg?ֳكֳCֳֳ#ֳ٣ֳcֳֳg9?|lll5mummmmmm܌willlllllllllllllllllllllllllll3'ggg6/ο_o× _6,u9wY1d5SYd5[Yqd5WYd5_Y d5PYd5X_Ih>dސލֱy,ӱy"ӱy*ӱy&ӱy.ӱy!ӱy)ӱy%ӱy-ӱy#ӱy+ӱy'ӱ9o]֤2MO!Ӥ2MO%Ӥ2MO#Ӥ2MO'Ӥ2M Ӥ2M$g7s޺9o>k2-&Ӣ2-!Ӣ2-%Ӣ6e>3ui>K4i>L 4i٦yؘcݵi|Qi|q̗i|I̗i|i̗|Y̗|yW|EW|eW|UW|uא|Mג|mב|]ד|}7|C!ӟF2S?go7|7|37| ̷|+̷|̷|;̷|w|'w|w|7w||/||? 09fѡkݙ#ӝ2ݙ'ӝ2ݙ ӝ2ݙ$ӝ2ݙ"ӝ2ݙ&ӝ2ݙ!ӝ2ݙ%ӝ2ݙ#ӝ2ݙ'ӝ2ݙ_ ӝ2ݙ_$ӝ2ݙ_"ӝ2ݙ_&ӝ2ݙ_!ӝ2_%ӟ2 _l_l=_l7-㽲AQך3ٚ3ٚ3ٚ3ٚ3ٚ3ٚ3ٚ3ٚ3ٚ3ٚ3ٺ3o{y9Q33򇝭1G1G1ǜ1ǝ1s'kI1×fG]kigkgkYgk9gkygkgkEgk%gkegkgۘфt 7Zo8[o:[o9[o;[86u].G]kgkCgk#gkcgۃ'Ο_ ޝE?օօW¯ o o     ٞ?;=qf{͙ua1$Ӆh2]X.Ӆ2]X)ӅX2]X-Ӆ82]X+Ӆx2]X/Ӆ2]XL(ӅD2]XL,Ӆ$2]XL*Ӆd2]X ddedeHdHede(d(edehdhede!Ӆ2]XL!ӅŔ2]XL%Ӆ2]XL#ӅŴ2]XL'Ӆ2]X ӅŌ2]X$Ӆ_dY YdU ta1Lta1Lsta1ۮ-x7)N֋4k}X/Ӈ2}X,(ӇB2}X,,Ӈ"2}X,*Ӈb2}X,.Ӈ2}X,)ӇR2}X,-Ӈ22}X,+Ӈr2}X,/Ӈ 2}X(ӇJ2}X,Ӈ*2}X*Ӈj2}X.Ӈ2}X)ӇZ2}X-Ӈ:2}X+Ӈz2}X/ӇrnЙw~Iͳ~,6yiǂwF p:Le:B-e:Mlgc]WQ?yN#/W,x.2W*xn2WlSŞ×7>ɞsG}eOe8@e8HÊ`BsYok]U&U2mU!#7MPű2U'S2mU ݊Oyi䑗*NT*Nt*ΐL*Βl*Α\*Γ|*.Bg"gbggRg2grg gJg*gjggZg:gzggFg&gfggVg6gvggNg.gnggSlUlUlUF+irF+ir!F+irF+ir1F+ir F+ir)F+irF+ir9F+irF+Wir%F+WirF+Wir5F+Wir F+הir-F+זirF+וir=F+חirF+7i2Vn$h?eLircF+7irSF+7irsF+irKF+irkF+ir[F+ir{F+wirGF+wirgF+wirWF+wirwF+irOF+iroF+ir_F+irF+i6hܵ*iP*ip*iH*ih*iX*ix*OiD*Oid*OiT*Oit*ϐiL*ϒil*q*u*s*w*/p*/t*/r*/v*/q*/uZ^kEgYZ%uU9ڪfZ_:[c9[c;[c78[c7:[c79-oYըk]UlUUU]UU=U%op3SʹfF]k!gkagkgk&WFHζ'ysmgaP ||||Z|yn}c菶cMUlMUlMUlMUlMUlMUlMU~lMU~lMU~lMU~lMU~lMU~lMU~lMU~lMU~lMU~lMU~lMU~lMU~lMU~lMU~lMU~lMUlMUlMUlMUlMUlMUlMUlMUlMU 4U5LSU4U5LSUc4U5LSUc4U5LSU4U5LSU4U5LSU4U5LSU4U5LSU4U5LSUB"bR2r J*jZ:zF4U5-E?LR5L/USR5L/UȥmjZg`v*Pwe:ItR5L'UtR5L'Uj6NfjNj.N&I2T#Ie:Wd:_d:ZPd:ZXEd:ZTd:Z\%d:ZRd:ZZed:ZV6i #/T8MJriZykljMU>T2MU)TZ2MU-T:2MU+T)tK2Tm(K?dzHR/Yۙ7JDk Tm& +G~*MDkj둗>ij[Fj{^vijǡ?uTПyO}U"Yծ2U&Z2U!Z՞2U%Z2U#]վri۱⭤hwܵƪi@ƪi`ƪiPƪipƪiHƪihƪiXƪixƪNiDƪNidƪNiTƪNitƪΐiLƪrƪvƪqƪuƪsƪwƪ.pƪ.tƪ.rƪ.vƪ.qƪ.uƪ.sƪ.wƪpƪtƪrƪvƪqƪuƪsƪwƪnpƪntƪnrƪnvƪnqƪnuƪnsƪnwpX՝X]XX=XսX}XSv,}Ǻzp菞Q׺wa[mD#GG9[UO8[UO:[UO9[UO;[U8[U:[U9[U;[U/8[U/:[U/9[U/;[U8[U:[U9[U;[Uo8[Uo:[Uo9[Uo;[U8[U:[U9[U;[U8[U:[U9[U;[U8[U:[#U9['U;[+U_8[+U_:[/U_9M_;[CU8[KU:[OU9[OU;[pfnə3gvμl ݵdZMeZC1ezKlc;VO٤[ּ=EKR2-UO(RD2-UO,R$2-UO*Rd2-UdZdZeZdZeZNdZNeZdZeZ.dZ.eZvg];6Itde!P2 UO!P2 UO%P2 UO#P2 UO'P2 U P2 U$P_dYYdU4T=LCճ4T=LCs4T=LCizni2 U+P|2 U/P2 U/(PB2 U/,P"2 U/*Pb2 U/.P2 U/)PR2 U/-P22 U/+Pr2 U//P 2 U(PJ2 U,P*2 U*Pj2 U.P2 U)PZ2 U-P:2 U+P5o>}ntcșwfuQo.7z.7z3.7z .z+.z.z;.z.wz'.wz.wz7.wz.z/.z.z?.. ..0..(..8.y"۰t3Z'9[';[ԧ8[ԧ:[ԧ9[ԧ;Nkz|wy}QZ>ZZZZZZZZZZZZZZZZc78[7:or歷wF]kVgk6gkvgkgkNgk.gkngkgk^gk>gk~gkgk?::C::#::c::u9[O8[O:[O9[O;[8[:[9[;[/8[/:[/9[/;[ԯ8[ԯ:[ԯ9[ԯ;[o8[o:[o9[o;[8[:[9[;[8[:[9[;[ԟ8[ԟ:[ԟ9[ԟ;[_8[_:[_9[_;[8[:[9֭wau T_CtШk۶7˾]kftiƐifLiƒifliƑif\iƓif|i&ifBi&ifbi&ifRi&if 8M 8M(8M$8M,8M"8M*8M&8M.8M!8M)8M%8M-8M#8M+8M'8M/8i&if iif*iifiif:ik 3m 9]kffififV]oEcco~c|co{{N'k=]GyezOGezY@GezYHGezYDGEezYLGezYBG%ezYJGeYFmg6:/7|nxiܵ6iVife6iVifU6iVifu6i֐ifM6i֒ifm6i֑if]6i֓if}6i6ifC6i!&F2mSMɴIo6i6if6i6if36i6if 6iif+6iif6iif;6iif6ivif'6ivif6ivif76ivif6iif/6iif6iif?6ii6ii 6ii6ii06ii6i(Nii |[ۮm4omNr7iNuӝyۭohQz9z9z9z9z9z9zzzzzzzzzzzzzzzzzzzzzc6:[49[4;[4w8[4w:[4w9[4w;[48[4:[49[4;[48[4qitiriviq<.؆mO_:!Cng9ym6#41Zs4/:[s4/9[s4/;[s48[s4:[s49[s4;[s4o8[s4o:[w4o9o;[48~lu~o[4_#gcggSg3gsg gKg+gkgg[g;g{ggGg'ggg6/'ͯ'o''LI;LcI;LcI;LI;LI;LI;LI;LI;LI;66666666银银银银银银银银vLI;LSI;LS4J;LJ;myϭWIyiܵ~igiv}Vghsܵfigivfiiv.fi&,2#,eWYd_Yd]PYڅd]XYEd]TYd]\Y%d]RYڥd]ZYed]VYd]^Yd]QYڕd]YYUd]UYd]]Y5d]SYڵd][Yud]WYd]_nl߶8oMk'[an<4wMdTd\-d:Rڭd:Zmn3 KZ;OL;OLOLOL{OL{4PL tQL4R{L#4R{L#4R{L#4R{L#4R{L#G4R{L#G4R{L#4R{L#4R{L#'4R{L#'4R{L#:[#9[#;[#g8[#g:[#g9[#g;[#8[#:[#9[#;[#8[#:[#9[#;[#8[#:[#9[#;[#W8[#W:[#W9[#W;[#8[#:[#9[#;[#78[#7:[#79[#7;[#8[#:6gkvgkgkNgk.gkngkgk^gk>gk~gkgk?Hζy[~Wh ~'=&j;|h cF]kIgk)gkigkgkYgk9gkygkgkEgk%gkegkgkUgk5gkugk gkMgk-gkmgkgk]gk=gk}gkgkCgk#gkcgkgkSgk3gksgk gkKgk+gkkgkgk[gk;gk{gkgkGg:'g- o~s6iwdMeC1eKeGqeOe:@nm#w:󶳗wrDIeLLuLuLuLuLuLuLuLuLuLuLuLuLuLuLuLuLu#d\)dRdZidVd^dQdLu34P7Lu4PWfinvinNio2 -@<2 ]yeOe[@e[He[DEe[Le[B%e[Je[Fee[Ne[Ae[Ie[EUe[Me[C5e[Ke[Gue[OnmCw;o0|=:hm8ݿeXqMdTqd\q-dRqdZqmdVqd^qdQqdYq]dUqd]q=dSqd[q}dWqd_qd;Pqd;XqCd;Tqd;\q:~_~XtG4Mw5Mw5Mw5Mw5Mw5Mw5Mw5Mw5Mw5Mw5Mw5Mw5Mw5MwuMwm,糇/-2ZZZZZZZZZZZZZZZZZپM::-:ݭ:m:::ݝ:]::=:ݽ:}:::uuuuGuGuǜuǝu:[tsptrvqusw^p^t^r^v^q^u^s^wptrvqusw>p>t>r>v>q>u>s>wptrvqusw~pMo/C4Pg7tmCόߝe!Gi~tǐi~Lǒi~lǑi~\Ǔi~|'i~B'i~b'i~R'i~ 2} 2}(2}$2},2}"2}*2}&2}.2}!2})2}%2}-2}#2}+2}'2}/w{~_XSȴL?LSɴL?LȴL?LɴL?L3ȴL?L3ɴLgi~gi2=&521;\qO?߆~z~.X# 4RL#4RL#4RL#K4RL#K4RL#4RL#4RL#+4RL#+4RL#4RL#4RL#k4RL#k4RL#4RL#4RL#4RL#i~#F)HdL#4RL#4RL#4RL#[4RL#[4RL#4RL#4RL#;4RL#;4RL#4RL#4RL#{4RL#{4RL#4RL#4RL#4RL#4RL#4RL#4RL#G4RL#G4RL#4RL#4RL''ʝm$g~;(nD#E5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q}ۜ۝msnXCPPPPPPPPgkAgk!gkagkgkQgk1gkqgkB''颧gm[:?7|wk?:/=Пڪuk×w7w7ښZ8[:[9[;[8[:[9[;[_8[_:[_9[_;[8[:[9[;[?8[?:[?9[?;[8[:[9[;[؈ezl2=6bL1L[F#c#ƕ؈ezl2=6bB1LXFL"c#&؈LdzlD(c#"؈DF2=6"L(dzlD)c#*QDž=KrO?m'۶mض7mvm;vr?8;w>WuǂYd`V{,M cA s=D2XcA"s=d2XcA!s-{,(e-s{,dǂF 2XГǂA{,] 搹ǂ9e`.{,[ 摹ɂya3p n/n Een`1+X\ %en`)+XZ een`9+X^ Ven`%+XY VUen`5+X] ֐5en`-+X[ ֑uen`=+X_ 6<`*X 6Men`3*\ -en`+*Z men`;*^ ven`'*Y v]en`7*] Z]^0|k{/Xߨ;,_ łen ,8x?[-8d?-8t?.8l?{.8|?.8b?;/8R en/8V en/8Q Nen/8U Nen`!szw؋=-ss2\p=oƞ .0c炋sf3\p{.̌=\nƞ 0cW炫sf3\p{.Ό=\oƞ n0c7炛sf3\p{.͌=nƞ 0cw炻sf3\p{.ό=oƞ 0c炇5crflK3\[.ڌ-|cƖ 5cߙrflG3\[.ٌ-bƖ ~5crfl]47{y#{l?p4+] ǐ1ep,+[ Ǒqep<+_ ' ep"+X 'Iep2+\ )ep*+Z iep:,^ gep&,Y. gYep6,&s]2wYea,s]2wYea.s]d¶]vdZ. ,eaO. epv,C. |se3n2,W 瓹enp,\P …enp,\T enp ,\R ¥enp,\V enp,\Q W•enp,\U Wenp ,\S גµenp,\W דenp,P 7enp,T 7enp ,R ­enp,V enp,Q wenp,U wenp, )s{`27X +sa2Xx9 4gbo[2Vx̽.soG[2Vx̽-so[2Vx̽/so'[2VsazCl=n 3Cf,3Px{(<nj=k 3c盱 Cf"3Px{(Č=^j /3c+Cf*3Px{(ƌ=^k 3cכCf&3Px{(Ō=j o3c&Ì=i 2cw{Cf>3Px{(|=>h B?C/O'|Ԍ>f 7cO}'>Sfli3O'|֌9zy—2cD}b]&z;fK3vG#ڌ}c5cwDߙ= f|F?yϰ71^W3i3w3i0O3i2o3i1_3E< s_ģ2E<})s_c2E<}+s_2E<}O(s_2E<}O*s_ē2E<}O)s_S2E<}O+s_2E<}(s_32E<}*s_ij0"d8/H澈c"Nd8/L澈s".d%s_ĥ}e#s_ĕ}2EqW=*{'9dxN{"K枈疹'ydx^{"O枈痹)ߺ/mzc.n;ƈ1%dnxI#^Jƈ1ednxY#^Nƈ1dnxE#^IƈW1UdnxU#^MƈW15dnxM#^Kƈז1udnx]#^Oƈח1 dnxC#Hƈ71MdnxS#Lƈ71-dnxK#Jƈ1mdnx[#Nƈ1dnxG#Iƈw3]/owbg3=ex/;#[Έ3}ex?;#_Έ5AGc6l 7~}0Gq̸f3{|=>Όo}O0'q̸f3{|=>͌n}q3̸f,3{|=>njk}3q ̸f"3{|=Č_j}/3Ǘq+̸f#2Wqk̸f:3{|=h}o27q[̸f63{|=Ìؘp:o9Ћg7vq͸Cfa3ww<~Ԍј7nnu:~Ҍ[?eƭ6VϘqg͸sfy3nu:~ь[dƭ_6VǯqW͸kfx:~݌[aƭ4Voq͸;f]3nu:~ߌ[`ƭ?4Vq͸'fS3nu:܌[aƭ4V_q͸7f[3nu:ތ[`ƭ4V?qvo_vo zߨߨqw:MNFy1ddL:K-m& &n{27Ʒi2w7h{qIddR7;LN&y)ddJ7;JNyiddZ7;NNyddF7;INfyYddV7;MNɼI f'̛D2ov˼I"f'̛d2ov˼I!f'-7;)e-f'7;d줖yFN2ovғyA7;]Ny9ed.7;[Nyyed>9wjV~V>?`/q{,"'ʼb2q{,!L4>mNyeed99Y^mNVyed%9YYmNVyUed59Y]mN֐y5ed-9Y[mN֑yued=9Y_mN6y ed#9XmN6yMed39\mNy-ed+9ZmNymed;9^mNvyed'9YmNvy]ed79]mNyɼɞ2os-1ygyy799hMN2&'qC̸ɡf03nrrw99|h3wr7<9֌;gnr;ۋ{>w{NN5n'q͸p3vrw;9ӌeN6n'qs͸yf|3vrw;Ќ\dN.6n'qK͸efr3%Wq+͸Ufj3vrw;֌\gN7n'7q͸Mff3vrw;ՌfNn7n'wq;͸]fn3vrw;׌gN78N-{ͻ<&'qG̸ɣf13rfjc`l7:yΌ3F'q/̸ɗf+3nt7:ƌ|kƍN3F'ߛq̸ɏf'3nt7:ŌjƍN~3F'q?̸ɟf/3nt7:nj;kƽNh/,:KNǖyqdt\:ONǗy dtB:HN'yIdtR:LN'y)dtJwft_3h߫fVTѡ74=Ȍl M1ㆦqC̸f3nhz74=ʌm M1ㆦǚqC̸f3nhzw4=Ɍ{lwkʛ7sŽLO7^͸fL3ez2=ی{cƽL5^q/ǒ^`ƽL/4^C/_z/Ԍ^fK/7Wq+͸Ufܿj3_z/֌^gK7Ӹsmg]WC/nUz*Ō[jƭJo3^ݘa1w,oЋ>dJ6~qG͸_cfܯq3W+}Ҍ>eJ6~Ϙqg͸_sfܯy3W+}ьdJ_6~qW͸_kfܯt+}݌aJ4~oqҷ͸_;fܯ]3W+}ߌ~`J?4~qҏ͸_'fܯS3W+܌~aJ4~_qү͸_7fܯ[3W{3fޯͼ_?y~60śuQy0Fi73oԿfܨl@Fyeިl 7*Sƒyeިl9ŷ`ƛ4^ܢl|(@-&ydޢlb(D-&ydޢlr(B-ʦS|eSyyx.w'Vɦyweޝlw'Qfyweޝlw'UfS|f.佹^ܗ,y_X}%Keޘ,yk\NfEvޏzPoV_tީ]z2R6(.e˼K2R6̻%.es˼K<2R6̻'.e˼K2R̻-$.e ˼K"2R̻-&.e˼K2R̻-%.eK˼K22R̻-'.e˼K 2R̻$.e+˼K*2R̻&.e˼K2R̻%.ek˼K:2R̻'.e˼K2R̻m$.e˼K&2R̻m&6e)#-Q؋m-&eȼIٶ2oR̛moMv0&e;q̸Ifܤl3nR7)͌nM0;27i=6eq}͸G~fܣl3Qv(;Ќ{d=6eq2 ޙ7&;܌aƍɎ4dGqc͸11fܘX3nLvߍfM[2d#;ՌےfmN7d05psxg^|Kf瘹/!p_xS^ܓb3Iv$Ԍ{]f=.7dWqO+͸'Ufܓj3Iv$֌{]g=ɮ7d7qO͸'Mfܓf3Iv$Ռ{f=n7dwqO;͸']fܓn3Iv$׌{g=7dqO͸'Cfܓa3I${Ԍ{=f=7dOqO'͸'Sfܓi3I${֌{=g=ɞ7d/qO͸'Kfܓe3I7%{Ռ5[›2doqO͸';fޓwͼ'yO7|`={c3'fޓOͼ)!˛7K3oWfތͼߘy35f|g̛ߢ7>l}73fއ?̼y#2[o?"N-`ۋcl~>c'_ yq G Dro|b3މK]'y)dޅ|Jw!J]ȧyidޅ|Zw!N]ȧydޅ|Fw!I]gyYdޅ|Vw!M]ȇɼ y .̻G2B˼ y".̻g2B˼ y!.-w!/eޅ-.w!dޅyF]Ȼ2BޓyAw!]]y9eޅ|.w![]yyeޅ|>w!_]yeޅ|!w!_X]yEeވ|1"_\/ax^܆|i!_Fmȗydކ|y!_AmWydކ|e!_Es_6|e/.2)Z2-:2+g̹-_E F#[h{̶l{̶{bf75n-0?֧/]e#3ϛV-^4cl'{Om^U3[-af _![x dž[Vcf5㛯~cةSe>0K٥fv3].}nf0K_٥fv3].}of~0K?٥fv3].nf0K٥OeSk@fZSkt}j!O1e5>Ɩ٧82WfZSk|}jM O e5>&٧$2ԚTfZSkr}jM!O)e5>٧42՚VfZlUkzjq˱M ?d65\۱-Fvmy^|Q/ GJ+ |b3¦g/Z;-^ՖَVGf;Zvjh52lG'Ah.9d5vَ2њGf;ZlGk>h/dvَ2ZDf;ZlGk1h-.%d̆2#Hk3:Z֌3#Hk3:ZьV2#Hk3:ZՌV3#Hk 3:Zӌ2#Hk3:Z׌3#Hk3:Ќ62#Hk3:Ԍ63㛰y}kawveESZۛ}7"¦%C/ZŌv5'ka%lHe/W [}ŎЋV0hE 3Z:،V1ChE03Z:܌V0#hE(3Z:ڌV1chE83Z:ތVN0hE$3Z:ٌVN1ShE43Z:݌Vي3lřf,3[q8Vkf+3ي lŅf"3[qV\jf+.3ي+lŕf*3[qV\kf+3כيlōf&3[qnjw]6;k@{ݹnjoֽf>6h{ٝkq<01 [nicm{siך{z\^ka׸Ѹءew^5;ٝfvu3yefw6;ٝw{fv}3|dfw>6;ٝOgfvs3|efw6;ߘٝowfv{3dfw~6;ٝ_ofvw3efw6;ٝN9 ;h2S.;2S);X2S-;82S+;x2S/;2SN(AD2{TN,K$2TN*Md2TN.Or ߟfn:}zHo-oP~wGO+J쫒]z^&Xp6Ѩm*c**Ӂӱ2OBnᛳlrیcF؋̞̞]=+{2{VY9̞sY9̞sY9̞Y9̞Y9̞ Y̞ Y̞Y̞Y̞KY̞KY̞Y̞Y̞+Y̞+Y̞Y̞Y̞kѳrM3zVeFʵY=+5gzf\ߌѳrC3zVndFʍY=+75gff܌[ѳrK3zVneFʭY=+5ivf|ft?lr6YMV{ܭbٹ~Jlߒ[WEʽ[+5s~ftߌΕѹ@3:WdFʃ\yClaf<܌۫bAoEc^y+7{ ft<ь'ѽd3WbFS^y+O7{p3WaF3^y+6{9ft<׌ѽ|3W^`F ^y+/6{%ftԌѽr3W^aF+^y+6{5ft֌יѽz3W`fn4{7ٽ-fvV3wݻaf4{wٽ=fv^3wݻ=`f4{ٽ#fvQ3ߤ%d/620lr{{=gf7u/ٺlKfe3[{ֽffFٺlfM3{{c7g;-d}hf>2wٻOݧf33{}if5\{ٮol׷f;3vhf~2]?ٮ_lׯf73vif2]ٮl׿f= ]d=vǐٮ2KfclW{j+]d=v'ٮ2՞HflW{jO*]d=vٮ2՞JfSlW{7i{Z373ߪ7){Ѣ2[ԞMfdlQ;٢v$EXfډS-jg2[e]lQ%ERfmcc/v]{Mb>idv-Ǿ)&|g/ОSfsl@{n h#ye6=ـ2^Pf l@{a h/"Ee67%h@{I3^ʌ6eh@{Y3^Ό7h@{E3^ɌW6Uh@{U3^͌W75h@{M3^ˌ6uh@{]3^ό7 @{C3pm촑m/61-_l?4hokF#ۙшf4hhF#;шf4hjF#ڻшf4H3=D{/3{hcƷ`{_~;mƞkcõfۇnn}fGnm}fǙ> fO4w}]bT3ק>p3g>Yf6w}s]g|3Ef/6w}K]_fr3WF7aon/ךFohWێo;{[fo3~;io.3w[f3~?ho!3{f6ుቁvI3Oz#Vn/mx6`f^4 /نl+fU3maf^7 oن7l[fm3mx6gf7 نlGfc3m6|ff>7 _ن/lWfk3m6|gf7۰ͽN\>e؅.>ff~737-?o3}׌>td3>tFه2Sf:cCgl}#qe3>tƗه2ЙPf:Cgb}L"Ie3>t&و2[љRn3ZљVf+:lEgz e3Vtfي,2[љUf+:lEgبwd'޲]2ЉdvB'مN* Lf:.t ]dvSB- .t*]2idvӕمNOf:2Й]f:sBgN];vd~E:z6g΂2YHn{zYLf:уf=,eF:Kу2f=,gF:˛у f=dF:+у*f=fF:уf=eF:kу:fMgƷfg}3(;6 Bg#3،.t61 MBg33܌.t0 -/ ݺm/Z֌t3hAg3Zьtv2hAg3ZՌtv3ogw3ZÌtgF :{т^f-cF :т~f-`حl{0[so6k۔шΑf4smF':ǘ-9|\`g#lЋntN6ٍSifvt31naf74gٍ9fv\3q8n\`f7.4ٍ%fvR3qݸn\af74W-۹|Mٓe?77ُMff3q߻[ͷ_˞afS4)wٔl=f6^3rM̦<`fS4)ٔl 7)[~e/{񘙽x^3ٍ/Ɨfv+3n|kf73ߛٍƏfv'3vjfC~3[Ýʆ`/fmf31эj@f;d]f?1dSf?d[f?qdWf?d_f? dPf?dX۵ʎ4I٤l'f6S3YeN|if2?_ٟoϷf;3hf~2Q?WmZϸF^o3}׌>2T&O2T!O2T%O2T#O2T'O2TO O2TO$Q2;UO"U2[UO&U2[UO!U2[UO%Urz3wV=h/C^ˑ%)ٗhK=먗mg٘zSr:2;NFPP]Pݒ١١-CuGfJfZfFf=ev]f9dvSfF#z?^Of{e^@f{e^Hf{e^Df{Ee^Lf{e^Bf{%e^JmX/m^f6 5^n?+|+WZ5nW5Sjft^݌NkѩzM3:UeFT5Szft^ߌNѩzC3:UodFTItT^4̌&՛Ѥz 3ToiFhR]1۰bآzF{j|5 2'NfٌԻٖ]L~=/6X=C/SmFw}Nݩ3;fc0;ft>Ȍѝ3SjFwN}ݩ0;>|TE/:TcFchQ}-7E f>ь'Ѣd3ZTbFShQ}-O7Ep3ZTaF3Q}M6K9ft>׌.Ѧ|3u/4{|qcF6^23{u^]if2WW٫kյf:3{u^hfn2W7Xbc6Naf4Sw٩=f| vgW{ٙ̃f!3yČoQcv٥}e6CϘ١gsfvy3;zdf^6C١Wkfvh-zaf4Io٤l;f6]3Mz&}`f>4I٤l'f6S3M&}af4I_٤l7f6[3M&`f~4O?Xlrr[Naf4S٩?fv_3: T3N5T3N5cT3N5clU3\<ިj[2L([D2L,[$2L*]drofr3^M`5n wƎ=d/ [͌2$]2"mf5s e׳WM WM(WM$WM,WM"WM*WM&WM.WM!WMKfRf^5j*jjjj2{d٫fvj٫fNj٫fnj٫f^j٫f~j٫fAj٫faj٫fQj٫fqj٫fIj٬fijٱfYjMcjV٭f%jV6[*ftYՌn5ѭfu3լaF5Vj6[:fY׌~5Ѱf}3l'լj62WfČ^5٬Fm67c6eFʼuk5lEǚXkv4cNkٻKFd.jEhUjgF=hUj6U>f׌V5Ѫf3Z`FdFhUsj5Uaf9܌V5GѪH3ZeFhUsj5Uqf9ތV5'ѪD3Z՜dFhUsjN5Uif9݌V5hUsj4UYf9یV5ѫ\3Y؆[5SͅftN]lf.1S٩fv 3;uN]mf1Sך٩Vm7٬/{u^bfn5W٬vm0srq߱ENcg9){ˆ4!ِl'f6S3 ̆|afG4Ȧ\d/ ̆|ofC~0!?ِlf63 ̆nfC0!ّlf3{=Iw4=.'1d;̦tǒ|Sv6؝Gur hFwN*d6;ftٌ2ѝJf3SlFwN+d6;ftgٌ2ѝIf33lFw*d6;Lf3ftCF2эe6lF7ٌn&\f3ft[2-e6ٌۖnGf3ftk62lF'A.7Nr+l ݹd;6tن2НOflCwm.( ݅d6tن2]Lfцfm.eFKц2wQ-zтrf4߁+ߕF zbjfaZfkczfn`FfnbffnaVf[ncvfۛ`Nf;b`nw4[>C/~}w5όzw3~w4=Ȍz`3~Cw5=̌zp3~#io(3G[?ƌoflבo3'{?Ɍo.6ktoz3]i,3g>f3w} ]_h"3f/3w}+]_i*3Wf3w}]h&37fo3w};]i.3w}ڽnj:7?7m?doa3ۏ~cf7'm?eoi3Ϙ~sf7ߦܾh/ۯ~Ռk; x⻴˽ʍԑ]8^vC3;|bf>5فfvK3;|cf5ߙفfvG3;bf~5فfvO3;cf5&ev7ƔفX2; zܫ'_o7~oBD2e{&M&ߛ\o7~oJT2e{M'ߛ^77noF3.[f*.k{ܸoqϾC+z^22+.g{-3zܥ [hGَ^#vz2َ2ћCf;zslGo.-yd7vَ2[@f;z lGo!-,Edvَ2[Bf;zKlGo)-mF;z˘ю޲f-oF;z+юފflƷnoz† Gou3[Ì~4Gom3[nj~5Go}3~64Goc3Č~65Gos3Œ4㛹yIo[3zΌ7)nhvekF᛹;vآl MoO3zˌ6-*{؝=lM6zќAflFszќޡf4wnFszGќޑf4wmFszǘќޱf4woFsz'ќމf4wlFszќީf4wnFszhN 3;efs69ٜslyf6|3s͹\dƷtb3a/s͹\afs49Wٜl5f6Z3s͹`fsn497ٜl-f6V3s͹af{4?wٟ=f^3s ߌ)[N=d&ݽ.=j7r1zQO٨l3f|/5?/ٮe^4[;b}z>ffF٧fM3}z>cf5O٧fC3}>}bf>5O٧fK3}>}cf5Oߙ٧fG3ٌo/fnOr{٧fO3}>cf5O248> .Oc248> -O248> /O248> N,O248w v $58ըZxp3#h 258v $_3,258~ &adl0{& QF&d^m sr u{ѳ̞ V2{6X`#g]=̞ .gs2{68̞ -?J "DHK&O;u=O{کu|oggg9{kӕϬ3khᙵk3Zxf-<YugVh4Zxf-<YF Ϭg֩3h2ZxfYF Ӭ%J>(|z3F Ϭk-aha Xa8aJw0CJ >0#J >0cJ >0J >0SJ >03J >0sJ >p J pKJ +J kJ 4weJ˾(\>V=}RZm}QZ]}SZ}}?PZC}?RZc}?QZS}?SZs}PZK}RZk}QZ[}SZ{}PZJ OJ /Js?J=qWZw¸(-¸) 8;h01Zg-!qv8;l0Ύ-F 8{ha7Zg'I-¸+ikvhUZ9q8{ha=f0-ǍF Iqvha=e0Ξ6Zg-F Yq8{ha]2Zg/-KF eq9{hnm(z:{hamή--umvٮ:3ZXgW5u:{hag7ZXg-F :i>4ZXg-'F Su:en-ύ eo]0ξ8F k* k) k+ ( * ) + ( * ) + ( * ) + [( [*׾;a'|/UٷU};!mDPg>.J>J>nJ>J>J>J>^J>J>>J>J>~J>J>2aa@a a`aaPa0a}Ұ~Ұ~~G) G+ͽ~ҏIa'\4\4 d?Qih?Iih?Yih?Eih?Uih?Mih?]ih?Cih?Sih?Kih_4\4\4\4\4\Sih?_ih@ihPihHihXihDihTihLih\i+foN ~(-,|)-,|7(-,|7)-,|·(-,|·)-,|w(-,|w)-,|(=~ҲG^a&^pJseV~(`aQZQSZqPZIRZiQZYSZy_PZE_RZe_QZU_SZuPZ?J ?[J ?;J ?{J CJs׶'p'J GpgJ GpJ GpWJ Gp7J GpwJ GpJ GWiIi蟕Ei_Miߕ^pJ Gp_JQ'` mswd?F=gp -tn:aNh5ZČn:F 7M'apI-tRF 7ANhᦓ1Zdn:CF ;amNNi W'tƌ~:ymθҲ ~?p)-\u:F WNh3kpՙ3Z-\uJF W΢Ugh᪳lpY1Z-\u֌:F W Nh᪳ip2Zl-\u*F Whc-\ukp:UNh᪳cp5Zmsv>|yܟ'u:GF ccΉXhasf0i-uF csNhasXjF c-ua0ֹXZF ck-uc0ֹXzF c-un`0ֹ0ֹ0ֹ0ֹ^`p:7W:P:T:R:V:Q:* S* S) S+ S;( S;* S;) S;+ S( S* S) W+}۹~X᪰:V{sԋOx_ix\4IiFW-J-nJ-J-J-J-^J-J->J-J-~J-J-2@ `P0{p}p}p}p}4hX8J-J- J-J-IJ-J-)J.J0iJsu4;Lv g) +__s_s__*-z¯(-z¯)-z¯(-z¯)-z¯W(-z¯W)- {g]3a­puJ ^p J ިpMJ ެp-J ުpmJ ޮpJ ީp]J ޭ4w\=J^*f]=QSZ~QW*-¨*-oQRZaQQZQQSZqQPZIQRZiQQZYQSZyQ_PZEQ_RZeQ_QZUQ_SZuQPZ?J 0[J 0;J p{Jsu¬+S#Q?VZQ?UZ3Q?WZ QTZ+QVZQUZ;QWZQ0J 0J]/JN+zz RZQTZ/a0ZFy=F ^Q^(/d07Z免FyS^h{';0 $/a0K-LRF AI^ha1Ze&yCF aI^ha7b05Z-LF qIބ$ohaW0ZM-L&y3F $oha7g0ɛ7Z䕌&y F EIޒ$ohab0[5Z-L֍.yFܱҲ?6ZU6y&6Z9F yF ]؞)a?y-aVyJ"4,.QyWSyWWyPyTyRyVyQw ,s.>w}wwCw#wcwwSw3wsw wKw+wkwwƻƻƻƻƻƻƻƻƻƻƻƻƻƻƻƻƻƻƻ0ǻLif {7{Ұ{Ұ{40awҰ{Ұ{Ұ{Ұ{Ұ{Ұ{Ұ{Ұ{ҰaxaaDa$ad{aŧpiJ WpJ WpYJ WPZl+QZ\+SZJsqLz C^0EJ C^0%J C^0eJ C^0J C^0UJ C^05J C^0uJ C^0 J Cި0MJ Cެ0-J Cު0mJ Cޮ0J Cީ0]J Cޭ0=J Cޫ0俔Oia\0J G>4weᅰ]|DiG|LiǕ|Bi'|Jiȧ|Fig|Ni|Ai|Iiȗ|EiW|MiוW"yz 7p[J 7p;J 7p{J 7pJ 7~4wcˍp'J '~pgJ '~pJ '~pWJ '~p7J '~pwJ '~pB]0)=GUZzoJK]iTZz_JՀՠ竽FKWq׭WXQ1FKWFKWFKWFKWSFKWޯޯfޯfޯ-_6Zz3Zz:b~uhռqF{oKK=i׫3FKWFKWg^-^7ZzZ2.[=XzIoWޮ.-]]1Zzjvuh eJ_J/E={Պ{Uh齪m^1Zz-WUjMiz4WUޫ)MUJ{պ_4wjBI]|o#[Diz4V=S~ߪm[4VDiz5ՕߪP~^Siz-굕ߪQ~^WiUvg7鱋Oz 7RXizM7S{fYKz~Riz+ꭕQ~^4TS]YzGEzBNJꝕ^ wUZznJK/]i{(-pO½^^8VO_dJKdAJKd!JKdaJK/WZp%PZH%RZh%QZX7VُzJd;N~~܇Sw識7(-J{y^ެ(-J{y^ޮw(͝N<'VZ{w^Nާ+-J|@iy'TZ+-CJ;]QS|ߨ'?x)O+-^FiJןSZ__PQO+J_UZו?JTZ])-_i@~?VZ|Os_(-^RiȎe>ViwJϿWZ|*->QiOJVZ|_w竔]|O{s37N;?o^ -"FKR{-f^0Zjōk Zh2Zj -FK__gmHi 5J]TQjJSSmLij啦ڸTPjJSS45զڴߛUZ9WZw-(-עw-)-ײw(͝4w~]9mJ(-mU?kJO[JTZCo9RZcN>ZK)Ku5w]]i}PݾvM 7\+-J︡;n+^{Λ);^ҷ{+ZiQZ~Jュ]kugQiYwRZ~֝uoϹw{(-?Jϸs4w}s艹s.SZ~@g=HiVD!|zx3.WZ~Õ3SG+-cJsO=w<^ig4~?A=ykOw>QQ{ j2G/Oas\_ZY`~YT ~AN`,`=fM`Y/s?`0.w6ρm:p,(0'cp"@=W~ 99 9^* ~!}xw~: ^s ܙ܃mW3;x=:^` Gv{]=-~Y氛ba cثNNyAa]y'AsdAKd.y?A`9y/AEAAAwAGA A;H  >6H w  Kw[S0A< ~?P=< ;v:]u9Ȯd?{H8Ak4d k2>d qCO?=L}Co=L=܃=xþу=ڃ=ڃ=ڃ=ڃ=ڃ=ڃ=ڃ=ڃ=ڃ=ڃ=ڃ=ڃ=ڃ=ڃ=ڃ=ڃ=ڃ=ڃ=YK=xý{z;Zw2C{\G/'0nŠޜ]/ˆ^K{B/\ 䯗…^~ z^v^z~ev2{oa2{{̮^fP/3P Ͻv/K/ýз/弒Z9{rr]rW%sI{w~?-{z\/^^2K/ým/=KzO}0>xڇ?}ǮGO3c> `;X}>_}>`_cK3C~ϳCyL[80|a߫jk?}dye{7}r>q_#}t>ѷ}ed#}dLdLdLd<`;Kȁ!Z߇C̣3(b1gB!;e0%RУ!rCφewb ѿ!2b >B4DWB"!( 1wBs&s; wCx5z5!< !fQ1Bzyy1B !U6?oCd=DCp!KC37Cp37Cp3 ]>~aA?|~~~~~~< ̄|~z6y?l 6Æ~O~x?>m?g?l W~Y?É~8B?>S?>S?>S?>S?>_ua SƧ0>)Oa| SƧ0>)Oa| SfjY)a| È0 _f/ga| 3_̗0 3_̗0%| 3_̗0|Ã0% 1L/L_*&03'Vucy<3L&d2~m!a|s\d0\0+arr`r&_aWf ;azYa_""KRaVEx9aGx9aGx9aG?#d5r=?xaG?C"0$?"d7BV#!=)("p!"p!"p!"p!"p!#p BG;g"xE._<EiFiY0"5gX"̲?8l~F`oFaoDaoFaoFqQ<(.ZG̿(/Jޣ9Z2 (GtNGtGauwQz Jx(^G:Qux(^G:Qux(^G:Qux(^GjxQfWlF/4Q4Q|wxeo7b 1{C!^b÷{C!W17b 1{Cb2co7`i v`f9co7b 1{C fƞó,ƾ1Xc~/܊|,=ûi bx+_11<12#1||1}>>>>>>>>>>>>>>:pvy4̤f3i <~6=li,Y dq,8@74wx7@; x6@O^8ǣ8o)N8S)N8S)NO8=b^QƙCqz2e978g3hhӣqz4N&7qfR(N/WƙU+qrgvřq8s,qg?8~ƙMqfR|5ά8>N>̝883?̏383d2N&d2N&d2I  r r r r r r r r rLMOyx'$!I|HAy$I2$cIr$SI2$SIORԟ$'?IIOR_簷$oqK$KQ%ZG$K$3;ɜN2.IR,o)YK_ 8=S.)v{h 5U4E.SxbGJh*{j?6ŻH1SP)v;T*bJ1SPeSR)K}6>bMnR&cS)8bMMYM_S4KS)X))>lJh5Ů⮔I)z?ŻJ+ÜOR̪H H1Ş.;J^R̥!{H H1S8;I_!)S{A†Af j4{= y?AA|0b ; wA + rdOɃx. „Ax0u ,dF 2Qܛ7 rovAf ~4]`?ȌAķA9>\dA>H psi 1tR?ƃ4 M,])MiOSԟ4?MiOSԟ4?MiOSL4{P=(iz?i?ii8i8i8iHÁ49KKu if1|c3 ̰sgع33C/fY/Kedxŷ,¶,߲,39LYϲ̙,ewaNg=Y2.YfvefgY5=aF9#0gF6Bo#6Bo#6Bo#6Bo#6Bo#o#6Bo#6Bo#6Bo#6Bo#6BQ|%_j~%Kg~FQ23Jofތ›Qx3 oF(7fR(R(R(R(R(R(R(R(R(R(R(R(R(R(R(R(R(R(R(R(R(QQ1zi^#cx1F&#cdbL121F&#cdbL1sh94c1ƘCc̡1cDcDcGr?cAcAcAcAcAcAcAcc0g 13s`9c0g 1cG1zdcV1ǘcGaN$'y2LJ<ȓ)Oy|8>Ïq1?8y'+de8Y'+deq88qivǧqr3Nngggggggggofofofofo8\puq:/df/b/b/b/&b/&b/&b/&b/&b/&b/&b/&bo&aLPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPOPO=gd>OrOd.OpċIg;$$x;$=4,dO2'Óc< $Izg2ܝddddddddddddddddddddNL’II|dddddddd'$2?j;$wIPܡ&a&PXR]`g)0a'),pHH pG p@H|=XR#fMYS`5fMYS`5>RxMS`?)U ErT GrT GrT GrT GrT`R,R d@ d@ p ]\`N`Ng v;`}R`_)`O`\M)r5Eyb"CSdh M)24wSdh M)24Em Ϧ"CSdh M)24E£)|"CSdh M)24E"CSdh M)hy4s`^L)꟢)꟢)꟢)꟢)꟢)ꟺmLi3 v80v4|~=Mn=gdelLNNNNNNNNNNsw?B`/b/b/b/b/b/b/b,̓y00000000000000000000000O J_CJ0OKpCJP_(((((ҹ`F;p Ɩ`G oJxS›ޔ7%QŸ?%)----1oJ0ļ)ļ)1oJ̛ļ)1oJ̛ļ)ļ)1oJ̛ľVb_+Z}m}mYY`,0kfYY( tYY`,0kffYYffYY`,0k5 ̚ffY@ Կ@ Կ@ Կ@ Կ@ Կ@ Կ@ Կ@ Կ@ Կ@ Կ@ Կ@ Կ@ Կ@ Կ@ Կ@ Կ@ԿH̘E2}f,'"}H,Ed>YOEd>YOEd\,'da,,EH"9X$`,Ed>YOEdaaaaaawE"}///////K/Kb\,%rD.X"Kb\,%rD.X"Kb\,%rD.X"Kb\,%rD.X"Kb\,~,~,~,~,~,~,X"KԿDKԿDKKc{>,,,,,,%!!dd=d,Ðe ?ر ;2X&c?2,2,2,2e3g,sY>̮}f2we.Wy牜ryleeeeeeee2L.//ǖǖd}l/b/b/b/VaVaVaVaVaV9v+V׭0WWعVطVZ}nWWWWWWWWWWWWWWWrB.V X!+ yX/VbX/VJ_*}J_*}J_*}J_*ŠUrJV*9X%`X7V*J*J*J*J*J*J*JkkkkkFYX# kkda,5FYX# kda,5v\c_#kxF>X#kc=| _e _e _e _e _e _;w5555r?gv50YisY.NԿNԿNԿNԿNԿAԿAԿAԿAԿAԿAԿAԿAl0W79 < < < < < < < < < < < < <؀A6C7C7%K~)/eYeYeYeY_K~)/eL2R_P_K~)/eL2RWG(ezeQf(#e(G?QƏ2~e(G?xQƋ2^e(E(Î2}QeQfL6xR!eQ&eQ&eloo{mwmwm‘M|děMM S6h6h6h6h6h6h6h6h6h6h6h6h~l&e|dl2_6/̗M&eIN6a&e|dl2_7M&ؤ_6M<٤_6c?6c?6c~٢_-e~٢_-e -e~-e~ق[b ^l-ze^٢W-ze^٢W-ze^٢W-zel+[[s ` ` ` ` ` ` ` ` ` `cllclclcll?Clklkl/6Mlm2Mlo3kmf6;6;6sv9 ;m6sv9͌fn3c̖m63v͌ݦ_x,fl3K%̒mf6dY,fl3cmf63vMl'x 76ئOm 7 fffI~/BT 3rRaV?zBT RW*J^+zBT RW*J^+zBT RW*J^+zBTITITITITITITITITITBN*BN*Jo*RaG?*aEF,2bXd"#Xx`၅Xx`၅Xx`၅Xx`၅Xx`၅Xx`၅Xx`၅Xx`၅Xx`၅Xx`၅Xx`၅Xx`  Zxa3=c Xdb,f}fl2a}̆6b+6b+6b+6b+6b+6bㅍ6^xaㅍ6^xaㅍ6^xaㅍ6^Ob3_l|/6~-_7YcC6'c3slf!_6~e㗍W6'lb&/yqȋC^{NzxvtrqNonm<~5uGoƣ.Q=x>`^^\Z~,~t'tt3t t~Pt?]w;$III{I;II;II;I{I`j{`j;`j`j{`j;`j`j;`j2ަ.|9~/~tt;\tÇ~y~ y~ y~ y~ˏC$/*? ~o~t??SIEEsEsEo|w}.|~:Y9k$'3 '3&3&3ϼƣgRQsxLe<~1u?c ]<~϶g1Kt?~+=LTzL3E*=O~&t?oK7χěg3g/RćA3JgQwl:~^w?F7g},kfרV|)~~w?ÉD5~w?+Dǃt?!#Ϝ/r\'o aRË^5E /jxQË^5E /jxQË^5E /jxQËed=u_vEvEvF9;;g;UNSv;v՝s\޺sm퐓ś]%'KNv.9%'d쒓]rKNv.9%'d쒓]|%'ԿKԿKԿKԿKԿKԿKԿKԿKԿKԿKԿKԿKԿKԿKԿKԿKԿKԿKԿKԿKԿKԿG{ԿG{ԿG{ԿG{ԿG{a<쑇=G\p#{b\ry# {ܘss,ݻNq8<3=d9̖=f 9/弒Ì{#筜wr˹Þ1Χ8ﱳﱏ1cvu{w=2{̗=1/>}v}}zd_1x?2n>}wxϬ~n~~Os~n9ns~|~nn>>>swlln}l]l=l=l=l>w}|u}|Ǐ}Ǐ}Ǐ}Ǐ8888~{8 dlq@68 dlq@68 dlsp;O>9OxPg稳sahQg稳sCQg稳s9uv:F7`uv:VguH]Vg`uv:;XU^[^[gwչֹA밢uPw_N6dN6dN6dN6dN6dN6dN6dN6d.Vou@4ݷA~p fP,5Ax S Pk0pwpwpsoooooooooAdAdAdAdAdAxjjjjjjjpkpksՅjqMp9ܤ&7IMoRߤ&7IMoRߤ&7IMoRd4&}դU4J4J4J4J4J4R4N4N4N4N4i&^4Q62$SM2$SMiMo(+p7xs7xs7xs7xs7xs7xs7xs7xs9ěC9ěC9ěC9ěC9ěCz^;Cz^;Cz^;Cz^;ˇxs7xs7xs7xs7xs7xs7xsH_!!!}u0{ߡxA_OGqD?Gxr3#Xt`,:EG#Xt`|{q>>|}#G܇#2r}#G܇O?a1 9c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?c?w18~Ïcq ?18~Ïcz瘞9~Ïcz|_ucO =rBN =rB#' ''''f |l>a60O'f |l>a60O'f 9!'0rCN` 9!'p,pBN Y8! 'd,pBN Y8a=8888#)^)^)^)^‹S|8<)>ŒS8px 7N)~)~)~)~)~)~)~)~)~)~)8pnSq 7N)8pnSq 7N)8pnSq<>eW;c1wϘgz\=cW;cW;cW;cW;cW;cW;#gpgxpFy8#gFgFgFgFgFgFgFgFgFgFgFgFgFgFgFgFgFgFg9rgxpgxpgxp-'Ct}ҡO:I>'Ct}ҡO:I>'XсCtYCtѡ?:|谇wxavfiYavfiYavfiYavCt=ҡG:H#zzzzp ^\%xq ^\aBr` B4`L$B @QQqz^{kz5 ((9(*DFIM bg3^ĺbXC!~u?ĺbXC!~u?ĺbv"NډX;k'bDv"Nډ>ߐo7-|6"vw;|7ߋ/}X>wD,&\K{"+buWĺ7c3;c3;c3X888888888888888888888888888,838qqqq!a   $D~$G~$G~$G~$G~$G~$G~$G~$G? ߏK34K34K34K34C33C62"/2"/2"/2"/2"/2"/2"?33?3lJoffoffoffoffKfF\dggeg&fg&fgx㑏G>x㐏A>cA{{{{{{L>cA>cA>cA>cA>cA>cEX`PA`PA`PA㓋-kmmm<mQGxQGxt~n)K K K V?N)>pl`T` o *;U` 8Nة;UY]MXMnMMM!M!M!M!M!M!MNM!rM!f|[ȷ|[ȷ|[ȷxmm!m!m!m!NbTQ!FbS(;|[K!8m!m!m!bP_c +Rhw NڞB~)B~)rEn"7~ѿ;En"\۾m_-ESĹE';Eo"w\E~IE~\$E~HQERCH>](ҧ";]ddHVq|"("("("7LH1E:USE:UM?VaTQFE"wL1so1so1so1so1so1c1S1S1S1S1S1SS:US:US:US:UOSKcS1ŘsLK1NK1K1K1J1QE1XcP/R/2R/?YX K K K K K Kx `P"#%2RC`QE %X`QE %X`QE %X`QE %X`QE %X`QE %X`QE %X`QE %X`QE %X`QE %X`QE %X`QRX)XbQ+P*P*P*P*xK)oQʷnR-R-R-R-uۖmKݶnR[-u痺kKݳR})š;JTWJ;J;J;J;J;J;J;J;J;KT/J;K;K;˸;˸;˸;˸;˸;˸;˸ 2,2,2,2,2,2,2,2,2,2,2,àM_NeQ&eQeQeQeQ/{>}_H{̭VV+>([geYƟeYΟYΟ2QΟYΟYΟYΟY.YΟQYΟYΟXE^E^EEy'帔H9G|G|XK9&~rm,;֖XΡZΡZΡZΡzR.Q.Q.Q.Q.Q.Q!Q!Q!Q!Q!Q!Q!Q!Q!Q!Q!TG|TG|TG|TGQ!Q!QrQQQQQQQQA\T7|T`QxTQaO*lm#vŽTؑ ;RiG*H#QQQQvҍVQQQQQQQQ2Q)2Q)2Q)Y7p%&TbRI?L%VI%NSU%VXUbUU%VXUrITSM%6R)+R)+R)+Rl?^%3U2S%3U2S%3U2S%3U2S%3U2S%3U2S%3U2S%3U2S%3U2S%3U2S%3U2S%3U2S%3U2S%3U2S%3U2S%3U2S%3U2S%3U2S%3U2SO>UTSKU8TPCU8TPCU8TPCU8TPCU8TPCT{Tۗj mLݭƣZfmo5&՘TcRI5&՘TcRI5&՘TcRI5&՘TcRI5&՘TcRI5&՘TcRI5&՘TcRI5&՘TcRI5&՘TcRI5&՘TcRI5&՘TcRI5&՘Tw6<[?j=֣j=֣j=6;jlp F5SK{H{=R÷5TKޭޭޭޭwkZnq8jܭ5wk ָ[kܭ5aqSݩ;5vP؝ScwjNݩ;5v_jx,jNݩ;5v؝ScwjtڝZSkwjeڝZSkwjN-vkk9SjdQ+Q+Rk{jmO=ڞZSkojdnZ7Y׺jyֺjdnZ7Y-ԺjdnZ7YMV&uk[kdnZ7YMV&Zy :yc\qlRǵu2R'#u2R'#u2R'#un:٨sֹYO>u[ǹu[ǹuqnqnqn֑XPqnqnqn:;\gpuZgpuv:TLKwuR+uR+uRgslNۜz>9xPosۜzSosۜzS__________?H=\R/+:S'|R'|R'|R'|R'|R'|R'|R'|R#[[ϱ[ϱ[ϱ[ϱ `cA>lL6ؘ>m>mh>m>mhЙiЙiNmNmNmNmNmNm;0i;;;;;;;;;;;;;;Q_u;;;;;Q7FlFlFlFlFlFlFlFlFoFoFoFoFoFoFoFoFoFoFhĠFhFhFhFhFӰ&h&h%M<M<M<M<M<M~6mğM~6=l߳MĝMĝMĝMĝMĝM:ğMğMѤMğMğMğMğMğMğMX4D^4ߏOi¦I6pi¥I6dI6dI6dI6dI6eY6eY6eY6eY6eY6eY6eY6eY6eY6eY6eY6eY6eY6eY6eY6eY6eY6eY6eY6eY6eY6eY6eY6eY6hƠ[[[~8g|G|G|G|G|G|G|G|G|G|G|G|GlFlFlFlFlFlFlF ih"-žI}m-:Ң#-:Ң#-:Ң#-:Ң#a:Ҫ#xڑVlť՞bӪ3vG[mK+6նږVj[ZmKmi-նږVj[ZmKmi-նږVj[ZmKҶMmiVjOZmkmmնVj[[mk+.նViնVնVj[[mkmmmͶ6LڰhàۼۼۼۼۼۼۼۼۼۼdMOHi#mv͎mmfKli-mm͖6[fKli-mmfKli6[fKli-mm͖6[fK3  g@?Џ~#G@?Џ~#G+8i3xC@# F7 '> )SN8p )SN8p )SN8p )SN8pjws9hוv.iws9nv7Ghws9vF{ݽhwohwo7v,GjvovovovovovovovovovovoוvNmחv}ivivivi* 됕Y鐕Y鐕Y鐕Y鐕Y鐕Y鐕Y鐕Y鐕Y鐕Y鐕Y鐕:p:p:p:p:p:p:p3:lKotivivi8tЁC8t@[a8tЉC'8tЉC'8tЉC'8tЉC}ӾvNi_;ktJ}i_;uS/:ӾvNi_;k}ӾvNi_;k}ӾvN :k}i_;k}ӾvNi_k}']vˆt.r_t/].E}]]]]% ]e[lkm.]< ]e[lkm]˶v.e[lkm]ˮv%]6 .څG]xtхG]xtхG]xtхG]xtэG7xtэG7xtэG7xtэG7xtэG7xtэGC>C>C>C>C>^Չ^Չ>Ӊ>tO'tO'tO'tO'tO'tO'tO'tO'tO'tO'tO'tO'tO'tO'tO'tO'tO'tO'tO't#8#88> 0à> 0à> 0à_ ЯzѯzѯzѯzѯzѯzяCۡ~C~w?e?W~o7f췛vn~o7f췛vn~vn~ϓv_7~C~w?O~yw?uCl6s@'tb@'tb@'tb@'tb@Ћ,pAAԉAԉAԉAԉA`P'ݑz1tKà,  ,  ,  , W0ȗ21ș9ș9ș9ș9ș9ș9ș9ș9ș9ș9ș9ș|9ȗ|9ȗ|9ȗ|9ȗ|9ȗ|9ȗ|9(C|9ėC6cH7tcH7tcH7tcH7db!<bHaHaHaHa(!!!!!!!!!!!!!!r? }>{r=9rO'ܓC!{r+ܓCIQ ֍a֍a֍a֍a֍auc^ Ű^ ۋa{1l/Űb~c1ú121ú1ú1ú18 İL Ȱ Ȱ Ȱ Ȱ Ȱ Ȱ Ȱ Ȱ Ȱ Ȱ Ȱ Ȱ Ȱ Ȱ ȈȈȈȈȈȈLĈLĈLĈLĈ~1##:2##21##:2—#1—#|9—#|9#&#:2LjȈȈȈȈȈȈȈȈȈȈȈȈȈȈȨȨȨȨȨڏQ1ʙc~ڏQwըj]5QQQQQQ=QQQQQQQQQQQQQQQQ111111111c 1<ưӓ1w;s̝9Ɲc9ƙc9c1gȘcx1cx1cx1cx1cx1cx1cx1cx18x18x18x18x1Ǹs8&1/1.qqqqqLc\6Ʊbq,Ʊbq,Ʊbq,Ʊbq,Ʊbq,Ʊbq,Ʊbq,Ʊbq,&b ,&b ,&b ,&G'c <&cžLؓ {2#:2#:2L`0LLȄ\L`1<:ޚpoM&[ ք{k½5ޚpoM&[ ք{k½5ޚpoM&[ ք{k½5ޚpoM&[6G|?3?sK>,&XL3&2ΘIɸߏK'qԛIԛIԛIԛIƤ[cI$N$N$N$N$N$N$N$N$N$N$N$N$N$N$N$NNNNNN)L씝);;eg씮LɔLɔLɔLɔLȔ;cʝ1S1ÔLŧb ),b ),b ),b ),S)Ɣ{cʽ1ޘroL7S)Ɣ{cʽ1ޘroL72lڽ1ޘvoL7cZ>cZ>cZ>+Lʹ16fLۘiiNii٘i٘i٘i٘dZ6ci3,>3,>3,>3,>b3,6b3,6b3,6b3˧|:˧|:˧|:˧|:˧|:˧|:ͬb33:33:33:33xb03:33:339 0`9 0`9 0`9 d?c?c?c?dd?c?cNWl̜1s6fCcζ9,^{e9K,᳄>K,᳄ϒ ^K6x/%dlϒY%Ld %}KzGKz-ђ-ʒ,ʒ,ʒ,ʒ,.q~ _v/ʲ,ɲ,se,M-Ӗiz̳<̳<̳<_cen] n nd <6c <6c <6bo' Ȇ{d=Æl~ݰvxo N 9b ,6pn,ܰ5flؚ [ak6lٰ͆5flؚ 7ۆmͶXl`Xl`&Xl7ueo?W|vf٘Mɯ6flژMic6m̦bMnMnݔMyaS6aS6aS6#MȦ{dMnM^ԙMؔNtm~lⲉ&.lⲉ&.lⲉ&.lⲉ&.lⲉ&.lᲅ˖lȖlȖlȖlȖlȖlȖlȖl'gwb| _/͖llƖllƖlla&[l᱅[ .[6gKN8eS8eKoxeKwtgKwtgKwp-7N[V[XmaV[XmaV[XmaVAX b*U VAX b*U VAX b*U VAX b*U VAX b*CAl:u(h97(3A[EA[ .AӮ>̞>Ӟ>Ӟʞʞʞ᳇{Þ>Ӟ>Ӟ>Ӟ>Ӟ>Ӟ>Ӟ ۓ=,aݷ۳{=wߞoݷ{{{vk}{=wmeO^eO^eO^eO^eO^eO^b},b},b},b},b},b},b},b}n}yؗ}Yؗ}Yؗ}Yؗ}Yؗ}Y`_~?/c>&con}w ﻅ;iwv_>qe}\8-|>w΁;s9ps9zt%zs3r9ps9w΁;s9ps92r9w΁{;pz}s9p`qpq)r`p9r`_@^@^@^@^@^~9~9C~9C\݀rs5!!!!!!!!!!!!!!!!!!!F|rh9dC9C|9C|9C|9C|909#<8ҧ#9#L09#L09#L09#L09#L09#L09#L09#L09ˑ :#Y9#=:#]:ҥ#]:H5G~?tG~[evyرѱȱѱ1ztGztGx1&ǘcr1&ǘcr1&ǘcr3Ӿ/-{6 m->====LN ǜ .'r .'r .'r .'r .'r &'x=p=љ ʉʉʉ￟>9Wͩܜͩܜͩܜͩܜͩܜͩܜ̜ͩ)sʿ{ʿ{ʿ2s^9S9եS]:TNuTN9ѧ<|ç<|ç<|ç<|ç<|ç~-rOtʹr*/r).r*+SY9S7˩StjNѩ=:gǜqǜqǜqǜq˙>ҙ.ҙ.ҙ.ҙ.r&gar&gn& 3w˙rn9s[-g3}n9Ig6˙>3^939ӡ3y9ӡ3L09sÝqǙϙ|ar&#g2u92r.#2r9\v1:s1:s1:s1:s1:s1:s9s>s>׫s9\~\~\~\~&ۤs9.u.?sչυ\`uV޻½w޻O l.|so~tN8]tN8]tN8]tN8]tN8]tN l. l..d y .肋.肋.xB.dB.dB.d .0 .0 ar 6!NSHB܄&MHnB{8! a$I/p qs(On V! C~Cx;wTC~G _HBҿ/$S! _HBҿ/!E qR-rlYȎ8;!!tC< }yBn' y.9钏.R.1K.1K]KK.KK\.1ҭ|)G\K7<]ڳK{vחҞ]bs)Sw%o_%o_%o_%o_%F]bt%F]btѥ]ӥ=K.qKvQtO+ҹ+J߮8_+;vsW]ݕ]Օ\]uw֕YW~g]++W +W2sϕ\̕\̕\.W\&WvoWvoWvoWvoW\ܕ]']q']q']asIWtIWtIW|t%7W2skW+lQ߰klZ׮95.ھ_kzvm߯}Z\'dek8bpwap;wsΝw~?wN^NN;ӥ;L0;L0;L0;L0;L0;L0;L0;L0;>;Y;Y;Y;Y;Awzs'N˰{>{L1{L1O{q{ݹ?|r~to=.{ϻ{ϻ{ϻ{ϻtomV{[}o=ޭ|Vw+ʽʽʽʽʽʽʽ<ʃ<ʃ<.))) #)<d'/ / / / / / / / / / / / / / /fypy7Gɣ}>yG3'yҙ'yҙ'xҙ'yҙ'yҙ'y 'px 'px 'px 'px 'px'yx'YxF~?x'x'x'x'x'x'x'x'x'x'x'x'x'x'xgxgxgxgxgxg3&ϘyvyqO^'/.y.y.y >/ >/ >/ >/ >/n7ʋϋɋ Ǿp Ǿp Ǿ Ͼ 6/ؼ` 6/ؼ` 6/ؼ` 6/ؼ` 6/ؼ`+6ؼb+6ؼb+6ؼb+.˫yůnW;j_~ïv޼W;j_ܼ+.+.b+r+r+8ʫbKU^1yWL^1yWzAؼr+׼r+׼r+׼r+׼r Uq׼q׼q׼q׼q׼q͛}~o͝Nys(o7ovo\߈oؼ7[fssl-~ӣ7[&+oؼɛɛț-~ox7[fl-~o8Ǽɛ7yox?*km;߼;߼̻߇~}}{+>7MYefywY,w7ʻ};&c;&c;&cn9S9S9S]V]Fe]Fe]F]6wto>o>o>o>o>o>&胋?oЩ|>|>|>|>Cn>Cn>d.}إyKv.}إOYSN>Oi>ҧ]K6s?mɧ|ɧ|'X|Ч}Ч}Ч}*}Fs|˧|r'x|ǧ}r'|r'|˧IOw˧)O.O.O.OԝO%_\%'_r%_\%_x|ȗ|ȗ|ȗ|_x|_X|͗|͗|͗|͗|͗|~q~a%_X|a_X|Ɨl|Ɨl|Ɨl|Ɨl|Ɨl|Ɨl|Ɨl|Η|Η||a_XQ7X|c7X|cͫ߼ͫ߼ͫ߼ͫ߼+:ͫ߼ͫ2-2-2msy|ۜomsqo196fv}پlno{mk7~᷇|<|sL|ķL|ķL|ķL|78|a?8?8?8Ïď <~<~<~GG~tGG~tGG~tGG~tGG~k?nڏOncg~̏3?v<~;cg~u.'&@t LT(HTPA$D̑ĉC&HLk߫v]l9//xfJ7]O5o֪w]U߆ӟvկ.^Yzn #|=G>bL|{}FЩ&@w @6f d3lcd d2L2@&d d2L2@&d d2`` 0N'dq28` dq28` ` `````` CСt:t:`@.셇  !!0ĺ2ĺ2ĺ2Bg 3C!t:c1Bg !!BCb ?C!c1B ?ztuwuwuw[d:-2b 1F#C!cd12b 1F#C!c1Bw !!!cd12al`{```````0WFWGWGWGXcGX[GX[GXOFA#bq1¸a\0.F#se2\a0WF+#̕rA#a9 ֓֓֓֓֓c1A#tc1Aw;F/Pc1tc1c~1?Ƙc̏1c1c}cl!1d1Ccc y!11<ƐCcc y!11<ƐCcc y!1tcuuuudddddd e8Əc=c=c=c=cL1&c1cb11Ƙc`j@b[cy2<`L0O&'̓ dy2<`L0O&dy2`m`m`m`m`nL07&̍ sc1ܘ`nL07&̍ sc1ܘ`nL @bq1`LL0&& cb11`LL0&& cb11`LL0&'戀6rBoNasMasMasMacLasMasMasMLasMasM1&{)rS妐rBSMbmbmbmbmbmbmBoN3ЙS)t:s 9Μb~L3ЙS)t:s 9ΜBgN3ЙS)t:s 9ΜBgN3ЙS)rbLL1&S zb=1AO̠'f3 zb=1AO̠'f3̋ zb=1üa^0/f3̋ by1üa^0/f3̋ by1üa^ 0f rA3a9 0f rA3a9 0f rA3acc{{{{0Xc,1 s9ca̡#rCsa9!90r9֌9!sC؇̱c2>d}9!s̋9a0xCsa9!90rCsa9!90~Cs9t:b1CG̡#s9a0xc<,0 axX`<,0rX@ a9, 䰀rX@ a9, 䰀~X`^,0/ ̋byX@ a9, 䰀rX@ a9, 䰀Г rX@ `, d 2X@ `, lɻ%zr5c5c5c5c5c5c5cĚĚĚĚMZZZĜXbN,1'K̉%sb9ĜXbN,1'K̉%sb9ĜXbN,!%zr =\b\b\b\b\†X†X†X†X†X†X†X†X†X†X\\\BG.!%a =\Bw+a9 䰂V rXA+a90V+ axXa<0V+ a¼Xa^0/V+̋ by| a+V؃[al= { ca90V XA+d,V XA+++++5l5l5l55555䰆֐rXc<1k5axXc<1~ VV1'֘k̉5sb9ƜXcN1'֘k̉5a9ƜXcN1'֘k̉5sb9nXC7 k5t:r \CG#טk` !5d ֐2@`l d 666666666X37X37X37X37X37X372@`l dvvvv`Nl0'6̉ sb9`Nl0'6 `q8`l06 2@`l drbNl1'[̉-sbXb,l1 [-caXb,l1 [-ŜbNl1'[̉-sb9ŜbNl1'[-a --- xb s|9@>dslv9@>c1sĘ9ba{a{a{a{a{!##s|9B>G!#sq5:8B[-G#tY[XsWGGGGGGGGGgCOG!Gyaa###G]WGz|>BvGٝ ֢wN ;A~'u9AN?' zO't y0N :A^'y  6 :A^'ywN :a|NC'N'n'1;8~d.ug~O?7 o~_V0._[_}?w~/s}cW׃}+~W77Co׋>;+C{p{˹o}fV{].E~ωsx \z3u=>-{uje>?>xo^^/S8G~<8 3~_qzː[Wq&WwJmmMT|_&.;mxy֑y5?ۚfs^WBu#>W\~#n.'2c ^.{x8?ޏ-]4M3źy~j?Cz&_~XϾGc#Ko}7qʎ/A/V;/}^w){- EWbT~ЯoH_>i8.ߓbb} ~/4M,W#~TOn|ޗLy1z^oT>N0/֥X7y?$kerkf l8z*<۲^!g{iTy㸕e}Z^]sv;No70o}W^Y|NJob9vA>\Wba^ */z>'ϿR~+Hك"?~הI>$}y\(y.U'sw:#cƏU<ױuh< z["cS}`xs|n3GAK*M~KC;TvfX^7wյ?;>]yۖq-.}:w}N׹\~rU|]re>?8\9_Scyc#Lž˾GsUWmW/S>bq3U'TM {,~/Շ7K_[!cq_-Vl]Ta}|4M,cj}uw*4c'Qtyu#߫/w~ܾlF?>ۙ*?)W~>Z)8 ngyWR~*N}zU<+ryK3ťΏ'fDzK~qPN|j (}+R^{~a{H]msU<i{i_fyu}>m;O?_Rv"x]R>~ @Tz>j O庒ѿT (RSƩzuϳ|?8';"7฾]N͕z]ʎS~kj~Tyoo9DJMcoij>nߓ[[!^/|/qλz=z[כ:&Szu~uo~sqTvuWp^SWWug@Ui<.U}i:)/!oe\4Z,SzQye*.ڮNEmϟlq~9QCMx[*]A*4M4M6v/Uw\y}U ur5>Ǻ~'z,]S~#Տ*^#pPybj|ݚǑ0 S~@>TTg?[#U\oazki7,J?vM4vXw}I_y?~2WwWV5u'w/ous76M^'m=~ޫ_G|Bkr?Q]7y{"ǏYNsP _r9_P+5O9R35u:橼uw=?M4>2Mϥr=e,]7?jA>0\/{/m?yo6寖}i|Ȇs넣>ʃ|8Z1祟 2/`Gxz\6=ĸc>Awr}Ru*;گK奤;mݟz'_I!'9y5#G~oa[vEߕ۷>ii}CS~W+3W~ U|Sѷq|4Δ=/K/s\,⬹)||>꼃JŎ*r&}䩞J}ͷ*_80RYS:uL\S[N]W罨y4M4M4{}c9l\l}LyVLu'>'SӏڮGPrU} C]>}뙦i?aZ~fL*hu~>s]g_+#nr>(3<[f\OUa;77?T$@uMT7giižөzc׹խ}l̦[DsMzݶT|2|^v߰vo\F虦Y_cvQnܑ󭸿G r\N'z/ۨ|>틦UjqRexPS}y^벎F}i(|4MQWS\j v?W/5y?~IJOO-WU,*Ec`:*n?K2_9}'1Kr5^量.3K=SWŪ娮+yj~=yuljGQ'NJH*牚i>'s5Uu4g-㥩: >*,i>=>=ύ%}e7tul*Ozc:-Ggz?ǺtUW~|~aGUϵ4MӬö WS=~ti34;u~>#}Ծ_}cpl<Ƕ?_xq{(e|[5[ȍםZwRy|:OWsOz5b}sz}sii>"fi7 ]?S5'y:?ӹwnc>?_uU~Y/RsM9T s"}QX.xA;c=M+4M4MS3WsC,_#6<}WV}"θ|i>/u_ϰz opݏM4M4>1S\~+3/yq~|/_[}u(Oyʦ_:|~~XGoCsT?'{5qy1{?a7qky>C~KM4M4M _wI=]4ۘWXOa>y>s׭}Oy7m5/5gߍ>:D|N߄=|d*Anpg/ov˺crQ#ʮsZ3ޗu=s _e;*~׃\T܃;^aiiT~W08??BE)vg y;ss]kz>I6yܲ]y'-ʼn.?4M4M4Ro:S42Ws##:"0x̫`6SU8 ί>fljzHnu꼳o-'Mջp_GU4M4M4b>l,&8N Fk5>&|Tfg'(?/:8n΋x׉竛iiiͿ}}@"_5|T:r*׿4Ms,Ώ|=^>RdiԹg5M4>H>^k?G1ǡ `9 k>4S?VT}B\:xוcscx]*=ϜB,oS)^UgY?}'u增B(4MӼK R^G ZMU+Fy~s~ Mw}ZgRzy*P篛yf(;F_Sm}[{g-Sc_iO<\ܟ%GS|2E߆su.go:㾞`/!b8\ܿ-ّ_P7~Ր׽ΏOX<};4M4Mu\n.sL|\m{.}ib+=i?[is~=A1y`+g[[M#2Pp?fCYK֏xG_ٯxcy<6M4MٷMؿq~OqWɗ1M~͇ }z.b][z:=E>T}cs̓{++u-|Sa1744M4MS<<u7׏>q~-4" 7~qx}<~_ZITbr<ܷ7U~{#Cs/^L4M4ǺorWo ~Ͼo1M;GWozߔO/y}ߔ"ˣ}}Ϫs[LTU>`aܗEMGU^z]N5oyDsܹ$#׹ii6Ϧ9Ogx&9ߋ J]4îOWmߛ5귞Ϳu#Kg%ߗǙ\czyni@?Rq>gyN[s=D_ie\wC;%"_VD]կ3z7 r)~܍)W9:gi+0e׫z墨γ)}qW}TM4͟0wP~3p>*'Uڇ#}M?c]̭Uq8(? 4M+䞳f-~L_> lg*ŸtҮi棰0[y)g TėuZ׉9%eQvii>K문~/!J+r{Wng9C:z|L4[ڨ<}S~T%՗7/NRu+W3fifG> #`+ '8O84ge ~j 6'Du>-2M4M4K!-sh&Y8QP(,+މ`i^_:A%~4M4M6\w-C}?iR ){7ƛ^Hé7d7~L4M4MK͇?*P;R!Q4Mb?[M[]o?s>74W̶h=U_-Eu>[3M4M٘[} {g{ȺՏzxwߋA֘̾{usږG~f]?~jMux:4M4Ɣ}v-~g>)Oߔ~__?VټRS~~>LKr~~>]Gos4M4T~ 5_Iԭr~ϕ:.@ {s_ॎFi2ywzochEM4MS}_ai q>_3Q(/`?L4ۥTͰ4Ourks 4MSqg]~?~s*64`.^aʯ}qxsoiT(=}t;ޞjy]{\?:0wTD})L4~1~.st< ߿}5M|l9UՓ0Kis{5~\:짿վr4~~^:4M]_ K|uݾ_ۋTe -//=/(f/=?S]ۣjݟί7Wp4M5V?^պo>8OۊE]c_ctqmO{6vQϫk?;.u|Poymi%֝}Wo*n:g:J{4ѩ9S'7?eGߧڷ$RŸ1M43s2eK,|9_UV﫚azoǰ/ze<'gMM~q_[ifpb<֍g^w0M4`> ᇏބp'nT3>Qt2xGkW+s^WSʿ㪯+_~|W}hY}hGU$7x5M4__V~>d}GSyF}=mG]k]8W~m#U|ω/+>י?i'Ͽwܹm{<W7eﲿ[q.K~vhylfLsoh6Z9z:ar| ?o7eGzkni}sESߨ7d5eع/6**?ل]z}/S Ou=7ncҪ)c}zO8KZoK|^?üWYSz/Nݏ'n}=띔~fqTHS맪 Q}ݠ)}Rjp}Oɍϲܕֿ^O}i_*&3M3=?>cݎr2Rqİ>NXl/ٿc?3t;w_)|il+_d8s·T&}NNe??O+#p>s?\Չ|8Q_W|*>xiiuT,Ϊ<#횰 `IU)q_;SNJ#?!+u}Pg>ysv!۵>4M4g.Oc><;}Þ㸛{f]PJ_=|VSEU]QsU|¾jLųf\_ {ǜ~8ef7k_r^T@oٵWu|~=MۦƋi<_W>wfn|'8OlWpe0*;+)W,,Vẽ˹Hy/M1ާs}{NvL?afxk߀G/:67Y?KۮW/?qTz>]~YN+XQÔ_k(}V|Ϧy^Pוgd{&Ʀ>.WYZUCp&םs] 9~D{^/<=?e[WߩA]{~n_NezQ= w`*_c"^Fp{WoίL[+ٱTΔsrǫ5Y7ey<~u'|ʸ*%Oҗ\:Sq燘_^);vFT}u^>~]]}yhܚGu3Z11?V>|-/xxK?܏-as8bg3e|sK]o>:'qp?uf,=HrܦoʛS9>#z[6 =q0WꝹ_ڏzhT]MC'i> exxq:m|م>sߩƕx>*W2_<8z"Wij]Tn=~b*zfnP^V~8єb,y[:|gq1/5UXS˔^o?:l_s[W}GU?TΫܺG7+wߗ?c?:948:%bֿsAASso ?_ +qj \M4usuXC L>32er=^*4MͦH=6_G65̰gT2MOCSyAU}LyϪϙq>OҰ6VOU|XUuV翰}vku=7~G|<ͯq_AXjrQn)/Kq0E%>}q0[SכR|ǿH,=dʏC#Ӧz=ߋn\k|%rџɝ?e=\y˜Oq\]J#si,Tvi6?/o&sVlǖuYQ}c4p?жfXMod;VKalc<7wx4KY7"h+lc~s̒qYs:/}x,4f_ݽO6T>kN]6M)In|s8yG/y &s`unM4벩>cWp\9xk]_=4MmN쒩8V<|&|c6M̵%mM0}A:l}Yj?y oiv\;T=j:Q,5Vq f<>7?X̵g{i_' ɳ.q˳i@_} dܻهq׳w|.|7WIun}>%ˣ^zyf˺z=!:oQ},O2/~8svY/C\C*֔'l/]V멺ek]_O؎}Us2cu`̳omlڿWzϠ%we9>con7=bC*}/inst/NEWS.Rd")) \name{NEWS} \title{News for \R{} Package \pkg{Matrix}} \encoding{UTF-8} %% NB: The date (yyyy-mm-dd) is the "Packaged: " date in ../DESCRIPTION \section{Changes in version 1.6-5 (2024-01-06 r4560)}{ \subsection{Bug Fixes}{ \itemize{ \item \code{x[]} works for \code{x} inheriting from virtual class \code{sparseVector}. \item \code{length(x)} is always an integer for \code{x} inheriting from virtual class \code{sparseVector}. Truncation did not occur for \code{x@length} of type \code{"double"} equal to or greater than \code{.Machine[["integer.max"]] + 1}. \item \code{tril(, -n)} now works again. \item \code{tri[ul](, k)} now works correctly for \code{k != 0}. \item \proglang{C} API function \code{cholmod_triplet_as_sexp} transposes entries \dQuote{opposite} the \code{stype} when that is nonzero, following CHOLMOD. \item \code{R_init_Matrix} did not register \code{cholmod_defaults}, so calls to the corresponding stub did not work. } } \subsection{Misc}{ \itemize{ \item \code{\%||\%} is defined in the \pkg{Matrix} namespace only for \R{} versions less than 4.4.0. } } } \section{Changes in version 1.6-4 (2023-11-29 r4523)}{ \subsection{Bug Fixes}{ \itemize{ \item \code{printf} format mismatches detected by R-devel are fixed in 3 \file{src/*.c}. \item better deprecation message for \code{..2dge()}. } } \subsection{Misc}{ \itemize{ \item Entry point \code{M_chm_triplet_to_SEXP}, removed in \pkg{Matrix} version 1.6-2, is restored (as a macro). It was \dQuote{covertly} used by package \pkg{Rmosek}. } } } \section{Changes in version 1.6-3 (2023-11-13 r4513)}{ \subsection{Misc}{ \itemize{ \item With an \R built with \command{configure} option \option{--disable-long-double}, \code{prod(M)} now very slightly differs for two differently classed versions of \code{M}. \item \code{checkMatrix()} from \file{test-tools-Matrix.R} gets optional \code{MSG} argument for suppressing \code{prod()} differences. } } } \section{Changes in version 1.6-2 (2023-11-05 r4503)}{ \subsection{Significant User-Visible Changes}{ \itemize{ \item Methods for generic functions \code{rbind2}, \code{cbind2}, \code{\%*\%}, \code{\%&\%}, \code{crossprod}, and \code{tcrossprod} determine the class of the result using more strict rules, designed to avoid \dQuote{surprising} coercions where possible. Notably, operations involving \code{RsparseMatrix} now return an \code{RsparseMatrix} in more cases. \code{TsparseMatrix} and \code{diagonalMatrix} may be handled as \code{CsparseMatrix} or as \code{RsparseMatrix}, depending on context. } } \subsection{New Features}{ \itemize{ \item New \R{} function \code{Matrix.Version}, taking no arguments and returning \code{list(package, abi, suitesparse)}, a list containing the numeric versions of the package, its ABI, and the internal SuiteSparse library. ABI versioning is new: the version is 1 in this release and will be incremented by 1 in each future release that changes the ABI. Versions and their components are defined in a header for use by packages with \code{LinkingTo: Matrix} in \file{DESCRIPTION}. See \file{inst/include/Matrix/version.h}. %% TODO {for 1.6-3}: Ops using (x@x | is.na(x@x)) for ndiMatrix 'x' \item New nonvirtual class \code{ndiMatrix}, extending virtual classes \code{diagonalMatrix} and \code{nMatrix}, for nonzero pattern diagonal matrices. It is used to represent the result of \code{is.na}, \code{is.nan}, \code{is.infinite} applied to \code{diagonalMatrix}, as well as diagonal boolean products. Coercions \code{as(, "nMatrix")} now give \code{ndiMatrix} instead of \code{ntCMatrix}. The latter can for now still be obtained by coercing to \code{nsparseMatrix} instead of \code{nMatrix}. \item New C-level validity methods for \code{sparseVector} and \code{[nlidz]sparseVector}, now requiring \code{length} not exceeding \code{2^53}, which on most platforms is the maximum integer representable exactly as \code{double}. \item \code{mean(, trim=)} now works efficiently for nonzero values of \code{trim}. \item \code{rep(, each=)} now works efficiently, avoiding \code{rep(., times = rep(each, times = length(.)))}. \item \code{.m2dense} and \code{.m2sparse} gain an argument \code{trans} indicating if vectors that are not matrices should be coerced to 1-row matrices rather than 1-column matrices. \item \code{.m2dense} and \code{.m2sparse} can be called with one argument. Their \code{class} arguments admit new default values \code{".ge"} and \code{".gC"}. \item \code{.diag2dense} and \code{.diag2sparse} gain an argument \code{kind} indicating the \dQuote{kind} of the result. \item New exports \code{.M2V} and \code{.m2V}, for coercing \code{Matrix} and \code{matrix} (and in fact \code{vector}) to \code{sparseVector}. \item New exports \code{isUniqueT} and \code{asUniqueT}, with optional argument \code{byrow} allowing for row-major ordering of entries. \code{asUniqueT} supercedes \code{uniqTsparse}, which is no longer documented. \item New export \code{aggregateT}, for aggregating \code{TsparseMatrix} \emph{without} sorting. \item Methods for \code{all.equal} now report the packages where S4 classes are defined. \item \code{sum(x)} and \code{prod(x)} no longer require a coercion from \code{symmetricMatrix} to \code{generalMatrix}. Results where coercions are now avoided may differ numerically due to reordering of adds and multiplies, most commonly on systems where \code{sizeof(long double) == sizeof(double)}. } } \subsection{Bug Fixes}{ \itemize{ \item Methods for \code{cbind2} and \code{rbind2} did not in all cases handle vectors as 1-column and 1-row matrices, respectively. \item Methods for \code{cbind2} and \code{rbind2} did not handle 0-length vectors (including \code{NULL}) correctly where the result would have 0 rows and columns, respectively. \item Methods for \code{cbind2} and \code{rbind2} did not handle \code{NA} in the \code{x} slot of \code{ndenseMatrix} correctly (i.e., as \code{TRUE}). \item \code{cbind2(, )} gave \code{ngeMatrix} instead of \code{lgeMatrix}. \code{cbind2(, )} gave \code{dgCMatrix} instead of \code{lgCMatrix}. Methods for \code{rbind2} had similar problems. \item \code{rcond(<0-by-0>)} now returns \code{Inf}; see \PR{18543}. \item \code{round()} and \code{signif()} now return \code{ds[yp]Matrix} rather than \code{dp[op]Matrix} and now discard \code{factors}. \item Methods for \code{length} now return \code{integer} rather than \code{double} if the result does not exceed \code{INT_MAX}. \item \code{dsparseVector} with \code{x} slot of type \code{integer} are now formally invalid, as always intended. \item Methods for subscripting \code{sparseVector} did not behave compatibly with \pkg{base} when supplied with fractional, \code{NA}, or out-of-bounds subscripts. \item \code{symmpart(x)}, \code{skewpart(x)}, \code{band(x, k1, k2)}, \code{triu(x, k)}, and \code{tril(x, k)} now always return a \code{.diMatrix} for \code{x} inheriting from \code{diagonalMatrix}. \item \code{colSums(<(n|l|ind)Matrix>)} and \code{rowSums(<(n|l|ind)Matrix>)} now always give a result of type \code{"integer"}. Methods differed previously, some giving \code{"double"} (as \pkg{base} does, suboptimally, traditional matrices of type \code{"logical"}). \item Some methods for generic function \code{lu} did not transmit \code{Dimnames} to the result. \item Some methods for group generic function \code{Summary} ignored arguments matching \code{\dots}. Other methods did not ignore the \dQuote{garbage} elements of the \code{x} slot of dense, triangular matrices. \item \code{kronecker(, )} threw an error for attempting to access the nonexistent \code{x} slot of its first argument. \item Matrix products now behave exactly as \pkg{base} when testing for conformable arguments. \item Numeric products (\code{\%*\%}) did not always return a \code{dMatrix}. \item Methods for \code{all.equal} now \dQuote{see} attributes of S4 objects that are not slots. This can be disabled by setting argument \code{check.attributes} to \code{NA}, which is otherwise equivalent to \code{TRUE}. \item \code{prod(x)} is computed more diligently for \code{x} inheriting from \code{sparseMatrix}, \code{sparseVector}, or \code{.t[rp]Matrix}, i.e., those \code{x} that can be understood to have \dQuote{structural} zeros. Now, multiplication by zero occurs at the position of the first structural zero in the matrix or vector (when traversed by row in the case of \code{RsparseMatrix}). An exception is \code{TsparseMatrix}, for which multiplication by zero occurs before multiplication by any stored entry, regardless of the position of the first structural zero in the corresponding sorted matrix (to avoid the cost of sorting). \item \code{tri[ul](<.t[rp]Matrix>, k)} was often wrong for nonzero \code{k}, setting too many bands to zero. \item C-level \code{tCsparse_diag} (formerly \code{diag_tC}) now handles structural zeros and \code{NaN} on the main diagonal correctly. Option \code{"diagBack"} now works correctly. \item The prototype of API function \code{M_cholmod_band_inplace} was wrongly copied from \code{cholmod_band}, instead of from \code{cholmod_band_inplace}. \item Many API function prototypes wrongly used \code{const} qualifiers where the registered routines do not. \item \code{expm(x)} failed for \code{x} of class \code{dtpMatrix} or \code{dspMatrix}, since \pkg{Matrix} version 1.6-1. \item \code{.m2dense(x, ".ge")} allocated unnecessarily for \code{x} without attributes. } } \subsection{Misc}{ \itemize{ \item C code now refers to the symbol \code{factors} as \code{Matrix_factorsSym}, rather than \code{Matrix_factorSym}. \item Certain never or seldom used class unions are removed. \item The content of \file{src/Mutils.[ch]} has been migrated to more transparently named files: \file{src/attrib.[ch]}, \file{src/objects.[ch]}, etc. Similarly, much of \file{src/factorizations.[ch]} have been migrated to \file{src/solve.[ch]} and \file{src/determinant.[ch]}. \item All matrix product code has been migrated to \file{products.[Rch]}. \item Files in \file{po/} and \file{inst/po/} have been updated due to more frequent use of \code{gettextf} in \file{R/*.R}. \item C code is prepared to handle complex matrices and their factorizations. Notably, new machinery in \file{src/cs-etc.[ch]} will enable linking the CXSparse library instead of the CSparse library, the latter supporting numeric types but not complex ones. \item Some API declarations and macros not used by \emph{any} reverse \code{LinkingTo} are removed or remapped. \item API headers are now nested under \file{inst/include/Matrix/} for better namespacing. Where possible, packages should start to use \code{LinkingTo: Matrix (>= 1.6-2)} and include files from the new subdirectory, e.g., with \code{#include }. \item Users including API headers can define macro \code{R_MATRIX_INLINE}, typically with \code{#define R_MATRIX_INLINE inline}, to allow the compiler to inline stubs for registered routines. \item \pkg{Matrix} did not pass its checks under \R{} 3.5.0, implicitly violating \code{Depends: R (>= 3.5.0)}. This release restores compatibility. } } } \section{Changes in version 1.6-1.1 (2023-09-08)}{ \subsection{Misc}{ \itemize{ \item Export the generics \code{crossprod()} and \code{tcrossprod()} explicitly, needed for R-devel when they become primitive internal generics. } } } \section{Changes in version 1.6-1 (2023-08-11 r4228)}{ \subsection{New Features}{ \itemize{ \item Several new coercion utilities, exported and documented in \code{help("fastMisc")}. Some of these supercede ones made available (experimentally) in \pkg{Matrix} 1.5-4; for example, \code{.M2m} makes both \code{.dense2m} and \code{.sparse2m} redundant. The superceded ones are not yet formally deprecated, but are no longer documented. \item \code{drop0} is now implemented independently of \code{CHOLMOD}, becoming more efficient notably for logical arguments, no longer requiring a coercion to double. \item \code{drop0} gains an argument \code{give.Csparse} to complement \code{is.Csparse}. \code{FALSE} indicates that \code{RsparseMatrix}, \code{TsparseMatrix}, and \code{indMatrix} arguments should be handled directly, without a coercion to \code{CsparseMatrix}. The default value is \code{TRUE}, for backwards compatibility. } } \subsection{Bug Fixes}{ \itemize{ \item Fix four Valgrind-detected memory bugs. %% \item \code{[cr]bind(, )} now behaves as %% \code{[cr]bind(, )} in more cases, always %% handling the vector as a 1-column (\code{cbind}) or 1-row %% (\code{rbind}) matrix. \item \code{ \%*\% } works again. \item \code{diag() <- value} works again, no longer giving a \code{p} slot of length \code{Dim[2]} rather than \code{Dim[1]}. \item \code{as(, "symmetricMatrix")} now checks for symmetric \code{Dimnames}, for consistency. \item as(, "[nld](sparse)?Matrix") now returns a \code{.gRMatrix} or a \code{.gCMatrix} depending on the \code{margin} slot. \item \code{as(<[CR]sparseMatrix>, "generalMatrix")} now checks if the number of nonzero entries in the result would exceed \code{INT_MAX} and throws an error in that case. \item Validity checks on the \code{perm} slot of classes \code{Cholesky} and \code{pCholesky} have been enabled (forgotten in \pkg{Matrix} 1.6-0). \item API C function \code{chm_sparse_to_SEXP} now sorts and packs its first argument \emph{before} assigning struct members to variables, no longer accessing blocks of memory freed by \code{cholmod_sort}. } } \subsection{Misc}{ \itemize{ \item Run speed-measuring tests only \code{if(doExtras)}: these were too slow when run under Valgrind. \item Most coercion code has been migrated to \file{coerce.[Rch]} from elsewhere. \item The number of methods for generic functions \code{coerce} and \code{as.*} has been reduced substantially, from 306 to 194 (not counting deprecated ones), partly as a result of efforts to do more fine-grained dispatch in C code. \item Files in \file{po/} and \file{inst/po/} have been updated (again), as many more C level messages now use format strings as a result of \code{vsnprintf} usage in \file{src/validity.c}. } } } \section{Changes in version 1.6-0 (2023-06-30 r4125)}{ \subsection{Significant User-Visible Changes}{ \itemize{ \item Class \code{indMatrix} gains a \code{margin} slot with value \code{1L} or \code{2L} (\code{1L} being the prototype and previously implicit value), indicating that the object represents a row or column index matrix, with ones at \code{[i, perm[i]]} or \code{[perm[j], j]}, respectively. \cr Methods with \code{indMatrix} or its subclass \code{pMatrix} in the signature have been adjusted to account for the new slot. Notably, multiplication on the right by an \code{indMatrix} with \code{margin = 2} is now implemented as a column subscript, and the transpose of an \code{indMatrix} is now the same object but with \dQuote{opposite} \code{margin}. \item Virtual class \code{MatrixFactorization} gains a \code{Dimnames} slot. Now all factorizations preserve the \code{Dimnames} of the original, factorized \code{Matrix}, whereas previously classes \code{Schur}, \code{sparseLU}, \code{sparseQR}, \code{dCHMsimpl}, and \code{dCHMsuper} did \emph{not}. Users can get the value of the new \code{Dimnames} slot with \code{dimnames(.)} and set it with \code{dimnames(.) <- value}. \item Classes \code{p?BunchKaufman} and \code{p?Cholesky} no longer extend \code{dtrMatrix} or \code{dtpMatrix} and in turn no longer extend \code{Matrix}. They retain slots \code{Dim}, \code{Dimnames}, \code{uplo}, and \code{x}, but not \code{diag}. This change implies that virtual classes \code{Matrix} and \code{MatrixFactorization} no longer intersect. \item Classes \code{p?Cholesky} gain a \code{perm} slot with prototype \code{integer(0L)} to support representation of pivoted factorizations, as typically computed by LAPACK routine \code{dpstrf}. \code{perm} of length 0 is valid and equivalent to the identity permutation. \item Methods for generic function \code{chol} that previously returned an object of class \code{p?Cholesky} now return an equivalent object of class \code{dtrMatrix} or \code{dtpMatrix}. Existing code that relied (correctly) on \code{chol} to return the upper triangular Cholesky factor as a \code{Matrix} can be expected to work as before. } } \subsection{New Features}{ \itemize{ \item Methods for subscripting \code{Matrix} now use the more systematic code in \file{R/subscript.R} and \file{src/subscript.c}, becoming more efficient for all \code{lsparseMatrix} (no longer coercing to \code{dsparseMatrix} and back), sparse \code{symmetricMatrix} (no longer coercing to \code{generalMatrix} and back when \code{i} in \code{x[i, i]} is monotone), \code{unpackedMatrix} (no longer coercing to \code{matrix} and back), and \code{RsparseMatrix} (no longer coercing to \code{TsparseMatrix}, then to \code{CsparseMatrix}, then back to \code{TsparseMatrix} [!]). \cr \code{x[i, j, drop = FALSE]} preserves the class of \code{x} in more cases where \code{x} is a \code{triangularMatrix}, \code{diagonalMatrix}, or \code{pMatrix}, doing more complete checks on \code{i} and \code{j}. \cr Notably, for \code{x} inheriting from \code{RsparseMatrix}, the result is now always an \code{RsparseMatrix}, rather than always a \code{TsparseMatrix}. \item \code{NULL} subscripts, as in \code{x[NULL]}, \code{x[NULL, j]}, and \code{x[i, NULL]}, are now supported for \code{x} inheriting from \code{Matrix}. They are handled as \code{integer(0)}, consistent with \pkg{base}. \item New nonvirtual class \code{pcorMatrix} extending \code{dppMatrix}. It is the counterpart of \code{corMatrix} using packed storage, supporting more efficient storage of dense correlation matrices. Now \code{pack()} gives a \code{pcorMatrix} preserving the \code{sd} slot, rather than a \code{dppMatrix} without an \code{sd} slot. \item New virtual classes \code{BunchKaufmanFactorization}, \code{SchurFactorization}, and \code{QR}, extended by existing nonvirtual classes \code{p?BunchKaufman}, \code{Schur}, and \code{sparseQR}, respectively. These are parallel to the existing virtual classes \code{CholeskyFactorization} and \code{LU}. Packages defining new factorization classes may extend these. \item Virtual class \code{CHMfactor} and its subclasses gain formal validity methods. \item The validity method for class \code{sparseQR} now checks that the \code{V} slot is lower trapezoidal and that the \code{R} slot has non-negative diagonal elements. \item New generic functions \code{expand1} and \code{expand2}, intended to eventually replace \code{expand} and certain coercions from (subclasses of) \code{MatrixFactorization} to (subclasses of) \code{Matrix}. \code{expand1} is used as \code{expand1(, )} and constructs by name factors appearing in the factorization. \code{expand2} is used as \code{expand2()} and returns a named list of \emph{all} factors appearing in the factorization, in order and with row names on the first factor and column names on the last factor. The result can be used to reconstruct the factorized \code{Matrix} as the product of the elements of the list, namely \code{Reduce(`\%*\%`, expand2(.))}. \cr \code{expand} and its methods are retained for backwards compatibility. They may be formally deprecated in the future, hence new code should use \code{expand1} and \code{expand2}. Notably, \code{expand1} and \code{expand2} have methods for all factorizations in \pkg{Matrix}, whereas \code{expand} continues to have methods only for \code{denseLU}, \code{sparseLU}, and \code{CHMfactor}. See \code{help("expand-methods")} for a list of methods, including useful optional arguments. \item Generic function \code{Cholesky} gains methods for \code{denseMatrix} returning an object of class \code{p?Cholesky}. The method for subclass \code{dsyMatrix} admits an argument \code{perm} indicating if the pivoted factorization should be computed. The corresponding \code{chol} method gains an argument \code{pivot} indicating the same. By default, \code{Cholesky} pivots and \code{chol} does not. \item Many subclasses of \code{MatrixFactorization} can now be coerced to \dQuote{nearby} subclasses of \code{Matrix}. The resulting \code{Matrix} reflects the internal representation of the factorization and not necessarily a particular matrix factor. The new coercions are: \code{as(, "dgeMatrix")}, \code{as(, "dtrMatrix")}, \code{as(, "dtpMatrix")}, \code{as(, "dtrMatrix")}, \code{as(, "dtpMatrix")}, \code{as(, "dtCMatrix")}, and \code{as(, "dgCMatrix")}. See \code{help("denseLU-class")} (and similar) for details. \item \code{determinant(x, \dots)} and \code{solve(a, b, \dots)} now work for \code{x} and \code{a} inheriting from \code{MatrixFactorization}, behaving as if \code{x} and \code{a} were replaced by the factorized \code{Matrix}. The exception is \code{x} inheriting from \code{CHMfactor}, where for backwards compatibility the default behaviour is still to compute the determinant of the Cholesky factor. This exception should be considered \emph{temporary}, hence defensive code will call \code{determinant} with (new) optional argument \code{sqrt} set to \code{TRUE} or \code{FALSE} explicitly, to not rely on the current default value. See \code{help("CHMfactor-class")} for details. \item Generic function \code{diag} gains methods for \code{p?Cholesky} and \code{CHMfactor}. The result is a numeric vector containing the diagonal entries of the diagonal matrix \eqn{D}, as defined in \code{help("Cholesky-class")} and \code{help("CHMfactor-class")}. \item The \code{lu} and \code{qr} methods for class \code{dgCMatrix} now admit an \code{order} argument with value in \code{0:3}, allowing the expert user to choose among all ordering methods made available by the CSparse library. \item \code{solve(, b, sparse = TRUE)} is now handled entirely in C code via \code{cs_spsolve} from the CSparse library. \item New utilities \code{invertPerm}, \code{signPerm}, \code{isPerm}, and \code{asPerm} for computing the inverse and sign of a permutation vector, testing if an integer vector is a permutation vector, and coercing a transposition vector to a permutation vector. \code{invertPerm} is a more general version of the already exported function \code{invPerm}, which is retained as a wrapper around \code{invertPerm} for backwards compatibility. \item The \code{qr.R} method for class \code{sparseQR} gains a \code{backPermute} argument with default \code{FALSE}, for compatibility with \pkg{base}. Function \code{qrR}, which existed primarily to provide a back-permuting option, is retained for backwards compatibility. } } \subsection{Bug Fixes}{ \itemize{ \item \code{x[integer(0), ]} and \code{x[, integer(0)]} now give a \code{generalMatrix} result when \code{x} is a 0-by-0 \code{diagonalMatrix}, for consistency with all other cases of \code{x[seq_len(n), ]} and \code{x[, seq_len(n)]}, where \code{x} is an \code{n}-by-\code{n} triangular, symmetric, or diagonal matrix. \item For \code{x} inheriting from \code{RsparseMatrix}, subassignment of the form \code{x[i, ] <- value} is now correctly distinguished from \code{x[i] <- value}. \item \code{rownames(x[integer(0), , drop = FALSE])} and \code{colnames(x[, integer(0), drop = FALSE])} are now always \code{NULL} and never \code{character(0)}, consistent with the implementation in \pkg{base}. \item Subscript operations on \code{Matrix} now correctly error whenever the formal argument \dots{} is matched, as in \code{x[i, j, drop]}, where \code{x[i, j, drop = drop]} is almost always intended. \item \code{x[i, ]} now correctly drops dimensions when \code{x} is a 1-by-\code{n} \code{Matrix} and \code{i} is \code{TRUE}. \item Methods for \code{solve} now obey the following rules much more strictly: \itemize{ \item \code{solve(a=, b=)} must return a vector. \item \code{solve(a=, b=)} must return a \code{denseMatrix}. \item \code{solve(a=, b=, sparse=FALSE)} must return a \code{denseMatrix}. \item \code{solve(a=, b=, sparse=TRUE)} must return a \code{sparseMatrix}. } resolving some longstanding incompatibilities with \pkg{base}. \cr Note that methods for sparse \code{a} and missing or sparse \code{b} have default \code{sparse = TRUE}, while methods for sparse \code{a} and dense \code{b} have default \code{sparse = FALSE}. \item \code{solve()} now always gives a \code{symmetricMatrix} result. \code{solve()} and \code{solve()} preserve formal positive definiteness, giving a \code{dpoMatrix} and \code{dppMatrix}, respectively. \item The prototype of the \code{Dim} slot of virtual class \code{MatrixFactorization} is now \code{integer(2L)}. Previously it was \code{integer(0L)}, with the result that \code{validObject(new(""))} was always an error. \item The prototype of the \code{L} slot of class \code{sparseLU} is now formally lower triangular, so that \code{validObject(new("sparseLU"))} is not an error. \item The prototypes of the \code{Q} and \code{T} slots of class \code{Schur} are now 0-by-0 \code{dgeMatrix}, so that \code{validObject(new("Schur"))} is not an error. \item \code{BunchKaufman()} now works when argument \code{uplo} (documented to be optional) is missing. \item The validity method for class \code{corMatrix} now tolerates nonfinite elements in the \code{sd} slot. It no longer tolerates nonunit diagonal elements in the \code{x} slot. \item Coercions to \code{corMatrix} now set the diagonal elements of the result to 1, consistent with \code{cov2cor}. \item \code{dimnames(x) <- value} now validates \code{x@Dim} before \code{value} to avoid undefined behaviour in C-level check. \item \code{invPerm(p)} no longer segfaults for \code{p} that are not valid permutation vectors. (\code{invPerm(NA)} was enough to trigger a segfault.) \item \code{chol2inv(x)} now ignores the lower triangular part of \code{x} not inheriting from \code{triangularMatrix}. \item \code{chol2inv(x)} now computes \code{crossprod(solve(x))} instead of \code{tcrossprod(solve(x))} for all formally lower triangular \code{x}. Previously, \code{crossprod} was used only for dense \code{x}. \item \code{rcond(x, norm)} throws a nicer error for \code{x} of length 0. \item Error messages due to invalid \code{norm} in \code{rcond(x, norm)} now refer to the argument as \code{norm} rather than \code{type}. \item \code{rcond(x, norm)} now validates \code{norm} also for \code{x} of class \code{d(sy|sp|po|pp)Matrix}, even if for such \code{x} all valid \code{norm} give the same result. \item \code{which(<[RT]sparseMatrix>, ...)} now gives indices in column-major order in all cases, to be consistent with \code{help("which")}. \item Factorizations inheriting from virtual class \code{LU} are now cached under the name \code{denseLU} or \code{sparseLU}, depending on the nonvirtual class, rather than always under the name \code{LU}. Note that user code should \emph{not} rely on the details of the cache and should instead rely on functions such as \code{lu} to retrieve cached factorizations. \item Errors signaled by \code{as(, "dpoMatrix")} and \code{as(, "dppMatrix")} now clarify that the coercions do not attempt to test for positive semidefiniteness when the matrix is not positive definite. } } \subsection{Misc}{ \itemize{ \item Help pages for matrix factorization classes and methods have been broadly expanded and updated to use consistent notation. \item C code interfacing the CSparse library now checks in more places for failed allocations inside of \code{cs_*()}. \item The length of the \pkg{Matrix} namespace has been reduced by ~15\%. More than 100 unused symbols have been removed. \item The following dependencies, needed only for a small number of \code{Rd} cross references, have been removed: \pkg{MatrixModels}, \pkg{expm}, \pkg{igraph}, \pkg{maptools}, \pkg{sp}, \pkg{spdep}. Links to CRAN and Bioconductor in \file{.Rd} files are preserved throughout. \item \pkg{sfsmisc} has been moved from \code{Enhances} to \code{Suggests}, as \pkg{Matrix} does not formally enhance it by providing methods, etc. \item \pkg{grDevices} and \pkg{datasets} have been added to \code{Imports} and \code{Suggests}, respectively, as \file{NAMESPACE} does import from \pkg{grDevices} and vignettes do load data (albeit \emph{un}conditionally) from \pkg{datasets}. \item Example, test, and vignette code no longer fails when \env{R_DEFAULT_PACKAGES} is set to \code{NULL}, thanks to additional \dQuote{invisible} \code{library} calls in the problematic source files. \item Examples now use \code{requireNamespace} instead of \code{require}, preserving the user search path in more cases. \item Updates to \file{po/*.\{po,pot\}} and \file{inst/po/*} for translators. } } } \section{Changes in version 1.5-4.1 (2023-05-16)}{% hot patch there \subsection{Misc}{ \itemize{ \item Use \code{#ifdef PR18534fixed} to adapt to \R{}'s Lapack header fix for \PR{18534}. } } } \section{Changes in version 1.5-4 (2023-04-02 r3837)}{ \subsection{Deprecated and Defunct}{ \itemize{ \item The following low level coercion utilities, which were previously exported but always \dQuote{hidden} and undocumented, are now deprecated: \code{..2dge}, \code{.C2nC}, \code{.T2Cmat}, \code{.asmatrix}, \code{.dense2sy}, \code{.diag2mat}, \code{.diag2sT}, \code{.diag2tT}, \code{.dsy2dsp}, \code{.dsy2mat}, \code{.dxC2mat}, \code{.m2dgC}, \code{.m2lgC}, \code{.m2ngC}, \code{.m2ngCn}, \code{.m2ngTn}, \code{.n2dgT}, \code{.nC2d}, \code{.nC2l}. \cr The deprecations follow efforts to define more general and more systematic (but still fast) coercion utilities, to allow expert users to bypass S4 dispatch in more cases. The subset of these currently exported is documented under \code{help("fastMisc")}. Deprecation warnings will suggest an appropriate replacement, mostly from that list. \cr It is not always the case that the replacement can be \dQuote{dropped in}, hence users should consult the relevant documentation when changing their code. \item Warnings signaled by coercion methods deprecated in \pkg{Matrix} 1.5-0 now correctly inherit from class \code{deprecatedWarning}. } } \subsection{Bug Fixes}{ \itemize{ \item Defining \code{sequence.default} for \R{} \code{< 4.0.0}, so that \code{kronecker(, )}, \code{kronecker(, )}, and \code{ \%*\% } continue to work there. } } \subsection{Misc}{ \itemize{ \item C-level utilities \code{Matrix_memset()} and \code{Matrix_memcpy()}, both new, are now used in many places instead of API macros \code{Memzero()} and \code{Memcpy()} which never check for overflow. C-level macro \code{AZERO()} is no longer defined. \item C-level macro \code{Calloc_or_Alloca_TO()} now zero-initializes also in the \code{alloca}-using case. \item Replace deprecated \code{Rdefines.h} with \code{Rinternals.h} and move inclusion outside of \code{extern "C"} wrapper in API header \file{inst/include/Matrix.h}. \item Replace \code{sprintf} with \code{snprintf} globally to avoid potential buffer overflows. } } } \section{Changes in version 1.5-3 (2022-11-10 r3772)}{ \subsection{Bug Fixes}{ \itemize{ \item \code{dimScale(x)} with argument \code{d1} missing is no longer an error. (The default value had \code{diag(x, FALSE)} instead of \code{diag(x, names = FALSE)}.) \item \code{(dim|row|col)Scale(x)} is no longer an error for traditional matrices \code{x} without a \code{dimnames} attribute. \item Our \code{cov2cor()} methods now again preserve (symmetrized!) \code{dimnames}, fixing Matrix bug #6783 reported by Ben Bolker. \item \code{colSums()} and friends now always give a \emph{named} result when the marginal \code{Dimnames} are non-\code{NULL}. (Names were \dQuote{forgotten} for \code{diagonalMatrix} and \code{indMatrix} arguments.) \item \code{colSums()} and friends now respect \code{na.rm} when handling \code{diagonalMatrix} with \code{NA} diagonal entries. \item \code{expand()} now \dQuote{copies-on-modify}, no longer duplicating the \code{m*n}-length \code{x} slot in the \code{m == n} case, when it can be used directly. \item \code{lu()}, \code{lu(<0-by-n>)}, and \code{BunchKaufman(<0-by-0>)} now give sensible (0-extent) results, rather than a LAPACK error, for \code{denseMatrix}. } } \subsection{New Features}{ \itemize{ \item \code{Diagonal()} gets a new optional \code{names} argument. \item \code{diag(x) <- value} is now done in C also for \code{[CRT]sparseMatrix}. \item \code{.diagU2N()} gets fast counterpart \code{.diagN2U()}. \item \code{colSums()} and friends are now implemented more efficiently for \code{denseMatrix} and \code{[CRT]sparseMatrix}. Notably, methods for triangular and symmetric matrices no longer go via \code{generalMatrix}, and methods for \code{[CRT]sparseMatrix} now handle nonzero pattern and logical matrices directly (no longer coercing to double, a constraint of the earlier implementation using CHOLMOD). \item \code{determinant()} is now computed via the Bunch-Kaufman factorization. Factorizations are cached in the \code{factors} slot for future reuse. } } \subsection{Misc}{ \itemize{ \item Package \pkg{methods} has been moved from \code{Imports} to \code{Depends}, as suggested in the WRE manual. Now \code{as()} and other basic S4 machinery are available whenever \pkg{Matrix} is attached. This change affects R processes started with environment variable \env{R_DEFAULT_PACKAGES} set to \code{NULL} (or some list not containing \pkg{methods}). \item \file{Simple.R} test for sparse \code{"POSIXlt"} example adapted to latest R-devel always having \code{"zone"} which is character. \item C-level wrappers for LAPACK \code{d..trf} routines gain an argument \code{warn} indicating how to handle \code{info > 0}: \code{warn <= 0} is silent, \code{warn = 1} is a warning, and \code{warn > 1} is an error. In the case of \code{dp[op]trf}, for which \code{info > 0} implies an incomplete factorization, \code{info} is now returned as a length-1 integer. } } } \section{Changes in version 1.5-2 (2022-10-21 r3702)}{ \subsection{Bug Fixes}{ \itemize{ \item C-level functions now \code{PROTECT()} the result of \code{R_do_slot()}, \code{getAttrib()}, \code{mkString()}, etc. in many more (but not yet all) places, resolving many new and some old \code{rchk} warnings. \item \code{lu(x)@L@uplo} is now \code{"L"}, not \code{"U"}, for 0-by-0 and 1-by-1 \code{dgCMatrix} \code{x}. \item The validity methods for classes \code{l[ts]CMatrix} now correctly test for structurally nonzero entries on the wrong side of the diagonal, and fail in that case. This test was previously only performed for \code{d[ts]Matrix}. \item The validity and initialization methods for virtual class \code{sparseVector} are more diligent, i.e., catching more edge cases such as \code{NA} in the \code{length} or \code{i} slot. \item The validity method for \code{corMatrix} now throws a better error when the \code{sd} slot is of type \code{"integer"} rather than \code{"double"}. \item \code{.sparseDiagonal()} now agrees with \code{Diagonal()} when called with no arguments, returning a 0-by-0 (rather than 1-by-1) diagonal \code{Matrix}. \item \code{sparseMatrix(i, j)} with 0-length \code{i} and \code{j} now returns a 0-by-0 matrix rather than throwing a perplexing error. \item \code{sparseMatrix(dims = )} and \code{sparseMatrix(x = )} now produce errors. \item \code{diag(x) <- value} now coerces \code{diagonalMatrix} \code{x} if \code{typeof(value)} is \dQuote{higher} than \code{typeof(x@x)} in the usual hierarchy, for consistency with methods for \code{denseMatrix} and with \code{base::`diag<-`}. \item Methods for \code{kronecker()} no longer ignore the \code{make.dimnames} argument. \item Printing a \code{sparseMatrix} with \code{NA} row or column names is no longer an error. \item Products of two \code{pMatrix} objects \code{x} and \code{y} are now computed correctly. Previously, \code{y \%*\% x} was returned instead of \code{x \%*\% y}! \item Products \code{x \%*\% y} with \code{x} a \code{diagonalMatrix} or \code{indMatrix} and \code{y} a traditional matrix or vector, or with \code{x} a traditional matrix or vector and \code{y} a \code{diagonalMatrix} or \code{pMatrix}, now treat the unclassed argument as a \code{.geMatrix} and return a \code{.geMatrix}, for greater consistency with other products involving one \code{Matrix} and one non-\code{Matrix}. \item Similarly, \code{kronecker(x, y)} with one of \code{x} and \code{y} a \code{Matrix} and the other a traditional matrix or vector now treats the unclassed argument as a \code{.geMatrix}. \item \code{dimnames(solve(x))} is now \code{rev(dimnames(x))} for \code{denseMatrix} \code{x}, consistent with the handling of \code{dimnames} by \code{solve.default}. Methods for \code{sparseMatrix} \code{x} have not been addressed (yet). } } \subsection{New Features}{ \itemize{ \item \code{is.nan(x)} is now implemented for all \code{x} inheriting from virtual class \code{Matrix} or \code{sparseVector}. \item New C-level validity methods for \code{n[ts][CRT]Matrix}, \code{p?Cholesky}, \code{p?BunchKaufman}, \code{Schur}, \code{denseLU}, \code{sparseLU}, and \code{sparseQR}. Notably, in the \code{MatrixFactorization} cases, the following properties are now checked: the dimensions of each factor, the orientation of each triangular (or trapezoidal) factor, and the validity of each permutation vector. \item \code{Diagonal(n=, x=)} now recycles \code{x} of any positive length to length \code{n}. Previously, recycling was supported only for \code{x} of length 1. \item Products involving \code{diagonalMatrix} or \code{indMatrix} have been broadly improved as follows: \itemize{ \item \code{dimnames(A \%*\% B)} is now always \code{c(dimnames(A)[1], dimnames(B)[2])}. \item \code{t?crossprod()} methods involving \code{indMatrix} or its subclass \code{pMatrix} gain a \code{boolArith} argument. \item Numeric and boolean products are always returned as \code{dMatrix} and \code{nMatrix}, respectively, except in a few special cases where the product can be represented as an \code{indMatrix}. (Previously, coercions were skipped when one of the operands was unit diagonal.) \item Products of \code{diagonalMatrix} with dense \code{triangularMatrix} now correctly give a \code{triangularMatrix} result (and without unpacking). \item Products of \code{diagonalMatrix} with \code{[RT]sparseMatrix} now preserve storage, no longer coercing to \code{CsparseMatrix}. \item \code{crossprod(x, y)} no longer requires the product of \code{ncol(x)} and \code{ncol(y)} to be less than \code{2^31} when both \code{x} and \code{y} are \code{indMatrix}. (The new implementation now always gives a \code{dgTMatrix} result, whereas previously the result would typically but not always be a \code{dgCMatrix}.) } \item \code{kronecker(, )} now gives the correct \dQuote{shape} (general, [unit] triangular, symmetric, diagonal) in all cases where it can be known without checking. \item \code{kronecker(<[CR]sparseMatrix>, )} now retains the storage of the first argument, no longer coercing to \code{TsparseMatrix}. \item New exported functions \code{dimScale}, \code{rowScale}, and \code{colScale}, for scaling rows and columns of a \code{[mM]atrix} without losing \code{dimnames} and where appropriate without losing symmetry. } } } \section{Changes in version 1.5-1 (2022-09-12 r3642)}{ \subsection{Bug Fixes}{ \itemize{ \item ASAN-detected bugs fixed in C-level functions \code{Tsparse_as_CRsparse()} (triggered by \code{.T2C(<0-by-0>)}) and \code{pMatrix_validate()} (triggered by \code{as(, "pMatrix")}). } } } \section{Changes in version 1.5-0 (2022-09-09 r3636)}{ \subsection{Deprecated and Defunct}{ \itemize{ \item With a few exceptions, direct coercions to non-virtual subclasses of \code{Matrix} (e.g., \code{dsCMatrix}) have been formally deprecated. For now, these will continue to work as before, but with a warning indicating how to accomplish the desired coercion via virtual classes (e.g., \code{symmetricMatrix}) alone. How such warnings are signaled is controlled by the global option \code{Matrix.warnDeprecatedCoerce}. \describe{ \item{\code{0} or less}{is to be silent.} \item{\code{1}}{is to signal a warning with each deprecated coercion.} \item{\code{2} or greater}{is to signal an error with each deprecated coercion.} \item{\code{NA}}{is to signal a message or warning (see below) with the next deprecated coercion and be silent after that.} } If unset or invalid, then the value of the environment variable \env{R_MATRIX_WARN_DEPRECATED_COERCE} (\code{NA} if unset) is used. This is cached when the \pkg{Matrix} namespace is loaded. \cr Option values are coerced to integer before use. \cr To reduce disruption to existing code, the \code{NA} case signals messages rather than warnings with coercions to the most-used non-virtual subclasses of \code{Matrix}, namely \code{dg.Matrix} and \code{d.CMatrix}. This may change in the future. } } \subsection{Bug Fixes}{ \itemize{ \item Symmetrization of \code{@Dimnames} and \code{dimnames()} now goes through C utility \code{symmDN()} in most places, resolving some earlier inconsistencies. \item Many more validity methods now correctly operate under the assumption that methods for superclasses have already been called, eliminating many redundant checks. \item Validation of \code{@Dim} now looks at type \emph{before} length, avoiding a misleading error message. \item Validation of \code{@Dimnames} now avoids \code{isNewList}, which had allowed an error message suggesting that \code{NULL} is a list. \item Setting a factor on a \code{compMatrix} is now to install the factor itself, not a copy, for efficiency and consistency with the semantics of \code{@factors[[name]] <- value}. \item Long vector support in methods for packing and unpacking \code{denseMatrix}, and others. \item \code{diag<-} incorrectly preserved the class of dense matrices, so that, e.g., \code{`diag<-`(x=, value=-1)} was still a \code{dpoMatrix}. Now the result is always one of the more general \code{.(ge|tr|sy|tp|sp)Matrix}. \item \code{t()} no longer clears the \code{sd} slot. \code{t()} now returns one of the more general \code{dt[rp]Matrix}, rather than preserving class and clearing the \code{perm} slot. \item \code{t()} no longer reverses the \code{Dimnames} slot. Symmetrization of \code{dn <- x@Dimnames} and \code{t(x)@Dimnames} had given different results when \code{dn[[1]]} and \code{dn[[2]]} were non-\code{NULL} and asymmetric. \item \code{isTriangular(x, upper)} had incorrectly returned \code{FALSE} for \code{x} of class \code{triangularMatrix} when \code{upper = TRUE} and \code{x@uplo = "L"} or when \code{upper = FALSE} and \code{x@uplo = "U"}. \code{isTriangular} is now equivalent to \code{isDiagonal} in those cases. \item \code{isSymmetric()} was equivalent to \code{isDiagonal()} for triangular matrices, \emph{not} allowing numerical fuzz via an argument \code{tol}. A \code{tol} argument is now implemented for all subclasses of \code{dMatrix} except for those inheriting from \code{symmetricMatrix} or \code{diagonalMatrix}. \item Methods for \code{isSymmetric} now also look at \code{Dimnames} and \code{names(Dimnames)}, following \code{isSymmetric.matrix} from \pkg{base}. See also New Features. \item \code{band(x, -k, k)} for sparse \code{x} used \code{isSymmetric(x)} (which tolerates numerical fuzz) to test for symmetry, resulting in loss of information in some cases. Now it tests that \code{x} inherits from \code{symmetricMatrix}, and so returns \code{symmetricMatrix} in fewer cases. \item \code{triu(x, k)} and \code{tril(x, k)} incorrectly required \code{k <= m} (instead of \code{k <= n}), for \code{m}-by-\code{n} sparse \code{x}. They now accept all \code{k} from \code{-m} to \code{n}, with fewer errors in the \code{m < n} case. \item \code{crossprod(, )} and similar now work again (optional \code{boolArith} was not passed on), fixing Matrix bug #6766 by David Cortes. Ditto for \code{tcrossprod()}, where the old result was even wrong when it had \dQuote{worked}, before Matrix 1.2-0. \item \code{as(, "nMatrix")} can now be sparse \emph{or} dense, going via \code{Matrix()}, for greater consistency with coercions to \code{dMatrix} and \code{lMatrix}. (Previously, the result was always an \code{ngTMatrix}.) \item \code{forceSymmetric(<[RT]sparseMatrix>)} are now more efficient, returning symmetric \code{[RT]sparseMatrix} without intermediate coercions to \code{CsparseMatrix}. \item \code{tcrossprod(a, b)} for unit triangular sparse matrices now works correctly. \item \code{!} is no longer an error in the 0-by-0 unit diagonal case. \item Coercions among \code{[CRT]sparseMatrix} preserve the \code{factors} slot in more cases. \item Coercions of overallocated \code{l.TMatrix} to \code{denseMatrix} or \code{CsparseMatrix} now give \code{TRUE} instead of \code{NA} in the \code{NA || TRUE} case, following conventional logic. \item Methods for unpacking and indexing \code{packedMatrix} and for coercing from \code{[CRT]sparseMatrix} to \code{denseMatrix} now check more consistently for overflow of \code{R_XLEN_T_MAX}. \item \code{solve(, )} is removed from the method list. It had allowed infinite recursion, e.g., with \code{solve(new("dgeMatrix"), NULL)}. \item \code{is.na()} gave \code{TRUE} where the \code{x} slot had \code{NA}. Now the result is always a zero matrix. \item \code{is.na(<.t[rp]Matrix>)} and \code{is.infinite(<.t[rp]Matrix>)} ignored the \code{diag} slot, behaving always as though \code{diag == "N"}. They now give \code{FALSE} on the diagonal in the \code{diag != "N"} case. \item Now only \dQuote{nontrivial} matrix elements determine whether \code{is.na()} is an \code{ndenseMatrix} or an \code{nsparseMatrix}. \item \code{is.na()} coerced to \code{lMatrix}. This unnecessary step is avoided now, saving a potentially nontrivial allocation. \item \code{solve(, b)} coerced the first argument to \code{dgeMatrix} when \code{b} was not a \code{ddenseMatrix} or traditional \code{matrix}. This unnecessary step is avoided now, so that specialized methods for \code{d(tr|sy|po|tp|sp|pp)Matrix} are used where possible (including for \code{b} inheriting from \code{[ln]denseMatrix}, \code{sparseMatrix}, or \code{numLike}). \item \code{`dim<-`(x, -x@Dim)} is now an error, no longer yielding an invalid \code{Matrix} object. \item \code{`dim<-`(x, x@Dim)} is now faster, returning \code{x} without allocation in all cases. \item \code{`dim<-`(x, value)} gives a better error when \code{value} contains \code{NA} or elements exceeding \code{INT_MAX}. \item \code{`dim<-`(, value)} is now an \code{RsparseMatrix}, rather than a \code{TsparseMatrix}. \item For consistency with other methods, \code{symmpart()} now always inherits from both \code{dMatrix} and \code{symmetricMatrix}, and \code{skewpart()} now always has symmetric \code{Dimnames}. \item Zeros on the diagonal of \code{skewpart(<[CRT]sparseMatrix>)} are now \emph{structural}. \item \code{as(, "(vector|matrix|[dl]Matrix)")} and \code{nnzero()} now correctly treat \code{NA} in the \code{x} slot as \code{TRUE}. \item \code{as(<[nl].TMatrix>, "dMatrix")} now correctly handles the overallocated case: data for each unique \code{[i,j]} pair are aggregated logically (\code{x1 || ... || xn}) rather than arithmetically (\code{x1 + ... + xn}), so that elements of the result are restricted to the set \code{c(0, 1, NA)}. This bug had also affected the result of \code{sum(<[nl].TMatrix>)}. \item \code{dimnames(as(x, "matrix"))} is now \code{NULL} for \emph{all} \code{x} inheriting from \code{Matrix}, when \code{x@Dimnames} is the trivial \code{list(NULL, NULL)}. \item \code{.bdiag()} no longer propagates names to the \code{Dim} slot of the result. \item \code{as(, "denseMatrix")} now correctly propagates \code{names} to the result. \item \code{as(, "lMatrix")} no longer drops non-structural zeros, for greater consistency with analogous coercions. \item \code{Matrix(x, doDiag)} now behaves as documented for diagonal matrices \code{x} with asymmetric \code{dimnames}, returning a \code{diagonalMatrix} when \code{doDiag = TRUE}, rather than a \code{triangularMatrix}. \item Matrix() now works for \code{n != 2}. \item \code{Matrix()} now works for vector lengths other than 1, no longer giving an error about length mismatch when neither of \code{nrow} and \code{ncol} are supplied. \item \code{Matrix(, doDiag = FALSE)} is now a \code{symmetricMatrix}, not a \code{diagonalMatrix}, matching the documentation of \code{doDiag}. \item \code{Matrix(<.geMatrix>, sparse = TRUE, forceCheck)} and \code{Matrix(<.g[CRT]Matrix>, sparse = FALSE, forceCheck)} now respect \code{forceCheck = FALSE} by always returning \code{generalMatrix}, i.e., \emph{not} testing for symmetric or triangular structure. \item \code{Matrix(0, nrow, )}, \code{Matrix(0, , ncol)} now throw (correct) errors for \code{nrow}, \code{ncol} in the interval \eqn{[0,1)}, consistent with \code{base::matrix()}. \item \code{sparseDefault()} now counts zeros without coercing to \code{matrix}, making \code{Matrix(, sparse = NULL)} much more efficient. \item Methods for group generic \code{Math} no longer preserve \code{x@diag == "U"} or lose \code{x@Dimnames} when \code{f(0) == 0} and \code{f(1) != 1}. (The former happened for \code{triangularMatrix} \code{x} and the latter for \code{diagonalMatrix} \code{x}.) \item \code{image(Z)} for a completely \dQuote{empty} (all 0) \code{sparseMatrix} works again (?!). \item \code{x[i, ] <- value} and \code{y[, j] <- value} is now an error in more cases for \code{m}-by-0 \code{CsparseMatrix} \code{x} and 0-by-\code{n} \code{CsparseMatrix} \code{y}. In these cases, subassignment gave a (formally) invalid result. \item \code{chol()} now calls the underlying C-level routine exactly once. Previously, it was called an extra time in order to test for positive definiteness, with the result thrown away (!). Hence these methods should become approximately two times faster. \item \code{dimnames(chol(x))} is identical to \code{dimnames(x)} in all cases, now even when \code{chol(x)} is constructed from a cached \code{MatrixFactorization}, for greater consistency with \code{base::chol.default()}. \item \code{chol()} no longer looks at \code{Dimnames} when testing for symmetry. \item \code{lu()} no longer returns an invalid \code{sparseLU} object in the lower triangular case. \item \code{lu(x)} had sometimes incorrectly cached its return value as element \code{"lu"} (rather than \code{"LU"}) of \code{x@factors}. Now it is always \code{"LU"}. \item \code{"Compare"} operators, e.g., \code{a > b}, \code{x != y}, now work correctly in more dense unitriangular and sparse 0-extent cases. \item \code{!} is now always an \code{nMatrix}, never an \code{lMatrix}. \item \code{!} and \code{which()} now correctly handle \code{NA} as \code{TRUE}. \item \code{anyNA()} had incorrectly returned \code{anyNA(.@x)} in many cases, giving false positives for some \code{.(tr|sy)Matrix} and \code{ndenseMatrix}. Now methods respect the \dQuote{rules} of these classes. \item The boolean arithmetic product \code{A \%&\% B} and e.g., \code{crossprod(A, B, boolArith=TRUE)} now should behave as if \code{drop0(A)} and \code{drop0(B)} were used, i.e., for formally sparse matrices, the boolean product results should be stable with respect to non-structural vs structural zeros. \item \code{t()} now retains the \code{factors} slot, avoiding recomputation. \item \code{qr()} no longer segfaults in some cases, but now warns about \dQuote{Out of memory} and stops, fixing Matrix bug #6610 reported by Benjamin Tyner. \item Fixed \code{ \%*\% } possible memory corruption, visible via valgrind, fixing Matrix bug #6726 reported by David Cortes. \item Fixed the (quite \emph{long standing}) Matrix bug #6777, reported by Manuel Koller: \code{tcrossprod(, <[dln]sCMatrix>)} has been wrong in some cases. } } \subsection{New Features}{ \itemize{ \item \code{KhatriRao()} gets new \code{sparseY = TRUE} option and also works for more \code{Matrix} classes. \item Virtual class \code{packedMatrix} gains methods for \code{pack}, \code{unpack}, \code{isSymmetric}, \code{isTriangular}, and \code{isDiagonal} implemented in C, replacing those defined for many subclasses individually. \item New virtual class \code{unpackedMatrix} containing \code{denseMatrix} _without_ \code{packedMatrix}, with methods for \code{pack}, \code{unpack}, \code{isSymmetric}, \code{isTriangular}, \code{isDiagonal}, \code{t}, \code{diag}, and \code{diag<-} implemented in C, replacing those defined for many subclasses individually. \item \code{isTriangular} and \code{isDiagonal} are now implemented in C also for \code{[CRT]sparseMatrix} and standard \code{matrix}. \code{isSymmetric} is now implemented in C for all \code{denseMatrix} and all \code{[CRT]sparseMatrix}, though these C routines are currently only called when testing for \emph{exact} symmetry (always for \code{[ln]Matrix}, only when \code{tol = 0} for \code{dMatrix}). \item Methods for \code{isSymmetric} gain an argument \code{checkDN = TRUE} indicating whether symmetry of \code{Dimnames} should be checked. For backwards compatibility and consistency with \code{isSymmetric.matrix} from \pkg{base}, the actual condition is \code{checkDN && check.attributes}. \item \code{isTriangular(x, upper)} now has a \code{kind} attribute \emph{if and only if} \code{x} is triangular and \code{upper} is \code{NA}. \item \code{diag() <- value} now behaves like \code{diag() <- value}, supporting coercions depending on \code{typeof(value)}, consistent with \code{diag<-} from \pkg{base}. \item \code{pack} and \code{unpack} are now identity functions for \code{packedMatrix} and \code{unpackedMatrix} arguments, respectively (previously an error). \code{pack(<.geMatrix>)} (previously an error) now behaves as \code{pack()}, i.e., by checking for symmetry or triangularity before packing. \code{unpack()} now works and is equivalent to \code{as(, "unpackedMatrix")}, with result inheriting from \code{.(ge|tr|sy)Matrix}, as appropriate. \item Many more validity methods implemented in C, for efficiency, including methods for \code{Matrix}, \code{compMatrix}, \code{diagonalMatrix}, \code{indMatrix}, \code{pMatrix}, \code{corMatrix}, \code{[liz]Matrix}, and \code{ndenseMatrix}. \item The validity method of \code{dppMatrix} now follows the validity method of \code{dpoMatrix}, requiring non-negative diagonal elements. \item Validation of \code{@Dimnames[[i]]} now tolerates vector types other than character, which are coerced to character in C via the new \code{R_DimNames_fixup()}, for greater consistency with base \code{matrix()}. \item \code{band(x, k1, k2)} is optimized further for both dense and sparse \code{x}, returning \code{triangularMatrix}, \code{symmetricMatrix}, and \code{packedMatrix} in more cases. \item \code{band()} is now implemented also for \code{diagonalMatrix} (only \code{tri[ul]()} worked before). \item Coercions \code{.ge<->.g[CRT]}, \code{.t[rp]<->.t[CRT]}, \code{.s[yp]<->.s[CRT]}, and \code{..[CRT]<->matrix} are now fully implemented and optimized, with minimal intermediate allocations. These (and others) no longer rely on CHOLMOD, which had handled integer types as double and required preprocessing in many cases (with \code{diagU2N()}, etc.). \item Fixes in group methods (e.g., \code{>}, \code{&}, \code{|}), notably for matrices inheriting from class \code{symmetricMatrix}, \code{triangularMatrix}, \code{lMatrix}, or \code{nMatrix}. \item \code{as.vector}, \code{as.numeric}, and \code{as.logical} are now implemented for all \code{Matrix}. \item Subassignment to \code{indMatrix} is no longer prohibited, now going via \code{TsparseMatrix}. \item \code{indMatrix} gains methods for \code{isTriangular}, \code{isDiagonal}, \code{diag}, \code{diag<-}, \code{band}, \code{tri[ul]}, and \code{forceSymmetric}. It also gains coercions to more virtual classes (notably \code{denseMatrix}) and a coercion to \code{pMatrix}. \item \code{solve(, )} now works in all cases. \item \code{determinant()} is now much faster in the positive definite case, no longer going via \code{dgeMatrix}. \item \code{diag(<[CRT]sparseMatrix>)} is now done in C and is highly optimized in the \code{.[ts][CR]Matrix} case. \item \code{symmpart} and \code{skewpart} are now done in C for all \code{denseMatrix} and all \code{[CRT]sparseMatrix}. Both now more faithfully preserve the \dQuote{storage} of their argument. (Previously, \code{symmpart()} was an \code{unpackedMatrix}, and \code{(symm|skew)part(<[RT]sparseMatrix>)} was a \code{CsparseMatrix}.) \item \code{as(, "([dln]?dense|[dlnCRT]?sparse)Matrix")} are now fully and more consistently implemented. In the vector case, the result is now always a \code{length}-by-1 \code{generalMatrix}. In the matrix case, structure is now always examined, hence the result is a \code{symmetricMatrix} or \code{triangularMatrix} in more cases. \item \code{Matrix()} now works for classes other than \code{table}. \item \code{lu()} and \code{lu()} now behave more consistently. In the diagonal, upper triangular, and unit lower triangular cases, the result is obtained \dQuote{directly}, i.e., without pivoting. In the non-unit lower triangular case, it is obtained with pivoting. (Previously, pivoting was never done for \code{dtCMatrix} and always done for \code{dt[rpRT]Matrix} and \code{ddiMatrix}.) \item \code{lu(x)} now caches its return value also for all \code{ds.Matrix} \code{x} (by default). \item \code{readMM()} now warns if the number of entries found is less than number reported in the header. \item \code{x[i]} now works for \code{nMatrix} \code{i}, just as for \code{lMatrix} \code{i}. This supports constructions such as \code{x[is.na(x)]}, where the logical operation produces an \code{nMatrix} because it is never \code{NA}. } } \subsection{Misc}{ \itemize{ \item \code{AZERO()} and friends gain an argument specifying a zero constant (0 for \code{int} arrays, 0.0 for \code{double} arrays). \item C-level utilities \code{(R_)?[gs]et_factors()} have been renamed \code{(R_)?[gs]et_factor()}, as they only ever get and set \emph{one} factor. \item The signature of \code{set_factor()} has been changed to match other \code{set*()} functions: to \code{(object,name,value)} from \code{(object,value,name)}. \item For clarity, \code{set_factor()} now returns \code{void} and is used like other \code{set*()} functions (i.e., for its side effect). The R interface is unchanged: \code{R_set_factor()} continues to return the value being set. \item C-level utilities \code{make_[di]_matrix_(triangular|symmetric)()}, \code{packed_to_full_(double|int)()}, \code{full_to_packed_(double|int)()}, and \code{install_diagonal(_int)?()} are replaced by safer, more consistently named ones. Previous versions allowed integer overflow. \item C-level utilities \code{dup_mMatrix_as_d?geMatrix()} are replaced by the more general \code{dense_as_general()}, which takes arguments controlling memory allocation and the \dQuote{kind} of the \code{.geMatrix} result. \item New C-level utility \code{DimNames_is_symmetric()} with R interface \code{isSymmetricDN()}, which should be used consistently to test for symmetry of \code{[dD]imnames}. Note that these are intended to behave consistently with \code{symmetricMatrix_validate()}, by allowing, e.g., \code{list(NULL, nms)}, but not, e.g., \code{list(A = NULL, B = nms)}. \item Coercions to \code{triangularMatrix} and \code{symmetricMatrix} are now almost all inherited from \code{Matrix}, whose methods simply call \code{tri[ul]()} and \code{forceSymmetric()} if \code{isTriangular()} and \code{isSymmetric()}, respectively, return \code{TRUE}. \item Many of the exported \code{.*2*} utilities have been redefined as aliases or wrappers of new, more general functions (see below). These not-yet-deprecated functions have been centralized in \file{R/denseMatrix.R} and \file{R/sparseMatrix.R}. \item New C-level utilities \code{R_(dense|sparse)_as_kind()} for coercion from one \dQuote{kind} to another; \code{R_(dense|sparse)_as_general()} for coercion from triangular and symmetric to general; \code{R_(dense|sparse)_band()} for coercion to triangular (and other banded); \code{R_(unpacked*|packed*|sparse)_force_symmetric()} for coercion to symmetric; \code{R_(dense|sparse)_as_(sparse|dense)()} for coercion between dense and sparse of the same \dQuote{kind} and \dQuote{structure}; \code{R_diagonal_as_sparse()} for coercion from \code{diagonalMatrix} to any \code{[CRT]sparseMatrix}; \code{R_(dense|sparse|geMatrix)_as_(matrix|vector)()} for coercion to base matrix and vector; and \code{tCRsparse_as_RCsparse()} for the idioms \code{as(t(<[CR]sparseMatrix>), "[RC]sparseMatrix")}. These all have not-yet-exported R wrappers. \item \code{indTri()} and \code{indDiag()} now in C, with a new argument \code{packed} for efficiently indexing \code{packedMatrix}. \code{indDiag()} now behaves sensibly in the \code{n = 0} case. \item \code{.M.kind()}, \code{.M.shape()}, and (new) \code{.M.repr()} are now done in C via \code{R_check_class_etc()}, requiring a class definition only in \dQuote{rare} cases. } } } \section{Changes in version 1.4-1 (2022-03-21 r3446)}{ \subsection{Bug Fixes}{ \itemize{ \item \code{diag(x)} methods now mostly also keep \code{names} from \code{dimnames(x)} by default and obey \code{names=*} more generally. } } \subsection{New Features}{ \itemize{ \item New virtual class \code{packedMatrix} containing packed (dense) symmetric and triangular matrices. Methods for subscripting, including \code{diag()}, notably keeping names by default and for \code{t()} which are memory efficient, i.e., do not work via unpacking, thanks to Mikael Jagan. \item New \code{dmperm()} implementing a Dulmage-Mendelsohn decomposition, thanks to the persistency of Mauricio Vargas (@uc.cl). \item Export more low-level conversion utilities: \code{.n2dgT}, \code{.m2ngCn}, \code{.m2ngTn}. \item Provide some matrix multiplication methods for \code{"RsparseMatrix"}. } } \subsection{Misc}{ \itemize{ \item Our C sources now use \code{R_Calloc()}, \code{R_Free()} etc, instead of the shorter versions without 'R_'. Consequently, we get closer to \code{STRICT_R_HEADERS}. Also, include \code{} for \code{DBL_EPSILON}. \item \code{PROTECT()} 3 more; as from \samp{rchk} for Matrix 1.4-0. \item Slightly better patch notably for Windows, for \file{src/SuiteSparse_config/SuiteSparse_config.h} \item Fix to continue working for \R{} 3.5.0 and newer, providing \code{tryInvokeRestart()} for older versions of \R{}, thanking Michael Chirico for the heads up. \item Modified \code{AZERO()} to work with \code{R_xlen_t} and new \code{AZEROs()} for \code{size_t}; other tweaks to evade \code{-Wconversion} warnings. } } } \section{Changes in version 1.4-0 (2021-12-08 r3419)}{ \subsection{Bug Fixes}{ \itemize{ \item Update many \file{src/*.c} preventing integer overflow in \dQuote{pointer} and index computations for large (dense) matrices; prompted by Dario Strbenac's post to R-devel.% June 7, "dgTMatrix Segmentation Fault" \item \code{sparse.model.matrix(.., contrasts.arg = <.. ddiMatrix ..>)} now works correctly, fixing R-forge Matrix bug #6673 by Davor Josipovic. \item \code{sparse.model.matrix(..)} now also works in cases the contrast matrix has become a \code{"denseMatrix"}; e.g., in a case using \code{poly(.)} in the formula; now works correctly, fixing R-forge Matrix bug #6657 and useful suggestions by Nick Hanewinckel. \item Fixed the internal \code{attr.all_Mat()} auxiliary for \code{all.equal()}, notably for the case when exactly one of the matrices is a base \code{matrix}. \item Fixed long-standing bug in the \code{rbind2()} method for logical dense matrices, specifically \code{"lgeMatrix"}, thanks to the notice by Aaron Lun. \item fix leak in C-level \code{Csparse_to_dense()} thanks to Bill Dunlap in \R{}'s \PR{18204} and \code{install_lu()} called from \code{solve()} in \PR{18206}. \item fix leak in crossprod(), thanks to report and patch in \PR{18205} by Bill Dunlap. \item \code{band(M, k1, k2)} now also works when \code{k1 * k2} is larger than 2^31-1, the maximal integer, fixing R-forge Matrix bug #6743 by Ariel Paulson. Further, it works when \code{M} is a sparse \code{"symmetricMatrix"} but the band is not symmetric, \code{k1 != -k2}. \item fix leak in C-level code for \code{cbind(m1,m2)} or \code{rbind(*)} when \code{m1} is \code{"n.Csparse"} and \code{m2} is not, thanks to Bill Dunlap's diagnosis and patch in \R{}'s \PR{18210}. \item \code{sparseVector(i=integer(), length=2^33)} now does show/print, after fixing a bug in the \code{head()} method for \emph{empty} sparseVectors. Reported by David Cortes as Matrix bug #6745. \item inverting or solving \code{dsCMatrix} no longer catches C level warnings too early which would not free, but rather leak memory; thanks to Bill Dunlap's analysis and patch in \R{}'s \PR{18214}. Additionally, such warnings and error are \code{message()}d when \code{getOption("Matrix.verbose")} is \code{ >= 1}. \item \file{test-tools-1.R}: \code{Sys.memGB()} can no longer use \code{memory.limit()} on Windows; no returns \code{NA.value = 2.10201} in such cases. \item \code{ss <- [i]} gave an invalid sparseVector \code{ss} as \code{ss@i} was not necessarily sorted; thanks to a report by Quran Wu. \item \code{as(, "generalMatrix")} and similar, sometimes did \emph{not} use (C-level) \code{symmetric_Dimnames()} etc; report (to \R{}'s \PR{18250} by Mikael Jagan); fixed all on C level. As a consequence, you will now see \emph{more} preserved dimnames after matrix transformations or operations which involved symmetric matrices. \item \code{as(, "matrix")} no longer loses dimnames, thanks to Mikael Jagan's report as Matrix bug #6751. } } \subsection{Misc}{ \itemize{ \item No longer include \file{Rdefines.h} as it is somewhat deprecated. } } } \section{Changes in version 1.3-4 (2021-05-24 r3392)}{ \subsection{Misc}{ \itemize{ \item Update \code{matrix(, n,m)} in \file{tests/*} to work with \command{R-devel CMD check --as-cran} } } } \section{Changes in version 1.3-3 (2021-05-01 r3390)}{ \subsection{Deprecated and Defunct}{ \itemize{ \item \code{cBind()} and \code{rBind()} are now defunct: simply use \code{cbind()} and \code{rbind()} instead. } } \subsection{Dependency}{ \itemize{ \item For now revert to \code{R (>= 3.5.0)} dependency to accomodate users on older R installations. } } \subsection{Bug Fixes}{ \itemize{ \item Fixed a thinko (in 1.3-2): Now direct coercion from \code{"ddiMatrix"} to \code{"dgCMatrix"}, and hence, e.g., \code{as(Matrix(1, sparse=TRUE), "dgCMatrix") now works.} \item Fixed error message in multiplication. \item Fixed long-standing bug in \code{R[,j] <- v} when \code{R} is "Rsparse*", R-forge Matrix bug #6709 by David Cortes. \item \file{./include/cholmod.h} and \file{./include/Matrix_stubs.h} needed updating from SparseSuite update; R-forge Matrix bug #6714 by Kasper Kristensen (TMB pkg). \item \code{as.matrix()} and \code{as.array()} now work for \code{"sparseVector"}s as expected; see Matrix bug #6708. \item \code{M[,]} (and similar) now work as in base \R{}; R-forge Matrix bug #6720 by David Cortes. \item \code{-S} now works also when \code{S} has no `factors` slot. It signalled an error, e.g., for sparse triangular matrices \code{S}; R-forge Matrix bug #6656, reported by Chun Fung (Jackson) Kwok. \item \code{M*2} and similar no longer keep cached factorizations (in `factors` slot), but drop them via internal new \code{.empty.factors()}. R-forge Matrix bug #6606, reported by Tomas Lumley. \item removed the nowhere used (and unexported but still active) class union \code{"Mnumeric"} which actually trickled into many base classes properties. Notably would it break validity of \code{factor} with a proposed change in validity checking, as factors were also \code{"Mnumeric"} but did not fulfill its validity method. Similarly removed (disabled) unused class union \code{"numericVector"}. \item removed a few duplicated \code{.alias{.}} from \file{man/*.Rd}. } } \subsection{Misc}{ \itemize{ \item translation updates (of outlines only); finally added Italian (by Daniele Medri) to svn; updated French (by Philippe Grosjean), forgotten (R part of) Korean. New Lithuanian translations by Gabriele Stupuriene & Rimantas Zakauskas. \item In internal \code{diagOdiag()} method, no longer use \code{matrix(x, n,n)} when \code{x} is longer than n*n. \item Update tests/*.R to future \code{matrix(x, n,k)} warning in more mismatch cases. \item Eliminating the need for \file{ftp://*}, add the very small \code{jgl009} MatrixMarket example to our \file{external/} files. } } } \section{Changes in version 1.3-2 (2021-01-05 r3362)}{ \subsection{Bug Fixes}{ \itemize{ \item \code{rankMatrix()} tweaks for the singular values based methods, notably \code{method = "maybeGrad"}. \item \code{as(new("dtCMatrix", diag="U"), "matrix")} now works, as C-level \code{diagU2N()} now also works for 0-dimensional triangular matrices; this also fixes a subsetting (\dQuote{indexing}) bug of such 0-dimensional matrices, thanks to a report by Aaron Lun. \item logical subsetting of 0-dim. (diagonal/triangular) matrices fixes. \item The new \code{FCONE} macros added for newer Fortran/C compiler combinations are now defined back compatibly with R >= 3.6.0. \item \code{chol()} now works. \item \file{rchk}: fix potentially un\code{PROTECT}ed vars in \file{src/dsyMatrix.c} } } } \section{Changes in version 1.3-1 (2020-12-23 r3352)}{ \subsection{Bug Fixes}{ \itemize{ \item \code{rankMatrix(, method="qr.R")} no longer assumes non-negative diagonal entries of the \eqn{R} matrix. } } } \section{Changes in version 1.3-0 (2020-12-15 r3351)}{ \subsection{Significant User-Visible Change}{ \itemize{ \item \code{Matrix(*, doDiag=TRUE)} where \code{doDiag=TRUE} has always been the \emph{default} is now obeyed also in the sparse case, as all \code{"diagonalMatrix"} are also \code{"sparseMatrix"}. \code{Matrix(0, 3,3)} returns a \code{"ddiMatrix"} instead of a \code{"dsCMatrix"} previously. The latter is still returned from \code{Matrix(0, 3,3, doDiag=FALSE)}, and e.g., \code{.symDiagonal(3,pi)}. Also a triangular matrix, e.g., \code{"dtrMatrix"} is detected now in cases with \code{NA}s. This is both a bug fix \emph{and} an API change which breaks code that assumes \code{Matrix(.)} to return a \code{"CsparseMatrix"} in cases where it now returns a \code{"diagonalMatrix"} (which does extend \code{"sparseMatrix"}). } } \subsection{New Features}{ \itemize{ \item Subassignment to \code{"diagonalMatrix"} now returns sparse \code{"triangularMatrix"} more often; also (sparse) \code{"symmetricMatrix"}. \item \code{nearPD()} gets new option: If \code{base.matrix = TRUE}, the resulting \code{mat} component is a \pkg{base} \code{matrix}, as often used desired when \code{nearPD()} is used outside the \pkg{Matrix} package context. \item Factored out new \code{qr2rankMatrix()} utility from \code{rankMatrix()}. \item New \code{BunchKaufman()} method. \item Added \code{wrld_1deg} sparse matrix example to \emph{distributed} version of \pkg{Matrix} (no longer excluding it via \file{.Rbuildignore}). \item New (simple) \code{mat2triplet()} function to be used instead of \code{summary()} in code. \item Internal \code{.diag2tT()} gains new option \code{drop0 = TRUE} and hence now by default drops zero diagonal entries. Consequently, e.g., \code{as(, "CsparseMatrix")} now drops such zeros, too. \item Updated the crucial underlying C libraries from SuiteSparse, from 4.2.1 to 5.7.1 (from 2020-02-20), visible in \code{.SuiteSparse_version()} . \item \code{sparseMatrix()} gets new argument \code{repr = "C"}, superseding the (now deprecated) \code{giveCsparse = TRUE}. Allows to return \code{"RsparseMatrix"} matrices. Similarly, \code{rsparsematrix()}, \code{fac2sparse()} and \code{fac2Sparse()} get the new \code{repr} argument and their \code{giveCsparse} is deprecated, sometimes only informally for now.% no deprecation warning yet \item \code{sparse.model.matrix()} gets option \code{sep = ""}, with, e.g., \code{sep = ":"} allowing to get easier column names; from R-forge Matrix (non-)bug #6581, by Vitalie Spinu. } } \subsection{Bug Fixes}{ \itemize{ \item \code{rankMatrix(, method="qr")} now returns \code{NA} (or \code{NaN}) instead of signalling an error in the case the sparse \eqn{Q R} decomposition gave \code{NA}s in \code{diag(R)}. \item Coercion (\code{as(., .)}) from e.g., \code{"lsyMatrix"} to \code{"CsparseMatrix"} silently made asymmetric dimnames symmetric, as did the \emph{internal} \code{forceCspSymmetric(*, dimNames)} which may be called from \code{forceSymmetric()}. \item Adapt code to new Fortran requirements of passing length of character arguments, thanks to Brian Ripley. \item (R-forge Matrix bug #6659, reported by Georg Kindermann): \code{[i] <- val} bug fixed. \item (R-forge Matrix bug #6666, reported by Ezra Tucker): \code{which(, array.ind=TRUE)} thinko fixed. \item For R-devel Dec 4, 2020: adapt all.equal() check of sparse matrix images (which contain panel functions with environments ..). \item tried fixing warning \emph{'cholmod_factorize_p' accessing 16 bytes in a region of size 8 [-Wstringop-overflow=]} in \file{src/dsCMatrix.c} (in two places); seen by pre-release-gcc11 compilation. } } } % \section{Changes in version 1.2-18 (2019-11-26, manually picked from svn)}{ \subsection{Bug Fixes}{ \itemize{ \item Fix last(?) \code{PROTECT()} warning found by \command{rchk} in \file{src/dense.c}'s \code{ddense_skewpart()}. \item \code{as(m, "dgTMatrix")} does not lose \code{dimnames} anymore when \code{m} is a (traditional) \code{matrix}. \item \code{M[logical(0), ]} now has dimension \eqn{0 x k} for sparse \code{M} as for base matrices. \item \code{log(M, base)} (the 2-argument version of \code{log()}) wrongly gave the result for \code{base = exp(1)}, i.e., the 1-argument default. \item \file{test-tools-Matrix.R}: \code{Qidentical()} no longer assumes \code{class()} to be of length 1. \item \file{test-tools-1.R}: provide bug-fixed \code{canCoerce()} in old R versions. } } } \section{Changes in version 1.2-17 (2019-03-20, svn r3294)}{ \subsection{New Features}{ \itemize{ \item (none) } } \subsection{Bug Fixes}{ \itemize{ \item Fix new \code{PROTECT()} warnings (bugs?) found by \command{rchk}. \item Provide \code{isFALSE()} for \R{} < 3.5.0 as now need it for sparseMatrix printing. } } } \section{Changes in version 1.2-16 (2019-03-04, svn r3291)}{ \subsection{New Features}{ \itemize{ \item regression tests depending on \code{sample()} now are future proof reproducible, via \code{RNGversion(.)}. \item give information about #\{rows\} and #\{columns\} that are suppressed in print()ing if the matrix is larger than \code{max.print}. } } \subsection{Bug Fixes}{ \itemize{ \item \code{data()} no longer attaches \pkg{Matrix} to the search path. \item \code{"Ops"} group methods, i.e., "Arith", "Compare" & "Logic", now should all work with 0-extent matrices as well, thanks to bug reports by Aaron Lun, University of Cambridge. \item when printing and formatting sparse matrices, see \code{formatSpMatrix()}, the \code{maxp} option, e.g., from \code{getOption("max.print")}, is \dQuote{rounded up} to 100, as very small values are very rarely appropriate. } } } \section{Changes in version 1.2-15 (2018-08-20, svn r3283)}{ \subsection{New Features}{ \itemize{ \item \code{image()} gets new optional argument \code{border.color}. } } \subsection{Bug Fixes}{ \itemize{ \item \code{image(Matrix(0, n,m))} now works. } } } \section{Changes in version 1.2-14 (2018-04-08, svn r3278)}{ \subsection{New Features}{ \itemize{ \item German translation updates. } } \subsection{Bug Fixes}{ \itemize{ \item one more \code{PROTECT()}. } } } \section{Changes in version 1.2-13 (2018-03-25, svn r3275)}{ \subsection{New Features}{ \itemize{ \item Faster \code{as(, "sparseMatrix")} and coercion \code{"dgCMatrix"}, \code{"ngCMatrix"}, etc, via new direct C \code{matrix_to_Csparse()} which does \emph{not} go via \code{"dgeMatrix"}. This also works for large matrices \code{m}, i.e., when \code{length(m) >= .Machine$integer.max}. Also provide low-level \R{} functions \code{.m2dgC()}, \code{.m2lgC()}, and \code{.m2ngC()} for these. } } \subsection{Bug Fixes}{ \itemize{ \item \code{cbind(NULL,)} no longer return \code{NULL}; analogously for \code{rbind()}, \code{rbind2()}, \code{cbind2()}, fixing very long standing typo in the corresponsing \code{cbind2()} and \code{rbind2()} methods. \item The deprecation warning (once per session) for \code{cBind()} and \code{rBind()} finally works (fixing a simple thinko). \item \code{cbind()} and \code{rbind()} for largish sparse matrices no longer gives an error because of integer overflow (in the default case where \code{sparse} is not been specified hence is chosen by a \code{nnzero()} based heuristic). \item \code{.symDiagonal(5, 5:1)} and \code{.trDiagonal(x = 4:1)} now work as expected. \item \code{Sp[i]} now is much more efficient for large sparse matrices \code{Sp}, notably when the result is short. \item \code{[ ]} now also gives the correct answer when the result is \dQuote{empty}, i.e., all zero or false. \item large \code{"dspMatrix"} and \code{"dtpMatrix"} objects can now be constructed via \code{new(*, Dim = *, x = *)} also when \code{length(x)} is larger than 2^31 (as the C internal validation method no longer suffers from integer overflow). \item More \samp{PROTECT()}ing to be \dQuote{rather safe than sorry} thanks to Tomas Kalibera's check tools. } } } \section{Changes in version 1.2-12 (2017-11-10, svn r3239)}{ \subsection{New Features}{ \itemize{ \item \code{crossprod(x,y)} and \code{kronecker(x,y)} have become considerably more efficient for large \code{"indMatrix"} objects \code{x, y}, thanks to private nudging by Boris Vaillant. } } \subsection{Bug Fixes}{ \itemize{ \item (R-forge Matrix bug #6185): \code{c < 0} now also works for derived sparse Matrices (which only \emph{contain} Matrix classes); via improving hidden \code{MatrixClass()}. Part of such derived matrices only work in R >= 3.5.0. \item using \code{Authors@R} in \file{../DESCRIPTION} to list all contributors. \item \code{solve(-m)} no longer should use a cached Cholesky factorization (of \code{m}). } } } \section{Changes in version 1.2-11 (2017-08-10, svn r3225)}{ \subsection{New Features}{ \itemize{ \item S4 method dispatch no longer emits ambiguity notes (by default) for everybody, apart from the package maintainer. You can reactivate them by \code{options(Matrix.ambiguityNotes = TRUE)} } } \subsection{Bug Fixes}{ \itemize{ \item \code{rankMatrix()} now gives zero for all methods, as it should be. \item no longer calling \code{length(NULL) <- } which has been deprecated in R-devel since July. \item \code{qr.coef(, y)} now finally has correct (row) names (from pivot back permutation). \item \code{.trDiagonal()} utility is now exported. } } } \section{Changes in version 1.2-10 (2017-04-19, svn r3216)}{ \subsection{Bug Fixes}{ \itemize{ \item quite a collection of new \code{PROTECT(.)}'s thanks to Tomas Kalibera's \sQuote{rprotect} analysis. } } } \section{Changes in version 1.2-9 (2017-03-08, svn r3211)}{ \subsection{New Features}{ \itemize{ \item \code{"Ops"} between "table", "xtabs", and our matrices now work. \item \code{as(matrix(diag(3), 3, dimnames=rep(list(c("A","b","c")),2)), "diagonalMatrix")@x} is no longer named. \item \code{norm(x, "2")} now works as well (and equivalently to \code{base::norm}). \item \code{sparseVector()} now also works without \code{x} argument. \item \code{c.sparseVector()} method for \code{c()} of sparseVectors (and available as regular function on purpose). } } \subsection{Bug Fixes}{ \itemize{ \item \code{as(Diagonal(3), "denseMatrix")} no longer returns a non-dense \code{"ddiMatrix"}. \item \code{S[sel,] <- value} and similar no longer segfault, but give a \code{"not (yet?) supported"} error for sparse matrices \code{S} and logical \code{sel} when \code{sel} contains \code{NA}s. The same error (instead of a low-level one) is signalled for \emph{indexing} (with NA-containing logical \code{sel}), i.e., \code{S[sel,]}. %% from in ../TODO : %% \item \code{S[sel,]}, \code{S[,sel] <- value} and similar now also work for %% sparse matrices \code{S} and logical \code{sel} when \code{sel} contains \code{NA}s. \item \code{which(x, arr.ind=TRUE, *)} (when \code{x} is a \code{"lMatrix"} or \code{"nMatrix"}) now works the same as \code{base::which}, obeying an optional \code{useNames} argument which defaults to \code{TRUE}. Previously, the resulting two-column matrix typically had empty \code{dimnames}. } } } \section{Changes in version 1.2-8 (2017-01-16, svn r3201)}{ \subsection{New Features}{ \itemize{ \item 0-length matrix \code{"Ops"} (binary operations) are now compatible to R-devel (to be \R{} 3.4.0). \item C-API: \code{SuiteSparse_long} is now defined as \code{int64_t} on all platforms, and we now include (C99) \file{inttypes.h} } } \subsection{Bug Fixes}{ \itemize{ \item \code{x[.] <- value} now also works for \code{"sparseVector"}'s, both as \code{x} and as \code{value}. \item \code{x[FALSE] <- value} now also works for \code{"sparseVector"}'s. \item \code{rep(x, *)} now works for \code{"sparseVector"}s and sparse and dense \code{"Matrix"}-classed matrices \code{x}. \item \code{solve()} no gives an error in some cases of singular matrices, where before the C code accessed illegal memory locations. } } } \section{Changes in version 1.2-7.1 (2016-08-29, svn r3187)}{ \itemize{ \item in C code, protect _POSIX_C_SOURCE by #ifdef __GLIBC__ } } \section{Changes in version 1.2-7 (2016-08-27, svn r3185)}{ \subsection{New Features}{ \itemize{ \item \code{cBind()} and \code{rBind()} have been almost silently deprecated in \R{} \code{>= 3.2.0} and now give a warning, \dQuote{once per session} only. \item \code{bandSparse(*, k=k, *)} now returns matrices inheriting from \code{"triangularMatrix"} when obvious from the diagonal indices \code{k}. } } \subsection{Bug Fixes}{ \itemize{ \item \code{KhatriRao(X,Y)} now also works when \code{X} or \code{Y} is completely zero. } } } \section{Changes in version 1.2-6 (2016-04-27, svn r3175)}{ \subsection{Bug Fixes}{ \itemize{ \item The 0-dim. Matrix multiplication fix in 1.2-5 did trigger wrong warnings in other diagonal matrix multiplications. } } } \section{Changes in version 1.2-5 (2016-04-14, svn r3170)}{ \subsection{New Features}{ \itemize{ \item \code{isSymmetric(m)} now also works for \code{"indMatrix"} \code{m}. \item \code{isSymmetric(m)} is faster for large dense asymmetric matrices. } } \subsection{Bug Fixes}{ \itemize{ \item Matrix multiplications (\code{A \%*\% B}) now work correctly when one of the matrices is diagonal and the other has a zero dimension. } } } \section{Changes in version 1.2-4 (2016-02-29, svn r3162)}{ \subsection{New Features}{ \itemize{ \item \code{sparseMatrix()} gets new argument \code{triangular} and a smarter default for \code{dims} when \code{symmetric} or \code{triangular} is true. \item \code{as(, "denseMatrix")} now works in more cases when \code{prod(dim(.))} is larger than \eqn{2^{31} - 1}. Hence, e.g., \code{!S} now works for much larger sparse matrices \code{S}. } } \subsection{Bug Fixes}{ \itemize{ \item creating very large dense matrices, e.g., by \code{as(, "matrix")} would segfault (in case it could allocate enough storage). } } } \section{Changes in version 1.2-3 (2015-11-19, svn r3155)}{ \subsection{New Features}{ \itemize{ \item \code{MatrixClass()} is exported now. \item More exports of semi-internal functions (for speed, named \code{"."}, i.e., inofficial API), such as \code{.solve.dgC.lu()}. \item more Korean translations } } \subsection{Bug Fixes}{ \itemize{ \item Packages \emph{linking} to \pkg{Matrix} (\code{LinkingTo:} in \file{DESCRIPTION}) now find \samp{alloca} properly defined in \file{Matrix.h} even for non-GNU compilation environments such as on Solaris or AIX. \item extended "n?CMatrix" classes (e.g., from \code{setClass(., contains="ngCMatrix")}) now can be coerced via \code{as(.)} to \code{"d.CMatrix"}. \item The printing of largish sparse matrices is improved, notably in the case where columns are suppressed, via new \code{fitWidth = TRUE} option in \code{printSpMatrix2()}. %%% FIXME __ EXAMPLES __ \item \code{cbind2()} and \code{rbind2()} no longer fail to determine \code{sparse} when it is unspecified and hence \code{NA}, fixing R-forge bug #6259. } } } \section{Changes in version 1.2-2 (2015-07-03, svn r3131)}{ \subsection{New Features}{ \itemize{ \item Explicitly import from \dQuote{base} packages such as \code{"stats"}. } } \subsection{Bug Fixes}{ \itemize{ \item Our \code{colSums(x)}, \code{rowMeans(y)}, \dots, methods now \dQuote{keep names}, i.e., if the result is a numeric vector, and the matrix \code{x} has column or row names, these become the \code{names(.)} of the result, fixing R-forge bug #6018. } } } \section{Changes in version 1.2-1 (2015-05-30, svn r3127)}{ \subsection{New Features}{ \itemize{ \item \code{"Matrix"} now has an \code{initialization()} method coercing 0-length dimnames components to \code{NULL} and other non-\code{NULL} dimnames to \code{character}. Before, e.g., numeric dimnames components partially worked, even though it has always been documented that non-\code{NULL} dimnames should be \code{character}. \item For \code{symmetricMatrix} objects which have symmetrical dimnames by definition, it is allowed to only set one half of the \code{dimnames} to save storage, e.g., \code{list(NULL, nms)} is \emph{semantically} equivalent to \code{list(nms, nms)}. \item \code{as.vector()} etc, now work, too. \item \code{lu()} now keeps \code{dimnames}. \item better \file{NEWS.Rd} (which pleases Kurt and \command{tidy} ;-) } } \subsection{Bug Fixes}{ \itemize{ \item \code{S[] <- T} and \code{S[] <- spV} now work (in more cases) for sparse matrices S, T and sparseVector \code{spV}. \item Huge dense matrix multiplication did lead to segfaults, see R-help, \dQuote{does segfault mean (always) a bug?}, May 5, 2015. Fixed by using C's Alloca() only in smallish cases. \item Optional arguments in \code{image()}, e.g., \code{main= <..>)} now also work for \code{lgCMatrix}, \code{nMatrix} etc; thanks to a 4.5 years old report by Mstislav Elagin. \item \code{dimnames(A) <- val} now resets the \code{factors} slot to empty, as the factorizations now keep dimnames more often. \item \code{crossprod(, Diagonal())} works again (and these are tested more systematically). \item Matrix products (\code{\%*\%}, \code{crossprod}, and \code{tcrossprod}) for \code{"dtrMatrix"} are correct in all cases, including keeping dimnames. \item \code{Matrix(d)} (and other coercions to \code{"Matrix"}) now correctly keeps \code{dimnames} also when \code{d} is a traditional \emph{diagonal} \code{"matrix"}. } } } \section{Changes in version 1.2-0 (2015-04-03, svn r3096)}{ \subsection{New Features}{ \itemize{ \item New \code{\%&\%} for \dQuote{boolean arithmetic} matrix product. \item New argument \code{boolArith = NA} in \code{crossprod()} and \code{tcrossprod()}. \code{boolArith = TRUE} now forces boolean arithmetic, where \code{boolArith = FALSE} forces numeric one. Several of these products are more efficient thanks to new C functionality based on our new \code{chm_transpose_dense()}, and others based on \code{geMatrix_crossprod}, \code{geMatrix_matrix_mm}, etc. \item Most dense matrix products, also for non-\code{dgeMatrix}, including \code{"l..Matrix"} and \code{"n..Matrix"} ones are now directly handled by new \code{.Call()}s. \item \code{"dMatrix"} (numeric) and \code{"lMatrix"} (logical) matrices can now be coerced to \code{"nMatrix"} (non-zero pattern or \dQuote{boolean}) even when they contain \code{NA}s, which then become \code{TRUE}s. \item More thorough checking of \code{cbind2()} and \code{rbind2()} methods, notably as they are called from \code{cbind()} and \code{rbind()} from \R{} version 3.2.0 on. \code{rbind2(, )} is faster, being based on new C code. \item symmetric Matrices (i.e., inheriting from \code{"symmetricMatrix"}) are allowed to have \code{dimnames} of the form \code{list(NULL, )} \emph{and} now print correctly and get correctly coerced to general matrices. \item \code{indMatrix} object (\dQuote{index matrices}) no longer need to be \dQuote{skinny}. \item \code{rsparseMatrix()} now accepts \code{rand.x = NULL} and then creates a random \emph{patter\bold{n}} matrix (\code{"nsparseMatrix"}). \item \code{anyDuplicatedT()} and \code{uniqTsparse()} low level utilities are exported now. \item Partial Korean translations of messages. } } \subsection{Deprecation}{ \itemize{ \item For \eqn{R \ge 3.2.0}, \code{cBind()} and \code{rBind()} are deprecated, as they are no longer needed since \code{cbind()} and \code{rbind()} do work automatically. } } \subsection{Bug Fixes}{ \itemize{ \item Fix some \code{rbind2()} methods. \item \code{t()} now transposes the dimnames even for symmetric matrices. \item \code{diag(M) <- val} did not always recycle \code{val} to full length, e.g., when \code{M} was a \code{"dtrMatrix"}. \item \code{crossprod()} was wrong in cases where the matrix had all-zero columns. \item Matrix products (\code{\%*\%}, \code{crossprod}, and \code{tcrossprod}) with one sparse and one dense argument now return \emph{numeric} (a \code{"dMatrix"}) when they should, i.e., unless the new setting \code{boolArith = TRUE} is applied. } } } \section{Changes in version 1.1-5 (2015-01-18, svn r3037)}{ \subsection{New Features}{ \itemize{ \item More use of \code{anyNA()} (for speedup). \item Matrix products (\code{\%*\%}, \code{crossprod}, \code{tcrossprod}) now behave compatibly to \R{} 3.2.0, i.e., more lenient in matching dimensions for matrix - vector products. \item \code{isTriangular()} gets new optional argument \code{upper = NA}. } } \subsection{Bug Fixes}{ \itemize{ \item \code{crossprod()} and \code{tcrossprod()} fixes for several o combinations. \item \code{rowMeans(, na.rm=TRUE)} was wrong sometimes. \item fix and speedup of coercions (\code{as(., .)}) from and to symmetric or triangular matrices. \item \code{invPerm()} coercion to integer \item \code{dimnames( solve(.,.) )} fix [r3036] \item \code{tril()} and \code{triu()} now return correct \code{uplo}. \item \code{names(dimnames(.))} now preserved, e.g. in \code{symmpart()} or subsetting (\code{A[i,j]}). } } } \section{Changes in version 1.1-4 (2014-06-14, svn r2994)}{ \subsection{New Features}{ \itemize{ \item new \code{rsparsematrix()} for random sparse Matrices. \item improved warnings, notably for unused arguments previously swallowed into \code{...}. } } \subsection{Bug Fixes}{ \itemize{ \item \code{crossprod(, )} fixed. \item \code{crossprod()} and \code{kronecker()} fixes for some cases. } } } \section{Changes in version 1.1-3 (2014-03-30, svn r2982)}{ \subsection{New Features}{ \itemize{ \item \code{\%*\%} and \code{crossprod()} now also work with \code{sparseVector}s. \item speedup of \code{crossprod(v, )}, thanks to nudge by Niels Richard Hansen. \item new help page for all such matrix products (\file{../man/matrix-products.Rd}). } } \subsection{Bug Fixes}{ \itemize{ \item \code{image()} now gets correct \code{ylim} again. \item More consistent matrix products. } } } \section{Changes in version 1.1-2-2 (2014-03-04, svn r2966)}{ \subsection{Bug Fixes}{ \itemize{ \item correct adaption to \R{} 3.1.0 \item using \code{tolerance} (and not \sQuote{tol}) in \code{all.equal()} } } } \section{Changes in version 1.1-2 (2014-01-28, svn r2962)}{ \subsection{New Features}{ \itemize{ \item export fast power-user coercion utilities \code{.dsy2mat()}, \code{.dxC2mat()}, \code{.T2Cmat()}, \code{..2dge()}. } } \subsection{Bug Fixes}{ \itemize{ \item matrix products now (mostly) work with \code{sparseVector}s; and correctly in some more cases. } } } \section{Changes in version 1.1-1.1 (2013-12-30, svn r2957)}{ \itemize{ \item Testing code's \code{assertWarning()} adapted for \eqn{R \le 3.0.1}. \item \code{Depends: R >= 2.15.2} eases checking. } } \section{Changes in version 1.1-1 (2013-12-28)}{ \subsection{New Features}{ \itemize{ \item \code{image(.., xlim, ylim)}: nicer defaults %% ../R/dgTMatrix.R for the axis limits, and \code{ylim} is sorted decreasingly; not strictly back-compatible but should never harm. \item \code{rankMatrix(*, method="qr")} now using \code{tol} \item \code{T2graph()} and \code{graph2T()} export old functionality explicitly. Tweaks in conversions between \code{"graph"} and \code{"sparseMatrix"} objects. Notably, \code{as(, )} now more often returns a (0/1 pattern) "n..Matrix". \item \code{sparseMatrix()}: new \code{use.last.ij} argument. } } \subsection{Bug Fixes}{ \itemize{ \item \code{KhatriRao()}: fix rownames (X <-> Y) \item \code{qr.coef()}, \code{qr.fitted}, and \code{qr.resid} now also work with \emph{sparse} RHS \code{y}. \item sparse matrix \dQuote{sub assignments}, e.g., \code{M[ii] <- v}, speedup and fixes. \item bug fixes also in \code{M[negative indices] <- value} and \code{[cbind(i,j)]}. } } } \section{Changes in version 1.1-0 (2013-10-21, svn r2930)}{ \subsection{New Features}{ \itemize{ \item \code{fac2sparse} and \code{fac2Sparse} now exported, with a new \code{giveCsparse} option. \item Update to latest \command{SuiteSparse} C library by Tim Davis, U. Florida. \item ensuing \dQuote{C API changes} \item new \code{.SuiteSparse_version()} function \item Many \sQuote{Imports:} instead of \sQuote{Depends:}. } } \subsection{Bug Fixes}{ \itemize{ \item fixed long lasting undetected \code{solve(, *)} bug. \item Our \code{all.equal()} methods no longer sometimes return \code{c("TRUE", "....difference..")}. \item \code{rankMatrix()}: fix the internal \code{x.dense} definition. } } } \section{Changes in version 1.0-14 (2013-09-12, svn r2907)}{ \subsection{Bug Fixes}{ \itemize{ \item Revert some wrong changes to \code{solve(, *)} from 1.0-13 (\dQuote{stop gap fix} for \R{} 3.0.2). } } } \section{Changes in version 1.0-13 (2013-09-10, svn r2904)}{ \subsection{New Features}{ \itemize{ \item New (efficient) \code{KhatriRao()} function by Michael Cysouw \item New \code{"indMatrix"} class of \dQuote{index matrices}, a generalization of \code{"pMatrix"}, the permutation matrices, many methods generalized from pMatrix to indMatrix. All (initial) functionality contributed by Fabian Scheibl, Univ.\sspace{} Munich. \item Export and document \code{isDiagonal()} and \code{isTriangular()} as they are useful outside of \pkg{Matrix}. \item \code{rankMatrix(M, method="qr")} no longer needs \code{sval} which makes it considerably more useful for large sparse \code{M}. \item Start providing \code{anyNA} methods for \eqn{R >= 3.1.0}. \item \code{solve( a, b)}: if \code{a} is symmetric, now compute \emph{sparse} result. \item \code{nearPD()} gets new option \code{conv.norm.type = "I"}. \item \code{determinant()} now uses \code{chol()}, and hence also an existing (\sQuote{cached}) Cholesky factor. \item 3 new \code{C -> R} utilities (including hidden \R{} function \code{.set.factors()} for caching also from \R{}, not just in C). } } \subsection{Bug Fixes}{ \itemize{ \item \code{M[] <- v} for unitriangular \code{M} now correct. \item \code{lu(.)} no longer sometimes returns unsorted columns. } } } %% TODO: fill in from here <<<<<<<<<<<<<<<<<<< %% ---- using ../ChangeLog and notably my ../svn-log-from.all \section{Changes in version 1.0-12 (2013-03-26, svn r2872)}{ \subsection{New Features}{ \itemize{ \item . } } \subsection{Bug Fixes}{ \itemize{ \item . } } } \section{Changes in version 1.0-11 (2013-02-02)}{ \subsection{New Features}{ \itemize{ \item . } } \subsection{Bug Fixes}{ \itemize{ \item \code{as(, "dgCMatrix")} (from package \CRANpkg{SparseM}) now works again. \item . } } } \section{Changes in version 1.0-10 (2012-10-22)}{ \subsection{New Features}{ \itemize{ \item \code{.sparseDiagonal()}: new \code{unitri} argument, and more flexibility; \item new \code{solve(, )} via efficient C code. } } \subsection{Bug Fixes}{ \itemize{ \item . } } } \section{Changes in version 1.0-9 (2012-09-05)}{ \subsection{New Features}{ \itemize{ \item new \code{sparseVector()} constructor function. \item \code{is.finite()} \code{is.infinite()} now work for our matrices and "*sparseVector" objects. \item \code{diag(.) <- V} now preserves symmetricity, triangularity and even uni-triangularity sometimes. } } \subsection{Bug Fixes}{ \itemize{ \item Quite a few fixes for \code{Ops} (arithmetic, logic, etc) group methods. \item Ditto for \code{diagonalMatrix} methods. } } } \section{Changes in version 1.0-6 (2012-03-16, publ. 2012-06-18)}{ \subsection{New Features}{ \itemize{ \item . } } \subsection{Bug Fixes}{ \itemize{ \item . } } } \section{Changes in version 1.0-5 (2012-03-15)}{ \subsection{New Features}{ \itemize{ \item . } } \subsection{Bug Fixes}{ \itemize{ \item . } } } \section{Changes in version 1.0-4 (2012-02-21)}{ \subsection{New Features}{ \itemize{ \item . } } \subsection{Bug Fixes}{ \itemize{ \item . } } } \section{Changes in version 1.0-3 (2012-01-13)}{ \subsection{New Features}{ \itemize{ \item . } } \subsection{Bug Fixes}{ \itemize{ \item . } } } \section{Changes in version 1.0-2 (2011-11-19)}{ \subsection{New Features}{ \itemize{ \item . } } \subsection{Bug Fixes}{ \itemize{ \item . } } } \section{Changes in version 1.0-1 (2011-10-18)}{ \subsection{New Features}{ \itemize{ \item . } } \subsection{Bug Fixes}{ \itemize{ \item . } } } \section{Changes in version 1.0-0 (2011-10-04)}{ \subsection{New Features}{ \itemize{ \item . } } \subsection{Bug Fixes}{ \itemize{ \item . } } } \section{Changes in version 0.9996875-3 (2011-08-13)}{ \subsection{New Features}{ \itemize{ \item . } } \subsection{Bug Fixes}{ \itemize{ \item . } } } \section{Changes in version 0.9996875-2 (2011-08-09)}{ \subsection{New Features}{ \itemize{ \item . } } \subsection{Bug Fixes}{ \itemize{ \item . } } } \section{Changes in version 0.9996875-1 (2011-08-08)}{ \subsection{New Features}{ \itemize{ \item . } } \subsection{Bug Fixes}{ \itemize{ \item . } } } \section{Changes in version 0.999375-50 (2011-04-08)}{ \subsection{New Features}{ \itemize{ \item . } } \subsection{Bug Fixes}{ \itemize{ \item . } } } % How can I add vertical space ? % \preformatted{} is not allowed, nor is \cr %--------------- start of DB+MM history: ------------------------ \section{Changes in version 0.95-1 (2005-02-18, svn r561)}{ \subsection{Authorship}{ \itemize{ \item During Doug Bates' sabbatical in Zurich, Martin Maechler becomes co-author of the \pkg{Matrix} package. } } \subsection{New Features}{ \itemize{ \item Beginning of class reorganization with a more systematic naming scheme. } } \subsection{Bug Fixes}{ \itemize{ \item More (correct) coercions \code{as(, )}. } } } \section{Changes in version 0.9-1 (2005-01-24, svn r451)}{ \subsection{New Features}{ \itemize{ \item lme4 / lmer specific R code moved out to \CRANpkg{lme4} package. } } \subsection{Bug Fixes}{ \itemize{ \item . } } } % How can I add vertical space ? ( \preformatted{} is not allowed, nor is \cr ) %--------------- pre-pre-history: ------------------------ \section{Changes in version 0.8-2 (2004-04-06, svn r51)}{ \subsection{Authorship}{ \itemize{ \item Doug Bates (only) } } \subsection{New Features}{ \itemize{ \item Sparse matrices, classes and methods, partly via \item Interface to LDL, TAUCS, Metis and UMFPACK C libraries } } } % How can I add vertical space ? ................................. \section{Version 0.2-4}{ \subsection{..., 0.3-1, 0.3-n (n=3,5,...,26): 22 more CRAN releases}{ \itemize{ \item ............................................. } }} % How can I add vertical space ? % \preformatted{} is not allowed, nor is \cr \section{Version 0.2-1 (2000-07-15)}{ The first CRAN release of the \pkg{Matrix} package, titled \dQuote{A Matrix library for R} authored by Douglas Bates (maintainer, principal author) and Saikat DebRoy. \subsection{Features}{ \itemize{ \item \code{Matrix()} constructor for \R{} objects of class \code{Matrix}. \item \code{Matrix.class()} returning informal subclasses such as \code{"Hermitian"}, \code{"LowerTriangular"} \item \code{is.Orthonormal()}, \code{is.Hermitian()} , \code{is.UpperTriangular()} functions. \item \code{SVD()}, \code{lu()}, and \code{schur()} decomposition generics with \code{"Matrix"} methods. \item \code{rcond()}, \code{norm()}, \code{det()}; \code{expand()} and \code{facmul()}. \item C++ interface to LAPACK } } } Matrix/inst/po/0000755000176200001440000000000014547723665013134 5ustar liggesusersMatrix/inst/po/ko/0000755000176200001440000000000014547723665013545 5ustar liggesusersMatrix/inst/po/ko/LC_MESSAGES/0000755000176200001440000000000014547723665015332 5ustar liggesusersMatrix/inst/po/ko/LC_MESSAGES/Matrix.mo0000644000176200001440000001241414521047060017111 0ustar liggesusers%D5l@A+a+3-!P=M"<'<+d0,,2'N-v.&+&F/m+@<$$a$0O -g T > Q) J{ S N Ji T T X^ ^ CCZIHH1dz'-.5(d@HAHYYUR^l4O4Q0 0<OmN % # " !$ 'data' must be of a vector typeArgument ij must be 2-column integer matrixArgument must be numeric-like atomic vectorMatrix exponential requires square, non-null matrixX must be a numeric (double precision) matrixX must be a real (numeric) matrixdata length [%d] is not a sub-multiple or multiple of the number of columns [%d]data length [%d] is not a sub-multiple or multiple of the number of rows [%d]data length exceeds size of matrixdgeMatrix_Schur: argument x must be a non-null square matrixdgeMatrix_Schur: dgees returned code %ddgeMatrix_Schur: first call to dgees faileddgeMatrix_exp: LAPACK routine dgebal returned %ddgeMatrix_exp: dgetrf returned error code %ddgeMatrix_exp: dgetrs returned error code %di and j must be integer vectors of the same lengthincorrect left cyclic shift, j (%d) < 0incorrect left cyclic shift, j (%d) >= k (%d)incorrect left cyclic shift, k (%d) > ldx (%d)invalid '%s' argumentinvalid 'ncol' value (< 0)invalid 'ncol' value (too large or NA)invalid 'nrow' value (< 0)invalid 'nrow' value (too large or NA)invalid class of 'value' in Csparse_subassign()invalid class of 'x' in Csparse_subassign()non-numeric matrix extentnumber of rows in y (%d) does not match number of rows in X (%d)programming error in Csparse_subassign() should never happensubscript 'i' out of bounds in M[ij]subscript 'j' out of bounds in M[ij]tol, given as %g, must be <= 1too many elements specifiedx[] <- val: val is coerced to logical for "%s" xx[] <- val: val should be integer or logical, is coerced to integer, for "%s" xy must be a numeric (double precision) matrixProject-Id-Version: Matrix 1.1-3 Report-Msgid-Bugs-To: PO-Revision-Date: 2015-07-15 17:14-0600 Last-Translator:Chel Hee Lee Language-Team: Chel Hee Lee Language: ko MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=1; plural=0; 'data'는 반드시 벡터형(vector type)이어야 합니다.인자 ij는 반드시 2개의 열을 가진 정수형 행렬이어야 합니다.인자는 반드시 수치형과 같은 기본형 벡터이어야합니다행렬의 지수(exponential)은 정방이고 non-null인 행렬이어야 합니다X는 반드시 double precision을 가진 수치형 행렬이어야 합니다.X는 반드시 실수(real)형 숫자를 가진 행렬이어야 합니다.데이터의 길이[%d]가 열의 개수[%d]의 약수 또는 배수가 아닙니다데이터의 길이[%d]가 행의 개수[%d]의 약수 또는 배수가 아닙니다데이터의 길이(data length)가 행렬의 크기(size of matrix)를 초과합니다.dgeMatrix_Schur: 인자 x는 반드시 null이 아닌 정방(square)행렬이어야 합니다.dgeMatrix_Schur: 코드 %d가 dgees로부터 반환되었습니다.dgeMatrix_Schur: dgees로의 첫번째 호출에 실패했습니다dgeMatrix_exp: %d가 LAPACK 루틴 dgebal로부터 반환되었습니다.dgeMatrix_exp: 에러코드 %d가 dgetrf로부터 반환되었습니다.dgeMatrix_exp: 에러코드 %d가 dgetrs로부터 반환되었습니다.i와 j는 반드시 같은 길이를 가지는 정수형 벡터(integer vectors)이어야 합니다.incorrect left cyclic shift, j (%d) < 0incorrect left cyclic shift, j (%d) >= k (%d)incorrect left cyclic shift, k (%d) > ldx (%d)'%s' 인자는 유효하지 않습니다'ncol'의 값이 0보다 작으므로 올바르지 않습니다.'ncol'의 값이 너무 크거나 NA이므로 올바르지 않습니다.'nrow'의 값이 0 보다 작으므로 올바르지 않습니다.'nrow'의 값이 너무 크거나 NA이므로 올바르지 않습니다.Csparse_subassign()에서 사용되는 'value'의 클래스가 올바르지 않습니다.Csparse_subassign()에서 사용되는 'x'의 클래스가 올바르지 않습니다.non-numeric matrix extenty가 가진 행의 개수 (%d)가 X가 가진 행의 개수 (%d)와 일치하지 않습니다.Csparse_subassign()를 사용 중 발생하지 말아야 하는 프로그래밍 에러(programming error)가 발견되었습니다.첨자 'i'가 M[ij]내에 존재하지 않습니다.첨자 'j'가 M[ij]내에 존재하지 않습니다.tol의 값은 1보다 작거나 같아야 하는데 %g를 가지고 있습니다.너무 많은 요소들이 지정되었습니다x[] <- val: val is coerced to logical for "%s" xx[] <- val: val should be integer or logical, is coerced to integer, for "%s" xy는 반드시 double precision을 가진 수치형 행렬이어야 합니다.Matrix/inst/po/ko/LC_MESSAGES/R-Matrix.mo0000644000176200001440000004170614502411615017316 0ustar liggesuserssL 6 3 , 9H  6 1 / ,; *h #  , ; #4 X 4l $ W ( 0G $x 0  8 ''Oo:5#,8.e$D4%F=l-7 -*Nye"""1EwI"@ @a56. =^y"13:-Q@?=9>0x=51O'i&$&7BO(&?""*E;p%)!9>>xA (0A`r5, 76nO>I<c:H,$=Q[_@K O 4 [!?m!`!X"Eg"@"."E#_c#@#-$\2$E$$(%@%4&@I&4&J&C 'N'Hn'A'C'=(=(U(MT)))S) *b*6 +MB+J+N+?*,Cj,\,F -R-<(.<e.X.!./E//0|0o 1wy151.'2GV20202A3fB3f34b4g5[x5=5?6kR6O6U7Ed77K738&D8$k8C8B8;9eS98979O*:?z:S:;6;N;XE<D<_<dC=G=2=?#>5c>0>~>]I?e?R @C`@O@U@JAAfBBI|C -+ _[;CG=,M4QP:NX8T!ld".)Ur?J2qR7SV5*3 ji1n0$Y &IAZW'%bkEHKa9` c6s@\ L^#D]m<peo>(gBhfFO/'%s()' is not yet implemented for representation '%s''%s()' is not yet implemented for element type '%s''A' must be a square matrix'NA' indices are not (yet?) supported for sparse Matrices'by' argument is much too small'diagonals' matrix must have %d columns (= length(k) )'diagonals' must have the same length (%d) as 'k''file' must be a character string or connection'force' must be (coercable to) TRUE or FALSE'lwd' must be NULL or non-negative numeric'ncol' is not a factor of length(x)'ncol' must be >= 0'nearPD()' did not converge in %d iterations'nrow' and 'ncol' must be the same when 'symmetric' is true'nrow' is not a factor of length(x)'nrow' must be >= 0'x' must have length nrow^2 when 'symmetric' is true'x' must inherit from "sparseVector".M.repl.i.2col(): 'i' has no integer column number; should never happen; please report.M.repl.i.2col(): drop 'matrix' case ... --> is not yet implemented[i] is not yet implemented --> is not yet implementedClass %s is not yet implementedCmp.Mat.atomic() should not be called for diagonalMatrixInternal bug: nargs()=%d; please reportInvalid assembled indicator: %sInvalid storage format: %sInvalid storage type: %sLogic.Mat.atomic() should not be called for diagonalMatrixMatrices must have same number of rows for arithmeticMatrix seems negative semi-definiteMust specify 'nrow' when 'symmetric' is trueNAs are not allowed in subscripted assignmentsNot a valid formatOnly numeric sparse matrices allowedRHS 'value' (class %s) matches 'ANY', but must match matrix class %s[ ] indexing not allowed: forgot a "," ?all() is not yet implementedc(,..) of different kinds, coercing all to 'rleDiff'column indices must be <= ncol(.) which is %ddim [product %d] do not match the length of object [%d]dimnames [%d] mismatch in %selement type '%s' not recognizedelement type 'complex' not yet implementedfile is not a MatrixMarket filefor symmetric band matrix, only specify upper or lower triangle hence, all k must have the same signhit a cycle (1) -- stop iterationshit a cycle (2) -- stop iterationsi1[1] == 0 ==> C-level verbosity will not happen!index larger than maximal %dindex must be numeric, logical or sparseVector for indexing sparseVectorsinefficient method used for "- e1"intermediate 'r' is of type %sinternal bug in "Compare" method (Cmp.Mat.atomic); please reportinternal bug in "Logic" method (Logic.Mat.atomic); please reportinternal bug: matrix 'i' in replTmat(): please reportinternal bug: missing 'i' in replTmat(): please reportinvalid 'col.names' string: %sinvalid 'data'invalid (to - from)/by in seq(.)invalid character indexinginvalid nargs()= %dlength must be non-negative numberlength of 1st arg does not match dimension of 2ndlength of 2nd arg does not match dimension of firstlogic programming error in printSpMatrix2(), please reportlogical subscript too long (%d, should be %d)longer object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthm[ ] <- v: inefficiently treating single elementsmust either specify 'A' or the functions 'A.x' and 'At.x'nargs() = %d should never happen; please report.nargs() = %d. Extraneous illegal arguments inside '[ .. ]' ?negative values are not allowed in a matrix subscriptno 'dimnames[[.]]': cannot use character indexingnon-conformable argumentsnon-conformable matrix dimensions in %snot converged in %d iterationsnot enough new vecs -- stop iterationsnot yet implementednot yet implemented .. please reportnot-yet-implemented 'Matrix[<-' methodnothing to replace withnumber of items to replace is not a multiple of replacement lengthnumber of rows are not compatible for %sprod() is not yet implementedrankMatrix(x, method='qr'): computing t(x) as nrow(x) < ncol(x)representation '%s' not recognizedrow indices must be <= nrow(.) which is %dsuch indexing must be by logical or 2-column numeric matrixsum() is not yet implementedsymmetric matrix must be squaresymmetry form '%s' is not yet implementedsymmetry form '%s' not recognizedsymmetry form 'hermitian' not yet implemented for readingsymmetry form 'skew-symmetric' not yet implemented for readingthe %d-th (sub)-diagonal (k = %d) is too short; filling with NA'stoo many argumentstoo many replacement valuestype '%s' not recognizedusing "old code" part in Csparse subassignmentusing"old code" part in Csparse subassignment >>> please report to Matrix-authors@r-project.orgvariable '%s' is absent, its contrast will be ignoredvector too long in Matrix - vector operationwhen 'A' is specified, 'A.x' and 'At.x' are disregardedwrong sign in 'by' argumentx / 0 for an x with sign-change no longer representable as 'rleDiff'x[.,.] <- val : x being coerced from Tsparse* to CsparseMatrixx[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced NA |--> TRUE.x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced.x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced.x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced; NA |--> TRUE.you cannot mix negative and positive indicesProject-Id-Version: Matrix 1.1-3 PO-Revision-Date: 2015-07-15 17:14-0600 Last-Translator:Chel Hee Lee Language-Team: Chel Hee Lee Language: ko MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=1; plural=0; 표현(representation)이 '%2$s'의 경우에 아직 구현되지 않은 '%1$s()'입니다.원소유형(element type)이 '%2$s'의 경우에 아직 구현되지 않은 '%1$s()'입니다.'A'는 반드시 정방행렬(square matrix)이어야 합니다.'NA'는 sparse Matrices에 (아직은?) 사용할 수 없는 인덱스입니다'by' 인자에 사용된 값이 너무 작습니다.'diagonals' 행렬은 반드시 %d (=length(k))개의 열을 가지고 있어야 합니다.'diagnoals'의 길이는 반드시 'k'(=%d)이어야 합니다.'file'은 반드시 문자열(character string) 또는 커넥션(connection)이어야 합니다.'force'는 반드시 (강제변환될 수 있는) TRUE 또는 FALSE 이어야 합니다.'lwd'는 반드시 NULL 또는 음이 아닌 수 이어야 합니다.'ncol'는 길이가 length(x)인 요인(factor)가 아닙니다.'ncol'은 반드시 >= 0 이어야 합니다. 'nearPD()'는 %d 번째 반복에서도 수렴하지 않았습니다.'symmetric'이 참인 경우에는 반드시 'nrow'와 'ncol'을 지정해 주어야 합니다.'nrow'는 길이가 length(x)인 요인(factor)가 아닙니다.'nrow'는 반드시 >= 0 이어야 합니다.'symmetric'이 참인 경우에는 'x'의 길이는 반드시 nrow^2와 같아야 합니다.'x'는 "sparseVector"로부터의 상속(inherit)이어야 합니다..M.repl.i.2col(): 'i'는 정수형 행번호(integer column number)을 가지고 있지 않습니다. 이런 경우는 존재할 수 없으므로 패키지 관리자에게 보고해 주시길 부탁드립니다..M.repl.i.2col(): drop 'matrix' case ... --> 은 아직 구현되지 않았습니다.[i]는 아직 구현되지 않았습니다. --> 은 아직 구현되지 않았습니다.클래스 %s는 아직 구현되지 않았습니다.Cmp.Mat.atomic()은 digonalMatrix에 의하여 호출될 수 없습니다.내부버그 발견: nargs()=%d. 꼭 보고를 부탁드립니다.Invalid assembled indicator: %s%s는 사용할 수 있는 저장형식(storage format)이 아닙니다.%s는 사용할 수 없는 저장형식(storage format)입니다.Logic.Mat.atomic()은 diagonalMatrix에 호출될 수 없습니다.원소단위의 연산을 수행하기 위해서는 입력된 각 행렬이 가지는 열의 개수가 서로 같아야 합니다.음의 반정치(negative semi-definite) 행렬 같습니다.'symmetric'이 참인 경우에는 반드시 'nrow'를 지정해 주어야 합니다.NA는 행렬의 첨자(subscripted assignment)로 사용할 수 없습니다.올바른 형식(format)이 아닙니다.오로지 수치형 희소행렬(sparse matrices)만을 사용할 수 있습니다.클래스 %s를 가지는 우변의 'value'는 'ANY'에 매치되지만, 반드시 행렬의 클래스 %s에 매치되어야 합니다.[ ]와 같은 인덱싱은 사용할 수 없습니다. ","의 사용을 잊었나요?all()는 아직 구현되지 않았습니다.c(,..) of different kinds, 모두 'rleDiff'로 강제변환합니다열에 사용되는 인덱스는 %d 보다 같거나 작아야 합니다. dim [product %d]의 값이 객체 [%d]의 길이와 일치하지 않습니다.%2$s에 입력된 dimnames [%1$d]가 일치하지 않습니다.'%s'는 사용가능한 원소유형(element type)이 아닙니다.원소유형(element type)이 'complex'인 경우에는 아직 구현되지 않았습니다.file에 MatrixMarket 형식의 파일이 입력되지 않았습니다.대칭 띠 행렬(symmetric band matrix)의 경우, 오로지 상삼각(upper triangle) 또는 하삼각(lower)만을 지정합니다. 따라서, 모든 k는 반드시 같은 부호(sign)를 가져야 합니다.cycle (1)에 도달했습니다 -- 반복을 중지합니다cycle (2)에 도달했습니다 -- 반복을 중지합니다i1[1] == 0 ==> C-레벨에서의 진행과정표시는 나타나지 않을 것입니다!인덱스가 %d 보다 큽니다.sparseVectors를 인덱싱하기 위해서는 인덱스는 반드시 수치형, 논리형 또는 sparseVectors이어야 합니다."- e1"를 사용하는데 비효율적인 메소드(method)입니다.intermediate 'r' is of type %s메소드 "Compare" (Cmp.Mat.atomic)내에서 버그(internal bug)가 발생했습니다. 이를 꼭 보고해 주셨으면 합니다.메소드 "Logic" (Logic.Mat.atomic)내에서 버그가 발생되었습니다. 이를 꼭 보고해 주셨으면 합니다.내부버그 발견: replTmat()내에서 'i'는 행렬입니다. 이를 보고해 주시길 부탁드립니다.내부버그 발견: replTmat()내에서 'i'를 찾을 수 없습니다. 이를 보고해 주시길 부탁드립니다.%s은 올바른 'col.names' 문자열이 아닙니다입력된 'data'는 올바르지 않습니다.seq(.)의 사용시 (to - from)/by의 값이 올바르지 않습니다.유효하지 않은 문자형 인덱싱입니다nargs()= %d의 값이 올바르지 않습니다.길이(length)는 반드시 음이 아닌 수이어야 합니다.첫번째 인자(arg)의 길이는 두번째 인자의 차원(dimension)과 일치하지 않습니다.두번째 인자(arg)의 길이가 첫번째 인자의 차원(dimension)과 일치하지 않습니다.printSpMatrix2()를 이용 도중 논리적 프로그래밍 에러(logic programming error)가 발생했습니다. 이를 꼭 보고를 부탁드립니다.길이가 너무 긴 논리형 첨자(subscript)입니다 (%2$d이어야 하는데 %1$d입니다).객체의 길이(긴 것)가 다른 객체가 가지는 길이(짧은 것)의 배수가 아닙니다.객체의 길이(긴 것)이 다른 객체의 길이(짧은 것)의 배수가 아닙니다.m[ ] <- v: inefficiently treating single elements'A' 또는 'A.x'와 'At.x'는 반드시 주어져야 합니다.nargs() = %d 와 같은 경우는 발생할 수 없으므로 꼭 보고해 주시기를 부탁드립니다.nargs() = %d. 필요이상의 인자들이 '[ .. ]' 내에 이용되었나요?음수(negative values)는 행렬의 첨자(subscript)로 사용할 수 없습니다.no 'dimnames[[.]]': 문자형 인덱싱을 사용할 수 없습니다non-conformable arguments%s에 입력된 행렬의 차원이 정합(conformable)하지 않습니다.%d번째 반복에서도 수렴하지 않습니다.not enough new vecs -- stop iterations아직 구현되지 않았습니다.아직 구현되지 않았습니다. 보고를 부탁드립니다.아직 구현되지 않은 'Matrix[<-' 메소드입(method)니다.교체(replace)해야 할 것이 아무것도 없습니다.교체(replace)할 항목의 개수가 입력된 value가 가지는 길이의 배수가 아닙니다.%s의 경우 행의 개수가 올바르지 않습니다.prod()는 아직 구현되지 않았습니다.rankMatrix(x, method='qr'): nrow(x) < ncol(x)이므로 t(x)를 계산합니다.'%s'는 사용가능한 표현(representation)이 아닙니다.행에 사용되는 인덱스는 반드시 %d 보다 같거나 작아야 합니다.이와 같은 유형의 인덱싱(indexing)은 반드시 논리형(logical) 또는 2개의 열로 구성된 수치형(numeric) 행렬에 의해서만 이루어져야 합니다.sum()는 아직 구현되지 않았습니다.대칭행렬(symmetric matrix)는 반드시 정방(square)이어야 합니다.대칭형식(symmetry form)이 '%s'인 경우에는 아직 구현되지 않았습니다.'%s'는 사용가능한 대칭형식(symmetry form)이 아닙니다.대칭형식(symmetry form)이 'hermitian'의 경우에는 아직 구현되지 않았습니다.대칭형식(symmetry form)이 'skew-symmetric'인 경우에는 아직 구현되지 않았습니다.%d-번째 (부분)-대각 (k = %d)이 너무 짧아 NA로 채웁니다.입력된 인자의 개수가 너무 많습니다.교체에 이용될 값이 너무 많이 입력되었습니다.'%s'는 사용가능한 유형(type)이 아닙니다.using "old code" part in Csparse subassignmentusing"old code" part in Csparse subassignment >>> Matrix-authors@r-project.org으로 이를 보고해 주시길 바랍니다.변수 '%s'를 찾을 수 없어 관련 대비(contrast)는 계산되지 않을 것입니다.행렬과 벡터 연산(Matrix - vector operation)에 사용될 벡터의 길이가 너무 깁니다.'A'가 주어진 경우에 입력된 'A.x'와 'At.x'는 사용되지 않습니다.'by' 인자에 사용된 부호(sign)가 올바르지 않습니다.x / 0 for an x with sign-change no longer representable as 'rleDiff'x[.,.] <- val : Tsparse* 에서 CsparseMatrix로 강제변환(coerced)된 x입니다.x[.,.] <- val: x의 클래스는 %s입니다. {TRUE, FALSE}에 해당하지 않는 val의 값은 TRUE로 강제변환(coerced) 되었습니다. x[.,.] <- val: x의 클래스는 %s입니다. {TRUE, FALSE}에 해당하지 않는 val의 값은 강제변환(coerced) 되었습니다. x[.] <- val: x의 클래스는 %s입니다. {TRUE, FALSE}에 해당하지 않는 val의 값은 강제변환(coerced) 되었습니다.x[.] <- val: x의 클래스는 %s입니다. {TRUE, FALSE}에 해당하지 않는 val의 값은 TRUE로 강제변환(coerced) 되었습니다.인덱스에 음수와 양수를 혼용하여 사용할 수 없습니다.Matrix/inst/po/fr/0000755000176200001440000000000014547723665013543 5ustar liggesusersMatrix/inst/po/fr/LC_MESSAGES/0000755000176200001440000000000014547723665015330 5ustar liggesusersMatrix/inst/po/fr/LC_MESSAGES/Matrix.mo0000644000176200001440000001154314521047060017111 0ustar liggesusers&L5|PQ+q+3-!+PMM"<'L+t0,,2+'^-.&;&V/}+@<4%q$$ 0 OM - \ !( <J V D 7# /[ b ` 8O G 6 66>5u5=28R9+(+G5s1"MRL6  %">La|7+ &   $ #!"% 'data' must be of a vector typeArgument ij must be 2-column integer matrixArgument must be numeric-like atomic vectorMatrix exponential requires square, non-null matrixX must be a numeric (double precision) matrixX must be a real (numeric) matrixdata length [%d] is not a sub-multiple or multiple of the number of columns [%d]data length [%d] is not a sub-multiple or multiple of the number of rows [%d]data length exceeds size of matrixdgeMatrix_Schur: argument x must be a non-null square matrixdgeMatrix_Schur: dgees returned code %ddgeMatrix_Schur: first call to dgees faileddgeMatrix_exp: LAPACK routine dgebal returned %ddgeMatrix_exp: dgetrf returned error code %ddgeMatrix_exp: dgetrs returned error code %di and j must be integer vectors of the same lengthincorrect left cyclic shift, j (%d) < 0incorrect left cyclic shift, j (%d) >= k (%d)incorrect left cyclic shift, k (%d) > ldx (%d)invalid '%s' argumentinvalid 'ncol' value (< 0)invalid 'ncol' value (too large or NA)invalid 'nrow' value (< 0)invalid 'nrow' value (too large or NA)invalid class of 'value' in Csparse_subassign()invalid class of 'x' in Csparse_subassign()non-numeric matrix extentnumber of rows in y (%d) does not match number of rows in X (%d)programming error in Csparse_subassign() should never happenreplacement diagonal has wrong lengthsubscript 'i' out of bounds in M[ij]subscript 'j' out of bounds in M[ij]tol, given as %g, must be <= 1too many elements specifiedx[] <- val: val is coerced to logical for "%s" xx[] <- val: val should be integer or logical, is coerced to integer, for "%s" xy must be a numeric (double precision) matrixProject-Id-Version: Matrix 1.1-1 Report-Msgid-Bugs-To: PO-Revision-Date: 2021-04-12 18:57+0200 Last-Translator: Philippe Grosjean Language-Team: none Language: fr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n > 1); X-Generator: Poedit 2.4.2 'data' doit être de type vecteurL'argument ij doit être une matrice d'entiers à 2 colonnesL'argument doit être un vecteur atomique de type numérique ou convertible en nombresL'exponentiation de matrice nécessite une matrice carrée non nulleX doit être une matrice numérique (double précision)X doit être une matrice (numérique) de réelsla longueur des données [%d] n'est pas un sous-multiple ni un multiple du nombre de colonnes [%d]la longueur des données [%d] n'est pas un sous-multiple ni un multiple du nombre de lignes [%d]la longueur des données excède la taille de la matricedgeMatrix_Schur : l'argument x doit être une matrice carrée non nulledgeMatrix_Schur : dgees a renvoyé le code d'erreur %ddgeMatrix_Schur : le premier appel à dgees a échouédgeMatrix_exp : la routine LAPACK dgebal a renvoyé %ddgeMatrix_exp : dgetrf a renvoyé le code d'erreur %ddgeMatrix_exp : dgetrs a renvoyé le code d'erreur %di et j doivent être des vecteurs d'entiers de même longueurdécalage cyclique à gauche incorrect, j (%d) < 0décalage cyclique à gauche incorrect, j (%d) >= k (%d)décalage cyclique à gauche incorrect, k (%d) > ldx (%d)argument '%s' incorrectvaleur 'ncol' incorrecte (< 0)valeur 'ncol' incorrecte (trop large ou NA)valeur 'nrow' incorrecte (< 0)valeur 'nrow' incorrecte (trop large ou NA)classe de 'value' incorrecte dans Csparse_subassign()classe de 'x' incorrecte dans Csparse_subassign()étendue de matrice non numériquele nombre de lignes de y (%d) ne correspond pas au nombre de lignes de X (%d)erreur de programmation dans Csparse_subassign() qui ne devrait jamais se produirela diagonale de remplacement a une longueur incorrecteindice 'i' hors plage dans M[ij]indice 'j' hors plage dans M[ij]tol, donné comme %g, doit être <= 1trop d'éléments sont spécifiésx[] <- val: val est converti automatiquement en valeurs logiques pour "%s" xx[] <- val: val devrait être des entiers ou des valeurs booléennes, il est converti automatiquement en entiers pour "%s" xy doit être une matrice numérique (double précision)Matrix/inst/po/fr/LC_MESSAGES/R-Matrix.mo0000644000176200001440000004111614521047060017307 0ustar liggesusers,< 6 3( \ 9x  6 1 /; ,k ? : * #> b ,v ; # 4$LWq(0$#0Hy8'5:N5#,.?$RDw4D%6=\-7 *>ie""15gI"@@Q56(- Vw":91>3p:-@ ?N=2909=j51'*R&q$&B(S&|Bv?]"*;%'M"d)!9>AA 0+4\0`5# ,Y 7  O >*!Ii!<!:!H+",t"E"?#B'$"j$M$'$=%5A%=w%1%?%C'&/k&'&&-&E''N'v'?'#''/v(6(*(6)+?)Ak)3)&)!***CJ*X*,*6+AK++9+}+H^,Q,,,N&-;u-A-#-!.;9.,u..22/2e/N/+/_0)s0$0R0R1Dh1E121&2172$i2.22-2F3EH3B3E3M4/e4b4a4BZ5M575D#6Ch6H6U67K7,7$747 81"8-T88X8%8-9GF99C+:!o:9:i:,5;b;'};;);9;)"<PL<U<V<J=[=*{==?=L=KI>><!?6^?F?$?`@Lb@^@QAO`A^A>Bo],WOc?3j_Cs5}6P{ F<Xl%VfxSU#Hb)+g!zIra|9 1 Z*`/nA$4wmMKh\JB-0t&7DN2"E i;^d[qu'pL:Ry= @vQY(.>eGT~8k'%s()' is not yet implemented for representation '%s''%s()' is not yet implemented for element type '%s''A' must be a square matrix'NA' indices are not (yet?) supported for sparse Matrices'by' argument is much too small'diagonals' matrix must have %d columns (= length(k) )'diagonals' must have the same length (%d) as 'k''file' must be a character string or connection'force' must be (coercable to) TRUE or FALSE'giveCsparse' has been deprecated; setting 'repr = "T"' for you'giveCsparse' has been deprecated; will use 'repr' instead'lwd' must be NULL or non-negative numeric'ncol' is not a factor of length(x)'ncol' must be >= 0'nearPD()' did not converge in %d iterations'nrow' and 'ncol' must be the same when 'symmetric' is true'nrow' is not a factor of length(x)'nrow' must be >= 0'x' must have length nrow^2 when 'symmetric' is true'x' must inherit from "sparseVector".M.repl.i.2col(): 'i' has no integer column number; should never happen; please report.M.repl.i.2col(): drop 'matrix' case ... --> is not yet implemented[i] is not yet implemented --> is not yet implementedClass %s is not yet implementedCmp.Mat.atomic() should not be called for diagonalMatrixInternal bug: nargs()=%d; please reportInvalid assembled indicator: %sInvalid storage format: %sInvalid storage type: %sLogic.Mat.atomic() should not be called for diagonalMatrixMatrices must have same number of rows for arithmeticMatrix seems negative semi-definiteMust specify 'nrow' when 'symmetric' is trueNAs are not allowed in subscripted assignmentsNot a valid formatOnly numeric sparse matrices allowedRHS 'value' (class %s) matches 'ANY', but must match matrix class %s[ ] indexing not allowed: forgot a "," ?a sparseMatrix should rarely be centered: will not be sparse anymoreall() is not yet implementedc(,..) of different kinds, coercing all to 'rleDiff'column indices must be <= ncol(.) which is %ddim [product %d] do not match the length of object [%d]dimnames [%d] mismatch in %selement type '%s' not recognizedelement type 'complex' not yet implementedfile is not a MatrixMarket filefor symmetric band matrix, only specify upper or lower triangle hence, all k must have the same signhit a cycle (1) -- stop iterationshit a cycle (2) -- stop iterationsi1[1] == 0 ==> C-level verbosity will not happen!index larger than maximal %dindex must be numeric, logical or sparseVector for indexing sparseVectorsinefficient method used for "- e1"intermediate 'r' is of type %sinternal bug in "Compare" method (Cmp.Mat.atomic); please reportinternal bug in "Logic" method (Logic.Mat.atomic); please reportinternal bug: matrix 'i' in replTmat(): please reportinternal bug: missing 'i' in replTmat(): please reportinvalid 'col.names' string: %sinvalid 'data'invalid 'repr'; must be "C", "T", or "R"invalid (to - from)/by in seq(.)invalid character indexinginvalid nargs()= %dlength must be non-negative numberlength of 'center' must equal the number of columns of 'x'length of 'scale' must equal the number of columns of 'x'length of 1st arg does not match dimension of 2ndlength of 2nd arg does not match dimension of firstlogic programming error in printSpMatrix2(), please reportlogical subscript too long (%d, should be %d)longer object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthm[ ] <- v: inefficiently treating single elementsmatrix can only be symmetric if square, but n != mmust either specify 'A' or the functions 'A.x' and 'At.x'nargs() = %d should never happen; please report.nargs() = %d. Extraneous illegal arguments inside '[ .. ]' ?negative values are not allowed in a matrix subscriptno 'dimnames[[.]]': cannot use character indexingnon-conformable argumentsnon-conformable matrix dimensions in %snot converged in %d iterationsnot enough new vecs -- stop iterationsnot yet implementednot yet implemented .. please reportnot-yet-implemented 'Matrix[<-' methodnothing to replace withnumber of items to replace is not a multiple of replacement lengthnumber of rows are not compatible for %sprod() is not yet implementedqr2rankMatrix(.): QR with only %d out of %d finite diag(R) entriesrankMatrix(, method = '%s') coerces to dense matrix. Probably should rather use method = 'qr' !?rankMatrix(x, method='qr'): computing t(x) as nrow(x) < ncol(x)representation '%s' not recognizedrow indices must be <= nrow(.) which is %dsuch indexing must be by logical or 2-column numeric matrixsum() is not yet implementedsuppressing %d columnssuppressing %d columns and %d rowssuppressing %d rowssymmetric matrix must be squaresymmetry form '%s' is not yet implementedsymmetry form '%s' not recognizedsymmetry form 'hermitian' not yet implemented for readingsymmetry form 'skew-symmetric' not yet implemented for readingthe %d-th (sub)-diagonal (k = %d) is too short; filling with NA'stoo many argumentstoo many replacement valuestriangular matrix must be squaretype '%s' not recognizeduniDiag=TRUE, but not all diagonal entries are 1uniDiag=TRUE, not all entries in diagonal coded as 1using "old code" part in Csparse subassignmentusing"old code" part in Csparse subassignment >>> please report to Matrix-authors@r-project.orgvariable '%s' is absent, its contrast will be ignoredvector too long in Matrix - vector operationwhen 'A' is specified, 'A.x' and 'At.x' are disregardedwrong sign in 'by' argumentx / 0 for an x with sign-change no longer representable as 'rleDiff'x[.,.] <- val : x being coerced from Tsparse* to CsparseMatrixx[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced NA |--> TRUE.x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced.x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced.x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced; NA |--> TRUE.you cannot mix negative and positive indicesProject-Id-Version: Matrix 1.1-1 PO-Revision-Date: 2021-02-11 11:04+0100 Last-Translator: Philippe Grosjean Language-Team: none Language: fr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Generator: Poedit 2.4.2 Plural-Forms: nplurals=2; plural=(n > 1); '%s' n'est pas encore implémenté pour la représentation '%s''%s()' n'est pas encore implémenté pour le type d'élément '%s''A' doit être une matrice carréeles indices 'NA' ne sont pas (encore?) supportés pour les Matrices éparsesl'argument 'by' est beaucoup trop petitune matrice 'diagonals' doit avoir %d colonnes (= length(k) )'diagonals' doit avoir la même longueur (%d) que 'k''file' doit être une chaîne de caractères ou une connexion'force' doit être (convertible en) TRUE ou FALSE'giveCsparse' est obsolète ; j’ai mis 'repr = "T"' pour vous‘giveCsparse’ est obsolète ; utilisation de 'repr' à la place'lwd' doit être un nombre non négatif ou NULL'ncol' n'est pas un factor de length(x)'ncol' doit être >= 0'nearPD()' n'a pas converti en %d itérations'now' et 'ncol' doivent être les mêmes lorsque 'symmetric' est vrai'nrow' n'est pas un factor de length(x)'nrow' doit être >= 0'x' doit avoir une longueur nrow^2 lorsque 'symmetric' est vrai'x' doit hériter de "sparseVector".M.repl.i.2col() : 'i' n'a pas un nombre entier de colonnes ; ceci ne devrait pas se produite. Veuillez envoyer un rapport de bogue.M.repl.i.2col() : cas 'matrix' non traité ... --> n'est pas encore implémenté[i] n'est pas encore implémenté --> n'est pas encore implémentéLa classe %s n'est pas encore implémentéeCmp.Mat.atomic() ne devrait pas être appelé pour diagonalMatrixBogue interne : nargs()=%d ; veuillez reporter ceciIndicateur d'assemblage incorrect : %sFormat de stockage incorrect : %sType de stockage incorrect : %sLogic.Mat.atomic() ne devrait pas être appelé pour diagonalMatrixLes matrices doivent avoir le même nombre de lignes pour les opérations arithmétiquesLa matrice semble négative et semi-définieIl faut spécifier 'nrow' lorsque 'symmetric' est vraiLes NAs ne sont pas autorisés dans les assignations avec indicesPas un format acceptableSeules les matrices éparses numériques sont autoriséesLa 'value' du membre gauche de l'équation (classe %s) correspond à 'ANY', mais doit correspondre à la classe de matrice %sindiçage [ ] non permis : n'avez-vous pas oublié une "," ?une sparseMatrix doit rarement être centrée : elle ne sera plus éparse ensuiteall() n'est pas encore implémentéc(,..) de différentes sortes, convertis automatiquement en 'rleDiff"les indices de colonnes doivent être <= ncol(.) qui est %ddim [product %d] ne correspond pas à la longueur de l'objet [%d]dimnames [%d] incohérentes dans %stype d'élément '%s' non reconnule type d'élément 'complex' n'est pas encore implémentéle fichier n'est pas un fichier MatrixMarketpour une matrice de bande symétrique, spécifiez seulement le triangle supérieur ou inférieur donc, tous les k doivent avoir le même signeun cycle est atteint (1) -- arrêt des itérationsun cycle est atteint (2) -- arrêt des itérationsi1[1] == 0 ==> au niveau C, aucune information détaillée ne sera affichée !indice plus grand que la valeur maximale %dles indices doivent être numériques, booléens ou sparseVector pour l'indiçage sparseVectorsméthode inefficace utilisée pour "- e1"le 'r' intermédiaire est de type %sbogue interne dans la méthode "Compare" (Cmp.Mat.atomic) ; veuillez reporter cecibogue interne dans la méthode "Logic" (Logic.Mat.atomic) ; veuillez reporter cecibogue interne : matrice 'i' dans replTmat() : veuillez reporter cecibogue interne : 'i' manquant dans replTmat() : veuillez reporter cecichaîne de caractères 'col.names' incorrecte : %s'data' incorrect'repr' incorrect ; il doit être "C", "T", ou "R"(to - from)/by incorrect dans seq(.)indiçage de chaînes de caractères incorrectnargs()= %d incorrectla longueur doit être un nombre non négatifla longueur de 'center' doit être égale au nombre de colonnes de 'x'la longueur de 'scale' doit être égale au nombre de colonnes de 'x'la longueur du 1er arg ne correspond pas à la dimension du secondla longueur du 2ème arg ne correspond pas à la dimension du premiererreur logique de programmation dans printSpMAtrix2(), veuillez reporter ceciindice logique trop long (%d, devrait être %d)la longueur de l'objet le plus long n'est pas un multiple de la longueur de l'objet le plus courtla longueur de l'objet le plus long n'est pas un multiple de la longueur de l'objet le plus courtm[ ] <- v : traitement inefficace d'éléments uniquesune matrice peut seulement être symétrique si elle est carrée, mais n != mil faut spécifier 'A' ou les fonctions 'A.x' et 'At.x'nargs() = %d ne devrait jamais se produire ; veuillez reporter ceci.nargs() = %d. Arguments supplémentaires dans '[ .. ]' illégaux ?les valeurs négatives ne sont pas permises dans les indices de matricespas de 'dimnames[[.]]' : impossible d'utiliser un indiçage de chaîne de caractèresmatrices de dimensions incompatibles dans les argumentsmatrices de dimensions incompatibles dans %spas de convergence en %d itérationspas assez de nouveaux vecs -- arrêt des itérationspas encore implémentépas encore implémenté .. veuillez reporter ceciméthode 'Matrix[<-' non encore implémentéerien à remplacer avecle nombre d'éléments à remplacer n'est pas un multiple de la longueur de remplacementnombre incompatible de lignes pour %sprod() n'est pas encore implémentéqr2rankMatrix(.): QR avec seulement %d de %d entrées finies de diag(R)rankMatrix(, method = '%s') converti automatiquement en matrice dense. Il faudrait probablement plutôt utiliser une méthode = 'qr' ?rankMatrix(x, method='qr') : calcul de t(x) comme nrow(x) < ncol(x)représentation '%s' non reconnueles indices de lignes doivent être <= nrow(.) qui est %dun tel indiçage doit être réalisé avec un vecteur booléen ou une matrice numérique à deux colonnessum() n'est pas encore implémentésuppression de %d colonnessuppression de %d colonnes et %d lignessuppression de %d lignesla matrice symétrique doit être carréela forme de symétrie '%s' n'est pas encore implémentéela symétrie n'est pas reconnue pour '%s'la forme de symétrie 'hermitian' n'est pas encore implémentée pour la lecturela forme de symétrie 'skew-symmetric' n'est pas encore implémentée pour la lecturela %d-ième (sous)-diagonale (k = %d) est trop courte ; elle est repliée avec des NAstrop d'argumentstrop de valeurs de remplacementla matrice triangulaire doit être carréetype '%s' non reconnuuniDiag=TRUE, mais pas toutes les entrées diagonales sont à 1uniDiag=TRUE, toutes les entrées de la diagonale ne sont pas encodées à 1utilisation d'une partie d'"ancien code" dans une sous-assignation Csparseutilisation d'une partie d'"ancien code" dans une sous-assignation Csparse >>> veuillez envoyer un rapport à Matrix-authors@r-project.orgla variable '%s' est absente, ses contrastes seront ignorésvecteur trop long dans une opération Matrix - vecteurlorsque 'A' est spécifié, 'A.x' et 'At.x' ne sont pas pris en comptesigne incorrect dans l'argument 'by'x / 0 pour un x avec changement de signe il n'est plus représentable comme 'rleDiff'x[.,.] <- val: x est converti automatiquement de Tsparse* vers CsparseMatrixx[.,.] <- val: x vaut %s, val qui ne sont pas dans {TRUE, FALSE} sont convertis NA |--> TRUE.x[.,.] <- val: x vaut %s, val qui ne sont pas dans {TRUE, FALSE} sont convertis.x[.] <- val: x vaut %s, val qui ne sont pas dans {TRUE, FALSE} sont convertis.x[.] <- val: x vaut %s, val qui ne sont pas dans {TRUE, FALSE} sont convertis ; NA |--> TRUE.vous ne pouvez pas mélanger des indices négatifs et positifsMatrix/inst/po/it/0000755000176200001440000000000014547723665013550 5ustar liggesusersMatrix/inst/po/it/LC_MESSAGES/0000755000176200001440000000000014547723665015335 5ustar liggesusersMatrix/inst/po/it/LC_MESSAGES/Matrix.mo0000644000176200001440000001134714521047060017120 0ustar liggesusers&L5|PQ+q+3-!+PMM"<'L+t0,,2+'^-.&;&V/}+@<4%q$$ 0 OM - ~ !J =l 2 D 6" )Y U S 8- Hf 1 / 8:J:?/506f,,"3O/%IK#0o""& 2)T\5 &   $ #!"% 'data' must be of a vector typeArgument ij must be 2-column integer matrixArgument must be numeric-like atomic vectorMatrix exponential requires square, non-null matrixX must be a numeric (double precision) matrixX must be a real (numeric) matrixdata length [%d] is not a sub-multiple or multiple of the number of columns [%d]data length [%d] is not a sub-multiple or multiple of the number of rows [%d]data length exceeds size of matrixdgeMatrix_Schur: argument x must be a non-null square matrixdgeMatrix_Schur: dgees returned code %ddgeMatrix_Schur: first call to dgees faileddgeMatrix_exp: LAPACK routine dgebal returned %ddgeMatrix_exp: dgetrf returned error code %ddgeMatrix_exp: dgetrs returned error code %di and j must be integer vectors of the same lengthincorrect left cyclic shift, j (%d) < 0incorrect left cyclic shift, j (%d) >= k (%d)incorrect left cyclic shift, k (%d) > ldx (%d)invalid '%s' argumentinvalid 'ncol' value (< 0)invalid 'ncol' value (too large or NA)invalid 'nrow' value (< 0)invalid 'nrow' value (too large or NA)invalid class of 'value' in Csparse_subassign()invalid class of 'x' in Csparse_subassign()non-numeric matrix extentnumber of rows in y (%d) does not match number of rows in X (%d)programming error in Csparse_subassign() should never happenreplacement diagonal has wrong lengthsubscript 'i' out of bounds in M[ij]subscript 'j' out of bounds in M[ij]tol, given as %g, must be <= 1too many elements specifiedx[] <- val: val is coerced to logical for "%s" xx[] <- val: val should be integer or logical, is coerced to integer, for "%s" xy must be a numeric (double precision) matrixProject-Id-Version: Matrix 1.3-3 Report-Msgid-Bugs-To: PO-Revision-Date: 2021-04-14 12:18+0200 Last-Translator: Daniele Medri Language-Team: Italian https://github.com/dmedri/R-italian-lang Language: it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); X-Generator: Poedit 2.2.1 'data' dev'essere un tipo vettoreL'argomento ij dev'essere una matrice di interi con 2 colonneL'argomento dev'essere un vettore atomico numericoL'esponenziale della matrice richiede una matrice quadrata non nullaX deve essere una matrice numerica (doppia precisione)X dev'essere una matrice (numerica) realela lunghezza dati [%d] non è un sotto-multiplo o multiplo del numero di colonne [%d]la lunghezza dati [%d] non è un sotto-multiplo o multiplo del numero di righe [%d]la lunghezza dei dati eccede la dimensione della matricedgeMatrix_Schur: l'argomento x dev'essere una matrice quadrata non nulladgeMatrix_Schur: dgees ha restituito il codice %ddgeMatrix_Schur: prima chiamata a dgees fallitadgeMatrix_exp: la routine LAPACK dgebal ha restituito %ddgeMatrix_exp: dgetrf ha restituito il codice di errore %ddgeMatrix_exp: dgetrs ha restituito il codice di errore %di e j devono essere vettori di interi con la medesima lunghezzaspostamento ciclico sinistro errato, j (%d) < 0spostamento ciclico sinistro errato, j (%d) >= k (%d)spostamento ciclico sinistro errato, k (%d) > ldx (%d)argomento '%s' non validovalore 'ncol' non valido (< 0)valore 'ncol' non valido (troppo larga o NA)valore 'nrow' non valido (< 0)valore 'nrow' non valido (troppo largo o NA)classe di 'value' in Csparse_subassign() non validaclasse of 'x' in Csparse_subassign() non validaestensione della matrice non numericail numero di righe in y (%d) non corrisponde al numero di righe in X (%d)l'errore di programmazione in Csparse_subassign() non dovrebbe mai accaderela diagonale di ricambio ha una lunghezza erratasubscript 'i' fuori banda in M[ij]subscript 'j' fuori banda in M[ij]tol, indicato come %g, dev'essere <= 1specificati troppi elementix[] <- val: val è convertito in logico per x "%s"x[] <- val: val dovrebbe essere intero o logico, è convertito in intero, per x "%s"y dev'essere una matrice numerica (doppia precisione)Matrix/inst/po/it/LC_MESSAGES/R-Matrix.mo0000644000176200001440000004004414521047060017313 0ustar liggesusers,< 6 3( \ 9x  6 1 /; ,k ? : * #> b ,v ; # 4$LWq(0$#0Hy8'5:N5#,.?$RDw4D%6=\-7 *>ie""15gI"@@Q56(- Vw":91>3p:-@ ?N=2909=j51'*R&q$&B(S&|Bv?]"*;%'M"d)!9>AA 0+4\0`5# ,Y 7  O >*!Ii!<!:!H+",t""?4$;t$#$C$"%;;%8w%<%/%>&7\&0&%&&('<+'%h'':'$'o(1u(4(((4)':)@b).)#)')$*BC*D*$*5*+&+R+*k+^+F+K<,),>,8,C*-#n-#-2-#- .).).6. /X@/)//K/K/0?{0>0"01-/1#]1#11.1D1C02Pt2N2M36b3Z3_3DT4C444:5DM535S5"6%=6 c6E6606*7>7VS7.7*7H8wM8B8&92/9Hb9)999 :(:5F:.|:G:L:D@;;;); ;3;>3<Jr<<9M=6=7= =X>Ap>V>H ?FR?T?5?o],WOc?3j_Cs5}6P{ F<Xl%VfxSU#Hb)+g!zIra|9 1 Z*`/nA$4wmMKh\JB-0t&7DN2"E i;^d[qu'pL:Ry= @vQY(.>eGT~8k'%s()' is not yet implemented for representation '%s''%s()' is not yet implemented for element type '%s''A' must be a square matrix'NA' indices are not (yet?) supported for sparse Matrices'by' argument is much too small'diagonals' matrix must have %d columns (= length(k) )'diagonals' must have the same length (%d) as 'k''file' must be a character string or connection'force' must be (coercable to) TRUE or FALSE'giveCsparse' has been deprecated; setting 'repr = "T"' for you'giveCsparse' has been deprecated; will use 'repr' instead'lwd' must be NULL or non-negative numeric'ncol' is not a factor of length(x)'ncol' must be >= 0'nearPD()' did not converge in %d iterations'nrow' and 'ncol' must be the same when 'symmetric' is true'nrow' is not a factor of length(x)'nrow' must be >= 0'x' must have length nrow^2 when 'symmetric' is true'x' must inherit from "sparseVector".M.repl.i.2col(): 'i' has no integer column number; should never happen; please report.M.repl.i.2col(): drop 'matrix' case ... --> is not yet implemented[i] is not yet implemented --> is not yet implementedClass %s is not yet implementedCmp.Mat.atomic() should not be called for diagonalMatrixInternal bug: nargs()=%d; please reportInvalid assembled indicator: %sInvalid storage format: %sInvalid storage type: %sLogic.Mat.atomic() should not be called for diagonalMatrixMatrices must have same number of rows for arithmeticMatrix seems negative semi-definiteMust specify 'nrow' when 'symmetric' is trueNAs are not allowed in subscripted assignmentsNot a valid formatOnly numeric sparse matrices allowedRHS 'value' (class %s) matches 'ANY', but must match matrix class %s[ ] indexing not allowed: forgot a "," ?a sparseMatrix should rarely be centered: will not be sparse anymoreall() is not yet implementedc(,..) of different kinds, coercing all to 'rleDiff'column indices must be <= ncol(.) which is %ddim [product %d] do not match the length of object [%d]dimnames [%d] mismatch in %selement type '%s' not recognizedelement type 'complex' not yet implementedfile is not a MatrixMarket filefor symmetric band matrix, only specify upper or lower triangle hence, all k must have the same signhit a cycle (1) -- stop iterationshit a cycle (2) -- stop iterationsi1[1] == 0 ==> C-level verbosity will not happen!index larger than maximal %dindex must be numeric, logical or sparseVector for indexing sparseVectorsinefficient method used for "- e1"intermediate 'r' is of type %sinternal bug in "Compare" method (Cmp.Mat.atomic); please reportinternal bug in "Logic" method (Logic.Mat.atomic); please reportinternal bug: matrix 'i' in replTmat(): please reportinternal bug: missing 'i' in replTmat(): please reportinvalid 'col.names' string: %sinvalid 'data'invalid 'repr'; must be "C", "T", or "R"invalid (to - from)/by in seq(.)invalid character indexinginvalid nargs()= %dlength must be non-negative numberlength of 'center' must equal the number of columns of 'x'length of 'scale' must equal the number of columns of 'x'length of 1st arg does not match dimension of 2ndlength of 2nd arg does not match dimension of firstlogic programming error in printSpMatrix2(), please reportlogical subscript too long (%d, should be %d)longer object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthm[ ] <- v: inefficiently treating single elementsmatrix can only be symmetric if square, but n != mmust either specify 'A' or the functions 'A.x' and 'At.x'nargs() = %d should never happen; please report.nargs() = %d. Extraneous illegal arguments inside '[ .. ]' ?negative values are not allowed in a matrix subscriptno 'dimnames[[.]]': cannot use character indexingnon-conformable argumentsnon-conformable matrix dimensions in %snot converged in %d iterationsnot enough new vecs -- stop iterationsnot yet implementednot yet implemented .. please reportnot-yet-implemented 'Matrix[<-' methodnothing to replace withnumber of items to replace is not a multiple of replacement lengthnumber of rows are not compatible for %sprod() is not yet implementedqr2rankMatrix(.): QR with only %d out of %d finite diag(R) entriesrankMatrix(, method = '%s') coerces to dense matrix. Probably should rather use method = 'qr' !?rankMatrix(x, method='qr'): computing t(x) as nrow(x) < ncol(x)representation '%s' not recognizedrow indices must be <= nrow(.) which is %dsuch indexing must be by logical or 2-column numeric matrixsum() is not yet implementedsuppressing %d columnssuppressing %d columns and %d rowssuppressing %d rowssymmetric matrix must be squaresymmetry form '%s' is not yet implementedsymmetry form '%s' not recognizedsymmetry form 'hermitian' not yet implemented for readingsymmetry form 'skew-symmetric' not yet implemented for readingthe %d-th (sub)-diagonal (k = %d) is too short; filling with NA'stoo many argumentstoo many replacement valuestriangular matrix must be squaretype '%s' not recognizeduniDiag=TRUE, but not all diagonal entries are 1uniDiag=TRUE, not all entries in diagonal coded as 1using "old code" part in Csparse subassignmentusing"old code" part in Csparse subassignment >>> please report to Matrix-authors@r-project.orgvariable '%s' is absent, its contrast will be ignoredvector too long in Matrix - vector operationwhen 'A' is specified, 'A.x' and 'At.x' are disregardedwrong sign in 'by' argumentx / 0 for an x with sign-change no longer representable as 'rleDiff'x[.,.] <- val : x being coerced from Tsparse* to CsparseMatrixx[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced NA |--> TRUE.x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced.x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced.x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced; NA |--> TRUE.you cannot mix negative and positive indicesProject-Id-Version: R-Matrix 1.3-3 Report-Msgid-Bugs-To: bugs.r-project.org PO-Revision-Date: 2021-04-14 12:18+0200 Last-Translator: Daniele Medri Language-Team: Italian https://github.com/dmedri/R-italian-lang Language: it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); X-Generator: Poedit 2.2.1 '%s()' non è ancora implementato per la rappresentazione '%s''%s()' non è ancora implementato per il tipo elemento '%s''A' dev'essere una matrice quadratagli indici 'NA' non sono (ancora?) supportati per le matrici sparsel'argomento 'by' è troppo piccolola matrice 'diagonals' deve avere %d colonne (= length(k) )'diagonals' deve avere la medesima lunghezza (%d) di 'k''file' dev'essere una stringa di caratteri o una connessione'force' dev'essere (coercibile in) TRUE o FALSE'giveCsparse' è stato deprecato; viene impostato 'repr = "T"''giveCsparse' è stato deprecato; si utilizzerà 'repr''lwd' dev'essere NULL o un numerico non negativo'ncol' non è un fattore di length(x)'ncol' dev'essere >= 0'nearPD()' non converge in %d iterazioni'nrow' e 'ncol' dev'essere uguali quando 'symmetric' è true'nrow' non è un fattore di length(x)'nrow' dev'essere >= 0'x' deve avere lunghezza nrow^2 quando 'symmetric' è true'x' deve ereditare da "sparseVector".M.repl.i.2col(): 'i' non ha un numero di colonna intero; non dovrebbe mai accadere; per piacere, segnalatelo.M.repl.i.2col(): si elimina il caso 'matrix' ... --> non è ancora implementato[i] non è ancora implementato --> non è ancora implementatoLa classe %s non è ancora implementataCmp.Mat.atomic() non dovrebbe essere chiamata per diagonalMatrixBug interno: nargs()=%d; per piacere riportaloIndicatore assemblato non valido:%sFormato di archiviazione non valido: %sTipo di archiviazione non valido: %sLogic.Mat.atomic() non dovrebbe essere chiamato per diagonalMatrixLe matrici devono avere il medesimo numero di righe per l'aritmeticaMatrix sembra semi-definito negativoBisogna specificare 'nrow' quando 'symmetric' è trueNA non ammessi nelle assegnazioni subscriptNon è un formato validoSono ammesse solo matrici sparse numericheRHS 'value' (classe %s) corrisponde a 'ANY', ma deve corrispondere ad una classe di matrice %s[ ] indicizzazione non ammessa: si è dimenticato un "," ?una sparseMatrix dovrebbe essere raramente centrata: non sarà più sparsa.all() non è ancora implementatoc(,..) di diverso tipo, convertendo tutto a 'rleDiff'gli indici di colonna devono essere <= ncol(.) e sono %ddim [product %d] non corrisponde con la lunghezza dell'oggetto [%d]dimnames [%d] non corrisponde in %stipo elemento '%s' non riconosciutotipo di elemento 'complex' non ancora implementatoil file non è un file MatrixMarketper la matrice di bande simmetriche, specificare solo il triangolo superiore o inferiore poi, tutti i k devono avere lo stesso segnofine ciclo (1) - interrompe le iterazionifine ciclo (2) - interrompe le iterazionii1[1] == 0 ==> la verbosità a livello C non accadrà!indice più largo del massimo %dl'indice dev'essere numerico, logico o sparseVector per l'indicizzazione di sparseVectorutilizzato metodo inefficiente per "- e1"la 'r' intermedia è di tipo %sbug interno nel metodo "Compare" (Cmp.Mat.atomic); per piacere, riportatelobug interno nel metodo "Logic" (Logic.Mat.atomic); per piacere, segnalatelobug interno: matrix 'i' in replTmat(): per piacere, riportatelobug interno: manca 'i' in replTmat(): per piacere, riportatelostringa 'col.names' non valida: %s'data' non valido'repr' non valido; dev'essere "C", "T", o "R"(to - from)/by in seq(.) non validoindicizzazione carattere non validanargs()= %d non validola lunghezza dev'essere un numero non negativola lunghezza di 'center' deve eguagliare il numero di colonne di 'x'la lunghezza di 'scale' deve eguagliare il numero di colonne di 'x'la lunghezza del primo argomento non corrisponde con la dimensione della secondala lunghezza del secondo argomento non corrisponde con la dimensione del primoerrore di programmazione logica in printSpMatrix2(), per piacere, riportatelosubscript logico troppo lungo (%d, dovrebbe essere %d)la lunghezza dell'oggetto più lungo non è un multiplo di lunghezza di quello più cortola lunghezza più lunga dell'oggetto non è un multiplo della lunghezza più corta dell'oggettom[ ] <- v: trattamento inefficiente dei singoli elementila matrice può essere unicamente simmetrica se quadrata, ma n != msi deve specificare 'A' o le funzioni 'A.x' e 'At.x'nargs() = %d non dovrebbe accadere; per piacere riportalo.nargs() = %d. Argomenti illegali estranei all'interno di '[ .. ]' ?valori negativi non ammessi in subscript di matricenessuna 'dimnames[[.]]': non è possibile utilizzare l'indicizzazione dei caratterigli argomenti non sono compatibilidimensioni matrice non conformi in %snon convergente in %d iterazioninon ci sono abbastanza nuovi vettori -- si interrompono le iterazioninon ancora implementatonon ancora implementato .. per piacere riportalometodo 'Matrix[<-' non ancora implementatoniente da sostituireil numero di articoli da sostituire non è un multiplo della lunghezza di sostituzioneil numero di righe non sono compatibili per %sprod() non è ancora implementatoqr2rankMatrix(.): QR con solo %d elementi fuori dai %d finiti di diag(R)rankMatrix(, method = '%s') convertito in matrice densa. Non si dovrebbe provare method = 'qr' !?rankMatrix(x, method='qr'): calcolando t(x) come nrow(x) < ncol(x)rappresentazione '%s' non riconosciutagli indici riga devono essere <= nrow(.) e sono %dtale indicizzazione dev'essere per matrice logica o numerica a 2 colonnesum() non è ancora implementatosoppresse %d colonnesoppresse %d colonne e %d righesoppresse %d righela matrice simmetrica dev'esser quadratala forma di simmetria '%s' non è ancora implementatala forma di simmetria '%s' non è riconosciutala forma di simmetria 'hermitian' non è ancora implementata in letturala forma di simmetria 'skew-symmetric' non è ancora implementata in letturala %d' (sotto)-diagonale (k = %d) è troppo corta; si riempie con NAtroppi argomentitroppi valori di sostituzionela matrice triangolare dev'esser quadratail tipo '%s' non è riconosciutouniDiag=TRUE, ma non tutte le voci diagonali sono 1uniDiag=TRUE, non tutte le voci in diagonale codificate come 1si utilizza una parte di "vecchio codice" nel sotto-assegnamento Csparsesi utilizza una parte di "vecchio codice" nel sotto-assegnamento Csparse >>> per piacere, riportatelo agli autori Matrix-authors@r-project.orgvariabile '%s' assente, i suoi contrasti saranno ignorativettore troppo lungo in Matrix - operazione vettorialequando 'A' è specificato, 'A.x' e 'At.x' sono ignoratisegno errato nell'argomento 'by'x / 0 per un x con cambio di segno non è più rappresentabile come 'rleDiff'x[.,.] <- val : x è stato convertito da Tsparse* a CsparseMatrixx[.,.] <- val: x è %s, il valore esterno a {TRUE, FALSE} è convertito; NA |--> TRUE.x[.,.] <- val: x è %s, il valore esterno a {TRUE, FALSE} è convertito.x[.] <- val: x è %s, il valore esterno a {TRUE, FALSE} è convertito.x[.] <- val: x è %s, il valore esterno a {TRUE, FALSE} è convertito; NA |--> TRUE.non è possibile mischiare indici negativi e positiviMatrix/inst/po/de/0000755000176200001440000000000014547723665013524 5ustar liggesusersMatrix/inst/po/de/LC_MESSAGES/0000755000176200001440000000000014547723665015311 5ustar liggesusersMatrix/inst/po/de/LC_MESSAGES/Matrix.mo0000644000176200001440000001130614521047060017067 0ustar liggesusers&L5|PQ+q+3-!+PMM"<'L+t0,,2+'^-.&;&V/}+@<4%q$$ 0 OM - _ + :J ' E 9 *- RX Q - L+ 0x 7 3 //E=u067S$m1$140P"G7.$.S.#:_,9 &   $ #!"% 'data' must be of a vector typeArgument ij must be 2-column integer matrixArgument must be numeric-like atomic vectorMatrix exponential requires square, non-null matrixX must be a numeric (double precision) matrixX must be a real (numeric) matrixdata length [%d] is not a sub-multiple or multiple of the number of columns [%d]data length [%d] is not a sub-multiple or multiple of the number of rows [%d]data length exceeds size of matrixdgeMatrix_Schur: argument x must be a non-null square matrixdgeMatrix_Schur: dgees returned code %ddgeMatrix_Schur: first call to dgees faileddgeMatrix_exp: LAPACK routine dgebal returned %ddgeMatrix_exp: dgetrf returned error code %ddgeMatrix_exp: dgetrs returned error code %di and j must be integer vectors of the same lengthincorrect left cyclic shift, j (%d) < 0incorrect left cyclic shift, j (%d) >= k (%d)incorrect left cyclic shift, k (%d) > ldx (%d)invalid '%s' argumentinvalid 'ncol' value (< 0)invalid 'ncol' value (too large or NA)invalid 'nrow' value (< 0)invalid 'nrow' value (too large or NA)invalid class of 'value' in Csparse_subassign()invalid class of 'x' in Csparse_subassign()non-numeric matrix extentnumber of rows in y (%d) does not match number of rows in X (%d)programming error in Csparse_subassign() should never happenreplacement diagonal has wrong lengthsubscript 'i' out of bounds in M[ij]subscript 'j' out of bounds in M[ij]tol, given as %g, must be <= 1too many elements specifiedx[] <- val: val is coerced to logical for "%s" xx[] <- val: val should be integer or logical, is coerced to integer, for "%s" xy must be a numeric (double precision) matrixProject-Id-Version: R 4.0.4 / Matrix 1.3-3 Report-Msgid-Bugs-To: PO-Revision-Date: 2021-02-11 13:00+0100 Last-Translator: Detlef Steuer Language-Team: R Core Language: de MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); 'data' muss ein Vektortyp seinArgument ij muss eine zweispaltige ganzzahlige Matrix seinArgument muss zahl-ähnlich atomar seinExponentielle Matrix benötigt eine quadratische Matrix ungleich NullX muss eine numerische (doppelte Genauigkeit) Matrix seinX muss eine echte (numerische) Matrix seinDatenlänge [%d] ist kein Teilvielfaches oder Vielfaches der Zahl der Spalten [%d]Datenlänge [%d] ist kein Teilvielfaches oder Vielfaches der Zahl der Zeilen [%d]Datenlänge überschreitet Größe der MatrixdgeMatrix_Schur: Argument x muss eine quadratische Matrix ungleich Null seindgeMatrix_Schur: dgees gab Fehlerkode %d zurückdgeMatrix_Schur: Erster Aufruf von dgees fehlgeschlagendgeMatrix_exp: LAPACK-Routine dgebal gab %d zurückdgeMatrix_exp: dgetrf gab Fehlerkode %d zurückdgeMatrix_exp: dgetrs gab Fehlerkode %d zurücki und j müssen Ganzzahlvektoren mit der gleichen Länge seinfalsches zyklisches Linksverschieben, j (%d) < 0falsches zyklisches Linksverschieben, j (%d) >= k (%d)falsches zyklisches Linksverschieben, k (%d) > ldx (%d)ungültiges '%s' Argumentunzulässiger Wert für 'ncol' (< 0)unzulässiger Wert für 'ncol' (zu groß oder NA)unzulässiger Wert für 'nrow' (< 0)unzulässiger Wert für 'nrow' (zu groß oder NA)ungültige Klasse von 'value' in Csparse_subassign()ungültige Klasse von 'x' in Csparse_subassign()nicht-numerische Matrix-AusdehnungAnzahl der Zeilen in y (%d) passt nicht zur Anzahl der Zeilen in X (%d)Fehler in Csparse_subassign(); sollte niemals vorkommenDiagonale zur Ersetzung hat die falsche LängeSubskript 'i' außerhalb des Bereichs in M[ij]Subskript 'j' außerhalb des Bereichs in M[ij]tol, als %g gegeben, muss <= 1 seinzu viele Elemente angegebenx[] <- val: val in booleschen Wert umgewandelt für "%s" xx[] <- val: val sollte ganzzahlig oder logisch sein, wird in ganze Zahl umgewandelt für "%s" xy muss eine numerische (doppelte Genauigkeit) Matrix seinMatrix/inst/po/de/LC_MESSAGES/R-Matrix.mo0000644000176200001440000003664114521047060017277 0ustar liggesusers  6 3 , 9H  6 1 / ,; *h #  , ; #4 X 4l $ W (0G$x08''Oo:5#,8.e$D4DF%=-7U r*e"D"g1I"#F@e@56Ts ":901j3:- @9?z=29+0e=51 <'V~&$&$B<(&Bv?"*;%Sy")!93>mA >0W40`5O,7O >V I < :!HW!,!m!9;#8u#&#K#!$7<$6t$2$4$1%$E%j%0%L%$%#&A9&'{&^&-'30')d'3'"'C'))()S(}((E(@(*?)Cj)1))#)L*;g*d*++R4+2+8+ +,-2,"`,,6-6:-3q--S-(.#B.Jf.K.:.=8/'v//&///) 0<70;t0;0A0@.10o1E1D1>+2Gj2>272B)3;l3C33&4+,45X44)4-44J5.a5,5I5}6@6"616L7+h77,77)7+(8 T8<u8A8M8B9U9$m9969D99%:m_:1:/:G/;$w;[;@;R9<D<D<R=7i=lt*TL`=1g\@ ~p3z4MxC:Ui#Scu|PR!E_')dwFo^y7/ W(]-kZ"2jJHeYG?+.q$5AK0 B f9[aXnr%mI8Ov; >}sNV&,<bDQ{6h'%s()' is not yet implemented for representation '%s''%s()' is not yet implemented for element type '%s''A' must be a square matrix'NA' indices are not (yet?) supported for sparse Matrices'by' argument is much too small'diagonals' matrix must have %d columns (= length(k) )'diagonals' must have the same length (%d) as 'k''file' must be a character string or connection'force' must be (coercable to) TRUE or FALSE'lwd' must be NULL or non-negative numeric'ncol' is not a factor of length(x)'ncol' must be >= 0'nearPD()' did not converge in %d iterations'nrow' and 'ncol' must be the same when 'symmetric' is true'nrow' is not a factor of length(x)'nrow' must be >= 0'x' must have length nrow^2 when 'symmetric' is true'x' must inherit from "sparseVector".M.repl.i.2col(): 'i' has no integer column number; should never happen; please report.M.repl.i.2col(): drop 'matrix' case ... --> is not yet implemented[i] is not yet implemented --> is not yet implementedClass %s is not yet implementedCmp.Mat.atomic() should not be called for diagonalMatrixInternal bug: nargs()=%d; please reportInvalid assembled indicator: %sInvalid storage format: %sInvalid storage type: %sLogic.Mat.atomic() should not be called for diagonalMatrixMatrices must have same number of rows for arithmeticMatrix seems negative semi-definiteMust specify 'nrow' when 'symmetric' is trueNAs are not allowed in subscripted assignmentsNot a valid formatOnly numeric sparse matrices allowedRHS 'value' (class %s) matches 'ANY', but must match matrix class %s[ ] indexing not allowed: forgot a "," ?a sparseMatrix should rarely be centered: will not be sparse anymoreall() is not yet implementedc(,..) of different kinds, coercing all to 'rleDiff'column indices must be <= ncol(.) which is %ddim [product %d] do not match the length of object [%d]dimnames [%d] mismatch in %selement type '%s' not recognizedelement type 'complex' not yet implementedfile is not a MatrixMarket filefor symmetric band matrix, only specify upper or lower triangle hence, all k must have the same signhit a cycle (1) -- stop iterationshit a cycle (2) -- stop iterationsi1[1] == 0 ==> C-level verbosity will not happen!index larger than maximal %dindex must be numeric, logical or sparseVector for indexing sparseVectorsinefficient method used for "- e1"intermediate 'r' is of type %sinternal bug in "Compare" method (Cmp.Mat.atomic); please reportinternal bug in "Logic" method (Logic.Mat.atomic); please reportinternal bug: matrix 'i' in replTmat(): please reportinternal bug: missing 'i' in replTmat(): please reportinvalid 'col.names' string: %sinvalid 'data'invalid (to - from)/by in seq(.)invalid character indexinginvalid nargs()= %dlength must be non-negative numberlength of 'center' must equal the number of columns of 'x'length of 'scale' must equal the number of columns of 'x'length of 1st arg does not match dimension of 2ndlength of 2nd arg does not match dimension of firstlogic programming error in printSpMatrix2(), please reportlogical subscript too long (%d, should be %d)longer object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthm[ ] <- v: inefficiently treating single elementsmatrix can only be symmetric if square, but n != mmust either specify 'A' or the functions 'A.x' and 'At.x'nargs() = %d should never happen; please report.nargs() = %d. Extraneous illegal arguments inside '[ .. ]' ?negative values are not allowed in a matrix subscriptno 'dimnames[[.]]': cannot use character indexingnon-conformable argumentsnon-conformable matrix dimensions in %snot converged in %d iterationsnot enough new vecs -- stop iterationsnot yet implementednot yet implemented .. please reportnot-yet-implemented 'Matrix[<-' methodnothing to replace withnumber of items to replace is not a multiple of replacement lengthnumber of rows are not compatible for %sprod() is not yet implementedqr2rankMatrix(.): QR with only %d out of %d finite diag(R) entriesrankMatrix(, method = '%s') coerces to dense matrix. Probably should rather use method = 'qr' !?rankMatrix(x, method='qr'): computing t(x) as nrow(x) < ncol(x)representation '%s' not recognizedrow indices must be <= nrow(.) which is %dsuch indexing must be by logical or 2-column numeric matrixsum() is not yet implementedsuppressing %d columnssuppressing %d columns and %d rowssuppressing %d rowssymmetric matrix must be squaresymmetry form '%s' is not yet implementedsymmetry form '%s' not recognizedsymmetry form 'hermitian' not yet implemented for readingsymmetry form 'skew-symmetric' not yet implemented for readingthe %d-th (sub)-diagonal (k = %d) is too short; filling with NA'stoo many argumentstoo many replacement valuestriangular matrix must be squaretype '%s' not recognizeduniDiag=TRUE, but not all diagonal entries are 1uniDiag=TRUE, not all entries in diagonal coded as 1using "old code" part in Csparse subassignmentusing"old code" part in Csparse subassignment >>> please report to Matrix-authors@r-project.orgvariable '%s' is absent, its contrast will be ignoredvector too long in Matrix - vector operationwhen 'A' is specified, 'A.x' and 'At.x' are disregardedwrong sign in 'by' argumentx / 0 for an x with sign-change no longer representable as 'rleDiff'x[.,.] <- val : x being coerced from Tsparse* to CsparseMatrixx[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced NA |--> TRUE.x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced.x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced.x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced; NA |--> TRUE.you cannot mix negative and positive indicesProject-Id-Version: R 4.0.0 / matrix 1.3-0 Report-Msgid-Bugs-To: bugs.r-project.org PO-Revision-Date: 2020-04-01 16:01+0200 Last-Translator: Detlef Steuer Language-Team: R-Core Language: de MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); '%s()' ist noch nicht implementiert für Darstellung '%s''%s()' ist noch nicht für Elementtyp '%s' implementiert'A' muss eine quadratische Matrix sein'NA'-Indizes werden (noch?) nicht für dünn besetzte Matrizen unterstütztArgument 'by' ist zu klein'diagonals'-Matrix muss %d Spalten haben (= length(k) )'diagonals' muss die gleiche Länge (%d) wie 'k' haben'file' muss eine Zeichenkette oder Verbindung sein'force' muss (umwandelbar nach) TRUE oder FALSE sein'lwd' muss NULL oder nicht negativ numerisch sein'ncol' ist kein Faktor von length(x)'ncol' muss >= 0 seinnearPD() ist nicht in %d Iterationen konvergiert'nrow' und 'ncol' müssen gleich sein, wenn 'symmetric' auf true gesetzt ist'nrow' ist kein Faktor von length(x)'nrow' muss >= 0 sein'x' muss die Länge nrow^2, wenn 'symmetric' auf true gesetzt ist'x' muss von "sparseVector" geerbt sein.M.repl.i.2col(): 'i' hat keine ganzzahlige Spaltennummer. Sollte nie passieren. Bitte melden..M.repl.i.2col(): 'matrix'-Fall weglassen ... --> ist noch nicht implementiert[i] ist noch nicht implementiert --> ist noch nicht implementiertKlasse %s noch nicht implementiertCmp.Mat.atomic() sollte nicht für diagonalMatrix aufgerufen werdenInterner Fehler: nargs()=%d; bitte meldenUngültig zusammengesetzter Indikator: %sUngültiges Speicherformat: %sUngültiger Speichertyp: %sLogic.mat.atomic() sollte für diagonalMatrix nicht aufgerufen werdenMatrizen müssen für Arithmetik die gleiche Anzahl Zeilen habenMatrix scheint negativ semidefinit zu sein'nrow' muss angegeben werden, wenn 'symmetric' auf true gesetzt istNAs sind in indexierten Anweisungen nicht erlaubtKein gültiges FormatNur dünn besetzte Matrizen erlaubtRHS 'value' (Klasse %s) passt zu 'ANY', muss aber zur Matrixklasse %s passen[ ] Indexierung nicht erlaubt: Ein ',' vergessen?eine schwach besetze Matrix sollte kaum je zentriert werden: sie ist dann nicht mehr schwach besetztall() ist noch nicht implementiertc(,..) von unterschiedlichen Arten, alle werden in 'rleDiff' umgewandeltSpaltenindizes müssen <= ncol(.) sein, das ist %ddim [produkt %d] passt nicht zur Länge des Objekts [%d]dimnames [%d] passen nicht in %sElementtyp '%s' nicht erkanntElementtyp 'complex' noch nicht implementiertDatei ist keine MatrixMarket-Dateigeben Sie für symmetrische Bandmatrizen nur oberes oder unteres Dreieck an. deshalb müssen alle k dasselbe Vorzeichen haben.auf einen Zyklus getroffen (1) – Iterationen stoppenauf einen Zyklus getroffen (2) – Iterationen stoppeni1[1] == 0 ==> C-Ebene wird nicht detailliert sein!Index größer als maximales %dIndex muss numerisch, logisch oder sparseVector sein, um sparseVector zu indizierenineffiziente Methode für '- e1' benutztZwischenergebnis 'r' ist vom Typ %sinterner Fehler in der "Compare"-Methode (Cmp.Mat.atomic). Bitte berichteninterner Fehler in der "Logic"-Methode (.Logic.Mat.atomic). Bitte berichteninterner Fehler: Matrix 'i' in replTmat(): Bitte berichteninterner Fehler: Fehlendes 'i' in replTmat(): Bitte berichtenungültige 'col.names'-Zeichenkette: %sungültiges 'data'unzulässiges (to - from)/by in seq(.)ungültige Zeichenindexierungungültige nargs()= %dLänge muss eine nicht negative Zahl seinLänge von 'center' muss der Spaltenzahl von 'x' entsprechenLänge von 'scale' muss der Spaltenzahl von 'x' entsprechenLänge des ersten arg passt nicht zur Dimension des zweitenLänge des zweiten Arguments passt nicht zur Dimension des erstenlogischer Programmierfehler in printSpMatrix2(), bitte berichtenlogisches Subskript zu lang (%d, sollte %d sein)längere Objektlänge ist kein Vielfaches der kürzeren Objektlängelängere Objektlänge ist kein Vielfaches der kürzeren Objektlängem[ ] <- v: Einzelne Elemente ineffizient behandeltMatrix kann nur symmetrisch sein, wenn sie quadratisch ist, aber n != mmuss entweder 'A' angeben oder die Funktionen 'A.x' und 'At.x'nargs() = %d sollte niemals vorkommen. Bitte berichten.nargs() = %d. Irrelevante ungültige Argumente innerhalb '[ .. ]'?negative Werte sind in einer Matrix-Subskript nicht erlaubtkeine 'dimnames[[.]]': Zeichenindexierung kann nicht benutzt werdennicht passende Argumentenicht konforme Matrixdimensionen in %snicht konvergiert in %d Iterationsschrittennicht genügend neue Vektoren – Iterationen stoppennoch nicht implementiertnoch nicht implementiert ... bitte meldennoch nicht implementierte 'Matrix[<-'-Methodenichts zu ersetzen mitAnzahl der zu ersetzenden Elemente ist kein Vielfaches der AustauschlängeAnzahl der Zeilen ist nicht kompatibel für %sprod() ist noch nicht implementiertqr2rankMatrix(.): QR Zerlegung mit nur %d von %d endlichen diag(R) WertenrankMatrix(, method = '%s') wird in dicht besetzte Matrix umgewandelt. Evtl. eher method = 'qr' nutzen? rankMatrix(x, method='qr'): t(x) berechnet, da nrow(x) < ncol(x)Repräsentation '%s' nicht erkanntZeilenindizes müssen <= nrow(.) sein, das ist %dsolche Indexierung muss von logischer oder 2-spaltig numerischer Matrix seinsum() ist noch nicht implementiert%d Spalten werden unterdrückt%d Spalten und %d Zeilen werden unterdrückt%d Zeilen werden unterdrücktsymmetrische Matrix muss quadratisch seinSymmetrieform '%s' noch nicht implementiertSymmetrieform '%s' nicht erkanntSymmetrieform 'hermitian' noch nicht zum Lesen implementiertSymmetrieform 'skew-symmetric' noch nicht zum Lesen implementiertdie %d-te (Unter)-Diagonale (k = %d) ist zu kurz und wird mit NA aufgefülltzu viele Argumentezu viele AustauschwerteDreiecksmatrix muss quadratisch seinTyp '%s' nicht erkanntuniDiag=TRUE, aber nicht alle Diagonaleinträge sind 1uniDiag=TRUE, aber nicht alle Einträge der Diagonalen als 1 kodiertbenutzt wird 'alter Kode'-Teil in Csparse-Unterzuweisungbenutzt wird 'alter Kode'-Teil in Csparse-Unterzuweisung >>> bitte an Matrix-authors@r-project.org berichtenVariable '%s' fehlt, ihr Kontrast wird irgnoriertVektor zu lang in der Matrix - Vektor Operationwenn 'A' angegeben wurde, werden 'A.x' und 'At.x' nicht berücksichtigtfalsches Vorzeichen im Argument 'by'x / 0 für einen x mit Vorzeichenwechsel nicht länger als 'rleDiff' darstellbarx[.,.] <- val : x wird von Tsparse* in CsparseMatrix umgewandeltx[.,.] <- val: x ist %s, val nicht in {TRUE, FALSE} wird umgewandelt NA |--> TRUE.x[.,.] <- val: x ist %s, val nicht in {TRUE, FALSE} wird umgewandeltx[.] <- val: x ist %s, val nicht in {TRUE, FALSE}, wird umgewandelt.x[.] <- val: x ist %s, val nicht in {TRUE, FALSE}, wird umgewandelt; NA |--> TRUE.Sie können positive und negative Indizes nicht mischenMatrix/inst/po/pl/0000755000176200001440000000000014547723665013547 5ustar liggesusersMatrix/inst/po/pl/LC_MESSAGES/0000755000176200001440000000000014547723665015334 5ustar liggesusersMatrix/inst/po/pl/LC_MESSAGES/Matrix.mo0000644000176200001440000001167714521047060017125 0ustar liggesusers%D5l@A+a+3-!P=M"<'<+d0,,2'N-v.&+&F/m+@<$$a$0O -g  v A . @ 9E 0 ] ^ -m G 4 I8b;;L4`:; "&:I":95RFoM""'?J M9 % # " !$ 'data' must be of a vector typeArgument ij must be 2-column integer matrixArgument must be numeric-like atomic vectorMatrix exponential requires square, non-null matrixX must be a numeric (double precision) matrixX must be a real (numeric) matrixdata length [%d] is not a sub-multiple or multiple of the number of columns [%d]data length [%d] is not a sub-multiple or multiple of the number of rows [%d]data length exceeds size of matrixdgeMatrix_Schur: argument x must be a non-null square matrixdgeMatrix_Schur: dgees returned code %ddgeMatrix_Schur: first call to dgees faileddgeMatrix_exp: LAPACK routine dgebal returned %ddgeMatrix_exp: dgetrf returned error code %ddgeMatrix_exp: dgetrs returned error code %di and j must be integer vectors of the same lengthincorrect left cyclic shift, j (%d) < 0incorrect left cyclic shift, j (%d) >= k (%d)incorrect left cyclic shift, k (%d) > ldx (%d)invalid '%s' argumentinvalid 'ncol' value (< 0)invalid 'ncol' value (too large or NA)invalid 'nrow' value (< 0)invalid 'nrow' value (too large or NA)invalid class of 'value' in Csparse_subassign()invalid class of 'x' in Csparse_subassign()non-numeric matrix extentnumber of rows in y (%d) does not match number of rows in X (%d)programming error in Csparse_subassign() should never happensubscript 'i' out of bounds in M[ij]subscript 'j' out of bounds in M[ij]tol, given as %g, must be <= 1too many elements specifiedx[] <- val: val is coerced to logical for "%s" xx[] <- val: val should be integer or logical, is coerced to integer, for "%s" xy must be a numeric (double precision) matrixProject-Id-Version: Matrix 1.1-2-2 Report-Msgid-Bugs-To: PO-Revision-Date: 2014-03-24 17:53+0100 Last-Translator: Łukasz Daniel Language-Team: Łukasz Daniel Language: pl_PL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); X-Poedit-SourceCharset: iso-8859-1 X-Generator: Poedit 1.5.4 'data' musi być type wektorArgument 'ij' musi być 2-kolumnową macierzą liczb całkowitychArgument musi być atomowym wektorem liczbowymEksponencjowanie macierzy wymaga kwadratowej, niepustej macierzy'X' musi być macierzą liczbową (o podwójnej precyzji)'X' musi być rzeczywistą (liczbową) macierządługość danych [%d] nie jest podwielokrotnością lub wielokrotnością liczby kolumn [%d]długość danych [%d] nie jest podwielokrotnością lub wielokrotnością liczby wierszy [%d]długość danych przekracza rozmiar macierzydgeMatrix_Schur: argument 'x' musi być niepustą macierzą kwadratowądgeMatrix_Schur: funkcja 'dgees()' zwróciła kod %ddgeMatrix_Schur: pierwsze wywołanie funkcji 'dgees()' nie powiodło siędgeMatrix_exp: procedura LAPACK 'dgebal()' zwróciła %ddgeMatrix_exp: funkcja 'dgetrf()' zwróciła kod błędu %ddgeMatrix_exp: funkcja 'dgetrs()' zwróciła kod błędu %d'i' oraz 'j' muszą być wektorami liczb całkowitych o tej samej długościniepoprawne lewe cykliczne przesunięcie, j (%d) < 0niepoprawne lewe cykliczne przesunięcie, j (%d) >= k (%d)niepoprawne lewe cykliczne przesunięcie, k (%d) > ldx (%d)niepoprawny argument '%s'niepoprawna wartość 'ncol' (< 0)niepoprawna wartość 'ncol' (zbyt duża lub wartość NA)niepoprawna wartość 'nrow' (< 0)niepoprawna wartość 'nrow' (zbyt duża lub wartość NA)niepoprawna klasa 'value' w funkcji 'Csparse_subassign()'niepoprawna klasa 'x' w funkcji 'Csparse_subassign()'nieliczbowy rozmiar macierzyliczba wierszy w 'y' (%d) nie zgadza się z liczbą wierszy w 'X' (%d)błąd programowy w funkcji 'Csparse_subassign()' nie powinien się wydarzyćindeks 'i' poza zakresem w 'M[ij]'indeks 'j' poza zakresem w 'M[ij]'argument 'tol', podany jako %g, musi być mniejszy lub równy 1określono zbyt dużo elementówx[] <- val: 'val' została przekształcone w wartość logiczną dla "%s" 'x'x[] <- val: 'val' powinno być liczbą całkowitą lub wartością logiczną, została przekształcona na liczbę całkowitą, dla "%s" 'x''y' musi być macierzą liczbową (o podwójnej precyzji)Matrix/inst/po/pl/LC_MESSAGES/R-Matrix.mo0000644000176200001440000003556514502411615017326 0ustar liggesuserssL 6 3 , 9H  6 1 / ,; *h #  , ; #4 X 4l $ W ( 0G $x 0  8 ''Oo:5#,8.e$D4%F=l-7 -*Nye"""1EwI"@ @a56. =^y"13:-Q@?=9>0x=51'Ow&$&B5(x&v??"*;% /)O!y9>AVi0`50,f7O>7Iv<:H8,? ? #!!?E!$!9!7!8"6U";"1""8#UI#1##L#44$zi$/$:%1O%:%*%C%8+&$d&%&"&E&h'+'>'<')(/<(Wl(@(2)O8)8)?)&*((*8Q*)**07+0h+>+,+,%,,R,S -Ht-H-%.,.'?.!g..'.C.C /GP/7/X/W)0G050D0=D171A11$25A2w272.22]3%l3333BU4*494b42`5(585.5S$6Xx6K67$47Y78y7|7>/81n888"8Y8QV9l9_:]u:k:5?; -+ _[;CG=,M4PO:W8S!ld".)Tr?J2qQ7RU5*3 ji1n0$Y &IAZV'%bkEHKa9` c6s@\ L^#D]m<pXeo>(gBhfFN/'%s()' is not yet implemented for representation '%s''%s()' is not yet implemented for element type '%s''A' must be a square matrix'NA' indices are not (yet?) supported for sparse Matrices'by' argument is much too small'diagonals' matrix must have %d columns (= length(k) )'diagonals' must have the same length (%d) as 'k''file' must be a character string or connection'force' must be (coercable to) TRUE or FALSE'lwd' must be NULL or non-negative numeric'ncol' is not a factor of length(x)'ncol' must be >= 0'nearPD()' did not converge in %d iterations'nrow' and 'ncol' must be the same when 'symmetric' is true'nrow' is not a factor of length(x)'nrow' must be >= 0'x' must have length nrow^2 when 'symmetric' is true'x' must inherit from "sparseVector".M.repl.i.2col(): 'i' has no integer column number; should never happen; please report.M.repl.i.2col(): drop 'matrix' case ... --> is not yet implemented[i] is not yet implemented --> is not yet implementedClass %s is not yet implementedCmp.Mat.atomic() should not be called for diagonalMatrixInternal bug: nargs()=%d; please reportInvalid assembled indicator: %sInvalid storage format: %sInvalid storage type: %sLogic.Mat.atomic() should not be called for diagonalMatrixMatrices must have same number of rows for arithmeticMatrix seems negative semi-definiteMust specify 'nrow' when 'symmetric' is trueNAs are not allowed in subscripted assignmentsNot a valid formatOnly numeric sparse matrices allowedRHS 'value' (class %s) matches 'ANY', but must match matrix class %s[ ] indexing not allowed: forgot a "," ?all() is not yet implementedc(,..) of different kinds, coercing all to 'rleDiff'column indices must be <= ncol(.) which is %ddim [product %d] do not match the length of object [%d]dimnames [%d] mismatch in %selement type '%s' not recognizedelement type 'complex' not yet implementedfile is not a MatrixMarket filefor symmetric band matrix, only specify upper or lower triangle hence, all k must have the same signhit a cycle (1) -- stop iterationshit a cycle (2) -- stop iterationsi1[1] == 0 ==> C-level verbosity will not happen!index larger than maximal %dindex must be numeric, logical or sparseVector for indexing sparseVectorsinefficient method used for "- e1"intermediate 'r' is of type %sinternal bug in "Compare" method (Cmp.Mat.atomic); please reportinternal bug in "Logic" method (Logic.Mat.atomic); please reportinternal bug: matrix 'i' in replTmat(): please reportinternal bug: missing 'i' in replTmat(): please reportinvalid 'col.names' string: %sinvalid 'data'invalid (to - from)/by in seq(.)invalid character indexinginvalid nargs()= %dlength must be non-negative numberlength of 1st arg does not match dimension of 2ndlength of 2nd arg does not match dimension of firstlogic programming error in printSpMatrix2(), please reportlogical subscript too long (%d, should be %d)longer object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthm[ ] <- v: inefficiently treating single elementsmust either specify 'A' or the functions 'A.x' and 'At.x'nargs() = %d should never happen; please report.nargs() = %d. Extraneous illegal arguments inside '[ .. ]' ?negative values are not allowed in a matrix subscriptno 'dimnames[[.]]': cannot use character indexingnon-conformable matrix dimensions in %snot converged in %d iterationsnot enough new vecs -- stop iterationsnot yet implementednot yet implemented .. please reportnot-yet-implemented 'Matrix[<-' methodnothing to replace withnumber of items to replace is not a multiple of replacement lengthnumber of rows are not compatible for %sprod() is not yet implementedrankMatrix(, method = '%s') coerces to dense matrix. Probably should rather use method = 'qr' !?rankMatrix(x, method='qr'): computing t(x) as nrow(x) < ncol(x)representation '%s' not recognizedrow indices must be <= nrow(.) which is %dsuch indexing must be by logical or 2-column numeric matrixsum() is not yet implementedsymmetric matrix must be squaresymmetry form '%s' is not yet implementedsymmetry form '%s' not recognizedsymmetry form 'hermitian' not yet implemented for readingsymmetry form 'skew-symmetric' not yet implemented for readingthe %d-th (sub)-diagonal (k = %d) is too short; filling with NA'stoo many argumentstoo many replacement valuestype '%s' not recognizedusing "old code" part in Csparse subassignmentusing"old code" part in Csparse subassignment >>> please report to Matrix-authors@r-project.orgvariable '%s' is absent, its contrast will be ignoredvector too long in Matrix - vector operationwhen 'A' is specified, 'A.x' and 'At.x' are disregardedwrong sign in 'by' argumentx / 0 for an x with sign-change no longer representable as 'rleDiff'x[.,.] <- val : x being coerced from Tsparse* to CsparseMatrixx[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced NA |--> TRUE.x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced.x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced.x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced; NA |--> TRUE.you cannot mix negative and positive indicesProject-Id-Version: Matrix 1.1-2-2 Report-Msgid-Bugs-To: bugs.r-project.org PO-Revision-Date: 2014-03-27 14:47+0100 Last-Translator: Łukasz Daniel Language-Team: Łukasz Daniel Language: pl_PL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); X-Poedit-SourceCharset: iso-8859-1 X-Generator: Poedit 1.5.4 '%s()' nie jest jeszcze zaimplementowane dla reprezentacji '%s''%s()' nie jest jeszcze zaimplementowany dla typu '%s' elementu'A' musi być macierzą kwadratowąindeksy 'NA' nie są (jeszcze?) wspierane dla rzadkich macierzyargument 'by' jest znacznie za małymacierz 'diagonals' musi mieć %d kolumnę (= length(k) )'diagonals' musi mieć tę samą długość (%d) co 'k''file' musi być łańcuchem tekstowym lub połączeniem'force' musi być (przekształcalne do) TRUE lub FALSE'lwd' musi mieć wartość NULL lub być nieujemną liczbą'ncol' nie jest czynnikiem długości 'length(x)''ncol' musi być >= 0funkcja 'nearPD()' nie uzbieżniła się w %d iteracjach'nrow' oraz 'ncol' muszą mieć tę samą wartość gdy 'symmetric' ma wartość TRUE'nrow' nie jest czynnikiem długości 'length(x)''nrow' musi być >= 0'x' musi mieć długość równą 'nrow'^2 gdy 'symmetric' ma wartość TRUEargument 'x' musi być obiektem klasy "sparseVector".M.repl.i.2col(): 'i' posiada niecałkowitą liczbę kolumn; to nie powinno się nigdy wydarzyć; proszę zgłosić raport.M.repl.i.2col(): zrzuć przypadek 'matrix' ... --> nie jest jeszcze zaimplementowane'[i]' nie jest jeszcze zaimplementowane --> nie jest jeszcze zaimplementowaneKlasa %s nie jest jeszcze zaimplementowana'Cmp.Mat.atomic()' nie powinien być wywołany dla 'diagonalMatrix'Błąd wewnętrzny: nargs()=%d; proszę zgłosić raportNiepoprawnie złożony wskaźnik: %sNiepoprawny format przechowywania: %sNiepoprawny typ przechowywania: %s'Logic.Mat.atomic()' nie powinien być wywołany dla 'diagonalMatrix'Macierze muszą mieć tę samą liczbę wierszy jeśli mają być przeprowadzane działania arytmetyczneMacierz wydaje się być ujemnie określona'nrow' musi być określone, gdy 'symmetric' ma wartość TRUEwartości NA nie są dozwolone w indeksowanych przypisaniachNiepoprawny formatDozwolone są jedynie liczbowe rzadkie macierzeprawa strona 'value' (klasa %s) pasuje do 'ANY', a musi pasować do klasy macierzy '%s'indeksowanie [ ] nie jest dozwolone: zapomniałeś ',' ?'all()' nie jest jeszcze zaimplementowane'c(,..)' różnych rodzajów, przekształcanie wszystkich do 'rleDiff'indeksy kolumn muszą być <= 'ncol(.)' który wynosi %dwymiar [produkt %d] nie zgadza się z długością obiektu [%d]niezgodność nazw wymiarów [%d] w %selement typu '%s' nie został rozpoznanytyp elementu 'complex' nie jest jeszcze zaimplementowanyplik nie jest plikiem typu 'MatrixMarket'dla symetrycznej macierzy wstęgowej, określ jedynie górny oraz dolny trójkąt tak więc, wszystkie k muszą mieć ten sam znaknatrafiona na cykl (1) -- zatrzymywanie iteracjinatrafiona na cykl (2) -- zatrzymywanie iteracjii1[1] == 0 ==> tryb 'verbose' poziomu C nie zostanie wykonany!indeks dłuższy niż maksymalny możliwy %dindeks musi być typem liczbowym, logicznym lub obiektem klasy 'sparseVector' na potrzeby indeksowania obiektów klasy 'sparseVector'nieefektywna metoda użyta dla '- e1'pośrednie 'r' jest typu %sbłąd wewnętrzny w metodzie 'Compare' (Cmp.Mat.atomic); proszę zgłosić raportbłąd wewnętrzny w metodzie 'Logic' (.Logic.Mat.atomic); proszę zgłosić raportwewnętrzny błąd: macierz 'i' w 'replTmat()': proszę zgłosić raportbłąd wewnętrzny: brakuje 'i' w 'replTmat()': proszę zgłosić raportniepoprawny łańcuch 'col.names': %sniepoprawne 'data'niepoprawne '(to - from)/by' w 'seq(.)'niepoprawne tekstowe indeksowanieniepoprawne nargs()=%ddługość musi być nieujemną liczbądługość pierwszego argumentu nie zgadza się z wymiarem drugiegodługość drugiego argumentu nie zgadza się z wymiarem pierwszegobłąd logiczny programu w 'printSpMatrix2()', proszę zgłosić raportindeks logiczny jest zbyt długi (%d, powinien być %d)długość dłuższego obiektu nie jest wielokrotnością długości krótszego obiektudługość dłuższego obiektu nie jest wielokrotnością długości krótszego obiektum[ ] <- v: nieefektywne traktowanie pojedynczych elementówpotrzeba określić 'A' lub funkcje 'A.x' oraz 'At.x''nargs() = %d' nie powinno się wydarzyć; proszę zgłosić raport.nargs() = %d. Obce nielegalne argumenty wewnątrz '[ .. ]' ?ujemne wartości nie są dozwolone w indeksach macierzybrak 'dimnames[[.]]': nie można używać indeksowania tekstowegoniezgodne wymiary macierzy w %snie uzbieżnił się w %d iteracjachzbyt mało nowych wektorów -- zatrzymywanie iteracjijeszcze niezaimplementowanejeszcze niezaimplementowane .. proszę zgłosić raportjeszcze niezaimplementowana metoda 'Matrix[<-'nic do zastąpienialiczba pozycji do zastąpienia nie jest wielokrotnością długości elementu zastępującegoliczba wierszy nie jest zgodna dla %s'prod()' nie jest jeszcze zaimplementowanerankMatrix(, method = '%s') przekształca macierz do gęstej macierzy. Prawdopodobnie należy użyć 'method = "qr"' !?rankMatrix(x, method='qr'): obliczanie t(x) jako nrow(x) < ncol(x)reprezentacja '%s' nie została rozpoznanaindeksy wiersza muszą być <= 'nrow(.)' który wynosi %dtakie indeksowanie musi być wykonane poprzez macierz logiczną lub 2-kolumnową macierz liczbową'sum()' nie jest jeszcze zaimplementowanemacierz symetryczna musi być kwadratowaforma symetryczna '%s' nie jest jeszcze zaimplementowanaforma symetryczna '%s' nie została rozpoznanaforma symetryczna 'hermitian' nie jest jeszcze zaimplementowana na potrzeby odczytuforma symetryczna 'skew-symmetric' nie jest jeszcze zaimplementowana na potrzeby odczytu(pod)-diagonala %d (k = %d) jest zbyt krótkal wypełnianie wartościami NAzbyt wiele argumentówzbyt dużo wartości zamieniającychtyp '%s' nie został rozpoznanyużywanie części 'old code' w przypisaniu w 'Csparse'używanie części 'old code' w przypisaniu w 'Csparse' >>> proszę zgłosić raport na adres 'Matrix-authors@r-project.org'zmienna '%s' jest nieobecna, jej kontrast zostanie zignorowanywektor jest zbyt długi w operacji macierz-wektorgdy 'A' jest określone, 'A.x' oraz 'At.x' są odrzucaneniepoprawny znak w argumencie 'by'x / 0 dla ' x' ze zmianą znaku nie jest dłużej reprezentowalne jako 'rleDiff'x[.,.] <- wartość : 'x' zostaje przekształcone z 'Tsparse*' na 'CsparseMatrix'x[.,.] <- wartość: 'x' to %s, wartość nie w zakresie {TRUE, FALSE} zostaje przekształcona NA |--> TRUE.x[.,.] <- wartość: 'x' to %s, wartość nie w zakresie {TRUE, FALSE} zostaje przekształcona.x[.] <- wartość: 'x' to %s, wartość nie w zakresie {TRUE, FALSE} zostaje przekształcona.x[.] <- wartość: 'x' to %s, wartość nie w zakresie {TRUE, FALSE} zostaje przekształcona; NA |--> TRUE.nie można mieszać ujemnych oraz dodatnich indeksówMatrix/inst/po/lt/0000755000176200001440000000000014547723665013553 5ustar liggesusersMatrix/inst/po/lt/LC_MESSAGES/0000755000176200001440000000000014547723665015340 5ustar liggesusersMatrix/inst/po/lt/LC_MESSAGES/Matrix.mo0000644000176200001440000001140714521047060017120 0ustar liggesusers&L5|PQ+q+3-!+PMM"<'L+t0,,2+'^-.&;&V/}+@<4%q$$ 0 OM -  ! B 2 B! 1d ) K J &W G~ + 8 2+0^055;,<h!1!164h0TB?(%%/2rb1 &   $ #!"% 'data' must be of a vector typeArgument ij must be 2-column integer matrixArgument must be numeric-like atomic vectorMatrix exponential requires square, non-null matrixX must be a numeric (double precision) matrixX must be a real (numeric) matrixdata length [%d] is not a sub-multiple or multiple of the number of columns [%d]data length [%d] is not a sub-multiple or multiple of the number of rows [%d]data length exceeds size of matrixdgeMatrix_Schur: argument x must be a non-null square matrixdgeMatrix_Schur: dgees returned code %ddgeMatrix_Schur: first call to dgees faileddgeMatrix_exp: LAPACK routine dgebal returned %ddgeMatrix_exp: dgetrf returned error code %ddgeMatrix_exp: dgetrs returned error code %di and j must be integer vectors of the same lengthincorrect left cyclic shift, j (%d) < 0incorrect left cyclic shift, j (%d) >= k (%d)incorrect left cyclic shift, k (%d) > ldx (%d)invalid '%s' argumentinvalid 'ncol' value (< 0)invalid 'ncol' value (too large or NA)invalid 'nrow' value (< 0)invalid 'nrow' value (too large or NA)invalid class of 'value' in Csparse_subassign()invalid class of 'x' in Csparse_subassign()non-numeric matrix extentnumber of rows in y (%d) does not match number of rows in X (%d)programming error in Csparse_subassign() should never happenreplacement diagonal has wrong lengthsubscript 'i' out of bounds in M[ij]subscript 'j' out of bounds in M[ij]tol, given as %g, must be <= 1too many elements specifiedx[] <- val: val is coerced to logical for "%s" xx[] <- val: val should be integer or logical, is coerced to integer, for "%s" xy must be a numeric (double precision) matrixProject-Id-Version: Matrix 1.3-3 Report-Msgid-Bugs-To: PO-Revision-Date: 2021-02-25 14:30+0200 Last-Translator: Gabrielė Stupurienė Language-Team: none Language: lt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=3; plural=(n%10==1 && (n%100<11 || n%100>19) ? 0 : n%10>=2 && n%10<=9 && (n%100<11 || n%100>19) ? 1 : 2); X-Generator: Poedit 2.4.2 'data' turi būti vektoriaus tipoArgumentas ij turi būti 2 stulpelių sveikųjų skaičių matricaArgumentas turi būti skaitinis atominis vektoriusMatricos eksponentė reikalauja kvadratinės, ne nulinės matricosX turi būti skaitinė (dvigubo tikslumo) matricaX turi būti realioji (skaitinė) matricaduomenų ilgis [%d] nėra stulpelių skaičiaus pogrupis ar kartotinis [%d]duomenų ilgis [%d] nėra eilučių skaičiaus pogrupis ar kartotinis [%d]duomenų ilgis viršija matricos dydįdgeMatrix_Schur: argumentas x turi būti ne nulinė kvadratinė matricadgeMatrix_Schur: dgees grąžintas kodas %ddgeMatrix_Schur: pirmasis iškvietimas į dgees nepavykodgeMatrix_exp: LAPACK programa dgebal grąžino %ddgeMatrix_exp: dgetrf grąžino klaidos kodą %ddgeMatrix_exp: dgetrs grąžino klaidos kodą %di ir j turi būti to paties ilgio sveikieji vektoriaineteisingas kairysis ciklinis pastūmimas, j (%d) < 0neteisingas kairysis ciklinis pastūmimas, j (%d) >= k (%d)neteisingas kairysis ciklinis pastūmimas, k (%d) > ldx (%d)netinkamas argumentas '%s'neleistina 'ncol' reikšmė (< 0)neleistina 'ncol' reikšmė (per didelė arba NA)neleistina 'nrow' reikšmė (< 0)neleistina 'nrow' reikšmė (per didelė arba NA)netinkama 'value' klasė, esanti Csparse_subassign()netinkama 'x' klasė, esanti Csparse_subassign()neskaitinės matricos dydiseilučių skaičius, esantis y (%d) neatitinka eilučių skaičiaus, esančio X (%d)programavimo klaida Csparse_subassign() niekada neturėtų įvyktikeitimo įstrižainės ilgis neteisingasapatinis indeksas 'i' už M[ij] ribųapatinis indeksas 'j' už M[ij] ribųtol, kaip %g, turi būti < = 1nurodyta per daug elementųx[] <- val: val yra paverstas į loginį "%s" xx[] <- val: val turėtų būti sveikasis skaičius arba loginis, yra pakeistas į sveikąjį skaičių dėl "%s" xy turi būti skaitinė (dvigubo tikslumo) matricaMatrix/inst/po/lt/LC_MESSAGES/R-Matrix.mo0000644000176200001440000003673414521047060017331 0ustar liggesusers,< 6 3( \ 9x  6 1 /; ,k ? : * #> b ,v ; # 4$LWq(0$#0Hy8'5:N5#,.?$RDw4D%6=\-7 *>ie""15gI"@@Q56(- Vw":91>3p:-@ ?N=2909=j51'*R&q$&B(S&|Bv?]"*;%'M"d)!9>AA 0+4\0`5# ,Y 7  O >*!Ii!<!:!H+",t"",H$.u$"$2$$=%7S%-%1%:%5&&1\& &&&&A& /'P':g'&'q'/;(*k((+((:).;)&j)"))F)?*+Z*2*/****P)+<z+>+!+B,7[,.,,$,,- 2-~S-,-,-3,.#`.T.&./D/D^/B/;/""0E02X0&0"00'0817M1+1-1@1; 2A\2@2B2:"30]3<3B3>4=M44,44.45(.5&W5~5?5'5#5A"6d6E6#-77Q7H7!77& 828)H8(r8%898@8;<9x99(9979=':<e:p:4;;H;6;#;K;?+<Vk<I<G =UT=1=o],WOc?3j_Cs5}6P{ F<Xl%VfxSU#Hb)+g!zIra|9 1 Z*`/nA$4wmMKh\JB-0t&7DN2"E i;^d[qu'pL:Ry= @vQY(.>eGT~8k'%s()' is not yet implemented for representation '%s''%s()' is not yet implemented for element type '%s''A' must be a square matrix'NA' indices are not (yet?) supported for sparse Matrices'by' argument is much too small'diagonals' matrix must have %d columns (= length(k) )'diagonals' must have the same length (%d) as 'k''file' must be a character string or connection'force' must be (coercable to) TRUE or FALSE'giveCsparse' has been deprecated; setting 'repr = "T"' for you'giveCsparse' has been deprecated; will use 'repr' instead'lwd' must be NULL or non-negative numeric'ncol' is not a factor of length(x)'ncol' must be >= 0'nearPD()' did not converge in %d iterations'nrow' and 'ncol' must be the same when 'symmetric' is true'nrow' is not a factor of length(x)'nrow' must be >= 0'x' must have length nrow^2 when 'symmetric' is true'x' must inherit from "sparseVector".M.repl.i.2col(): 'i' has no integer column number; should never happen; please report.M.repl.i.2col(): drop 'matrix' case ... --> is not yet implemented[i] is not yet implemented --> is not yet implementedClass %s is not yet implementedCmp.Mat.atomic() should not be called for diagonalMatrixInternal bug: nargs()=%d; please reportInvalid assembled indicator: %sInvalid storage format: %sInvalid storage type: %sLogic.Mat.atomic() should not be called for diagonalMatrixMatrices must have same number of rows for arithmeticMatrix seems negative semi-definiteMust specify 'nrow' when 'symmetric' is trueNAs are not allowed in subscripted assignmentsNot a valid formatOnly numeric sparse matrices allowedRHS 'value' (class %s) matches 'ANY', but must match matrix class %s[ ] indexing not allowed: forgot a "," ?a sparseMatrix should rarely be centered: will not be sparse anymoreall() is not yet implementedc(,..) of different kinds, coercing all to 'rleDiff'column indices must be <= ncol(.) which is %ddim [product %d] do not match the length of object [%d]dimnames [%d] mismatch in %selement type '%s' not recognizedelement type 'complex' not yet implementedfile is not a MatrixMarket filefor symmetric band matrix, only specify upper or lower triangle hence, all k must have the same signhit a cycle (1) -- stop iterationshit a cycle (2) -- stop iterationsi1[1] == 0 ==> C-level verbosity will not happen!index larger than maximal %dindex must be numeric, logical or sparseVector for indexing sparseVectorsinefficient method used for "- e1"intermediate 'r' is of type %sinternal bug in "Compare" method (Cmp.Mat.atomic); please reportinternal bug in "Logic" method (Logic.Mat.atomic); please reportinternal bug: matrix 'i' in replTmat(): please reportinternal bug: missing 'i' in replTmat(): please reportinvalid 'col.names' string: %sinvalid 'data'invalid 'repr'; must be "C", "T", or "R"invalid (to - from)/by in seq(.)invalid character indexinginvalid nargs()= %dlength must be non-negative numberlength of 'center' must equal the number of columns of 'x'length of 'scale' must equal the number of columns of 'x'length of 1st arg does not match dimension of 2ndlength of 2nd arg does not match dimension of firstlogic programming error in printSpMatrix2(), please reportlogical subscript too long (%d, should be %d)longer object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthm[ ] <- v: inefficiently treating single elementsmatrix can only be symmetric if square, but n != mmust either specify 'A' or the functions 'A.x' and 'At.x'nargs() = %d should never happen; please report.nargs() = %d. Extraneous illegal arguments inside '[ .. ]' ?negative values are not allowed in a matrix subscriptno 'dimnames[[.]]': cannot use character indexingnon-conformable argumentsnon-conformable matrix dimensions in %snot converged in %d iterationsnot enough new vecs -- stop iterationsnot yet implementednot yet implemented .. please reportnot-yet-implemented 'Matrix[<-' methodnothing to replace withnumber of items to replace is not a multiple of replacement lengthnumber of rows are not compatible for %sprod() is not yet implementedqr2rankMatrix(.): QR with only %d out of %d finite diag(R) entriesrankMatrix(, method = '%s') coerces to dense matrix. Probably should rather use method = 'qr' !?rankMatrix(x, method='qr'): computing t(x) as nrow(x) < ncol(x)representation '%s' not recognizedrow indices must be <= nrow(.) which is %dsuch indexing must be by logical or 2-column numeric matrixsum() is not yet implementedsuppressing %d columnssuppressing %d columns and %d rowssuppressing %d rowssymmetric matrix must be squaresymmetry form '%s' is not yet implementedsymmetry form '%s' not recognizedsymmetry form 'hermitian' not yet implemented for readingsymmetry form 'skew-symmetric' not yet implemented for readingthe %d-th (sub)-diagonal (k = %d) is too short; filling with NA'stoo many argumentstoo many replacement valuestriangular matrix must be squaretype '%s' not recognizeduniDiag=TRUE, but not all diagonal entries are 1uniDiag=TRUE, not all entries in diagonal coded as 1using "old code" part in Csparse subassignmentusing"old code" part in Csparse subassignment >>> please report to Matrix-authors@r-project.orgvariable '%s' is absent, its contrast will be ignoredvector too long in Matrix - vector operationwhen 'A' is specified, 'A.x' and 'At.x' are disregardedwrong sign in 'by' argumentx / 0 for an x with sign-change no longer representable as 'rleDiff'x[.,.] <- val : x being coerced from Tsparse* to CsparseMatrixx[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced NA |--> TRUE.x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced.x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced.x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced; NA |--> TRUE.you cannot mix negative and positive indicesProject-Id-Version: Matrix 1.3-3 PO-Revision-Date: 2021-03-01 20:55+0200 Last-Translator: Gabrielė Stupurienė Language-Team: none Language: lt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Generator: Poedit 2.4.2 Plural-Forms: nplurals=3; plural=(n%10==1 && (n%100<11 || n%100>19) ? 0 : n%10>=2 && n%10<=9 && (n%100<11 || n%100>19) ? 1 : 2); '%s()' dar neįgyvendinta '%s' atvaizdavimui'%s()' dar neįgyvendinta elementų tipui '%s''A' turi būti kvadratinė matrica'NA' indeksai nėra (dar?) remiami sparse Matrices'by' argumentas per mažas'diagonals' matricoje turi būti %d stulpeliai (= length(k) )'diagonals' turi būti tokio pat ilgio (%d) kaip ir 'k''file' turi būti simbolių eilutė ar ryšys'force' turi būti (verčiama į) TRUE arba FALSE'giveCsparse' nebenaudojamas; nustatymas 'repr = "T"' jums'giveCsparse' nebenaudojamas; vietoj to naudos 'repr''lwd' turi būti NULL arba ne neigiamas skaitinis'ncol' nėra length(x) faktorius'ncol' turi būti >= 0'nearPD()' nekonvergavo %d iteracijose'nrow' ir 'ncol' turi būti vienodi, kai 'symmetric' yra teisinga"nrow" nėra length(x) faktorius'nrow' turi būti >= 0'x' turi būti ilgio nrow^2, kai 'symmetric' yra teisingas'x' turi paveldėti iš "sparseVector".M.repl.i.2col(): 'i' neturi sveiko skaičiaus stulpelio numerio; niekada neturėtų įvykti; prašome pranešti.M.repl.i.2col(): išmetė 'matrix' atveją ... --> dar neįgyvendinta[i] dar neįgyvendinta --> dar neįgyvendintasKlasės %s dar neįgyvendintaCmp.Mat.atomic() negalima būti iškviestas diagonalMatrixVidinė klaida: nargs()=%d; prašome praneštiNeleistinas surinktas indikatorius: %sNeleistinas saugyklos formatas: %sNetinkamas saugyklos tipas: %sLogic.Mat.atomic() neturėtų būti iškviečiamas dėl diagonalMatrixMatricos turi turėti tą patį eilučių skaičių aritmetikaiMatrica atrodo pusiau neigiamai apibrėžtaTuri nurodyti 'nrow', kai 'symmetric' yra teisingaNA neleidžiamos apatinio indekso priskyrimuoseNeleistinas formatasLeidžiamos tik skaitinės sparse matricosRHS 'value' (%s klasė) atitinka 'ANY', tačiau turi atitikti matricos klasę %s[ ] indeksavimas neleidžiamas: pamiršote "," ?sparseMatrix retai turėtų būti centre: daugiau nebus sparseall() dar neįgyvendintic(,..) įvairių rūšių, paverčiant visus į 'rleDiff'stulpelių indeksai turi būti <= ncol(.), kuris yra %ddim [product %d] neatitinka objekto ilgio [%d]dimnames [%d] neatitikimas %selemento tipas '%s' neatpažįstamaselemento tipas 'complex' dar neįgyvendintasfailas nėra MatrixMarket failassimetrinės juostos matricai nurodykite tik viršutinį arba apatinį trikampį taigi, visi k turi turėti tą patį ženkląpasiekti ciklą (1) -- sustabdyti iteracijaspasiekti ciklą (2) -- sustabdyti iteracijasi1[1] == 0 ==> C lygio daugiakalbiškumas neįvyks!indeksas didesnis nei maksimalus %dindeksas turi būti skaitinis, loginis arba sparseVector, sparseVectors indeksavimuineefektyvus metodas, naudojamas "- e1"tarpinis 'r' yra %s tipovidinė klaida "Compare" metode (Cmp.Mat.atomic); prašome praneštividinė klaida "Logic" metode (Logic.Mat.atomic); prašome praneštividinė klaida: matrica 'i', esanti replTmat(): prašome praneštividinė klaida: trūksta 'i' replTmat(): prašome praneštineleistina 'col.names' eilutė: %sneleistinas 'data'negaliojantis 'repr'; turi būti "C", "T" arba "R"negaliojantis (iki - nuo)/pagal seq(.)neleistinas simbolių indeksavimasneleistini nargs()= %dilgis turi būti ne neigiamas skaičius'center' ilgis turi būti lygus stulpelių skaičiui 'x''scale' ilgis turi būti lygus stulpelių skaičiui 'x'1-mo arg ilgis nesutampa su 2-ojo dimensija2-ojo arg ilgis neatitinka pirmojo dimensijosloginio programavimo klaida printSpMatrix2(), prašome praneštiloginis apatinis indeksas per ilgas (%d, turėtų būti %d)ilgesnis objekto ilgis nėra trumpesnio objekto ilgio kartotinisilgesnis objekto ilgis nėra trumpesnio objekto ilgio kartotinism[ ] <- v: neefektyviai apdorojant pavienius elementusmatrica gali būti simetriška tik kvadratinė, bet n != mturi nurodyti 'A' arba funkcijas 'A.x' ir 'At.x'nargs() = %d niekada neturėtų įvykti; prašome pranešti.nargs() = %d. Pašaliniai neteisėti argumentai viduje '[ .. ]' ?matricos apatiniame indekse neigiamos reikšmės neleidžiamosnėra 'dimnames[[.]]': negalima naudoti simbolių indeksavimoneatitinkantys argumentaineatitinkantys matricos matmenys, esantys %snekonverguoja %d iteracijosenepakanka naujų vecs -- sustabdyti iteracijasdar neįvykdytadar neįgyvendinta .. prašome praneštidar neįgyvendintas 'Matrix[<-' methodnėra nieko pakeisti sukeičiamų elementų skaičius nėra keičiamo ilgio kartotiniseilučių skaičius nesuderinamas su %sprod() dar neįgyvendintasqr2rankMatrix(.): QR tik su %d iš %d baigtinių diag(R) įrašųrankMatrix(, method = '%s') paverčiamas į tankio matricą. Tikriausiai reikėtų naudoti metodą = 'qr' !?rankMatrix(x, method='qr'): skaičiavimas t(x) kaip nrow(x) < ncol(x)neatpažįstamas atvaizdavimas '%s'eilučių indeksai turi būti < = nrow(.), kuris yra %dtoks indeksavimas turi būti loginis arba 2 stulpelių skaitinė matricasum() dar neįgyvendintanerodyti %d stulpeliųnerodyti %d stulpelių ir %d eilučiųnerodyti %d eilučiųsimetrinė matrica turi būti kvadratinėsimetrinė forma '%s' dar neįgyvendintasimetrinė forma '%s' neatpažįstamasimetrinė forma 'hermitian' dar neįgyvendinta skaitymuisimetriška forma 'skew-symmetric', dar neįgyvendinta skaitymui%d įstrižainė (k = %d) yra per trumpa; užpildymas su NAper daug argumentųper daug pakeitimo reikšmiųtrikampė matrica turi būti kvadratinėtipas '%s' neatpažįstamasuniDiag=TRUE, bet ne visi įstrižainės įrašai yra 1uniDiag=TRUE, ne visi įstrižainės įrašai, koduoti kaip 1naudojant "senojo kodo" dalį Csparse antriniame priskyrimenaudojant "senojo kodo" dalį Csparse antriniame priskyrime >>> prašome pranešti Matrix-authors@r-project.orgkintamojo '%s' nėra, jo kontrastas bus ignoruojamasvektorius, esantis Matrix, per ilgas - vektoriaus operacijakai nurodyta 'A', į 'A.x' and 'At.x' neatsižvelgiamaneteisingas ženklas 'by' argumentex / 0 dėl x su ženklo pakeitimu nebeatitinkamas kaip 'rleDiff'x[.,.] <- val: x yra paverčiamas iš Tsparse* į CsparseMatrixx[...] <- val: x yra %s, val, kurio nėra {TRUE, FALSE} yra paverčiamas NA |--> TRUE.x[.,.] <- val: x yra %s, val, kurio nėra {TRUE, FALSE} yra paverčiamas.x[.] <- val: x yra %s, val, kurio nėra {TRUE, FALSE} yra paverčiamas.x[.] <- val: x yra %s, val, kurio nėra {TRUE, FALSE} yra paverčiamas; NA |--> TRUE.negalite maišyti neigiamų ir teigiamų indeksųMatrix/inst/po/en@quot/0000755000176200001440000000000014547723665014547 5ustar liggesusersMatrix/inst/po/en@quot/LC_MESSAGES/0000755000176200001440000000000014547723665016334 5ustar liggesusersMatrix/inst/po/en@quot/LC_MESSAGES/Matrix.mo0000644000176200001440000005343114521047060020117 0ustar liggesusers<  7 *7Ii<'//:I$000 -<j% ,,Mz&   )">az%'$=b u:9 !"?b!!." @,'m $+!!)K(k'((%7N)&9BA|*8'"-Jx%)RFXF+$+P(|*.#$# #H $l = - 3 =1!,o!-!-!!!3"AN"/""!"1":0#9k#"#&#7#2'$!Z$|$!$-$)$> %+J%Pv%M%"&-8&<f&'&+&0&,(',U'/'','1'$-(?R(A(((#(7!)2Y)")')-).*4*L*b*w*&**&**/++I+u+X++#+-#,3Q,+,5,!,% -$/-AT----)-(.>:.@y.%.;.<//Y/%/9//;0$=0$b00000<0F:111141 202OG2-2/23 4 %47F4 ~4444<4+53A53u5:5$54 60>60o6-6666717%Q7w7 747 7*828 B8c8r888&889%9C9]9w9)9/9,9:(9:Bb:A::!;&#;"J;%m;%;2;;&<D,<+q<$<(<3<%=%E=#k=,=#='=+>,4>,a>?>>->?!*?L?j??=?E?.*@<Y@+@1@"@!A)9A-cAVAJAJ3B!~B#B+B+B0C2MC.C#C$C#C$D=AD-D3DAD,#E-PE-~E!E7EEF3LFF%F1F:F93G"mG&G7G2G!"HDH!YH1{H)H>H/IPFIMI"I-J<6J'sJ+J0J,J,%K/RKK4K9K$ LG2LEzL,L'L?M2UM.M'M-M. NjR@R%R;S<LS/S%S=ST;5T(qT(TTTTU@9UNzU U U V4&V[V0jVOV-VN@ E$(p*"~s+v ilD 9T8%nUb\}j'e1m4h:^>A/gB{_PMZ)VXRGWHk2y`w0;a S<zqC!& QI 5d]7=f|L?Y6.ot,-x#3cFuOJ[rK%s cannot exceed %s%s has elements not in {%s}%s has elements not in {%s}\{%s}%s is %d but columns are not stored in increasing order%s is not %d%s is not in {%s}%s is not representable as "%s"%s length cannot exceed %s%s too dense for %s; would have more than %s nonzero entries%s(%s) is undefined: '%s' is not square%s(%s, %s) requires m-by-n '%s' with m >= n > 0%s(%s, %s) requires m-by-n '%s' with n >= m > 0%s(<%s>) does not support structurally rank deficient case%s(<%s>, <%s>) failed: out of memory%s-by-%s %s invalid for positive '%s' when %s=%d%s="%s" but there are entries above the diagonal%s="%s" but there are entries below the diagonal%s="%s" but there are entries on the diagonal%s[%d] (%s) is negative%s[%d] (%s) is not %d%s[%d] (%s) is not %d or %d%s[%d] (%s) is not in %s%s[%d] (%s) is not less than %s%s[1] != %s[2] (matrix is not square)%s[1] differs from %s[2]%s[[%d]] is not NULL or a vector'%s' and '%s' slots do not have equal length'%s' does not have length %d'%s' does not support complex matrices'%s' failed'%s' has length exceeding %s'%s' is NA'%s' is NA or less than %s'%s' is empty or not square'%s' is not a number'%s' is not a number or not finite'%s' is not of type "%s"'%s' is not square'%s' must be "%s" or "%s"'%s' must be %d or %d'%s' must be %s or %s'%s' must be %s or %s or %s'%s' must be an integer from %s to %s'%s' must be less than or equal to '%s''%s' or '%s' does not have length %d'%s' or '%s' is NA'%s' or '%s' is not of type "%s"'%s' slot allocates fewer than %s elements for column '%s''%s' slot allocates more than %s elements for column '%s''%s' slot contains NA'%s' slot contains duplicates'%s' slot does not have %s columns'%s' slot does not have %s row'%s' slot does not have length %d'%s' slot does not have length %s'%s' slot does not have length %s or length %s'%s' slot exceeds %s'%s' slot has elements not in {%s}'%s' slot has elements not in {%s} after truncation towards zero'%s' slot has elements not in {%s}\{%s}'%s' slot has fewer than %s rows'%s' slot has length greater than %s'%s' slot has length greater than '%s' slot'%s' slot has length less than %d'%s' slot has length less than %s'%s' slot has more than %s rows'%s' slot has negative diagonal elements'%s' slot has negative elements'%s' slot has no '%s' attribute'%s' slot has nonunit diagonal elements'%s' slot has nonzero length but %s is 0'%s' slot has unpaired negative elements'%s' slot is "%s" but '%s' slot does not have length %s'%s' slot is NA'%s' slot is lower (not upper) triangular'%s' slot is negative'%s' slot is not "%s" or "%s"'%s' slot is not %d or %d'%s' slot is not a list'%s' slot is not increasing'%s' slot is not increasing after truncation towards zero'%s' slot is not increasing when traversed in stored column order'%s' slot is not increasing within columns'%s' slot is not increasing within columns after sorting'%s' slot is not increasing within rows'%s' slot is not increasing within supernodes'%s' slot is not nondecreasing'%s' slot is not of type "%s"'%s' slot is not of type "%s" or "%s"'%s' slot is upper (not lower) triangular'%s' slot is wrong within diagonal blocks (row and column indices do not coincide)'%s' slot must be lower trapezoidal but has entries above the diagonal'%s' slot must be upper trapezoidal but has entries below the diagonal'%s' would overflow type "%s"'data' must be of a vector typeArgument ij must be 2-column integer matrixArgument must be numeric-like atomic vectorCHOLMOD error '%s' at file '%s', line %dCHOLMOD warning '%s' at file '%s', line %dCholesky factor has negative diagonal elementsLAPACK dgels returned error code %dLAPACK dgeqrf returned error code %dLAPACK dposv returned error code %dLAPACK dtrcon returned error code %dLU factorization of %s failed: out of memory or near-singularLU factorization of m-by-n %s requires m == nMatrix exponential requires square, non-null matrixNA subscripts in %s not supported for '%s' inheriting from %sQR factorization of %s failed: out of memoryQR factorization of m-by-n %s requires m >= nX must be a numeric (double precision) matrixX must be a real (numeric) matrixargument '%s' ("%s") does not have string length %dargument '%s' ("%s") is not "%s", "%s", "%s", "%s", "%s", or "%s"argument '%s' ("%s") is not "%s", "%s", or "%s"argument '%s' has length %dargument '%s' is not of type "%s"attempt to allocate vector of length exceeding %sattempt to construct %s with more than %s nonzero elementsattempt to construct %s with more than %s nonzero entriesattempt to construct non-square %sattempt to get sign of non-permutationattempt to get skew-symmetric part of non-square matrixattempt to get symmetric part of non-square matrixattempt to invert non-permutationattempt to pack a %sattempt to pack non-square matrixattempt to set factor on %s without '%s' slotattempt to symmetrize a non-square matrixcoercing n-by-n %s to %s is not supported for n*n exceeding %scolumn '%s' is stored first but %s is not 0data length [%d] is not a sub-multiple or multiple of the number of columns [%d]data length [%d] is not a sub-multiple or multiple of the number of rows [%d]data length exceeds size of matrixdeterminant of non-square matrix is undefineddgeMatrix_Schur: argument x must be a non-null square matrixdgeMatrix_Schur: dgees returned code %ddgeMatrix_Schur: first call to dgees faileddgeMatrix_exp: LAPACK routine dgebal returned %ddgeMatrix_exp: dgetrf returned error code %ddgeMatrix_exp: dgetrs returned error code %ddgeMatrix_svd(x,*): dim(x)[j] = %d is too largedimensions cannot exceed %sdimensions of '%s' and '%s' are inconsistentdimensions of '%s' slot are not identical to '%s'failed to open file "%s" for writingfirst differences of '%s' slot are less than those of '%s' slotfirst differences of '%s' slot are not equal to supernode lengthsfirst differences of '%s' slot exceed %sfirst element of '%s' slot is not 0first entry in column '%s' does not have row index '%s'i and j must be integer vectors of the same lengthincompatible '%s' and '%s' in '%s'incorrect left cyclic shift, j (%d) < 0incorrect left cyclic shift, j (%d) >= k (%d)incorrect left cyclic shift, k (%d) > ldx (%d)indices would exceed %sinvalid '%s' argumentinvalid '%s' to '%s'invalid 'ncol' value (< 0)invalid 'ncol' value (too large or NA)invalid 'nrow' value (< 0)invalid 'nrow' value (too large or NA)invalid class "%s" object: %sinvalid class of 'value' in Csparse_subassign()invalid class of 'x' in Csparse_subassign()invalid factor nameinvalid simplicial Cholesky factorization: structural zero on main diagonal in column %dinvalid transposition vectorlast element of '%s' slot is not %sleading dimension not equal to number of rowsleading principal minor of order %d is not positiveleading principal minor of order %d is zerolength of %s[[%d]] (%lld) is not equal to %s[%d] (%d)matrix has more columns than rowsmatrix has negative diagonal elementsmatrix has nonunit diagonal elementsmatrix length (%d * %d) is not a multiple of vector length (%lld)n+1 would overflow type "%s"non-conformable argumentsnon-numeric matrix extentnonempty vector supplied for empty matrixnumber of columns of matrices must matchnumber of columns of result is not a multiple of vector lengthnumber of rows in y (%d) does not match number of rows in X (%d)number of rows of matrices must matchnumber of rows of result is not a multiple of vector lengthprogramming error in Csparse_subassign() should never happenreplacement diagonal has incompatible type "%s"replacement diagonal has wrong lengthsecond argument of '%s' does not specify a subclass of %sshould never happen ...sparse->dense coercion: allocating vector of size %0.1f GiBsubscript 'i' out of bounds in M[ij]subscript 'j' out of bounds in M[ij]supernode lengths exceed %stol, given as %g, must be <= 1tol, given as %g, must be >= 0too many elements specifiedtraversal of '%s' slot does not complete in exactly %s stepsunable to aggregate %s with '%s' and '%s' slots of length exceeding %sunexpected kind "%c" in '%s'unexpected type "%s" in '%s'unknown error in getGivensvector length (%lld) exceeds matrix length (%d * %d)wrong '%s'x[] <- val: val is coerced to logical for "%s" xx[] <- val: val should be integer or logical, is coerced to integer, for "%s" xy must be a numeric (double precision) matrixProject-Id-Version: Matrix 1.6-2 Report-Msgid-Bugs-To: PO-Revision-Date: 2023-11-02 21:33-0400 Last-Translator: Automatically generated Language-Team: none Language: en MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); %s cannot exceed %s%s has elements not in {%s}%s has elements not in {%s}\{%s}%s is %d but columns are not stored in increasing order%s is not %d%s is not in {%s}%s is not representable as "%s"%s length cannot exceed %s%s too dense for %s; would have more than %s nonzero entries%s(%s) is undefined: ‘%s’ is not square%s(%s, %s) requires m-by-n ‘%s’ with m >= n > 0%s(%s, %s) requires m-by-n ‘%s’ with n >= m > 0%s(<%s>) does not support structurally rank deficient case%s(<%s>, <%s>) failed: out of memory%s-by-%s %s invalid for positive ‘%s’ when %s=%d%s="%s" but there are entries above the diagonal%s="%s" but there are entries below the diagonal%s="%s" but there are entries on the diagonal%s[%d] (%s) is negative%s[%d] (%s) is not %d%s[%d] (%s) is not %d or %d%s[%d] (%s) is not in %s%s[%d] (%s) is not less than %s%s[1] != %s[2] (matrix is not square)%s[1] differs from %s[2]%s[[%d]] is not NULL or a vector‘%s’ and ‘%s’ slots do not have equal length‘%s’ does not have length %d‘%s’ does not support complex matrices‘%s’ failed‘%s’ has length exceeding %s‘%s’ is NA‘%s’ is NA or less than %s‘%s’ is empty or not square‘%s’ is not a number‘%s’ is not a number or not finite‘%s’ is not of type "%s"‘%s’ is not square‘%s’ must be "%s" or "%s"‘%s’ must be %d or %d‘%s’ must be %s or %s‘%s’ must be %s or %s or %s‘%s’ must be an integer from %s to %s‘%s’ must be less than or equal to ‘%s’‘%s’ or ‘%s’ does not have length %d‘%s’ or ‘%s’ is NA‘%s’ or ‘%s’ is not of type "%s"‘%s’ slot allocates fewer than %s elements for column ‘%s’‘%s’ slot allocates more than %s elements for column ‘%s’‘%s’ slot contains NA‘%s’ slot contains duplicates‘%s’ slot does not have %s columns‘%s’ slot does not have %s row‘%s’ slot does not have length %d‘%s’ slot does not have length %s‘%s’ slot does not have length %s or length %s‘%s’ slot exceeds %s‘%s’ slot has elements not in {%s}‘%s’ slot has elements not in {%s} after truncation towards zero‘%s’ slot has elements not in {%s}\{%s}‘%s’ slot has fewer than %s rows‘%s’ slot has length greater than %s‘%s’ slot has length greater than ‘%s’ slot‘%s’ slot has length less than %d‘%s’ slot has length less than %s‘%s’ slot has more than %s rows‘%s’ slot has negative diagonal elements‘%s’ slot has negative elements‘%s’ slot has no ‘%s’ attribute‘%s’ slot has nonunit diagonal elements‘%s’ slot has nonzero length but %s is 0‘%s’ slot has unpaired negative elements‘%s’ slot is "%s" but ‘%s’ slot does not have length %s‘%s’ slot is NA‘%s’ slot is lower (not upper) triangular‘%s’ slot is negative‘%s’ slot is not "%s" or "%s"‘%s’ slot is not %d or %d‘%s’ slot is not a list‘%s’ slot is not increasing‘%s’ slot is not increasing after truncation towards zero‘%s’ slot is not increasing when traversed in stored column order‘%s’ slot is not increasing within columns‘%s’ slot is not increasing within columns after sorting‘%s’ slot is not increasing within rows‘%s’ slot is not increasing within supernodes‘%s’ slot is not nondecreasing‘%s’ slot is not of type "%s"‘%s’ slot is not of type "%s" or "%s"‘%s’ slot is upper (not lower) triangular‘%s’ slot is wrong within diagonal blocks (row and column indices do not coincide)‘%s’ slot must be lower trapezoidal but has entries above the diagonal‘%s’ slot must be upper trapezoidal but has entries below the diagonal‘%s’ would overflow type "%s"‘data’ must be of a vector typeArgument ij must be 2-column integer matrixArgument must be numeric-like atomic vectorCHOLMOD error ‘%s’ at file ‘%s’, line %dCHOLMOD warning ‘%s’ at file ‘%s’, line %dCholesky factor has negative diagonal elementsLAPACK dgels returned error code %dLAPACK dgeqrf returned error code %dLAPACK dposv returned error code %dLAPACK dtrcon returned error code %dLU factorization of %s failed: out of memory or near-singularLU factorization of m-by-n %s requires m == nMatrix exponential requires square, non-null matrixNA subscripts in %s not supported for ‘%s’ inheriting from %sQR factorization of %s failed: out of memoryQR factorization of m-by-n %s requires m >= nX must be a numeric (double precision) matrixX must be a real (numeric) matrixargument ‘%s’ ("%s") does not have string length %dargument ‘%s’ ("%s") is not "%s", "%s", "%s", "%s", "%s", or "%s"argument ‘%s’ ("%s") is not "%s", "%s", or "%s"argument ‘%s’ has length %dargument ‘%s’ is not of type "%s"attempt to allocate vector of length exceeding %sattempt to construct %s with more than %s nonzero elementsattempt to construct %s with more than %s nonzero entriesattempt to construct non-square %sattempt to get sign of non-permutationattempt to get skew-symmetric part of non-square matrixattempt to get symmetric part of non-square matrixattempt to invert non-permutationattempt to pack a %sattempt to pack non-square matrixattempt to set factor on %s without ‘%s’ slotattempt to symmetrize a non-square matrixcoercing n-by-n %s to %s is not supported for n*n exceeding %scolumn ‘%s’ is stored first but %s is not 0data length [%d] is not a sub-multiple or multiple of the number of columns [%d]data length [%d] is not a sub-multiple or multiple of the number of rows [%d]data length exceeds size of matrixdeterminant of non-square matrix is undefineddgeMatrix_Schur: argument x must be a non-null square matrixdgeMatrix_Schur: dgees returned code %ddgeMatrix_Schur: first call to dgees faileddgeMatrix_exp: LAPACK routine dgebal returned %ddgeMatrix_exp: dgetrf returned error code %ddgeMatrix_exp: dgetrs returned error code %ddgeMatrix_svd(x,*): dim(x)[j] = %d is too largedimensions cannot exceed %sdimensions of ‘%s’ and ‘%s’ are inconsistentdimensions of ‘%s’ slot are not identical to ‘%s’failed to open file "%s" for writingfirst differences of ‘%s’ slot are less than those of ‘%s’ slotfirst differences of ‘%s’ slot are not equal to supernode lengthsfirst differences of ‘%s’ slot exceed %sfirst element of ‘%s’ slot is not 0first entry in column ‘%s’ does not have row index ‘%s’i and j must be integer vectors of the same lengthincompatible ‘%s’ and ‘%s’ in ‘%s’incorrect left cyclic shift, j (%d) < 0incorrect left cyclic shift, j (%d) >= k (%d)incorrect left cyclic shift, k (%d) > ldx (%d)indices would exceed %sinvalid ‘%s’ argumentinvalid ‘%s’ to ‘%s’invalid ‘ncol’ value (< 0)invalid ‘ncol’ value (too large or NA)invalid ‘nrow’ value (< 0)invalid ‘nrow’ value (too large or NA)invalid class "%s" object: %sinvalid class of ‘value’ in Csparse_subassign()invalid class of ‘x’ in Csparse_subassign()invalid factor nameinvalid simplicial Cholesky factorization: structural zero on main diagonal in column %dinvalid transposition vectorlast element of ‘%s’ slot is not %sleading dimension not equal to number of rowsleading principal minor of order %d is not positiveleading principal minor of order %d is zerolength of %s[[%d]] (%lld) is not equal to %s[%d] (%d)matrix has more columns than rowsmatrix has negative diagonal elementsmatrix has nonunit diagonal elementsmatrix length (%d * %d) is not a multiple of vector length (%lld)n+1 would overflow type "%s"non-conformable argumentsnon-numeric matrix extentnonempty vector supplied for empty matrixnumber of columns of matrices must matchnumber of columns of result is not a multiple of vector lengthnumber of rows in y (%d) does not match number of rows in X (%d)number of rows of matrices must matchnumber of rows of result is not a multiple of vector lengthprogramming error in Csparse_subassign() should never happenreplacement diagonal has incompatible type "%s"replacement diagonal has wrong lengthsecond argument of ‘%s’ does not specify a subclass of %sshould never happen ...sparse->dense coercion: allocating vector of size %0.1f GiBsubscript ‘i’ out of bounds in M[ij]subscript ‘j’ out of bounds in M[ij]supernode lengths exceed %stol, given as %g, must be <= 1tol, given as %g, must be >= 0too many elements specifiedtraversal of ‘%s’ slot does not complete in exactly %s stepsunable to aggregate %s with ‘%s’ and ‘%s’ slots of length exceeding %sunexpected kind "%c" in ‘%s’unexpected type "%s" in ‘%s’unknown error in getGivensvector length (%lld) exceeds matrix length (%d * %d)wrong ‘%s’x[] <- val: val is coerced to logical for "%s" xx[] <- val: val should be integer or logical, is coerced to integer, for "%s" xy must be a numeric (double precision) matrixMatrix/inst/po/en@quot/LC_MESSAGES/R-Matrix.mo0000644000176200001440000007104314521047060020315 0ustar liggesusersL]|<.I[i 4(WDEN21>d'+ )#HlB#&'/W!l(# $!46V3971V&61#//S,?:5+1a#*"+#Nr,;# 8' ,` $    4 !$>!Wc!(!0!$"0:"k"8"""'"#8#S#:l#5###,$..$]$$p$D$4$)%D9%%~%D%% &0%&)V&&&&)&8&=('f'''-'''-(J6(7(((,(") ?)*`):))#)e *"p*"*1*3*+;+IX+"++@+@%,5f,6,,,,-,-=-\-k-(z-(- --.!#.E.W.k... .'."/:*/9e/1/3/ 00:)0d0-0@0?0=.12l1&1*1)142P2e2%}2B2252`539383> 49H49404=4&+55R5155'5#5 6)-6W6M\66&66$7&)7P7Bh7*7(7<70<8 m8z8&8B8v8?d939/90:19:/k:%:":*:;';(?;;h;%;;";<<)8<!b<9<><A<?=== >.'>V>!o>0>4>N>0F?`w?5?,@7;@s@O@>@IA<hA:AHA,)BVB@jCCC[C BD8cD,D[DI%ERoE6EBE/OI;II=I#(J"LJ5oJJ*J:J9&K'`K3K0KGKB5L9xL9LL'M'0MXM.qM&M'MM0NG8N'NNHN0 O(:OcO"O!O<O(P[,P,P0P$P0 Qfc9cEc0%dAVd*d5d5d/e'Ie#qe e)eeMef&>fef$yf*ffBf*$g(Og<xg0g gg&gB#h~fhCh7)i/ai4i1i/i%(j&Nj*ujjj(j;j%5k[k"rkkk-k%k=lB[lAllmm m.mn% n0Fn4wnNn0n`,o9o,oCo8pSXp>pIp<5q:rqHq,qw_X,@N3GM~.d`t)7vex 1=j{KJ[o+}( UIr%z!*LEkBflVC&u\ DF'>8?cR/P9Sa5$;#q]<H 6"s4^-nAZbiQm0yhYT: Opg W|2%1$s(%2$s) is undefined: '%2$s' is not positive semidefinite%s length cannot exceed %s%s(<%s>) is not yet implemented%s(<%s>, <%s>) is not yet implemented; ask maintainer("%s") to implement the missing method%s="%s" invalid for %s@uplo="%s"'%1$s' is computationally singular, rcond(%1$s)=%2$g'%1$s' is not "%2$s", "%3$s", or "%2$s."'%1$s' is not "%2$s1", "%2$s1.", "%2$s2", "%2$s2.", "%3$s", "%3$s1", "%4$s", or "%4$s1"'%1$s' is not "%2$s1", "%2$s1.", "%2$s2", "%2$s2.", "%3$s", or "%4$s"'%1$s' is not "%2$s1", "%2$s1.", "%3$s", "%3$s.", "%3$s1", "%3$s1.", or "%4$s"'%1$s' is not "%2$s1", "%2$s1.", "%3$s", or "%4$s"'%1$s' is not formally symmetric; factorizing tcrossprod(%1$s)'%s' and '%s' must be positive integers'%s' contains NA'%s' does not inherit from virtual class %s'%s' has elements exceeding '%s''%s' has elements less than %d'%s' has length 0 but '%s' does not'%s' has non-finite values'%s' has the wrong length'%s' is computationally singular, min(d)/max(d)=%g, d=abs(diag(U))'%s' is deprecated; setting %s="%s"'%s' is deprecated; using '%s' instead'%s' is not "%1$s", "D%1$s", or "%1$s."'%s' is not %d or %d'%s' is not a non-negative number'%s' is not a permutation of seq_len(%s)'%s' is not a square numeric matrix'%s' is not of type "%s" or "%s"'%s' is not square'%s' method must use default %s="%s"'%s' via sparse -> dense coercion'%s()' is not yet implemented for representation '%s''%s()' is not yet implemented for element type '%s''A' must be a square matrix'NA' indices are not (yet?) supported for sparse Matrices'by' argument is much too small'cl' is not a character string'cols' has elements not in seq(0, length.out = n)'cols' must be numeric'contrasts.arg' argument must be named'diagonals' matrix must have %d columns (= length(k) )'diagonals' must have the same length (%d) as 'k''dims' must contain all (i,j) pairs'file' must be a character string or connection'force' must be (coercable to) TRUE or FALSE'giveCsparse' has been deprecated; setting 'repr = "T"' for you'giveCsparse' has been deprecated; will use 'repr' instead'giveCsparse' is deprecated; setting repr="T" for you'giveCsparse' is deprecated; using 'repr' instead'i' and 'j' must be'i' and 'j' must not contain NA'kind' must be one of "d", "l", "n"'lst' must be a list'lwd' must be NULL or non-negative numeric'n' must be a non-negative integer'ncol' is not a factor of length(x)'ncol' must be >= 0'nearPD()' did not converge in %d iterations'nrow' and 'ncol' must be the same when 'symmetric' is true'nrow' is not a factor of length(x)'nrow' must be >= 0'nrow', 'ncol', 'byrow' disregarded for [mM]atrix 'data''p' must be a nondecreasing vector c(0, ...)'shape' must be one of "g", "t", "s"'uplo' must be "U" or "L"'x' has unsupported class "%s"'x' has unsupported type "%s"'x' must have length nrow^2 when 'symmetric' is true'x' must inherit from "sparseVector".M.repl.i.2col(): 'i' has no integer column number; should never happen; please report.M.repl.i.2col(): drop 'matrix' case ... --> is not yet implemented[i] is not yet implemented --> is not yet implementedClass %s is not yet implementedCmp.Mat.atomic() should not be called for diagonalMatrixD[i,i] is NA, i=%dD[i,i] is negative, i=%dInternal bug: nargs()=%d; please reportInvalid assembled indicator: %sInvalid storage format: %sInvalid storage type: %sLogic.Mat.atomic() should not be called for diagonalMatrixMatrices must have same number of rows for arithmeticMatrix seems negative semi-definiteMust specify 'nrow' when 'symmetric' is trueNAs are not allowed in subscripted assignmentsNot a valid formatOnly numeric sparse matrices allowedRHS 'value' (class %s) matches 'ANY', but must match matrix class %s[ ] indexing not allowed: forgot a "," ?[[ suppressing %d column name%s %s ... ]]a sparseMatrix should rarely be centered: will not be sparse anymoreall() is not yet implementedassigned dimensions [product %.0f] do not match object length [%.0f]assigned dimensions are NAassigned dimensions are negativeassigned dimensions are not of type "%s" or "%s"assigned dimensions do not have length %dassigned dimensions exceed %sattempt to coerce matrix with NA to %sattempt to coerce non-square matrix to %sattempt to recycle 'x' of length 0 to length 'n' (n > 0)c(,..) of different kinds, coercing all to 'rleDiff'cannot coerce from %s to %scannot coerce matrix of type "%s" to %scolumn indices must be <= ncol(.) which is %dcomplex %s not yet implementeddata is too longdeterminant of non-square matrix is undefineddiag(%s) has non-positive or non-finite entries; finite result is doubtfuldim [product %d] do not match the length of object [%d]dimensions cannot exceed %sdimensions cannot exceed 2^31-1dimensions of '%s' and '%s' are inconsistentdimnames [%d] mismatch in %selement type '%s' not recognizedelement type 'complex' not yet implementedexactly one of 'i', 'j', and 'p' must be missing from callfile is not a MatrixMarket filefirst element used of '%s' argumentfor symmetric band matrix, only specify upper or lower triangle hence, all k must have the same signhit a cycle (1) -- stop iterationshit a cycle (2) -- stop iterationsi1[1] == 0 ==> C-level verbosity will not happen!in show(); maybe adjust options(max.print=, width=)incorrect number of dimensionsindex larger than maximal %dindex must be numeric, logical or sparseVector for indexing sparseVectorsinefficient method used for "- e1"intermediate 'r' is of type %sinternal bug in "Compare" method (Cmp.Mat.atomic); please reportinternal bug in "Logic" method (Logic.Mat.atomic); please reportinternal bug: matrix 'i' in replTmat(): please reportinternal bug: missing 'i' in replTmat(): please reportinvalid %s="%s"invalid %s="%s" to '%s'invalid '%s' argumentinvalid '%s': not in %d:%dinvalid 'Class2'invalid 'col.names' string: %sinvalid 'data'invalid 'dims'invalid 'repr'; must be "C", "R", or "T"invalid 'repr'; must be "C", "T", or "R"invalid (to - from)/by in seq(.)invalid character indexinginvalid class "%s" in '%s'invalid class "%s" in '%s' methodinvalid mode "%s"invalid nargs()= %dinvalid subscript class "%s"invalid subscript type "%s"invalid type "%s" in '%s'invalid type "%s" in '%s' methodis not an integer multiple of length(x)length must be non-negative numberlength of 'center' must equal the number of columns of 'x'length of 'scale' must equal the number of columns of 'x'length of 1st arg does not match dimension of 2ndlength of 2nd arg does not match dimension of firstlength(i)length(x) must not exceedlogic programming error in printSpMatrix2(), please reportlogical subscript too longlogical subscript too long (%d, should be %d)longer object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthm[ ] <- v: inefficiently treating single elementsmatrix can only be symmetric if square, but n != mmatrix exactly singular, J[i,]=0, i=%dmatrix is exactly singular, D[i,i]=0, i=%dmatrix is exactly singular, J[,j]=0, j=%dmatrix is not diagonal; consider Diagonal(x=diag(.))matrix is not squarematrix is not symmetricmatrix is not symmetric or triangularmatrix is not symmetric; consider forceSymmetric(.) or symmpart(.)matrix is not triangularmatrix is not triangular; consider triu(.) or tril(.)matrix is structurally rank deficient; using augmented matrix with additional %d row(s) of zerosmatrix must have exactly one entry in each row and columnmatrix must have exactly one entry in each row or columnmismatch between typeof(x)="%s" and kind="%s"; using kind="%s"model frame and formula mismatch in sparse.model.matrix()must either specify 'A' or the functions 'A.x' and 'At.x'nargs() = %d should never happen; please report.nargs() = %d. Extraneous illegal arguments inside '[ .. ]' ?need greater '%s' as pivoting occurrednegative values are not allowed in a matrix subscriptno 'dimnames[[.]]': cannot use character indexingnon-conformable argumentsnon-conformable matrix dimensions in %snon-list contrasts argument ignorednon-negativenon0.i() not yet implemented for class %snormnot a positive definite matrix (and positive semidefiniteness is not checked)not converged in %d iterationsnot enough new vecs -- stop iterationsnot yet implementednot yet implemented .. please reportnot-yet-implemented 'Matrix[<-' methodnothing to replace withnumber of items to replace is not a multiple of replacement lengthnumber of nonzero entries cannot exceed %snumber of rows are not compatible for %sonly square matrices can be used as graph incidence matricesonly zeros may be mixed with negative subscriptsp[length(p)]positiveprod() is not yet implementedqr2rankMatrix(.): QR with only %d out of %d finite diag(R) entriesrankMatrix(, method = '%s') coerces to dense matrix. Probably should rather use method = 'qr' !?rankMatrix(x, method='qr'): computing t(x) as nrow(x) < ncol(x)readMM(): column indices 'j' are not in 1:ncol[=%d]readMM(): expected %d entries but found only %dreadMM(): row indices 'i' are not in 1:nrow[=%d]recycled %s would have maximal index exceeding %sreplacement diagonal has incompatible type "%s"replacement diagonal has wrong lengthrepresentation '%s' not recognizedrow indices must be <= nrow(.) which is %dshould never happen ...subscript out of boundssubscripts exceeding %s replaced with NAsuch indexing must be by logical or 2-column numeric matrixsum() is not yet implementedsuppressing %d columnssuppressing %d columns and %d rowssuppressing %d rowssymmetric matrix must be squaresymmetry form '%s' is not yet implementedsymmetry form '%s' not recognizedsymmetry form 'hermitian' not yet implemented for readingsymmetry form 'skew-symmetric' not yet implemented for readingthe %d-th (sub)-diagonal (k = %d) is too short; filling with NA'sthe default value of argument '%s' of method '%s(<%s>, <%s>)' may change from %s to %s as soon as the next release of Matrix; set '%s' when programmingtoo many argumentstoo many replacement valuestriangular matrix must be squaretrimmed means are not defined for complex datatype '%s' not recognizedunexpected %s="%s" in '%s' methoduniDiag=TRUE, but not all diagonal entries are 1uniDiag=TRUE, not all entries in diagonal coded as 1use Diagonal() to construct diagonal (symmetric && triangular) sparse matricesusing "old code" part in Csparse subassignmentusing"old code" part in Csparse subassignment >>> please report to Matrix-authors@r-project.orgvariable '%s' is absent, its contrast will be ignoredvector too long in Matrix - vector operationwhen 'A' is specified, 'A.x' and 'At.x' are disregardedwrong sign in 'by' argumentx / 0 for an x with sign-change no longer representable as 'rleDiff'x[.,.] <- val : x being coerced from Tsparse* to CsparseMatrixx[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced NA |--> TRUE.x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced.x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced.x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced; NA |--> TRUE.you cannot mix negative and positive indicesProject-Id-Version: Matrix 1.6-2 PO-Revision-Date: 2023-11-02 21:33 Last-Translator: Automatically generated Language-Team: none Language: en MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); %1$s(%2$s) is undefined: ‘%2$s’ is not positive semidefinite%s length cannot exceed %s%s(<%s>) is not yet implemented%s(<%s>, <%s>) is not yet implemented; ask maintainer("%s") to implement the missing method%s="%s" invalid for %s@uplo="%s"‘%1$s’ is computationally singular, rcond(%1$s)=%2$g‘%1$s’ is not "%2$s", "%3$s", or "%2$s."‘%1$s’ is not "%2$s1", "%2$s1.", "%2$s2", "%2$s2.", "%3$s", "%3$s1", "%4$s", or "%4$s1"‘%1$s’ is not "%2$s1", "%2$s1.", "%2$s2", "%2$s2.", "%3$s", or "%4$s"‘%1$s’ is not "%2$s1", "%2$s1.", "%3$s", "%3$s.", "%3$s1", "%3$s1.", or "%4$s"‘%1$s’ is not "%2$s1", "%2$s1.", "%3$s", or "%4$s"‘%1$s’ is not formally symmetric; factorizing tcrossprod(%1$s)‘%s’ and ‘%s’ must be positive integers‘%s’ contains NA‘%s’ does not inherit from virtual class %s‘%s’ has elements exceeding ‘%s’‘%s’ has elements less than %d‘%s’ has length 0 but ‘%s’ does not‘%s’ has non-finite values‘%s’ has the wrong length‘%s’ is computationally singular, min(d)/max(d)=%g, d=abs(diag(U))‘%s’ is deprecated; setting %s="%s"‘%s’ is deprecated; using ‘%s’ instead‘%s’ is not "%1$s", "D%1$s", or "%1$s."‘%s’ is not %d or %d‘%s’ is not a non-negative number‘%s’ is not a permutation of seq_len(%s)‘%s’ is not a square numeric matrix‘%s’ is not of type "%s" or "%s"‘%s’ is not square‘%s’ method must use default %s="%s"‘%s’ via sparse -> dense coercion‘%s()’ is not yet implemented for representation ‘%s’‘%s()’ is not yet implemented for element type ‘%s’‘A’ must be a square matrix‘NA’ indices are not (yet?) supported for sparse Matrices‘by’ argument is much too small‘cl’ is not a character string‘cols’ has elements not in seq(0, length.out = n)‘cols’ must be numeric‘contrasts.arg’ argument must be named‘diagonals’ matrix must have %d columns (= length(k) )‘diagonals’ must have the same length (%d) as ‘k’‘dims’ must contain all (i,j) pairs‘file’ must be a character string or connection‘force’ must be (coercable to) TRUE or FALSE‘giveCsparse’ has been deprecated; setting ‘repr = "T"’ for you‘giveCsparse’ has been deprecated; will use ‘repr’ instead‘giveCsparse’ is deprecated; setting repr="T" for you‘giveCsparse’ is deprecated; using ‘repr’ instead‘i’ and ‘j’ must be‘i’ and ‘j’ must not contain NA‘kind’ must be one of "d", "l", "n"‘lst’ must be a list‘lwd’ must be NULL or non-negative numeric‘n’ must be a non-negative integer‘ncol’ is not a factor of length(x)‘ncol’ must be >= 0‘nearPD()’ did not converge in %d iterations‘nrow’ and ‘ncol’ must be the same when ‘symmetric’ is true‘nrow’ is not a factor of length(x)‘nrow’ must be >= 0‘nrow’, ‘ncol’, ‘byrow’ disregarded for [mM]atrix ‘data’‘p’ must be a nondecreasing vector c(0, ...)‘shape’ must be one of "g", "t", "s"‘uplo’ must be "U" or "L"‘x’ has unsupported class "%s"‘x’ has unsupported type "%s"‘x’ must have length nrow^2 when ‘symmetric’ is true‘x’ must inherit from "sparseVector".M.repl.i.2col(): ‘i’ has no integer column number; should never happen; please report.M.repl.i.2col(): drop ‘matrix’ case ... --> is not yet implemented[i] is not yet implemented --> is not yet implementedClass %s is not yet implementedCmp.Mat.atomic() should not be called for diagonalMatrixD[i,i] is NA, i=%dD[i,i] is negative, i=%dInternal bug: nargs()=%d; please reportInvalid assembled indicator: %sInvalid storage format: %sInvalid storage type: %sLogic.Mat.atomic() should not be called for diagonalMatrixMatrices must have same number of rows for arithmeticMatrix seems negative semi-definiteMust specify ‘nrow’ when ‘symmetric’ is trueNAs are not allowed in subscripted assignmentsNot a valid formatOnly numeric sparse matrices allowedRHS ‘value’ (class %s) matches ‘ANY’, but must match matrix class %s[ ] indexing not allowed: forgot a "," ?[[ suppressing %d column name%s %s ... ]]a sparseMatrix should rarely be centered: will not be sparse anymoreall() is not yet implementedassigned dimensions [product %.0f] do not match object length [%.0f]assigned dimensions are NAassigned dimensions are negativeassigned dimensions are not of type "%s" or "%s"assigned dimensions do not have length %dassigned dimensions exceed %sattempt to coerce matrix with NA to %sattempt to coerce non-square matrix to %sattempt to recycle ‘x’ of length 0 to length ‘n’ (n > 0)c(,..) of different kinds, coercing all to ‘rleDiff’cannot coerce from %s to %scannot coerce matrix of type "%s" to %scolumn indices must be <= ncol(.) which is %dcomplex %s not yet implementeddata is too longdeterminant of non-square matrix is undefineddiag(%s) has non-positive or non-finite entries; finite result is doubtfuldim [product %d] do not match the length of object [%d]dimensions cannot exceed %sdimensions cannot exceed 2^31-1dimensions of ‘%s’ and ‘%s’ are inconsistentdimnames [%d] mismatch in %selement type ‘%s’ not recognizedelement type ‘complex’ not yet implementedexactly one of ‘i’, ‘j’, and ‘p’ must be missing from callfile is not a MatrixMarket filefirst element used of ‘%s’ argumentfor symmetric band matrix, only specify upper or lower triangle hence, all k must have the same signhit a cycle (1) -- stop iterationshit a cycle (2) -- stop iterationsi1[1] == 0 ==> C-level verbosity will not happen!in show(); maybe adjust options(max.print=, width=)incorrect number of dimensionsindex larger than maximal %dindex must be numeric, logical or sparseVector for indexing sparseVectorsinefficient method used for "- e1"intermediate ‘r’ is of type %sinternal bug in "Compare" method (Cmp.Mat.atomic); please reportinternal bug in "Logic" method (Logic.Mat.atomic); please reportinternal bug: matrix ‘i’ in replTmat(): please reportinternal bug: missing ‘i’ in replTmat(): please reportinvalid %s="%s"invalid %s="%s" to ‘%s’invalid ‘%s’ argumentinvalid ‘%s’: not in %d:%dinvalid ‘Class2’invalid ‘col.names’ string: %sinvalid ‘data’invalid ‘dims’invalid ‘repr’; must be "C", "R", or "T"invalid ‘repr’; must be "C", "T", or "R"invalid (to - from)/by in seq(.)invalid character indexinginvalid class "%s" in ‘%s’invalid class "%s" in ‘%s’ methodinvalid mode "%s"invalid nargs()= %dinvalid subscript class "%s"invalid subscript type "%s"invalid type "%s" in ‘%s’invalid type "%s" in ‘%s’ methodis not an integer multiple of length(x)length must be non-negative numberlength of ‘center’ must equal the number of columns of ‘x’length of ‘scale’ must equal the number of columns of ‘x’length of 1st arg does not match dimension of 2ndlength of 2nd arg does not match dimension of firstlength(i)length(x) must not exceedlogic programming error in printSpMatrix2(), please reportlogical subscript too longlogical subscript too long (%d, should be %d)longer object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthm[ ] <- v: inefficiently treating single elementsmatrix can only be symmetric if square, but n != mmatrix exactly singular, J[i,]=0, i=%dmatrix is exactly singular, D[i,i]=0, i=%dmatrix is exactly singular, J[,j]=0, j=%dmatrix is not diagonal; consider Diagonal(x=diag(.))matrix is not squarematrix is not symmetricmatrix is not symmetric or triangularmatrix is not symmetric; consider forceSymmetric(.) or symmpart(.)matrix is not triangularmatrix is not triangular; consider triu(.) or tril(.)matrix is structurally rank deficient; using augmented matrix with additional %d row(s) of zerosmatrix must have exactly one entry in each row and columnmatrix must have exactly one entry in each row or columnmismatch between typeof(x)="%s" and kind="%s"; using kind="%s"model frame and formula mismatch in sparse.model.matrix()must either specify ‘A’ or the functions ‘A.x’ and ‘At.x’nargs() = %d should never happen; please report.nargs() = %d. Extraneous illegal arguments inside ‘[ .. ]’ ?need greater ‘%s’ as pivoting occurrednegative values are not allowed in a matrix subscriptno ‘dimnames[[.]]’: cannot use character indexingnon-conformable argumentsnon-conformable matrix dimensions in %snon-list contrasts argument ignorednon-negativenon0.i() not yet implemented for class %snormnot a positive definite matrix (and positive semidefiniteness is not checked)not converged in %d iterationsnot enough new vecs -- stop iterationsnot yet implementednot yet implemented .. please reportnot-yet-implemented ‘Matrix[<-’ methodnothing to replace withnumber of items to replace is not a multiple of replacement lengthnumber of nonzero entries cannot exceed %snumber of rows are not compatible for %sonly square matrices can be used as graph incidence matricesonly zeros may be mixed with negative subscriptsp[length(p)]positiveprod() is not yet implementedqr2rankMatrix(.): QR with only %d out of %d finite diag(R) entriesrankMatrix(, method = ‘%s’) coerces to dense matrix. Probably should rather use method = ‘qr’ !?rankMatrix(x, method=‘qr’): computing t(x) as nrow(x) < ncol(x)readMM(): column indices ‘j’ are not in 1:ncol[=%d]readMM(): expected %d entries but found only %dreadMM(): row indices ‘i’ are not in 1:nrow[=%d]recycled %s would have maximal index exceeding %sreplacement diagonal has incompatible type "%s"replacement diagonal has wrong lengthrepresentation ‘%s’ not recognizedrow indices must be <= nrow(.) which is %dshould never happen ...subscript out of boundssubscripts exceeding %s replaced with NAsuch indexing must be by logical or 2-column numeric matrixsum() is not yet implementedsuppressing %d columnssuppressing %d columns and %d rowssuppressing %d rowssymmetric matrix must be squaresymmetry form ‘%s’ is not yet implementedsymmetry form ‘%s’ not recognizedsymmetry form ‘hermitian’ not yet implemented for readingsymmetry form ‘skew-symmetric’ not yet implemented for readingthe %d-th (sub)-diagonal (k = %d) is too short; filling with NA'sthe default value of argument ‘%s’ of method ‘%s(<%s>, <%s>)’ may change from %s to %s as soon as the next release of Matrix; set ‘%s’ when programmingtoo many argumentstoo many replacement valuestriangular matrix must be squaretrimmed means are not defined for complex datatype ‘%s’ not recognizedunexpected %s="%s" in ‘%s’ methoduniDiag=TRUE, but not all diagonal entries are 1uniDiag=TRUE, not all entries in diagonal coded as 1use Diagonal() to construct diagonal (symmetric && triangular) sparse matricesusing "old code" part in Csparse subassignmentusing"old code" part in Csparse subassignment >>> please report to Matrix-authors@r-project.orgvariable ‘%s’ is absent, its contrast will be ignoredvector too long in Matrix - vector operationwhen ‘A’ is specified, ‘A.x’ and ‘At.x’ are disregardedwrong sign in ‘by’ argumentx / 0 for an x with sign-change no longer representable as ‘rleDiff’x[.,.] <- val : x being coerced from Tsparse* to CsparseMatrixx[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced NA |--> TRUE.x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced.x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced.x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced; NA |--> TRUE.you cannot mix negative and positive indicesMatrix/po/0000755000176200001440000000000014547724215012147 5ustar liggesusersMatrix/po/lt.po0000644000176200001440000015070514521047060013122 0ustar liggesusers# Lithuanian translations for Matrix package. # Copyright (C) 2020 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the Matrix package. # Gabrielė Stupurienė , 2020. # msgid "" msgstr "" "Project-Id-Version: Matrix 1.3-3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-11-02 21:33-0400\n" "PO-Revision-Date: 2021-02-25 14:30+0200\n" "Last-Translator: Gabrielė Stupurienė \n" "Language-Team: none\n" "Language: lt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && (n%100<11 || n%100>19) ? 0 : " "n%10>=2 && n%10<=9 && (n%100<11 || n%100>19) ? 1 : 2);\n" "X-Generator: Poedit 2.4.2\n" #: Csparse.c:26 Csparse.c:318 chm_common.c:165 chm_common.c:291 #: chm_common.c:813 chm_common.c:816 chm_common.c:849 chm_common.c:867 #: dgCMatrix.c:18 dgCMatrix.c:43 dgCMatrix.c:70 dgCMatrix.c:84 dgCMatrix.c:89 #: dgCMatrix.c:94 #, fuzzy, c-format msgid "'%s' failed" msgstr "cs_qr nepavyko" #: Csparse.c:35 chm_common.c:54 #, fuzzy, c-format msgid "'%s' slot is not increasing within columns after sorting" msgstr "laukas j nedidėja stulpelio viduje" #: Csparse.c:77 coerce.c:220 coerce.c:240 coerce.c:250 coerce.c:905 #: coerce.c:911 coerce.c:1015 coerce.c:1501 coerce.c:1521 coerce.c:1531 #: coerce.c:2061 coerce.c:2256 coerce.c:2262 coerce.c:2268 coerce.c:2397 #: coerce.c:2404 coerce.c:2494 coerce.c:2629 coerce.c:2707 coerce.c:2729 #: coerce.c:4327 coerce.c:4396 dense.c:701 products.c:936 products.c:1288 #: solve.c:719 solve.c:968 solve.c:1100 sparse.c:1233 sparse.c:1625 #, fuzzy, c-format msgid "invalid '%s' to '%s'" msgstr "netinkamas argumentas '%s'" #: Csparse.c:316 #, fuzzy, c-format msgid "failed to open file \"%s\" for writing" msgstr "nepavyko atidaryti failo \"%s\" rašymui" #: attrib.c:229 #, fuzzy msgid "invalid factor name" msgstr "netinkamas argumentas '%s'" #: attrib.c:233 #, c-format msgid "attempt to set factor on %s without '%s' slot" msgstr "" #: bind.c:46 bind.c:153 msgid "number of rows of matrices must match" msgstr "" #: bind.c:48 bind.c:155 msgid "number of columns of matrices must match" msgstr "" #: bind.c:51 bind.c:158 bind.c:182 bind.c:206 chm_common.c:474 chm_common.c:623 #: chm_common.c:717 cholmod-etc.c:183 cholmod-etc.c:282 cholmod-etc.c:325 #: coerce.c:215 coerce.c:235 coerce.c:260 coerce.c:268 coerce.c:276 #: coerce.c:341 coerce.c:1496 coerce.c:1516 coerce.c:1543 coerce.c:1551 #: coerce.c:1559 products.c:28 products.c:50 products.c:56 #, c-format msgid "dimensions cannot exceed %s" msgstr "" #: bind.c:210 msgid "number of rows of result is not a multiple of vector length" msgstr "" #: bind.c:212 msgid "number of columns of result is not a multiple of vector length" msgstr "" #: bind.c:626 bind.c:691 sparse.c:912 sparse.c:993 #, c-format msgid "%s cannot exceed %s" msgstr "" #: bind.c:756 bind.c:853 chm_common.c:720 cholmod-etc.c:328 coerce.c:29 #: coerce.c:518 coerce.c:811 coerce.c:945 coerce.c:2772 coerce.c:3041 #: coerce.c:3139 dense.c:924 products.c:151 products.c:212 products.c:291 #: products.c:379 products.c:456 products.c:550 products.c:865 subscript.c:1232 #: subscript.c:1417 utils-R.c:32 #, c-format msgid "attempt to allocate vector of length exceeding %s" msgstr "" #: bind.c:858 products.c:1354 msgid "should never happen ..." msgstr "" #: chm_common.c:11 chm_common.c:34 validity.c:38 validity.c:183 validity.c:262 #: validity.c:281 validity.c:290 validity.c:309 validity.c:335 validity.c:355 #: validity.c:405 validity.c:422 validity.c:456 validity.c:473 validity.c:507 #: validity.c:509 validity.c:959 validity.c:992 validity.c:1074 validity.c:1094 #: validity.c:1160 validity.c:1162 validity.c:1210 validity.c:1273 #: validity.c:1275 validity.c:1321 validity.c:1368 validity.c:1417 #: validity.c:1450 validity.c:1460 validity.c:1473 validity.c:1527 #: validity.c:1529 validity.c:1561 validity.c:1573 validity.c:1596 #: validity.c:1659 validity.c:1678 validity.c:1680 validity.c:1712 #: validity.c:1747 validity.c:1775 #, fuzzy, c-format msgid "'%s' slot is not of type \"%s\"" msgstr "Dim laukas nėra sveikasis skaičius" #: chm_common.c:14 validity.c:357 validity.c:407 validity.c:458 validity.c:880 #: validity.c:891 validity.c:961 validity.c:994 validity.c:1096 validity.c:1164 #: validity.c:1212 validity.c:1277 validity.c:1323 validity.c:1462 #: validity.c:1479 validity.c:1531 validity.c:1533 validity.c:1563 #: validity.c:1575 validity.c:1598 validity.c:1714 validity.c:1751 #: validity.c:1779 validity.c:1829 #, fuzzy, c-format msgid "'%s' slot does not have length %s" msgstr "Dim laukas turi būti 2 ilgio" #: chm_common.c:18 validity.c:410 validity.c:461 validity.c:1667 #: validity.c:1687 validity.c:1689 #, fuzzy, c-format msgid "first element of '%s' slot is not 0" msgstr "pirmasis lauko p elementas turi būti lygus nuliui" #: chm_common.c:23 chm_common.c:46 validity.c:43 validity.c:361 validity.c:414 #: validity.c:432 validity.c:465 validity.c:483 validity.c:519 validity.c:521 #: validity.c:1041 validity.c:1053 validity.c:1100 validity.c:1173 #: validity.c:1185 validity.c:1286 validity.c:1298 validity.c:1327 #: validity.c:1378 validity.c:1427 validity.c:1466 validity.c:1486 #: validity.c:1567 validity.c:1583 validity.c:1608 validity.c:1672 #: validity.c:1692 validity.c:1694 validity.c:1721 #, c-format msgid "'%s' slot contains NA" msgstr "" #: chm_common.c:26 validity.c:416 validity.c:467 #, fuzzy, c-format msgid "'%s' slot is not nondecreasing" msgstr "laukas p turi būti nemažėjantis" #: chm_common.c:29 validity.c:418 validity.c:469 #, c-format msgid "first differences of '%s' slot exceed %s" msgstr "" #: chm_common.c:37 validity.c:424 validity.c:475 #, fuzzy, c-format msgid "'%s' slot has length less than %s" msgstr "'Dim' lauko ilgis yra mažesnis nei du" #: chm_common.c:49 validity.c:363 validity.c:434 validity.c:485 validity.c:523 #: validity.c:526 validity.c:1043 validity.c:1102 validity.c:1175 #: validity.c:1187 validity.c:1288 validity.c:1300 validity.c:1380 #: validity.c:1429 validity.c:1488 validity.c:1610 validity.c:1723 #, fuzzy, c-format msgid "'%s' slot has elements not in {%s}" msgstr "'Dim' lauko ilgis yra mažesnis nei du" #: chm_common.c:467 chm_common.c:470 chm_common.c:472 chm_common.c:616 #: chm_common.c:619 chm_common.c:621 chm_common.c:711 chm_common.c:713 #: cholmod-etc.c:177 cholmod-etc.c:179 cholmod-etc.c:181 cholmod-etc.c:276 #: cholmod-etc.c:278 cholmod-etc.c:280 cholmod-etc.c:319 cholmod-etc.c:321 #: cs-etc.c:43 #, c-format msgid "wrong '%s'" msgstr "" #: chm_common.c:477 cholmod-etc.c:186 #, fuzzy, c-format msgid "'%s' would overflow type \"%s\"" msgstr "Dim laukas nėra sveikasis skaičius" #: chm_common.c:481 cholmod-etc.c:190 #, c-format msgid "n+1 would overflow type \"%s\"" msgstr "" #: chm_common.c:486 cholmod-etc.c:195 #, fuzzy, c-format msgid "leading principal minor of order %d is not positive" msgstr "vadovaujantis minoras, kurio eilė yra %d, nėra teigiamai apibrėžtas" #: chm_common.c:489 cholmod-etc.c:198 #, fuzzy, c-format msgid "leading principal minor of order %d is zero" msgstr "vadovaujantis minoras, kurio eilė yra %d, nėra teigiamai apibrėžtas" #: chm_common.c:715 cholmod-etc.c:323 msgid "leading dimension not equal to number of rows" msgstr "" #: chm_common.c:778 #, c-format msgid "" "invalid simplicial Cholesky factorization: structural zero on main diagonal " "in column %d" msgstr "" #: chm_common.c:838 #, fuzzy, c-format msgid "CHOLMOD error '%s' at file '%s', line %d" msgstr "Cholmod klaida '%s' faile %s, eilutė %d" #: chm_common.c:841 #, fuzzy, c-format msgid "CHOLMOD warning '%s' at file '%s', line %d" msgstr "Cholmod įspėjimas '%s' faile %s, eilutė %d" #: coerce.c:24 coerce.c:364 coerce.c:1050 #, fuzzy, c-format msgid "attempt to construct non-square %s" msgstr "Determinantui reikia kvadratinės matricos" #: coerce.c:186 coerce.c:476 coerce.c:1467 coerce.c:1622 #, c-format msgid "second argument of '%s' does not specify a subclass of %s" msgstr "" #: coerce.c:194 coerce.c:200 coerce.c:484 coerce.c:490 coerce.c:925 #: coerce.c:1475 coerce.c:1481 coerce.c:1630 coerce.c:1636 coerce.c:2275 #: coerce.c:3344 coerce.c:3349 #, fuzzy, c-format msgid "'%s' must be \"%s\" or \"%s\"" msgstr "'%s' turi būti '%s'" #: coerce.c:246 coerce.c:496 coerce.c:793 coerce.c:917 coerce.c:1527 #: coerce.c:1642 dense.c:322 dense.c:1107 dense.c:1683 dense.c:1688 #: dense.c:1934 dense.c:2129 sparse.c:783 sparse.c:2448 sparse.c:3140 #: sparse.c:3145 sparse.c:3150 sparse.c:3426 sparse.c:3663 #, fuzzy, c-format msgid "'%s' must be %s or %s" msgstr "'%s' turi būti '%s'" #: coerce.c:266 coerce.c:274 coerce.c:285 coerce.c:1549 coerce.c:1557 #: coerce.c:1568 msgid "nonempty vector supplied for empty matrix" msgstr "" #: coerce.c:287 coerce.c:1570 #, c-format msgid "vector length (%lld) exceeds matrix length (%d * %d)" msgstr "" #: coerce.c:290 coerce.c:1573 #, c-format msgid "matrix length (%d * %d) is not a multiple of vector length (%lld)" msgstr "" #: coerce.c:521 #, c-format msgid "coercing n-by-n %s to %s is not supported for n*n exceeding %s" msgstr "" #: coerce.c:525 coerce.c:815 coerce.c:949 #, c-format msgid "sparse->dense coercion: allocating vector of size %0.1f GiB" msgstr "" #: coerce.c:1196 coerce.c:1941 coerce.c:2948 coerce.c:2954 #, c-format msgid "attempt to construct %s with more than %s nonzero entries" msgstr "" #: coerce.c:3246 #, fuzzy msgid "attempt to pack non-square matrix" msgstr "Determinantui reikia kvadratinės matricos" #: coerce.c:3420 coerce.c:3590 #, c-format msgid "unable to aggregate %s with '%s' and '%s' slots of length exceeding %s" msgstr "" #: coerce.c:4211 #, fuzzy, c-format msgid "attempt to pack a %s" msgstr "Determinantui reikia kvadratinės matricos" #: coerce.c:4330 dense.c:1237 sparse.c:2579 #, fuzzy, c-format msgid "'%s' must be %s or %s or %s" msgstr "'%s' turi būti '%s'" #: dense.c:210 dense.c:215 sparse.c:590 sparse.c:595 #, fuzzy, c-format msgid "'%s' must be an integer from %s to %s" msgstr "'%s' turi būti '%s'" #: dense.c:218 sparse.c:598 #, fuzzy, c-format msgid "'%s' must be less than or equal to '%s'" msgstr "'%s' turi būti '%s'" #: dense.c:428 sparse.c:1069 #, fuzzy, c-format msgid "replacement diagonal has incompatible type \"%s\"" msgstr "keitimo įstrižainės ilgis neteisingas" #: dense.c:437 sparse.c:1078 msgid "replacement diagonal has wrong length" msgstr "keitimo įstrižainės ilgis neteisingas" #: dense.c:627 sparse.c:1274 #, fuzzy msgid "attempt to symmetrize a non-square matrix" msgstr "Determinantui reikia kvadratinės matricos" #: dense.c:726 sparse.c:1652 msgid "attempt to get symmetric part of non-square matrix" msgstr "" #: dense.c:878 sparse.c:2082 msgid "attempt to get skew-symmetric part of non-square matrix" msgstr "" #: dense.c:1678 sparse.c:3135 #, fuzzy, c-format msgid "'%s' must be %d or %d" msgstr "'%s' turi būti '%s'" #: dense.c:2161 #, c-format msgid "incorrect left cyclic shift, j (%d) < 0" msgstr "neteisingas kairysis ciklinis pastūmimas, j (%d) < 0" #: dense.c:2164 #, c-format msgid "incorrect left cyclic shift, j (%d) >= k (%d)" msgstr "neteisingas kairysis ciklinis pastūmimas, j (%d) >= k (%d)" #: dense.c:2167 #, c-format msgid "incorrect left cyclic shift, k (%d) > ldx (%d)" msgstr "neteisingas kairysis ciklinis pastūmimas, k (%d) > ldx (%d)" #: dense.c:2220 #, fuzzy msgid "unknown error in getGivens" msgstr "Nežinoma getGivens klaida" #: dense.c:2229 dense.c:2243 dense.c:2273 msgid "X must be a numeric (double precision) matrix" msgstr "X turi būti skaitinė (dvigubo tikslumo) matrica" #: dense.c:2245 dense.c:2275 msgid "y must be a numeric (double precision) matrix" msgstr "y turi būti skaitinė (dvigubo tikslumo) matrica" #: dense.c:2249 dense.c:2279 #, c-format msgid "number of rows in y (%d) does not match number of rows in X (%d)" msgstr "" "eilučių skaičius, esantis y (%d) neatitinka eilučių skaičiaus, esančio X (%d)" #: dense.c:2265 #, fuzzy, c-format msgid "LAPACK dposv returned error code %d" msgstr "Lapack programa dposv grąžino klaidos kodą %d" #: dense.c:2293 dense.c:2299 #, fuzzy, c-format msgid "LAPACK dgels returned error code %d" msgstr "Lapack programa %s grąžino klaidos kodą %d" #: dense.c:2318 msgid "X must be a real (numeric) matrix" msgstr "X turi būti realioji (skaitinė) matrica" #: dense.c:2321 #, fuzzy, c-format msgid "tol, given as %g, must be >= 0" msgstr "tol, kaip %g, turi būti < = 1" #: dense.c:2323 #, c-format msgid "tol, given as %g, must be <= 1" msgstr "tol, kaip %g, turi būti < = 1" #: dense.c:2352 dense.c:2360 #, fuzzy, c-format msgid "LAPACK dgeqrf returned error code %d" msgstr "Pirmasis iškvietimas į dgeqrf grąžino klaidos kodą %d" #: dense.c:2365 dense.c:2388 #, fuzzy, c-format msgid "LAPACK dtrcon returned error code %d" msgstr "Lapack programa dtrcon grąžino klaidos kodą %d" #: determinant.c:33 #, fuzzy msgid "determinant of non-square matrix is undefined" msgstr "Determinantui reikia kvadratinės matricos" #: determinant.c:276 #, fuzzy, c-format msgid "%s(<%s>) does not support structurally rank deficient case" msgstr "%s(): struktūrinio rango deficito atvejis: galbūt WRONG nuliai" #: dgCMatrix.c:14 #, fuzzy, c-format msgid "'%s' is empty or not square" msgstr "Matrica nėra kvadratinė" #: dgCMatrix.c:16 dgCMatrix.c:38 dgCMatrix.c:61 solve.c:43 solve.c:984 #, fuzzy, c-format msgid "dimensions of '%s' and '%s' are inconsistent" msgstr "Sistemos, kurią reikia išspręsti, matmenys yra nenuoseklūs" #: dgCMatrix.c:40 #, c-format msgid "%s(%s, %s) requires m-by-n '%s' with m >= n > 0" msgstr "" #: dgCMatrix.c:63 #, c-format msgid "%s(%s, %s) requires m-by-n '%s' with n >= m > 0" msgstr "" #: dgeMatrix.c:22 #, fuzzy, c-format msgid "dgeMatrix_svd(x,*): dim(x)[j] = %d is too large" msgstr "Matricos matmenys %d x %d (= %g) yra per dideli" #: dgeMatrix.c:90 msgid "Matrix exponential requires square, non-null matrix" msgstr "Matricos eksponentė reikalauja kvadratinės, ne nulinės matricos" #: dgeMatrix.c:107 dgeMatrix.c:109 #, c-format msgid "dgeMatrix_exp: LAPACK routine dgebal returned %d" msgstr "dgeMatrix_exp: LAPACK programa dgebal grąžino %d" #: dgeMatrix.c:147 #, c-format msgid "dgeMatrix_exp: dgetrf returned error code %d" msgstr "dgeMatrix_exp: dgetrf grąžino klaidos kodą %d" #: dgeMatrix.c:149 #, c-format msgid "dgeMatrix_exp: dgetrs returned error code %d" msgstr "dgeMatrix_exp: dgetrs grąžino klaidos kodą %d" #: dgeMatrix.c:224 msgid "dgeMatrix_Schur: argument x must be a non-null square matrix" msgstr "dgeMatrix_Schur: argumentas x turi būti ne nulinė kvadratinė matrica" #: dgeMatrix.c:237 msgid "dgeMatrix_Schur: first call to dgees failed" msgstr "dgeMatrix_Schur: pirmasis iškvietimas į dgees nepavyko" #: dgeMatrix.c:246 #, c-format msgid "dgeMatrix_Schur: dgees returned code %d" msgstr "dgeMatrix_Schur: dgees grąžintas kodas %d" #: factorizations.c:355 sparse.c:196 #, fuzzy, c-format msgid "'%s' is not a number" msgstr "%s nėra sąrašas" #: factorizations.c:376 #, c-format msgid "LU factorization of m-by-n %s requires m == n" msgstr "" #: factorizations.c:385 #, c-format msgid "LU factorization of %s failed: out of memory or near-singular" msgstr "" #: factorizations.c:462 #, c-format msgid "QR factorization of m-by-n %s requires m >= n" msgstr "" #: factorizations.c:471 #, c-format msgid "QR factorization of %s failed: out of memory" msgstr "" #: factorizations.c:571 factorizations.c:849 #, c-format msgid "'%s' is not a number or not finite" msgstr "" #: idz.c:467 idz.c:528 #, c-format msgid "incompatible '%s' and '%s' in '%s'" msgstr "" #: kappa.c:10 kappa.c:54 #, fuzzy, c-format msgid "argument '%s' is not of type \"%s\"" msgstr "argumentas type[1]='%s' turi būti vienos raidės simbolio eilutė" #: kappa.c:13 kappa.c:57 #, fuzzy, c-format msgid "argument '%s' has length %d" msgstr "'%s' eilutės ilgis turi būti 1" #: kappa.c:17 kappa.c:61 #, fuzzy, c-format msgid "argument '%s' (\"%s\") does not have string length %d" msgstr "'%s' eilutės ilgis turi būti 1" #: kappa.c:41 #, c-format msgid "" "argument '%s' (\"%s\") is not \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", or " "\"%s\"" msgstr "" #: kappa.c:75 #, fuzzy, c-format msgid "argument '%s' (\"%s\") is not \"%s\", \"%s\", or \"%s\"" msgstr "'%s' eilutės ilgis turi būti 1" #: kappa.c:238 #, c-format msgid "%s(%s) is undefined: '%s' is not square" msgstr "" #: objects.c:23 #, c-format msgid "unexpected type \"%s\" in '%s'" msgstr "" #: objects.c:41 objects.c:58 #, c-format msgid "unexpected kind \"%c\" in '%s'" msgstr "" #: perm.c:26 perm.c:106 msgid "attempt to get sign of non-permutation" msgstr "" #: perm.c:51 perm.c:123 msgid "attempt to invert non-permutation" msgstr "" #: perm.c:66 #, fuzzy msgid "invalid transposition vector" msgstr "neleistinas eilutės indeksas padėtyje %d" #: perm.c:79 perm.c:81 perm.c:96 perm.c:98 perm.c:113 perm.c:133 perm.c:145 #, fuzzy, c-format msgid "'%s' is not of type \"%s\"" msgstr "Dim laukas nėra sveikasis skaičius" #: perm.c:83 perm.c:100 perm.c:147 #, fuzzy, c-format msgid "'%s' does not have length %d" msgstr "'%s' lauko ilgis turi būti 1" #: perm.c:86 perm.c:103 #, c-format msgid "'%s' is NA" msgstr "" #: perm.c:115 perm.c:138 #, fuzzy, c-format msgid "'%s' or '%s' is not of type \"%s\"" msgstr "Dim laukas nėra sveikasis skaičius" #: perm.c:117 perm.c:140 #, fuzzy, c-format msgid "'%s' or '%s' does not have length %d" msgstr "'%s' lauko ilgis turi būti 1" #: perm.c:120 perm.c:143 #, c-format msgid "'%s' or '%s' is NA" msgstr "" #: perm.c:136 #, c-format msgid "'%s' has length exceeding %s" msgstr "" #: perm.c:150 #, c-format msgid "'%s' is NA or less than %s" msgstr "" #: products.c:107 products.c:210 products.c:289 products.c:377 products.c:454 #: products.c:548 products.c:809 products.c:859 msgid "non-conformable arguments" msgstr "" #: products.c:782 products.c:807 #, c-format msgid "'%s' does not support complex matrices" msgstr "" #: solve.c:38 #, fuzzy, c-format msgid "'%s' is not square" msgstr "Matrica nėra kvadratinė" #: solve.c:497 #, c-format msgid "%s(<%s>, <%s>) failed: out of memory" msgstr "" #: solve.c:618 #, fuzzy, c-format msgid "attempt to construct %s with more than %s nonzero elements" msgstr "Determinantui reikia kvadratinės matricos" #: sparseVector.c:90 #, c-format msgid "%s length cannot exceed %s" msgstr "" #: subscript.c:1542 subscript.c:1695 subscript.c:1938 subscript.c:2122 #, c-format msgid "%s too dense for %s; would have more than %s nonzero entries" msgstr "" #: subscript.c:2209 #, c-format msgid "NA subscripts in %s not supported for '%s' inheriting from %s" msgstr "" #: t_Csparse_subassign.c:142 msgid "invalid class of 'x' in Csparse_subassign()" msgstr "netinkama 'x' klasė, esanti Csparse_subassign()" #: t_Csparse_subassign.c:144 msgid "invalid class of 'value' in Csparse_subassign()" msgstr "netinkama 'value' klasė, esanti Csparse_subassign()" #: t_Csparse_subassign.c:187 #, c-format msgid "x[] <- val: val is coerced to logical for \"%s\" x" msgstr "x[] <- val: val yra paverstas į loginį \"%s\" x" #: t_Csparse_subassign.c:192 #, c-format msgid "" "x[] <- val: val should be integer or logical, is coerced to integer, for " "\"%s\" x" msgstr "" "x[] <- val: val turėtų būti sveikasis skaičius arba loginis, yra pakeistas į " "sveikąjį skaičių dėl \"%s\" x" #: t_Csparse_subassign.c:199 msgid "programming error in Csparse_subassign() should never happen" msgstr "programavimo klaida Csparse_subassign() niekada neturėtų įvykti" #: utils-R.c:30 utils-R.c:116 #, c-format msgid "indices would exceed %s" msgstr "" #: utils-R.c:235 utils-R.c:270 utils-R.c:281 utils-R.c:312 msgid "Argument must be numeric-like atomic vector" msgstr "Argumentas turi būti skaitinis atominis vektorius" #: utils-R.c:345 msgid "'data' must be of a vector type" msgstr "'data' turi būti vektoriaus tipo" #: utils-R.c:352 #, c-format msgid "invalid '%s' argument" msgstr "netinkamas argumentas '%s'" #: utils-R.c:359 utils-R.c:367 msgid "non-numeric matrix extent" msgstr "neskaitinės matricos dydis" #: utils-R.c:362 msgid "invalid 'nrow' value (too large or NA)" msgstr "neleistina 'nrow' reikšmė (per didelė arba NA)" #: utils-R.c:364 msgid "invalid 'nrow' value (< 0)" msgstr "neleistina 'nrow' reikšmė (< 0)" #: utils-R.c:370 msgid "invalid 'ncol' value (too large or NA)" msgstr "neleistina 'ncol' reikšmė (per didelė arba NA)" #: utils-R.c:372 msgid "invalid 'ncol' value (< 0)" msgstr "neleistina 'ncol' reikšmė (< 0)" #: utils-R.c:390 #, c-format msgid "" "data length [%d] is not a sub-multiple or multiple of the number of rows [%d]" msgstr "duomenų ilgis [%d] nėra eilučių skaičiaus pogrupis ar kartotinis [%d]" #: utils-R.c:395 #, c-format msgid "" "data length [%d] is not a sub-multiple or multiple of the number of columns " "[%d]" msgstr "" "duomenų ilgis [%d] nėra stulpelių skaičiaus pogrupis ar kartotinis [%d]" #: utils-R.c:399 msgid "data length exceeds size of matrix" msgstr "duomenų ilgis viršija matricos dydį" #: utils-R.c:404 msgid "too many elements specified" msgstr "nurodyta per daug elementų" #: utils-R.c:545 msgid "Argument ij must be 2-column integer matrix" msgstr "Argumentas ij turi būti 2 stulpelių sveikųjų skaičių matrica" #: utils-R.c:570 msgid "subscript 'i' out of bounds in M[ij]" msgstr "apatinis indeksas 'i' už M[ij] ribų" #: utils-R.c:572 msgid "subscript 'j' out of bounds in M[ij]" msgstr "apatinis indeksas 'j' už M[ij] ribų" #: utils-R.c:626 msgid "i and j must be integer vectors of the same length" msgstr "i ir j turi būti to paties ilgio sveikieji vektoriai" #: validity.c:40 validity.c:73 validity.c:264 validity.c:283 validity.c:292 #: validity.c:311 validity.c:337 validity.c:1010 validity.c:1452 #: validity.c:1476 #, fuzzy, c-format msgid "'%s' slot does not have length %d" msgstr "Dim laukas turi būti 2 ilgio" #: validity.c:45 validity.c:965 validity.c:998 #, fuzzy, c-format msgid "'%s' slot has negative elements" msgstr "'Dim' lauko ilgis yra mažesnis nei du" #: validity.c:71 validity.c:197 #, fuzzy, c-format msgid "'%s' slot is not a list" msgstr "Dim laukas nėra sveikasis skaičius" #: validity.c:89 #, fuzzy, c-format msgid "%s[[%d]] is not NULL or a vector" msgstr "Dimnames[%d] nėra simbolių vektorius" #: validity.c:92 #, fuzzy, c-format msgid "length of %s[[%d]] (%lld) is not equal to %s[%d] (%d)" msgstr "length(Dimnames[%d]) skiriasi nuo Dim[%d], kuris yra %d" #: validity.c:203 #, c-format msgid "'%s' slot has no '%s' attribute" msgstr "" #: validity.c:214 validity.c:277 validity.c:305 validity.c:376 validity.c:1115 #: validity.c:1446 validity.c:1807 #, c-format msgid "%s[1] != %s[2] (matrix is not square)" msgstr "" #: validity.c:239 validity.c:252 #, c-format msgid "%s[1] differs from %s[2]" msgstr "" #: validity.c:267 validity.c:286 validity.c:295 validity.c:314 #, fuzzy, c-format msgid "'%s' slot is not \"%s\" or \"%s\"" msgstr "x laukas nėra \"double\"" #: validity.c:320 validity.c:324 #, fuzzy, c-format msgid "'%s' slot is \"%s\" but '%s' slot does not have length %s" msgstr "Dim laukas turi būti 2 ilgio" #: validity.c:340 #, fuzzy, c-format msgid "'%s' slot is not %d or %d" msgstr "x laukas nėra \"double\"" #: validity.c:346 validity.c:349 #, c-format msgid "%s-by-%s %s invalid for positive '%s' when %s=%d" msgstr "" #: validity.c:386 validity.c:1178 validity.c:1190 validity.c:1291 #: validity.c:1303 validity.c:1383 validity.c:1432 validity.c:1491 #, c-format msgid "'%s' slot contains duplicates" msgstr "" #: validity.c:437 validity.c:1613 #, fuzzy, c-format msgid "'%s' slot is not increasing within columns" msgstr "laukas j nedidėja stulpelio viduje" #: validity.c:488 #, fuzzy, c-format msgid "'%s' slot is not increasing within rows" msgstr "laukas j nedidėja stulpelio viduje" #: validity.c:512 validity.c:801 validity.c:827 validity.c:853 validity.c:1076 #: validity.c:1682 validity.c:1684 #, fuzzy, c-format msgid "'%s' and '%s' slots do not have equal length" msgstr "Dim laukas turi būti 2 ilgio" #: validity.c:515 #, c-format msgid "'%s' slot has nonzero length but %s is 0" msgstr "" #: validity.c:555 validity.c:600 validity.c:646 validity.c:691 validity.c:735 #: validity.c:770 #, fuzzy, c-format msgid "%s=\"%s\" but there are entries below the diagonal" msgstr "uplo='U' neturi turėti sparse įrašų po įstrižainės" #: validity.c:565 validity.c:613 validity.c:656 validity.c:704 validity.c:740 #: validity.c:781 #, fuzzy, c-format msgid "%s=\"%s\" but there are entries above the diagonal" msgstr "uplo='L' neturi turėti sparse įrašų virš įstrižainės" #: validity.c:603 validity.c:616 validity.c:694 validity.c:707 validity.c:773 #: validity.c:784 #, fuzzy, c-format msgid "%s=\"%s\" but there are entries on the diagonal" msgstr "uplo='U' neturi turėti sparse įrašų po įstrižainės" #: validity.c:911 validity.c:935 validity.c:939 msgid "matrix has negative diagonal elements" msgstr "" #: validity.c:955 validity.c:983 validity.c:987 msgid "matrix has nonunit diagonal elements" msgstr "" #: validity.c:1007 validity.c:1032 validity.c:1826 #, fuzzy, c-format msgid "'%s' slot is not of type \"%s\" or \"%s\"" msgstr "Dim laukas nėra sveikasis skaičius" #: validity.c:1015 validity.c:1022 #, fuzzy, c-format msgid "'%s' slot is NA" msgstr "Dim laukas nėra sveikasis skaičius" #: validity.c:1017 validity.c:1024 #, fuzzy, c-format msgid "'%s' slot is negative" msgstr "'Dim' lauko ilgis yra mažesnis nei du" #: validity.c:1026 #, fuzzy, c-format msgid "'%s' slot exceeds %s" msgstr "'%s' turi būti '%s'" #: validity.c:1036 #, fuzzy, c-format msgid "'%s' slot has length greater than '%s' slot" msgstr "'Dim' lauko ilgis yra mažesnis nei du" #: validity.c:1046 validity.c:1674 validity.c:1696 validity.c:1698 #, fuzzy, c-format msgid "'%s' slot is not increasing" msgstr "laukas j nedidėja stulpelio viduje" #: validity.c:1056 #, fuzzy, c-format msgid "'%s' slot has elements not in {%s} after truncation towards zero" msgstr "'Dim' lauko ilgis yra mažesnis nei du" #: validity.c:1059 #, fuzzy, c-format msgid "'%s' slot is not increasing after truncation towards zero" msgstr "laukas j nedidėja stulpelio viduje" #: validity.c:1125 validity.c:1152 validity.c:1814 validity.c:1821 #, fuzzy, c-format msgid "dimensions of '%s' slot are not identical to '%s'" msgstr "X ir y matmenys nesuderinami su %s" #: validity.c:1127 #, c-format msgid "'%s' slot is upper (not lower) triangular" msgstr "" #: validity.c:1140 #, c-format msgid "'%s' slot has nonunit diagonal elements" msgstr "" #: validity.c:1154 #, c-format msgid "'%s' slot is lower (not upper) triangular" msgstr "" #: validity.c:1166 validity.c:1279 validity.c:1370 validity.c:1419 #, fuzzy, c-format msgid "'%s' slot does not have length %s or length %s" msgstr "Dim laukas turi būti 2 ilgio" #: validity.c:1206 msgid "matrix has more columns than rows" msgstr "" #: validity.c:1226 #, fuzzy, c-format msgid "'%s' slot has fewer than %s rows" msgstr "'Dim' lauko ilgis yra mažesnis nei du" #: validity.c:1228 #, fuzzy, c-format msgid "'%s' slot has more than %s rows" msgstr "'Dim' lauko ilgis yra mažesnis nei du" #: validity.c:1230 validity.c:1252 #, fuzzy, c-format msgid "'%s' slot does not have %s columns" msgstr "Dim laukas turi būti 2 ilgio" #: validity.c:1237 #, fuzzy, c-format msgid "'%s' slot must be lower trapezoidal but has entries above the diagonal" msgstr "uplo='L' neturi turėti sparse įrašų virš įstrižainės" #: validity.c:1250 #, fuzzy, c-format msgid "'%s' slot does not have %s row" msgstr "Dim laukas turi būti 2 ilgio" #: validity.c:1259 #, fuzzy, c-format msgid "'%s' slot must be upper trapezoidal but has entries below the diagonal" msgstr "uplo='U' neturi turėti sparse įrašų po įstrižainės" #: validity.c:1263 #, c-format msgid "'%s' slot has negative diagonal elements" msgstr "" #: validity.c:1329 #, c-format msgid "'%s' slot has elements not in {%s}\\{%s}" msgstr "" #: validity.c:1338 #, c-format msgid "'%s' slot has unpaired negative elements" msgstr "" #: validity.c:1364 validity.c:1408 validity.c:1412 validity.c:1760 #: validity.c:1792 msgid "Cholesky factor has negative diagonal elements" msgstr "" #: validity.c:1455 #, fuzzy, c-format msgid "%s[%d] (%s) is not in %s" msgstr "%s nėra sąrašas" #: validity.c:1468 validity.c:1569 #, fuzzy, c-format msgid "%s is not in {%s}" msgstr "%s nėra sąrašas" #: validity.c:1505 #, c-format msgid "%s is not representable as \"%s\"" msgstr "" #: validity.c:1510 validity.c:1516 #, c-format msgid "%s[%d] (%s) is not %d or %d" msgstr "" #: validity.c:1513 validity.c:1629 validity.c:1632 validity.c:1635 #, c-format msgid "%s[%d] (%s) is not %d" msgstr "" #: validity.c:1538 #, c-format msgid "%s has elements not in {%s}" msgstr "" #: validity.c:1541 #, c-format msgid "%s has elements not in {%s}\\{%s}" msgstr "" #: validity.c:1544 #, c-format msgid "%s is %d but columns are not stored in increasing order" msgstr "" #: validity.c:1547 validity.c:1550 #, c-format msgid "traversal of '%s' slot does not complete in exactly %s steps" msgstr "" #: validity.c:1556 validity.c:1558 #, fuzzy, c-format msgid "%s is not %d" msgstr "%s nėra sąrašas" #: validity.c:1579 #, c-format msgid "column '%s' is stored first but %s is not 0" msgstr "" #: validity.c:1585 #, fuzzy, c-format msgid "'%s' slot is not increasing when traversed in stored column order" msgstr "laukas j nedidėja stulpelio viduje" #: validity.c:1587 #, c-format msgid "'%s' slot allocates fewer than %s elements for column '%s'" msgstr "" #: validity.c:1590 #, c-format msgid "'%s' slot allocates more than %s elements for column '%s'" msgstr "" #: validity.c:1604 #, c-format msgid "first entry in column '%s' does not have row index '%s'" msgstr "" #: validity.c:1638 validity.c:1641 #, c-format msgid "%s[%d] (%s) is negative" msgstr "" #: validity.c:1644 #, c-format msgid "%s[%d] (%s) is not less than %s" msgstr "" #: validity.c:1662 #, fuzzy, c-format msgid "'%s' slot has length less than %d" msgstr "'Dim' lauko ilgis yra mažesnis nei du" #: validity.c:1664 #, fuzzy, c-format msgid "'%s' slot has length greater than %s" msgstr "'Dim' lauko ilgis yra mažesnis nei du" #: validity.c:1669 #, fuzzy, c-format msgid "last element of '%s' slot is not %s" msgstr "pirmasis lauko p elementas turi būti lygus nuliui" #: validity.c:1702 #, c-format msgid "first differences of '%s' slot are less than those of '%s' slot" msgstr "" #: validity.c:1705 #, c-format msgid "supernode lengths exceed %s" msgstr "" #: validity.c:1707 #, c-format msgid "first differences of '%s' slot are not equal to supernode lengths" msgstr "" #: validity.c:1727 #, c-format msgid "" "'%s' slot is wrong within diagonal blocks (row and column indices do not " "coincide)" msgstr "" #: validity.c:1730 #, fuzzy, c-format msgid "'%s' slot is not increasing within supernodes" msgstr "laukas j nedidėja stulpelio viduje" #: validity.c:1845 #, fuzzy, c-format msgid "invalid class \"%s\" object: %s" msgstr "netinkama objekto klasė į %s" #, c-format #~ msgid "diagonal element %d of Cholesky factor is missing" #~ msgstr "trūksta Choleskio faktoriaus įstrižainės elemento %d" #, c-format #~ msgid "cholmod_factorize_p failed: status %d, minor %d of ncol %d" #~ msgstr "cholmod_factorize_p nepavyko: būsena %d, nedideli %d iš ncol %d" #~ msgid "cholmod_change_factor failed" #~ msgstr "cholmod_change_factor nepavyko" #~ msgid "cholmod_write_sparse returned error code" #~ msgstr "cholmod_write_sparse grąžintas klaidos kodas" #, c-format #~ msgid "%s = '%s' (back-permuted) is experimental" #~ msgstr "%s = '%s' (atgalinis) yra eksperimentinis" #~ msgid "diag_tC(): invalid 'resultKind'" #~ msgstr "diag_tC(): netinkamas 'resultKind'" #, fuzzy #~ msgid "complex matrices are not yet supported" #~ msgstr "sudėtinis sparse matricos kodas dar neįrašytas" #~ msgid "Argument rho must be an environment" #~ msgstr "Argumentas rho turi būti aplinka" #~ msgid "invalid class of object to as_cholmod_sparse" #~ msgstr "netinkama objekto klasė į as_cholmod_sparse" #~ msgid "invalid object passed to as_cholmod_sparse" #~ msgstr "neleistinas objektas perduotas į as_cholmod_sparse" #~ msgid "in_place cholmod_sort returned an error code" #~ msgstr "in_place cholmod_sort grąžino klaidos kodą" #~ msgid "cholmod_sort returned an error code" #~ msgstr "cholmod_sort grąžino klaidos kodą" #~ msgid "chm_sparse_to_SEXP(, *): invalid 'Rkind' (real kind code)" #~ msgstr "" #~ "chm_sparse_to_SEXP (, *): neteisingas 'Rkind' (tikrasis rūšies " #~ "kodas)" #~ msgid "unknown xtype in cholmod_sparse object" #~ msgstr "nežinomas xtype cholmod_sparse objekte" #~ msgid "complex sparse matrix code not yet written" #~ msgstr "sudėtinis sparse matricos kodas dar neįrašytas" #~ msgid "Symmetric and triangular both set" #~ msgstr "Simetriškas ir trikampis abiejų rinkinys" #~ msgid "invalid class of object to as_cholmod_triplet" #~ msgstr "netinkama objekto klasė į as_cholmod_triplet" #~ msgid "as_cholmod_triplet(): could not reallocate for internal diagU2N()" #~ msgstr "as_cholmod_triplet(): nepavyko perskirstyti vidiniam diagU2N()" #~ msgid "unknown xtype in cholmod_triplet object" #~ msgstr "nežinomas xtype cholmod_triplet objekte" #~ msgid "invalid class of object to as_cholmod_dense" #~ msgstr "netinkama objekto klasė į as_cholmod_dense" #, c-format #~ msgid "" #~ "chm_transpose_dense(ans, x) not yet implemented for %s different from %s" #~ msgstr "" #~ "chm_transpose_dense(ans, x) dar neįgyvendintas dėl %s skiriasi nuo %s" #, c-format #~ msgid "Unable to initialize cholmod: error code %d" #~ msgstr "Neįmanoma inicijuoti cholmod: klaidos kodas %d" #~ msgid "unknown 'Rkind'" #~ msgstr "nežinomas 'Rkind'" #~ msgid "unknown xtype" #~ msgstr "nežinomas xtype" #~ msgid "code for cholmod_dense with holes not yet written" #~ msgstr "cholmod_dense kodas su dar neįrašytais tarpais" #~ msgid "don't know if a dense pattern matrix makes sense" #~ msgstr "nežinau, ar tankio modelio matrica turi prasmę" #, fuzzy #~ msgid "object of invalid class to 'as_cholmod_factor()'" #~ msgstr "netinkama objekto klasė į as_cholmod_factor" #~ msgid "failure in as_cholmod_factor" #~ msgstr "klaida, esanti as_cholmod_factor" #~ msgid "CHOLMOD factorization was unsuccessful" #~ msgstr "CHOLMOD faktoringas buvo nesėkmingas" #, c-format #~ msgid "f->xtype of %d not recognized" #~ msgstr "neatpažintas %d f->xtype" #, c-format #~ msgid "chm_diagN2U(): nrow=%d, ncol=%d" #~ msgstr "chm_diagN2U(): nrow=%d, ncol=%d" #, c-format #~ msgid "chm_diagN2U(x, uploT = %d): uploT should be +- 1" #~ msgstr "chm_diagN2U(x, uploT = %d): uploT turi būti +- 1" #~ msgid "dgCMatrix_lusol requires a square, non-empty matrix" #~ msgstr "dgCMatrix_lusol reikia kvadratinės, netuščios matricos" #~ msgid "Dimensions of system to be solved are inconsistent" #~ msgstr "Sistemos, kurią reikia išspręsti, matmenys yra nenuoseklūs" #~ msgid "cs_lusol failed" #~ msgstr "cs_lusol nepavyko" #~ msgid "dgCMatrix_qrsol(., order) needs order in {0,..,3}" #~ msgstr "dgCMatrix_qrsol(., tvarka) reikia tvarkos {0,..,3}" #, c-format #~ msgid "" #~ "dgCMatrix_qrsol(<%d x %d>-matrix) requires a 'tall' rectangular matrix" #~ msgstr "" #~ "dgCMatrix_qrsol(<%d x %d>-matrix) reikalauja 'tall' stačiakampės matricos" #~ msgid "cs_qrsol() failed inside dgCMatrix_qrsol()" #~ msgstr "cs_qrsol() nepavyko viduje dgCMatrix_qrsol ()" #~ msgid "dgCMatrix_cholsol requires a 'short, wide' rectangular matrix" #~ msgstr "dgCMatrix_cholsol reikia 'short, wide' stačiakampės matricos" #~ msgid "cholmod_sdmult error (rhs)" #~ msgstr "cholmod_sdmult klaida (rhs)" #, c-format #~ msgid "cholmod_factorize failed: status %d, minor %d from ncol %d" #~ msgstr "cholmod_factorize nepavyko: būsena %d, nedideli %d iš ncol %d" #, c-format #~ msgid "cholmod_solve (CHOLMOD_A) failed: status %d, minor %d from ncol %d" #~ msgstr "" #~ "cholmod_solve (CHOLMOD_A) nepavyko: būsena %d, nedideli %d iš ncol %d" #~ msgid "cholmod_sdmult error (resid)" #~ msgstr "cholmod_sdmult klaida (resid)" #~ msgid "SuiteSparseQR_C_QR returned an error code" #~ msgstr "SuiteSparseQR_C_QR grąžino klaidos kodą" #, fuzzy, c-format #~ msgid "LAPACK routine '%s': matrix is exactly singular, %s[i,i]=0, i=%d" #~ msgstr "Lapack programa dgetrs: sistema yra tiksliai singuliari" #, fuzzy, c-format #~ msgid "" #~ "LAPACK routine '%s': leading principal minor of order %d is not positive" #~ msgstr "vadovaujantis minoras, kurio eilė yra %d, nėra teigiamai apibrėžtas" #, fuzzy #~ msgid "missing 'Matrix' namespace; should never happen" #~ msgstr "trūksta 'Matrix' vardų srities: niekada neturėtų įvykti" #, fuzzy #~ msgid "'Matrix' namespace not determined correctly" #~ msgstr "Matricos vardų sritis nustatyta neteisingai" #~ msgid "Csparse_sort(x): x is not a valid (apart from sorting) CsparseMatrix" #~ msgstr "" #~ "Csparse_sort(x): x nėra galiojantis (išskyrus rūšiavimą) CsparseMatrix" #, c-format #~ msgid "Impossible Rk_x/Rk_y in Csparse_%s(), please report" #~ msgstr "Neįmanoma Rk_x/Rk_y, esanti Csparse_%s(), prašome pranešti" #, c-format #~ msgid "chm_MOD_xtype() was not successful in Csparse_%s(), please report" #~ msgstr "chm_MOD_xtype() nebuvo sėkmingas Csparse_%s(), prašome pranešti" #, c-format #~ msgid "the number of columns differ in R_rbind2_vector: %d != %d" #~ msgstr "stulpelių skaičius skiriasi R_rbind2_vector: %d != %d" #~ msgid "csp_eye argument n must be positive" #~ msgstr "csp_eye argumentas n turi būti teigiamas" #~ msgid "invalid class of 'x' in Matrix_as_cs(a, x)" #~ msgstr "netinkama 'x' klasė, esanti Matrix_as_cs(a, x)" #, c-format #~ msgid "invalid class of object to %s" #~ msgstr "netinkama objekto klasė į %s" #, c-format #~ msgid "cs matrix not compatible with class '%s'" #~ msgstr "cs matrica nesuderinama su klase '%s'" #, c-format #~ msgid "Inappropriate class cl='%s' in Matrix_css_to_SEXP(S, cl, ..)" #~ msgstr "Netinkama klasė cl ='%s', esanti Matrix_css_to_SEXP(S, cl, ..)" #, c-format #~ msgid "Inappropriate class cl='%s' in Matrix_csn_to_SEXP(S, cl, ..)" #~ msgstr "Netinkama klasė cl ='%s', esanti Matrix_csn_to_SEXP(S, cl, ..)" #, c-format #~ msgid "Dimensions of x and y are not compatible for %s" #~ msgstr "X ir y matmenys nesuderinami su %s" #~ msgid "Argument y must be numeric, integer or logical" #~ msgstr "Argumentas y turi būti skaitinis, sveikasis skaičius arba loginis" #~ msgid "Matrices are not conformable for multiplication" #~ msgstr "Matricos nėra tinkamos daugybai" #~ msgid "dtrMatrix must be square" #~ msgstr "dtrMatrix turi būti kvadratinė" #, c-format #~ msgid "Dimensions of a (%d,%d) and b (%d,%d) do not conform" #~ msgstr "Matmenys a (%d,%d) ir b (%d,%d) neatitinka" #~ msgid "right=TRUE is not yet implemented __ FIXME" #~ msgstr "right=TRUE dar neįgyvendinta __ FIXME" #, c-format #~ msgid "cholmod_change_factor failed with status %d" #~ msgstr "cholmod_change_factor nepavyko su būsena %d" #~ msgid "system argument is not valid" #~ msgstr "sistemos argumentas neleistinas" #, c-format #~ msgid "cholmod_updown() returned %d" #~ msgstr "cholmod_updown() grąžintas %d" #~ msgid "cholmod_drop() failed" #~ msgstr "cholmod_drop() nepavyko" #, fuzzy #~ msgid "'off' does not have length 1" #~ msgstr "'%s' lauko ilgis turi būti 1" #, fuzzy #~ msgid "invalid 'code' to 'R_matrix_as_dense()'" #~ msgstr "netinkama klasė '%s' į dup_mMatrix_as_dgeMatrix" #, fuzzy #~ msgid "invalid 'uplo' to 'R_matrix_as_dense()'" #~ msgstr "netinkama klasė '%s' į dup_mMatrix_as_dgeMatrix" #, fuzzy #~ msgid "invalid 'diag' to 'R_matrix_as_dense()'" #~ msgstr "netinkama klasė '%s' į dup_mMatrix_as_dgeMatrix" #, fuzzy #~ msgid "invalid argument 'system'" #~ msgstr "netinkamas argumentas '%s'" #, fuzzy #~ msgid "dimensions of 'qr' and 'y' are inconsistent" #~ msgstr "Sistemos, kurią reikia išspręsti, matmenys yra nenuoseklūs" #, fuzzy #~ msgid "invalid 'op'" #~ msgstr "netinkamas argumentas '%s'" #, fuzzy #~ msgid "'names' must be TRUE or FALSE" #~ msgstr "'uplo' turi būti UPP arba LOW" #~ msgid "Csparse_crossprod(): error return from cholmod_aat()" #~ msgstr "Csparse_crossprod(): klaida grąžinima iš cholmod_aat()" #, fuzzy #~ msgid "invalid 'kind' to 'R_sparse_as_kind()'" #~ msgstr "netinkama 'x' klasė, esanti Csparse_subassign()" #~ msgid "slot p must have length = nrow(.) + 1" #~ msgstr "lauko p ilgis turi būti = nrow(.) + 1" #~ msgid "last element of slot p must match length of slots j and x" #~ msgstr "paskutinis lauko p elementas turi atitikti laukų j ir x ilgį" #~ msgid "all column indices must be between 0 and ncol-1" #~ msgstr "visi stulpelių indeksai turi būti nuo 0 iki ncol-1" #~ msgid "slot j is not *strictly* increasing inside a column" #~ msgstr "laukas j nėra *griežtai* didėjantis stulpelio viduje" #~ msgid "Csparse_to_nz_pattern(x, tri = NA): 'tri' is taken as TRUE" #~ msgstr "Csparse_to_nz_pattern(x, tri = NA): 'tri' laikoma TRUE" #~ msgid "not a 'n.CMatrix'" #~ msgstr "ne 'n.CMatrix'" #, c-format #~ msgid "nz2Csparse(): invalid/non-implemented r_kind = %d" #~ msgstr "nz2Csparse(): netinkamas/neįgyvendintas r_kind = %d" #~ msgid "Nonsymmetric matrix in Csparse_symmetric_to_general" #~ msgstr "Nesimetrinė matrica, esanti Csparse_symmetric_to_general" #~ msgid "Csparse_general_to_symmetric(): matrix is not square!" #~ msgstr "Csparse_general_to_symmetric (): matrica nėra kvadratinė!" #~ msgid "Index i must be NULL or integer" #~ msgstr "Rodyklė i turi būti NULL arba sveikasis skaičius" #~ msgid "Index j must be NULL or integer" #~ msgstr "Rodyklė j turi būti NULL arba sveikasis skaičius" #, c-format #~ msgid "negative vector lengths not allowed: np = %d, nnz = %d" #~ msgstr "neigiami vektoriaus ilgiai neleidžiami: np = %d, nnz = %d" #~ msgid "exactly 1 of 'i', 'j' or 'p' must be NULL" #~ msgstr "tiksliai 1 iš 'i', 'j' arba 'p' turi būti NULL" #, c-format #~ msgid "np = %d, must be zero when p is NULL" #~ msgstr "np = %d, turi būti nulis, kai p yra NULL" #, c-format #~ msgid "p[0] = %d, should be zero" #~ msgstr "p[0] = %d, turėtų būti nulis" #~ msgid "p must be non-decreasing" #~ msgstr "p turi būti nemažėjantis" #, c-format #~ msgid "Inconsistent dimensions: np = 0 and nnz = %d" #~ msgstr "Nenuoseklūs matmenys: np = 0 ir nnz = %d" #, c-format #~ msgid "invalid column index at position %d" #~ msgstr "neleistinas stulpelio indeksas padėtyje %d" #, c-format #~ msgid "strlen of cls argument = %d, should be 8" #~ msgstr "cls argumento strlen = %d, turėtų būti 8" #, c-format #~ msgid "cls = \"%s\" does not end in \"CMatrix\"" #~ msgstr "cls = \"%s\" nesibaigia \"CMatrix\"" #, c-format #~ msgid "cls = \"%s\" must begin with 'd', 'l' or 'n'" #~ msgstr "cls = \"%s\" turi prasidėti 'd', 'l' arba 'n'" #~ msgid "Only 'g'eneral sparse matrix types allowed" #~ msgstr "Leidžiami tik 'g'eneral sparse matricų tipai" #~ msgid "code not yet written for cls = \"lgCMatrix\"" #~ msgstr "kodas dar neparašytas dėl cls = \"lgCMatrix\"" #, c-format #~ msgid "%s must be (traditional R) matrix" #~ msgstr "%s turi būti (tradicinė R) matrica" #, c-format #~ msgid "%s must be character string" #~ msgstr "%s turi būti simbolių eilutė" #, c-format #~ msgid "nrow * ncol = %d * %d must equal length(x) = %ld" #~ msgstr "nrow * ncol = %d * %d turi būti lygus length(x) = %ld" #, c-format #~ msgid "strlen of cls argument = %d, should be 9" #~ msgstr "cls argumento strlen = %d, turėtų būti 9" #, c-format #~ msgid "cls = \"%s\" must begin with 'd', 'l' or 'n' for now" #~ msgstr "cls = \"%s\" turi prasidėti 'd', 'l' arba 'n'" #, c-format #~ msgid "%s must be a logical or double vector" #~ msgstr "%s turi būti loginis arba dvigubas vektorius" #, c-format #~ msgid "argument type[1]='%s' must be one of 'M','1','O','I','F' or 'E'" #~ msgstr "" #~ "argumentas type[1]='%s' turi būti vienas iš 'M','1','O','I','F' arba 'E'" #, c-format #~ msgid "argument type[1]='%s' must be one of '1','O', or 'I'" #~ msgstr "argumentas type[1]='%s' turi būti vienas iš '1','O' arba 'I'" #~ msgid "object must be a named, numeric vector" #~ msgstr "objektas turi būti įvardytas, skaitinis vektorius" #~ msgid "'factors' slot must be a named list" #~ msgstr "'factors' laukas turi būti įvardytas sąrašas" #~ msgid "Matrix object has no 'factors' slot" #~ msgstr "Matricos objektas neturi 'factors' lauko" #~ msgid "'s1' and 's2' must be \"character\" vectors" #~ msgstr "'s1' ir 's2' turi būti \"character\" vektoriai" #~ msgid "length of x slot != prod(Dim)" #~ msgstr "x lauko ilgis != prod(Dim)" #~ msgid "Negative value in Dim" #~ msgid_plural "Negative values in Dim" #~ msgstr[0] "Neigiama dim reikšmė" #~ msgstr[1] "Neigiamos dim reikšmės" #~ msgstr[2] "Neigiamų dim reikšmių" #, c-format #~ msgid "%s is a list, but not of length 2" #~ msgstr "%s yra sąrašas, bet ne ilgio 2" #, c-format #~ msgid "invalid class '%s' to dup_mMatrix_as_geMatrix" #~ msgstr "netinkama klasė '%s' į dup_mMatrix_as_geMatrix" #, c-format #~ msgid "unexpected ctype = %d in dup_mMatrix_as_geMatrix" #~ msgstr "netikėtas ctype = %d, esantis dup_mMatrix_as_geMatrix" #~ msgid "lengths of slots i and j must match" #~ msgstr "laukų i ir j ilgiai turi atitikti" #~ msgid "slot Dim must have length 2" #~ msgstr "laukas Dim turi būti 2 ilgio" #~ msgid "" #~ "all row indices (slot 'i') must be between 0 and nrow-1 in a TsparseMatrix" #~ msgstr "" #~ "visi eilučių indeksai (laukas 'i') turi būti nuo 0 iki nrow-1, esančio " #~ "TsparseMatrix" #~ msgid "" #~ "all column indices (slot 'j') must be between 0 and ncol-1 in a " #~ "TsparseMatrix" #~ msgstr "" #~ "visi stulpelių indeksai (laukas 'j') turi būti nuo 0 iki ncol-1, esančio " #~ "TsparseMatrix" #~ msgid "Supernodal LDL' decomposition not available" #~ msgstr "Supernodal LDL' skilimas negalimas" #~ msgid "Supernodal/simplicial class inconsistent with type flags" #~ msgstr "Supernodal/simplicial klasė nesuderinama su tipo vėliavėlėmis" #~ msgid "Number of supernodes must be positive when is_super is TRUE" #~ msgstr "Super mazgų skaičius turi būti teigiamas, kai is_super yra TRUE" #~ msgid "Lengths of super and pi must be equal" #~ msgstr "Super ir pi ilgiai turi būti lygūs" #~ msgid "Lengths of super and px must be equal" #~ msgstr "Super ir px ilgiai turi būti lygūs" #, c-format #~ msgid "First call to Lapack routine dgels returned error code %d" #~ msgstr "" #~ "Pirmasis iškvietimas į Lapack programą dgels grąžino klaidos kodą %d" #, c-format #~ msgid "Second call to Lapack routine dgels returned error code %d" #~ msgstr "Antrasis skambutis į Lapack programą dgels grąžino klaidos kodą %d" #, c-format #~ msgid "tol, given as %g, must be non-negative" #~ msgstr "tol, kaip %g, turi būti ne neigiamas" #, c-format #~ msgid "Second call to dgeqrf returned error code %d" #~ msgstr "Antrasis iškvietimas į dgeqrf grąžino klaidos kodą %d" #, c-format #~ msgid "" #~ "dense_to_Csparse(): cholmod_l_dense_to_sparse failure status=%d" #~ msgstr "" #~ "dense_to_Csparse(): cholmod_l_dense_to_sparse klaida status=%d" #, c-format #~ msgid "" #~ "Matrix dimension %d x %d (= %g) too large [FIXME calling " #~ "cholmod_l_dense_to_sparse]" #~ msgstr "" #~ "Matricos dimensija %d x %d (= %g) per didelė [FIXME iškvietė " #~ "cholmod_l_dense_to_sparse]" #, c-format #~ msgid "Lower band %d > upper band %d" #~ msgstr "Apatinė juosta %d > viršutinė juosta %d" #~ msgid "ddense_to_symmetric(): matrix is not square!" #~ msgstr "ddense_to_symmetric (): matrica nėra kvadratinė!" #, c-format #~ msgid "matrix is not symmetric [%d,%d]" #~ msgstr "matrica nėra simetrinė [%d,%d]" #~ msgid "matrix is not square! (symmetric part)" #~ msgstr "matrica nėra kvadratinė! (simetrinė dalis)" #~ msgid "matrix is not square! (skew-symmetric part)" #~ msgstr "matrica nėra kvadratinė! (Iškreipta simetriška dalis)" #~ msgid "lengths of slots 'i' and 'x' must match" #~ msgstr "laukų 'i' ir 'x' ilgiai turi atitikti" #~ msgid "lengths of slots 'j' and 'x' must match" #~ msgstr "laukų 'j' ir 'x' ilgiai turi atitikti" #, c-format #~ msgid "invalid class(x) '%s' in compressed_to_TMatrix(x)" #~ msgstr "netinkama class(x) '%s', esanti compressed_to_TMatrix(x)" #, c-format #~ msgid "invalid class(x) '%s' in R_to_CMatrix(x)" #~ msgstr "netinkama class(x) '%s', esanti R_to_CMatrix(x)" #~ msgid "A must have #{rows} >= #{columns}" #~ msgstr "Turi būti #{rows} >= #{columns}" #~ msgid "cs_sqr failed" #~ msgstr "cs_sqr nepavyko" #~ msgid "dgcMatrix_QR(*, keep_dimnames = NA): NA taken as TRUE" #~ msgstr "dgcMatrix_QR(*, keep_dimnames = NA): NA laikoma TRUE" #~ msgid "LU decomposition applies only to square matrices" #~ msgstr "LU dekompozicija taikoma tik kvadratinėms matricoms" #~ msgid "cs_lu(A) failed: near-singular A (or out of memory)" #~ msgstr "cs_lu (A) nepavyko: beveik singuliari A (arba trūksta atminties)" #~ msgid "dgcMatrix_LU(*, keep_dimnames = NA): NA taken as TRUE" #~ msgstr "dgcMatrix_LU(*, keep_dimnames = NA): NA laikoma TRUE" #~ msgid "dgCMatrix_matrix_solve(.., sparse=TRUE) not yet implemented" #~ msgstr "dgCMatrix_matrix_solve(.., sparse=TRUE) dar neįgyvendinta" #~ msgid "lengths of slots i and x must match" #~ msgstr "laukų i ir x ilgiai turi atitikti" #, c-format #~ msgid "too large matrix: %.0f" #~ msgstr "per didelė matrica: %.0f" #, c-format #~ msgid "Cannot coerce to too large *geMatrix with %.0f entries" #~ msgstr "Negalima pakeisti į per didelį *geMatrix su %.0f įrašais" #~ msgid "x slot must be numeric \"double\"" #~ msgstr "x laukas turi būti skaitinis \"double\"" #~ msgid "factors slot must be named list" #~ msgstr "faktorių laukas turi būti įvardytas sąrašas" #~ msgid "rcond requires a square, non-empty matrix" #~ msgstr "rcond reikia kvadratinės, netuščios matricos" #~ msgid "diagonal to be added has wrong length" #~ msgstr "pridedamos įstrižainės ilgis neteisingas" #~ msgid "Cannot factor a matrix with zero extents" #~ msgstr "Negalima faktorizuoti matricos su nuliniais dydžiais" #, c-format #~ msgid "Exact singularity detected during LU decomposition: %s, i=%d." #~ msgstr "Tikslus singuliarumas, aptiktas LU dekomponavimo metu: %s, i=%d." #~ msgid "Solve requires a square matrix" #~ msgstr "Norint išspręsti reikia kvadratinės matricos" #, c-format #~ msgid "error [%d] from Lapack 'dgecon()'" #~ msgstr "klaida [%d] iš Lapack 'dgecon()'" #, c-format #~ msgid "" #~ "Lapack dgecon(): system computationally singular, reciprocal condition " #~ "number = %g" #~ msgstr "" #~ "Lapack dgecon(): singuliariai apskaičiuota sistema, abipusės sąlygos " #~ "skaičius = %g" #~ msgid "Lapack routine dgetri: system is exactly singular" #~ msgstr "Lapack programa dgetri: sistema yra tiksliai singuliari" #~ msgid "dpoMatrix is not positive definite" #~ msgstr "dpoMatrix nėra teigiamai apibrėžta" #~ msgid "Cannot solve() for matrices with zero extents" #~ msgstr "Negalima solve() matricoms su nuliniais dydžiais" #~ msgid "Argument b must be a numeric matrix" #~ msgstr "Argumentas b turi būti skaitinė matrica" #~ msgid "chm_factor_name(): did not get string of length 11" #~ msgstr "chm_factor_name(): negavo 11 ilgio eilutės" #~ msgid "" #~ "Cholesky factorization failed; unusually, please report to Matrix-authors" #~ msgstr "" #~ "Cholesky faktoringas nepavyko; neįprastai, prašome pranešti Matrix " #~ "autoriams" #~ msgid "internal_chm_factor: Cholesky factorization failed" #~ msgstr "internal_chm_factor: Cholesky faktoringas nepavyko" #~ msgid "Non-symmetric matrix passed to dsCMatrix_to_dgTMatrix" #~ msgstr "Ne simetrinė matrica perduota į dsCMatrix_to_dgTMatrix" #~ msgid "Incorrect length of 'x' slot" #~ msgstr "Neteisingas 'x' lauko ilgis" #, c-format #~ msgid "Lapack routine dsytrf returned error code %d" #~ msgstr "Lapack programa dsytrf grąžino klaidos kodą %d" #~ msgid "x must be a \"double\" (numeric) matrix" #~ msgstr "x turi būti \"double\" (skaitinė) matrica" #~ msgid "matrix_trf(x, *): matrix is not square" #~ msgstr "matrix_trf(x, *): matrica nėra kvadratinė" #~ msgid "matrix_trf(*, uplo): uplo must be string" #~ msgstr "matrix_trf(*, uplo): uplo turi būti eilutė" #~ msgid "cannot set diag() as long as 'diag = \"U\"'" #~ msgstr "negali nustatyti diag() tol, kol 'diag = \"U\"'" #~ msgid "cannot add diag() as long as 'diag = \"U\"'" #~ msgstr "negali pridėti diag() tol, kol 'diag = \"U\"'" #~ msgid "x slot is not of correct length" #~ msgstr "x laukas nėra tinkamo ilgio" #~ msgid "A must be a logical matrix" #~ msgstr "A turi būti loginė matrica" #~ msgid "length(p) must match nrow(V)" #~ msgstr "length(p) turi atitikti nrow(V)" #~ msgid "length(beta) must match ncol(V)" #~ msgstr "length(beta) turi atitikti ncol(V)" #~ msgid "length(q) must be zero or ncol(R)" #~ msgstr "length(q) turi būti lygus nuliui arba ncol(R)" #, c-format #~ msgid "sparseQR_Qmult(): nrow(y) = %d != %d = nrow(V)" #~ msgstr "sparseQR_Qmult(): nrow(y) = %d != %d = nrow(V)" #~ msgid "\"dtrMatrix\" objects in '%*%' must have matching (square) dimension" #~ msgstr "" #~ "\"dtrMatrix\" objektai, esantys '%*%', turi turėti sutampantį " #~ "(kvadratinį) matmenį" Matrix/po/R-lt.po0000644000176200001440000011707214521047060013321 0ustar liggesusersmsgid "" msgstr "" "Project-Id-Version: Matrix 1.3-3\n" "POT-Creation-Date: 2023-11-02 21:33\n" "PO-Revision-Date: 2021-03-01 20:55+0200\n" "Last-Translator: Gabrielė Stupurienė \n" "Language-Team: none\n" "Language: lt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 2.4.2\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && (n%100<11 || n%100>19) ? 0 : " "n%10>=2 && n%10<=9 && (n%100<11 || n%100>19) ? 1 : 2);\n" #, fuzzy msgid "invalid mode \"%s\"" msgstr "negaliojantis 'mod': %s" msgid "" "%s(<%s>, <%s>) is not yet implemented; ask maintainer(\"%s\") to implement " "the missing method" msgstr "" #, fuzzy msgid "complex %s not yet implemented" msgstr "Klasės %s dar neįgyvendinta" #, fuzzy msgid "cannot coerce matrix of type \"%s\" to %s" msgstr "negalima paversti 'NA' į \"nsparseMatrix\"" #, fuzzy msgid "non0.i() not yet implemented for class %s" msgstr "dar neįgyvendinta klasei %s" msgid "%s=\"%s\" invalid for %s@uplo=\"%s\"" msgstr "" msgid "'%s' is not \"%1$s\", \"D%1$s\", or \"%1$s.\"" msgstr "" msgid "unexpected %s=\"%s\" in '%s' method" msgstr "" msgid "Not a valid format" msgstr "Neleistinas formatas" msgid "'file' must be a character string or connection" msgstr "'file' turi būti simbolių eilutė ar ryšys" msgid "Invalid storage type: %s" msgstr "Netinkamas saugyklos tipas: %s" msgid "Only numeric sparse matrices allowed" msgstr "Leidžiamos tik skaitinės sparse matricos" msgid "Invalid storage format: %s" msgstr "Neleistinas saugyklos formatas: %s" msgid "Invalid assembled indicator: %s" msgstr "Neleistinas surinktas indikatorius: %s" msgid "file is not a MatrixMarket file" msgstr "failas nėra MatrixMarket failas" msgid "type '%s' not recognized" msgstr "tipas '%s' neatpažįstamas" msgid "representation '%s' not recognized" msgstr "neatpažįstamas atvaizdavimas '%s'" msgid "element type '%s' not recognized" msgstr "elemento tipas '%s' neatpažįstamas" msgid "symmetry form '%s' not recognized" msgstr "simetrinė forma '%s' neatpažįstama" msgid "readMM(): expected %d entries but found only %d" msgstr "" #, fuzzy msgid "readMM(): row indices 'i' are not in 1:nrow[=%d]" msgstr "readMM(): eilučių\t reikšmės 'i' nėra 1:nr" #, fuzzy msgid "readMM(): column indices 'j' are not in 1:ncol[=%d]" msgstr "readMM(): stulpelių reikšmės 'j' nėra 1:nc" msgid "symmetry form 'skew-symmetric' not yet implemented for reading" msgstr "simetriška forma 'skew-symmetric', dar neįgyvendinta skaitymui" msgid "symmetry form 'hermitian' not yet implemented for reading" msgstr "simetrinė forma 'hermitian' dar neįgyvendinta skaitymui" msgid "symmetry form '%s' is not yet implemented" msgstr "simetrinė forma '%s' dar neįgyvendinta" msgid "element type 'complex' not yet implemented" msgstr "elemento tipas 'complex' dar neįgyvendintas" msgid "'%s()' is not yet implemented for element type '%s'" msgstr "'%s()' dar neįgyvendinta elementų tipui '%s'" msgid "'%s()' is not yet implemented for representation '%s'" msgstr "'%s()' dar neįgyvendinta '%s' atvaizdavimui" msgid "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%3$s\", or \"%4$s\"" msgstr "" msgid "" "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%2$s2\", \"%2$s2.\", \"%3$s\", or " "\"%4$s\"" msgstr "" msgid "longer object length is not a multiple of shorter object length" msgstr "ilgesnis objekto ilgis nėra trumpesnio objekto ilgio kartotinis" #, fuzzy msgid "invalid class \"%s\" in '%s' method" msgstr "neleistina 'col.names' eilutė: %s" msgid "invalid type \"%s\" in '%s' method" msgstr "" msgid "non-conformable matrix dimensions in %s" msgstr "neatitinkantys matricos matmenys, esantys %s" msgid "dimnames [%d] mismatch in %s" msgstr "dimnames [%d] neatitikimas %s" msgid "inefficient method used for \"- e1\"" msgstr "neefektyvus metodas, naudojamas \"- e1\"" msgid "dim [product %d] do not match the length of object [%d]" msgstr "dim [product %d] neatitinka objekto ilgio [%d]" msgid "internal bug in \"Compare\" method (Cmp.Mat.atomic); please report" msgstr "vidinė klaida \"Compare\" metode (Cmp.Mat.atomic); prašome pranešti" msgid "Cmp.Mat.atomic() should not be called for diagonalMatrix" msgstr "Cmp.Mat.atomic() negalima būti iškviestas diagonalMatrix" msgid "Matrices must have same number of rows for arithmetic" msgstr "Matricos turi turėti tą patį eilučių skaičių aritmetikai" msgid "number of rows are not compatible for %s" msgstr "eilučių skaičius nesuderinamas su %s" msgid "length of 2nd arg does not match dimension of first" msgstr "2-ojo arg ilgis neatitinka pirmojo dimensijos" msgid "length of 1st arg does not match dimension of 2nd" msgstr "1-mo arg ilgis nesutampa su 2-ojo dimensija" msgid "internal bug in \"Logic\" method (Logic.Mat.atomic); please report" msgstr "vidinė klaida \"Logic\" metode (Logic.Mat.atomic); prašome pranešti" msgid "Logic.Mat.atomic() should not be called for diagonalMatrix" msgstr "Logic.Mat.atomic() neturėtų būti iškviečiamas dėl diagonalMatrix" msgid "vector too long in Matrix - vector operation" msgstr "vektorius, esantis Matrix, per ilgas - vektoriaus operacija" msgid "" "longer object length\n" "\tis not a multiple of shorter object length" msgstr "" "ilgesnis objekto ilgis\n" "\tnėra trumpesnio objekto ilgio kartotinis" msgid "intermediate 'r' is of type %s" msgstr "tarpinis 'r' yra %s tipo" msgid "not yet implemented .. please report" msgstr "dar neįgyvendinta .. prašome pranešti" msgid "'force' must be (coercable to) TRUE or FALSE" msgstr "'force' turi būti (verčiama į) TRUE arba FALSE" msgid "invalid (to - from)/by in seq(.)" msgstr "negaliojantis (iki - nuo)/pagal seq(.)" msgid "wrong sign in 'by' argument" msgstr "neteisingas ženklas 'by' argumente" msgid "'by' argument is much too small" msgstr "'by' argumentas per mažas" msgid "length must be non-negative number" msgstr "ilgis turi būti ne neigiamas skaičius" msgid "too many arguments" msgstr "per daug argumentų" msgid "c(,..) of different kinds, coercing all to 'rleDiff'" msgstr "c(,..) įvairių rūšių, paverčiant visus į 'rleDiff'" msgid "[i] is not yet implemented" msgstr "[i] dar neįgyvendinta" msgid "all() is not yet implemented" msgstr "all() dar neįgyvendinti" msgid "sum() is not yet implemented" msgstr "sum() dar neįgyvendinta" msgid "prod() is not yet implemented" msgstr "prod() dar neįgyvendintas" msgid "not yet implemented" msgstr "dar neįvykdyta" msgid "" "x / 0 for an x with sign-change\n" " no longer representable as 'rleDiff'" msgstr "" "x / 0 dėl x su ženklo pakeitimu\n" " nebeatitinkamas kaip 'rleDiff'" msgid " --> is not yet implemented" msgstr " --> dar neįgyvendinta" msgid " --> is not yet implemented" msgstr " --> dar neįgyvendintas" #, fuzzy msgid "%1$s(%2$s) is undefined: '%2$s' is not positive semidefinite" msgstr "chol() neapibrėžtas įstrižainei matricai su neigiamais įrašais" #, fuzzy msgid "matrix is not square" msgstr "matrica nėra įstrižainė" msgid "" "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%3$s\", \"%3$s.\", \"%3$s1\", \"%3$s1." "\", or \"%4$s\"" msgstr "" #, fuzzy msgid "'%s' does not inherit from virtual class %s" msgstr "'x' turi paveldėti iš \"sparseVector\"" msgid "D[i,i] is NA, i=%d" msgstr "" msgid "D[i,i] is negative, i=%d" msgstr "" msgid "'%1$s' is not formally symmetric; factorizing tcrossprod(%1$s)" msgstr "" #, fuzzy msgid "matrix is not symmetric; consider forceSymmetric(.) or symmpart(.)" msgstr "ne simetriška matrica; apsvarstykite forceSymmetric() arba symmpart()" #, fuzzy msgid "matrix is not triangular; consider triu(.) or tril(.)" msgstr "matrica nėra trikampė" msgid "matrix is not diagonal; consider Diagonal(x=diag(.))" msgstr "" #, fuzzy msgid "invalid type \"%s\" in '%s'" msgstr "neleistinas 'type'" #, fuzzy msgid "invalid %s=\"%s\" to '%s'" msgstr "Netinkamas saugyklos tipas: %s" msgid "dimensions cannot exceed %s" msgstr "" #, fuzzy msgid "invalid class \"%s\" in '%s'" msgstr "neleistina 'col.names' eilutė: %s" msgid "%s length cannot exceed %s" msgstr "" msgid "'A' must be a square matrix" msgstr "'A' turi būti kvadratinė matrica" msgid "must either specify 'A' or the functions 'A.x' and 'At.x'" msgstr "turi nurodyti 'A' arba funkcijas 'A.x' ir 'At.x'" msgid "when 'A' is specified, 'A.x' and 'At.x' are disregarded" msgstr "kai nurodyta 'A', į 'A.x' and 'At.x' neatsižvelgiama" msgid "not converged in %d iterations" msgstr "nekonverguoja %d iteracijose" msgid "hit a cycle (1) -- stop iterations" msgstr "pasiekti ciklą (1) -- sustabdyti iteracijas" msgid "hit a cycle (2) -- stop iterations" msgstr "pasiekti ciklą (2) -- sustabdyti iteracijas" msgid "not enough new vecs -- stop iterations" msgstr "nepakanka naujų vecs -- sustabdyti iteracijas" msgid "invalid 'data'" msgstr "neleistinas 'data'" #, fuzzy msgid "'nrow', 'ncol', 'byrow' disregarded for [mM]atrix 'data'" msgstr "matricos 'data' atveju neatsižvelgiama į 'nrow', 'ncol' ir t. t." msgid "data is too long" msgstr "" #, fuzzy msgid "exactly one of 'i', 'j', and 'p' must be missing from call" msgstr "iškvietimo metu turi trūkti tiksliai vieno iš 'i', 'j' arba 'p'" msgid "" "use Diagonal() to construct diagonal (symmetric && triangular) sparse " "matrices" msgstr "" #, fuzzy msgid "'giveCsparse' is deprecated; using 'repr' instead" msgstr "'giveCsparse' nebenaudojamas; vietoj to naudos 'repr'" #, fuzzy msgid "'giveCsparse' is deprecated; setting repr=\"T\" for you" msgstr "'giveCsparse' nebenaudojamas; nustatymas 'repr = \"T\"' jums" #, fuzzy msgid "'p' must be a nondecreasing vector c(0, ...)" msgstr "'p' turi būti nemažėjantis vektorius (0, ...)" msgid "dimensions cannot exceed 2^31-1" msgstr "" msgid "'i' and 'j' must not contain NA" msgstr "" msgid "'i' and 'j' must be" msgstr "" msgid "positive" msgstr "" msgid "non-negative" msgstr "" #, fuzzy msgid "invalid 'dims'" msgstr "neleistinas 'data'" msgid "'dims' must contain all (i,j) pairs" msgstr "" msgid "symmetric matrix must be square" msgstr "simetrinė matrica turi būti kvadratinė" msgid "triangular matrix must be square" msgstr "trikampė matrica turi būti kvadratinė" msgid "p[length(p)]" msgstr "" msgid "length(i)" msgstr "" #, fuzzy msgid "is not an integer multiple of length(x)" msgstr "length(i) nėra length(x) kartotinis" msgid "length(x) must not exceed" msgstr "" #, fuzzy msgid "invalid 'repr'; must be \"C\", \"R\", or \"T\"" msgstr "negaliojantis 'repr'; turi būti \"C\", \"T\" arba \"R\"" #, fuzzy msgid "'n' must be a non-negative integer" msgstr "ilgis turi būti ne neigiamas skaičius" msgid "'x' has unsupported class \"%s\"" msgstr "" msgid "'x' has unsupported type \"%s\"" msgstr "" msgid "attempt to recycle 'x' of length 0 to length 'n' (n > 0)" msgstr "" msgid "'shape' must be one of \"g\", \"t\", \"s\"" msgstr "" #, fuzzy msgid "'kind' must be one of \"d\", \"l\", \"n\"" msgstr "negaliojantis 'repr'; turi būti \"C\", \"T\" arba \"R\"" msgid "mismatch between typeof(x)=\"%s\" and kind=\"%s\"; using kind=\"%s\"" msgstr "" #, fuzzy msgid "'cols' must be numeric" msgstr "'ncol' turi būti >= 0" msgid "'cols' has elements not in seq(0, length.out = n)" msgstr "" #, fuzzy msgid "'uplo' must be \"U\" or \"L\"" msgstr "negaliojantis 'repr'; turi būti \"C\", \"T\" arba \"R\"" #, fuzzy msgid "'lst' must be a list" msgstr "'ncol' turi būti >= 0" msgid "'giveCsparse' has been deprecated; setting 'repr = \"T\"' for you" msgstr "'giveCsparse' nebenaudojamas; nustatymas 'repr = \"T\"' jums" msgid "'giveCsparse' has been deprecated; will use 'repr' instead" msgstr "'giveCsparse' nebenaudojamas; vietoj to naudos 'repr'" msgid "'diagonals' matrix must have %d columns (= length(k) )" msgstr "'diagonals' matricoje turi būti %d stulpeliai (= length(k) )" msgid "'diagonals' must have the same length (%d) as 'k'" msgstr "'diagonals' turi būti tokio pat ilgio (%d) kaip ir 'k'" msgid "matrix can only be symmetric if square, but n != m" msgstr "matrica gali būti simetriška tik kvadratinė, bet n != m" msgid "" "for symmetric band matrix, only specify upper or lower triangle\n" " hence, all k must have the same sign" msgstr "" "simetrinės juostos matricai nurodykite tik viršutinį arba apatinį trikampį\n" " taigi, visi k turi turėti tą patį ženklą" msgid "the %d-th (sub)-diagonal (k = %d) is too short; filling with NA's" msgstr "%d įstrižainė (k = %d) yra per trumpa; užpildymas su NA" msgid "invalid 'repr'; must be \"C\", \"T\", or \"R\"" msgstr "negaliojantis 'repr'; turi būti \"C\", \"T\" arba \"R\"" msgid "'x' must inherit from \"sparseVector\"" msgstr "'x' turi paveldėti iš \"sparseVector\"" msgid "'ncol' must be >= 0" msgstr "'ncol' turi būti >= 0" msgid "'nrow' must be >= 0" msgstr "'nrow' turi būti >= 0" msgid "Must specify 'nrow' when 'symmetric' is true" msgstr "Turi nurodyti 'nrow', kai 'symmetric' yra teisinga" msgid "'nrow' and 'ncol' must be the same when 'symmetric' is true" msgstr "'nrow' ir 'ncol' turi būti vienodi, kai 'symmetric' yra teisinga" msgid "'x' must have length nrow^2 when 'symmetric' is true" msgstr "'x' turi būti ilgio nrow^2, kai 'symmetric' yra teisingas" msgid "'ncol' is not a factor of length(x)" msgstr "'ncol' nėra length(x) faktorius" msgid "'nrow' is not a factor of length(x)" msgstr "\"nrow\" nėra length(x) faktorius" msgid "Class %s is not yet implemented" msgstr "Klasės %s dar neįgyvendinta" #, fuzzy msgid "'%s' and '%s' must be positive integers" msgstr "ilgis turi būti ne neigiamas skaičius" #, fuzzy msgid "matrix is not symmetric or triangular" msgstr "'x' nėra nei simetriškas, nei trikampis" #, fuzzy msgid "matrix is not symmetric" msgstr "matrica nėra trikampė" #, fuzzy msgid "matrix is not triangular" msgstr "'x' nėra nei simetriškas, nei trikampis" msgid "" "the default value of argument '%s' of method '%s(<%s>, <%s>)' may change " "from %s to %s as soon as the next release of Matrix; set '%s' when " "programming" msgstr "" msgid "determinant of non-square matrix is undefined" msgstr "" msgid "replacement diagonal has wrong length" msgstr "" msgid "replacement diagonal has incompatible type \"%s\"" msgstr "" msgid "assigned dimensions are not of type \"%s\" or \"%s\"" msgstr "" msgid "assigned dimensions do not have length %d" msgstr "" msgid "assigned dimensions are NA" msgstr "" msgid "assigned dimensions are negative" msgstr "" msgid "assigned dimensions exceed %s" msgstr "" #, fuzzy msgid "assigned dimensions [product %.0f] do not match object length [%.0f]" msgstr "dim [product %d] neatitinka objekto ilgio [%d]" msgid "'%s' has non-finite values" msgstr "" msgid "'%1$s' is not \"%2$s\", \"%3$s\", or \"%2$s.\"" msgstr "" #, fuzzy msgid "only square matrices can be used as graph incidence matrices" msgstr "" "tik kvadratinės matricos gali būti naudojamos kaip paplitimo matricos " "grafikams" msgid "'lwd' must be NULL or non-negative numeric" msgstr "'lwd' turi būti NULL arba ne neigiamas skaitinis" #, fuzzy msgid "%s(<%s>) is not yet implemented" msgstr "Klasės %s dar neįgyvendinta" msgid "'%s' is not of type \"%s\" or \"%s\"" msgstr "" msgid "'%s' contains NA" msgstr "" msgid "'%s' has elements less than %d" msgstr "" #, fuzzy msgid "'%s' is not a non-negative number" msgstr "ilgis turi būti ne neigiamas skaičius" msgid "'%s' has elements exceeding '%s'" msgstr "" msgid "'%s' is not %d or %d" msgstr "" #, fuzzy msgid "'%s' is not a permutation of seq_len(%s)" msgstr "'ncol' nėra length(x) faktorius" #, fuzzy msgid "matrix must have exactly one entry in each row or column" msgstr "eilutėje turi būti lygiai vienas ne nulinis įrašas" #, fuzzy msgid "attempt to coerce non-square matrix to %s" msgstr "negalima paversti nesimetrinio \"dgTMatrix\" į \"dsCMatrix\" klasę" #, fuzzy msgid "matrix must have exactly one entry in each row and column" msgstr "eilutėje turi būti lygiai vienas ne nulinis įrašas" #, fuzzy msgid "'%s' via sparse -> dense coercion" msgstr "rcond(.) per sparse -> dense pavertimą" #, fuzzy msgid "invalid %s=\"%s\"" msgstr "neleistini nargs()= %d" msgid "norm" msgstr "" #, fuzzy msgid "'%s' method must use default %s=\"%s\"" msgstr "kronecker metodas turi naudoti numatytąjį 'FUN'" #, fuzzy msgid "number of nonzero entries cannot exceed %s" msgstr "eilučių skaičius nesuderinamas su %s" msgid "Matrix seems negative semi-definite" msgstr "Matrica atrodo pusiau neigiamai apibrėžta" msgid "'nearPD()' did not converge in %d iterations" msgstr "'nearPD()' nekonvergavo %d iteracijose" #, fuzzy msgid "'cl' is not a character string" msgstr "'V' nėra *kvadratinė* matrica" msgid "" "not a positive definite matrix (and positive semidefiniteness is not checked)" msgstr "" #, fuzzy msgid "'%s' is not a square numeric matrix" msgstr "'V' nėra *kvadratinė* matrica" #, fuzzy msgid "" "diag(%s) has non-positive or non-finite entries; finite result is doubtful" msgstr "diag(.) turėjo 0 arba NA įrašus; abejotinas ne baigtinis rezultatas" msgid "non-conformable arguments" msgstr "neatitinkantys argumentai" msgid "" "matrix is structurally rank deficient; using augmented matrix with " "additional %d row(s) of zeros" msgstr "" msgid "" "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%2$s2\", \"%2$s2.\", \"%3$s\", " "\"%3$s1\", \"%4$s\", or \"%4$s1\"" msgstr "" #, fuzzy msgid "'%s' has the wrong length" msgstr "RHS 'b' ilgis neteisingas" #, fuzzy msgid "invalid '%s': not in %d:%d" msgstr "neleistina 'col.names' eilutė: %s" msgid "need greater '%s' as pivoting occurred" msgstr "" msgid "qr2rankMatrix(.): QR with only %d out of %d finite diag(R) entries" msgstr "qr2rankMatrix(.): QR tik su %d iš %d baigtinių diag(R) įrašų" msgid "" "rankMatrix(, method = '%s') coerces to dense matrix.\n" " Probably should rather use method = 'qr' !?" msgstr "" "rankMatrix(, method = '%s') paverčiamas į tankio " "matricą.\n" " Tikriausiai reikėtų naudoti metodą = 'qr' !?" msgid "rankMatrix(x, method='qr'): computing t(x) as nrow(x) < ncol(x)" msgstr "rankMatrix(x, method='qr'): skaičiavimas t(x) kaip nrow(x) < ncol(x)" #, fuzzy msgid "[[ suppressing %d column name%s %s ... ]]" msgstr "[[ nerodyti %d stulpelių pavadinimų %s ... ]]" msgid "invalid 'col.names' string: %s" msgstr "neleistina 'col.names' eilutė: %s" msgid "uniDiag=TRUE, but not all diagonal entries are 1" msgstr "uniDiag=TRUE, bet ne visi įstrižainės įrašai yra 1" msgid "uniDiag=TRUE, not all entries in diagonal coded as 1" msgstr "uniDiag=TRUE, ne visi įstrižainės įrašai, koduoti kaip 1" #, fuzzy msgid "in show(); maybe adjust options(max.print=, width=)" msgstr "show(); galbūt pritaikyti 'options(max.print= *, width = *)'" msgid "suppressing %d columns and %d rows" msgstr "nerodyti %d stulpelių ir %d eilučių" msgid "suppressing %d rows" msgstr "nerodyti %d eilučių" msgid "suppressing %d columns" msgstr "nerodyti %d stulpelių" msgid "logic programming error in printSpMatrix2(), please report" msgstr "loginio programavimo klaida printSpMatrix2(), prašome pranešti" #, fuzzy msgid "'%s' is not square" msgstr "'V' nėra kvadratinė matrica" msgid "dimensions of '%s' and '%s' are inconsistent" msgstr "" msgid "'%1$s' is computationally singular, rcond(%1$s)=%2$g" msgstr "" msgid "'%s' is computationally singular, min(d)/max(d)=%g, d=abs(diag(U))" msgstr "" msgid "matrix is exactly singular, D[i,i]=0, i=%d" msgstr "" msgid "matrix is exactly singular, J[,j]=0, j=%d" msgstr "" msgid "matrix exactly singular, J[i,]=0, i=%d" msgstr "" msgid "cannot coerce from %s to %s" msgstr "" #, fuzzy msgid "model frame and formula mismatch in sparse.model.matrix()" msgstr "modelio sistemos ir formulės neatitikimas model.matrix()" #, fuzzy msgid "non-list contrasts argument ignored" msgstr "neleistinas argumentas 'contrasts.arg'" #, fuzzy msgid "'contrasts.arg' argument must be named" msgstr "neleistinas argumentas 'contrasts.arg'" msgid "variable '%s' is absent, its contrast will be ignored" msgstr "kintamojo '%s' nėra, jo kontrastas bus ignoruojamas" msgid "a sparseMatrix should rarely be centered: will not be sparse anymore" msgstr "sparseMatrix retai turėtų būti centre: daugiau nebus sparse" msgid "length of 'center' must equal the number of columns of 'x'" msgstr "'center' ilgis turi būti lygus stulpelių skaičiui 'x'" msgid "length of 'scale' must equal the number of columns of 'x'" msgstr "'scale' ilgis turi būti lygus stulpelių skaičiui 'x'" msgid "trimmed means are not defined for complex data" msgstr "" msgid "first element used of '%s' argument" msgstr "" #, fuzzy msgid "invalid '%s' argument" msgstr "neleistinas 'data'" msgid "should never happen ..." msgstr "" #, fuzzy msgid "'%s' is deprecated; using '%s' instead" msgstr "'giveCsparse' nebenaudojamas; vietoj to naudos 'repr'" #, fuzzy msgid "'%s' is deprecated; setting %s=\"%s\"" msgstr "'giveCsparse' nebenaudojamas; nustatymas 'repr = \"T\"' jums" msgid "" ".M.repl.i.2col(): 'i' has no integer column number;\n" " should never happen; please report" msgstr "" ".M.repl.i.2col(): 'i' neturi sveiko skaičiaus stulpelio numerio;\n" " niekada neturėtų įvykti; prašome pranešti" msgid "such indexing must be by logical or 2-column numeric matrix" msgstr "toks indeksavimas turi būti loginis arba 2 stulpelių skaitinė matrica" msgid ".M.repl.i.2col(): drop 'matrix' case ..." msgstr ".M.repl.i.2col(): išmetė 'matrix' atveją ..." msgid "negative values are not allowed in a matrix subscript" msgstr "matricos apatiniame indekse neigiamos reikšmės neleidžiamos" msgid "NAs are not allowed in subscripted assignments" msgstr "NA neleidžiamos apatinio indekso priskyrimuose" msgid "number of items to replace is not a multiple of replacement length" msgstr "keičiamų elementų skaičius nėra keičiamo ilgio kartotinis" msgid "m[ ] <- v: inefficiently treating single elements" msgstr "m[ ] <- v: neefektyviai apdorojant pavienius elementus" msgid "nargs() = %d. Extraneous illegal arguments inside '[ .. ]' ?" msgstr "nargs() = %d. Pašaliniai neteisėti argumentai viduje '[ .. ]' ?" msgid "RHS 'value' (class %s) matches 'ANY', but must match matrix class %s" msgstr "" "RHS 'value' (%s klasė) atitinka 'ANY', tačiau turi atitikti matricos klasę %s" msgid "not-yet-implemented 'Matrix[<-' method" msgstr "dar neįgyvendintas 'Matrix[<-' method" msgid "invalid nargs()= %d" msgstr "neleistini nargs()= %d" msgid "nothing to replace with" msgstr "nėra nieko pakeisti su" msgid "too many replacement values" msgstr "per daug pakeitimo reikšmių" msgid "i1[1] == 0 ==> C-level verbosity will not happen!" msgstr "i1[1] == 0 ==> C lygio daugiakalbiškumas neįvyks!" msgid "using\t \"old code\" part in Csparse subassignment" msgstr "naudojant\t \"senojo kodo\" dalį Csparse antriniame priskyrime" msgid "" "using\"old code\" part in Csparse subassignment\n" " >>> please report to Matrix-authors@r-project.org" msgstr "" "naudojant \"senojo kodo\" dalį Csparse antriniame priskyrime\n" " >>> prašome pranešti Matrix-authors@r-project.org" msgid "you cannot mix negative and positive indices" msgstr "negalite maišyti neigiamų ir teigiamų indeksų" msgid "index larger than maximal %d" msgstr "indeksas didesnis nei maksimalus %d" msgid "'NA' indices are not (yet?) supported for sparse Matrices" msgstr "'NA' indeksai nėra (dar?) remiami sparse Matrices" msgid "logical subscript too long (%d, should be %d)" msgstr "loginis apatinis indeksas per ilgas (%d, turėtų būti %d)" msgid "no 'dimnames[[.]]': cannot use character indexing" msgstr "nėra 'dimnames[[.]]': negalima naudoti simbolių indeksavimo" msgid "invalid character indexing" msgstr "neleistinas simbolių indeksavimas" msgid "internal bug: missing 'i' in replTmat(): please report" msgstr "vidinė klaida: trūksta 'i' replTmat(): prašome pranešti" msgid "[ ] indexing not allowed: forgot a \",\" ?" msgstr "[ ] indeksavimas neleidžiamas: pamiršote \",\" ?" msgid "internal bug: matrix 'i' in replTmat(): please report" msgstr "vidinė klaida: matrica 'i', esanti replTmat(): prašome pranešti" msgid "" "x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced; NA |--> TRUE." msgstr "" "x[.] <- val: x yra %s, val, kurio nėra {TRUE, FALSE} yra paverčiamas; NA |--" "> TRUE." msgid "x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced." msgstr "x[.] <- val: x yra %s, val, kurio nėra {TRUE, FALSE} yra paverčiamas." msgid "" "x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced NA |--> TRUE." msgstr "" "x[...] <- val: x yra %s, val, kurio nėra {TRUE, FALSE} yra paverčiamas NA |--" "> TRUE." msgid "x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced." msgstr "" "x[.,.] <- val: x yra %s, val, kurio nėra {TRUE, FALSE} yra paverčiamas." msgid "x[.,.] <- val : x being coerced from Tsparse* to CsparseMatrix" msgstr "x[.,.] <- val: x yra paverčiamas iš Tsparse* į CsparseMatrix" msgid "nargs() = %d should never happen; please report." msgstr "nargs() = %d niekada neturėtų įvykti; prašome pranešti." msgid "row indices must be <= nrow(.) which is %d" msgstr "eilučių indeksai turi būti < = nrow(.), kuris yra %d" msgid "column indices must be <= ncol(.) which is %d" msgstr "stulpelių indeksai turi būti <= ncol(.), kuris yra %d" msgid "Internal bug: nargs()=%d; please report" msgstr "Vidinė klaida: nargs()=%d; prašome pranešti" msgid "" "index must be numeric, logical or sparseVector for indexing sparseVectors" msgstr "" "indeksas turi būti skaitinis, loginis arba sparseVector, sparseVectors " "indeksavimui" #, fuzzy msgid "invalid subscript class \"%s\"" msgstr "netinkama klasė: %s" #, fuzzy msgid "invalid subscript type \"%s\"" msgstr "Netinkamas saugyklos tipas: %s" msgid "recycled %s would have maximal index exceeding %s" msgstr "" msgid "subscripts exceeding %s replaced with NA" msgstr "" msgid "subscript out of bounds" msgstr "" #, fuzzy msgid "logical subscript too long" msgstr "loginis apatinis indeksas per ilgas (%d, turėtų būti %d)" #, fuzzy msgid "incorrect number of dimensions" msgstr "nesuderinamos matricos dimensijos" msgid "only zeros may be mixed with negative subscripts" msgstr "" msgid "'%s' has length 0 but '%s' does not" msgstr "" #, fuzzy msgid "attempt to coerce matrix with NA to %s" msgstr "negalima paversti nesimetrinio \"dgTMatrix\" į \"dsCMatrix\" klasę" #, fuzzy msgid "invalid 'Class2'" msgstr "neleistinas 'data'" #~ msgid "qr2rankMatrix(.): QR has negative diag(R) entries" #~ msgstr "qr2rankMatrix(.): QR turi neigiamų diag(R) įrašų" #, fuzzy #~ msgid "invalid 'each' argument" #~ msgstr "neteisingas ženklas 'by' argumente" #, fuzzy #~ msgid "invalid 'times' argument" #~ msgstr "neleistinas 'data'" #~ msgid "" #~ "not-yet-implemented method for %s(<%s>).\n" #~ " ->> Ask the package authors to implement the missing feature." #~ msgstr "" #~ "dar neįgyvendintas metodas dėl %s (<%s>).\n" #~ " ->> Paprašykite paketo autorių įgyvendinti trūkstamą funkciją." #~ msgid "" #~ "not-yet-implemented method for %s(<%s>, <%s>).\n" #~ " ->> Ask the package authors to implement the missing feature." #~ msgstr "" #~ "dar neįgyvendintas metodas dėl %s (<%s>, <%s>).\n" #~ " ->> Paprašykite paketo autorių įgyvendinti trūkstamą funkciją." #, fuzzy #~ msgid "complex \"diagonalMatrix\" not yet implemented" #~ msgstr "bendroji Matrix klasė dar neįgyvendinta %s" #, fuzzy #~ msgid "not yet implemented for class \"%s\"" #~ msgstr "dar neįgyvendinta klasei %s" #, fuzzy #~ msgid "invalid 'uplo'" #~ msgstr "neleistinas 'type'" #~ msgid "'lag' and 'differences' must be integers >= 1" #~ msgstr "'lag' ir 'differences' turi būti sveikieji skaičiai >= 1" #~ msgid "" #~ "programming error: min() should have dispatched w/ 1st arg much earlier" #~ msgstr "programavimo klaida: min() turėjo išsiųsti w/ 1st arg daug anksčiau" #~ msgid "in Summary(, .): %s(<%s>, <%s>,...)" #~ msgstr "esantis Summary(, .): %s(<%s>, <%s>,...)" #~ msgid "in Summary(, .): %s(<%s>, <%s>)" #~ msgstr "esantis Summary(, .): %s(<%s>, <%s>)" #, fuzzy #~ msgid "number of rows of matrices must match" #~ msgstr "eilučių skaičius nesuderinamas su %s" #, fuzzy #~ msgid "number of columns of matrices must match" #~ msgstr "eilučių skaičius nesuderinamas su %s" #~ msgid "resulting x-slot has different type than x's or y's" #~ msgstr "gautas x-slot turi skirtingą tipą nei x arba y" #, fuzzy #~ msgid "dimensions must be numeric of length 2" #~ msgstr "dim(.) reikšmė turi būti skaitinio ilgio 2" #, fuzzy #~ msgid "'perm' must be numeric" #~ msgstr "'A' turi būti kvadratinė matrica" #, fuzzy #~ msgid "'margin' must be 1 or 2" #~ msgstr "'ncol' turi būti >= 0" #~ msgid "not-yet-implemented method for <%s> %%*%% <%s>" #~ msgstr "dar neįgyvendintas metodas <%s> %%*%% <%s>" #~ msgid "'boolArith = %d' not yet implemented" #~ msgstr "'boolArith = %d' dar neįgyvendintas" #, fuzzy #~ msgid "'rcond' via sparse -> dense coercion" #~ msgstr "rcond(.) per sparse -> dense pavertimą" #, fuzzy #~ msgid "invalid 'norm'" #~ msgstr "neleistinas 'data'" #, fuzzy #~ msgid "cannot coerce zsparseVector to dgCMatrix" #~ msgstr "negalima paversti NA reikšmes į modelį \"ngCMatrix\"" #, fuzzy #~ msgid "cannot coerce zsparseVector to dgeMatrix" #~ msgstr "negalima paversti 'NA' į \"nsparseVector\"" #~ msgid "" #~ "number of non zeros is smaller than 'nnz' because of duplicated (i,j)s" #~ msgstr "ne nulių skaičius yra mažesnis už 'nnz' dėl dubliuotų (i,j)s" #~ msgid "'times >= 0' is required" #~ msgstr "'times >= 0' yra būtinas" #~ msgid "'giveCsparse' has been deprecated; setting 'repr = \"%s\"' for you" #~ msgstr "'giveCsparse' nebenaudojamas; nustatymas 'repr = \"%s\"' jums" #~ msgid "Matrices must have same number of rows in %s" #~ msgstr "Matricos turi turėti tą patį eilučių skaičių %s" #~ msgid "Matrices must have same number of columns in %s" #~ msgstr "Matricos turi turėti tą patį stulpelių skaičių %s" #, fuzzy #~ msgid "only 2-dimensional tables can be coerced to sparseMatrix" #~ msgstr "" #~ "tik 2 matmenų lentelės gali būti tiesiogiai paverstos į sparse matricas" #, fuzzy #~ msgid "matrix is not symmetric or" #~ msgstr "'x' nėra nei simetriškas, nei trikampis" #, fuzzy #~ msgid "triangular" #~ msgstr "ne trikampė matrica" #, fuzzy #~ msgid "matrix is not" #~ msgstr "matrica nėra įstrižainė" #~ msgid "'x' is not positive definite -- chol() undefined." #~ msgstr "'x' nėra teigiamai apibrėžtas -- chol() neapibrėžtas." #~ msgid "Matrices must have same dimensions in %s" #~ msgstr "Matricos turi turėti tuos pačius matmenis %s" #~ msgid "names(dimnames()) must be NULL or of length two" #~ msgstr "names(dimnames()) turi būti NULL arba dviejų ilgių" #~ msgid "[[ suppressing %d column names %s ]]" #~ msgstr "[[ nerodyti %d stulpelių pavadinimų %s ]]" #~ msgid "'x' must be \"sparseMatrix\"" #~ msgstr "'x' turi būti \"sparseMatrix\"" #~ msgid "not yet implemented for matrix with typeof %s" #~ msgstr "dar neįgyvendinta matricai su typeof %s" #~ msgid "not yet implemented for %s" #~ msgstr "dar neįgyvendinta %s" #~ msgid "" #~ "Quadratic matrix '%s' (=: A) is not formally\n" #~ "\tsymmetric. Will be treated as\tA A'" #~ msgstr "" #~ "Kvadratinė matrica '%s' (=: A) formaliai nėra\n" #~ "\tsimetrinis. Bus traktuojama kaip as\tA A'" #~ msgid "" #~ "'update' must be logical or '+' or '-'; 'C' a matrix, and 'L' a " #~ "\"CHMfactor\"" #~ msgstr "" #~ "'update' turi būti loginis arba '+' arba '-'; 'C' matrica, o 'L' – " #~ "\"CHMfactor\"" #~ msgid "update must be TRUE/FALSE or '+' or '-'" #~ msgstr "atnaujinimas turi būti TRUE/FALSE arba '+' arba '-'" #~ msgid "Matrix-internal error in [i,,d]; please report" #~ msgstr "Matricos vidinė klaida, esanti [i,,d]; prašome pranešti" #~ msgid "" #~ "Cholesky() -> *symbolic* factorization -- not yet implemented" #~ msgstr "" #~ "Cholesky() -> *symbolic* faktoringas -- dar neįgyvendintas" #~ msgid "" #~ "as.matrix() is deprecated (to become a no-op in the future).\n" #~ "Use as(x, \"matrix\") or .asmatrix(x) instead." #~ msgstr "" #~ "as.matrix() yra nebenaudojamas (ateityje taps no-op).\n" #~ "Vietoj to naudokite as(x, \"matrix\") arba .asmatrix(x)." #~ msgid "" #~ "as.array() is deprecated. Use as(x, \"matrix\") or .asmatrix(x) " #~ "instead." #~ msgstr "" #~ "as.array() nebenaudojamas. Vietoj to naudokite as(x, \"matrix\") " #~ "arba .asmatrix(x)." #~ msgid "trimmed mean of 'sparseVector' -- suboptimally using as.numeric(.)" #~ msgstr "" #~ "apdorotas 'sparseVector' vidurkis -- suboptimally naudojant as.numeric(.)" #~ msgid "invalid dimnames given for %s object" #~ msgstr "neleistinas dimnames %s objektui" #~ msgid "" #~ "dimnames(.) <- NULL: translated to \n" #~ "dimnames(.) <- list(NULL,NULL) <==> unname(.)" #~ msgstr "" #~ "dimnames(.) <- NULL: išverstas į \n" #~ "dimnames(.) <- list(NULL,NULL) <==> unname(.)" #~ msgid "" #~ "'nrow', 'ncol', etc, are disregarded when 'data' is \"Matrix\" already" #~ msgstr "" #~ "Į 'nrow', 'ncol' ir t. t. neatsižvelgiama, kai 'data' jau yra \"Matrix\"" #~ msgid "complex matrices not yet implemented in Matrix package" #~ msgstr "kompleksinės matricos dar neįgyvendintos Matrix pakete" #~ msgid "using slow kronecker() method" #~ msgstr "naudojant lėtą kronecker() metodą" #~ msgid "" #~ "Cholesky(A) called for 'A' of class \"%s\";\n" #~ "\t it is currently defined for sparseMatrix only; consider using chol() " #~ "instead" #~ msgstr "" #~ "Cholesky(A) iškvietė dėl 'A' klasės \"%s\";\n" #~ "\t šiuo metu jis nustatytas tik rsparseMatrix; apsvarstyti galimybę " #~ "vietoj to naudoti chol ()" #~ msgid "invalid or not-yet-implemented 'Matrix' subsetting" #~ msgstr "neleistinas arba dar neįgyvendintas 'Matrix' pogrupis" #~ msgid "[ ] : .M.sub.i.logical() maybe inefficient" #~ msgstr "[ ] : . M.sub.i.logical() gal neefektyvus" #~ msgid "" #~ "nargs() = %d. Extraneous illegal arguments inside '[ .. ]' (i.logical)?" #~ msgstr "" #~ "nargs() = %d. Pašaliniai neteisėti argumentai viduje '[ .. ]' (i." #~ "logical)?" #~ msgid "" #~ "m[]: inefficiently indexing single elements - should not " #~ "happen, please report!" #~ msgstr "" #~ "m[]: neefektyviai indeksuojant pavienius elementus - neturėtų " #~ "įvykti, prašome pranešti!" #~ msgid "" #~ "nargs() = %d. Extraneous illegal arguments inside '[ .. ]' (i.2col)?" #~ msgstr "" #~ "nargs() = %d. Pašaliniai neteisėti argumentai viduje '[ .. ]' (i.2col)?" #~ msgid "" #~ ".M.sub.i.2col(): 'i' has no integer column number;\n" #~ " should never happen; please report" #~ msgstr "" #~ ".M.sub.i.2col(): 'i' neturi sveiko skaičiaus stulpelio numerio;\n" #~ " niekada neturėtų įvykti; prašome pranešti" #~ msgid "not-yet-implemented coercion to \"TsparseMatrix\"" #~ msgstr "dar neįgyvendinta paverstas į \"TsparseMatrix\"" #~ msgid "Matrix-internal error in [i,,d]; please report" #~ msgstr "Matricos vidinė klaida, esanti [i,,d]; prašome pranešti" #~ msgid "FIXME: NOT YET FINISHED IMPLEMENTATION" #~ msgstr "FIXME: DAR NEBAIGTAS ĮGYVENDINIMAS" #~ msgid "diagonalMatrix in .dense2C() -- should never happen, please report!" #~ msgstr "" #~ "diagonalMatrix, esanti .dense2C() -- niekada neturėtų atsitikti, prašome " #~ "pranešti!" #~ msgid "undefined method for class %s" #~ msgstr "neapibrėžtas metodas klasei %s" #~ msgid "dimensions don't match the number of cells" #~ msgstr "matmenys neatitinka langelių skaičiaus" #~ msgid "" #~ "LU computationally singular: ratio of extreme entries in |diag(U)| = %9.4g" #~ msgstr "" #~ "LU skaičiavimo singuliarumas: ekstremalių įrašų santykis |diag(U)| = %9.4g" #~ msgid "RHS 'b' has wrong number of rows:" #~ msgstr "RHS 'b' turi neteisingą eilučių skaičių:" #~ msgid "'x' has invalid data type" #~ msgstr "'x' turi neleistiną duomenų tipą" #~ msgid "length(x) must be either 1 or #{cols}" #~ msgstr "length(x) turi būti 1 arba #{cols}" #~ msgid "some arguments are not matrices" #~ msgstr "kai kurie argumentai nėra matricos" #~ msgid "%s kind not yet implemented" #~ msgstr "%s rūšis dar neįgyvendinta" #~ msgid "non-square matrix" #~ msgstr "nekvadratinė matrica" #~ msgid "" #~ "matrix with non-zero off-diagonals cannot be coerced to \"diagonalMatrix\"" #~ msgstr "" #~ "matricos su ne nulinėmis įstrižainėmis negalima paversti į " #~ "\"diagonalMatrix\"" #~ msgid "non-matching dimensions" #~ msgstr "nesutampančios dimensijos" #~ msgid "not a positive definite matrix" #~ msgstr "ne teigiamai abiprėžta matrica" #~ msgid "" #~ "as(.,\"dsCMatrix\") is deprecated (since 2008); do use as(., " #~ "\"symmetricMatrix\")" #~ msgstr "" #~ "as(.,\"dsCMatrix\") nebenaudojamas (nuo 2008 m.); naudoti as(., " #~ "\"symmetricMatrix\")" #~ msgid "inefficient coercion (lost triangularity); please report" #~ msgstr "neefektyvi pavertimas (prarastas trianguliarumas); prašome pranešti" #~ msgid "coercion to \"indMatrix\" only works from integer numeric" #~ msgstr "pavertimas į \"indMatrix\" veikia tik iš sveikųjų skaitinių" #~ msgid "" #~ "coercion from list(i1,...,ik, d) to \"indMatrix\" failed.\n" #~ " All entries must be integer valued and the number of columns, d, not " #~ "smaller\n" #~ " than the maximal index i*." #~ msgstr "" #~ "pavertimas iš list(i1,...,ik, d) į \"indMatrix\" nepavyko.\n" #~ " Visi įrašai turi būti vertinami kaip sveikieji ir stulpelių skaičius d " #~ "ne mažesnis\n" #~ " nei maksimalus indeksas i*." #~ msgid "the number of non-zero entries differs from nrow(.)" #~ msgstr "ne nulinių įrašų skaičius skiriasi nuo nrow(.)" #~ msgid "resulting matrix dimension would be too large" #~ msgstr "gautas matricos matmuo būtų per didelis" #~ msgid "replacing \"indMatrix\" entries is not allowed, as rarely sensible" #~ msgstr "pakeisti \"indMatrix\" įrašų neleidžiama, kaip retai praktiškų" #~ msgid "temporarily disabled" #~ msgstr "laikinai išjungtas" #~ msgid "cannot coerce NA values to pattern \"ntCMatrix\"" #~ msgstr "negalima paversti NA reikšmes į modelį \"ntCMatrix\"" #~ msgid "coercion to \"pMatrix\" only works from integer numeric" #~ msgstr "pavertimas į \"pMatrix\" veikia tik iš sveikųjų skaitinių" #~ msgid "not a square matrix" #~ msgstr "ne kvadratinė matrica" #~ msgid "NA's in (i,j) are not allowed" #~ msgstr "NA esantys (i,j) yra neleidžiami" #~ msgid "" #~ "Both 'symmetric' and 'triangular', i.e. asking for diagonal matrix. Use " #~ "'Diagonal()' instead" #~ msgstr "" #~ "Ir 'symmetric', ir 'triangular', t. y. prašant įstrižinės matricos. " #~ "Vietoj to naudokite 'Diagonal()'" #~ msgid "triangular matrix must have all i >= j or i <= j" #~ msgstr "trikampė matrica turi turėti visus i >= j arba i <= j" #~ msgid "Matrix-internal error in [i,,d]; please report" #~ msgstr "Matricos vidinė klaida, esanti [i,,d]; prašome pranešti" #~ msgid "" #~ "qr.R() may differ from qr.R() because of permutations. " #~ "Possibly use our qrR() instead" #~ msgstr "" #~ "qr.R() gali skirtis nuo qr.R() dėl perstatų. Galbūt " #~ "vietoj to naudokite mūsų qrR()" #~ msgid "(un)packing only applies to dense matrices, class(x)='%s'" #~ msgstr "(iš)pakavimas taikomas tik tankio matricoms, class(x)='%s'" #~ msgid "'x' is not symmetric -- chol() undefined." #~ msgstr "'x' nėra simetriškas -- chol() neapibrėžtas." #~ msgid "" #~ "extra argument %s will be disregarded in\n" #~ " %s" #~ msgid_plural "" #~ "extra arguments %s will be disregarded in\n" #~ " %s" #~ msgstr[0] "" #~ "papildomas argumentas %s, į kurį bus neatsižvelgiama\n" #~ " %s" #~ msgstr[1] "" #~ "papildomi argumentai %s, į kuriuos bus neatsižvelgiama\n" #~ " %s" #~ msgstr[2] "" #~ "papildomų argumentų %s, į kuriuos bus neatsižvelgiama\n" #~ " %s" Matrix/po/R-Matrix.pot0000644000176200001440000004070614521047060014331 0ustar liggesusersmsgid "" msgstr "" "Project-Id-Version: Matrix 1.6-2\n" "POT-Creation-Date: 2023-11-02 21:33\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" msgid "invalid mode \"%s\"" msgstr "" msgid "%s(<%s>, <%s>) is not yet implemented; ask maintainer(\"%s\") to implement the missing method" msgstr "" msgid "complex %s not yet implemented" msgstr "" msgid "cannot coerce matrix of type \"%s\" to %s" msgstr "" msgid "non0.i() not yet implemented for class %s" msgstr "" msgid "%s=\"%s\" invalid for %s@uplo=\"%s\"" msgstr "" msgid "'%s' is not \"%1$s\", \"D%1$s\", or \"%1$s.\"" msgstr "" msgid "unexpected %s=\"%s\" in '%s' method" msgstr "" msgid "Not a valid format" msgstr "" msgid "'file' must be a character string or connection" msgstr "" msgid "Invalid storage type: %s" msgstr "" msgid "Only numeric sparse matrices allowed" msgstr "" msgid "Invalid storage format: %s" msgstr "" msgid "Invalid assembled indicator: %s" msgstr "" msgid "file is not a MatrixMarket file" msgstr "" msgid "type '%s' not recognized" msgstr "" msgid "representation '%s' not recognized" msgstr "" msgid "element type '%s' not recognized" msgstr "" msgid "symmetry form '%s' not recognized" msgstr "" msgid "readMM(): expected %d entries but found only %d" msgstr "" msgid "readMM(): row indices 'i' are not in 1:nrow[=%d]" msgstr "" msgid "readMM(): column indices 'j' are not in 1:ncol[=%d]" msgstr "" msgid "symmetry form 'skew-symmetric' not yet implemented for reading" msgstr "" msgid "symmetry form 'hermitian' not yet implemented for reading" msgstr "" msgid "symmetry form '%s' is not yet implemented" msgstr "" msgid "element type 'complex' not yet implemented" msgstr "" msgid "'%s()' is not yet implemented for element type '%s'" msgstr "" msgid "'%s()' is not yet implemented for representation '%s'" msgstr "" msgid "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%3$s\", or \"%4$s\"" msgstr "" msgid "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%2$s2\", \"%2$s2.\", \"%3$s\", or \"%4$s\"" msgstr "" msgid "longer object length is not a multiple of shorter object length" msgstr "" msgid "invalid class \"%s\" in '%s' method" msgstr "" msgid "invalid type \"%s\" in '%s' method" msgstr "" msgid "non-conformable matrix dimensions in %s" msgstr "" msgid "dimnames [%d] mismatch in %s" msgstr "" msgid "inefficient method used for \"- e1\"" msgstr "" msgid "dim [product %d] do not match the length of object [%d]" msgstr "" msgid "internal bug in \"Compare\" method (Cmp.Mat.atomic); please report" msgstr "" msgid "Cmp.Mat.atomic() should not be called for diagonalMatrix" msgstr "" msgid "Matrices must have same number of rows for arithmetic" msgstr "" msgid "number of rows are not compatible for %s" msgstr "" msgid "length of 2nd arg does not match dimension of first" msgstr "" msgid "length of 1st arg does not match dimension of 2nd" msgstr "" msgid "internal bug in \"Logic\" method (Logic.Mat.atomic); please report" msgstr "" msgid "Logic.Mat.atomic() should not be called for diagonalMatrix" msgstr "" msgid "vector too long in Matrix - vector operation" msgstr "" msgid "longer object length\n\tis not a multiple of shorter object length" msgstr "" msgid "intermediate 'r' is of type %s" msgstr "" msgid "not yet implemented .. please report" msgstr "" msgid "'force' must be (coercable to) TRUE or FALSE" msgstr "" msgid "invalid (to - from)/by in seq(.)" msgstr "" msgid "wrong sign in 'by' argument" msgstr "" msgid "'by' argument is much too small" msgstr "" msgid "length must be non-negative number" msgstr "" msgid "too many arguments" msgstr "" msgid "c(,..) of different kinds, coercing all to 'rleDiff'" msgstr "" msgid "[i] is not yet implemented" msgstr "" msgid "all() is not yet implemented" msgstr "" msgid "sum() is not yet implemented" msgstr "" msgid "prod() is not yet implemented" msgstr "" msgid "not yet implemented" msgstr "" msgid "x / 0 for an x with sign-change\n no longer representable as 'rleDiff'" msgstr "" msgid " --> is not yet implemented" msgstr "" msgid " --> is not yet implemented" msgstr "" msgid "%1$s(%2$s) is undefined: '%2$s' is not positive semidefinite" msgstr "" msgid "matrix is not square" msgstr "" msgid "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%3$s\", \"%3$s.\", \"%3$s1\", \"%3$s1.\", or \"%4$s\"" msgstr "" msgid "'%s' does not inherit from virtual class %s" msgstr "" msgid "D[i,i] is NA, i=%d" msgstr "" msgid "D[i,i] is negative, i=%d" msgstr "" msgid "'%1$s' is not formally symmetric; factorizing tcrossprod(%1$s)" msgstr "" msgid "matrix is not symmetric; consider forceSymmetric(.) or symmpart(.)" msgstr "" msgid "matrix is not triangular; consider triu(.) or tril(.)" msgstr "" msgid "matrix is not diagonal; consider Diagonal(x=diag(.))" msgstr "" msgid "invalid type \"%s\" in '%s'" msgstr "" msgid "invalid %s=\"%s\" to '%s'" msgstr "" msgid "dimensions cannot exceed %s" msgstr "" msgid "invalid class \"%s\" in '%s'" msgstr "" msgid "%s length cannot exceed %s" msgstr "" msgid "'A' must be a square matrix" msgstr "" msgid "must either specify 'A' or the functions 'A.x' and 'At.x'" msgstr "" msgid "when 'A' is specified, 'A.x' and 'At.x' are disregarded" msgstr "" msgid "not converged in %d iterations" msgstr "" msgid "hit a cycle (1) -- stop iterations" msgstr "" msgid "hit a cycle (2) -- stop iterations" msgstr "" msgid "not enough new vecs -- stop iterations" msgstr "" msgid "invalid 'data'" msgstr "" msgid "'nrow', 'ncol', 'byrow' disregarded for [mM]atrix 'data'" msgstr "" msgid "data is too long" msgstr "" msgid "exactly one of 'i', 'j', and 'p' must be missing from call" msgstr "" msgid "use Diagonal() to construct diagonal (symmetric && triangular) sparse matrices" msgstr "" msgid "'giveCsparse' is deprecated; using 'repr' instead" msgstr "" msgid "'giveCsparse' is deprecated; setting repr=\"T\" for you" msgstr "" msgid "'p' must be a nondecreasing vector c(0, ...)" msgstr "" msgid "dimensions cannot exceed 2^31-1" msgstr "" msgid "'i' and 'j' must not contain NA" msgstr "" msgid "'i' and 'j' must be" msgstr "" msgid "positive" msgstr "" msgid "non-negative" msgstr "" msgid "invalid 'dims'" msgstr "" msgid "'dims' must contain all (i,j) pairs" msgstr "" msgid "symmetric matrix must be square" msgstr "" msgid "triangular matrix must be square" msgstr "" msgid "p[length(p)]" msgstr "" msgid "length(i)" msgstr "" msgid "is not an integer multiple of length(x)" msgstr "" msgid "length(x) must not exceed" msgstr "" msgid "invalid 'repr'; must be \"C\", \"R\", or \"T\"" msgstr "" msgid "'n' must be a non-negative integer" msgstr "" msgid "'x' has unsupported class \"%s\"" msgstr "" msgid "'x' has unsupported type \"%s\"" msgstr "" msgid "attempt to recycle 'x' of length 0 to length 'n' (n > 0)" msgstr "" msgid "'shape' must be one of \"g\", \"t\", \"s\"" msgstr "" msgid "'kind' must be one of \"d\", \"l\", \"n\"" msgstr "" msgid "mismatch between typeof(x)=\"%s\" and kind=\"%s\"; using kind=\"%s\"" msgstr "" msgid "'cols' must be numeric" msgstr "" msgid "'cols' has elements not in seq(0, length.out = n)" msgstr "" msgid "'uplo' must be \"U\" or \"L\"" msgstr "" msgid "'lst' must be a list" msgstr "" msgid "'giveCsparse' has been deprecated; setting 'repr = \"T\"' for you" msgstr "" msgid "'giveCsparse' has been deprecated; will use 'repr' instead" msgstr "" msgid "'diagonals' matrix must have %d columns (= length(k) )" msgstr "" msgid "'diagonals' must have the same length (%d) as 'k'" msgstr "" msgid "matrix can only be symmetric if square, but n != m" msgstr "" msgid "for symmetric band matrix, only specify upper or lower triangle\n hence, all k must have the same sign" msgstr "" msgid "the %d-th (sub)-diagonal (k = %d) is too short; filling with NA's" msgstr "" msgid "invalid 'repr'; must be \"C\", \"T\", or \"R\"" msgstr "" msgid "'x' must inherit from \"sparseVector\"" msgstr "" msgid "'ncol' must be >= 0" msgstr "" msgid "'nrow' must be >= 0" msgstr "" msgid "Must specify 'nrow' when 'symmetric' is true" msgstr "" msgid "'nrow' and 'ncol' must be the same when 'symmetric' is true" msgstr "" msgid "'x' must have length nrow^2 when 'symmetric' is true" msgstr "" msgid "'ncol' is not a factor of length(x)" msgstr "" msgid "'nrow' is not a factor of length(x)" msgstr "" msgid "Class %s is not yet implemented" msgstr "" msgid "'%s' and '%s' must be positive integers" msgstr "" msgid "matrix is not symmetric or triangular" msgstr "" msgid "matrix is not symmetric" msgstr "" msgid "matrix is not triangular" msgstr "" msgid "the default value of argument '%s' of method '%s(<%s>, <%s>)' may change from %s to %s as soon as the next release of Matrix; set '%s' when programming" msgstr "" msgid "determinant of non-square matrix is undefined" msgstr "" msgid "replacement diagonal has wrong length" msgstr "" msgid "replacement diagonal has incompatible type \"%s\"" msgstr "" msgid "assigned dimensions are not of type \"%s\" or \"%s\"" msgstr "" msgid "assigned dimensions do not have length %d" msgstr "" msgid "assigned dimensions are NA" msgstr "" msgid "assigned dimensions are negative" msgstr "" msgid "assigned dimensions exceed %s" msgstr "" msgid "assigned dimensions [product %.0f] do not match object length [%.0f]" msgstr "" msgid "'%s' has non-finite values" msgstr "" msgid "'%1$s' is not \"%2$s\", \"%3$s\", or \"%2$s.\"" msgstr "" msgid "only square matrices can be used as graph incidence matrices" msgstr "" msgid "'lwd' must be NULL or non-negative numeric" msgstr "" msgid "%s(<%s>) is not yet implemented" msgstr "" msgid "'%s' is not of type \"%s\" or \"%s\"" msgstr "" msgid "'%s' contains NA" msgstr "" msgid "'%s' has elements less than %d" msgstr "" msgid "'%s' is not a non-negative number" msgstr "" msgid "'%s' has elements exceeding '%s'" msgstr "" msgid "'%s' is not %d or %d" msgstr "" msgid "'%s' is not a permutation of seq_len(%s)" msgstr "" msgid "matrix must have exactly one entry in each row or column" msgstr "" msgid "attempt to coerce non-square matrix to %s" msgstr "" msgid "matrix must have exactly one entry in each row and column" msgstr "" msgid "'%s' via sparse -> dense coercion" msgstr "" msgid "invalid %s=\"%s\"" msgstr "" msgid "norm" msgstr "" msgid "'%s' method must use default %s=\"%s\"" msgstr "" msgid "number of nonzero entries cannot exceed %s" msgstr "" msgid "Matrix seems negative semi-definite" msgstr "" msgid "'nearPD()' did not converge in %d iterations" msgstr "" msgid "'cl' is not a character string" msgstr "" msgid "not a positive definite matrix (and positive semidefiniteness is not checked)" msgstr "" msgid "'%s' is not a square numeric matrix" msgstr "" msgid "diag(%s) has non-positive or non-finite entries; finite result is doubtful" msgstr "" msgid "non-conformable arguments" msgstr "" msgid "matrix is structurally rank deficient; using augmented matrix with additional %d row(s) of zeros" msgstr "" msgid "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%2$s2\", \"%2$s2.\", \"%3$s\", \"%3$s1\", \"%4$s\", or \"%4$s1\"" msgstr "" msgid "'%s' has the wrong length" msgstr "" msgid "invalid '%s': not in %d:%d" msgstr "" msgid "need greater '%s' as pivoting occurred" msgstr "" msgid "qr2rankMatrix(.): QR with only %d out of %d finite diag(R) entries" msgstr "" msgid "rankMatrix(, method = '%s') coerces to dense matrix.\n Probably should rather use method = 'qr' !?" msgstr "" msgid "rankMatrix(x, method='qr'): computing t(x) as nrow(x) < ncol(x)" msgstr "" msgid "[[ suppressing %d column name%s %s ... ]]" msgstr "" msgid "invalid 'col.names' string: %s" msgstr "" msgid "uniDiag=TRUE, but not all diagonal entries are 1" msgstr "" msgid "uniDiag=TRUE, not all entries in diagonal coded as 1" msgstr "" msgid "in show(); maybe adjust options(max.print=, width=)" msgstr "" msgid "suppressing %d columns and %d rows" msgstr "" msgid "suppressing %d rows" msgstr "" msgid "suppressing %d columns" msgstr "" msgid "logic programming error in printSpMatrix2(), please report" msgstr "" msgid "'%s' is not square" msgstr "" msgid "dimensions of '%s' and '%s' are inconsistent" msgstr "" msgid "'%1$s' is computationally singular, rcond(%1$s)=%2$g" msgstr "" msgid "'%s' is computationally singular, min(d)/max(d)=%g, d=abs(diag(U))" msgstr "" msgid "matrix is exactly singular, D[i,i]=0, i=%d" msgstr "" msgid "matrix is exactly singular, J[,j]=0, j=%d" msgstr "" msgid "matrix exactly singular, J[i,]=0, i=%d" msgstr "" msgid "cannot coerce from %s to %s" msgstr "" msgid "model frame and formula mismatch in sparse.model.matrix()" msgstr "" msgid "non-list contrasts argument ignored" msgstr "" msgid "'contrasts.arg' argument must be named" msgstr "" msgid "variable '%s' is absent, its contrast will be ignored" msgstr "" msgid "a sparseMatrix should rarely be centered: will not be sparse anymore" msgstr "" msgid "length of 'center' must equal the number of columns of 'x'" msgstr "" msgid "length of 'scale' must equal the number of columns of 'x'" msgstr "" msgid "trimmed means are not defined for complex data" msgstr "" msgid "first element used of '%s' argument" msgstr "" msgid "invalid '%s' argument" msgstr "" msgid "should never happen ..." msgstr "" msgid "'%s' is deprecated; using '%s' instead" msgstr "" msgid "'%s' is deprecated; setting %s=\"%s\"" msgstr "" msgid ".M.repl.i.2col(): 'i' has no integer column number;\n should never happen; please report" msgstr "" msgid "such indexing must be by logical or 2-column numeric matrix" msgstr "" msgid ".M.repl.i.2col(): drop 'matrix' case ..." msgstr "" msgid "negative values are not allowed in a matrix subscript" msgstr "" msgid "NAs are not allowed in subscripted assignments" msgstr "" msgid "number of items to replace is not a multiple of replacement length" msgstr "" msgid "m[ ] <- v: inefficiently treating single elements" msgstr "" msgid "nargs() = %d. Extraneous illegal arguments inside '[ .. ]' ?" msgstr "" msgid "RHS 'value' (class %s) matches 'ANY', but must match matrix class %s" msgstr "" msgid "not-yet-implemented 'Matrix[<-' method" msgstr "" msgid "invalid nargs()= %d" msgstr "" msgid "nothing to replace with" msgstr "" msgid "too many replacement values" msgstr "" msgid "i1[1] == 0 ==> C-level verbosity will not happen!" msgstr "" msgid "using\t \"old code\" part in Csparse subassignment" msgstr "" msgid "using\"old code\" part in Csparse subassignment\n >>> please report to Matrix-authors@r-project.org" msgstr "" msgid "you cannot mix negative and positive indices" msgstr "" msgid "index larger than maximal %d" msgstr "" msgid "'NA' indices are not (yet?) supported for sparse Matrices" msgstr "" msgid "logical subscript too long (%d, should be %d)" msgstr "" msgid "no 'dimnames[[.]]': cannot use character indexing" msgstr "" msgid "invalid character indexing" msgstr "" msgid "internal bug: missing 'i' in replTmat(): please report" msgstr "" msgid "[ ] indexing not allowed: forgot a \",\" ?" msgstr "" msgid "internal bug: matrix 'i' in replTmat(): please report" msgstr "" msgid "x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced; NA |--> TRUE." msgstr "" msgid "x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced." msgstr "" msgid "x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced NA |--> TRUE." msgstr "" msgid "x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced." msgstr "" msgid "x[.,.] <- val : x being coerced from Tsparse* to CsparseMatrix" msgstr "" msgid "nargs() = %d should never happen; please report." msgstr "" msgid "row indices must be <= nrow(.) which is %d" msgstr "" msgid "column indices must be <= ncol(.) which is %d" msgstr "" msgid "Internal bug: nargs()=%d; please report" msgstr "" msgid "index must be numeric, logical or sparseVector for indexing sparseVectors" msgstr "" msgid "invalid subscript class \"%s\"" msgstr "" msgid "invalid subscript type \"%s\"" msgstr "" msgid "recycled %s would have maximal index exceeding %s" msgstr "" msgid "subscripts exceeding %s replaced with NA" msgstr "" msgid "subscript out of bounds" msgstr "" msgid "logical subscript too long" msgstr "" msgid "incorrect number of dimensions" msgstr "" msgid "only zeros may be mixed with negative subscripts" msgstr "" msgid "'%s' has length 0 but '%s' does not" msgstr "" msgid "attempt to coerce matrix with NA to %s" msgstr "" msgid "invalid 'Class2'" msgstr "" Matrix/po/Matrix.pot0000644000176200001440000006127314521047060014134 0ustar liggesusers# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the Matrix package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Matrix 1.6-2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-11-02 21:33-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: Csparse.c:26 Csparse.c:318 chm_common.c:165 chm_common.c:291 #: chm_common.c:813 chm_common.c:816 chm_common.c:849 chm_common.c:867 #: dgCMatrix.c:18 dgCMatrix.c:43 dgCMatrix.c:70 dgCMatrix.c:84 dgCMatrix.c:89 #: dgCMatrix.c:94 #, c-format msgid "'%s' failed" msgstr "" #: Csparse.c:35 chm_common.c:54 #, c-format msgid "'%s' slot is not increasing within columns after sorting" msgstr "" #: Csparse.c:77 coerce.c:220 coerce.c:240 coerce.c:250 coerce.c:905 #: coerce.c:911 coerce.c:1015 coerce.c:1501 coerce.c:1521 coerce.c:1531 #: coerce.c:2061 coerce.c:2256 coerce.c:2262 coerce.c:2268 coerce.c:2397 #: coerce.c:2404 coerce.c:2494 coerce.c:2629 coerce.c:2707 coerce.c:2729 #: coerce.c:4327 coerce.c:4396 dense.c:701 products.c:936 products.c:1288 #: solve.c:719 solve.c:968 solve.c:1100 sparse.c:1233 sparse.c:1625 #, c-format msgid "invalid '%s' to '%s'" msgstr "" #: Csparse.c:316 #, c-format msgid "failed to open file \"%s\" for writing" msgstr "" #: attrib.c:229 msgid "invalid factor name" msgstr "" #: attrib.c:233 #, c-format msgid "attempt to set factor on %s without '%s' slot" msgstr "" #: bind.c:46 bind.c:153 msgid "number of rows of matrices must match" msgstr "" #: bind.c:48 bind.c:155 msgid "number of columns of matrices must match" msgstr "" #: bind.c:51 bind.c:158 bind.c:182 bind.c:206 chm_common.c:474 chm_common.c:623 #: chm_common.c:717 cholmod-etc.c:183 cholmod-etc.c:282 cholmod-etc.c:325 #: coerce.c:215 coerce.c:235 coerce.c:260 coerce.c:268 coerce.c:276 #: coerce.c:341 coerce.c:1496 coerce.c:1516 coerce.c:1543 coerce.c:1551 #: coerce.c:1559 products.c:28 products.c:50 products.c:56 #, c-format msgid "dimensions cannot exceed %s" msgstr "" #: bind.c:210 msgid "number of rows of result is not a multiple of vector length" msgstr "" #: bind.c:212 msgid "number of columns of result is not a multiple of vector length" msgstr "" #: bind.c:626 bind.c:691 sparse.c:912 sparse.c:993 #, c-format msgid "%s cannot exceed %s" msgstr "" #: bind.c:756 bind.c:853 chm_common.c:720 cholmod-etc.c:328 coerce.c:29 #: coerce.c:518 coerce.c:811 coerce.c:945 coerce.c:2772 coerce.c:3041 #: coerce.c:3139 dense.c:924 products.c:151 products.c:212 products.c:291 #: products.c:379 products.c:456 products.c:550 products.c:865 subscript.c:1232 #: subscript.c:1417 utils-R.c:32 #, c-format msgid "attempt to allocate vector of length exceeding %s" msgstr "" #: bind.c:858 products.c:1354 msgid "should never happen ..." msgstr "" #: chm_common.c:11 chm_common.c:34 validity.c:38 validity.c:183 validity.c:262 #: validity.c:281 validity.c:290 validity.c:309 validity.c:335 validity.c:355 #: validity.c:405 validity.c:422 validity.c:456 validity.c:473 validity.c:507 #: validity.c:509 validity.c:959 validity.c:992 validity.c:1074 validity.c:1094 #: validity.c:1160 validity.c:1162 validity.c:1210 validity.c:1273 #: validity.c:1275 validity.c:1321 validity.c:1368 validity.c:1417 #: validity.c:1450 validity.c:1460 validity.c:1473 validity.c:1527 #: validity.c:1529 validity.c:1561 validity.c:1573 validity.c:1596 #: validity.c:1659 validity.c:1678 validity.c:1680 validity.c:1712 #: validity.c:1747 validity.c:1775 #, c-format msgid "'%s' slot is not of type \"%s\"" msgstr "" #: chm_common.c:14 validity.c:357 validity.c:407 validity.c:458 validity.c:880 #: validity.c:891 validity.c:961 validity.c:994 validity.c:1096 validity.c:1164 #: validity.c:1212 validity.c:1277 validity.c:1323 validity.c:1462 #: validity.c:1479 validity.c:1531 validity.c:1533 validity.c:1563 #: validity.c:1575 validity.c:1598 validity.c:1714 validity.c:1751 #: validity.c:1779 validity.c:1829 #, c-format msgid "'%s' slot does not have length %s" msgstr "" #: chm_common.c:18 validity.c:410 validity.c:461 validity.c:1667 #: validity.c:1687 validity.c:1689 #, c-format msgid "first element of '%s' slot is not 0" msgstr "" #: chm_common.c:23 chm_common.c:46 validity.c:43 validity.c:361 validity.c:414 #: validity.c:432 validity.c:465 validity.c:483 validity.c:519 validity.c:521 #: validity.c:1041 validity.c:1053 validity.c:1100 validity.c:1173 #: validity.c:1185 validity.c:1286 validity.c:1298 validity.c:1327 #: validity.c:1378 validity.c:1427 validity.c:1466 validity.c:1486 #: validity.c:1567 validity.c:1583 validity.c:1608 validity.c:1672 #: validity.c:1692 validity.c:1694 validity.c:1721 #, c-format msgid "'%s' slot contains NA" msgstr "" #: chm_common.c:26 validity.c:416 validity.c:467 #, c-format msgid "'%s' slot is not nondecreasing" msgstr "" #: chm_common.c:29 validity.c:418 validity.c:469 #, c-format msgid "first differences of '%s' slot exceed %s" msgstr "" #: chm_common.c:37 validity.c:424 validity.c:475 #, c-format msgid "'%s' slot has length less than %s" msgstr "" #: chm_common.c:49 validity.c:363 validity.c:434 validity.c:485 validity.c:523 #: validity.c:526 validity.c:1043 validity.c:1102 validity.c:1175 #: validity.c:1187 validity.c:1288 validity.c:1300 validity.c:1380 #: validity.c:1429 validity.c:1488 validity.c:1610 validity.c:1723 #, c-format msgid "'%s' slot has elements not in {%s}" msgstr "" #: chm_common.c:467 chm_common.c:470 chm_common.c:472 chm_common.c:616 #: chm_common.c:619 chm_common.c:621 chm_common.c:711 chm_common.c:713 #: cholmod-etc.c:177 cholmod-etc.c:179 cholmod-etc.c:181 cholmod-etc.c:276 #: cholmod-etc.c:278 cholmod-etc.c:280 cholmod-etc.c:319 cholmod-etc.c:321 #: cs-etc.c:43 #, c-format msgid "wrong '%s'" msgstr "" #: chm_common.c:477 cholmod-etc.c:186 #, c-format msgid "'%s' would overflow type \"%s\"" msgstr "" #: chm_common.c:481 cholmod-etc.c:190 #, c-format msgid "n+1 would overflow type \"%s\"" msgstr "" #: chm_common.c:486 cholmod-etc.c:195 #, c-format msgid "leading principal minor of order %d is not positive" msgstr "" #: chm_common.c:489 cholmod-etc.c:198 #, c-format msgid "leading principal minor of order %d is zero" msgstr "" #: chm_common.c:715 cholmod-etc.c:323 msgid "leading dimension not equal to number of rows" msgstr "" #: chm_common.c:778 #, c-format msgid "" "invalid simplicial Cholesky factorization: structural zero on main diagonal " "in column %d" msgstr "" #: chm_common.c:838 #, c-format msgid "CHOLMOD error '%s' at file '%s', line %d" msgstr "" #: chm_common.c:841 #, c-format msgid "CHOLMOD warning '%s' at file '%s', line %d" msgstr "" #: coerce.c:24 coerce.c:364 coerce.c:1050 #, c-format msgid "attempt to construct non-square %s" msgstr "" #: coerce.c:186 coerce.c:476 coerce.c:1467 coerce.c:1622 #, c-format msgid "second argument of '%s' does not specify a subclass of %s" msgstr "" #: coerce.c:194 coerce.c:200 coerce.c:484 coerce.c:490 coerce.c:925 #: coerce.c:1475 coerce.c:1481 coerce.c:1630 coerce.c:1636 coerce.c:2275 #: coerce.c:3344 coerce.c:3349 #, c-format msgid "'%s' must be \"%s\" or \"%s\"" msgstr "" #: coerce.c:246 coerce.c:496 coerce.c:793 coerce.c:917 coerce.c:1527 #: coerce.c:1642 dense.c:322 dense.c:1107 dense.c:1683 dense.c:1688 #: dense.c:1934 dense.c:2129 sparse.c:783 sparse.c:2448 sparse.c:3140 #: sparse.c:3145 sparse.c:3150 sparse.c:3426 sparse.c:3663 #, c-format msgid "'%s' must be %s or %s" msgstr "" #: coerce.c:266 coerce.c:274 coerce.c:285 coerce.c:1549 coerce.c:1557 #: coerce.c:1568 msgid "nonempty vector supplied for empty matrix" msgstr "" #: coerce.c:287 coerce.c:1570 #, c-format msgid "vector length (%lld) exceeds matrix length (%d * %d)" msgstr "" #: coerce.c:290 coerce.c:1573 #, c-format msgid "matrix length (%d * %d) is not a multiple of vector length (%lld)" msgstr "" #: coerce.c:521 #, c-format msgid "coercing n-by-n %s to %s is not supported for n*n exceeding %s" msgstr "" #: coerce.c:525 coerce.c:815 coerce.c:949 #, c-format msgid "sparse->dense coercion: allocating vector of size %0.1f GiB" msgstr "" #: coerce.c:1196 coerce.c:1941 coerce.c:2948 coerce.c:2954 #, c-format msgid "attempt to construct %s with more than %s nonzero entries" msgstr "" #: coerce.c:3246 msgid "attempt to pack non-square matrix" msgstr "" #: coerce.c:3420 coerce.c:3590 #, c-format msgid "unable to aggregate %s with '%s' and '%s' slots of length exceeding %s" msgstr "" #: coerce.c:4211 #, c-format msgid "attempt to pack a %s" msgstr "" #: coerce.c:4330 dense.c:1237 sparse.c:2579 #, c-format msgid "'%s' must be %s or %s or %s" msgstr "" #: dense.c:210 dense.c:215 sparse.c:590 sparse.c:595 #, c-format msgid "'%s' must be an integer from %s to %s" msgstr "" #: dense.c:218 sparse.c:598 #, c-format msgid "'%s' must be less than or equal to '%s'" msgstr "" #: dense.c:428 sparse.c:1069 #, c-format msgid "replacement diagonal has incompatible type \"%s\"" msgstr "" #: dense.c:437 sparse.c:1078 msgid "replacement diagonal has wrong length" msgstr "" #: dense.c:627 sparse.c:1274 msgid "attempt to symmetrize a non-square matrix" msgstr "" #: dense.c:726 sparse.c:1652 msgid "attempt to get symmetric part of non-square matrix" msgstr "" #: dense.c:878 sparse.c:2082 msgid "attempt to get skew-symmetric part of non-square matrix" msgstr "" #: dense.c:1678 sparse.c:3135 #, c-format msgid "'%s' must be %d or %d" msgstr "" #: dense.c:2161 #, c-format msgid "incorrect left cyclic shift, j (%d) < 0" msgstr "" #: dense.c:2164 #, c-format msgid "incorrect left cyclic shift, j (%d) >= k (%d)" msgstr "" #: dense.c:2167 #, c-format msgid "incorrect left cyclic shift, k (%d) > ldx (%d)" msgstr "" #: dense.c:2220 msgid "unknown error in getGivens" msgstr "" #: dense.c:2229 dense.c:2243 dense.c:2273 msgid "X must be a numeric (double precision) matrix" msgstr "" #: dense.c:2245 dense.c:2275 msgid "y must be a numeric (double precision) matrix" msgstr "" #: dense.c:2249 dense.c:2279 #, c-format msgid "number of rows in y (%d) does not match number of rows in X (%d)" msgstr "" #: dense.c:2265 #, c-format msgid "LAPACK dposv returned error code %d" msgstr "" #: dense.c:2293 dense.c:2299 #, c-format msgid "LAPACK dgels returned error code %d" msgstr "" #: dense.c:2318 msgid "X must be a real (numeric) matrix" msgstr "" #: dense.c:2321 #, c-format msgid "tol, given as %g, must be >= 0" msgstr "" #: dense.c:2323 #, c-format msgid "tol, given as %g, must be <= 1" msgstr "" #: dense.c:2352 dense.c:2360 #, c-format msgid "LAPACK dgeqrf returned error code %d" msgstr "" #: dense.c:2365 dense.c:2388 #, c-format msgid "LAPACK dtrcon returned error code %d" msgstr "" #: determinant.c:33 msgid "determinant of non-square matrix is undefined" msgstr "" #: determinant.c:276 #, c-format msgid "%s(<%s>) does not support structurally rank deficient case" msgstr "" #: dgCMatrix.c:14 #, c-format msgid "'%s' is empty or not square" msgstr "" #: dgCMatrix.c:16 dgCMatrix.c:38 dgCMatrix.c:61 solve.c:43 solve.c:984 #, c-format msgid "dimensions of '%s' and '%s' are inconsistent" msgstr "" #: dgCMatrix.c:40 #, c-format msgid "%s(%s, %s) requires m-by-n '%s' with m >= n > 0" msgstr "" #: dgCMatrix.c:63 #, c-format msgid "%s(%s, %s) requires m-by-n '%s' with n >= m > 0" msgstr "" #: dgeMatrix.c:22 #, c-format msgid "dgeMatrix_svd(x,*): dim(x)[j] = %d is too large" msgstr "" #: dgeMatrix.c:90 msgid "Matrix exponential requires square, non-null matrix" msgstr "" #: dgeMatrix.c:107 dgeMatrix.c:109 #, c-format msgid "dgeMatrix_exp: LAPACK routine dgebal returned %d" msgstr "" #: dgeMatrix.c:147 #, c-format msgid "dgeMatrix_exp: dgetrf returned error code %d" msgstr "" #: dgeMatrix.c:149 #, c-format msgid "dgeMatrix_exp: dgetrs returned error code %d" msgstr "" #: dgeMatrix.c:224 msgid "dgeMatrix_Schur: argument x must be a non-null square matrix" msgstr "" #: dgeMatrix.c:237 msgid "dgeMatrix_Schur: first call to dgees failed" msgstr "" #: dgeMatrix.c:246 #, c-format msgid "dgeMatrix_Schur: dgees returned code %d" msgstr "" #: factorizations.c:355 sparse.c:196 #, c-format msgid "'%s' is not a number" msgstr "" #: factorizations.c:376 #, c-format msgid "LU factorization of m-by-n %s requires m == n" msgstr "" #: factorizations.c:385 #, c-format msgid "LU factorization of %s failed: out of memory or near-singular" msgstr "" #: factorizations.c:462 #, c-format msgid "QR factorization of m-by-n %s requires m >= n" msgstr "" #: factorizations.c:471 #, c-format msgid "QR factorization of %s failed: out of memory" msgstr "" #: factorizations.c:571 factorizations.c:849 #, c-format msgid "'%s' is not a number or not finite" msgstr "" #: idz.c:467 idz.c:528 #, c-format msgid "incompatible '%s' and '%s' in '%s'" msgstr "" #: kappa.c:10 kappa.c:54 #, c-format msgid "argument '%s' is not of type \"%s\"" msgstr "" #: kappa.c:13 kappa.c:57 #, c-format msgid "argument '%s' has length %d" msgstr "" #: kappa.c:17 kappa.c:61 #, c-format msgid "argument '%s' (\"%s\") does not have string length %d" msgstr "" #: kappa.c:41 #, c-format msgid "" "argument '%s' (\"%s\") is not \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", or " "\"%s\"" msgstr "" #: kappa.c:75 #, c-format msgid "argument '%s' (\"%s\") is not \"%s\", \"%s\", or \"%s\"" msgstr "" #: kappa.c:238 #, c-format msgid "%s(%s) is undefined: '%s' is not square" msgstr "" #: objects.c:23 #, c-format msgid "unexpected type \"%s\" in '%s'" msgstr "" #: objects.c:41 objects.c:58 #, c-format msgid "unexpected kind \"%c\" in '%s'" msgstr "" #: perm.c:26 perm.c:106 msgid "attempt to get sign of non-permutation" msgstr "" #: perm.c:51 perm.c:123 msgid "attempt to invert non-permutation" msgstr "" #: perm.c:66 msgid "invalid transposition vector" msgstr "" #: perm.c:79 perm.c:81 perm.c:96 perm.c:98 perm.c:113 perm.c:133 perm.c:145 #, c-format msgid "'%s' is not of type \"%s\"" msgstr "" #: perm.c:83 perm.c:100 perm.c:147 #, c-format msgid "'%s' does not have length %d" msgstr "" #: perm.c:86 perm.c:103 #, c-format msgid "'%s' is NA" msgstr "" #: perm.c:115 perm.c:138 #, c-format msgid "'%s' or '%s' is not of type \"%s\"" msgstr "" #: perm.c:117 perm.c:140 #, c-format msgid "'%s' or '%s' does not have length %d" msgstr "" #: perm.c:120 perm.c:143 #, c-format msgid "'%s' or '%s' is NA" msgstr "" #: perm.c:136 #, c-format msgid "'%s' has length exceeding %s" msgstr "" #: perm.c:150 #, c-format msgid "'%s' is NA or less than %s" msgstr "" #: products.c:107 products.c:210 products.c:289 products.c:377 products.c:454 #: products.c:548 products.c:809 products.c:859 msgid "non-conformable arguments" msgstr "" #: products.c:782 products.c:807 #, c-format msgid "'%s' does not support complex matrices" msgstr "" #: solve.c:38 #, c-format msgid "'%s' is not square" msgstr "" #: solve.c:497 #, c-format msgid "%s(<%s>, <%s>) failed: out of memory" msgstr "" #: solve.c:618 #, c-format msgid "attempt to construct %s with more than %s nonzero elements" msgstr "" #: sparseVector.c:90 #, c-format msgid "%s length cannot exceed %s" msgstr "" #: subscript.c:1542 subscript.c:1695 subscript.c:1938 subscript.c:2122 #, c-format msgid "%s too dense for %s; would have more than %s nonzero entries" msgstr "" #: subscript.c:2209 #, c-format msgid "NA subscripts in %s not supported for '%s' inheriting from %s" msgstr "" #: t_Csparse_subassign.c:142 msgid "invalid class of 'x' in Csparse_subassign()" msgstr "" #: t_Csparse_subassign.c:144 msgid "invalid class of 'value' in Csparse_subassign()" msgstr "" #: t_Csparse_subassign.c:187 #, c-format msgid "x[] <- val: val is coerced to logical for \"%s\" x" msgstr "" #: t_Csparse_subassign.c:192 #, c-format msgid "" "x[] <- val: val should be integer or logical, is coerced to integer, for " "\"%s\" x" msgstr "" #: t_Csparse_subassign.c:199 msgid "programming error in Csparse_subassign() should never happen" msgstr "" #: utils-R.c:30 utils-R.c:116 #, c-format msgid "indices would exceed %s" msgstr "" #: utils-R.c:235 utils-R.c:270 utils-R.c:281 utils-R.c:312 msgid "Argument must be numeric-like atomic vector" msgstr "" #: utils-R.c:345 msgid "'data' must be of a vector type" msgstr "" #: utils-R.c:352 #, c-format msgid "invalid '%s' argument" msgstr "" #: utils-R.c:359 utils-R.c:367 msgid "non-numeric matrix extent" msgstr "" #: utils-R.c:362 msgid "invalid 'nrow' value (too large or NA)" msgstr "" #: utils-R.c:364 msgid "invalid 'nrow' value (< 0)" msgstr "" #: utils-R.c:370 msgid "invalid 'ncol' value (too large or NA)" msgstr "" #: utils-R.c:372 msgid "invalid 'ncol' value (< 0)" msgstr "" #: utils-R.c:390 #, c-format msgid "" "data length [%d] is not a sub-multiple or multiple of the number of rows [%d]" msgstr "" #: utils-R.c:395 #, c-format msgid "" "data length [%d] is not a sub-multiple or multiple of the number of columns " "[%d]" msgstr "" #: utils-R.c:399 msgid "data length exceeds size of matrix" msgstr "" #: utils-R.c:404 msgid "too many elements specified" msgstr "" #: utils-R.c:545 msgid "Argument ij must be 2-column integer matrix" msgstr "" #: utils-R.c:570 msgid "subscript 'i' out of bounds in M[ij]" msgstr "" #: utils-R.c:572 msgid "subscript 'j' out of bounds in M[ij]" msgstr "" #: utils-R.c:626 msgid "i and j must be integer vectors of the same length" msgstr "" #: validity.c:40 validity.c:73 validity.c:264 validity.c:283 validity.c:292 #: validity.c:311 validity.c:337 validity.c:1010 validity.c:1452 #: validity.c:1476 #, c-format msgid "'%s' slot does not have length %d" msgstr "" #: validity.c:45 validity.c:965 validity.c:998 #, c-format msgid "'%s' slot has negative elements" msgstr "" #: validity.c:71 validity.c:197 #, c-format msgid "'%s' slot is not a list" msgstr "" #: validity.c:89 #, c-format msgid "%s[[%d]] is not NULL or a vector" msgstr "" #: validity.c:92 #, c-format msgid "length of %s[[%d]] (%lld) is not equal to %s[%d] (%d)" msgstr "" #: validity.c:203 #, c-format msgid "'%s' slot has no '%s' attribute" msgstr "" #: validity.c:214 validity.c:277 validity.c:305 validity.c:376 validity.c:1115 #: validity.c:1446 validity.c:1807 #, c-format msgid "%s[1] != %s[2] (matrix is not square)" msgstr "" #: validity.c:239 validity.c:252 #, c-format msgid "%s[1] differs from %s[2]" msgstr "" #: validity.c:267 validity.c:286 validity.c:295 validity.c:314 #, c-format msgid "'%s' slot is not \"%s\" or \"%s\"" msgstr "" #: validity.c:320 validity.c:324 #, c-format msgid "'%s' slot is \"%s\" but '%s' slot does not have length %s" msgstr "" #: validity.c:340 #, c-format msgid "'%s' slot is not %d or %d" msgstr "" #: validity.c:346 validity.c:349 #, c-format msgid "%s-by-%s %s invalid for positive '%s' when %s=%d" msgstr "" #: validity.c:386 validity.c:1178 validity.c:1190 validity.c:1291 #: validity.c:1303 validity.c:1383 validity.c:1432 validity.c:1491 #, c-format msgid "'%s' slot contains duplicates" msgstr "" #: validity.c:437 validity.c:1613 #, c-format msgid "'%s' slot is not increasing within columns" msgstr "" #: validity.c:488 #, c-format msgid "'%s' slot is not increasing within rows" msgstr "" #: validity.c:512 validity.c:801 validity.c:827 validity.c:853 validity.c:1076 #: validity.c:1682 validity.c:1684 #, c-format msgid "'%s' and '%s' slots do not have equal length" msgstr "" #: validity.c:515 #, c-format msgid "'%s' slot has nonzero length but %s is 0" msgstr "" #: validity.c:555 validity.c:600 validity.c:646 validity.c:691 validity.c:735 #: validity.c:770 #, c-format msgid "%s=\"%s\" but there are entries below the diagonal" msgstr "" #: validity.c:565 validity.c:613 validity.c:656 validity.c:704 validity.c:740 #: validity.c:781 #, c-format msgid "%s=\"%s\" but there are entries above the diagonal" msgstr "" #: validity.c:603 validity.c:616 validity.c:694 validity.c:707 validity.c:773 #: validity.c:784 #, c-format msgid "%s=\"%s\" but there are entries on the diagonal" msgstr "" #: validity.c:911 validity.c:935 validity.c:939 msgid "matrix has negative diagonal elements" msgstr "" #: validity.c:955 validity.c:983 validity.c:987 msgid "matrix has nonunit diagonal elements" msgstr "" #: validity.c:1007 validity.c:1032 validity.c:1826 #, c-format msgid "'%s' slot is not of type \"%s\" or \"%s\"" msgstr "" #: validity.c:1015 validity.c:1022 #, c-format msgid "'%s' slot is NA" msgstr "" #: validity.c:1017 validity.c:1024 #, c-format msgid "'%s' slot is negative" msgstr "" #: validity.c:1026 #, c-format msgid "'%s' slot exceeds %s" msgstr "" #: validity.c:1036 #, c-format msgid "'%s' slot has length greater than '%s' slot" msgstr "" #: validity.c:1046 validity.c:1674 validity.c:1696 validity.c:1698 #, c-format msgid "'%s' slot is not increasing" msgstr "" #: validity.c:1056 #, c-format msgid "'%s' slot has elements not in {%s} after truncation towards zero" msgstr "" #: validity.c:1059 #, c-format msgid "'%s' slot is not increasing after truncation towards zero" msgstr "" #: validity.c:1125 validity.c:1152 validity.c:1814 validity.c:1821 #, c-format msgid "dimensions of '%s' slot are not identical to '%s'" msgstr "" #: validity.c:1127 #, c-format msgid "'%s' slot is upper (not lower) triangular" msgstr "" #: validity.c:1140 #, c-format msgid "'%s' slot has nonunit diagonal elements" msgstr "" #: validity.c:1154 #, c-format msgid "'%s' slot is lower (not upper) triangular" msgstr "" #: validity.c:1166 validity.c:1279 validity.c:1370 validity.c:1419 #, c-format msgid "'%s' slot does not have length %s or length %s" msgstr "" #: validity.c:1206 msgid "matrix has more columns than rows" msgstr "" #: validity.c:1226 #, c-format msgid "'%s' slot has fewer than %s rows" msgstr "" #: validity.c:1228 #, c-format msgid "'%s' slot has more than %s rows" msgstr "" #: validity.c:1230 validity.c:1252 #, c-format msgid "'%s' slot does not have %s columns" msgstr "" #: validity.c:1237 #, c-format msgid "'%s' slot must be lower trapezoidal but has entries above the diagonal" msgstr "" #: validity.c:1250 #, c-format msgid "'%s' slot does not have %s row" msgstr "" #: validity.c:1259 #, c-format msgid "'%s' slot must be upper trapezoidal but has entries below the diagonal" msgstr "" #: validity.c:1263 #, c-format msgid "'%s' slot has negative diagonal elements" msgstr "" #: validity.c:1329 #, c-format msgid "'%s' slot has elements not in {%s}\\{%s}" msgstr "" #: validity.c:1338 #, c-format msgid "'%s' slot has unpaired negative elements" msgstr "" #: validity.c:1364 validity.c:1408 validity.c:1412 validity.c:1760 #: validity.c:1792 msgid "Cholesky factor has negative diagonal elements" msgstr "" #: validity.c:1455 #, c-format msgid "%s[%d] (%s) is not in %s" msgstr "" #: validity.c:1468 validity.c:1569 #, c-format msgid "%s is not in {%s}" msgstr "" #: validity.c:1505 #, c-format msgid "%s is not representable as \"%s\"" msgstr "" #: validity.c:1510 validity.c:1516 #, c-format msgid "%s[%d] (%s) is not %d or %d" msgstr "" #: validity.c:1513 validity.c:1629 validity.c:1632 validity.c:1635 #, c-format msgid "%s[%d] (%s) is not %d" msgstr "" #: validity.c:1538 #, c-format msgid "%s has elements not in {%s}" msgstr "" #: validity.c:1541 #, c-format msgid "%s has elements not in {%s}\\{%s}" msgstr "" #: validity.c:1544 #, c-format msgid "%s is %d but columns are not stored in increasing order" msgstr "" #: validity.c:1547 validity.c:1550 #, c-format msgid "traversal of '%s' slot does not complete in exactly %s steps" msgstr "" #: validity.c:1556 validity.c:1558 #, c-format msgid "%s is not %d" msgstr "" #: validity.c:1579 #, c-format msgid "column '%s' is stored first but %s is not 0" msgstr "" #: validity.c:1585 #, c-format msgid "'%s' slot is not increasing when traversed in stored column order" msgstr "" #: validity.c:1587 #, c-format msgid "'%s' slot allocates fewer than %s elements for column '%s'" msgstr "" #: validity.c:1590 #, c-format msgid "'%s' slot allocates more than %s elements for column '%s'" msgstr "" #: validity.c:1604 #, c-format msgid "first entry in column '%s' does not have row index '%s'" msgstr "" #: validity.c:1638 validity.c:1641 #, c-format msgid "%s[%d] (%s) is negative" msgstr "" #: validity.c:1644 #, c-format msgid "%s[%d] (%s) is not less than %s" msgstr "" #: validity.c:1662 #, c-format msgid "'%s' slot has length less than %d" msgstr "" #: validity.c:1664 #, c-format msgid "'%s' slot has length greater than %s" msgstr "" #: validity.c:1669 #, c-format msgid "last element of '%s' slot is not %s" msgstr "" #: validity.c:1702 #, c-format msgid "first differences of '%s' slot are less than those of '%s' slot" msgstr "" #: validity.c:1705 #, c-format msgid "supernode lengths exceed %s" msgstr "" #: validity.c:1707 #, c-format msgid "first differences of '%s' slot are not equal to supernode lengths" msgstr "" #: validity.c:1727 #, c-format msgid "" "'%s' slot is wrong within diagonal blocks (row and column indices do not " "coincide)" msgstr "" #: validity.c:1730 #, c-format msgid "'%s' slot is not increasing within supernodes" msgstr "" #: validity.c:1845 #, c-format msgid "invalid class \"%s\" object: %s" msgstr "" Matrix/po/R-ko.po0000644000176200001440000013401414521047060013306 0ustar liggesusers# Korean translations for Matrix package. # Recommended/Matrix/po/R-ko.po # # Thanks to Martin Maechler # # This file is distributed under the same license as the R Matrix package. # Maintained by Chel Hee Lee , 2013-2015. # # Notes: # Freezing on 15-JUL-2015 for R-3.3.0, QC: PASS # Freezing on 30-MAR-2015 for R-3.2.0, QC: PASS # Freezing on 28-FEB-2015 for R-3.1.3, QC: PASS # msgid "" msgstr "" "Project-Id-Version: Matrix 1.1-3\n" "POT-Creation-Date: 2023-11-02 21:33\n" "PO-Revision-Date: 2015-07-15 17:14-0600\n" "Last-Translator:Chel Hee Lee \n" "Language-Team: Chel Hee Lee \n" "Language: ko\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" #, fuzzy msgid "invalid mode \"%s\"" msgstr "사용할 수 있는 'mod'(%s)가 아닙니다." msgid "" "%s(<%s>, <%s>) is not yet implemented; ask maintainer(\"%s\") to implement " "the missing method" msgstr "" #, fuzzy msgid "complex %s not yet implemented" msgstr "클래스 %s는 아직 구현되지 않았습니다." #, fuzzy msgid "cannot coerce matrix of type \"%s\" to %s" msgstr "'NA'를 \"nsparseMatrix\"으로 강제변환(coerce)할 수 없습니다." #, fuzzy msgid "non0.i() not yet implemented for class %s" msgstr "클래스 %s의 경우에 아직 구현되지 않았습니다." msgid "%s=\"%s\" invalid for %s@uplo=\"%s\"" msgstr "" msgid "'%s' is not \"%1$s\", \"D%1$s\", or \"%1$s.\"" msgstr "" msgid "unexpected %s=\"%s\" in '%s' method" msgstr "" msgid "Not a valid format" msgstr "올바른 형식(format)이 아닙니다." msgid "'file' must be a character string or connection" msgstr "" "'file'은 반드시 문자열(character string) 또는 커넥션(connection)이어야 합니" "다." msgid "Invalid storage type: %s" msgstr "%s는 사용할 수 없는 저장형식(storage format)입니다." msgid "Only numeric sparse matrices allowed" msgstr "오로지 수치형 희소행렬(sparse matrices)만을 사용할 수 있습니다." msgid "Invalid storage format: %s" msgstr "%s는 사용할 수 있는 저장형식(storage format)이 아닙니다." msgid "Invalid assembled indicator: %s" msgstr "Invalid assembled indicator: %s" msgid "file is not a MatrixMarket file" msgstr "file에 MatrixMarket 형식의 파일이 입력되지 않았습니다." msgid "type '%s' not recognized" msgstr "'%s'는 사용가능한 유형(type)이 아닙니다." msgid "representation '%s' not recognized" msgstr "'%s'는 사용가능한 표현(representation)이 아닙니다." msgid "element type '%s' not recognized" msgstr "'%s'는 사용가능한 원소유형(element type)이 아닙니다." msgid "symmetry form '%s' not recognized" msgstr "'%s'는 사용가능한 대칭형식(symmetry form)이 아닙니다." msgid "readMM(): expected %d entries but found only %d" msgstr "" #, fuzzy msgid "readMM(): row indices 'i' are not in 1:nrow[=%d]" msgstr "readMM(): 행(row) 'i'는 1:nr 내에 존재하지 않습니다." #, fuzzy msgid "readMM(): column indices 'j' are not in 1:ncol[=%d]" msgstr "readMM(): 열(column) 'j'는 1:nc 내에 존재하지 않습니다." msgid "symmetry form 'skew-symmetric' not yet implemented for reading" msgstr "" "대칭형식(symmetry form)이 'skew-symmetric'인 경우에는 아직 구현되지 않았습니" "다." msgid "symmetry form 'hermitian' not yet implemented for reading" msgstr "" "대칭형식(symmetry form)이 'hermitian'의 경우에는 아직 구현되지 않았습니다." msgid "symmetry form '%s' is not yet implemented" msgstr "대칭형식(symmetry form)이 '%s'인 경우에는 아직 구현되지 않았습니다." msgid "element type 'complex' not yet implemented" msgstr "" "원소유형(element type)이 'complex'인 경우에는 아직 구현되지 않았습니다." msgid "'%s()' is not yet implemented for element type '%s'" msgstr "" "원소유형(element type)이 '%2$s'의 경우에 아직 구현되지 않은 '%1$s()'입니다." msgid "'%s()' is not yet implemented for representation '%s'" msgstr "" "표현(representation)이 '%2$s'의 경우에 아직 구현되지 않은 '%1$s()'입니다." msgid "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%3$s\", or \"%4$s\"" msgstr "" msgid "" "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%2$s2\", \"%2$s2.\", \"%3$s\", or " "\"%4$s\"" msgstr "" msgid "longer object length is not a multiple of shorter object length" msgstr "객체의 길이(긴 것)이 다른 객체의 길이(짧은 것)의 배수가 아닙니다." #, fuzzy msgid "invalid class \"%s\" in '%s' method" msgstr "%s은 올바른 'col.names' 문자열이 아닙니다" msgid "invalid type \"%s\" in '%s' method" msgstr "" msgid "non-conformable matrix dimensions in %s" msgstr "%s에 입력된 행렬의 차원이 정합(conformable)하지 않습니다." msgid "dimnames [%d] mismatch in %s" msgstr "%2$s에 입력된 dimnames [%1$d]가 일치하지 않습니다." msgid "inefficient method used for \"- e1\"" msgstr "\"- e1\"를 사용하는데 비효율적인 메소드(method)입니다." msgid "dim [product %d] do not match the length of object [%d]" msgstr "dim [product %d]의 값이 객체 [%d]의 길이와 일치하지 않습니다." msgid "internal bug in \"Compare\" method (Cmp.Mat.atomic); please report" msgstr "" "메소드 \"Compare\" (Cmp.Mat.atomic)내에서 버그(internal bug)가 발생했습니다. " "이를 꼭 보고해 주셨으면 합니다." msgid "Cmp.Mat.atomic() should not be called for diagonalMatrix" msgstr "Cmp.Mat.atomic()은 digonalMatrix에 의하여 호출될 수 없습니다." msgid "Matrices must have same number of rows for arithmetic" msgstr "" "원소단위의 연산을 수행하기 위해서는 입력된 각 행렬이 가지는 열의 개수가 서로 " "같아야 합니다." msgid "number of rows are not compatible for %s" msgstr "%s의 경우 행의 개수가 올바르지 않습니다." msgid "length of 2nd arg does not match dimension of first" msgstr "" "두번째 인자(arg)의 길이가 첫번째 인자의 차원(dimension)과 일치하지 않습니다." msgid "length of 1st arg does not match dimension of 2nd" msgstr "" "첫번째 인자(arg)의 길이는 두번째 인자의 차원(dimension)과 일치하지 않습니다." msgid "internal bug in \"Logic\" method (Logic.Mat.atomic); please report" msgstr "" "메소드 \"Logic\" (Logic.Mat.atomic)내에서 버그가 발생되었습니다. 이를 꼭 보" "고해 주셨으면 합니다." msgid "Logic.Mat.atomic() should not be called for diagonalMatrix" msgstr "Logic.Mat.atomic()은 diagonalMatrix에 호출될 수 없습니다." msgid "vector too long in Matrix - vector operation" msgstr "" "행렬과 벡터 연산(Matrix - vector operation)에 사용될 벡터의 길이가 너무 깁니" "다." msgid "" "longer object length\n" "\tis not a multiple of shorter object length" msgstr "" "객체의 길이(긴 것)가\n" "\t 다른 객체가 가지는 길이(짧은 것)의 배수가 아닙니다." msgid "intermediate 'r' is of type %s" msgstr "intermediate 'r' is of type %s" msgid "not yet implemented .. please report" msgstr "아직 구현되지 않았습니다. 보고를 부탁드립니다." msgid "'force' must be (coercable to) TRUE or FALSE" msgstr "'force'는 반드시 (강제변환될 수 있는) TRUE 또는 FALSE 이어야 합니다." msgid "invalid (to - from)/by in seq(.)" msgstr "seq(.)의 사용시 (to - from)/by의 값이 올바르지 않습니다." msgid "wrong sign in 'by' argument" msgstr "'by' 인자에 사용된 부호(sign)가 올바르지 않습니다." msgid "'by' argument is much too small" msgstr "'by' 인자에 사용된 값이 너무 작습니다." msgid "length must be non-negative number" msgstr "길이(length)는 반드시 음이 아닌 수이어야 합니다." msgid "too many arguments" msgstr "입력된 인자의 개수가 너무 많습니다." msgid "c(,..) of different kinds, coercing all to 'rleDiff'" msgstr "c(,..) of different kinds, 모두 'rleDiff'로 강제변환합니다" msgid "[i] is not yet implemented" msgstr "[i]는 아직 구현되지 않았습니다." msgid "all() is not yet implemented" msgstr "all()는 아직 구현되지 않았습니다." msgid "sum() is not yet implemented" msgstr "sum()는 아직 구현되지 않았습니다." msgid "prod() is not yet implemented" msgstr "prod()는 아직 구현되지 않았습니다." msgid "not yet implemented" msgstr "아직 구현되지 않았습니다." msgid "" "x / 0 for an x with sign-change\n" " no longer representable as 'rleDiff'" msgstr "" "x / 0 for an x with sign-change\n" " no longer representable as 'rleDiff'" msgid " --> is not yet implemented" msgstr " --> 은 아직 구현되지 않았습니다." msgid " --> is not yet implemented" msgstr " --> 은 아직 구현되지 않았습니다." #, fuzzy msgid "%1$s(%2$s) is undefined: '%2$s' is not positive semidefinite" msgstr "chol()은 음의 값을 가진 대각행렬에 대하여 정의되지 않았습니다." #, fuzzy msgid "matrix is not square" msgstr "대각행렬이 아닙니다." msgid "" "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%3$s\", \"%3$s.\", \"%3$s1\", \"%3$s1." "\", or \"%4$s\"" msgstr "" #, fuzzy msgid "'%s' does not inherit from virtual class %s" msgstr "'x'는 \"sparseVector\"로부터의 상속(inherit)이어야 합니다." msgid "D[i,i] is NA, i=%d" msgstr "" msgid "D[i,i] is negative, i=%d" msgstr "" msgid "'%1$s' is not formally symmetric; factorizing tcrossprod(%1$s)" msgstr "" #, fuzzy msgid "matrix is not symmetric; consider forceSymmetric(.) or symmpart(.)" msgstr "" "대칭행렬(symmetric matrix)가 아닙니다. forceSymmtric() 또는 symmpart() 함수" "의 사용을 고려해 보시길 바랍니다." #, fuzzy msgid "matrix is not triangular; consider triu(.) or tril(.)" msgstr "삼각행렬이 아닙니다." msgid "matrix is not diagonal; consider Diagonal(x=diag(.))" msgstr "" #, fuzzy msgid "invalid type \"%s\" in '%s'" msgstr "올바르지 않은 'type'입니다." #, fuzzy msgid "invalid %s=\"%s\" to '%s'" msgstr "%s는 사용할 수 없는 저장형식(storage format)입니다." msgid "dimensions cannot exceed %s" msgstr "" #, fuzzy msgid "invalid class \"%s\" in '%s'" msgstr "%s은 올바른 'col.names' 문자열이 아닙니다" msgid "%s length cannot exceed %s" msgstr "" msgid "'A' must be a square matrix" msgstr "'A'는 반드시 정방행렬(square matrix)이어야 합니다." msgid "must either specify 'A' or the functions 'A.x' and 'At.x'" msgstr "'A' 또는 'A.x'와 'At.x'는 반드시 주어져야 합니다." msgid "when 'A' is specified, 'A.x' and 'At.x' are disregarded" msgstr "'A'가 주어진 경우에 입력된 'A.x'와 'At.x'는 사용되지 않습니다." msgid "not converged in %d iterations" msgstr "%d번째 반복에서도 수렴하지 않습니다." msgid "hit a cycle (1) -- stop iterations" msgstr "cycle (1)에 도달했습니다 -- 반복을 중지합니다" msgid "hit a cycle (2) -- stop iterations" msgstr "cycle (2)에 도달했습니다 -- 반복을 중지합니다" msgid "not enough new vecs -- stop iterations" msgstr "not enough new vecs -- stop iterations" msgid "invalid 'data'" msgstr "입력된 'data'는 올바르지 않습니다." #, fuzzy msgid "'nrow', 'ncol', 'byrow' disregarded for [mM]atrix 'data'" msgstr "행렬 'data'인 경우에 입력된 'nrow', 'ncol' 등은 사용되지 않습니다." msgid "data is too long" msgstr "" #, fuzzy msgid "exactly one of 'i', 'j', and 'p' must be missing from call" msgstr "'i', 'j', 또는 'p' 중 하나가 호출(call)로부터 누락된 것 같습니다. " msgid "" "use Diagonal() to construct diagonal (symmetric && triangular) sparse " "matrices" msgstr "" msgid "'giveCsparse' is deprecated; using 'repr' instead" msgstr "" msgid "'giveCsparse' is deprecated; setting repr=\"T\" for you" msgstr "" #, fuzzy msgid "'p' must be a nondecreasing vector c(0, ...)" msgstr "'p'는 반드시 감소하지 않는(non-decreasing) 벡터 (0, ...)이어야 합니다." msgid "dimensions cannot exceed 2^31-1" msgstr "" msgid "'i' and 'j' must not contain NA" msgstr "" msgid "'i' and 'j' must be" msgstr "" msgid "positive" msgstr "" msgid "non-negative" msgstr "" #, fuzzy msgid "invalid 'dims'" msgstr "입력된 'data'는 올바르지 않습니다." msgid "'dims' must contain all (i,j) pairs" msgstr "" msgid "symmetric matrix must be square" msgstr "대칭행렬(symmetric matrix)는 반드시 정방(square)이어야 합니다." #, fuzzy msgid "triangular matrix must be square" msgstr "대칭행렬(symmetric matrix)는 반드시 정방(square)이어야 합니다." msgid "p[length(p)]" msgstr "" msgid "length(i)" msgstr "" #, fuzzy msgid "is not an integer multiple of length(x)" msgstr "length(i)는 length(x)의 배수가 아닙니다." msgid "length(x) must not exceed" msgstr "" msgid "invalid 'repr'; must be \"C\", \"R\", or \"T\"" msgstr "" #, fuzzy msgid "'n' must be a non-negative integer" msgstr "길이(length)는 반드시 음이 아닌 수이어야 합니다." msgid "'x' has unsupported class \"%s\"" msgstr "" msgid "'x' has unsupported type \"%s\"" msgstr "" msgid "attempt to recycle 'x' of length 0 to length 'n' (n > 0)" msgstr "" msgid "'shape' must be one of \"g\", \"t\", \"s\"" msgstr "" msgid "'kind' must be one of \"d\", \"l\", \"n\"" msgstr "" msgid "mismatch between typeof(x)=\"%s\" and kind=\"%s\"; using kind=\"%s\"" msgstr "" #, fuzzy msgid "'cols' must be numeric" msgstr "'ncol'은 반드시 >= 0 이어야 합니다. " msgid "'cols' has elements not in seq(0, length.out = n)" msgstr "" msgid "'uplo' must be \"U\" or \"L\"" msgstr "" #, fuzzy msgid "'lst' must be a list" msgstr "'ncol'은 반드시 >= 0 이어야 합니다. " msgid "'giveCsparse' has been deprecated; setting 'repr = \"T\"' for you" msgstr "" msgid "'giveCsparse' has been deprecated; will use 'repr' instead" msgstr "" msgid "'diagonals' matrix must have %d columns (= length(k) )" msgstr "" "'diagonals' 행렬은 반드시 %d (=length(k))개의 열을 가지고 있어야 합니다." msgid "'diagonals' must have the same length (%d) as 'k'" msgstr "'diagnoals'의 길이는 반드시 'k'(=%d)이어야 합니다." msgid "matrix can only be symmetric if square, but n != m" msgstr "" msgid "" "for symmetric band matrix, only specify upper or lower triangle\n" " hence, all k must have the same sign" msgstr "" "대칭 띠 행렬(symmetric band matrix)의 경우, 오로지 상삼각(upper triangle) 또" "는 하삼각(lower)만을 지정합니다. \n" " 따라서, 모든 k는 반드시 같은 부호(sign)를 가져야 합니다." msgid "the %d-th (sub)-diagonal (k = %d) is too short; filling with NA's" msgstr "%d-번째 (부분)-대각 (k = %d)이 너무 짧아 NA로 채웁니다." msgid "invalid 'repr'; must be \"C\", \"T\", or \"R\"" msgstr "" msgid "'x' must inherit from \"sparseVector\"" msgstr "'x'는 \"sparseVector\"로부터의 상속(inherit)이어야 합니다." msgid "'ncol' must be >= 0" msgstr "'ncol'은 반드시 >= 0 이어야 합니다. " msgid "'nrow' must be >= 0" msgstr "'nrow'는 반드시 >= 0 이어야 합니다." msgid "Must specify 'nrow' when 'symmetric' is true" msgstr "'symmetric'이 참인 경우에는 반드시 'nrow'를 지정해 주어야 합니다." msgid "'nrow' and 'ncol' must be the same when 'symmetric' is true" msgstr "" "'symmetric'이 참인 경우에는 반드시 'nrow'와 'ncol'을 지정해 주어야 합니다." msgid "'x' must have length nrow^2 when 'symmetric' is true" msgstr "" "'symmetric'이 참인 경우에는 'x'의 길이는 반드시 nrow^2와 같아야 합니다." msgid "'ncol' is not a factor of length(x)" msgstr "'ncol'는 길이가 length(x)인 요인(factor)가 아닙니다." msgid "'nrow' is not a factor of length(x)" msgstr "'nrow'는 길이가 length(x)인 요인(factor)가 아닙니다." msgid "Class %s is not yet implemented" msgstr "클래스 %s는 아직 구현되지 않았습니다." #, fuzzy msgid "'%s' and '%s' must be positive integers" msgstr "길이(length)는 반드시 음이 아닌 수이어야 합니다." #, fuzzy msgid "matrix is not symmetric or triangular" msgstr "'x'는 대칭(symmetric)도 아니고 삼각(triangular)도 아닙니다." #, fuzzy msgid "matrix is not symmetric" msgstr "삼각행렬이 아닙니다." #, fuzzy msgid "matrix is not triangular" msgstr "'x'는 대칭(symmetric)도 아니고 삼각(triangular)도 아닙니다." msgid "" "the default value of argument '%s' of method '%s(<%s>, <%s>)' may change " "from %s to %s as soon as the next release of Matrix; set '%s' when " "programming" msgstr "" msgid "determinant of non-square matrix is undefined" msgstr "" msgid "replacement diagonal has wrong length" msgstr "" msgid "replacement diagonal has incompatible type \"%s\"" msgstr "" msgid "assigned dimensions are not of type \"%s\" or \"%s\"" msgstr "" msgid "assigned dimensions do not have length %d" msgstr "" msgid "assigned dimensions are NA" msgstr "" msgid "assigned dimensions are negative" msgstr "" msgid "assigned dimensions exceed %s" msgstr "" #, fuzzy msgid "assigned dimensions [product %.0f] do not match object length [%.0f]" msgstr "dim [product %d]의 값이 객체 [%d]의 길이와 일치하지 않습니다." msgid "'%s' has non-finite values" msgstr "" msgid "'%1$s' is not \"%2$s\", \"%3$s\", or \"%2$s.\"" msgstr "" #, fuzzy msgid "only square matrices can be used as graph incidence matrices" msgstr "" "오로지 정방(square) 행렬만이 그래프를 위한 접속행렬(incidence matrices)로서 " "사용할 수 있습니다." msgid "'lwd' must be NULL or non-negative numeric" msgstr "'lwd'는 반드시 NULL 또는 음이 아닌 수 이어야 합니다." #, fuzzy msgid "%s(<%s>) is not yet implemented" msgstr "클래스 %s는 아직 구현되지 않았습니다." msgid "'%s' is not of type \"%s\" or \"%s\"" msgstr "" msgid "'%s' contains NA" msgstr "" msgid "'%s' has elements less than %d" msgstr "" #, fuzzy msgid "'%s' is not a non-negative number" msgstr "길이(length)는 반드시 음이 아닌 수이어야 합니다." msgid "'%s' has elements exceeding '%s'" msgstr "" msgid "'%s' is not %d or %d" msgstr "" #, fuzzy msgid "'%s' is not a permutation of seq_len(%s)" msgstr "'ncol'는 길이가 length(x)인 요인(factor)가 아닙니다." #, fuzzy msgid "matrix must have exactly one entry in each row or column" msgstr "각 행마다 반드시 정확히 하나의 영이 아닌 항목을 가지고 있어야 합니다." #, fuzzy msgid "attempt to coerce non-square matrix to %s" msgstr "" "비대칭(non-symmetric) \"dgTMatrix\"는 \"dsCMatrix\" 클래스로 강제변환" "(coerce) 할 수 없습니다. " #, fuzzy msgid "matrix must have exactly one entry in each row and column" msgstr "각 행마다 반드시 정확히 하나의 영이 아닌 항목을 가지고 있어야 합니다." #, fuzzy msgid "'%s' via sparse -> dense coercion" msgstr "rcond(.) via sparse -> dense coercion" #, fuzzy msgid "invalid %s=\"%s\"" msgstr "nargs()= %d의 값이 올바르지 않습니다." msgid "norm" msgstr "" #, fuzzy msgid "'%s' method must use default %s=\"%s\"" msgstr "" "크로넥커 메소드(kronecker method)는 반드시 기본 'FUN'을 사용해야 합니다." #, fuzzy msgid "number of nonzero entries cannot exceed %s" msgstr "%s의 경우 행의 개수가 올바르지 않습니다." msgid "Matrix seems negative semi-definite" msgstr "음의 반정치(negative semi-definite) 행렬 같습니다." msgid "'nearPD()' did not converge in %d iterations" msgstr "'nearPD()'는 %d 번째 반복에서도 수렴하지 않았습니다." #, fuzzy msgid "'cl' is not a character string" msgstr "'V'는 정방행렬(square matrix)이 아닙니다." msgid "" "not a positive definite matrix (and positive semidefiniteness is not checked)" msgstr "" #, fuzzy msgid "'%s' is not a square numeric matrix" msgstr "'V'는 정방행렬(square matrix)이 아닙니다." #, fuzzy msgid "" "diag(%s) has non-positive or non-finite entries; finite result is doubtful" msgstr "" "diag(.)에 0 또는 NA가 존재하므로 유한하지 않은 결과(non-finite result)를 얻" "을 것으로 생각됩니다." msgid "non-conformable arguments" msgstr "non-conformable arguments" msgid "" "matrix is structurally rank deficient; using augmented matrix with " "additional %d row(s) of zeros" msgstr "" msgid "" "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%2$s2\", \"%2$s2.\", \"%3$s\", " "\"%3$s1\", \"%4$s\", or \"%4$s1\"" msgstr "" #, fuzzy msgid "'%s' has the wrong length" msgstr "우변의 'b'가 올바르지 않은 길이(length)를 가지고 있습니다." #, fuzzy msgid "invalid '%s': not in %d:%d" msgstr "%s은 올바른 'col.names' 문자열이 아닙니다" msgid "need greater '%s' as pivoting occurred" msgstr "" msgid "qr2rankMatrix(.): QR with only %d out of %d finite diag(R) entries" msgstr "" msgid "" "rankMatrix(, method = '%s') coerces to dense matrix.\n" " Probably should rather use method = 'qr' !?" msgstr "" msgid "rankMatrix(x, method='qr'): computing t(x) as nrow(x) < ncol(x)" msgstr "rankMatrix(x, method='qr'): nrow(x) < ncol(x)이므로 t(x)를 계산합니다." #, fuzzy msgid "[[ suppressing %d column name%s %s ... ]]" msgstr "[[ %d개의 열이름 %s ...를 제거합니다 ]]" msgid "invalid 'col.names' string: %s" msgstr "%s은 올바른 'col.names' 문자열이 아닙니다" msgid "uniDiag=TRUE, but not all diagonal entries are 1" msgstr "" msgid "uniDiag=TRUE, not all entries in diagonal coded as 1" msgstr "" msgid "in show(); maybe adjust options(max.print=, width=)" msgstr "" #, fuzzy msgid "suppressing %d columns and %d rows" msgstr "[[ %d개의 열이름 %s를 제거합니다 ]]" #, fuzzy msgid "suppressing %d rows" msgstr "[[ %d개의 열이름 %s를 제거합니다 ]]" #, fuzzy msgid "suppressing %d columns" msgstr "[[ %d개의 열이름 %s를 제거합니다 ]]" msgid "logic programming error in printSpMatrix2(), please report" msgstr "" "printSpMatrix2()를 이용 도중 논리적 프로그래밍 에러(logic programming error)" "가 발생했습니다. 이를 꼭 보고를 부탁드립니다." #, fuzzy msgid "'%s' is not square" msgstr "'V'는 정방행렬(square matrix)이 아닙니다." msgid "dimensions of '%s' and '%s' are inconsistent" msgstr "" msgid "'%1$s' is computationally singular, rcond(%1$s)=%2$g" msgstr "" msgid "'%s' is computationally singular, min(d)/max(d)=%g, d=abs(diag(U))" msgstr "" msgid "matrix is exactly singular, D[i,i]=0, i=%d" msgstr "" msgid "matrix is exactly singular, J[,j]=0, j=%d" msgstr "" msgid "matrix exactly singular, J[i,]=0, i=%d" msgstr "" msgid "cannot coerce from %s to %s" msgstr "" #, fuzzy msgid "model frame and formula mismatch in sparse.model.matrix()" msgstr "" "model.matrix()를 사용할 때 모델프레임(model frame)과 모델식(formula)가 일치하" "지 않습니다." #, fuzzy msgid "non-list contrasts argument ignored" msgstr "'contrasts.arg' 인자가 올바르지 않습니다." #, fuzzy msgid "'contrasts.arg' argument must be named" msgstr "'contrasts.arg' 인자가 올바르지 않습니다." msgid "variable '%s' is absent, its contrast will be ignored" msgstr "변수 '%s'를 찾을 수 없어 관련 대비(contrast)는 계산되지 않을 것입니다." msgid "a sparseMatrix should rarely be centered: will not be sparse anymore" msgstr "" #, fuzzy msgid "length of 'center' must equal the number of columns of 'x'" msgstr "%s에 사용된 각 행렬이 가지는 열의 개수는 서로 같아야 합니다." #, fuzzy msgid "length of 'scale' must equal the number of columns of 'x'" msgstr "%s에 사용된 각 행렬이 가지는 열의 개수는 서로 같아야 합니다." msgid "trimmed means are not defined for complex data" msgstr "" msgid "first element used of '%s' argument" msgstr "" #, fuzzy msgid "invalid '%s' argument" msgstr "입력된 'data'는 올바르지 않습니다." msgid "should never happen ..." msgstr "" msgid "'%s' is deprecated; using '%s' instead" msgstr "" msgid "'%s' is deprecated; setting %s=\"%s\"" msgstr "" msgid "" ".M.repl.i.2col(): 'i' has no integer column number;\n" " should never happen; please report" msgstr "" ".M.repl.i.2col(): 'i'는 정수형 행번호(integer column number)을 가지고 있지 않" "습니다.\n" " 이런 경우는 존재할 수 없으므로 패키지 관리자에게 보고해 주시길 부탁드립니다." msgid "such indexing must be by logical or 2-column numeric matrix" msgstr "" "이와 같은 유형의 인덱싱(indexing)은 반드시 논리형(logical) 또는 2개의 열로 구" "성된 수치형(numeric) 행렬에 의해서만 이루어져야 합니다." msgid ".M.repl.i.2col(): drop 'matrix' case ..." msgstr ".M.repl.i.2col(): drop 'matrix' case ..." msgid "negative values are not allowed in a matrix subscript" msgstr "음수(negative values)는 행렬의 첨자(subscript)로 사용할 수 없습니다." msgid "NAs are not allowed in subscripted assignments" msgstr "NA는 행렬의 첨자(subscripted assignment)로 사용할 수 없습니다." msgid "number of items to replace is not a multiple of replacement length" msgstr "" "교체(replace)할 항목의 개수가 입력된 value가 가지는 길이의 배수가 아닙니다." msgid "m[ ] <- v: inefficiently treating single elements" msgstr "m[ ] <- v: inefficiently treating single elements" msgid "nargs() = %d. Extraneous illegal arguments inside '[ .. ]' ?" msgstr "nargs() = %d. 필요이상의 인자들이 '[ .. ]' 내에 이용되었나요?" msgid "RHS 'value' (class %s) matches 'ANY', but must match matrix class %s" msgstr "" "클래스 %s를 가지는 우변의 'value'는 'ANY'에 매치되지만, 반드시 행렬의 클래스 " "%s에 매치되어야 합니다." msgid "not-yet-implemented 'Matrix[<-' method" msgstr "아직 구현되지 않은 'Matrix[<-' 메소드입(method)니다." msgid "invalid nargs()= %d" msgstr "nargs()= %d의 값이 올바르지 않습니다." msgid "nothing to replace with" msgstr "교체(replace)해야 할 것이 아무것도 없습니다." msgid "too many replacement values" msgstr "교체에 이용될 값이 너무 많이 입력되었습니다." msgid "i1[1] == 0 ==> C-level verbosity will not happen!" msgstr "i1[1] == 0 ==> C-레벨에서의 진행과정표시는 나타나지 않을 것입니다!" msgid "using\t \"old code\" part in Csparse subassignment" msgstr "using\t \"old code\" part in Csparse subassignment" msgid "" "using\"old code\" part in Csparse subassignment\n" " >>> please report to Matrix-authors@r-project.org" msgstr "" "using\"old code\" part in Csparse subassignment\n" " >>> Matrix-authors@r-project.org으로 이를 보고해 주시길 바랍니다." msgid "you cannot mix negative and positive indices" msgstr "인덱스에 음수와 양수를 혼용하여 사용할 수 없습니다." msgid "index larger than maximal %d" msgstr "인덱스가 %d 보다 큽니다." msgid "'NA' indices are not (yet?) supported for sparse Matrices" msgstr "'NA'는 sparse Matrices에 (아직은?) 사용할 수 없는 인덱스입니다" msgid "logical subscript too long (%d, should be %d)" msgstr "" "길이가 너무 긴 논리형 첨자(subscript)입니다 (%2$d이어야 하는데 %1$d입니다)." msgid "no 'dimnames[[.]]': cannot use character indexing" msgstr "no 'dimnames[[.]]': 문자형 인덱싱을 사용할 수 없습니다" msgid "invalid character indexing" msgstr "유효하지 않은 문자형 인덱싱입니다" msgid "internal bug: missing 'i' in replTmat(): please report" msgstr "" "내부버그 발견: replTmat()내에서 'i'를 찾을 수 없습니다. 이를 보고해 주시길 부" "탁드립니다." msgid "[ ] indexing not allowed: forgot a \",\" ?" msgstr "" "[ ]와 같은 인덱싱은 사용할 수 없습니다. \",\"의 사용을 잊었나요?" msgid "internal bug: matrix 'i' in replTmat(): please report" msgstr "" "내부버그 발견: replTmat()내에서 'i'는 행렬입니다. 이를 보고해 주시길 부탁드립" "니다." msgid "" "x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced; NA |--> TRUE." msgstr "" "x[.] <- val: x의 클래스는 %s입니다. {TRUE, FALSE}에 해당하지 않는 val의 값" "은 TRUE로 강제변환(coerced) 되었습니다." msgid "x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced." msgstr "" "x[.] <- val: x의 클래스는 %s입니다. {TRUE, FALSE}에 해당하지 않는 val의 값" "은 강제변환(coerced) 되었습니다." msgid "" "x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced NA |--> TRUE." msgstr "" "x[.,.] <- val: x의 클래스는 %s입니다. {TRUE, FALSE}에 해당하지 않는 val의 값" "은 TRUE로 강제변환(coerced) 되었습니다. " msgid "x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced." msgstr "" "x[.,.] <- val: x의 클래스는 %s입니다. {TRUE, FALSE}에 해당하지 않는 val의 값" "은 강제변환(coerced) 되었습니다. " msgid "x[.,.] <- val : x being coerced from Tsparse* to CsparseMatrix" msgstr "" "x[.,.] <- val : Tsparse* 에서 CsparseMatrix로 강제변환(coerced)된 x입니다." msgid "nargs() = %d should never happen; please report." msgstr "" "nargs() = %d 와 같은 경우는 발생할 수 없으므로 꼭 보고해 주시기를 부탁드립니" "다." msgid "row indices must be <= nrow(.) which is %d" msgstr "행에 사용되는 인덱스는 반드시 %d 보다 같거나 작아야 합니다." msgid "column indices must be <= ncol(.) which is %d" msgstr "열에 사용되는 인덱스는 %d 보다 같거나 작아야 합니다. " msgid "Internal bug: nargs()=%d; please report" msgstr "내부버그 발견: nargs()=%d. 꼭 보고를 부탁드립니다." msgid "" "index must be numeric, logical or sparseVector for indexing sparseVectors" msgstr "" "sparseVectors를 인덱싱하기 위해서는 인덱스는 반드시 수치형, 논리형 또는 " "sparseVectors이어야 합니다." #, fuzzy msgid "invalid subscript class \"%s\"" msgstr "%s는 사용가능한 클래스(class)가 아닙니다." #, fuzzy msgid "invalid subscript type \"%s\"" msgstr "%s는 사용할 수 없는 저장형식(storage format)입니다." msgid "recycled %s would have maximal index exceeding %s" msgstr "" msgid "subscripts exceeding %s replaced with NA" msgstr "" msgid "subscript out of bounds" msgstr "" #, fuzzy msgid "logical subscript too long" msgstr "" "길이가 너무 긴 논리형 첨자(subscript)입니다 (%2$d이어야 하는데 %1$d입니다)." #, fuzzy msgid "incorrect number of dimensions" msgstr "차원(dimensions) 정보가 일치하지 않습니다." msgid "only zeros may be mixed with negative subscripts" msgstr "" msgid "'%s' has length 0 but '%s' does not" msgstr "" #, fuzzy msgid "attempt to coerce matrix with NA to %s" msgstr "" "비대칭(non-symmetric) \"dgTMatrix\"는 \"dsCMatrix\" 클래스로 강제변환" "(coerce) 할 수 없습니다. " #, fuzzy msgid "invalid 'Class2'" msgstr "입력된 'data'는 올바르지 않습니다." #, fuzzy #~ msgid "invalid 'each' argument" #~ msgstr "'by' 인자에 사용된 부호(sign)가 올바르지 않습니다." #, fuzzy #~ msgid "invalid 'times' argument" #~ msgstr "입력된 'data'는 올바르지 않습니다." #~ msgid "" #~ "not-yet-implemented method for %s(<%s>).\n" #~ " ->> Ask the package authors to implement the missing feature." #~ msgstr "" #~ "%s(<%s>)의 경우에 대하여 아직 구현되지 않은 메소드(method)입니다.\n" #~ " ->> 이 기능에 대한 구현을 패키지 관리자에게 문의해 주셨으면 합니다." #~ msgid "" #~ "not-yet-implemented method for %s(<%s>, <%s>).\n" #~ " ->> Ask the package authors to implement the missing feature." #~ msgstr "" #~ "%s(<%s>, <%s>)의 경우에 대하여 아직 구현되지 않은 메소드(method)입니다.\n" #~ " ->> 이 기능에 대한 구현을 패키지 관리자에게 문의해 주시길 바랍니다." #, fuzzy #~ msgid "complex \"diagonalMatrix\" not yet implemented" #~ msgstr "%s의 경우에는 아직 구현되지 않은 일반적인 Matrix 클래스입니다." #, fuzzy #~ msgid "not yet implemented for class \"%s\"" #~ msgstr "클래스 %s의 경우에 아직 구현되지 않았습니다." #, fuzzy #~ msgid "invalid 'uplo'" #~ msgstr "올바르지 않은 'type'입니다." #~ msgid "'lag' and 'differences' must be integers >= 1" #~ msgstr "'lag'과 'differences'는 반드시 1보다 크거나 같은 정수이어야 합니다." #~ msgid "" #~ "programming error: min() should have dispatched w/ 1st arg much earlier" #~ msgstr "" #~ "programming error: min() should have dispatched w/ 1st arg much earlier" #~ msgid "in Summary(, .): %s(<%s>, <%s>,...)" #~ msgstr "in Summary(, .): %s(<%s>, <%s>,...)" #~ msgid "in Summary(, .): %s(<%s>, <%s>)" #~ msgstr "in Summary(, .): %s(<%s>, <%s>)" #, fuzzy #~ msgid "number of rows of matrices must match" #~ msgstr "%s의 경우 행의 개수가 올바르지 않습니다." #, fuzzy #~ msgid "number of columns of matrices must match" #~ msgstr "%s의 경우 행의 개수가 올바르지 않습니다." #, fuzzy #~ msgid "dimensions must be numeric of length 2" #~ msgstr "dim(.)의 값은 반드시 길이가 2인 수치형 벡터이어야 합니다." #, fuzzy #~ msgid "'perm' must be numeric" #~ msgstr "'A'는 반드시 정방행렬(square matrix)이어야 합니다." #, fuzzy #~ msgid "'margin' must be 1 or 2" #~ msgstr "'ncol'은 반드시 >= 0 이어야 합니다. " #~ msgid "not-yet-implemented method for <%s> %%*%% <%s>" #~ msgstr "<%s> %%*%% <%s>에 사용할 수 있는 메소드가 아직 구현되지 않았습니다." #, fuzzy #~ msgid "'boolArith = %d' not yet implemented" #~ msgstr "아직 구현되지 않은 종류 %s입니다." #, fuzzy #~ msgid "'rcond' via sparse -> dense coercion" #~ msgstr "rcond(.) via sparse -> dense coercion" #, fuzzy #~ msgid "invalid 'norm'" #~ msgstr "입력된 'data'는 올바르지 않습니다." #, fuzzy #~ msgid "cannot coerce zsparseVector to dgCMatrix" #~ msgstr "'NA'를 \"nsparseMatrix\"으로 강제변환(coerce)할 수 없습니다." #, fuzzy #~ msgid "cannot coerce zsparseVector to dgeMatrix" #~ msgstr "'NA'를 \"nsparseVector\"로 강제변환(coerce) 할 수 없습니다." #~ msgid "" #~ "number of non zeros is smaller than 'nnz' because of duplicated (i,j)s" #~ msgstr "" #~ "중복된 (i,j)에 위치한 값들 때문에 영이 아닌 요소의 개수가 'nnz' 보다 작습" #~ "니다." #~ msgid "'times >= 0' is required" #~ msgstr "'times >= 0'이 요구되어집니다." #~ msgid "Matrices must have same number of rows in %s" #~ msgstr "%s에 사용된 각 행렬이 가지는 행의 개수는 서로 같아야 합니다." #~ msgid "Matrices must have same number of columns in %s" #~ msgstr "%s에 사용된 각 행렬이 가지는 열의 개수는 서로 같아야 합니다." #, fuzzy #~ msgid "only lists of length 2 can be coerced to indMatrix" #~ msgstr "" #~ "NA를 가진 \"lMatrix\" 객체는 \"nMatrix\"로 강제변환(coerced) 될 수 없습니" #~ "다." #, fuzzy #~ msgid "only 2-dimensional tables can be coerced to sparseMatrix" #~ msgstr "" #~ "오로지 2차원 테이블만이 희소행렬(sparse matrice)로 강제변환(coerced)될 수 " #~ "있습니다." #, fuzzy #~ msgid "matrix is not symmetric or" #~ msgstr "'x'는 대칭(symmetric)도 아니고 삼각(triangular)도 아닙니다." #, fuzzy #~ msgid "triangular" #~ msgstr "삼각행렬(triangular matrix)가 아닙니다." #, fuzzy #~ msgid "matrix is not" #~ msgstr "대각행렬이 아닙니다." #~ msgid "'x' is not positive definite -- chol() undefined." #~ msgstr "" #~ "'x'는 양정치(positive definite) 행렬이 아니므로 chol()가 정의되어지지 않습" #~ "니다." #~ msgid "Matrices must have same dimensions in %s" #~ msgstr "" #~ "%s에 입력된 행렬들은 반드시 같은 차원(dimensions)을 가지고 있어야 합니다." #~ msgid "names(dimnames()) must be NULL or of length two" #~ msgstr "names(dimnames())의 길이는 2이거나 NULL이어야 합니다." #~ msgid "[[ suppressing %d column names %s ]]" #~ msgstr "[[ %d개의 열이름 %s를 제거합니다 ]]" #~ msgid "'x' must be \"sparseMatrix\"" #~ msgstr "'x'는 반드시 \"sparseMatrix\"이어야 합니다." #~ msgid "not yet implemented for matrix with typeof %s" #~ msgstr "" #~ "저장방식(typeof) %s를 가지는 행렬의 경우에는 아직 구현되지 않았습니다." #~ msgid "not yet implemented for %s" #~ msgstr "%s의 경우에는 아직 구현되지 않았습니다." #~ msgid "" #~ "Quadratic matrix '%s' (=: A) is not formally\n" #~ "\tsymmetric. Will be treated as\tA A'" #~ msgstr "" #~ "이차행렬(quadratic matrix) '%s' (=: A)는 형식적으로\n" #~ "\t대칭(symmetric)이 아닙니다. \tA A'와 같이 다루겠나요?" #~ msgid "" #~ "'update' must be logical or '+' or '-'; 'C' a matrix, and 'L' a " #~ "\"CHMfactor\"" #~ msgstr "" #~ "'update'는 반드시 논리형(logical) 또는 '+' 또는 '-'이어야 하며, 'C'는 행렬" #~ "이어야 하고 'L'은 \"CHMfactor\"이어야 합니다." #~ msgid "update must be TRUE/FALSE or '+' or '-'" #~ msgstr "update는 반드시 TRUE/FALSE 또는 '+' 또는 '-'이어야 합니다." #~ msgid "Matrix-internal error in [i,,d]; please report" #~ msgstr "" #~ "[i,,d]에서 Matrix-내부오류(internal error)가 발생한 경우입니다. " #~ "이를 보고해 주시길 부탁드립니다." #~ msgid "" #~ "Cholesky() -> *symbolic* factorization -- not yet implemented" #~ msgstr "" #~ "Cholesky() -> *symbolic* factorization -- 아직 구현되지 않았습" #~ "니다." #~ msgid "trimmed mean of 'sparseVector' -- suboptimally using as.numeric(.)" #~ msgstr "trimmed mean of 'sparseVector' -- suboptimally using as.numeric(.)" #~ msgid "invalid dimnames given for %s object" #~ msgstr "객체 %s에 주어진 dimnames가 올바르지 않습니다." #~ msgid "" #~ "dimnames(.) <- NULL: translated to \n" #~ "dimnames(.) <- list(NULL,NULL) <==> unname(.)" #~ msgstr "" #~ "dimnames(.) <- NULL:은 다음과 같이 변경되었습니다. \n" #~ "dimnames(.) <- list(NULL,NULL) <==> unname(.)" #~ msgid "" #~ "'nrow', 'ncol', etc, are disregarded when 'data' is \"Matrix\" already" #~ msgstr "" #~ "'data'가 이미 \"Matrix\"인 경우에는 입력된 'nrow', 'ncol' 등은 사용되지 않" #~ "습니다." #~ msgid "complex matrices not yet implemented in Matrix package" #~ msgstr "" #~ "복소수형(complex) 행렬을 다루는 경우는 아직 Matrix 패키지내에서는 아직 구" #~ "현되지 않았습니다." #~ msgid "using slow kronecker() method" #~ msgstr "느린 크로넥커 방법(slow kronecker method)를 사용합니다." #~ msgid "" #~ "Cholesky(A) called for 'A' of class \"%s\";\n" #~ "\t it is currently defined for sparseMatrix only; consider using chol() " #~ "instead" #~ msgstr "" #~ "Cholesky(A)는 클래스 \"%s\"를 가지는 'A'를 호출합니다.\n" #~ "\t 이것은 현재 sparseMatrix 만을 위하여 정의되었으므로 chol()을 사용하시" #~ "길 바랍니다." #~ msgid "invalid or not-yet-implemented 'Matrix' subsetting" #~ msgstr "" #~ "올바르지 않거나 아직 구현되지 않은 'Matrix' 부분추출(subsetting)입니다." #~ msgid "[ ] : .M.sub.i.logical() maybe inefficient" #~ msgstr "" #~ "[ ] : .M.sub.i.logical()의 사용은 비효율적(inefficient) " #~ "일 수 있습니다." #~ msgid "" #~ "nargs() = %d. Extraneous illegal arguments inside '[ .. ]' (i.logical)?" #~ msgstr "" #~ "nargs() = %d. 필요이상의 인자들이 '[ .. ]' (i.logical)에 이용되었나요?" #, fuzzy #~ msgid "" #~ "m[]: inefficiently indexing single elements - should not " #~ "happen, please report!" #~ msgstr "m[ ]: inefficiently indexing single elements" #~ msgid "" #~ "nargs() = %d. Extraneous illegal arguments inside '[ .. ]' (i.2col)?" #~ msgstr "" #~ "nargs() = %d. 필요이상의 인자들이 '[ .. ]' (i.2col)에 이용되었나요?" #~ msgid "" #~ ".M.sub.i.2col(): 'i' has no integer column number;\n" #~ " should never happen; please report" #~ msgstr "" #~ ".M.sub.i.2col(): 'i'는 정수형 행번호(integer column number)를 가지고 있지 " #~ "않습니다.\n" #~ " 이런 경우는 존재할 수 없으므로 패키지 관리자에게 보고해 주시길 부탁드립니" #~ "다." #~ msgid "not-yet-implemented coercion to \"TsparseMatrix\"" #~ msgstr "" #~ "\"TsparseMatrix\"으로의 강제변환(coercion)은 아직 구현되지 않았습니다." #~ msgid "Matrix-internal error in [i,,d]; please report" #~ msgstr "" #~ "[i,,d] 내에서 행렬과 관련한 내부에러가 발생했습니다; 꼭 보고를 " #~ "부탁드립니다" #~ msgid "FIXME: NOT YET FINISHED IMPLEMENTATION" #~ msgstr "FIXME: 완전한 구현이 아직 이루어지지 않았습니다." #~ msgid "diagonalMatrix in .dense2C() -- should never happen, please report!" #~ msgstr "" #~ "diagonalMatrix in .dense2C() -- 발생해서는 안되는 경우이므로 꼭 보고를 부" #~ "탁드립니다!" #~ msgid "undefined method for class %s" #~ msgstr "클래스 %s에 정의된 메소드가 아닙니다." #~ msgid "dimensions don't match the number of cells" #~ msgstr "차원정보가 cell의 개수와 일치하지 않습니다" #~ msgid "" #~ "LU computationally singular: ratio of extreme entries in |diag(U)| = %9.4g" #~ msgstr "" #~ "LU computationally singular: ratio of extreme entries in |diag(U)| = %9.4g" #~ msgid "RHS 'b' has wrong number of rows:" #~ msgstr "우변의 'b'는 다음과 같은 올바르지 않은 행의 수를 가지고 있습니다: " #~ msgid "'x' has invalid data type" #~ msgstr "'x'의 데이터형(data type)은 사용가능하지 않습니다." #~ msgid "length(x) must be either 1 or #{cols}" #~ msgstr "length(x)는 반드시 1 또는 #{cols} 이어야 합니다. " #~ msgid "some arguments are not matrices" #~ msgstr "일부 인자가 행렬이 아닙니다." #~ msgid "%s kind not yet implemented" #~ msgstr "아직 구현되지 않은 종류 %s입니다." #~ msgid "non-square matrix" #~ msgstr "비정방(non-square) 행렬입니다." #~ msgid "" #~ "matrix with non-zero off-diagonals cannot be coerced to \"diagonalMatrix\"" #~ msgstr "" #~ "비대각원소의 값이 영이 아닌 행렬은 \"diagonalMatrix\"로 강제변환(coerced) " #~ "할 수 없습니다." #~ msgid "non-matching dimensions" #~ msgstr "차원(dimensions) 정보가 일치하지 않습니다." #~ msgid "not a positive definite matrix" #~ msgstr "양정치(positive definite) 행렬이 아닙니다." #~ msgid "" #~ "as(.,\"dsCMatrix\") is deprecated (since 2008); do use as(., " #~ "\"symmetricMatrix\")" #~ msgstr "" #~ "as(.,\"dsCMatrix\")은 2008년 이후로 지원되지 않으므로 as(., " #~ "\"symmetricMatrix\")를 이용해 주시길 바랍니다." #~ msgid "inefficient coercion (lost triangularity); please report" #~ msgstr "" #~ "비효율적인 강제변환입니다 (triangularity를 소실하였기 때문입니다). 꼭 보" #~ "고를 부탁드립니다." #~ msgid "coercion to \"indMatrix\" only works from integer numeric" #~ msgstr "" #~ "\"indMatrix\"로의 강제변환(coercion)은 오로지 정수를 가지는 숫자(integer " #~ "numeric)인 경우만 가능합니다." #~ msgid "" #~ "coercion from list(i1,...,ik, d) to \"indMatrix\" failed.\n" #~ " All entries must be integer valued and the number of columns, d, not " #~ "smaller\n" #~ " than the maximal index i*." #~ msgstr "" #~ "list(i1,...,ik, d)으로부터 \"indMatrix\"로의 강제변환(coercion)은 이루어지" #~ "지 않았습니다.\n" #~ " 모든 원소들은 반드시 정수이어야 하며 행의 개수 d는 인덱스 i* 중 \n" #~ " 가장 큰 수보다 보다 작지 않아야 합니다." #~ msgid "the number of non-zero entries differs from nrow(.)" #~ msgstr "영이 아닌 항목들의 개수가 nrow(.)와 다릅니다." #~ msgid "replacing \"indMatrix\" entries is not allowed, as rarely sensible" #~ msgstr "" #~ "\"indMatrix\" 요소를 변경하는 것은 허용되지 않습니다, as rarely sensible" #~ msgid "temporarily disabled" #~ msgstr "일시적으로 사용할 수 없습니다." #, fuzzy #~ msgid "cannot coerce NA values to pattern \"ntCMatrix\"" #~ msgstr "'NA'를 \"nsparseMatrix\"으로 강제변환(coerce)할 수 없습니다." #~ msgid "coercion to \"pMatrix\" only works from integer numeric" #~ msgstr "" #~ "\"pMatrix\"로의 강제변환(coercion)은 오로지 정수값을 가진 숫자(integer " #~ "numeric)인 경우로부터만 가능합니다." #~ msgid "not a square matrix" #~ msgstr "정방행렬(square matrix)이 아닙니다." #~ msgid "NA's in (i,j) are not allowed" #~ msgstr "(i,j) 위치에 NA는 사용될 수 없습니다." #~ msgid "Matrix-internal error in [i,,d]; please report" #~ msgstr "" #~ "[i,,d]를 사용중 행렬-내부 오류(matrix-internal error)가 발생했습" #~ "니다. 이를 꼭 보고 부탁드립니다." #~ msgid "" #~ "qr.R() may differ from qr.R() because of permutations. " #~ "Possibly use our qrR() instead" #~ msgstr "" #~ "qr.R()은 아마도 순열(permutations) 때문에 qr.R()와 다를 수 " #~ "있습니다. 따라서, qrR()을 사용하시길 바랍니다." #~ msgid "(un)packing only applies to dense matrices, class(x)='%s'" #~ msgstr "(un)packing only applies to dense matrices, class(x)='%s'" #, fuzzy #~ msgid "'x' is not symmetric -- chol() undefined." #~ msgstr "" #~ "'x'는 양정치(positive definite) 행렬이 아니므로 chol()가 정의되어지지 않습" #~ "니다." #~ msgid "" #~ "extra argument %s will be disregarded in\n" #~ " %s" #~ msgid_plural "" #~ "extra arguments %s will be disregarded in\n" #~ " %s" #~ msgstr[0] "추가 인자들(extra arguments) %s는 %s에서 사용되지 않을 것입니다." #~ msgid " %s %s is undefined" #~ msgstr " %1$s %2$s는 정의되지 않았습니다." #~ msgid "%s %s is undefined" #~ msgstr "%s %s 은 정의되지 않았습니다." #~ msgid "variable '%s' converted to a factor" #~ msgstr "변수 '%s'가 요인(factor)로 변환되었습니다." #~ msgid "\"dMatrix\" object with NAs cannot be coerced to \"nMatrix\"" #~ msgstr "" #~ "NA를 가진 \"dMatrix\" 객체는 \"nMatrix\"로 강제변환(coerced) 할 수 없습니" #~ "다." #~ msgid "not a skinny matrix" #~ msgstr "not a skinny matrix" Matrix/po/pl.po0000644000176200001440000025601214521047060013114 0ustar liggesusersmsgid "" msgstr "" "Project-Id-Version: Matrix 1.1-2-2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-11-02 21:33-0400\n" "PO-Revision-Date: 2014-03-24 17:53+0100\n" "Last-Translator: Łukasz Daniel \n" "Language-Team: Łukasz Daniel \n" "Language: pl_PL\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2);\n" "X-Poedit-SourceCharset: iso-8859-1\n" "X-Generator: Poedit 1.5.4\n" # Matrix/src/dgCMatrix.c: 160 # error(_("cs_lusol failed")) #: Csparse.c:26 Csparse.c:318 chm_common.c:165 chm_common.c:291 #: chm_common.c:813 chm_common.c:816 chm_common.c:849 chm_common.c:867 #: dgCMatrix.c:18 dgCMatrix.c:43 dgCMatrix.c:70 dgCMatrix.c:84 dgCMatrix.c:89 #: dgCMatrix.c:94 #, fuzzy, c-format msgid "'%s' failed" msgstr "funkcja 'cs_qr' nie powiodła się " # Matrix/src/Csparse.c: 97 # (_("slot j is not increasing inside a column")) #: Csparse.c:35 chm_common.c:54 #, fuzzy, c-format msgid "'%s' slot is not increasing within columns after sorting" msgstr "gniazdo 'j' nie jest rosnące wewnątrz kolumny" # Matrix/src/Mutils.c: 990 # error(_("invalid '%s' argument"), "byrow") #: Csparse.c:77 coerce.c:220 coerce.c:240 coerce.c:250 coerce.c:905 #: coerce.c:911 coerce.c:1015 coerce.c:1501 coerce.c:1521 coerce.c:1531 #: coerce.c:2061 coerce.c:2256 coerce.c:2262 coerce.c:2268 coerce.c:2397 #: coerce.c:2404 coerce.c:2494 coerce.c:2629 coerce.c:2707 coerce.c:2729 #: coerce.c:4327 coerce.c:4396 dense.c:701 products.c:936 products.c:1288 #: solve.c:719 solve.c:968 solve.c:1100 sparse.c:1233 sparse.c:1625 #, fuzzy, c-format msgid "invalid '%s' to '%s'" msgstr "niepoprawny argument '%s'" # Matrix/src/Csparse.c: 612 # error(_("failure to open file \"%s\" for writing"), # CHAR(asChar(fname))) #: Csparse.c:316 #, fuzzy, c-format msgid "failed to open file \"%s\" for writing" msgstr "nie udało się otworzyć pliku '%s' do zapisu" # Matrix/src/Mutils.c: 990 # error(_("invalid '%s' argument"), "byrow") #: attrib.c:229 #, fuzzy msgid "invalid factor name" msgstr "niepoprawny argument '%s'" #: attrib.c:233 #, c-format msgid "attempt to set factor on %s without '%s' slot" msgstr "" #: bind.c:46 bind.c:153 msgid "number of rows of matrices must match" msgstr "" #: bind.c:48 bind.c:155 msgid "number of columns of matrices must match" msgstr "" #: bind.c:51 bind.c:158 bind.c:182 bind.c:206 chm_common.c:474 chm_common.c:623 #: chm_common.c:717 cholmod-etc.c:183 cholmod-etc.c:282 cholmod-etc.c:325 #: coerce.c:215 coerce.c:235 coerce.c:260 coerce.c:268 coerce.c:276 #: coerce.c:341 coerce.c:1496 coerce.c:1516 coerce.c:1543 coerce.c:1551 #: coerce.c:1559 products.c:28 products.c:50 products.c:56 #, c-format msgid "dimensions cannot exceed %s" msgstr "" #: bind.c:210 msgid "number of rows of result is not a multiple of vector length" msgstr "" #: bind.c:212 msgid "number of columns of result is not a multiple of vector length" msgstr "" #: bind.c:626 bind.c:691 sparse.c:912 sparse.c:993 #, c-format msgid "%s cannot exceed %s" msgstr "" #: bind.c:756 bind.c:853 chm_common.c:720 cholmod-etc.c:328 coerce.c:29 #: coerce.c:518 coerce.c:811 coerce.c:945 coerce.c:2772 coerce.c:3041 #: coerce.c:3139 dense.c:924 products.c:151 products.c:212 products.c:291 #: products.c:379 products.c:456 products.c:550 products.c:865 subscript.c:1232 #: subscript.c:1417 utils-R.c:32 #, c-format msgid "attempt to allocate vector of length exceeding %s" msgstr "" #: bind.c:858 products.c:1354 msgid "should never happen ..." msgstr "" # Matrix/src/dgeMatrix.c: 19 # (_("'x' slot must be numeric \"double\"")) #: chm_common.c:11 chm_common.c:34 validity.c:38 validity.c:183 validity.c:262 #: validity.c:281 validity.c:290 validity.c:309 validity.c:335 validity.c:355 #: validity.c:405 validity.c:422 validity.c:456 validity.c:473 validity.c:507 #: validity.c:509 validity.c:959 validity.c:992 validity.c:1074 validity.c:1094 #: validity.c:1160 validity.c:1162 validity.c:1210 validity.c:1273 #: validity.c:1275 validity.c:1321 validity.c:1368 validity.c:1417 #: validity.c:1450 validity.c:1460 validity.c:1473 validity.c:1527 #: validity.c:1529 validity.c:1561 validity.c:1573 validity.c:1596 #: validity.c:1659 validity.c:1678 validity.c:1680 validity.c:1712 #: validity.c:1747 validity.c:1775 #, fuzzy, c-format msgid "'%s' slot is not of type \"%s\"" msgstr "gniazdo 'x' musi być liczbą typu \"double\"" # Matrix/src/dgeMatrix.c: 11 # (_("'Dim' slot must have length 2")) #: chm_common.c:14 validity.c:357 validity.c:407 validity.c:458 validity.c:880 #: validity.c:891 validity.c:961 validity.c:994 validity.c:1096 validity.c:1164 #: validity.c:1212 validity.c:1277 validity.c:1323 validity.c:1462 #: validity.c:1479 validity.c:1531 validity.c:1533 validity.c:1563 #: validity.c:1575 validity.c:1598 validity.c:1714 validity.c:1751 #: validity.c:1779 validity.c:1829 #, fuzzy, c-format msgid "'%s' slot does not have length %s" msgstr "gniazdo 'Dim' musi mieć długość 2" # Matrix/src/Csparse.c: 75 # (_("first element of slot p must be zero")) #: chm_common.c:18 validity.c:410 validity.c:461 validity.c:1667 #: validity.c:1687 validity.c:1689 #, fuzzy, c-format msgid "first element of '%s' slot is not 0" msgstr "pierwszy element gniazda 'p' musi być zerem" #: chm_common.c:23 chm_common.c:46 validity.c:43 validity.c:361 validity.c:414 #: validity.c:432 validity.c:465 validity.c:483 validity.c:519 validity.c:521 #: validity.c:1041 validity.c:1053 validity.c:1100 validity.c:1173 #: validity.c:1185 validity.c:1286 validity.c:1298 validity.c:1327 #: validity.c:1378 validity.c:1427 validity.c:1466 validity.c:1486 #: validity.c:1567 validity.c:1583 validity.c:1608 validity.c:1672 #: validity.c:1692 validity.c:1694 validity.c:1721 #, c-format msgid "'%s' slot contains NA" msgstr "" # Matrix/src/Csparse.c: 86 # (_("slot p must be non-decreasing")) #: chm_common.c:26 validity.c:416 validity.c:467 #, fuzzy, c-format msgid "'%s' slot is not nondecreasing" msgstr "gniazdo 'p' musi być niemalejące" #: chm_common.c:29 validity.c:418 validity.c:469 #, c-format msgid "first differences of '%s' slot exceed %s" msgstr "" # Matrix/src/dsyMatrix.c: 7 # (_("'dim' slot has length less than two")) # Matrix/src/dtrMatrix.c: 11 # (_("'dim' slot has length less than two")) #: chm_common.c:37 validity.c:424 validity.c:475 #, fuzzy, c-format msgid "'%s' slot has length less than %s" msgstr "gniazdo 'dim' ma długość mniejszą niż dwa" # Matrix/src/dsyMatrix.c: 7 # (_("'dim' slot has length less than two")) # Matrix/src/dtrMatrix.c: 11 # (_("'dim' slot has length less than two")) #: chm_common.c:49 validity.c:363 validity.c:434 validity.c:485 validity.c:523 #: validity.c:526 validity.c:1043 validity.c:1102 validity.c:1175 #: validity.c:1187 validity.c:1288 validity.c:1300 validity.c:1380 #: validity.c:1429 validity.c:1488 validity.c:1610 validity.c:1723 #, fuzzy, c-format msgid "'%s' slot has elements not in {%s}" msgstr "gniazdo 'dim' ma długość mniejszą niż dwa" #: chm_common.c:467 chm_common.c:470 chm_common.c:472 chm_common.c:616 #: chm_common.c:619 chm_common.c:621 chm_common.c:711 chm_common.c:713 #: cholmod-etc.c:177 cholmod-etc.c:179 cholmod-etc.c:181 cholmod-etc.c:276 #: cholmod-etc.c:278 cholmod-etc.c:280 cholmod-etc.c:319 cholmod-etc.c:321 #: cs-etc.c:43 #, c-format msgid "wrong '%s'" msgstr "" # Matrix/src/dgeMatrix.c: 19 # (_("'x' slot must be numeric \"double\"")) #: chm_common.c:477 cholmod-etc.c:186 #, fuzzy, c-format msgid "'%s' would overflow type \"%s\"" msgstr "gniazdo 'x' musi być liczbą typu \"double\"" #: chm_common.c:481 cholmod-etc.c:190 #, c-format msgid "n+1 would overflow type \"%s\"" msgstr "" # Matrix/src/dppMatrix.c: 34 # error(_("the leading minor of order %d is not positive definite"), # info) # Matrix/src/dpoMatrix.c: 40 # error(_("the leading minor of order %d is not positive definite"), # info) #: chm_common.c:486 cholmod-etc.c:195 #, fuzzy, c-format msgid "leading principal minor of order %d is not positive" msgstr "wiodący minor rzędu %d nie jest dodatnio określony" # Matrix/src/dppMatrix.c: 34 # error(_("the leading minor of order %d is not positive definite"), # info) # Matrix/src/dpoMatrix.c: 40 # error(_("the leading minor of order %d is not positive definite"), # info) #: chm_common.c:489 cholmod-etc.c:198 #, fuzzy, c-format msgid "leading principal minor of order %d is zero" msgstr "wiodący minor rzędu %d nie jest dodatnio określony" #: chm_common.c:715 cholmod-etc.c:323 msgid "leading dimension not equal to number of rows" msgstr "" #: chm_common.c:778 #, c-format msgid "" "invalid simplicial Cholesky factorization: structural zero on main diagonal " "in column %d" msgstr "" # Matrix/src/chm_common.c: 698 # error(_("Cholmod error '%s' at file %s, line %d"), message, file, line) #: chm_common.c:838 #, fuzzy, c-format msgid "CHOLMOD error '%s' at file '%s', line %d" msgstr "Błąd 'cholmod' '%s' w pliku %s, linia %d" # Matrix/src/chm_common.c: 702 # warning(_("Cholmod warning '%s' at file %s, line %d"), # message, file, line) #: chm_common.c:841 #, fuzzy, c-format msgid "CHOLMOD warning '%s' at file '%s', line %d" msgstr "Ostrzeżenie 'cholmod' '%s' w pliku %s, linia %d" # Matrix/src/dgeMatrix.c: 341 # error(_("Determinant requires a square matrix")) #: coerce.c:24 coerce.c:364 coerce.c:1050 #, fuzzy, c-format msgid "attempt to construct non-square %s" msgstr "Wyznacznik wymaga aby macierz była kwadratowa" #: coerce.c:186 coerce.c:476 coerce.c:1467 coerce.c:1622 #, c-format msgid "second argument of '%s' does not specify a subclass of %s" msgstr "" # Matrix/src/Mutils.c: 268 # _("'%s' must be in '%s'") #: coerce.c:194 coerce.c:200 coerce.c:484 coerce.c:490 coerce.c:925 #: coerce.c:1475 coerce.c:1481 coerce.c:1630 coerce.c:1636 coerce.c:2275 #: coerce.c:3344 coerce.c:3349 #, fuzzy, c-format msgid "'%s' must be \"%s\" or \"%s\"" msgstr "'%s' musi być w '%s'" # Matrix/src/Mutils.c: 268 # _("'%s' must be in '%s'") #: coerce.c:246 coerce.c:496 coerce.c:793 coerce.c:917 coerce.c:1527 #: coerce.c:1642 dense.c:322 dense.c:1107 dense.c:1683 dense.c:1688 #: dense.c:1934 dense.c:2129 sparse.c:783 sparse.c:2448 sparse.c:3140 #: sparse.c:3145 sparse.c:3150 sparse.c:3426 sparse.c:3663 #, fuzzy, c-format msgid "'%s' must be %s or %s" msgstr "'%s' musi być w '%s'" #: coerce.c:266 coerce.c:274 coerce.c:285 coerce.c:1549 coerce.c:1557 #: coerce.c:1568 msgid "nonempty vector supplied for empty matrix" msgstr "" #: coerce.c:287 coerce.c:1570 #, c-format msgid "vector length (%lld) exceeds matrix length (%d * %d)" msgstr "" #: coerce.c:290 coerce.c:1573 #, c-format msgid "matrix length (%d * %d) is not a multiple of vector length (%lld)" msgstr "" #: coerce.c:521 #, c-format msgid "coercing n-by-n %s to %s is not supported for n*n exceeding %s" msgstr "" #: coerce.c:525 coerce.c:815 coerce.c:949 #, c-format msgid "sparse->dense coercion: allocating vector of size %0.1f GiB" msgstr "" #: coerce.c:1196 coerce.c:1941 coerce.c:2948 coerce.c:2954 #, c-format msgid "attempt to construct %s with more than %s nonzero entries" msgstr "" # Matrix/src/dgeMatrix.c: 341 # error(_("Determinant requires a square matrix")) #: coerce.c:3246 #, fuzzy msgid "attempt to pack non-square matrix" msgstr "Wyznacznik wymaga aby macierz była kwadratowa" #: coerce.c:3420 coerce.c:3590 #, c-format msgid "unable to aggregate %s with '%s' and '%s' slots of length exceeding %s" msgstr "" # Matrix/src/dgeMatrix.c: 341 # error(_("Determinant requires a square matrix")) #: coerce.c:4211 #, fuzzy, c-format msgid "attempt to pack a %s" msgstr "Wyznacznik wymaga aby macierz była kwadratowa" # Matrix/src/Mutils.c: 268 # _("'%s' must be in '%s'") #: coerce.c:4330 dense.c:1237 sparse.c:2579 #, fuzzy, c-format msgid "'%s' must be %s or %s or %s" msgstr "'%s' musi być w '%s'" # Matrix/src/Mutils.c: 268 # _("'%s' must be in '%s'") #: dense.c:210 dense.c:215 sparse.c:590 sparse.c:595 #, fuzzy, c-format msgid "'%s' must be an integer from %s to %s" msgstr "'%s' musi być w '%s'" # Matrix/src/Mutils.c: 268 # _("'%s' must be in '%s'") #: dense.c:218 sparse.c:598 #, fuzzy, c-format msgid "'%s' must be less than or equal to '%s'" msgstr "'%s' musi być w '%s'" #: dense.c:428 sparse.c:1069 #, c-format msgid "replacement diagonal has incompatible type \"%s\"" msgstr "" #: dense.c:437 sparse.c:1078 msgid "replacement diagonal has wrong length" msgstr "" # Matrix/src/dgeMatrix.c: 341 # error(_("Determinant requires a square matrix")) #: dense.c:627 sparse.c:1274 #, fuzzy msgid "attempt to symmetrize a non-square matrix" msgstr "Wyznacznik wymaga aby macierz była kwadratowa" #: dense.c:726 sparse.c:1652 msgid "attempt to get symmetric part of non-square matrix" msgstr "" #: dense.c:878 sparse.c:2082 msgid "attempt to get skew-symmetric part of non-square matrix" msgstr "" # Matrix/src/Mutils.c: 268 # _("'%s' must be in '%s'") #: dense.c:1678 sparse.c:3135 #, fuzzy, c-format msgid "'%s' must be %d or %d" msgstr "'%s' musi być w '%s'" # Matrix/src/dense.c: 31 # error(_("incorrect left cyclic shift, j (%d) < 0"), j, k) #: dense.c:2161 #, c-format msgid "incorrect left cyclic shift, j (%d) < 0" msgstr "niepoprawne lewe cykliczne przesunięcie, j (%d) < 0" # Matrix/src/dense.c: 29 # error(_("incorrect left cyclic shift, j (%d) >= k (%d)"), j, k) #: dense.c:2164 #, c-format msgid "incorrect left cyclic shift, j (%d) >= k (%d)" msgstr "niepoprawne lewe cykliczne przesunięcie, j (%d) >= k (%d)" # Matrix/src/dense.c: 33 # error(_("incorrect left cyclic shift, k (%d) > ldx (%d)"), k, ldx) #: dense.c:2167 #, c-format msgid "incorrect left cyclic shift, k (%d) > ldx (%d)" msgstr "niepoprawne lewe cykliczne przesunięcie, k (%d) > ldx (%d)" # Matrix/src/dense.c: 78 # error(_("Unknown error in 'getGivens' function")) #: dense.c:2220 #, fuzzy msgid "unknown error in getGivens" msgstr "Nieznany błąd w funkcji 'getGivens()'" # Matrix/src/dense.c: 90 # error(_("'X' argument must be a numeric (double precision) matrix")) # Matrix/src/dense.c: 106 # error(_("'X' argument must be a numeric (double precision) matrix")) # Matrix/src/dense.c: 137 # error(_("'X' argument must be a numeric (double precision) matrix")) #: dense.c:2229 dense.c:2243 dense.c:2273 msgid "X must be a numeric (double precision) matrix" msgstr "'X' musi być macierzą liczbową (o podwójnej precyzji)" # Matrix/src/dense.c: 111 # error(_("'y' argument must be a numeric (double precision) matrix")) # Matrix/src/dense.c: 142 # error(_("'y' argument must be a numeric (double precision) matrix")) #: dense.c:2245 dense.c:2275 msgid "y must be a numeric (double precision) matrix" msgstr "'y' musi być macierzą liczbową (o podwójnej precyzji)" # Matrix/src/dense.c: 114 # error(_("number of rows in 'y' (%d) does not match number of rows in 'X' (%d)"), ydims[0], n) # Matrix/src/dense.c: 145 # error(_("number of rows in 'y' (%d) does not match number of rows in 'X' (%d)"), ydims[0], n) #: dense.c:2249 dense.c:2279 #, c-format msgid "number of rows in y (%d) does not match number of rows in X (%d)" msgstr "liczba wierszy w 'y' (%d) nie zgadza się z liczbą wierszy w 'X' (%d)" # Matrix/src/dense.c: 124 # error(_("Lapack routine 'dposv' returned error code %d"), info) #: dense.c:2265 #, fuzzy, c-format msgid "LAPACK dposv returned error code %d" msgstr "procedura Lapack 'dposv' zwróciła kod błędu %d" # Matrix/src/dppMatrix.c: 37 # error(_("Lapack routine '%s' returned error code %d"), "dpptrf", info) # Matrix/src/dpoMatrix.c: 43 # error(_("Lapack routine '%s' returned error code %d"), "dpotrf", info) # Matrix/src/dgeMatrix.c: 317 # error(_("Lapack routine '%s' returned error code %d"), "dgetrf()", info) # Matrix/src/dspMatrix.c: 182 # error(_("Lapack routine '%s' returned error code %d"), "dsptrf", info) #: dense.c:2293 dense.c:2299 #, fuzzy, c-format msgid "LAPACK dgels returned error code %d" msgstr "Procedura Lapack '%s' zwróciła kod błędu %d" # Matrix/src/dense.c: 173 # error(_("'X' must be a real (numeric) matrix")) #: dense.c:2318 msgid "X must be a real (numeric) matrix" msgstr "'X' musi być rzeczywistą (liczbową) macierzą" # Matrix/src/dense.c: 175 # error(_("'tol' argument, given as %g, must be less or equal to 1"), tol) #: dense.c:2321 #, fuzzy, c-format msgid "tol, given as %g, must be >= 0" msgstr "argument 'tol', podany jako %g, musi być mniejszy lub równy 1" # Matrix/src/dense.c: 175 # error(_("'tol' argument, given as %g, must be less or equal to 1"), tol) #: dense.c:2323 #, c-format msgid "tol, given as %g, must be <= 1" msgstr "argument 'tol', podany jako %g, musi być mniejszy lub równy 1" # Matrix/src/dense.c: 199 # error(_("First call to 'dgeqrf' returned error code %d"), info) #: dense.c:2352 dense.c:2360 #, fuzzy, c-format msgid "LAPACK dgeqrf returned error code %d" msgstr "Pierwsze wywołanie 'dgeqrf()' zwróciło kod błędu %d" # Matrix/src/dense.c: 210 # error(_("Lapack routine 'dtrcon' returned error code %d"), info) # Matrix/src/dense.c: 230 # error(_("Lapack routine 'dtrcon' returned error code %d"), info) #: dense.c:2365 dense.c:2388 #, fuzzy, c-format msgid "LAPACK dtrcon returned error code %d" msgstr "Procedura Lapack 'dtrcon()' zwróciła kod błędu %d" # Matrix/src/dgeMatrix.c: 341 # error(_("Determinant requires a square matrix")) #: determinant.c:33 #, fuzzy msgid "determinant of non-square matrix is undefined" msgstr "Wyznacznik wymaga aby macierz była kwadratowa" # Matrix/src/sparseQR.c: 121 # warning(_("%s(): structurally rank deficient case: possibly WRONG zeros"), # "sparseQR_qty") # Matrix/src/sparseQR.c: 159 # warning(_("%s(): structurally rank deficient case: possibly WRONG zeros"), # "sparseQR_coef") # Matrix/src/sparseQR.c: 195 # warning(_("%s(): structurally rank deficient case: possibly WRONG zeros"), # "sparseQR_resid_fitted") #: determinant.c:276 #, fuzzy, c-format msgid "%s(<%s>) does not support structurally rank deficient case" msgstr "" "%s(): przypadek strukturalnie z niedoborem rang: prawdopodobnie BŁĘDNE zera" # Matrix/src/dsyMatrix.c: 9 # (_("Matrix is not square")) # Matrix/src/dtrMatrix.c: 13 # (_("Matrix is not square")) #: dgCMatrix.c:14 #, fuzzy, c-format msgid "'%s' is empty or not square" msgstr "Macierz nie jest kwadratowa" # Matrix/src/dppMatrix.c: 81 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dpoMatrix.c: 92 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dpoMatrix.c: 117 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dsyMatrix.c: 85 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dtCMatrix.c: 90 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dtCMatrix.c: 106 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dgCMatrix.c: 158 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dgCMatrix.c: 184 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dgCMatrix.c: 438 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dgCMatrix.c: 471 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dtrMatrix.c: 99 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dgeMatrix.c: 423 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dspMatrix.c: 79 # error(_("Dimensions of system to be solved are inconsistent")) #: dgCMatrix.c:16 dgCMatrix.c:38 dgCMatrix.c:61 solve.c:43 solve.c:984 #, fuzzy, c-format msgid "dimensions of '%s' and '%s' are inconsistent" msgstr "Wymiary systemu, który ma być rozwiązany, są niespójne" #: dgCMatrix.c:40 #, c-format msgid "%s(%s, %s) requires m-by-n '%s' with m >= n > 0" msgstr "" #: dgCMatrix.c:63 #, c-format msgid "%s(%s, %s) requires m-by-n '%s' with n >= m > 0" msgstr "" #: dgeMatrix.c:22 #, c-format msgid "dgeMatrix_svd(x,*): dim(x)[j] = %d is too large" msgstr "" # Matrix/src/dgeMatrix.c: 570 # error(_("Matrix exponential requires square, non-null matrix")) #: dgeMatrix.c:90 msgid "Matrix exponential requires square, non-null matrix" msgstr "Eksponencjowanie macierzy wymaga kwadratowej, niepustej macierzy" # Matrix/src/dgeMatrix.c: 587 # error(_("dgeMatrix_exp: LAPACK routine 'dgebal()' returned %d"), j) # Matrix/src/dgeMatrix.c: 589 # error(_("dgeMatrix_exp: LAPACK routine 'dgebal()' returned %d"), j) #: dgeMatrix.c:107 dgeMatrix.c:109 #, c-format msgid "dgeMatrix_exp: LAPACK routine dgebal returned %d" msgstr "dgeMatrix_exp: procedura LAPACK 'dgebal()' zwróciła %d" # Matrix/src/dgeMatrix.c: 627 # error(_("dgeMatrix_exp: 'dgetrf()' returned error code %d"), j) #: dgeMatrix.c:147 #, c-format msgid "dgeMatrix_exp: dgetrf returned error code %d" msgstr "dgeMatrix_exp: funkcja 'dgetrf()' zwróciła kod błędu %d" # Matrix/src/dgeMatrix.c: 629 # error(_("dgeMatrix_exp: 'dgetrs()' returned error code %d"), j) #: dgeMatrix.c:149 #, c-format msgid "dgeMatrix_exp: dgetrs returned error code %d" msgstr "dgeMatrix_exp: funkcja 'dgetrs()' zwróciła kod błędu %d" # Matrix/src/dgeMatrix.c: 702 # error(_("dgeMatrix_Schur: 'x' argument must be a non-null square matrix")) #: dgeMatrix.c:224 msgid "dgeMatrix_Schur: argument x must be a non-null square matrix" msgstr "dgeMatrix_Schur: argument 'x' musi być niepustą macierzą kwadratową" # Matrix/src/dgeMatrix.c: 713 # error(_("dgeMatrix_Schur: first call to 'dgees()' function failed")) #: dgeMatrix.c:237 msgid "dgeMatrix_Schur: first call to dgees failed" msgstr "dgeMatrix_Schur: pierwsze wywołanie funkcji 'dgees()' nie powiodło się" # Matrix/src/dgeMatrix.c: 721 # error(_("dgeMatrix_Schur: 'dgees()' function returned code %d"), info) #: dgeMatrix.c:246 #, c-format msgid "dgeMatrix_Schur: dgees returned code %d" msgstr "dgeMatrix_Schur: funkcja 'dgees()' zwróciła kod %d" # Matrix/src/dsyMatrix.c: 9 # (_("Matrix is not square")) # Matrix/src/dtrMatrix.c: 13 # (_("Matrix is not square")) #: factorizations.c:355 sparse.c:196 #, fuzzy, c-format msgid "'%s' is not a number" msgstr "Macierz nie jest kwadratowa" #: factorizations.c:376 #, c-format msgid "LU factorization of m-by-n %s requires m == n" msgstr "" #: factorizations.c:385 #, c-format msgid "LU factorization of %s failed: out of memory or near-singular" msgstr "" #: factorizations.c:462 #, c-format msgid "QR factorization of m-by-n %s requires m >= n" msgstr "" #: factorizations.c:471 #, c-format msgid "QR factorization of %s failed: out of memory" msgstr "" #: factorizations.c:571 factorizations.c:849 #, c-format msgid "'%s' is not a number or not finite" msgstr "" #: idz.c:467 idz.c:528 #, c-format msgid "incompatible '%s' and '%s' in '%s'" msgstr "" # Matrix/src/Mutils.c: 13 # error( # _("argument type[1]='%s' must be a one-letter character string"), # typstr) # Matrix/src/Mutils.c: 32 # error( # _("argument type[1]='%s' must be a one-letter character string"), # typstr) #: kappa.c:10 kappa.c:54 #, fuzzy, c-format msgid "argument '%s' is not of type \"%s\"" msgstr "argument type[1]='%s' musi być jednoliterowym łańcuchem tekstowym" # Matrix/src/Mutils.c: 261 # _("'%s' must have string length 1") #: kappa.c:13 kappa.c:57 #, fuzzy, c-format msgid "argument '%s' has length %d" msgstr "'%s' musi mieć łańcuch długości 1" # Matrix/src/Mutils.c: 261 # _("'%s' must have string length 1") #: kappa.c:17 kappa.c:61 #, fuzzy, c-format msgid "argument '%s' (\"%s\") does not have string length %d" msgstr "'%s' musi mieć łańcuch długości 1" #: kappa.c:41 #, c-format msgid "" "argument '%s' (\"%s\") is not \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", or " "\"%s\"" msgstr "" # Matrix/src/Mutils.c: 261 # _("'%s' must have string length 1") #: kappa.c:75 #, fuzzy, c-format msgid "argument '%s' (\"%s\") is not \"%s\", \"%s\", or \"%s\"" msgstr "'%s' musi mieć łańcuch długości 1" #: kappa.c:238 #, c-format msgid "%s(%s) is undefined: '%s' is not square" msgstr "" #: objects.c:23 #, c-format msgid "unexpected type \"%s\" in '%s'" msgstr "" #: objects.c:41 objects.c:58 #, c-format msgid "unexpected kind \"%c\" in '%s'" msgstr "" #: perm.c:26 perm.c:106 msgid "attempt to get sign of non-permutation" msgstr "" #: perm.c:51 perm.c:123 msgid "attempt to invert non-permutation" msgstr "" # Matrix/src/Csparse.c: 797 # error(_("invalid row index at position %d"), ii) #: perm.c:66 #, fuzzy msgid "invalid transposition vector" msgstr "niepoprawny indeks wiersza na pozycji %d" # Matrix/src/dgeMatrix.c: 19 # (_("'x' slot must be numeric \"double\"")) #: perm.c:79 perm.c:81 perm.c:96 perm.c:98 perm.c:113 perm.c:133 perm.c:145 #, fuzzy, c-format msgid "'%s' is not of type \"%s\"" msgstr "gniazdo 'x' musi być liczbą typu \"double\"" # Matrix/src/Mutils.c: 257 # _("'%s' slot must have length 1") #: perm.c:83 perm.c:100 perm.c:147 #, fuzzy, c-format msgid "'%s' does not have length %d" msgstr "gniazdo '%s' musi mieć długość 1" #: perm.c:86 perm.c:103 #, c-format msgid "'%s' is NA" msgstr "" # Matrix/src/dgeMatrix.c: 19 # (_("'x' slot must be numeric \"double\"")) #: perm.c:115 perm.c:138 #, fuzzy, c-format msgid "'%s' or '%s' is not of type \"%s\"" msgstr "gniazdo 'x' musi być liczbą typu \"double\"" # Matrix/src/Mutils.c: 257 # _("'%s' slot must have length 1") #: perm.c:117 perm.c:140 #, fuzzy, c-format msgid "'%s' or '%s' does not have length %d" msgstr "gniazdo '%s' musi mieć długość 1" #: perm.c:120 perm.c:143 #, c-format msgid "'%s' or '%s' is NA" msgstr "" #: perm.c:136 #, c-format msgid "'%s' has length exceeding %s" msgstr "" #: perm.c:150 #, c-format msgid "'%s' is NA or less than %s" msgstr "" #: products.c:107 products.c:210 products.c:289 products.c:377 products.c:454 #: products.c:548 products.c:809 products.c:859 msgid "non-conformable arguments" msgstr "" #: products.c:782 products.c:807 #, c-format msgid "'%s' does not support complex matrices" msgstr "" # Matrix/src/dsyMatrix.c: 9 # (_("Matrix is not square")) # Matrix/src/dtrMatrix.c: 13 # (_("Matrix is not square")) #: solve.c:38 #, fuzzy, c-format msgid "'%s' is not square" msgstr "Macierz nie jest kwadratowa" #: solve.c:497 #, c-format msgid "%s(<%s>, <%s>) failed: out of memory" msgstr "" # Matrix/src/dgeMatrix.c: 341 # error(_("Determinant requires a square matrix")) #: solve.c:618 #, fuzzy, c-format msgid "attempt to construct %s with more than %s nonzero elements" msgstr "Wyznacznik wymaga aby macierz była kwadratowa" #: sparseVector.c:90 #, c-format msgid "%s length cannot exceed %s" msgstr "" #: subscript.c:1542 subscript.c:1695 subscript.c:1938 subscript.c:2122 #, c-format msgid "%s too dense for %s; would have more than %s nonzero entries" msgstr "" #: subscript.c:2209 #, c-format msgid "NA subscripts in %s not supported for '%s' inheriting from %s" msgstr "" # Matrix/src/t_Csparse_subassign.c: 144 # error(_("invalid class of 'x' in 'Csparse_subassign()' function")) #: t_Csparse_subassign.c:142 msgid "invalid class of 'x' in Csparse_subassign()" msgstr "niepoprawna klasa 'x' w funkcji 'Csparse_subassign()'" # Matrix/src/t_Csparse_subassign.c: 146 # error(_("invalid class of 'value' in 'Csparse_subassign()' function")) #: t_Csparse_subassign.c:144 msgid "invalid class of 'value' in Csparse_subassign()" msgstr "niepoprawna klasa 'value' w funkcji 'Csparse_subassign()'" # Matrix/src/t_Csparse_subassign.c: 189 # warning(_("x[] <- val: 'val' must be logical for \"%s\" x"), # valid_cM[ctype_x]) #: t_Csparse_subassign.c:187 #, c-format msgid "x[] <- val: val is coerced to logical for \"%s\" x" msgstr "" "x[] <- val: 'val' została przekształcone w wartość logiczną dla \"%s\" 'x'" # Matrix/src/t_Csparse_subassign.c: 194 # error(_("x[] <- val: 'val' must be integer or logical for \"%s\" x"), # valid_cM[ctype_x]) #: t_Csparse_subassign.c:192 #, c-format msgid "" "x[] <- val: val should be integer or logical, is coerced to integer, for " "\"%s\" x" msgstr "" "x[] <- val: 'val' powinno być liczbą całkowitą lub wartością logiczną, " "została przekształcona na liczbę całkowitą, dla \"%s\" 'x'" # Matrix/src/t_Csparse_subassign.c: 201 # error(_("programming error in 'Csparse_subassign()' function should never happen")) #: t_Csparse_subassign.c:199 msgid "programming error in Csparse_subassign() should never happen" msgstr "" "błąd programowy w funkcji 'Csparse_subassign()' nie powinien się wydarzyć" #: utils-R.c:30 utils-R.c:116 #, c-format msgid "indices would exceed %s" msgstr "" # Matrix/src/dpoMatrix.c: 115 # error(_("Argument 'b' must be a numeric matrix")) #: utils-R.c:235 utils-R.c:270 utils-R.c:281 utils-R.c:312 msgid "Argument must be numeric-like atomic vector" msgstr "Argument musi być atomowym wektorem liczbowym" # Matrix/src/Mutils.c: 983 # error(_("'data' must be of a vector type")) #: utils-R.c:345 msgid "'data' must be of a vector type" msgstr "'data' musi być type wektor" # Matrix/src/Mutils.c: 990 # error(_("invalid '%s' argument"), "byrow") #: utils-R.c:352 #, c-format msgid "invalid '%s' argument" msgstr "niepoprawny argument '%s'" # Matrix/src/Mutils.c: 997 # error(_("non-numeric matrix extent")) # Matrix/src/Mutils.c: 1005 # error(_("non-numeric matrix extent")) #: utils-R.c:359 utils-R.c:367 msgid "non-numeric matrix extent" msgstr "nieliczbowy rozmiar macierzy" # Matrix/src/Mutils.c: 1000 # error(_("invalid 'nrow' value (too large or NA)")) #: utils-R.c:362 msgid "invalid 'nrow' value (too large or NA)" msgstr "niepoprawna wartość 'nrow' (zbyt duża lub wartość NA)" # Matrix/src/Mutils.c: 1002 # error(_("invalid 'nrow' value (< 0)")) #: utils-R.c:364 msgid "invalid 'nrow' value (< 0)" msgstr "niepoprawna wartość 'nrow' (< 0)" # Matrix/src/Mutils.c: 1008 # error(_("invalid 'ncol' value (too large or NA)")) #: utils-R.c:370 msgid "invalid 'ncol' value (too large or NA)" msgstr "niepoprawna wartość 'ncol' (zbyt duża lub wartość NA)" # Matrix/src/Mutils.c: 1010 # error(_("invalid 'ncol' value (< 0)")) #: utils-R.c:372 msgid "invalid 'ncol' value (< 0)" msgstr "niepoprawna wartość 'ncol' (< 0)" # Matrix/src/Mutils.c: 1028 # warning(_("data length [%d] is not a sub-multiple or multiple of the number of rows [%d]"), lendat, nr) #: utils-R.c:390 #, c-format msgid "" "data length [%d] is not a sub-multiple or multiple of the number of rows [%d]" msgstr "" "długość danych [%d] nie jest podwielokrotnością lub wielokrotnością liczby " "wierszy [%d]" # Matrix/src/Mutils.c: 1031 # warning(_("data length [%d] is not a sub-multiple or multiple of the number of columns [%d]"), lendat, nc) #: utils-R.c:395 #, c-format msgid "" "data length [%d] is not a sub-multiple or multiple of the number of columns " "[%d]" msgstr "" "długość danych [%d] nie jest podwielokrotnością lub wielokrotnością liczby " "kolumn [%d]" # Matrix/src/Mutils.c: 1034 # warning(_("data length exceeds size of matrix")) #: utils-R.c:399 msgid "data length exceeds size of matrix" msgstr "długość danych przekracza rozmiar macierzy" # Matrix/src/Mutils.c: 1040 # error(_("too many elements specified")) #: utils-R.c:404 msgid "too many elements specified" msgstr "określono zbyt dużo elementów" # Matrix/src/Mutils.c: 840 # error(_("Argument 'ij' must be 2-column integer matrix")) #: utils-R.c:545 msgid "Argument ij must be 2-column integer matrix" msgstr "Argument 'ij' musi być 2-kolumnową macierzą liczb całkowitych" # Matrix/src/Mutils.c: 856 # error(_("subscript 'i' out of bounds in M[ij]")) #: utils-R.c:570 msgid "subscript 'i' out of bounds in M[ij]" msgstr "indeks 'i' poza zakresem w 'M[ij]'" # Matrix/src/Mutils.c: 858 # error(_("subscript 'j' out of bounds in M[ij]")) #: utils-R.c:572 msgid "subscript 'j' out of bounds in M[ij]" msgstr "indeks 'j' poza zakresem w 'M[ij]'" # Matrix/src/Mutils.c: 897 # error(_("'i' and 'j' arguments must be integer vectors of the same length")) #: utils-R.c:626 msgid "i and j must be integer vectors of the same length" msgstr "" "'i' oraz 'j' muszą być wektorami liczb całkowitych o tej samej długości" # Matrix/src/dgeMatrix.c: 11 # (_("'Dim' slot must have length 2")) #: validity.c:40 validity.c:73 validity.c:264 validity.c:283 validity.c:292 #: validity.c:311 validity.c:337 validity.c:1010 validity.c:1452 #: validity.c:1476 #, fuzzy, c-format msgid "'%s' slot does not have length %d" msgstr "gniazdo 'Dim' musi mieć długość 2" # Matrix/src/dsyMatrix.c: 7 # (_("'dim' slot has length less than two")) # Matrix/src/dtrMatrix.c: 11 # (_("'dim' slot has length less than two")) #: validity.c:45 validity.c:965 validity.c:998 #, fuzzy, c-format msgid "'%s' slot has negative elements" msgstr "gniazdo 'dim' ma długość mniejszą niż dwa" # Matrix/src/dgeMatrix.c: 19 # (_("'x' slot must be numeric \"double\"")) #: validity.c:71 validity.c:197 #, fuzzy, c-format msgid "'%s' slot is not a list" msgstr "gniazdo 'x' musi być liczbą typu \"double\"" # Matrix/src/Mutils.c: 287 # error(_("'s1' and 's2' must be \"character\" vectors")) #: validity.c:89 #, fuzzy, c-format msgid "%s[[%d]] is not NULL or a vector" msgstr "'s1' oraz 's2' muszą być wektorami tekstowymi" #: validity.c:92 #, c-format msgid "length of %s[[%d]] (%lld) is not equal to %s[%d] (%d)" msgstr "" #: validity.c:203 #, c-format msgid "'%s' slot has no '%s' attribute" msgstr "" #: validity.c:214 validity.c:277 validity.c:305 validity.c:376 validity.c:1115 #: validity.c:1446 validity.c:1807 #, c-format msgid "%s[1] != %s[2] (matrix is not square)" msgstr "" #: validity.c:239 validity.c:252 #, c-format msgid "%s[1] differs from %s[2]" msgstr "" # Matrix/src/dgeMatrix.c: 19 # (_("'x' slot must be numeric \"double\"")) #: validity.c:267 validity.c:286 validity.c:295 validity.c:314 #, fuzzy, c-format msgid "'%s' slot is not \"%s\" or \"%s\"" msgstr "gniazdo 'x' musi być liczbą typu \"double\"" # Matrix/src/dgeMatrix.c: 11 # (_("'Dim' slot must have length 2")) #: validity.c:320 validity.c:324 #, fuzzy, c-format msgid "'%s' slot is \"%s\" but '%s' slot does not have length %s" msgstr "gniazdo 'Dim' musi mieć długość 2" # Matrix/src/dgeMatrix.c: 19 # (_("'x' slot must be numeric \"double\"")) #: validity.c:340 #, fuzzy, c-format msgid "'%s' slot is not %d or %d" msgstr "gniazdo 'x' musi być liczbą typu \"double\"" #: validity.c:346 validity.c:349 #, c-format msgid "%s-by-%s %s invalid for positive '%s' when %s=%d" msgstr "" #: validity.c:386 validity.c:1178 validity.c:1190 validity.c:1291 #: validity.c:1303 validity.c:1383 validity.c:1432 validity.c:1491 #, c-format msgid "'%s' slot contains duplicates" msgstr "" # Matrix/src/Csparse.c: 97 # (_("slot j is not increasing inside a column")) #: validity.c:437 validity.c:1613 #, fuzzy, c-format msgid "'%s' slot is not increasing within columns" msgstr "gniazdo 'j' nie jest rosnące wewnątrz kolumny" # Matrix/src/Csparse.c: 97 # (_("slot j is not increasing inside a column")) #: validity.c:488 #, fuzzy, c-format msgid "'%s' slot is not increasing within rows" msgstr "gniazdo 'j' nie jest rosnące wewnątrz kolumny" # Matrix/src/dgeMatrix.c: 11 # (_("'Dim' slot must have length 2")) #: validity.c:512 validity.c:801 validity.c:827 validity.c:853 validity.c:1076 #: validity.c:1682 validity.c:1684 #, fuzzy, c-format msgid "'%s' and '%s' slots do not have equal length" msgstr "gniazdo 'Dim' musi mieć długość 2" #: validity.c:515 #, c-format msgid "'%s' slot has nonzero length but %s is 0" msgstr "" # Matrix/src/dtTMatrix.c: 24 # (_("uplo='U' must not have sparse entries below the diagonal")) # Matrix/src/dtCMatrix.c: 28 # (_("uplo='U' must not have sparse entries below the diagonal")) # Matrix/src/dtCMatrix.c: 63 # (_("uplo='U' must not have sparse entries below the diagonal")) #: validity.c:555 validity.c:600 validity.c:646 validity.c:691 validity.c:735 #: validity.c:770 #, fuzzy, c-format msgid "%s=\"%s\" but there are entries below the diagonal" msgstr "uplo='U' nie może mieć rzadkich wpisów poniżej diagonali" # Matrix/src/dtTMatrix.c: 29 # (_("uplo='L' must not have sparse entries above the diagonal")) # Matrix/src/dtCMatrix.c: 34 # (_("uplo='L' must not have sparse entries above the diagonal")) # Matrix/src/dtCMatrix.c: 69 # (_("uplo='L' must not have sparse entries above the diagonal")) #: validity.c:565 validity.c:613 validity.c:656 validity.c:704 validity.c:740 #: validity.c:781 #, fuzzy, c-format msgid "%s=\"%s\" but there are entries above the diagonal" msgstr "uplo='L' nie może mieć rzadkich wpisów powyżej diagonali" # Matrix/src/dtTMatrix.c: 24 # (_("uplo='U' must not have sparse entries below the diagonal")) # Matrix/src/dtCMatrix.c: 28 # (_("uplo='U' must not have sparse entries below the diagonal")) # Matrix/src/dtCMatrix.c: 63 # (_("uplo='U' must not have sparse entries below the diagonal")) #: validity.c:603 validity.c:616 validity.c:694 validity.c:707 validity.c:773 #: validity.c:784 #, fuzzy, c-format msgid "%s=\"%s\" but there are entries on the diagonal" msgstr "uplo='U' nie może mieć rzadkich wpisów poniżej diagonali" #: validity.c:911 validity.c:935 validity.c:939 msgid "matrix has negative diagonal elements" msgstr "" #: validity.c:955 validity.c:983 validity.c:987 msgid "matrix has nonunit diagonal elements" msgstr "" # Matrix/src/dgeMatrix.c: 19 # (_("'x' slot must be numeric \"double\"")) #: validity.c:1007 validity.c:1032 validity.c:1826 #, fuzzy, c-format msgid "'%s' slot is not of type \"%s\" or \"%s\"" msgstr "gniazdo 'x' musi być liczbą typu \"double\"" # Matrix/src/dgeMatrix.c: 19 # (_("'x' slot must be numeric \"double\"")) #: validity.c:1015 validity.c:1022 #, fuzzy, c-format msgid "'%s' slot is NA" msgstr "gniazdo 'x' musi być liczbą typu \"double\"" # Matrix/src/dsyMatrix.c: 7 # (_("'dim' slot has length less than two")) # Matrix/src/dtrMatrix.c: 11 # (_("'dim' slot has length less than two")) #: validity.c:1017 validity.c:1024 #, fuzzy, c-format msgid "'%s' slot is negative" msgstr "gniazdo 'dim' ma długość mniejszą niż dwa" # Matrix/src/Mutils.c: 268 # _("'%s' must be in '%s'") #: validity.c:1026 #, fuzzy, c-format msgid "'%s' slot exceeds %s" msgstr "'%s' musi być w '%s'" # Matrix/src/dsyMatrix.c: 7 # (_("'dim' slot has length less than two")) # Matrix/src/dtrMatrix.c: 11 # (_("'dim' slot has length less than two")) #: validity.c:1036 #, fuzzy, c-format msgid "'%s' slot has length greater than '%s' slot" msgstr "gniazdo 'dim' ma długość mniejszą niż dwa" # Matrix/src/Csparse.c: 97 # (_("slot j is not increasing inside a column")) #: validity.c:1046 validity.c:1674 validity.c:1696 validity.c:1698 #, fuzzy, c-format msgid "'%s' slot is not increasing" msgstr "gniazdo 'j' nie jest rosnące wewnątrz kolumny" # Matrix/src/dsyMatrix.c: 7 # (_("'dim' slot has length less than two")) # Matrix/src/dtrMatrix.c: 11 # (_("'dim' slot has length less than two")) #: validity.c:1056 #, fuzzy, c-format msgid "'%s' slot has elements not in {%s} after truncation towards zero" msgstr "gniazdo 'dim' ma długość mniejszą niż dwa" # Matrix/src/Csparse.c: 97 # (_("slot j is not increasing inside a column")) #: validity.c:1059 #, fuzzy, c-format msgid "'%s' slot is not increasing after truncation towards zero" msgstr "gniazdo 'j' nie jest rosnące wewnątrz kolumny" # Matrix/src/dgeMatrix.c: 127 # error(_("Dimensions of 'x' and 'y' are not compatible for '%s'"), # tr ? "tcrossprod" : "crossprod") # Matrix/src/dgeMatrix.c: 184 # error(_("Dimensions of 'x' and 'y' are not compatible for '%s'"), # tr ? "tcrossprod" : "crossprod") #: validity.c:1125 validity.c:1152 validity.c:1814 validity.c:1821 #, fuzzy, c-format msgid "dimensions of '%s' slot are not identical to '%s'" msgstr "Wymiary 'x' oraz 'y' nie są zgodne dla '%s'" #: validity.c:1127 #, c-format msgid "'%s' slot is upper (not lower) triangular" msgstr "" #: validity.c:1140 #, c-format msgid "'%s' slot has nonunit diagonal elements" msgstr "" #: validity.c:1154 #, c-format msgid "'%s' slot is lower (not upper) triangular" msgstr "" # Matrix/src/dgeMatrix.c: 11 # (_("'Dim' slot must have length 2")) #: validity.c:1166 validity.c:1279 validity.c:1370 validity.c:1419 #, fuzzy, c-format msgid "'%s' slot does not have length %s or length %s" msgstr "gniazdo 'Dim' musi mieć długość 2" #: validity.c:1206 msgid "matrix has more columns than rows" msgstr "" # Matrix/src/dsyMatrix.c: 7 # (_("'dim' slot has length less than two")) # Matrix/src/dtrMatrix.c: 11 # (_("'dim' slot has length less than two")) #: validity.c:1226 #, fuzzy, c-format msgid "'%s' slot has fewer than %s rows" msgstr "gniazdo 'dim' ma długość mniejszą niż dwa" # Matrix/src/dsyMatrix.c: 7 # (_("'dim' slot has length less than two")) # Matrix/src/dtrMatrix.c: 11 # (_("'dim' slot has length less than two")) #: validity.c:1228 #, fuzzy, c-format msgid "'%s' slot has more than %s rows" msgstr "gniazdo 'dim' ma długość mniejszą niż dwa" # Matrix/src/dgeMatrix.c: 11 # (_("'Dim' slot must have length 2")) #: validity.c:1230 validity.c:1252 #, fuzzy, c-format msgid "'%s' slot does not have %s columns" msgstr "gniazdo 'Dim' musi mieć długość 2" # Matrix/src/dtTMatrix.c: 29 # (_("uplo='L' must not have sparse entries above the diagonal")) # Matrix/src/dtCMatrix.c: 34 # (_("uplo='L' must not have sparse entries above the diagonal")) # Matrix/src/dtCMatrix.c: 69 # (_("uplo='L' must not have sparse entries above the diagonal")) #: validity.c:1237 #, fuzzy, c-format msgid "'%s' slot must be lower trapezoidal but has entries above the diagonal" msgstr "uplo='L' nie może mieć rzadkich wpisów powyżej diagonali" # Matrix/src/dgeMatrix.c: 11 # (_("'Dim' slot must have length 2")) #: validity.c:1250 #, fuzzy, c-format msgid "'%s' slot does not have %s row" msgstr "gniazdo 'Dim' musi mieć długość 2" # Matrix/src/dtTMatrix.c: 24 # (_("uplo='U' must not have sparse entries below the diagonal")) # Matrix/src/dtCMatrix.c: 28 # (_("uplo='U' must not have sparse entries below the diagonal")) # Matrix/src/dtCMatrix.c: 63 # (_("uplo='U' must not have sparse entries below the diagonal")) #: validity.c:1259 #, fuzzy, c-format msgid "'%s' slot must be upper trapezoidal but has entries below the diagonal" msgstr "uplo='U' nie może mieć rzadkich wpisów poniżej diagonali" #: validity.c:1263 #, c-format msgid "'%s' slot has negative diagonal elements" msgstr "" #: validity.c:1329 #, c-format msgid "'%s' slot has elements not in {%s}\\{%s}" msgstr "" #: validity.c:1338 #, c-format msgid "'%s' slot has unpaired negative elements" msgstr "" #: validity.c:1364 validity.c:1408 validity.c:1412 validity.c:1760 #: validity.c:1792 msgid "Cholesky factor has negative diagonal elements" msgstr "" #: validity.c:1455 #, c-format msgid "%s[%d] (%s) is not in %s" msgstr "" #: validity.c:1468 validity.c:1569 #, c-format msgid "%s is not in {%s}" msgstr "" #: validity.c:1505 #, c-format msgid "%s is not representable as \"%s\"" msgstr "" #: validity.c:1510 validity.c:1516 #, c-format msgid "%s[%d] (%s) is not %d or %d" msgstr "" #: validity.c:1513 validity.c:1629 validity.c:1632 validity.c:1635 #, c-format msgid "%s[%d] (%s) is not %d" msgstr "" #: validity.c:1538 #, c-format msgid "%s has elements not in {%s}" msgstr "" #: validity.c:1541 #, c-format msgid "%s has elements not in {%s}\\{%s}" msgstr "" #: validity.c:1544 #, c-format msgid "%s is %d but columns are not stored in increasing order" msgstr "" #: validity.c:1547 validity.c:1550 #, c-format msgid "traversal of '%s' slot does not complete in exactly %s steps" msgstr "" #: validity.c:1556 validity.c:1558 #, c-format msgid "%s is not %d" msgstr "" #: validity.c:1579 #, c-format msgid "column '%s' is stored first but %s is not 0" msgstr "" # Matrix/src/Csparse.c: 97 # (_("slot j is not increasing inside a column")) #: validity.c:1585 #, fuzzy, c-format msgid "'%s' slot is not increasing when traversed in stored column order" msgstr "gniazdo 'j' nie jest rosnące wewnątrz kolumny" #: validity.c:1587 #, c-format msgid "'%s' slot allocates fewer than %s elements for column '%s'" msgstr "" #: validity.c:1590 #, c-format msgid "'%s' slot allocates more than %s elements for column '%s'" msgstr "" #: validity.c:1604 #, c-format msgid "first entry in column '%s' does not have row index '%s'" msgstr "" #: validity.c:1638 validity.c:1641 #, c-format msgid "%s[%d] (%s) is negative" msgstr "" #: validity.c:1644 #, c-format msgid "%s[%d] (%s) is not less than %s" msgstr "" # Matrix/src/dsyMatrix.c: 7 # (_("'dim' slot has length less than two")) # Matrix/src/dtrMatrix.c: 11 # (_("'dim' slot has length less than two")) #: validity.c:1662 #, fuzzy, c-format msgid "'%s' slot has length less than %d" msgstr "gniazdo 'dim' ma długość mniejszą niż dwa" # Matrix/src/dsyMatrix.c: 7 # (_("'dim' slot has length less than two")) # Matrix/src/dtrMatrix.c: 11 # (_("'dim' slot has length less than two")) #: validity.c:1664 #, fuzzy, c-format msgid "'%s' slot has length greater than %s" msgstr "gniazdo 'dim' ma długość mniejszą niż dwa" # Matrix/src/Csparse.c: 75 # (_("first element of slot p must be zero")) #: validity.c:1669 #, fuzzy, c-format msgid "last element of '%s' slot is not %s" msgstr "pierwszy element gniazda 'p' musi być zerem" #: validity.c:1702 #, c-format msgid "first differences of '%s' slot are less than those of '%s' slot" msgstr "" #: validity.c:1705 #, c-format msgid "supernode lengths exceed %s" msgstr "" #: validity.c:1707 #, c-format msgid "first differences of '%s' slot are not equal to supernode lengths" msgstr "" #: validity.c:1727 #, c-format msgid "" "'%s' slot is wrong within diagonal blocks (row and column indices do not " "coincide)" msgstr "" # Matrix/src/Csparse.c: 97 # (_("slot j is not increasing inside a column")) #: validity.c:1730 #, fuzzy, c-format msgid "'%s' slot is not increasing within supernodes" msgstr "gniazdo 'j' nie jest rosnące wewnątrz kolumny" # Matrix/src/cs_utils.c: 170 # error(_("invalid class of object to %s"), "Matrix_as_css") # Matrix/src/cs_utils.c: 185 # error(_("invalid class of object to %s"), "Matrix_as_css") # Matrix/src/cs_utils.c: 205 # error(_("invalid class of object to %s"), "Matrix_as_csn") # Matrix/src/cs_utils.c: 218 # error(_("invalid class of object to %s"), "Matrix_as_csn") #: validity.c:1845 #, fuzzy, c-format msgid "invalid class \"%s\" object: %s" msgstr "niepoprawna klasa obiektu przekazanego do '%s'" # Matrix/src/CHMfactor.c: 97 # error(_("diagonal element %d of Cholesky factor is missing"), j) #, c-format #~ msgid "diagonal element %d of Cholesky factor is missing" #~ msgstr "brakuje elementu diagonalnego %d czynnika Cholesky'ego" # Matrix/src/CHMfactor.c: 135 # error(_("cholmod_factorize_p failed: status %d, minor %d of ncol %d"), # c.status, f->minor, f->n) #, c-format #~ msgid "cholmod_factorize_p failed: status %d, minor %d of ncol %d" #~ msgstr "" #~ "'cholmod_factorize_p' nie powiódł się: status %d, minor %d liczba kolumn " #~ "%d" # Matrix/src/CHMfactor.c: 140 # error(_("cholmod_change_factor failed")) #~ msgid "cholmod_change_factor failed" #~ msgstr "'cholmod_change_factor' nie powiódł się" # Matrix/src/Csparse.c: 616 # error(_("cholmod_write_sparse returned error code")) #~ msgid "cholmod_write_sparse returned error code" #~ msgstr "'cholmod_write_sparse' zwrócił kod błędu" # Matrix/src/Csparse.c: 689 # warning(_("%s = '%s' (back-permuted) is experimental"), # "resultKind", "diagBack") #, c-format #~ msgid "%s = '%s' (back-permuted) is experimental" #~ msgstr "%s = '%s' (wstecznie permutowany) jest eksperymentalny" # Matrix/src/Csparse.c: 699 # error(_("diag_tC(): invalid 'resultKind'")) #~ msgid "diag_tC(): invalid 'resultKind'" #~ msgstr "diag_tC(): niepoprawny 'resultKind'" # Matrix/src/chm_common.c: 383 # error(_("complex sparse matrix code not yet written")) # Matrix/src/chm_common.c: 577 # error(_("complex sparse matrix code not yet written")) # Matrix/src/chm_common.c: 812 # error(_("complex sparse matrix code not yet written")) # Matrix/src/chm_common.c: 862 # error(_("complex sparse matrix code not yet written")) #, fuzzy #~ msgid "complex matrices are not yet supported" #~ msgstr "kod dla zespolonych rzadkich macierzy nie został jeszcze napisany" # Matrix/src/chm_common.c: 67 # error(_("Argument 'rho' must be an environment")) #~ msgid "Argument rho must be an environment" #~ msgstr "Argument 'rho' musi być środowiskiem" # Matrix/src/chm_common.c: 230 # error(_("invalid class of object passed to 'as_cholmod_sparse' function")) #~ msgid "invalid class of object to as_cholmod_sparse" #~ msgstr "" #~ "niepoprawna klasa obiektu przekazanego do funkcji 'as_cholmod_sparse()'" # Matrix/src/chm_common.c: 232 # error(_("invalid object passed to 'as_cholmod_sparse' function")) #~ msgid "invalid object passed to as_cholmod_sparse" #~ msgstr "niepoprawny obiekt przekazany do funkcji 'as_cholmod_sparse()'" # Matrix/src/chm_common.c: 259 # error(_("'in_place' 'cholmod_sort' returned an error code")) #~ msgid "in_place cholmod_sort returned an error code" #~ msgstr "'in_place' funkcji 'cholmod_sort()' zwróciło kod błędu" # Matrix/src/chm_common.c: 265 # error(_("'cholmod_sort' function returned an error code")) #~ msgid "cholmod_sort returned an error code" #~ msgstr "funkcja 'cholmod_sort' zwróciła kod błędu" # Matrix/src/chm_common.c: 346 # error(_("chm_sparse_to_SEXP(, *): invalid 'Rkind' (real kind code)")) #~ msgid "chm_sparse_to_SEXP(, *): invalid 'Rkind' (real kind code)" #~ msgstr "" #~ "chm_sparse_to_SEXP(, *): niepoprawny 'Rkind' (kod 'real kind')" # Matrix/src/chm_common.c: 354 # error(_("unknown 'xtype' in \"cholmod_sparse\" object")) #~ msgid "unknown xtype in cholmod_sparse object" #~ msgstr "nieznany 'xtype' w obiekcie klasy \"cholmod_sparse\"" # Matrix/src/chm_common.c: 383 # error(_("complex sparse matrix code not yet written")) # Matrix/src/chm_common.c: 577 # error(_("complex sparse matrix code not yet written")) # Matrix/src/chm_common.c: 812 # error(_("complex sparse matrix code not yet written")) # Matrix/src/chm_common.c: 862 # error(_("complex sparse matrix code not yet written")) #~ msgid "complex sparse matrix code not yet written" #~ msgstr "kod dla zespolonych rzadkich macierzy nie został jeszcze napisany" # Matrix/src/chm_common.c: 388 # error(_("'symmetric' and 'triangular' both set")) # Matrix/src/chm_common.c: 582 # error(_("'symmetric' and 'triangular' both set")) #~ msgid "Symmetric and triangular both set" #~ msgstr "Ustawiono jednocześnie 'symmetric' oraz 'triangular'" # Matrix/src/chm_common.c: 428 # error(_("invalid class of object passed to 'as_cholmod_triplet' function")) #~ msgid "invalid class of object to as_cholmod_triplet" #~ msgstr "" #~ "niepoprawna klasa obiektu przekazanego do funkcji 'as_cholmod_triplet()'" # Matrix/src/chm_common.c: 452 # error(_("as_cholmod_triplet(): could not reallocate for internal 'diagU2N()' function")) #~ msgid "as_cholmod_triplet(): could not reallocate for internal diagU2N()" #~ msgstr "" #~ "as_cholmod_triplet(): nie można ponownie przydzielić dla wewnętrznej " #~ "funkcji 'diagU2N()'" # Matrix/src/chm_common.c: 549 # error(_("unknown 'xtype' in \"cholmod_triplet\" object")) #~ msgid "unknown xtype in cholmod_triplet object" #~ msgstr "nieznany 'xtype' w obiekcie klasy \"cholmod_triplet\"" # Matrix/src/chm_common.c: 628 # error(_("invalid class of object passed to 'as_cholmod_dense()' function")) #~ msgid "invalid class of object to as_cholmod_dense" #~ msgstr "" #~ "niepoprawna klasa obiektu przekazanego do funkcji 'as_cholmod_dense()'" # Matrix/src/chm_common.c: 731 # error(_("Unable to initialize 'cholmod' function: error code %d"), res) #, c-format #~ msgid "Unable to initialize cholmod: error code %d" #~ msgstr "Nie można zainicjować funkcji 'cholmod()': kod błędu %d" # Matrix/src/chm_common.c: 778 # error(_("unknown 'Rkind'")) #~ msgid "unknown 'Rkind'" #~ msgstr "nieznany 'Rkind'" # Matrix/src/chm_common.c: 785 # error(_("unknown 'xtype'")) # Matrix/src/chm_common.c: 848 # error(_("unknown 'xtype'")) #~ msgid "unknown xtype" #~ msgstr "nieznany 'xtype'" # Matrix/src/chm_common.c: 818 # error(_("code for 'cholmod_dense()' function with holes not yet written")) # Matrix/src/chm_common.c: 871 # error(_("code for 'cholmod_dense()' functionwith holes not yet written")) #~ msgid "code for cholmod_dense with holes not yet written" #~ msgstr "" #~ "kod dla funkcji 'cholmod_dense()' z dziurami nie jest jeszcze napisany" # Matrix/src/chm_common.c: 867 # error(_("don't know if a dense pattern matrix makes sense")) #~ msgid "don't know if a dense pattern matrix makes sense" #~ msgstr "nie wiadomo, czy gęsty wzrór macierzy ma sens" # Matrix/src/chm_common.c: 934 # error(_("invalid class of object passed to 'as_cholmod_factor' function")) #, fuzzy #~ msgid "object of invalid class to 'as_cholmod_factor()'" #~ msgstr "" #~ "niepoprawna klasa obiektu przekazanego do funkcji 'as_cholmod_factor()'" # Matrix/src/chm_common.c: 988 # error(_("failure in 'as_cholmod_factor' function")) #~ msgid "failure in as_cholmod_factor" #~ msgstr "niepowodzenie w funkcji 'as_cholmod_factor()'" # Matrix/src/chm_common.c: 1016 # error(_("CHOLMOD factorization was unsuccessful")) #~ msgid "CHOLMOD factorization was unsuccessful" #~ msgstr "Faktoryzacja 'CHOLMOD' nie powiodła się" # Matrix/src/chm_common.c: 1029 # error(_("f->xtype of %d not recognized"), f->xtype) #, c-format #~ msgid "f->xtype of %d not recognized" #~ msgstr "'f->xtype' dla %d nie został rozpoznany" # Matrix/src/chm_common.c: 1094 # error(_("chm_diagN2U(): nrow=%d, ncol=%d"), # n, chx->ncol) #, c-format #~ msgid "chm_diagN2U(): nrow=%d, ncol=%d" #~ msgstr "chm_diagN2U(): nrow=%d, ncol=%d" # Matrix/src/chm_common.c: 1137 # error(_("chm_diagN2U(x, uploT = %d): uploT should be +- 1"), uploT) #, c-format #~ msgid "chm_diagN2U(x, uploT = %d): uploT should be +- 1" #~ msgstr "chm_diagN2U(x, uploT = %d): 'uploT' powinien wynosić +/- 1" # Matrix/src/dgCMatrix.c: 156 # error(_("dgCMatrix_lusol requires a square, non-empty matrix")) #~ msgid "dgCMatrix_lusol requires a square, non-empty matrix" #~ msgstr "'dgCMatrix_lusol' wymaga kwadratowej, niepustej macierzy" # Matrix/src/dppMatrix.c: 81 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dpoMatrix.c: 92 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dpoMatrix.c: 117 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dsyMatrix.c: 85 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dtCMatrix.c: 90 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dtCMatrix.c: 106 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dgCMatrix.c: 158 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dgCMatrix.c: 184 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dgCMatrix.c: 438 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dgCMatrix.c: 471 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dtrMatrix.c: 99 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dgeMatrix.c: 423 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dspMatrix.c: 79 # error(_("Dimensions of system to be solved are inconsistent")) #~ msgid "Dimensions of system to be solved are inconsistent" #~ msgstr "Wymiary systemu, który ma być rozwiązany, są niespójne" # Matrix/src/dgCMatrix.c: 160 # error(_("cs_lusol failed")) #~ msgid "cs_lusol failed" #~ msgstr "'cs_lusol' nie powiódł się" # Matrix/src/dgCMatrix.c: 181 # error(_("'dgCMatrix_qrsol(., order)' function needs order in {0,..,3}")) #~ msgid "dgCMatrix_qrsol(., order) needs order in {0,..,3}" #~ msgstr "" #~ "funkcja 'dgCMatrix_qrsol(., order)' potrzebuje zmiennej 'order' ze zbioru " #~ "{0,..,3}" # Matrix/src/dgCMatrix.c: 190 # error(_("'dgCMatrix_qrsol(<%d x %d>-matrix)' function requires a 'tall' rectangular matrix"), # xc->m, xc->n) #, c-format #~ msgid "" #~ "dgCMatrix_qrsol(<%d x %d>-matrix) requires a 'tall' rectangular matrix" #~ msgstr "" #~ "funkcja 'dgCMatrix_qrsol(macierz <%d x %d>)' wymaga długiej prostokątnej " #~ "macierzy" # Matrix/src/dgCMatrix.c: 201 # error(_("'cs_qrsol()' function failed inside 'dgCMatrix_qrsol()' function")) #~ msgid "cs_qrsol() failed inside dgCMatrix_qrsol()" #~ msgstr "" #~ "funkcja 'cs_qrsol()' nie powiodła się wewnątrz funkcji 'dgCMatrix_qrsol()'" # Matrix/src/dgCMatrix.c: 469 # error(_("'dgCMatrix_cholsol' function requires a 'short, wide' rectangular matrix")) #~ msgid "dgCMatrix_cholsol requires a 'short, wide' rectangular matrix" #~ msgstr "" #~ "funkcja 'dgCMatrix_cholsol()' wymaga krótkiej lub szerokiej macierzy " #~ "prostokątnej" # Matrix/src/dgCMatrix.c: 477 # error(_("'cholmod_sdmult' function error (rhs)")) #~ msgid "cholmod_sdmult error (rhs)" #~ msgstr "błąd funkcji 'cholmod_sdmult' (prawa strona)" # Matrix/src/CHMfactor.c: 135 # error(_("cholmod_factorize_p failed: status %d, minor %d of ncol %d"), # c.status, f->minor, f->n) #, c-format #~ msgid "cholmod_factorize failed: status %d, minor %d from ncol %d" #~ msgstr "" #~ "'cholmod_factorize_p' nie powiódł się: status %d, minor %d liczba kolumn " #~ "%d" # Matrix/src/dgCMatrix.c: 484 # error(_("'cholmod_solve' function (CHOLMOD_A) failed: status %d, minor %d from ncol %d"), # c.status, L->minor, L->n) #, c-format #~ msgid "cholmod_solve (CHOLMOD_A) failed: status %d, minor %d from ncol %d" #~ msgstr "" #~ "funkcja 'cholmod_solve' (CHOLMOD_A) nie powiodła się: status %d, minor %d " #~ "z liczbą kolumn %d" # Matrix/src/dgCMatrix.c: 501 # error(_("'cholmod_sdmult' function error (resid)")) #~ msgid "cholmod_sdmult error (resid)" #~ msgstr "błąd funkcji 'cholmod_sdmult' (reszta)" # Matrix/src/dgCMatrix.c: 293 # error(_("'SuiteSparseQR_C_QR' function returned an error code")) #~ msgid "SuiteSparseQR_C_QR returned an error code" #~ msgstr "funkcja 'SuiteSparseQR_C_QR()' zwróciła kod błędu" # Matrix/src/dgeMatrix.c: 428 # error(_("Lapack routine 'dgetrs()': system is exactly singular")) #, fuzzy, c-format #~ msgid "LAPACK routine '%s': matrix is exactly singular, %s[i,i]=0, i=%d" #~ msgstr "procedura Lapack 'dgetrs()': system jest ściśle osobliwy" # Matrix/src/dppMatrix.c: 34 # error(_("the leading minor of order %d is not positive definite"), # info) # Matrix/src/dpoMatrix.c: 40 # error(_("the leading minor of order %d is not positive definite"), # info) #, fuzzy, c-format #~ msgid "" #~ "LAPACK routine '%s': leading principal minor of order %d is not positive" #~ msgstr "wiodący minor rzędu %d nie jest dodatnio określony" # Matrix/src/init.c: 356 # error(_("missing 'Matrix' namespace: should never happen")) #, fuzzy #~ msgid "missing 'Matrix' namespace; should never happen" #~ msgstr "brakuje przestrzeni nazw 'Matrix': nie powinno się wydarzyć" # Matrix/src/init.c: 367 # error(_("Matrix namespace not determined correctly")) #, fuzzy #~ msgid "'Matrix' namespace not determined correctly" #~ msgstr "przestrzeń nazw macierzy nie została poprawnie określona" # Matrix/src/Csparse.c: 55 # warning(_("Csparse_sort(x): x is not a valid (apart from sorting) CsparseMatrix")) #~ msgid "Csparse_sort(x): x is not a valid (apart from sorting) CsparseMatrix" #~ msgstr "" #~ "Csparse_sort(x): 'x' nie jest poprawnym (niezależnie od sortowania) " #~ "obiektem klasy \"CsparseMatrix\"" # Matrix/src/cs_utils.c: 37 # error(_("'csp_eye' function's argument 'n' must be positive")) #~ msgid "csp_eye argument n must be positive" #~ msgstr "argument 'n' w funkcji 'csp_eye()' musi być dodatni" # Matrix/src/cs_utils.c: 68 # error(_("invalid class of 'x' argument in 'Matrix_as_cs(a, x)' function")) #~ msgid "invalid class of 'x' in Matrix_as_cs(a, x)" #~ msgstr "niepoprawna klasa argumentu 'x' w funkcji 'Matrix_as_cs(a, x)'" # Matrix/src/cs_utils.c: 170 # error(_("invalid class of object to %s"), "Matrix_as_css") # Matrix/src/cs_utils.c: 185 # error(_("invalid class of object to %s"), "Matrix_as_css") # Matrix/src/cs_utils.c: 205 # error(_("invalid class of object to %s"), "Matrix_as_csn") # Matrix/src/cs_utils.c: 218 # error(_("invalid class of object to %s"), "Matrix_as_csn") #, c-format #~ msgid "invalid class of object to %s" #~ msgstr "niepoprawna klasa obiektu przekazanego do '%s'" # Matrix/src/cs_utils.c: 139 # error(_("cs matrix not compatible with class '%s'"), valid[ctype]) #, c-format #~ msgid "cs matrix not compatible with class '%s'" #~ msgstr "'cs matrix' nie jest zgodne z klasą '%s'" # Matrix/src/cs_utils.c: 242 # error(_("Inappropriate class cl='%s' in Matrix_css_to_SEXP(S, cl, ..)"), # cl) # Matrix/src/cs_utils.c: 261 # error(_("Inappropriate class cl='%s' in Matrix_css_to_SEXP(S, cl, ..)"), # cl) #, c-format #~ msgid "Inappropriate class cl='%s' in Matrix_css_to_SEXP(S, cl, ..)" #~ msgstr "Niepoprawna klasa cl='%s' w 'Matrix_css_to_SEXP(S, cl, ..)'" # Matrix/src/cs_utils.c: 287 # error(_("Inappropriate class cl='%s' in Matrix_csn_to_SEXP(S, cl, ..)"), # cl) # Matrix/src/cs_utils.c: 306 # error(_("Inappropriate class cl='%s' in Matrix_csn_to_SEXP(S, cl, ..)"), # cl) #, c-format #~ msgid "Inappropriate class cl='%s' in Matrix_csn_to_SEXP(S, cl, ..)" #~ msgstr "Niepoprawna klasa cl='%s' w 'Matrix_csn_to_SEXP(S, cl, ..)'" # Matrix/src/dgeMatrix.c: 127 # error(_("Dimensions of 'x' and 'y' are not compatible for '%s'"), # tr ? "tcrossprod" : "crossprod") # Matrix/src/dgeMatrix.c: 184 # error(_("Dimensions of 'x' and 'y' are not compatible for '%s'"), # tr ? "tcrossprod" : "crossprod") #, c-format #~ msgid "Dimensions of x and y are not compatible for %s" #~ msgstr "Wymiary 'x' oraz 'y' nie są zgodne dla '%s'" # Matrix/src/dgeMatrix.c: 166 # error(_("'y' argument must be numeric or integer")) #, fuzzy #~ msgid "Argument y must be numeric, integer or logical" #~ msgstr "Argument 'y' musi być liczbą lub rzeczywistą lub całkowitą" # Matrix/src/dsyMatrix.c: 122 # error(_("Matrices are not conformable for multiplication")) # Matrix/src/dtrMatrix.c: 123 # error(_("Matrices are not conformable for multiplication")) # Matrix/src/dgeMatrix.c: 447 # error(_("Matrices are not conformable for multiplication")) # Matrix/src/dgeMatrix.c: 469 # error(_("Matrices are not conformable for multiplication")) # Matrix/src/dspMatrix.c: 153 # error(_("Matrices are not conformable for multiplication")) #~ msgid "Matrices are not conformable for multiplication" #~ msgstr "Macierze nie są dostosowane do przemnożenia" # Matrix/src/dtrMatrix.c: 121 # error(_("object of class \"dtrMatrix\" must be square")) #~ msgid "dtrMatrix must be square" #~ msgstr "obiekt klasy \"dtrMatrix\" musi być kwadratowy" # Matrix/src/dtpMatrix.c: 125 # error(_("Dimensions of 'a' (%d,%d) and 'b' (%d,%d) do not conform"), # xDim[0], xDim[1], yDim[0], yDim[1]) # Matrix/src/dtpMatrix.c: 153 # error(_("Dimensions of 'a' (%d,%d) and 'b' (%d,%d) do not conform"), # aDim[0], aDim[1], bDim[0], bDim[1]) # Matrix/src/dtpMatrix.c: 184 # error(_("Dimensions of 'a' (%d,%d) and 'b' (%d,%d) do not conform"), # xDim[0], xDim[1], yDim[0], yDim[1]) #, c-format #~ msgid "Dimensions of a (%d,%d) and b (%d,%d) do not conform" #~ msgstr "Wymiary 'a' (%d,%d) oraz 'b' (%d,%d) nie pokrywają się" # Matrix/src/dtpMatrix.c: 132 # error(_("right=TRUE is not yet implemented __ FIXME")) #~ msgid "right=TRUE is not yet implemented __ FIXME" #~ msgstr "'right = TRUE' nie jest jeszcze zaimplementowane __ NAPRAW_MNIE" # Matrix/src/CHMfactor.c: 14 # error(_("cholmod_change_factor failed with status %d"), c.status) #, c-format #~ msgid "cholmod_change_factor failed with status %d" #~ msgstr "'cholmod_change_factor' nie powiódł się zwracając status %d" # Matrix/src/CHMfactor.c: 30 # error(_("system argument is not valid")) # Matrix/src/CHMfactor.c: 60 # error(_("system argument is not valid")) #~ msgid "system argument is not valid" #~ msgstr "argument systemowy nie jest poprawny" # Matrix/src/CHMfactor.c: 47 # error(_("cholmod_updown() returned %d"), r) #, c-format #~ msgid "cholmod_updown() returned %d" #~ msgstr "cholmod_updown() zwróciło %d" # Matrix/src/Csparse.c: 455 # error(_("cholmod_drop() failed")) #~ msgid "cholmod_drop() failed" #~ msgstr "'cholmod_drop()' nie powiódł się" # Matrix/src/Mutils.c: 257 # _("'%s' slot must have length 1") #, fuzzy #~ msgid "'off' does not have length 1" #~ msgstr "gniazdo '%s' musi mieć długość 1" # Matrix/src/Mutils.c: 794 # error(_("invalid class \"%s\" passed to 'dup_mMatrix_as_dgeMatrix' function"), # class_P(A)) #, fuzzy #~ msgid "invalid 'code' to 'R_matrix_as_dense()'" #~ msgstr "" #~ "niepoprawna klasa \"%s\" przekazana do funkcji " #~ "'dup_mMatrix_as_dgeMatrix()'" # Matrix/src/Mutils.c: 794 # error(_("invalid class \"%s\" passed to 'dup_mMatrix_as_dgeMatrix' function"), # class_P(A)) #, fuzzy #~ msgid "invalid 'uplo' to 'R_matrix_as_dense()'" #~ msgstr "" #~ "niepoprawna klasa \"%s\" przekazana do funkcji " #~ "'dup_mMatrix_as_dgeMatrix()'" # Matrix/src/Mutils.c: 794 # error(_("invalid class \"%s\" passed to 'dup_mMatrix_as_dgeMatrix' function"), # class_P(A)) #, fuzzy #~ msgid "invalid 'diag' to 'R_matrix_as_dense()'" #~ msgstr "" #~ "niepoprawna klasa \"%s\" przekazana do funkcji " #~ "'dup_mMatrix_as_dgeMatrix()'" # Matrix/src/Mutils.c: 990 # error(_("invalid '%s' argument"), "byrow") #, fuzzy #~ msgid "invalid argument 'system'" #~ msgstr "niepoprawny argument '%s'" # Matrix/src/dppMatrix.c: 81 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dpoMatrix.c: 92 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dpoMatrix.c: 117 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dsyMatrix.c: 85 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dtCMatrix.c: 90 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dtCMatrix.c: 106 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dgCMatrix.c: 158 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dgCMatrix.c: 184 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dgCMatrix.c: 438 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dgCMatrix.c: 471 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dtrMatrix.c: 99 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dgeMatrix.c: 423 # error(_("Dimensions of system to be solved are inconsistent")) # Matrix/src/dspMatrix.c: 79 # error(_("Dimensions of system to be solved are inconsistent")) #, fuzzy #~ msgid "dimensions of 'qr' and 'y' are inconsistent" #~ msgstr "Wymiary systemu, który ma być rozwiązany, są niespójne" # Matrix/src/Mutils.c: 990 # error(_("invalid '%s' argument"), "byrow") #, fuzzy #~ msgid "invalid 'op'" #~ msgstr "niepoprawny argument '%s'" # Matrix/src/Mutils.c: 330 # error(_("'uplo' must be UPP or LOW")) # Matrix/src/Mutils.c: 356 # error(_("'uplo' must be UPP or LOW")) #, fuzzy #~ msgid "'names' must be TRUE or FALSE" #~ msgstr "'uplo' musi być UPP lub LOW" # Matrix/src/Csparse.c: 423 # error(_("Csparse_crossprod(): error return from cholmod_aat()")) #~ msgid "Csparse_crossprod(): error return from cholmod_aat()" #~ msgstr "Csparse_crossprod(): błąd zwrócony z 'cholmod_aat()'" # Matrix/src/t_Csparse_subassign.c: 144 # error(_("invalid class of 'x' in 'Csparse_subassign()' function")) #, fuzzy #~ msgid "invalid 'kind' to 'R_sparse_as_kind()'" #~ msgstr "niepoprawna klasa 'x' w funkcji 'Csparse_subassign()'" # Matrix/src/Csparse.c: 73 # (_("slot p must have length = nrow(.) + 1")) #~ msgid "slot p must have length = nrow(.) + 1" #~ msgstr "gniazdo 'p' musi mieć długość = nrow(.) + 1" # Matrix/src/Csparse.c: 78 # (_("last element of slot p must match length of slots j and x")) #~ msgid "last element of slot p must match length of slots j and x" #~ msgstr "" #~ "ostatni element gniazda 'p' musi zgadzać się długością z gniazdem 'j' " #~ "oraz 'x'" # Matrix/src/Csparse.c: 81 # (_("all column indices must be between 0 and ncol-1")) #~ msgid "all column indices must be between 0 and ncol-1" #~ msgstr "wszystkie indeksy kolumn muszą być pomiędzy 0 a 'ncol-1'" # Matrix/src/Csparse.c: 99 # (_("slot j is not *strictly* increasing inside a column")) #~ msgid "slot j is not *strictly* increasing inside a column" #~ msgstr "gniazdo 'j' nie jest *ściśle* rosnące wewnątrz kolumny" #~ msgid "not a 'n.CMatrix'" #~ msgstr "to nie jest 'n.Cmatrix'" # Matrix/src/Csparse.c: 172 # error(_("nz2Csparse(): invalid/non-implemented r_kind = %d"), # r_kind) #, c-format #~ msgid "nz2Csparse(): invalid/non-implemented r_kind = %d" #~ msgstr "nz2Csparse(): niepoprawny/niezaimplementowany 'r_kind = %d'" # Matrix/src/Csparse.c: 221 # error(_("Nonsymmetric matrix in Csparse_symmetric_to_general")) #~ msgid "Nonsymmetric matrix in Csparse_symmetric_to_general" #~ msgstr "Niesymetryczna macierz w 'Csparse_symmetric_to_general'" # Matrix/src/Csparse.c: 232 # error(_("Csparse_general_to_symmetric(): matrix is not square!")) #~ msgid "Csparse_general_to_symmetric(): matrix is not square!" #~ msgstr "Csparse_general_to_symmetric(): macierz nie jest kwadratowa!" # Matrix/src/Csparse.c: 568 # error(_("Index i must be NULL or integer")) #~ msgid "Index i must be NULL or integer" #~ msgstr "Indeks 'i' musi być wartością NULL lub być liczbą całkowitą" # Matrix/src/Csparse.c: 570 # error(_("Index j must be NULL or integer")) #~ msgid "Index j must be NULL or integer" #~ msgstr "Indeks 'j' musi być wartością NULL lub być liczbą całkowitą" # Matrix/src/Csparse.c: 760 # error(_("negative vector lengths not allowed: np = %d, nnz = %d"), # np, nnz) #, c-format #~ msgid "negative vector lengths not allowed: np = %d, nnz = %d" #~ msgstr "ujemne długości wektora nie są dozwolone: np = %d, nnz = %d" # Matrix/src/Csparse.c: 765 # error(_("exactly 1 of 'i', 'j' or 'p' must be NULL")) #~ msgid "exactly 1 of 'i', 'j' or 'p' must be NULL" #~ msgstr "dokładnie jeden z 'i', 'j' lub 'p' musi być wartością NULL" # Matrix/src/Csparse.c: 767 # error(_("np = %d, must be zero when p is NULL"), np) #, c-format #~ msgid "np = %d, must be zero when p is NULL" #~ msgstr "np = %d, musi wynosić zero gdy 'p' ma wartość NULL" # Matrix/src/Csparse.c: 770 # error(_("p[0] = %d, should be zero"), p[0]) #, c-format #~ msgid "p[0] = %d, should be zero" #~ msgstr "'p[0] = %d', powinno być zero" # Matrix/src/Csparse.c: 773 # error(_("p must be non-decreasing")) #~ msgid "p must be non-decreasing" #~ msgstr "'p' musi być niemalejące" # Matrix/src/Csparse.c: 789 # error(_("Inconsistent dimensions: np = 0 and nnz = %d"), # nnz) #, c-format #~ msgid "Inconsistent dimensions: np = 0 and nnz = %d" #~ msgstr "Niespójne wymiary: 'np = 0' oraz 'nnz = %d'" # Matrix/src/Csparse.c: 804 # error(_("invalid column index at position %d"), jj) #, c-format #~ msgid "invalid column index at position %d" #~ msgstr "niepoprawny indeks kolumny na pozycji %d" # Matrix/src/Csparse.c: 814 # error(_("strlen of cls argument = %d, should be 8"), strlen(cls)) #, c-format #~ msgid "strlen of cls argument = %d, should be 8" #~ msgstr "długość argumentu 'cls = %d', powinna wynosić 8" # Matrix/src/Csparse.c: 816 # error(_("cls = \"%s\" does not end in \"CMatrix\""), cls) #, c-format #~ msgid "cls = \"%s\" does not end in \"CMatrix\"" #~ msgstr "'cls = \"%s\"' nie kończy się w 'CMatrix'" # Matrix/src/Csparse.c: 826 # error(_("cls = \"%s\" must begin with 'd', 'l' or 'n'"), cls) #, c-format #~ msgid "cls = \"%s\" must begin with 'd', 'l' or 'n'" #~ msgstr "'cls = \"%s\"' musi rozpoczynać się od 'd', 'l' lub 'n'" # Matrix/src/Csparse.c: 829 # error(_("Only 'g'eneral sparse matrix types allowed")) #~ msgid "Only 'g'eneral sparse matrix types allowed" #~ msgstr "Tylko ogólne ('g') typy rzadkich macierzy są dozwolone" # Matrix/src/Csparse.c: 857 # error(_("code not yet written for cls = \"lgCMatrix\"")) #~ msgid "code not yet written for cls = \"lgCMatrix\"" #~ msgstr "kod dla 'cls = \"lgCMatrix\"' nie został jeszcze napisany" # Matrix/src/lgCMatrix.c: 58 # error(_("'A' must be a logical matrix")) #, fuzzy, c-format #~ msgid "%s must be (traditional R) matrix" #~ msgstr "'A' musi być macierzą logiczną" # Matrix/src/Mutils.c: 287 # error(_("'s1' and 's2' must be \"character\" vectors")) #, fuzzy, c-format #~ msgid "%s must be character string" #~ msgstr "'s1' oraz 's2' muszą być wektorami tekstowymi" # Matrix/src/Csparse.c: 814 # error(_("strlen of cls argument = %d, should be 8"), strlen(cls)) #, fuzzy, c-format #~ msgid "strlen of cls argument = %d, should be 9" #~ msgstr "długość argumentu 'cls = %d', powinna wynosić 8" # Matrix/src/Csparse.c: 826 # error(_("cls = \"%s\" must begin with 'd', 'l' or 'n'"), cls) #, fuzzy, c-format #~ msgid "cls = \"%s\" must begin with 'd', 'l' or 'n' for now" #~ msgstr "'cls = \"%s\"' musi rozpoczynać się od 'd', 'l' lub 'n'" # Matrix/src/lgCMatrix.c: 58 # error(_("'A' must be a logical matrix")) #, fuzzy, c-format #~ msgid "%s must be a logical or double vector" #~ msgstr "'A' musi być macierzą logiczną" # Matrix/src/Mutils.c: 22 # error(_("argument type[1]='%s' must be one of 'M','1','O','I','F' or 'E'"), # typstr) #, c-format #~ msgid "argument type[1]='%s' must be one of 'M','1','O','I','F' or 'E'" #~ msgstr "argument type[1]='%s' musi być jednym z 'M','1','O','I','F' lub 'E'" # Matrix/src/Mutils.c: 39 # error(_("argument type[1]='%s' must be one of '1','O', or 'I'"), # typstr) #, c-format #~ msgid "argument type[1]='%s' must be one of '1','O', or 'I'" #~ msgstr "argument type[1]='%s' musi być jednym z '1','O', lub 'I'" # Matrix/src/Mutils.c: 50 # error(_("object must be a named, numeric vector")) # Matrix/src/Mutils.c: 66 # error(_("object must be a named, numeric vector")) #~ msgid "object must be a named, numeric vector" #~ msgstr "obiekt musi być nazwanym wektorem liczbowym" # Matrix/src/Mutils.c: 113 # error(_("'factors' slot must be a named list")) # Matrix/src/Mutils.c: 137 # error(_("'factors' slot must be a named list")) #~ msgid "'factors' slot must be a named list" #~ msgstr "gniazdo 'factors' musi być nazwaną listą" # Matrix/src/Mutils.c: 287 # error(_("'s1' and 's2' must be \"character\" vectors")) #~ msgid "'s1' and 's2' must be \"character\" vectors" #~ msgstr "'s1' oraz 's2' muszą być wektorami tekstowymi" # Matrix/src/Mutils.c: 309 # (_("length of 'x' slot is not equal to 'prod(Dim)'")) #~ msgid "length of x slot != prod(Dim)" #~ msgstr "długość gniazda 'x' nie równa się 'prod(Dim)'" # Matrix/src/dgeMatrix.c: 14 # ngettext("Matrix", # "Negative value in 'Dim' slot", # "Negative values in 'Dim' slot", # (m*n > 0) ? 2 : 1) #~ msgid "Negative value in Dim" #~ msgid_plural "Negative values in Dim" #~ msgstr[0] "Ujemna wartość w gnieździe 'Dim'" #~ msgstr[1] "Ujemne wartości w gnieździe 'Dim'" #~ msgstr[2] "Ujemne wartości w gnieździe 'Dim'" # Matrix/src/Mutils.c: 643 # error(_("invalid class \"%s\" passed to 'dup_mMatrix_as_geMatrix' function"), # class_P(A)) #, c-format #~ msgid "invalid class '%s' to dup_mMatrix_as_geMatrix" #~ msgstr "" #~ "niepoprawna klasa \"%s\" przekazana do funkcji 'dup_mMatrix_as_geMatrix()'" # Matrix/src/Mutils.c: 763 # error(_("unexpected ctype = %d in 'dup_mMatrix_as_geMatrix' function"), ctype) #, c-format #~ msgid "unexpected ctype = %d in dup_mMatrix_as_geMatrix" #~ msgstr "nieoczekiwany 'ctype = %d' w funkcji 'dup_mMatrix_as_geMatrix()'" # Matrix/src/Tsparse.c: 20 # (_("lengths of slots i and j must match")) #~ msgid "lengths of slots i and j must match" #~ msgstr "długość gniazd 'i' oraz 'j' musi się zgadzać" # Matrix/src/Tsparse.c: 23 # (_("slot 'dim' must have length 2")) #~ msgid "slot Dim must have length 2" #~ msgstr "gniazdo 'dim' musi mieć długość 2" # Matrix/src/Tsparse.c: 27 # (_("all row indices (slot 'i') must be between 0 and nrow-1 in a object of class \"TsparseMatrix\"")) #~ msgid "" #~ "all row indices (slot 'i') must be between 0 and nrow-1 in a TsparseMatrix" #~ msgstr "" #~ "wszystkie indeksy wierszy (gniazdo 'i') muszą być pomiędzy 0 a 'nrow-1' w " #~ "obiekcie klasy \"TsparseMatrix\"" # Matrix/src/Tsparse.c: 29 # (_("all column indices (slot 'j') must be between 0 and ncol-1 in a object of class \"TsparseMatrix\"")) #~ msgid "" #~ "all column indices (slot 'j') must be between 0 and ncol-1 in a " #~ "TsparseMatrix" #~ msgstr "" #~ "wszystkie indeksy kolumn (gniazdo 'j') muszą być pomiędzy 0 a 'ncol-1' w " #~ "obiekcie klasy \"TsparseMatrix\"" # Matrix/src/chm_common.c: 948 # error(_("Supernodal LDL decomposition not available")) #~ msgid "Supernodal LDL' decomposition not available" #~ msgstr "Dekompozycja supernodalna LDL nie jest dostępna" # Matrix/src/chm_common.c: 950 # error(_("Supernodal/simplicial class inconsistent with 'type' flags")) #~ msgid "Supernodal/simplicial class inconsistent with type flags" #~ msgstr "klasa supernodal/simplicial niespójna z flagami 'type'" # Matrix/src/chm_common.c: 968 # error(_("Number of supernodes must be positive when 'is_super' argument is TRUE")) #~ msgid "Number of supernodes must be positive when is_super is TRUE" #~ msgstr "" #~ "Liczba super węzłów musi być dodatnia gdy argument 'is_super' ma wartość " #~ "TRUE" # Matrix/src/chm_common.c: 971 # error(_("Lengths of 'super' and 'pi' arguments must be equal")) #~ msgid "Lengths of super and pi must be equal" #~ msgstr "Długości 'super' oraz 'pi' muszą być równe" # Matrix/src/chm_common.c: 975 # error(_("Lengths of 'super' and 'px' arguments must be equal")) #~ msgid "Lengths of super and px must be equal" #~ msgstr "Długości 'super' oraz 'px' muszą być równe" # Matrix/src/dense.c: 155 # error(_("First call to Lapack routine 'dgels' returned error code %d"), info) #, c-format #~ msgid "First call to Lapack routine dgels returned error code %d" #~ msgstr "Pierwsze wywołanie procedury Lapack 'dgels()' zwróciło kod błędu %d" # Matrix/src/dense.c: 161 # error(_("Second call to Lapack routine 'dgels' returned error code %d"), info) #, c-format #~ msgid "Second call to Lapack routine dgels returned error code %d" #~ msgstr "Drugie wywołanie procedury Lapack 'dgels()' zwróciło kod błędu %d" # Matrix/src/dense.c: 174 # error(_("'tol' argument, given as %g, must be non-negative"), tol) #, c-format #~ msgid "tol, given as %g, must be non-negative" #~ msgstr "argument 'tol', podany jako %g, musi być nieujemny" # Matrix/src/dense.c: 205 # error(_("Second call to 'dgeqrf' returned error code %d"), info) #, c-format #~ msgid "Second call to dgeqrf returned error code %d" #~ msgstr "Drugie wywołanie 'dgeqrf()' zwróciło kod %d" # Matrix/src/dense.c: 279 # error(_("Lower band %d is greater than upper band %d"), k1, k2) #, c-format #~ msgid "Lower band %d > upper band %d" #~ msgstr "Niższe pasmo %d jest większe niż górne pasmo %d" # Matrix/src/dense.c: 348 # error(_("ddense_to_symmetric(): matrix is not square!")) #~ msgid "ddense_to_symmetric(): matrix is not square!" #~ msgstr "ddense_to_symmetric(): macierz nie jest kwadratowa!" # Matrix/src/dense.c: 359 # error(_("matrix is not symmetric [%d,%d]"), i+1, j+1) #, c-format #~ msgid "matrix is not symmetric [%d,%d]" #~ msgstr "macierz nie jest symetryczna [%d,%d]" # Matrix/src/dense.c: 407 # error(_("matrix is not square! (symmetric part)")) #~ msgid "matrix is not square! (symmetric part)" #~ msgstr "macierz nie jest kwadratowa! (część symetryczna)" # Matrix/src/dense.c: 451 # error(_("matrix is not square! (skew-symmetric part)")) #~ msgid "matrix is not square! (skew-symmetric part)" #~ msgstr "macierz nie jest kwadratowa! (część skośno-symetryczna)" # Matrix/src/dgTMatrix.c: 15 # (_("lengths of slots 'i' and 'x' must match")) # Matrix/src/dgCMatrix.c: 18 # (_("lengths of slots 'i' and 'x' must match")) #~ msgid "lengths of slots 'i' and 'x' must match" #~ msgstr "długość gniazd 'i' oraz 'x' musi się zgadzać" # Matrix/src/dgCMatrix.c: 30 # (_("lengths of slots 'j' and 'x' must match")) #~ msgid "lengths of slots 'j' and 'x' must match" #~ msgstr "długość gniazd 'j' oraz 'x' musi się zgadzać" # Matrix/src/dgCMatrix.c: 52 # error(_("invalid class(x) '%s' in 'compressed_to_TMatrix(x)' function"), ncl) #, c-format #~ msgid "invalid class(x) '%s' in compressed_to_TMatrix(x)" #~ msgstr "niepoprawne 'class(x)' '%s' w funkcji 'compressed_to_TMatrix(x)'" # Matrix/src/dgCMatrix.c: 86 # error(_("invalid class(x) '%s' in 'R_to_CMatrix(x)' function"), ncl) #, c-format #~ msgid "invalid class(x) '%s' in R_to_CMatrix(x)" #~ msgstr "niepoprawne 'class(x)' '%s' w funkcji 'R_to_CMatrix(x)'" # Matrix/src/dgCMatrix.c: 220 # error(_("'A' must have #{rows} >= #{columns}")) #~ msgid "A must have #{rows} >= #{columns}" #~ msgstr "'A' musi mieć liczbę wierszy >= liczba kolumn" # Matrix/src/dgCMatrix.c: 160 # error(_("cs_lusol failed")) #~ msgid "cs_sqr failed" #~ msgstr "funkcja 'cs_lusol()' nie powiodła się" # Matrix/src/dgCMatrix.c: 337 # error(_("LU decomposition applies only to square matrices")) #~ msgid "LU decomposition applies only to square matrices" #~ msgstr "dekompozycja LU stosuje się tylko do macierzy kwadratowych" # Matrix/src/dgCMatrix.c: 346 # error(_("cs_lu(A) failed: near-singular 'A' (or out of memory)")) #~ msgid "cs_lu(A) failed: near-singular A (or out of memory)" #~ msgstr "" #~ "'cs_lu(A)' nie powiódł się: 'A' jest bliskie osobliwości (lub brak " #~ "pamięci)" # Matrix/src/dgCMatrix.c: 406 # error(_("dgCMatrix_matrix_solve(.., sparse=TRUE) not yet implemented")) #~ msgid "dgCMatrix_matrix_solve(.., sparse=TRUE) not yet implemented" #~ msgstr "" #~ "'dgCMatrix_matrix_solve(.., sparse=TRUE)' nie jest jeszcze " #~ "zaimplementowane" # Matrix/src/Tsparse.c: 20 # (_("lengths of slots i and j must match")) #~ msgid "lengths of slots i and x must match" #~ msgstr "długość gniazd 'i' oraz 'j' musi się zgadzać" # Matrix/src/dgTMatrix.c: 56 # error(_("Cannot coerce to too large '*geMatrix' with %.0f entries"), len) #, c-format #~ msgid "Cannot coerce to too large *geMatrix with %.0f entries" #~ msgstr "Nie można przekształcić do dużego '*geMatrix' z %.0f wpisami" # Matrix/src/dgeMatrix.c: 19 # (_("'x' slot must be numeric \"double\"")) #~ msgid "x slot must be numeric \"double\"" #~ msgstr "gniazdo 'x' musi być liczbą typu \"double\"" # Matrix/src/dgeMatrix.c: 32 # (_("'factors' slot must be named list")) #~ msgid "factors slot must be named list" #~ msgstr "gniazdo 'factors' musi być nazwaną listą" # Matrix/src/dgeMatrix.c: 70 # error(_("'rcond()' function requires a square, non-empty matrix")) #~ msgid "rcond requires a square, non-empty matrix" #~ msgstr "funkcja 'rcond()' wymaga kwadratowej, niepustej macierzy" # Matrix/src/dgeMatrix.c: 307 # error(_("Cannot factor a matrix with zero extents")) #~ msgid "Cannot factor a matrix with zero extents" #~ msgstr "Nie można faktoryzować macierzy o zerowym stopniu" # Matrix/src/dgeMatrix.c: 319 # warning(_("Exact singularity detected during LU decomposition: %s, i=%d."), # "U[i,i]=0", info) #, c-format #~ msgid "Exact singularity detected during LU decomposition: %s, i=%d." #~ msgstr "Wykryto dokładną osobliwość podczas dekompozycji LU: %s, i=%d." # Matrix/src/dgeMatrix.c: 383 # error(_("'solve' function requires a square matrix")) #~ msgid "Solve requires a square matrix" #~ msgstr "funkcja 'solve()' wymaga kwadratowej macierzy" # Matrix/src/dgeMatrix.c: 396 # error(_("error [%d] from Lapack 'dgecon()' function"), info) #, c-format #~ msgid "error [%d] from Lapack 'dgecon()'" #~ msgstr "błąd [%d] z funkcji Lapack 'dgecon()'" # Matrix/src/dgeMatrix.c: 398 # error(_("Lapack dgecon(): system computationally singular, reciprocal condition number = %g"), # rcond) #, c-format #~ msgid "" #~ "Lapack dgecon(): system computationally singular, reciprocal condition " #~ "number = %g" #~ msgstr "" #~ "Lapack dgecon(): system obliczeniowo osobliwy, numer obustronnego stanu = " #~ "%g" # Matrix/src/dgeMatrix.c: 408 # error(_("Lapack routine 'dgetri()': system is exactly singular")) #~ msgid "Lapack routine dgetri: system is exactly singular" #~ msgstr "procedura Lapack 'dgetri()': system jest ściśle osobliwy" # Matrix/src/dpoMatrix.c: 13 # (_("object of class \"dpoMatrix\" is not positive definite")) #~ msgid "dpoMatrix is not positive definite" #~ msgstr "obiekt klasy \"dpoMatrix\" nie jest dodatnio określony" # Matrix/src/dpoMatrix.c: 94 # error(_("Cannot perform 'solve()' function for matrices with zero extents")) #~ msgid "Cannot solve() for matrices with zero extents" #~ msgstr "Nie można wykonać funkcji 'solve()' dla macierzy o zerowym stopniu" # Matrix/src/dpoMatrix.c: 115 # error(_("Argument 'b' must be a numeric matrix")) #~ msgid "Argument b must be a numeric matrix" #~ msgstr "Argument 'b' musi być macierzą liczbową" # Matrix/src/dsCMatrix.c: 25 # error(_("chm_factor_name(): did not get string of length 11")) #~ msgid "chm_factor_name(): did not get string of length 11" #~ msgstr "" #~ "chm_factor_name(): nie uzyskano łańcucha tekstowego o długości 11 znaków" # Matrix/src/dsCMatrix.c: 99 # error(_("Cholesky factorization failed; unusually, please report to Matrix-authors")) #~ msgid "" #~ "Cholesky factorization failed; unusually, please report to Matrix-authors" #~ msgstr "" #~ "faktoryzacja Cholesky'ego nie powiodła się; nietypowo, proszę zgłosić " #~ "raport autorom pakietu Matrix" # Matrix/src/dsCMatrix.c: 105 # error(_("internal_chm_factor: Cholesky factorization failed")) #~ msgid "internal_chm_factor: Cholesky factorization failed" #~ msgstr "internal_chm_factor: faktoryzacja Cholesky'ego nie powiodła się" # Matrix/src/dsCMatrix.c: 241 # error(_("Non-symmetric matrix passed to 'dsCMatrix_to_dgTMatrix' function")) #~ msgid "Non-symmetric matrix passed to dsCMatrix_to_dgTMatrix" #~ msgstr "" #~ "Niesymetryczna macierz przekazana do funkcji 'dsCMatrix_to_dgTMatrix()'" # Matrix/src/dtpMatrix.c: 18 # (_("Incorrect length of 'x' slot")) # Matrix/src/dspMatrix.c: 14 # (_("Incorrect length of 'x' slot")) #~ msgid "Incorrect length of 'x' slot" #~ msgstr "Niepoprawna długość gniazda 'x'" # Matrix/src/dsyMatrix.c: 158 # error(_("Lapack routine 'dsytrf' returned error code %d"), info) #, c-format #~ msgid "Lapack routine dsytrf returned error code %d" #~ msgstr "procedura Lapack 'dsytrf()' zwróciła kod błędu %d" # Matrix/src/dense.c: 173 # error(_("'X' must be a real (numeric) matrix")) #, fuzzy #~ msgid "x must be a \"double\" (numeric) matrix" #~ msgstr "'X' musi być rzeczywistą (liczbową) macierzą" # Matrix/src/dense.c: 348 # error(_("ddense_to_symmetric(): matrix is not square!")) #, fuzzy #~ msgid "matrix_trf(x, *): matrix is not square" #~ msgstr "ddense_to_symmetric(): macierz nie jest kwadratowa!" # Matrix/src/dtrMatrix.c: 248 # error(_("cannot set diag() as long as 'diag = \"U\"'")) #~ msgid "cannot set diag() as long as 'diag = \"U\"'" #~ msgstr "nie można ustawić 'diag()' dopóki 'diag = \"U\"'" # Matrix/src/dtrMatrix.c: 269 # error(_("cannot add diag() as long as 'diag = \"U\"'")) #~ msgid "cannot add diag() as long as 'diag = \"U\"'" #~ msgstr "nie można dodać 'diag()' dopóki 'diag = \"U\"'" # Matrix/src/lgCMatrix.c: 58 # error(_("'A' must be a logical matrix")) #~ msgid "A must be a logical matrix" #~ msgstr "'A' musi być macierzą logiczną" # Matrix/src/sparseQR.c: 13 # (_("'length(p)' must match 'nrow(V)'")) #~ msgid "length(p) must match nrow(V)" #~ msgstr "'length(p)' musi zgadzać się z 'nrow(V)'" # Matrix/src/sparseQR.c: 15 # (_("'length(beta)' must match 'ncol(V)'")) #~ msgid "length(beta) must match ncol(V)" #~ msgstr "'length(beta)' musi zgadzać się z 'ncol(V)'" # Matrix/src/sparseQR.c: 18 # (_("'length(q)' must be zero or 'ncol(R)'")) #~ msgid "length(q) must be zero or ncol(R)" #~ msgstr "'length(q)' musi wynosić zero lub 'ncol(R)'" #, c-format #~ msgid "sparseQR_Qmult(): nrow(y) = %d != %d = nrow(V)" #~ msgstr "sparseQR_Qmult(): nrow(y) = %d != %d = nrow(V)" # Matrix/src/dtrMatrix.c: 161 # error(_("objects of class \"dtrMatrices\" in %*% must have matching (square) dimensions")) #, fuzzy #~ msgid "\"dtrMatrix\" objects in '%*%' must have matching (square) dimension" #~ msgstr "" #~ "obiekty klasy \"dtrMatrix\" w '%*%' muszą mieć pasujące (kwadratowe) " #~ "wymiary." #~ msgid "not a CsparseMatrix" #~ msgstr "to nie jest 'CsparseMatrix'" Matrix/po/it.po0000644000176200001440000015304214521047060013114 0ustar liggesusers# R Italian translation # This file is distributed under the same license as the R package. # Copyright (C) The R Foundation. # Daniele Medri , 2005-2021. # msgid "" msgstr "" "Project-Id-Version: Matrix 1.3-3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-11-02 21:33-0400\n" "PO-Revision-Date: 2021-04-14 12:18+0200\n" "Last-Translator: Daniele Medri \n" "Language-Team: Italian https://github.com/dmedri/R-italian-lang\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 2.2.1\n" #: Csparse.c:26 Csparse.c:318 chm_common.c:165 chm_common.c:291 #: chm_common.c:813 chm_common.c:816 chm_common.c:849 chm_common.c:867 #: dgCMatrix.c:18 dgCMatrix.c:43 dgCMatrix.c:70 dgCMatrix.c:84 dgCMatrix.c:89 #: dgCMatrix.c:94 #, fuzzy, c-format msgid "'%s' failed" msgstr "cs_qr fallita" #: Csparse.c:35 chm_common.c:54 #, fuzzy, c-format msgid "'%s' slot is not increasing within columns after sorting" msgstr "lo slot j non è crescente all'interno di una colonna" #: Csparse.c:77 coerce.c:220 coerce.c:240 coerce.c:250 coerce.c:905 #: coerce.c:911 coerce.c:1015 coerce.c:1501 coerce.c:1521 coerce.c:1531 #: coerce.c:2061 coerce.c:2256 coerce.c:2262 coerce.c:2268 coerce.c:2397 #: coerce.c:2404 coerce.c:2494 coerce.c:2629 coerce.c:2707 coerce.c:2729 #: coerce.c:4327 coerce.c:4396 dense.c:701 products.c:936 products.c:1288 #: solve.c:719 solve.c:968 solve.c:1100 sparse.c:1233 sparse.c:1625 #, fuzzy, c-format msgid "invalid '%s' to '%s'" msgstr "argomento '%s' non valido" #: Csparse.c:316 #, fuzzy, c-format msgid "failed to open file \"%s\" for writing" msgstr "apertura file \"%s\" in scrittura fallita" #: attrib.c:229 #, fuzzy msgid "invalid factor name" msgstr "argomento '%s' non valido" #: attrib.c:233 #, c-format msgid "attempt to set factor on %s without '%s' slot" msgstr "" #: bind.c:46 bind.c:153 msgid "number of rows of matrices must match" msgstr "" #: bind.c:48 bind.c:155 msgid "number of columns of matrices must match" msgstr "" #: bind.c:51 bind.c:158 bind.c:182 bind.c:206 chm_common.c:474 chm_common.c:623 #: chm_common.c:717 cholmod-etc.c:183 cholmod-etc.c:282 cholmod-etc.c:325 #: coerce.c:215 coerce.c:235 coerce.c:260 coerce.c:268 coerce.c:276 #: coerce.c:341 coerce.c:1496 coerce.c:1516 coerce.c:1543 coerce.c:1551 #: coerce.c:1559 products.c:28 products.c:50 products.c:56 #, c-format msgid "dimensions cannot exceed %s" msgstr "" #: bind.c:210 msgid "number of rows of result is not a multiple of vector length" msgstr "" #: bind.c:212 msgid "number of columns of result is not a multiple of vector length" msgstr "" #: bind.c:626 bind.c:691 sparse.c:912 sparse.c:993 #, c-format msgid "%s cannot exceed %s" msgstr "" #: bind.c:756 bind.c:853 chm_common.c:720 cholmod-etc.c:328 coerce.c:29 #: coerce.c:518 coerce.c:811 coerce.c:945 coerce.c:2772 coerce.c:3041 #: coerce.c:3139 dense.c:924 products.c:151 products.c:212 products.c:291 #: products.c:379 products.c:456 products.c:550 products.c:865 subscript.c:1232 #: subscript.c:1417 utils-R.c:32 #, c-format msgid "attempt to allocate vector of length exceeding %s" msgstr "" #: bind.c:858 products.c:1354 msgid "should never happen ..." msgstr "" #: chm_common.c:11 chm_common.c:34 validity.c:38 validity.c:183 validity.c:262 #: validity.c:281 validity.c:290 validity.c:309 validity.c:335 validity.c:355 #: validity.c:405 validity.c:422 validity.c:456 validity.c:473 validity.c:507 #: validity.c:509 validity.c:959 validity.c:992 validity.c:1074 validity.c:1094 #: validity.c:1160 validity.c:1162 validity.c:1210 validity.c:1273 #: validity.c:1275 validity.c:1321 validity.c:1368 validity.c:1417 #: validity.c:1450 validity.c:1460 validity.c:1473 validity.c:1527 #: validity.c:1529 validity.c:1561 validity.c:1573 validity.c:1596 #: validity.c:1659 validity.c:1678 validity.c:1680 validity.c:1712 #: validity.c:1747 validity.c:1775 #, fuzzy, c-format msgid "'%s' slot is not of type \"%s\"" msgstr "Lo slot dim non è intero" #: chm_common.c:14 validity.c:357 validity.c:407 validity.c:458 validity.c:880 #: validity.c:891 validity.c:961 validity.c:994 validity.c:1096 validity.c:1164 #: validity.c:1212 validity.c:1277 validity.c:1323 validity.c:1462 #: validity.c:1479 validity.c:1531 validity.c:1533 validity.c:1563 #: validity.c:1575 validity.c:1598 validity.c:1714 validity.c:1751 #: validity.c:1779 validity.c:1829 #, fuzzy, c-format msgid "'%s' slot does not have length %s" msgstr "Lo slot dim deve avere lunghezza 2" #: chm_common.c:18 validity.c:410 validity.c:461 validity.c:1667 #: validity.c:1687 validity.c:1689 #, fuzzy, c-format msgid "first element of '%s' slot is not 0" msgstr "il primo elemento dello slot p dev'essere zero" #: chm_common.c:23 chm_common.c:46 validity.c:43 validity.c:361 validity.c:414 #: validity.c:432 validity.c:465 validity.c:483 validity.c:519 validity.c:521 #: validity.c:1041 validity.c:1053 validity.c:1100 validity.c:1173 #: validity.c:1185 validity.c:1286 validity.c:1298 validity.c:1327 #: validity.c:1378 validity.c:1427 validity.c:1466 validity.c:1486 #: validity.c:1567 validity.c:1583 validity.c:1608 validity.c:1672 #: validity.c:1692 validity.c:1694 validity.c:1721 #, c-format msgid "'%s' slot contains NA" msgstr "" #: chm_common.c:26 validity.c:416 validity.c:467 #, fuzzy, c-format msgid "'%s' slot is not nondecreasing" msgstr "lo slot p dev'essere non decrescente" #: chm_common.c:29 validity.c:418 validity.c:469 #, c-format msgid "first differences of '%s' slot exceed %s" msgstr "" #: chm_common.c:37 validity.c:424 validity.c:475 #, fuzzy, c-format msgid "'%s' slot has length less than %s" msgstr "lo slot 'Dim' ha lunghezza inferiore a due" #: chm_common.c:49 validity.c:363 validity.c:434 validity.c:485 validity.c:523 #: validity.c:526 validity.c:1043 validity.c:1102 validity.c:1175 #: validity.c:1187 validity.c:1288 validity.c:1300 validity.c:1380 #: validity.c:1429 validity.c:1488 validity.c:1610 validity.c:1723 #, fuzzy, c-format msgid "'%s' slot has elements not in {%s}" msgstr "lo slot 'Dim' ha lunghezza inferiore a due" #: chm_common.c:467 chm_common.c:470 chm_common.c:472 chm_common.c:616 #: chm_common.c:619 chm_common.c:621 chm_common.c:711 chm_common.c:713 #: cholmod-etc.c:177 cholmod-etc.c:179 cholmod-etc.c:181 cholmod-etc.c:276 #: cholmod-etc.c:278 cholmod-etc.c:280 cholmod-etc.c:319 cholmod-etc.c:321 #: cs-etc.c:43 #, c-format msgid "wrong '%s'" msgstr "" #: chm_common.c:477 cholmod-etc.c:186 #, fuzzy, c-format msgid "'%s' would overflow type \"%s\"" msgstr "Lo slot dim non è intero" #: chm_common.c:481 cholmod-etc.c:190 #, c-format msgid "n+1 would overflow type \"%s\"" msgstr "" #: chm_common.c:486 cholmod-etc.c:195 #, fuzzy, c-format msgid "leading principal minor of order %d is not positive" msgstr "il minore principale dell'ordine %d non è definito positivo" #: chm_common.c:489 cholmod-etc.c:198 #, fuzzy, c-format msgid "leading principal minor of order %d is zero" msgstr "il minore principale dell'ordine %d non è definito positivo" #: chm_common.c:715 cholmod-etc.c:323 msgid "leading dimension not equal to number of rows" msgstr "" #: chm_common.c:778 #, c-format msgid "" "invalid simplicial Cholesky factorization: structural zero on main diagonal " "in column %d" msgstr "" #: chm_common.c:838 #, fuzzy, c-format msgid "CHOLMOD error '%s' at file '%s', line %d" msgstr "Errore cholmod '%s' nel file %s, linea %d" #: chm_common.c:841 #, fuzzy, c-format msgid "CHOLMOD warning '%s' at file '%s', line %d" msgstr "Avvertimento cholmod '%s' nel file %s, linea %d" #: coerce.c:24 coerce.c:364 coerce.c:1050 #, fuzzy, c-format msgid "attempt to construct non-square %s" msgstr "Il determinante richiede una matrice quadrata" #: coerce.c:186 coerce.c:476 coerce.c:1467 coerce.c:1622 #, c-format msgid "second argument of '%s' does not specify a subclass of %s" msgstr "" #: coerce.c:194 coerce.c:200 coerce.c:484 coerce.c:490 coerce.c:925 #: coerce.c:1475 coerce.c:1481 coerce.c:1630 coerce.c:1636 coerce.c:2275 #: coerce.c:3344 coerce.c:3349 #, fuzzy, c-format msgid "'%s' must be \"%s\" or \"%s\"" msgstr "'%s' dev'essere in '%s'" #: coerce.c:246 coerce.c:496 coerce.c:793 coerce.c:917 coerce.c:1527 #: coerce.c:1642 dense.c:322 dense.c:1107 dense.c:1683 dense.c:1688 #: dense.c:1934 dense.c:2129 sparse.c:783 sparse.c:2448 sparse.c:3140 #: sparse.c:3145 sparse.c:3150 sparse.c:3426 sparse.c:3663 #, fuzzy, c-format msgid "'%s' must be %s or %s" msgstr "'%s' dev'essere in '%s'" #: coerce.c:266 coerce.c:274 coerce.c:285 coerce.c:1549 coerce.c:1557 #: coerce.c:1568 msgid "nonempty vector supplied for empty matrix" msgstr "" #: coerce.c:287 coerce.c:1570 #, c-format msgid "vector length (%lld) exceeds matrix length (%d * %d)" msgstr "" #: coerce.c:290 coerce.c:1573 #, c-format msgid "matrix length (%d * %d) is not a multiple of vector length (%lld)" msgstr "" #: coerce.c:521 #, c-format msgid "coercing n-by-n %s to %s is not supported for n*n exceeding %s" msgstr "" #: coerce.c:525 coerce.c:815 coerce.c:949 #, c-format msgid "sparse->dense coercion: allocating vector of size %0.1f GiB" msgstr "" #: coerce.c:1196 coerce.c:1941 coerce.c:2948 coerce.c:2954 #, c-format msgid "attempt to construct %s with more than %s nonzero entries" msgstr "" #: coerce.c:3246 #, fuzzy msgid "attempt to pack non-square matrix" msgstr "Il determinante richiede una matrice quadrata" #: coerce.c:3420 coerce.c:3590 #, c-format msgid "unable to aggregate %s with '%s' and '%s' slots of length exceeding %s" msgstr "" #: coerce.c:4211 #, fuzzy, c-format msgid "attempt to pack a %s" msgstr "Il determinante richiede una matrice quadrata" #: coerce.c:4330 dense.c:1237 sparse.c:2579 #, fuzzy, c-format msgid "'%s' must be %s or %s or %s" msgstr "'%s' dev'essere in '%s'" #: dense.c:210 dense.c:215 sparse.c:590 sparse.c:595 #, fuzzy, c-format msgid "'%s' must be an integer from %s to %s" msgstr "'%s' dev'essere in '%s'" #: dense.c:218 sparse.c:598 #, fuzzy, c-format msgid "'%s' must be less than or equal to '%s'" msgstr "'%s' dev'essere in '%s'" #: dense.c:428 sparse.c:1069 #, fuzzy, c-format msgid "replacement diagonal has incompatible type \"%s\"" msgstr "la diagonale di ricambio ha una lunghezza errata" #: dense.c:437 sparse.c:1078 msgid "replacement diagonal has wrong length" msgstr "la diagonale di ricambio ha una lunghezza errata" #: dense.c:627 sparse.c:1274 #, fuzzy msgid "attempt to symmetrize a non-square matrix" msgstr "Il determinante richiede una matrice quadrata" #: dense.c:726 sparse.c:1652 msgid "attempt to get symmetric part of non-square matrix" msgstr "" #: dense.c:878 sparse.c:2082 msgid "attempt to get skew-symmetric part of non-square matrix" msgstr "" #: dense.c:1678 sparse.c:3135 #, fuzzy, c-format msgid "'%s' must be %d or %d" msgstr "'%s' dev'essere in '%s'" #: dense.c:2161 #, c-format msgid "incorrect left cyclic shift, j (%d) < 0" msgstr "spostamento ciclico sinistro errato, j (%d) < 0" #: dense.c:2164 #, c-format msgid "incorrect left cyclic shift, j (%d) >= k (%d)" msgstr "spostamento ciclico sinistro errato, j (%d) >= k (%d)" #: dense.c:2167 #, c-format msgid "incorrect left cyclic shift, k (%d) > ldx (%d)" msgstr "spostamento ciclico sinistro errato, k (%d) > ldx (%d)" #: dense.c:2220 #, fuzzy msgid "unknown error in getGivens" msgstr "Errore sconosciuto in getGivens" #: dense.c:2229 dense.c:2243 dense.c:2273 msgid "X must be a numeric (double precision) matrix" msgstr "X deve essere una matrice numerica (doppia precisione)" #: dense.c:2245 dense.c:2275 msgid "y must be a numeric (double precision) matrix" msgstr "y dev'essere una matrice numerica (doppia precisione)" #: dense.c:2249 dense.c:2279 #, c-format msgid "number of rows in y (%d) does not match number of rows in X (%d)" msgstr "" "il numero di righe in y (%d) non corrisponde al numero di righe in X (%d)" #: dense.c:2265 #, fuzzy, c-format msgid "LAPACK dposv returned error code %d" msgstr "La routine Lapack dposv ha restituito il codice di errore %d" #: dense.c:2293 dense.c:2299 #, fuzzy, c-format msgid "LAPACK dgels returned error code %d" msgstr "La routine Lapack %s ha restituito il codice di errore %d" #: dense.c:2318 msgid "X must be a real (numeric) matrix" msgstr "X dev'essere una matrice (numerica) reale" #: dense.c:2321 #, fuzzy, c-format msgid "tol, given as %g, must be >= 0" msgstr "tol, indicato come %g, dev'essere <= 1" #: dense.c:2323 #, c-format msgid "tol, given as %g, must be <= 1" msgstr "tol, indicato come %g, dev'essere <= 1" #: dense.c:2352 dense.c:2360 #, fuzzy, c-format msgid "LAPACK dgeqrf returned error code %d" msgstr "La prima chiamata a dgeqrf ha restituito il codice di errore %d" #: dense.c:2365 dense.c:2388 #, fuzzy, c-format msgid "LAPACK dtrcon returned error code %d" msgstr "La routine Lapack dtrcon ha restituito il codice di errore %d" #: determinant.c:33 #, fuzzy msgid "determinant of non-square matrix is undefined" msgstr "Il determinante richiede una matrice quadrata" #: determinant.c:276 #, fuzzy, c-format msgid "%s(<%s>) does not support structurally rank deficient case" msgstr "%s(): caso con rango strutturalmente carente: possibili zero sbagliati" #: dgCMatrix.c:14 #, fuzzy, c-format msgid "'%s' is empty or not square" msgstr "La matrice non è quadrata" #: dgCMatrix.c:16 dgCMatrix.c:38 dgCMatrix.c:61 solve.c:43 solve.c:984 #, fuzzy, c-format msgid "dimensions of '%s' and '%s' are inconsistent" msgstr "Le dimensioni del sistema da risolvere sono inconsistenti" #: dgCMatrix.c:40 #, c-format msgid "%s(%s, %s) requires m-by-n '%s' with m >= n > 0" msgstr "" #: dgCMatrix.c:63 #, c-format msgid "%s(%s, %s) requires m-by-n '%s' with n >= m > 0" msgstr "" #: dgeMatrix.c:22 #, fuzzy, c-format msgid "dgeMatrix_svd(x,*): dim(x)[j] = %d is too large" msgstr "Dimensione matrice %d x %d (= %g) è troppo grande" #: dgeMatrix.c:90 msgid "Matrix exponential requires square, non-null matrix" msgstr "L'esponenziale della matrice richiede una matrice quadrata non nulla" #: dgeMatrix.c:107 dgeMatrix.c:109 #, c-format msgid "dgeMatrix_exp: LAPACK routine dgebal returned %d" msgstr "dgeMatrix_exp: la routine LAPACK dgebal ha restituito %d" #: dgeMatrix.c:147 #, c-format msgid "dgeMatrix_exp: dgetrf returned error code %d" msgstr "dgeMatrix_exp: dgetrf ha restituito il codice di errore %d" #: dgeMatrix.c:149 #, c-format msgid "dgeMatrix_exp: dgetrs returned error code %d" msgstr "dgeMatrix_exp: dgetrs ha restituito il codice di errore %d" #: dgeMatrix.c:224 msgid "dgeMatrix_Schur: argument x must be a non-null square matrix" msgstr "" "dgeMatrix_Schur: l'argomento x dev'essere una matrice quadrata non nulla" #: dgeMatrix.c:237 msgid "dgeMatrix_Schur: first call to dgees failed" msgstr "dgeMatrix_Schur: prima chiamata a dgees fallita" #: dgeMatrix.c:246 #, c-format msgid "dgeMatrix_Schur: dgees returned code %d" msgstr "dgeMatrix_Schur: dgees ha restituito il codice %d" #: factorizations.c:355 sparse.c:196 #, fuzzy, c-format msgid "'%s' is not a number" msgstr "%s non è una lista" #: factorizations.c:376 #, c-format msgid "LU factorization of m-by-n %s requires m == n" msgstr "" #: factorizations.c:385 #, c-format msgid "LU factorization of %s failed: out of memory or near-singular" msgstr "" #: factorizations.c:462 #, c-format msgid "QR factorization of m-by-n %s requires m >= n" msgstr "" #: factorizations.c:471 #, c-format msgid "QR factorization of %s failed: out of memory" msgstr "" #: factorizations.c:571 factorizations.c:849 #, c-format msgid "'%s' is not a number or not finite" msgstr "" #: idz.c:467 idz.c:528 #, c-format msgid "incompatible '%s' and '%s' in '%s'" msgstr "" #: kappa.c:10 kappa.c:54 #, fuzzy, c-format msgid "argument '%s' is not of type \"%s\"" msgstr "" "tipo di argomento [1]='%s' deve essere una stringa di caratteri di una " "lettera" #: kappa.c:13 kappa.c:57 #, fuzzy, c-format msgid "argument '%s' has length %d" msgstr "'%s' deve avere una stringa di lunghezza 1" #: kappa.c:17 kappa.c:61 #, fuzzy, c-format msgid "argument '%s' (\"%s\") does not have string length %d" msgstr "'%s' deve avere una stringa di lunghezza 1" #: kappa.c:41 #, c-format msgid "" "argument '%s' (\"%s\") is not \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", or " "\"%s\"" msgstr "" #: kappa.c:75 #, fuzzy, c-format msgid "argument '%s' (\"%s\") is not \"%s\", \"%s\", or \"%s\"" msgstr "'%s' deve avere una stringa di lunghezza 1" #: kappa.c:238 #, c-format msgid "%s(%s) is undefined: '%s' is not square" msgstr "" #: objects.c:23 #, c-format msgid "unexpected type \"%s\" in '%s'" msgstr "" #: objects.c:41 objects.c:58 #, c-format msgid "unexpected kind \"%c\" in '%s'" msgstr "" #: perm.c:26 perm.c:106 msgid "attempt to get sign of non-permutation" msgstr "" #: perm.c:51 perm.c:123 msgid "attempt to invert non-permutation" msgstr "" #: perm.c:66 #, fuzzy msgid "invalid transposition vector" msgstr "indice riga non valido nella posizione %d" #: perm.c:79 perm.c:81 perm.c:96 perm.c:98 perm.c:113 perm.c:133 perm.c:145 #, fuzzy, c-format msgid "'%s' is not of type \"%s\"" msgstr "Lo slot dim non è intero" #: perm.c:83 perm.c:100 perm.c:147 #, fuzzy, c-format msgid "'%s' does not have length %d" msgstr "lo slot '%s' deve avere lunghezza 1" #: perm.c:86 perm.c:103 #, c-format msgid "'%s' is NA" msgstr "" #: perm.c:115 perm.c:138 #, fuzzy, c-format msgid "'%s' or '%s' is not of type \"%s\"" msgstr "Lo slot dim non è intero" #: perm.c:117 perm.c:140 #, fuzzy, c-format msgid "'%s' or '%s' does not have length %d" msgstr "lo slot '%s' deve avere lunghezza 1" #: perm.c:120 perm.c:143 #, c-format msgid "'%s' or '%s' is NA" msgstr "" #: perm.c:136 #, c-format msgid "'%s' has length exceeding %s" msgstr "" #: perm.c:150 #, c-format msgid "'%s' is NA or less than %s" msgstr "" #: products.c:107 products.c:210 products.c:289 products.c:377 products.c:454 #: products.c:548 products.c:809 products.c:859 msgid "non-conformable arguments" msgstr "" #: products.c:782 products.c:807 #, c-format msgid "'%s' does not support complex matrices" msgstr "" #: solve.c:38 #, fuzzy, c-format msgid "'%s' is not square" msgstr "La matrice non è quadrata" #: solve.c:497 #, c-format msgid "%s(<%s>, <%s>) failed: out of memory" msgstr "" #: solve.c:618 #, fuzzy, c-format msgid "attempt to construct %s with more than %s nonzero elements" msgstr "Il determinante richiede una matrice quadrata" #: sparseVector.c:90 #, c-format msgid "%s length cannot exceed %s" msgstr "" #: subscript.c:1542 subscript.c:1695 subscript.c:1938 subscript.c:2122 #, c-format msgid "%s too dense for %s; would have more than %s nonzero entries" msgstr "" #: subscript.c:2209 #, c-format msgid "NA subscripts in %s not supported for '%s' inheriting from %s" msgstr "" #: t_Csparse_subassign.c:142 msgid "invalid class of 'x' in Csparse_subassign()" msgstr "classe of 'x' in Csparse_subassign() non valida" #: t_Csparse_subassign.c:144 msgid "invalid class of 'value' in Csparse_subassign()" msgstr "classe di 'value' in Csparse_subassign() non valida" #: t_Csparse_subassign.c:187 #, c-format msgid "x[] <- val: val is coerced to logical for \"%s\" x" msgstr "x[] <- val: val è convertito in logico per x \"%s\"" #: t_Csparse_subassign.c:192 #, c-format msgid "" "x[] <- val: val should be integer or logical, is coerced to integer, for " "\"%s\" x" msgstr "" "x[] <- val: val dovrebbe essere intero o logico, è convertito in intero, per " "x \"%s\"" #: t_Csparse_subassign.c:199 msgid "programming error in Csparse_subassign() should never happen" msgstr "" "l'errore di programmazione in Csparse_subassign() non dovrebbe mai accadere" #: utils-R.c:30 utils-R.c:116 #, c-format msgid "indices would exceed %s" msgstr "" #: utils-R.c:235 utils-R.c:270 utils-R.c:281 utils-R.c:312 msgid "Argument must be numeric-like atomic vector" msgstr "L'argomento dev'essere un vettore atomico numerico" #: utils-R.c:345 msgid "'data' must be of a vector type" msgstr "'data' dev'essere un tipo vettore" #: utils-R.c:352 #, c-format msgid "invalid '%s' argument" msgstr "argomento '%s' non valido" #: utils-R.c:359 utils-R.c:367 msgid "non-numeric matrix extent" msgstr "estensione della matrice non numerica" #: utils-R.c:362 msgid "invalid 'nrow' value (too large or NA)" msgstr "valore 'nrow' non valido (troppo largo o NA)" #: utils-R.c:364 msgid "invalid 'nrow' value (< 0)" msgstr "valore 'nrow' non valido (< 0)" #: utils-R.c:370 msgid "invalid 'ncol' value (too large or NA)" msgstr "valore 'ncol' non valido (troppo larga o NA)" #: utils-R.c:372 msgid "invalid 'ncol' value (< 0)" msgstr "valore 'ncol' non valido (< 0)" #: utils-R.c:390 #, c-format msgid "" "data length [%d] is not a sub-multiple or multiple of the number of rows [%d]" msgstr "" "la lunghezza dati [%d] non è un sotto-multiplo o multiplo del numero di " "righe [%d]" #: utils-R.c:395 #, c-format msgid "" "data length [%d] is not a sub-multiple or multiple of the number of columns " "[%d]" msgstr "" "la lunghezza dati [%d] non è un sotto-multiplo o multiplo del numero di " "colonne [%d]" #: utils-R.c:399 msgid "data length exceeds size of matrix" msgstr "la lunghezza dei dati eccede la dimensione della matrice" #: utils-R.c:404 msgid "too many elements specified" msgstr "specificati troppi elementi" #: utils-R.c:545 msgid "Argument ij must be 2-column integer matrix" msgstr "L'argomento ij dev'essere una matrice di interi con 2 colonne" #: utils-R.c:570 msgid "subscript 'i' out of bounds in M[ij]" msgstr "subscript 'i' fuori banda in M[ij]" #: utils-R.c:572 msgid "subscript 'j' out of bounds in M[ij]" msgstr "subscript 'j' fuori banda in M[ij]" #: utils-R.c:626 msgid "i and j must be integer vectors of the same length" msgstr "i e j devono essere vettori di interi con la medesima lunghezza" #: validity.c:40 validity.c:73 validity.c:264 validity.c:283 validity.c:292 #: validity.c:311 validity.c:337 validity.c:1010 validity.c:1452 #: validity.c:1476 #, fuzzy, c-format msgid "'%s' slot does not have length %d" msgstr "Lo slot dim deve avere lunghezza 2" #: validity.c:45 validity.c:965 validity.c:998 #, fuzzy, c-format msgid "'%s' slot has negative elements" msgstr "lo slot 'Dim' ha lunghezza inferiore a due" #: validity.c:71 validity.c:197 #, fuzzy, c-format msgid "'%s' slot is not a list" msgstr "Lo slot dim non è intero" #: validity.c:89 #, fuzzy, c-format msgid "%s[[%d]] is not NULL or a vector" msgstr "Dimnames[%d] non è un vettore di caratteri" #: validity.c:92 #, fuzzy, c-format msgid "length of %s[[%d]] (%lld) is not equal to %s[%d] (%d)" msgstr "length(Dimnames[%d]) differisce da Dim[%d] che è %d" #: validity.c:203 #, c-format msgid "'%s' slot has no '%s' attribute" msgstr "" #: validity.c:214 validity.c:277 validity.c:305 validity.c:376 validity.c:1115 #: validity.c:1446 validity.c:1807 #, c-format msgid "%s[1] != %s[2] (matrix is not square)" msgstr "" #: validity.c:239 validity.c:252 #, c-format msgid "%s[1] differs from %s[2]" msgstr "" #: validity.c:267 validity.c:286 validity.c:295 validity.c:314 #, fuzzy, c-format msgid "'%s' slot is not \"%s\" or \"%s\"" msgstr "lo slot x non è \"double\"" #: validity.c:320 validity.c:324 #, fuzzy, c-format msgid "'%s' slot is \"%s\" but '%s' slot does not have length %s" msgstr "Lo slot dim deve avere lunghezza 2" #: validity.c:340 #, fuzzy, c-format msgid "'%s' slot is not %d or %d" msgstr "lo slot x non è \"double\"" #: validity.c:346 validity.c:349 #, c-format msgid "%s-by-%s %s invalid for positive '%s' when %s=%d" msgstr "" #: validity.c:386 validity.c:1178 validity.c:1190 validity.c:1291 #: validity.c:1303 validity.c:1383 validity.c:1432 validity.c:1491 #, c-format msgid "'%s' slot contains duplicates" msgstr "" #: validity.c:437 validity.c:1613 #, fuzzy, c-format msgid "'%s' slot is not increasing within columns" msgstr "lo slot j non è crescente all'interno di una colonna" #: validity.c:488 #, fuzzy, c-format msgid "'%s' slot is not increasing within rows" msgstr "lo slot j non è crescente all'interno di una colonna" #: validity.c:512 validity.c:801 validity.c:827 validity.c:853 validity.c:1076 #: validity.c:1682 validity.c:1684 #, fuzzy, c-format msgid "'%s' and '%s' slots do not have equal length" msgstr "Lo slot dim deve avere lunghezza 2" #: validity.c:515 #, c-format msgid "'%s' slot has nonzero length but %s is 0" msgstr "" #: validity.c:555 validity.c:600 validity.c:646 validity.c:691 validity.c:735 #: validity.c:770 #, fuzzy, c-format msgid "%s=\"%s\" but there are entries below the diagonal" msgstr "uplo='U' non deve avere voci sparse sotto la diagonale" #: validity.c:565 validity.c:613 validity.c:656 validity.c:704 validity.c:740 #: validity.c:781 #, fuzzy, c-format msgid "%s=\"%s\" but there are entries above the diagonal" msgstr "uplo='L' non deve avere voci sparse sopra la diagonale" #: validity.c:603 validity.c:616 validity.c:694 validity.c:707 validity.c:773 #: validity.c:784 #, fuzzy, c-format msgid "%s=\"%s\" but there are entries on the diagonal" msgstr "uplo='U' non deve avere voci sparse sotto la diagonale" #: validity.c:911 validity.c:935 validity.c:939 msgid "matrix has negative diagonal elements" msgstr "" #: validity.c:955 validity.c:983 validity.c:987 msgid "matrix has nonunit diagonal elements" msgstr "" #: validity.c:1007 validity.c:1032 validity.c:1826 #, fuzzy, c-format msgid "'%s' slot is not of type \"%s\" or \"%s\"" msgstr "Lo slot dim non è intero" #: validity.c:1015 validity.c:1022 #, fuzzy, c-format msgid "'%s' slot is NA" msgstr "Lo slot dim non è intero" #: validity.c:1017 validity.c:1024 #, fuzzy, c-format msgid "'%s' slot is negative" msgstr "lo slot 'Dim' ha lunghezza inferiore a due" #: validity.c:1026 #, fuzzy, c-format msgid "'%s' slot exceeds %s" msgstr "'%s' dev'essere in '%s'" #: validity.c:1036 #, fuzzy, c-format msgid "'%s' slot has length greater than '%s' slot" msgstr "lo slot 'Dim' ha lunghezza inferiore a due" #: validity.c:1046 validity.c:1674 validity.c:1696 validity.c:1698 #, fuzzy, c-format msgid "'%s' slot is not increasing" msgstr "lo slot j non è crescente all'interno di una colonna" #: validity.c:1056 #, fuzzy, c-format msgid "'%s' slot has elements not in {%s} after truncation towards zero" msgstr "lo slot 'Dim' ha lunghezza inferiore a due" #: validity.c:1059 #, fuzzy, c-format msgid "'%s' slot is not increasing after truncation towards zero" msgstr "lo slot j non è crescente all'interno di una colonna" #: validity.c:1125 validity.c:1152 validity.c:1814 validity.c:1821 #, fuzzy, c-format msgid "dimensions of '%s' slot are not identical to '%s'" msgstr "Le dimensioni di x e y sono non compatibili per %s" #: validity.c:1127 #, c-format msgid "'%s' slot is upper (not lower) triangular" msgstr "" #: validity.c:1140 #, c-format msgid "'%s' slot has nonunit diagonal elements" msgstr "" #: validity.c:1154 #, c-format msgid "'%s' slot is lower (not upper) triangular" msgstr "" #: validity.c:1166 validity.c:1279 validity.c:1370 validity.c:1419 #, fuzzy, c-format msgid "'%s' slot does not have length %s or length %s" msgstr "Lo slot dim deve avere lunghezza 2" #: validity.c:1206 msgid "matrix has more columns than rows" msgstr "" #: validity.c:1226 #, fuzzy, c-format msgid "'%s' slot has fewer than %s rows" msgstr "lo slot 'Dim' ha lunghezza inferiore a due" #: validity.c:1228 #, fuzzy, c-format msgid "'%s' slot has more than %s rows" msgstr "lo slot 'Dim' ha lunghezza inferiore a due" #: validity.c:1230 validity.c:1252 #, fuzzy, c-format msgid "'%s' slot does not have %s columns" msgstr "Lo slot dim deve avere lunghezza 2" #: validity.c:1237 #, fuzzy, c-format msgid "'%s' slot must be lower trapezoidal but has entries above the diagonal" msgstr "uplo='L' non deve avere voci sparse sopra la diagonale" #: validity.c:1250 #, fuzzy, c-format msgid "'%s' slot does not have %s row" msgstr "Lo slot dim deve avere lunghezza 2" #: validity.c:1259 #, fuzzy, c-format msgid "'%s' slot must be upper trapezoidal but has entries below the diagonal" msgstr "uplo='U' non deve avere voci sparse sotto la diagonale" #: validity.c:1263 #, c-format msgid "'%s' slot has negative diagonal elements" msgstr "" #: validity.c:1329 #, c-format msgid "'%s' slot has elements not in {%s}\\{%s}" msgstr "" #: validity.c:1338 #, c-format msgid "'%s' slot has unpaired negative elements" msgstr "" #: validity.c:1364 validity.c:1408 validity.c:1412 validity.c:1760 #: validity.c:1792 msgid "Cholesky factor has negative diagonal elements" msgstr "" #: validity.c:1455 #, fuzzy, c-format msgid "%s[%d] (%s) is not in %s" msgstr "%s non è una lista" #: validity.c:1468 validity.c:1569 #, fuzzy, c-format msgid "%s is not in {%s}" msgstr "%s non è una lista" #: validity.c:1505 #, c-format msgid "%s is not representable as \"%s\"" msgstr "" #: validity.c:1510 validity.c:1516 #, c-format msgid "%s[%d] (%s) is not %d or %d" msgstr "" #: validity.c:1513 validity.c:1629 validity.c:1632 validity.c:1635 #, c-format msgid "%s[%d] (%s) is not %d" msgstr "" #: validity.c:1538 #, c-format msgid "%s has elements not in {%s}" msgstr "" #: validity.c:1541 #, c-format msgid "%s has elements not in {%s}\\{%s}" msgstr "" #: validity.c:1544 #, c-format msgid "%s is %d but columns are not stored in increasing order" msgstr "" #: validity.c:1547 validity.c:1550 #, c-format msgid "traversal of '%s' slot does not complete in exactly %s steps" msgstr "" #: validity.c:1556 validity.c:1558 #, fuzzy, c-format msgid "%s is not %d" msgstr "%s non è una lista" #: validity.c:1579 #, c-format msgid "column '%s' is stored first but %s is not 0" msgstr "" #: validity.c:1585 #, fuzzy, c-format msgid "'%s' slot is not increasing when traversed in stored column order" msgstr "lo slot j non è crescente all'interno di una colonna" #: validity.c:1587 #, c-format msgid "'%s' slot allocates fewer than %s elements for column '%s'" msgstr "" #: validity.c:1590 #, c-format msgid "'%s' slot allocates more than %s elements for column '%s'" msgstr "" #: validity.c:1604 #, c-format msgid "first entry in column '%s' does not have row index '%s'" msgstr "" #: validity.c:1638 validity.c:1641 #, c-format msgid "%s[%d] (%s) is negative" msgstr "" #: validity.c:1644 #, c-format msgid "%s[%d] (%s) is not less than %s" msgstr "" #: validity.c:1662 #, fuzzy, c-format msgid "'%s' slot has length less than %d" msgstr "lo slot 'Dim' ha lunghezza inferiore a due" #: validity.c:1664 #, fuzzy, c-format msgid "'%s' slot has length greater than %s" msgstr "lo slot 'Dim' ha lunghezza inferiore a due" #: validity.c:1669 #, fuzzy, c-format msgid "last element of '%s' slot is not %s" msgstr "il primo elemento dello slot p dev'essere zero" #: validity.c:1702 #, c-format msgid "first differences of '%s' slot are less than those of '%s' slot" msgstr "" #: validity.c:1705 #, c-format msgid "supernode lengths exceed %s" msgstr "" #: validity.c:1707 #, c-format msgid "first differences of '%s' slot are not equal to supernode lengths" msgstr "" #: validity.c:1727 #, c-format msgid "" "'%s' slot is wrong within diagonal blocks (row and column indices do not " "coincide)" msgstr "" #: validity.c:1730 #, fuzzy, c-format msgid "'%s' slot is not increasing within supernodes" msgstr "lo slot j non è crescente all'interno di una colonna" #: validity.c:1845 #, fuzzy, c-format msgid "invalid class \"%s\" object: %s" msgstr "classe di oggetto a %s non valida" #, c-format #~ msgid "diagonal element %d of Cholesky factor is missing" #~ msgstr "l'elemento diagonale %d del fattore Cholesky è assente" #, c-format #~ msgid "cholmod_factorize_p failed: status %d, minor %d of ncol %d" #~ msgstr "cholmod_factorize_p non riuscito: stato %d, minore %d di ncol %d" #~ msgid "cholmod_change_factor failed" #~ msgstr "cholmod_change_factor fallito" #~ msgid "cholmod_write_sparse returned error code" #~ msgstr "cholmod_write_sparse ha restituito il codice di errore" #, c-format #~ msgid "%s = '%s' (back-permuted) is experimental" #~ msgstr "%s = '%s' (back-permuted) è sperimentale" #~ msgid "diag_tC(): invalid 'resultKind'" #~ msgstr "diag_tC(): 'resultKind' non valido" #, fuzzy #~ msgid "complex matrices are not yet supported" #~ msgstr "codice a matrice sparsa complessa non ancora scritto" #~ msgid "Argument rho must be an environment" #~ msgstr "L'argomento rho dev'essere un ambiente" #~ msgid "invalid class of object to as_cholmod_sparse" #~ msgstr "classe di oggetto a as_cholmod_sparse non valida" #~ msgid "invalid object passed to as_cholmod_sparse" #~ msgstr "oggetto non valido passato a as_cholmod_sparse" #~ msgid "in_place cholmod_sort returned an error code" #~ msgstr "in_place cholmod_sort ha restituito un codice di errore" #~ msgid "cholmod_sort returned an error code" #~ msgstr "cholmod_sort ha restituito un codice di errore" #~ msgid "chm_sparse_to_SEXP(, *): invalid 'Rkind' (real kind code)" #~ msgstr "" #~ "chm_sparse_to_SEXP(, *): 'Rkind' non valido (codice di tipo reale)" #~ msgid "unknown xtype in cholmod_sparse object" #~ msgstr "xtype sconosciuto nell'oggetto cholmod_sparse" #~ msgid "complex sparse matrix code not yet written" #~ msgstr "codice a matrice sparsa complessa non ancora scritto" #~ msgid "Symmetric and triangular both set" #~ msgstr "Simmetrici e triangolari entrambi impostati" #~ msgid "invalid class of object to as_cholmod_triplet" #~ msgstr "classe di oggetto a as_cholmod_triplet non valida" #~ msgid "as_cholmod_triplet(): could not reallocate for internal diagU2N()" #~ msgstr "" #~ "as_cholmod_triplet(): non è possibile riallocare per diagU2N() interno" #~ msgid "unknown xtype in cholmod_triplet object" #~ msgstr "xtype sconosciuto nell'oggetto cholmod_triplet" #~ msgid "invalid class of object to as_cholmod_dense" #~ msgstr "classe di oggetto a as_cholmod_dense non valida" #, c-format #~ msgid "" #~ "chm_transpose_dense(ans, x) not yet implemented for %s different from %s" #~ msgstr "" #~ "chm_transpose_dense(ans, x) non ancora implementato per %s diverso da%s" #, c-format #~ msgid "Unable to initialize cholmod: error code %d" #~ msgstr "Non è possibile inizializzare il colmod: codice di errore %d" #~ msgid "unknown 'Rkind'" #~ msgstr "'Rkind' sconosciuto" #~ msgid "unknown xtype" #~ msgstr "xtype sconosciuto" #~ msgid "code for cholmod_dense with holes not yet written" #~ msgstr "il codice per cholmod_dense con buchi non ancora scritto" #~ msgid "don't know if a dense pattern matrix makes sense" #~ msgstr "non sappiamo se una matrice di schemi densi abbia senso" #, fuzzy #~ msgid "object of invalid class to 'as_cholmod_factor()'" #~ msgstr "classe di oggetto a as_cholmod_factor non valida" #~ msgid "failure in as_cholmod_factor" #~ msgstr "fallimento in as_cholmod_factor" #~ msgid "CHOLMOD factorization was unsuccessful" #~ msgstr "La fattorizzazione CHOLMOD non è andata a buon fine" #, c-format #~ msgid "f->xtype of %d not recognized" #~ msgstr "f->xtype di %d non riconosciuta" #, c-format #~ msgid "chm_diagN2U(): nrow=%d, ncol=%d" #~ msgstr "chm_diagN2U (): nrow =%d, ncol =%d" #, c-format #~ msgid "chm_diagN2U(x, uploT = %d): uploT should be +- 1" #~ msgstr "chm_diagN2U (x, uploT =%d): uploT dovrebbe essere +-1" #~ msgid "dgCMatrix_lusol requires a square, non-empty matrix" #~ msgstr "dgCMatrix_lusol richiede una matrice quadrata non vuota" #~ msgid "Dimensions of system to be solved are inconsistent" #~ msgstr "Le dimensioni del sistema da risolvere sono inconsistenti" #~ msgid "cs_lusol failed" #~ msgstr "cs_lusol fallita" #~ msgid "dgCMatrix_qrsol(., order) needs order in {0,..,3}" #~ msgstr "dgCMatrix_qrsol(., order) richiede ordine in {0,..,3}" #, c-format #~ msgid "" #~ "dgCMatrix_qrsol(<%d x %d>-matrix) requires a 'tall' rectangular matrix" #~ msgstr "" #~ "dgCMatrix_qrsol(<%d x %d>-matrix) richiede una matrice rettangolare " #~ "\"alta\"" #~ msgid "cs_qrsol() failed inside dgCMatrix_qrsol()" #~ msgstr "cs_qrsol() fallita dentro dgCMatrix_qrsol()" #~ msgid "dgCMatrix_cholsol requires a 'short, wide' rectangular matrix" #~ msgstr "" #~ "dgCMatrix_cholsol richiede una matrice rettangolare \"corta, larga\"" #~ msgid "cholmod_sdmult error (rhs)" #~ msgstr "cholmod_sdmult error (rhs)" #, c-format #~ msgid "cholmod_factorize failed: status %d, minor %d from ncol %d" #~ msgstr "cholmod_factorize fallito: stato %d, minore %d da ncol %d" #, c-format #~ msgid "cholmod_solve (CHOLMOD_A) failed: status %d, minor %d from ncol %d" #~ msgstr "" #~ "cholmod_solve(CHOLMOD_A) non riuscito: stato %d, minore %d da ncol %d" #~ msgid "cholmod_sdmult error (resid)" #~ msgstr "cholmod_sdmult error (resid)" #~ msgid "SuiteSparseQR_C_QR returned an error code" #~ msgstr "SuiteSparseQR_C_QR ha restituito un codice di errore" #, fuzzy, c-format #~ msgid "LAPACK routine '%s': matrix is exactly singular, %s[i,i]=0, i=%d" #~ msgstr "Routine Lapack dgetrs: il sistema è esattamente singolare" #, fuzzy, c-format #~ msgid "" #~ "LAPACK routine '%s': leading principal minor of order %d is not positive" #~ msgstr "il minore principale dell'ordine %d non è definito positivo" #, fuzzy #~ msgid "missing 'Matrix' namespace; should never happen" #~ msgstr "namespace 'Matrix' assente: non dovrebbe mai accadere" #, fuzzy #~ msgid "'Matrix' namespace not determined correctly" #~ msgstr "Namespace della matrice non determinato correttamente" #~ msgid "Csparse_sort(x): x is not a valid (apart from sorting) CsparseMatrix" #~ msgstr "" #~ "Csparse_sort(x): x non è una valida (a parte l'ordinamento) CsparseMatrix" #, c-format #~ msgid "Impossible Rk_x/Rk_y in Csparse_%s(), please report" #~ msgstr "" #~ "Non è possibile avere Rk_x/Rk_y in Csparse_%s(), per piacere riportatelo" #, c-format #~ msgid "chm_MOD_xtype() was not successful in Csparse_%s(), please report" #~ msgstr "" #~ "chm_MOD_xtype() non ha avuto successo in Csparse_%s(), per piacere, " #~ "segnalatelo" #, c-format #~ msgid "the number of columns differ in R_rbind2_vector: %d != %d" #~ msgstr "il numero di colonne differisce in R_rbind2_vector: %d != %d" #~ msgid "csp_eye argument n must be positive" #~ msgstr "l'argomento csp_eye n dev'essere positivo" #~ msgid "invalid class of 'x' in Matrix_as_cs(a, x)" #~ msgstr "classe di 'x' in Matrix_as_cs(a, x) non valida" #, c-format #~ msgid "invalid class of object to %s" #~ msgstr "classe di oggetto a %s non valida" #, c-format #~ msgid "cs matrix not compatible with class '%s'" #~ msgstr "matrice cs non compatibile con la classe '%s'" #, c-format #~ msgid "Inappropriate class cl='%s' in Matrix_css_to_SEXP(S, cl, ..)" #~ msgstr "Classe inappropriata cl='%s' in Matrix_css_to_SEXP(S, cl, ..)" #, c-format #~ msgid "Inappropriate class cl='%s' in Matrix_csn_to_SEXP(S, cl, ..)" #~ msgstr "Classe inappropriata cl='%s' in Matrix_csn_to_SEXP(S, cl, ..)" #, c-format #~ msgid "Dimensions of x and y are not compatible for %s" #~ msgstr "Le dimensioni di x e y sono non compatibili per %s" #~ msgid "Argument y must be numeric, integer or logical" #~ msgstr "L'argomento y dev'essere numerico, intero o logico" #~ msgid "Matrices are not conformable for multiplication" #~ msgstr "Le matrici non sono conformi per la moltiplicazione" #, c-format #~ msgid "" #~ "dimension mismatch in matrix multiplication of \"dtrMatrix\": %d != %d" #~ msgstr "" #~ "dimensione non conforme nella moltiplicazione matriciale di " #~ "\"dtrMatrix\": %d != %d" #~ msgid "dtrMatrix must be square" #~ msgstr "dtrMatrix dev'essere quadrata" #, c-format #~ msgid "Dimensions of a (%d,%d) and b (%d,%d) do not conform" #~ msgstr "Dimensioni di a (%d,%d) e b (%d,%d) non conformi" #~ msgid "right=TRUE is not yet implemented __ FIXME" #~ msgstr "right=TRUE non è ancora implementato __ SISTEMATEMI" #, c-format #~ msgid "cholmod_change_factor failed with status %d" #~ msgstr "cholmod_change_factor fallito con status %d" #~ msgid "system argument is not valid" #~ msgstr "l'argomento di sistema non è valido" #, c-format #~ msgid "cholmod_updown() returned %d" #~ msgstr "cholmod_updown() ha restituito %d" #~ msgid "cholmod_drop() failed" #~ msgstr "cholmod_drop() fallito" #, fuzzy #~ msgid "'off' does not have length 1" #~ msgstr "lo slot '%s' deve avere lunghezza 1" #, fuzzy #~ msgid "invalid 'code' to 'R_matrix_as_dense()'" #~ msgstr "classe '%s' a dup_mMatrix_as_dgeMatrix non valida" #, fuzzy #~ msgid "invalid 'uplo' to 'R_matrix_as_dense()'" #~ msgstr "classe '%s' a dup_mMatrix_as_dgeMatrix non valida" #, fuzzy #~ msgid "invalid 'diag' to 'R_matrix_as_dense()'" #~ msgstr "classe '%s' a dup_mMatrix_as_dgeMatrix non valida" #, fuzzy #~ msgid "invalid argument 'system'" #~ msgstr "argomento '%s' non valido" #, fuzzy #~ msgid "dimensions of 'qr' and 'y' are inconsistent" #~ msgstr "Le dimensioni del sistema da risolvere sono inconsistenti" #, fuzzy #~ msgid "invalid 'op'" #~ msgstr "argomento '%s' non valido" #, fuzzy #~ msgid "'names' must be TRUE or FALSE" #~ msgstr "'uplo' dev'essere UPP o LOW" #~ msgid "Csparse_crossprod(): error return from cholmod_aat()" #~ msgstr "Csparse_crossprod(): errore restituito da cholmod_aat()" #, fuzzy #~ msgid "invalid 'kind' to 'R_sparse_as_kind()'" #~ msgstr "classe of 'x' in Csparse_subassign() non valida" #~ msgid "slot p must have length = nrow(.) + 1" #~ msgstr "lo slot p deve avere lunghezza = nrow(.) + 1" #~ msgid "last element of slot p must match length of slots j and x" #~ msgstr "" #~ "l'ultimo elemento dello slot p deve corrispondere alla lunghezza degli " #~ "slot j e x" #~ msgid "all column indices must be between 0 and ncol-1" #~ msgstr "tutti gli indici di colonna devono essere compresi tra 0 e ncol-1" #~ msgid "slot j is not *strictly* increasing inside a column" #~ msgstr "lo slot j non è *strettamente* crescente all'interno di una colonna" #~ msgid "Csparse_to_nz_pattern(x, tri = NA): 'tri' is taken as TRUE" #~ msgstr "Csparse_to_nz_pattern(x, tri = NA): 'tri' è preso come TRUE" #~ msgid "not a 'n.CMatrix'" #~ msgstr "non è una 'n.CMatrix'" #, c-format #~ msgid "nz2Csparse(): invalid/non-implemented r_kind = %d" #~ msgstr "nz2Csparse(): non valido/non-implementato r_kind = %d" #~ msgid "Nonsymmetric matrix in Csparse_symmetric_to_general" #~ msgstr "Matrice non simmetrica in Csparse_symmetric_to_general" #~ msgid "Csparse_general_to_symmetric(): matrix is not square!" #~ msgstr "Csparse_general_to_symmetric(): la matrice non è quadrata!" #~ msgid "Index i must be NULL or integer" #~ msgstr "L'indice i dev'essere NULL o intero" #~ msgid "Index j must be NULL or integer" #~ msgstr "L'indice j dev'essere NULL o intero" #, c-format #~ msgid "negative vector lengths not allowed: np = %d, nnz = %d" #~ msgstr "lunghezze vettore negativa non ammesse: np = %d, nnz = %d" #~ msgid "exactly 1 of 'i', 'j' or 'p' must be NULL" #~ msgstr "esattamente 1 di 'i', 'j' o 'p' dev'essere NULL" #, c-format #~ msgid "np = %d, must be zero when p is NULL" #~ msgstr "np = %d, dev'essere zero quando p è NULL" #, c-format #~ msgid "p[0] = %d, should be zero" #~ msgstr "p[0] = %d, dovrebbe essere zero" #~ msgid "p must be non-decreasing" #~ msgstr "p dev'essere non decrescente" #, c-format #~ msgid "Inconsistent dimensions: np = 0 and nnz = %d" #~ msgstr "Dimensioni inconsistenti: np = 0 e nnz = %d" #, c-format #~ msgid "invalid column index at position %d" #~ msgstr "indice colonna non valido nella posizione %d" #, c-format #~ msgid "strlen of cls argument = %d, should be 8" #~ msgstr "strlen dell'argomento cls = %d, dovrebbe essere 8" #, c-format #~ msgid "cls = \"%s\" does not end in \"CMatrix\"" #~ msgstr "cls = \"%s\" non finisce in \"CMatrix\"" #, c-format #~ msgid "cls = \"%s\" must begin with 'd', 'l' or 'n'" #~ msgstr "cls = \"%s\" deve iniziare con 'd', 'l' o 'n'" #~ msgid "Only 'g'eneral sparse matrix types allowed" #~ msgstr "Sono consentiti solo tipi di matrici sparse generali 'g'" #~ msgid "code not yet written for cls = \"lgCMatrix\"" #~ msgstr "codice non ancora scritto per cls = \"lgCMatrix\"" #, c-format #~ msgid "%s must be (traditional R) matrix" #~ msgstr "%s dev'essere una matrice (tradizionale di R)" #, c-format #~ msgid "%s must be character string" #~ msgstr "%s dev'essere una stringa di caratteri" #, c-format #~ msgid "nrow * ncol = %d * %d must equal length(x) = %ld" #~ msgstr "nrow * ncol = %d * %d deve eguagliare length(x) = %ld" #, c-format #~ msgid "strlen of cls argument = %d, should be 9" #~ msgstr "strlen dell'argomento cls = %d, dovrebbe essere 9" #, c-format #~ msgid "cls = \"%s\" must begin with 'd', 'l' or 'n' for now" #~ msgstr "cls = \"%s\" deve iniziare con 'd', 'l' o 'n' per ora" #, c-format #~ msgid "%s must be a logical or double vector" #~ msgstr "%s dev'essere un vettore di tipo logical o double" #, c-format #~ msgid "argument type[1]='%s' must be one of 'M','1','O','I','F' or 'E'" #~ msgstr "" #~ "tipo di argomento [1]='%s' dev'essere uno di 'M', '1', 'O', 'I', 'F' o 'E'" #, c-format #~ msgid "argument type[1]='%s' must be one of '1','O', or 'I'" #~ msgstr "tipo di argomento [1]='%s' dev'essere uno di '1', 'O' o 'I'" #~ msgid "object must be a named, numeric vector" #~ msgstr "l'oggetto dev'essere un vettore numerico nominato" #~ msgid "'factors' slot must be a named list" #~ msgstr "lo slot 'factors' deve essere una lista nominata" #~ msgid "Matrix object has no 'factors' slot" #~ msgstr "L'oggetto matrice non ha slot 'factors'" #~ msgid "'s1' and 's2' must be \"character\" vectors" #~ msgstr "'s1' e 's2' devono essere vettori di caratteri" #~ msgid "length of x slot != prod(Dim)" #~ msgstr "la lunghezza dello slot x != prod(Dim)" #~ msgid "Negative value in Dim" #~ msgid_plural "Negative values in Dim" #~ msgstr[0] "Valore negativo in Dim" #~ msgstr[1] "Valori negativi in Dim" #, c-format #~ msgid "%s is a list, but not of length 2" #~ msgstr "%s è una lista, ma non di lunghezza 2" #, c-format #~ msgid "invalid class '%s' to dup_mMatrix_as_geMatrix" #~ msgstr "classe '%s' to dup_mMatrix_as_geMatrix non valida" #, c-format #~ msgid "unexpected ctype = %d in dup_mMatrix_as_geMatrix" #~ msgstr "ctype inatteso = %d in dup_mMatrix_as_geMatrix" #~ msgid "lengths of slots i and j must match" #~ msgstr "le lunghezze degli slot i e j devono corrispondere" #~ msgid "slot Dim must have length 2" #~ msgstr "lo slot Dim deve avere lunghezza 2" #~ msgid "" #~ "all row indices (slot 'i') must be between 0 and nrow-1 in a TsparseMatrix" #~ msgstr "" #~ "tutti gli indici di riga (slot 'i') devono essere compresi tra 0 e nrow-1 " #~ "in una TsparseMatrix" #~ msgid "" #~ "all column indices (slot 'j') must be between 0 and ncol-1 in a " #~ "TsparseMatrix" #~ msgstr "" #~ "tutti gli indici di colonna (slot 'j') devono essere compresi tra 0 e " #~ "ncol-1 in una TsparseMatrix" #~ msgid "Supernodal LDL' decomposition not available" #~ msgstr "Decomposizione LDL Supernodal non disponibile" #~ msgid "Supernodal/simplicial class inconsistent with type flags" #~ msgstr "Classe sovranodale/simpliciale incompatibile con i flag di tipo" #~ msgid "Number of supernodes must be positive when is_super is TRUE" #~ msgstr "Il numero di supernodi dev'essere positivo quando is_super è TRUE" #~ msgid "Lengths of super and pi must be equal" #~ msgstr "Le lunghezze di super e pi devono essere uguali" #~ msgid "Lengths of super and px must be equal" #~ msgstr "Le lunghezze di super e px devono essere uguali" #, c-format #~ msgid "First call to Lapack routine dgels returned error code %d" #~ msgstr "" #~ "La prima chiamata alla routine Lapack dgels ha restituito il codice di " #~ "errore %d" #, c-format #~ msgid "Second call to Lapack routine dgels returned error code %d" #~ msgstr "" #~ "La seconda chiamata alla routine di Lapack dgels ha restituito il codice " #~ "di errore %d" #, c-format #~ msgid "tol, given as %g, must be non-negative" #~ msgstr "tol, indicato come %g, dev'essere non negativo" #, c-format #~ msgid "Second call to dgeqrf returned error code %d" #~ msgstr "La seconda chiamata a dgeqrf ha restituito il codice di errore %d" #, c-format #~ msgid "" #~ "dense_to_Csparse(): cholmod_l_dense_to_sparse failure status=%d" #~ msgstr "" #~ "dense_to_Csparse(): cholmod_l_dense_to_sparse riporta il seguente " #~ "errore=%d" #, c-format #~ msgid "" #~ "Matrix dimension %d x %d (= %g) too large [FIXME calling " #~ "cholmod_l_dense_to_sparse]" #~ msgstr "" #~ "Dimensione matrice %d x %d (= %g) troppo grande [RISOLVI chiamando " #~ "cholmod_l_dense_to_sparse]" #, c-format #~ msgid "Lower band %d > upper band %d" #~ msgstr "Banda inferiore %d > banda superiore %d" #~ msgid "ddense_to_symmetric(): matrix is not square!" #~ msgstr "ddense_to_symmetric(): la matrice non è quadrata!" #, c-format #~ msgid "matrix is not symmetric [%d,%d]" #~ msgstr "la matrice non è simmetrica [%d,%d]" #~ msgid "matrix is not square! (symmetric part)" #~ msgstr "la matrice non è quadrata! (parte simmetrica)" #~ msgid "matrix is not square! (skew-symmetric part)" #~ msgstr "la matrice non è quadrata! (parte obliqua-simmetrica))" #~ msgid "lengths of slots 'i' and 'x' must match" #~ msgstr "le lunghezze degli slot 'i' e 'x' devono corrispondere" #~ msgid "lengths of slots 'j' and 'x' must match" #~ msgstr "le lunghezze degli slot 'j' e 'x' devono corrispondere" #, c-format #~ msgid "invalid class(x) '%s' in compressed_to_TMatrix(x)" #~ msgstr "class(x) '%s' in compressed_to_TMatrix(x) non valida" #, c-format #~ msgid "invalid class(x) '%s' in R_to_CMatrix(x)" #~ msgstr "class(x) '%s' in R_to_CMatrix(x) non valida" #~ msgid "A must have #{rows} >= #{columns}" #~ msgstr "A deve avere #{righe} >= #{colonne}" #~ msgid "cs_sqr failed" #~ msgstr "cs_sqr fallita" #~ msgid "dgcMatrix_QR(*, keep_dimnames = NA): NA taken as TRUE" #~ msgstr "dgcMatrix_QR(*, keep_dimnames = NA): NA presi come TRUE" #~ msgid "LU decomposition applies only to square matrices" #~ msgstr "La decomposizione LU si applica solo alle matrici quadrate" #~ msgid "cs_lu(A) failed: near-singular A (or out of memory)" #~ msgstr "cs_lu(A) non riuscito: quasi singolare A (o memoria esaurita)" #~ msgid "dgcMatrix_LU(*, keep_dimnames = NA): NA taken as TRUE" #~ msgstr "dgcMatrix_LU(*, keep_dimnames = NA): NA presi come TRUE" #~ msgid "dgCMatrix_matrix_solve(.., sparse=TRUE) not yet implemented" #~ msgstr "dgCMatrix_matrix_solve(.., sparse=TRUE) non ancora implementato" #~ msgid "lengths of slots i and x must match" #~ msgstr "le lunghezze degli slot i e x devono corrispondere" #, c-format #~ msgid "too large matrix: %.0f" #~ msgstr "matrice troppo grande: %.0f" #, c-format #~ msgid "Cannot coerce to too large *geMatrix with %.0f entries" #~ msgstr "" #~ "Non è possibile la coercizione su una *geMatrix troppo grande con %.0f " #~ "voci" #~ msgid "x slot must be numeric \"double\"" #~ msgstr "lo slot x dev'essere un numerico \"double\"" #~ msgid "factors slot must be named list" #~ msgstr "lo slot dei fattori dev'essere una lista nominata" #~ msgid "rcond requires a square, non-empty matrix" #~ msgstr "rcond richiede una matrice quadrata, non vuota" #~ msgid "diagonal to be added has wrong length" #~ msgstr "la diagonale da aggiungere ha una lunghezza errata" #~ msgid "Cannot factor a matrix with zero extents" #~ msgstr "Non è possibile fattorizzare una matrice con zero estensioni" #, c-format #~ msgid "Exact singularity detected during LU decomposition: %s, i=%d." #~ msgstr "" #~ "Singolarità esatta rilevata durante la decomposizione LU: %s, i =%d." #~ msgid "Solve requires a square matrix" #~ msgstr "Solve richiede una matrice quadrata" #, c-format #~ msgid "error [%d] from Lapack 'dgecon()'" #~ msgstr "error [%d] da Lapack 'dgecon()'" #, c-format #~ msgid "" #~ "Lapack dgecon(): system computationally singular, reciprocal condition " #~ "number = %g" #~ msgstr "" #~ "Lapack dgecon(): sistema computazionalmente singolare, numero di " #~ "condizione reciproca =%g" #~ msgid "Lapack routine dgetri: system is exactly singular" #~ msgstr "Routine Lapack dgetri: il sistema è esattamente singolare" #~ msgid "dpoMatrix is not positive definite" #~ msgstr "dpoMatrix non è definita positiva" #~ msgid "Cannot solve() for matrices with zero extents" #~ msgstr "Non è possibile eseguire solve() per matrici con zero estensioni" #~ msgid "Argument b must be a numeric matrix" #~ msgstr "L'argomento b dev'essere una matrice numerica" #~ msgid "chm_factor_name(): did not get string of length 11" #~ msgstr "chm_factor_name(): non ha ottenuto una stringa di lunghezza 11" #~ msgid "" #~ "Cholesky factorization failed; unusually, please report to Matrix-authors" #~ msgstr "" #~ "Fattorizzazione di Cholesky fallita; insolitamente, per piacere " #~ "riportatelo agli autori del pacchetto" #~ msgid "internal_chm_factor: Cholesky factorization failed" #~ msgstr "internal_chm_factor: fattorizzazione Cholesky fallita" #~ msgid "Non-symmetric matrix passed to dsCMatrix_to_dgTMatrix" #~ msgstr "Matrice non simmetrica passata a dsCMatrix_to_dgTMatrix" #~ msgid "Incorrect length of 'x' slot" #~ msgstr "Lunghezza incorretta dello slot 'x'" #, c-format #~ msgid "Lapack routine dsytrf returned error code %d" #~ msgstr "La routine Lapack dsytrf ha restituito il codice di errore %d" #~ msgid "x must be a \"double\" (numeric) matrix" #~ msgstr "x dev'essere una matrice (numerica) \"double\"" #~ msgid "matrix_trf(x, *): matrix is not square" #~ msgstr "matrix_trf(x, *): la matrice non è quadrata" #~ msgid "matrix_trf(*, uplo): uplo must be string" #~ msgstr "matrix_trf(*, uplo): uplo dev'essere una stringa" #~ msgid "cannot set diag() as long as 'diag = \"U\"'" #~ msgstr "non è possibile impostare diag() purché 'diag = \"U\"'" #~ msgid "cannot add diag() as long as 'diag = \"U\"'" #~ msgstr "non è possibile aggiungere diag() purché 'diag = \"U\"'" #~ msgid "x slot is not of correct length" #~ msgstr "lo slot x non è della lunghezza corretta" #~ msgid "A must be a logical matrix" #~ msgstr "A dev'essere una matrice logica" #~ msgid "length(p) must match nrow(V)" #~ msgstr "length(p) deve corrispondere con nrow(V)" #~ msgid "length(beta) must match ncol(V)" #~ msgstr "length(beta) deve corrispondere con ncol(V)" #~ msgid "length(q) must be zero or ncol(R)" #~ msgstr "length(q) dev'essere zero o ncol(R)" #, c-format #~ msgid "sparseQR_Qmult(): nrow(y) = %d != %d = nrow(V)" #~ msgstr "sparseQR_Qmult(): nrow(y) = %d != %d = nrow(V)" #~ msgid "\"dtrMatrix\" objects in '%*%' must have matching (square) dimension" #~ msgstr "" #~ "gli oggetti \"dtrMatrix\" in '%*%' devono avere corrispondenti dimensioni " #~ "(quadrate)" Matrix/po/ko.po0000644000176200001440000016013714521047060013114 0ustar liggesusers# Korean translations for Matrix package. # Recommended/Matrix/po/ko.po # # Thanks to Martin Maechler # # This file is distributed under the same license as the R Matrix package. # Maintained by Chel Hee Lee , 2013-2015. # # Notes: # Freezing on 15-JUL-2015 for R-3.3.0, QC: PASS # Freezing on 30-MAR-2015 for R-3.2.0, QC: PASS # Freezing on 28-FEB-2015 for R-3.1.3, QC: PASS # msgid "" msgstr "" "Project-Id-Version: Matrix 1.1-3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-11-02 21:33-0400\n" "PO-Revision-Date: 2015-07-15 17:14-0600\n" "Last-Translator:Chel Hee Lee \n" "Language-Team: Chel Hee Lee \n" "Language: ko\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" #: Csparse.c:26 Csparse.c:318 chm_common.c:165 chm_common.c:291 #: chm_common.c:813 chm_common.c:816 chm_common.c:849 chm_common.c:867 #: dgCMatrix.c:18 dgCMatrix.c:43 dgCMatrix.c:70 dgCMatrix.c:84 dgCMatrix.c:89 #: dgCMatrix.c:94 #, fuzzy, c-format msgid "'%s' failed" msgstr "cs_qr 실패" #: Csparse.c:35 chm_common.c:54 #, fuzzy, c-format msgid "'%s' slot is not increasing within columns after sorting" msgstr "슬롯 j는 열(column)내에서 증가하지 않습니다" #: Csparse.c:77 coerce.c:220 coerce.c:240 coerce.c:250 coerce.c:905 #: coerce.c:911 coerce.c:1015 coerce.c:1501 coerce.c:1521 coerce.c:1531 #: coerce.c:2061 coerce.c:2256 coerce.c:2262 coerce.c:2268 coerce.c:2397 #: coerce.c:2404 coerce.c:2494 coerce.c:2629 coerce.c:2707 coerce.c:2729 #: coerce.c:4327 coerce.c:4396 dense.c:701 products.c:936 products.c:1288 #: solve.c:719 solve.c:968 solve.c:1100 sparse.c:1233 sparse.c:1625 #, fuzzy, c-format msgid "invalid '%s' to '%s'" msgstr "'%s' 인자는 유효하지 않습니다" #: Csparse.c:316 #, fuzzy, c-format msgid "failed to open file \"%s\" for writing" msgstr "쓰기 위하여 파일 \"%s\"을 여는데 실패했습니다." #: attrib.c:229 #, fuzzy msgid "invalid factor name" msgstr "'%s' 인자는 유효하지 않습니다" #: attrib.c:233 #, c-format msgid "attempt to set factor on %s without '%s' slot" msgstr "" #: bind.c:46 bind.c:153 msgid "number of rows of matrices must match" msgstr "" #: bind.c:48 bind.c:155 msgid "number of columns of matrices must match" msgstr "" #: bind.c:51 bind.c:158 bind.c:182 bind.c:206 chm_common.c:474 chm_common.c:623 #: chm_common.c:717 cholmod-etc.c:183 cholmod-etc.c:282 cholmod-etc.c:325 #: coerce.c:215 coerce.c:235 coerce.c:260 coerce.c:268 coerce.c:276 #: coerce.c:341 coerce.c:1496 coerce.c:1516 coerce.c:1543 coerce.c:1551 #: coerce.c:1559 products.c:28 products.c:50 products.c:56 #, c-format msgid "dimensions cannot exceed %s" msgstr "" #: bind.c:210 msgid "number of rows of result is not a multiple of vector length" msgstr "" #: bind.c:212 msgid "number of columns of result is not a multiple of vector length" msgstr "" #: bind.c:626 bind.c:691 sparse.c:912 sparse.c:993 #, c-format msgid "%s cannot exceed %s" msgstr "" #: bind.c:756 bind.c:853 chm_common.c:720 cholmod-etc.c:328 coerce.c:29 #: coerce.c:518 coerce.c:811 coerce.c:945 coerce.c:2772 coerce.c:3041 #: coerce.c:3139 dense.c:924 products.c:151 products.c:212 products.c:291 #: products.c:379 products.c:456 products.c:550 products.c:865 subscript.c:1232 #: subscript.c:1417 utils-R.c:32 #, c-format msgid "attempt to allocate vector of length exceeding %s" msgstr "" #: bind.c:858 products.c:1354 msgid "should never happen ..." msgstr "" #: chm_common.c:11 chm_common.c:34 validity.c:38 validity.c:183 validity.c:262 #: validity.c:281 validity.c:290 validity.c:309 validity.c:335 validity.c:355 #: validity.c:405 validity.c:422 validity.c:456 validity.c:473 validity.c:507 #: validity.c:509 validity.c:959 validity.c:992 validity.c:1074 validity.c:1094 #: validity.c:1160 validity.c:1162 validity.c:1210 validity.c:1273 #: validity.c:1275 validity.c:1321 validity.c:1368 validity.c:1417 #: validity.c:1450 validity.c:1460 validity.c:1473 validity.c:1527 #: validity.c:1529 validity.c:1561 validity.c:1573 validity.c:1596 #: validity.c:1659 validity.c:1678 validity.c:1680 validity.c:1712 #: validity.c:1747 validity.c:1775 #, fuzzy, c-format msgid "'%s' slot is not of type \"%s\"" msgstr "x 슬롯(slot)은 반드시 \"double\"형 숫자(numeric)이어야 합니다." #: chm_common.c:14 validity.c:357 validity.c:407 validity.c:458 validity.c:880 #: validity.c:891 validity.c:961 validity.c:994 validity.c:1096 validity.c:1164 #: validity.c:1212 validity.c:1277 validity.c:1323 validity.c:1462 #: validity.c:1479 validity.c:1531 validity.c:1533 validity.c:1563 #: validity.c:1575 validity.c:1598 validity.c:1714 validity.c:1751 #: validity.c:1779 validity.c:1829 #, fuzzy, c-format msgid "'%s' slot does not have length %s" msgstr "Dim 슬롯(slot)의 길이는 반드시 2이어야 합니다." #: chm_common.c:18 validity.c:410 validity.c:461 validity.c:1667 #: validity.c:1687 validity.c:1689 #, fuzzy, c-format msgid "first element of '%s' slot is not 0" msgstr "슬롯 p의 첫번째 요소는 반드시 0 이어야 합니다. " #: chm_common.c:23 chm_common.c:46 validity.c:43 validity.c:361 validity.c:414 #: validity.c:432 validity.c:465 validity.c:483 validity.c:519 validity.c:521 #: validity.c:1041 validity.c:1053 validity.c:1100 validity.c:1173 #: validity.c:1185 validity.c:1286 validity.c:1298 validity.c:1327 #: validity.c:1378 validity.c:1427 validity.c:1466 validity.c:1486 #: validity.c:1567 validity.c:1583 validity.c:1608 validity.c:1672 #: validity.c:1692 validity.c:1694 validity.c:1721 #, c-format msgid "'%s' slot contains NA" msgstr "" #: chm_common.c:26 validity.c:416 validity.c:467 #, fuzzy, c-format msgid "'%s' slot is not nondecreasing" msgstr "슬롯 p는 반드시 감소하지 않아야(non-decreasing) 합니다." #: chm_common.c:29 validity.c:418 validity.c:469 #, c-format msgid "first differences of '%s' slot exceed %s" msgstr "" #: chm_common.c:37 validity.c:424 validity.c:475 #, fuzzy, c-format msgid "'%s' slot has length less than %s" msgstr "'Dim'은 2 보다 짧은 슬롯의 길이를 가지고 있습니다." #: chm_common.c:49 validity.c:363 validity.c:434 validity.c:485 validity.c:523 #: validity.c:526 validity.c:1043 validity.c:1102 validity.c:1175 #: validity.c:1187 validity.c:1288 validity.c:1300 validity.c:1380 #: validity.c:1429 validity.c:1488 validity.c:1610 validity.c:1723 #, fuzzy, c-format msgid "'%s' slot has elements not in {%s}" msgstr "'Dim'은 2 보다 짧은 슬롯의 길이를 가지고 있습니다." #: chm_common.c:467 chm_common.c:470 chm_common.c:472 chm_common.c:616 #: chm_common.c:619 chm_common.c:621 chm_common.c:711 chm_common.c:713 #: cholmod-etc.c:177 cholmod-etc.c:179 cholmod-etc.c:181 cholmod-etc.c:276 #: cholmod-etc.c:278 cholmod-etc.c:280 cholmod-etc.c:319 cholmod-etc.c:321 #: cs-etc.c:43 #, c-format msgid "wrong '%s'" msgstr "" #: chm_common.c:477 cholmod-etc.c:186 #, fuzzy, c-format msgid "'%s' would overflow type \"%s\"" msgstr "x 슬롯(slot)은 반드시 \"double\"형 숫자(numeric)이어야 합니다." #: chm_common.c:481 cholmod-etc.c:190 #, c-format msgid "n+1 would overflow type \"%s\"" msgstr "" #: chm_common.c:486 cholmod-etc.c:195 #, fuzzy, c-format msgid "leading principal minor of order %d is not positive" msgstr "the leading minor of order %d is not positive definite" #: chm_common.c:489 cholmod-etc.c:198 #, fuzzy, c-format msgid "leading principal minor of order %d is zero" msgstr "the leading minor of order %d is not positive definite" #: chm_common.c:715 cholmod-etc.c:323 msgid "leading dimension not equal to number of rows" msgstr "" #: chm_common.c:778 #, c-format msgid "" "invalid simplicial Cholesky factorization: structural zero on main diagonal " "in column %d" msgstr "" #: chm_common.c:838 #, fuzzy, c-format msgid "CHOLMOD error '%s' at file '%s', line %d" msgstr "Cholmod error '%s' at file %s, line %d" #: chm_common.c:841 #, fuzzy, c-format msgid "CHOLMOD warning '%s' at file '%s', line %d" msgstr "Cholmod warning '%s' at file %s, line %d" #: coerce.c:24 coerce.c:364 coerce.c:1050 #, fuzzy, c-format msgid "attempt to construct non-square %s" msgstr "행렬식(determinant)를 얻기 위해서는 정방행렬을 사용해야 합니다." #: coerce.c:186 coerce.c:476 coerce.c:1467 coerce.c:1622 #, c-format msgid "second argument of '%s' does not specify a subclass of %s" msgstr "" #: coerce.c:194 coerce.c:200 coerce.c:484 coerce.c:490 coerce.c:925 #: coerce.c:1475 coerce.c:1481 coerce.c:1630 coerce.c:1636 coerce.c:2275 #: coerce.c:3344 coerce.c:3349 #, fuzzy, c-format msgid "'%s' must be \"%s\" or \"%s\"" msgstr "'%s'는 반드시 '%s'내에 있어야 합니다." #: coerce.c:246 coerce.c:496 coerce.c:793 coerce.c:917 coerce.c:1527 #: coerce.c:1642 dense.c:322 dense.c:1107 dense.c:1683 dense.c:1688 #: dense.c:1934 dense.c:2129 sparse.c:783 sparse.c:2448 sparse.c:3140 #: sparse.c:3145 sparse.c:3150 sparse.c:3426 sparse.c:3663 #, fuzzy, c-format msgid "'%s' must be %s or %s" msgstr "'%s'는 반드시 '%s'내에 있어야 합니다." #: coerce.c:266 coerce.c:274 coerce.c:285 coerce.c:1549 coerce.c:1557 #: coerce.c:1568 msgid "nonempty vector supplied for empty matrix" msgstr "" #: coerce.c:287 coerce.c:1570 #, c-format msgid "vector length (%lld) exceeds matrix length (%d * %d)" msgstr "" #: coerce.c:290 coerce.c:1573 #, c-format msgid "matrix length (%d * %d) is not a multiple of vector length (%lld)" msgstr "" #: coerce.c:521 #, c-format msgid "coercing n-by-n %s to %s is not supported for n*n exceeding %s" msgstr "" #: coerce.c:525 coerce.c:815 coerce.c:949 #, c-format msgid "sparse->dense coercion: allocating vector of size %0.1f GiB" msgstr "" #: coerce.c:1196 coerce.c:1941 coerce.c:2948 coerce.c:2954 #, c-format msgid "attempt to construct %s with more than %s nonzero entries" msgstr "" #: coerce.c:3246 #, fuzzy msgid "attempt to pack non-square matrix" msgstr "행렬식(determinant)를 얻기 위해서는 정방행렬을 사용해야 합니다." #: coerce.c:3420 coerce.c:3590 #, c-format msgid "unable to aggregate %s with '%s' and '%s' slots of length exceeding %s" msgstr "" #: coerce.c:4211 #, fuzzy, c-format msgid "attempt to pack a %s" msgstr "행렬식(determinant)를 얻기 위해서는 정방행렬을 사용해야 합니다." #: coerce.c:4330 dense.c:1237 sparse.c:2579 #, fuzzy, c-format msgid "'%s' must be %s or %s or %s" msgstr "'%s'는 반드시 '%s'내에 있어야 합니다." #: dense.c:210 dense.c:215 sparse.c:590 sparse.c:595 #, fuzzy, c-format msgid "'%s' must be an integer from %s to %s" msgstr "'%s'는 반드시 '%s'내에 있어야 합니다." #: dense.c:218 sparse.c:598 #, fuzzy, c-format msgid "'%s' must be less than or equal to '%s'" msgstr "'%s'는 반드시 '%s'내에 있어야 합니다." #: dense.c:428 sparse.c:1069 #, c-format msgid "replacement diagonal has incompatible type \"%s\"" msgstr "" #: dense.c:437 sparse.c:1078 msgid "replacement diagonal has wrong length" msgstr "" #: dense.c:627 sparse.c:1274 #, fuzzy msgid "attempt to symmetrize a non-square matrix" msgstr "행렬식(determinant)를 얻기 위해서는 정방행렬을 사용해야 합니다." #: dense.c:726 sparse.c:1652 msgid "attempt to get symmetric part of non-square matrix" msgstr "" #: dense.c:878 sparse.c:2082 msgid "attempt to get skew-symmetric part of non-square matrix" msgstr "" #: dense.c:1678 sparse.c:3135 #, fuzzy, c-format msgid "'%s' must be %d or %d" msgstr "'%s'는 반드시 '%s'내에 있어야 합니다." #: dense.c:2161 #, c-format msgid "incorrect left cyclic shift, j (%d) < 0" msgstr "incorrect left cyclic shift, j (%d) < 0" #: dense.c:2164 #, c-format msgid "incorrect left cyclic shift, j (%d) >= k (%d)" msgstr "incorrect left cyclic shift, j (%d) >= k (%d)" #: dense.c:2167 #, c-format msgid "incorrect left cyclic shift, k (%d) > ldx (%d)" msgstr "incorrect left cyclic shift, k (%d) > ldx (%d)" #: dense.c:2220 #, fuzzy msgid "unknown error in getGivens" msgstr "getGivens에서 알 수 없는 에러가 발생했습니다" #: dense.c:2229 dense.c:2243 dense.c:2273 msgid "X must be a numeric (double precision) matrix" msgstr "X는 반드시 double precision을 가진 수치형 행렬이어야 합니다." #: dense.c:2245 dense.c:2275 msgid "y must be a numeric (double precision) matrix" msgstr "y는 반드시 double precision을 가진 수치형 행렬이어야 합니다." #: dense.c:2249 dense.c:2279 #, c-format msgid "number of rows in y (%d) does not match number of rows in X (%d)" msgstr "y가 가진 행의 개수 (%d)가 X가 가진 행의 개수 (%d)와 일치하지 않습니다." #: dense.c:2265 #, fuzzy, c-format msgid "LAPACK dposv returned error code %d" msgstr "다음의 에러코드가 Lapack 루틴 dposv으로부터 반환되었습니다: %d" #: dense.c:2293 dense.c:2299 #, fuzzy, c-format msgid "LAPACK dgels returned error code %d" msgstr "에러코드 %2$d는 Lapack 루틴 %1$s로부터 얻어졌습니다." #: dense.c:2318 msgid "X must be a real (numeric) matrix" msgstr "X는 반드시 실수(real)형 숫자를 가진 행렬이어야 합니다." #: dense.c:2321 #, fuzzy, c-format msgid "tol, given as %g, must be >= 0" msgstr "tol의 값은 1보다 작거나 같아야 하는데 %g를 가지고 있습니다." #: dense.c:2323 #, c-format msgid "tol, given as %g, must be <= 1" msgstr "tol의 값은 1보다 작거나 같아야 하는데 %g를 가지고 있습니다." #: dense.c:2352 dense.c:2360 #, fuzzy, c-format msgid "LAPACK dgeqrf returned error code %d" msgstr "dgeqrf에 첫번째 호출로부터 다음과 같은 에러코드가 반환되었습니다: %d" #: dense.c:2365 dense.c:2388 #, fuzzy, c-format msgid "LAPACK dtrcon returned error code %d" msgstr "에러코드 %d가 Lapack 루틴 dtrcon으로부터 반환되었습니다." #: determinant.c:33 #, fuzzy msgid "determinant of non-square matrix is undefined" msgstr "행렬식(determinant)를 얻기 위해서는 정방행렬을 사용해야 합니다." #: determinant.c:276 #, fuzzy, c-format msgid "%s(<%s>) does not support structurally rank deficient case" msgstr "%s(): 구조적으로 계수에 문제가 있는 경우입니다: possibly WRONG zeros" #: dgCMatrix.c:14 #, fuzzy, c-format msgid "'%s' is empty or not square" msgstr "정방행렬이 아닙니다." #: dgCMatrix.c:16 dgCMatrix.c:38 dgCMatrix.c:61 solve.c:43 solve.c:984 #, fuzzy, c-format msgid "dimensions of '%s' and '%s' are inconsistent" msgstr "Dimensions of system to be solved are inconsistent" #: dgCMatrix.c:40 #, c-format msgid "%s(%s, %s) requires m-by-n '%s' with m >= n > 0" msgstr "" #: dgCMatrix.c:63 #, c-format msgid "%s(%s, %s) requires m-by-n '%s' with n >= m > 0" msgstr "" #: dgeMatrix.c:22 #, c-format msgid "dgeMatrix_svd(x,*): dim(x)[j] = %d is too large" msgstr "" #: dgeMatrix.c:90 msgid "Matrix exponential requires square, non-null matrix" msgstr "행렬의 지수(exponential)은 정방이고 non-null인 행렬이어야 합니다" #: dgeMatrix.c:107 dgeMatrix.c:109 #, c-format msgid "dgeMatrix_exp: LAPACK routine dgebal returned %d" msgstr "dgeMatrix_exp: %d가 LAPACK 루틴 dgebal로부터 반환되었습니다." #: dgeMatrix.c:147 #, c-format msgid "dgeMatrix_exp: dgetrf returned error code %d" msgstr "dgeMatrix_exp: 에러코드 %d가 dgetrf로부터 반환되었습니다." #: dgeMatrix.c:149 #, c-format msgid "dgeMatrix_exp: dgetrs returned error code %d" msgstr "dgeMatrix_exp: 에러코드 %d가 dgetrs로부터 반환되었습니다." #: dgeMatrix.c:224 msgid "dgeMatrix_Schur: argument x must be a non-null square matrix" msgstr "" "dgeMatrix_Schur: 인자 x는 반드시 null이 아닌 정방(square)행렬이어야 합니다." #: dgeMatrix.c:237 msgid "dgeMatrix_Schur: first call to dgees failed" msgstr "dgeMatrix_Schur: dgees로의 첫번째 호출에 실패했습니다" #: dgeMatrix.c:246 #, c-format msgid "dgeMatrix_Schur: dgees returned code %d" msgstr "dgeMatrix_Schur: 코드 %d가 dgees로부터 반환되었습니다." #: factorizations.c:355 sparse.c:196 #, fuzzy, c-format msgid "'%s' is not a number" msgstr "정방행렬이 아닙니다." #: factorizations.c:376 #, c-format msgid "LU factorization of m-by-n %s requires m == n" msgstr "" #: factorizations.c:385 #, c-format msgid "LU factorization of %s failed: out of memory or near-singular" msgstr "" #: factorizations.c:462 #, c-format msgid "QR factorization of m-by-n %s requires m >= n" msgstr "" #: factorizations.c:471 #, c-format msgid "QR factorization of %s failed: out of memory" msgstr "" #: factorizations.c:571 factorizations.c:849 #, c-format msgid "'%s' is not a number or not finite" msgstr "" #: idz.c:467 idz.c:528 #, c-format msgid "incompatible '%s' and '%s' in '%s'" msgstr "" #: kappa.c:10 kappa.c:54 #, fuzzy, c-format msgid "argument '%s' is not of type \"%s\"" msgstr "인자 type[1]='%s'는 반드시 길이가 1인 문자이어야 합니다." #: kappa.c:13 kappa.c:57 #, fuzzy, c-format msgid "argument '%s' has length %d" msgstr "'%s'는 반드시 길이가 1인 문자열(string)이어야 합니다." #: kappa.c:17 kappa.c:61 #, fuzzy, c-format msgid "argument '%s' (\"%s\") does not have string length %d" msgstr "'%s'는 반드시 길이가 1인 문자열(string)이어야 합니다." #: kappa.c:41 #, c-format msgid "" "argument '%s' (\"%s\") is not \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", or " "\"%s\"" msgstr "" #: kappa.c:75 #, fuzzy, c-format msgid "argument '%s' (\"%s\") is not \"%s\", \"%s\", or \"%s\"" msgstr "'%s'는 반드시 길이가 1인 문자열(string)이어야 합니다." #: kappa.c:238 #, c-format msgid "%s(%s) is undefined: '%s' is not square" msgstr "" #: objects.c:23 #, c-format msgid "unexpected type \"%s\" in '%s'" msgstr "" #: objects.c:41 objects.c:58 #, c-format msgid "unexpected kind \"%c\" in '%s'" msgstr "" #: perm.c:26 perm.c:106 msgid "attempt to get sign of non-permutation" msgstr "" #: perm.c:51 perm.c:123 msgid "attempt to invert non-permutation" msgstr "" #: perm.c:66 #, fuzzy msgid "invalid transposition vector" msgstr "%d번째 위치에서 유효하지 않은 행인덱스가 있습니다" #: perm.c:79 perm.c:81 perm.c:96 perm.c:98 perm.c:113 perm.c:133 perm.c:145 #, fuzzy, c-format msgid "'%s' is not of type \"%s\"" msgstr "x 슬롯(slot)은 반드시 \"double\"형 숫자(numeric)이어야 합니다." #: perm.c:83 perm.c:100 perm.c:147 #, fuzzy, c-format msgid "'%s' does not have length %d" msgstr "슬롯 '%s'의 길이는 반드시 1이어야 합니다." #: perm.c:86 perm.c:103 #, c-format msgid "'%s' is NA" msgstr "" #: perm.c:115 perm.c:138 #, fuzzy, c-format msgid "'%s' or '%s' is not of type \"%s\"" msgstr "x 슬롯(slot)은 반드시 \"double\"형 숫자(numeric)이어야 합니다." #: perm.c:117 perm.c:140 #, fuzzy, c-format msgid "'%s' or '%s' does not have length %d" msgstr "슬롯 '%s'의 길이는 반드시 1이어야 합니다." #: perm.c:120 perm.c:143 #, c-format msgid "'%s' or '%s' is NA" msgstr "" #: perm.c:136 #, c-format msgid "'%s' has length exceeding %s" msgstr "" #: perm.c:150 #, c-format msgid "'%s' is NA or less than %s" msgstr "" #: products.c:107 products.c:210 products.c:289 products.c:377 products.c:454 #: products.c:548 products.c:809 products.c:859 msgid "non-conformable arguments" msgstr "" #: products.c:782 products.c:807 #, c-format msgid "'%s' does not support complex matrices" msgstr "" #: solve.c:38 #, fuzzy, c-format msgid "'%s' is not square" msgstr "정방행렬이 아닙니다." #: solve.c:497 #, c-format msgid "%s(<%s>, <%s>) failed: out of memory" msgstr "" #: solve.c:618 #, fuzzy, c-format msgid "attempt to construct %s with more than %s nonzero elements" msgstr "행렬식(determinant)를 얻기 위해서는 정방행렬을 사용해야 합니다." #: sparseVector.c:90 #, c-format msgid "%s length cannot exceed %s" msgstr "" #: subscript.c:1542 subscript.c:1695 subscript.c:1938 subscript.c:2122 #, c-format msgid "%s too dense for %s; would have more than %s nonzero entries" msgstr "" #: subscript.c:2209 #, c-format msgid "NA subscripts in %s not supported for '%s' inheriting from %s" msgstr "" #: t_Csparse_subassign.c:142 msgid "invalid class of 'x' in Csparse_subassign()" msgstr "Csparse_subassign()에서 사용되는 'x'의 클래스가 올바르지 않습니다." #: t_Csparse_subassign.c:144 msgid "invalid class of 'value' in Csparse_subassign()" msgstr "Csparse_subassign()에서 사용되는 'value'의 클래스가 올바르지 않습니다." #: t_Csparse_subassign.c:187 #, c-format msgid "x[] <- val: val is coerced to logical for \"%s\" x" msgstr "x[] <- val: val is coerced to logical for \"%s\" x" #: t_Csparse_subassign.c:192 #, c-format msgid "" "x[] <- val: val should be integer or logical, is coerced to integer, for " "\"%s\" x" msgstr "" "x[] <- val: val should be integer or logical, is coerced to integer, for " "\"%s\" x" #: t_Csparse_subassign.c:199 msgid "programming error in Csparse_subassign() should never happen" msgstr "" "Csparse_subassign()를 사용 중 발생하지 말아야 하는 프로그래밍 에러" "(programming error)가 발견되었습니다." #: utils-R.c:30 utils-R.c:116 #, c-format msgid "indices would exceed %s" msgstr "" #: utils-R.c:235 utils-R.c:270 utils-R.c:281 utils-R.c:312 msgid "Argument must be numeric-like atomic vector" msgstr "인자는 반드시 수치형과 같은 기본형 벡터이어야합니다" #: utils-R.c:345 msgid "'data' must be of a vector type" msgstr "'data'는 반드시 벡터형(vector type)이어야 합니다." #: utils-R.c:352 #, c-format msgid "invalid '%s' argument" msgstr "'%s' 인자는 유효하지 않습니다" #: utils-R.c:359 utils-R.c:367 msgid "non-numeric matrix extent" msgstr "non-numeric matrix extent" #: utils-R.c:362 msgid "invalid 'nrow' value (too large or NA)" msgstr "'nrow'의 값이 너무 크거나 NA이므로 올바르지 않습니다." #: utils-R.c:364 msgid "invalid 'nrow' value (< 0)" msgstr "'nrow'의 값이 0 보다 작으므로 올바르지 않습니다." #: utils-R.c:370 msgid "invalid 'ncol' value (too large or NA)" msgstr "'ncol'의 값이 너무 크거나 NA이므로 올바르지 않습니다." #: utils-R.c:372 msgid "invalid 'ncol' value (< 0)" msgstr "'ncol'의 값이 0보다 작으므로 올바르지 않습니다." #: utils-R.c:390 #, c-format msgid "" "data length [%d] is not a sub-multiple or multiple of the number of rows [%d]" msgstr "데이터의 길이[%d]가 행의 개수[%d]의 약수 또는 배수가 아닙니다" #: utils-R.c:395 #, c-format msgid "" "data length [%d] is not a sub-multiple or multiple of the number of columns " "[%d]" msgstr "데이터의 길이[%d]가 열의 개수[%d]의 약수 또는 배수가 아닙니다" #: utils-R.c:399 msgid "data length exceeds size of matrix" msgstr "데이터의 길이(data length)가 행렬의 크기(size of matrix)를 초과합니다." #: utils-R.c:404 msgid "too many elements specified" msgstr "너무 많은 요소들이 지정되었습니다" #: utils-R.c:545 msgid "Argument ij must be 2-column integer matrix" msgstr "인자 ij는 반드시 2개의 열을 가진 정수형 행렬이어야 합니다." #: utils-R.c:570 msgid "subscript 'i' out of bounds in M[ij]" msgstr "첨자 'i'가 M[ij]내에 존재하지 않습니다." #: utils-R.c:572 msgid "subscript 'j' out of bounds in M[ij]" msgstr "첨자 'j'가 M[ij]내에 존재하지 않습니다." #: utils-R.c:626 msgid "i and j must be integer vectors of the same length" msgstr "" "i와 j는 반드시 같은 길이를 가지는 정수형 벡터(integer vectors)이어야 합니다." #: validity.c:40 validity.c:73 validity.c:264 validity.c:283 validity.c:292 #: validity.c:311 validity.c:337 validity.c:1010 validity.c:1452 #: validity.c:1476 #, fuzzy, c-format msgid "'%s' slot does not have length %d" msgstr "Dim 슬롯(slot)의 길이는 반드시 2이어야 합니다." #: validity.c:45 validity.c:965 validity.c:998 #, fuzzy, c-format msgid "'%s' slot has negative elements" msgstr "'Dim'은 2 보다 짧은 슬롯의 길이를 가지고 있습니다." #: validity.c:71 validity.c:197 #, fuzzy, c-format msgid "'%s' slot is not a list" msgstr "x 슬롯(slot)은 반드시 \"double\"형 숫자(numeric)이어야 합니다." #: validity.c:89 #, fuzzy, c-format msgid "%s[[%d]] is not NULL or a vector" msgstr "'s1'과 's2'는 반드시 \"character\"형 벡터이어야 합니다." #: validity.c:92 #, c-format msgid "length of %s[[%d]] (%lld) is not equal to %s[%d] (%d)" msgstr "" #: validity.c:203 #, c-format msgid "'%s' slot has no '%s' attribute" msgstr "" #: validity.c:214 validity.c:277 validity.c:305 validity.c:376 validity.c:1115 #: validity.c:1446 validity.c:1807 #, c-format msgid "%s[1] != %s[2] (matrix is not square)" msgstr "" #: validity.c:239 validity.c:252 #, c-format msgid "%s[1] differs from %s[2]" msgstr "" #: validity.c:267 validity.c:286 validity.c:295 validity.c:314 #, fuzzy, c-format msgid "'%s' slot is not \"%s\" or \"%s\"" msgstr "x 슬롯(slot)은 반드시 \"double\"형 숫자(numeric)이어야 합니다." #: validity.c:320 validity.c:324 #, fuzzy, c-format msgid "'%s' slot is \"%s\" but '%s' slot does not have length %s" msgstr "Dim 슬롯(slot)의 길이는 반드시 2이어야 합니다." #: validity.c:340 #, fuzzy, c-format msgid "'%s' slot is not %d or %d" msgstr "x 슬롯(slot)은 반드시 \"double\"형 숫자(numeric)이어야 합니다." #: validity.c:346 validity.c:349 #, c-format msgid "%s-by-%s %s invalid for positive '%s' when %s=%d" msgstr "" #: validity.c:386 validity.c:1178 validity.c:1190 validity.c:1291 #: validity.c:1303 validity.c:1383 validity.c:1432 validity.c:1491 #, c-format msgid "'%s' slot contains duplicates" msgstr "" #: validity.c:437 validity.c:1613 #, fuzzy, c-format msgid "'%s' slot is not increasing within columns" msgstr "슬롯 j는 열(column)내에서 증가하지 않습니다" #: validity.c:488 #, fuzzy, c-format msgid "'%s' slot is not increasing within rows" msgstr "슬롯 j는 열(column)내에서 증가하지 않습니다" #: validity.c:512 validity.c:801 validity.c:827 validity.c:853 validity.c:1076 #: validity.c:1682 validity.c:1684 #, fuzzy, c-format msgid "'%s' and '%s' slots do not have equal length" msgstr "Dim 슬롯(slot)의 길이는 반드시 2이어야 합니다." #: validity.c:515 #, c-format msgid "'%s' slot has nonzero length but %s is 0" msgstr "" #: validity.c:555 validity.c:600 validity.c:646 validity.c:691 validity.c:735 #: validity.c:770 #, fuzzy, c-format msgid "%s=\"%s\" but there are entries below the diagonal" msgstr "uplo='U'의 경우에는 어떠한 값들도 대각의 아랫부분에 있어서는 안됩니다." #: validity.c:565 validity.c:613 validity.c:656 validity.c:704 validity.c:740 #: validity.c:781 #, fuzzy, c-format msgid "%s=\"%s\" but there are entries above the diagonal" msgstr "uplo='L'의 경우는 어떠한 값들도 대각의 윗부분에 있어서는 안됩니다." #: validity.c:603 validity.c:616 validity.c:694 validity.c:707 validity.c:773 #: validity.c:784 #, fuzzy, c-format msgid "%s=\"%s\" but there are entries on the diagonal" msgstr "uplo='U'의 경우에는 어떠한 값들도 대각의 아랫부분에 있어서는 안됩니다." #: validity.c:911 validity.c:935 validity.c:939 msgid "matrix has negative diagonal elements" msgstr "" #: validity.c:955 validity.c:983 validity.c:987 msgid "matrix has nonunit diagonal elements" msgstr "" #: validity.c:1007 validity.c:1032 validity.c:1826 #, fuzzy, c-format msgid "'%s' slot is not of type \"%s\" or \"%s\"" msgstr "x 슬롯(slot)은 반드시 \"double\"형 숫자(numeric)이어야 합니다." #: validity.c:1015 validity.c:1022 #, fuzzy, c-format msgid "'%s' slot is NA" msgstr "x 슬롯(slot)은 반드시 \"double\"형 숫자(numeric)이어야 합니다." #: validity.c:1017 validity.c:1024 #, fuzzy, c-format msgid "'%s' slot is negative" msgstr "'Dim'은 2 보다 짧은 슬롯의 길이를 가지고 있습니다." #: validity.c:1026 #, fuzzy, c-format msgid "'%s' slot exceeds %s" msgstr "'%s'는 반드시 '%s'내에 있어야 합니다." #: validity.c:1036 #, fuzzy, c-format msgid "'%s' slot has length greater than '%s' slot" msgstr "'Dim'은 2 보다 짧은 슬롯의 길이를 가지고 있습니다." #: validity.c:1046 validity.c:1674 validity.c:1696 validity.c:1698 #, fuzzy, c-format msgid "'%s' slot is not increasing" msgstr "슬롯 j는 열(column)내에서 증가하지 않습니다" #: validity.c:1056 #, fuzzy, c-format msgid "'%s' slot has elements not in {%s} after truncation towards zero" msgstr "'Dim'은 2 보다 짧은 슬롯의 길이를 가지고 있습니다." #: validity.c:1059 #, fuzzy, c-format msgid "'%s' slot is not increasing after truncation towards zero" msgstr "슬롯 j는 열(column)내에서 증가하지 않습니다" #: validity.c:1125 validity.c:1152 validity.c:1814 validity.c:1821 #, fuzzy, c-format msgid "dimensions of '%s' slot are not identical to '%s'" msgstr "x와 y의 차원정보가 %s와 일치하지 않습니다." #: validity.c:1127 #, c-format msgid "'%s' slot is upper (not lower) triangular" msgstr "" #: validity.c:1140 #, c-format msgid "'%s' slot has nonunit diagonal elements" msgstr "" #: validity.c:1154 #, c-format msgid "'%s' slot is lower (not upper) triangular" msgstr "" #: validity.c:1166 validity.c:1279 validity.c:1370 validity.c:1419 #, fuzzy, c-format msgid "'%s' slot does not have length %s or length %s" msgstr "Dim 슬롯(slot)의 길이는 반드시 2이어야 합니다." #: validity.c:1206 msgid "matrix has more columns than rows" msgstr "" #: validity.c:1226 #, fuzzy, c-format msgid "'%s' slot has fewer than %s rows" msgstr "'Dim'은 2 보다 짧은 슬롯의 길이를 가지고 있습니다." #: validity.c:1228 #, fuzzy, c-format msgid "'%s' slot has more than %s rows" msgstr "'Dim'은 2 보다 짧은 슬롯의 길이를 가지고 있습니다." #: validity.c:1230 validity.c:1252 #, fuzzy, c-format msgid "'%s' slot does not have %s columns" msgstr "Dim 슬롯(slot)의 길이는 반드시 2이어야 합니다." #: validity.c:1237 #, fuzzy, c-format msgid "'%s' slot must be lower trapezoidal but has entries above the diagonal" msgstr "uplo='L'의 경우는 어떠한 값들도 대각의 윗부분에 있어서는 안됩니다." #: validity.c:1250 #, fuzzy, c-format msgid "'%s' slot does not have %s row" msgstr "Dim 슬롯(slot)의 길이는 반드시 2이어야 합니다." #: validity.c:1259 #, fuzzy, c-format msgid "'%s' slot must be upper trapezoidal but has entries below the diagonal" msgstr "uplo='U'의 경우에는 어떠한 값들도 대각의 아랫부분에 있어서는 안됩니다." #: validity.c:1263 #, c-format msgid "'%s' slot has negative diagonal elements" msgstr "" #: validity.c:1329 #, c-format msgid "'%s' slot has elements not in {%s}\\{%s}" msgstr "" #: validity.c:1338 #, c-format msgid "'%s' slot has unpaired negative elements" msgstr "" #: validity.c:1364 validity.c:1408 validity.c:1412 validity.c:1760 #: validity.c:1792 msgid "Cholesky factor has negative diagonal elements" msgstr "" #: validity.c:1455 #, c-format msgid "%s[%d] (%s) is not in %s" msgstr "" #: validity.c:1468 validity.c:1569 #, c-format msgid "%s is not in {%s}" msgstr "" #: validity.c:1505 #, c-format msgid "%s is not representable as \"%s\"" msgstr "" #: validity.c:1510 validity.c:1516 #, c-format msgid "%s[%d] (%s) is not %d or %d" msgstr "" #: validity.c:1513 validity.c:1629 validity.c:1632 validity.c:1635 #, c-format msgid "%s[%d] (%s) is not %d" msgstr "" #: validity.c:1538 #, c-format msgid "%s has elements not in {%s}" msgstr "" #: validity.c:1541 #, c-format msgid "%s has elements not in {%s}\\{%s}" msgstr "" #: validity.c:1544 #, c-format msgid "%s is %d but columns are not stored in increasing order" msgstr "" #: validity.c:1547 validity.c:1550 #, c-format msgid "traversal of '%s' slot does not complete in exactly %s steps" msgstr "" #: validity.c:1556 validity.c:1558 #, c-format msgid "%s is not %d" msgstr "" #: validity.c:1579 #, c-format msgid "column '%s' is stored first but %s is not 0" msgstr "" #: validity.c:1585 #, fuzzy, c-format msgid "'%s' slot is not increasing when traversed in stored column order" msgstr "슬롯 j는 열(column)내에서 증가하지 않습니다" #: validity.c:1587 #, c-format msgid "'%s' slot allocates fewer than %s elements for column '%s'" msgstr "" #: validity.c:1590 #, c-format msgid "'%s' slot allocates more than %s elements for column '%s'" msgstr "" #: validity.c:1604 #, c-format msgid "first entry in column '%s' does not have row index '%s'" msgstr "" #: validity.c:1638 validity.c:1641 #, c-format msgid "%s[%d] (%s) is negative" msgstr "" #: validity.c:1644 #, c-format msgid "%s[%d] (%s) is not less than %s" msgstr "" #: validity.c:1662 #, fuzzy, c-format msgid "'%s' slot has length less than %d" msgstr "'Dim'은 2 보다 짧은 슬롯의 길이를 가지고 있습니다." #: validity.c:1664 #, fuzzy, c-format msgid "'%s' slot has length greater than %s" msgstr "'Dim'은 2 보다 짧은 슬롯의 길이를 가지고 있습니다." #: validity.c:1669 #, fuzzy, c-format msgid "last element of '%s' slot is not %s" msgstr "슬롯 p의 첫번째 요소는 반드시 0 이어야 합니다. " #: validity.c:1702 #, c-format msgid "first differences of '%s' slot are less than those of '%s' slot" msgstr "" #: validity.c:1705 #, c-format msgid "supernode lengths exceed %s" msgstr "" #: validity.c:1707 #, c-format msgid "first differences of '%s' slot are not equal to supernode lengths" msgstr "" #: validity.c:1727 #, c-format msgid "" "'%s' slot is wrong within diagonal blocks (row and column indices do not " "coincide)" msgstr "" #: validity.c:1730 #, fuzzy, c-format msgid "'%s' slot is not increasing within supernodes" msgstr "슬롯 j는 열(column)내에서 증가하지 않습니다" #: validity.c:1845 #, fuzzy, c-format msgid "invalid class \"%s\" object: %s" msgstr "invalid class of object to %s" #, c-format #~ msgid "diagonal element %d of Cholesky factor is missing" #~ msgstr "콜레스키 분해(Cholesky factor)의 대각요소 %d를 찾을 수 없습니다" #, c-format #~ msgid "cholmod_factorize_p failed: status %d, minor %d of ncol %d" #~ msgstr "cholmod_factorize_p failed: status %d, minor %d of ncol %d" #~ msgid "cholmod_change_factor failed" #~ msgstr "cholmod_change_factor failed" #~ msgid "cholmod_write_sparse returned error code" #~ msgstr "cholmod_write_sparse가 에러코드를 반환하였습니다." #, c-format #~ msgid "%s = '%s' (back-permuted) is experimental" #~ msgstr "%s = '%s' (back-permuted)는 실험단계에 있습니다" #~ msgid "diag_tC(): invalid 'resultKind'" #~ msgstr "diag_tC(): 유효한 'resultKind'가 아닙니다" #, fuzzy #~ msgid "complex matrices are not yet supported" #~ msgstr "complex sparse matrix code not yet written" #~ msgid "Argument rho must be an environment" #~ msgstr "인자 rho는 반드시 인바이런먼트(environment)이어야 합니다." #~ msgid "invalid class of object to as_cholmod_sparse" #~ msgstr "as_cholmod_sparse에 전달된 객체가 올바르지 않습니다." #~ msgid "invalid object passed to as_cholmod_sparse" #~ msgstr "as_cholmod_sparse에 전달된 객체가 올바르지 않습니다." #~ msgid "in_place cholmod_sort returned an error code" #~ msgstr "in_place cholmod_sort returned an error code" #~ msgid "cholmod_sort returned an error code" #~ msgstr "에러코드가 cholmod_sort로부터 반환되었습니다." #~ msgid "chm_sparse_to_SEXP(, *): invalid 'Rkind' (real kind code)" #~ msgstr "chm_sparse_to_SEXP(, *): invalid 'Rkind' (real kind code)" #~ msgid "unknown xtype in cholmod_sparse object" #~ msgstr "cholmod_sparse 객체에 사용할 수 있는 xtype이 아닙니다." #~ msgid "complex sparse matrix code not yet written" #~ msgstr "complex sparse matrix code not yet written" #~ msgid "Symmetric and triangular both set" #~ msgstr "Symmetric and triangular both set" #~ msgid "invalid class of object to as_cholmod_triplet" #~ msgstr "as_cholmod_triplet에 전달된 객체의 클래스가 올바르지 않습니다." #~ msgid "as_cholmod_triplet(): could not reallocate for internal diagU2N()" #~ msgstr "as_cholmod_triplet(): could not reallocate for internal diagU2N()" #~ msgid "unknown xtype in cholmod_triplet object" #~ msgstr "cholmod_triplet 객체에서 사용할 수 있는 xtype이 아닙니다." #~ msgid "invalid class of object to as_cholmod_dense" #~ msgstr "as_cholmod_dense에 전달된 객체의 클래스가 올바르지 않습니다." #, c-format #~ msgid "Unable to initialize cholmod: error code %d" #~ msgstr "cholmod를 초기화 할 수 없습니다: 에러코드 %d" #~ msgid "unknown 'Rkind'" #~ msgstr "사용할 수 있는 'Rkind'이 아닙니다." #~ msgid "unknown xtype" #~ msgstr "사용할 수 있는 xtype이 아닙니다." #~ msgid "code for cholmod_dense with holes not yet written" #~ msgstr "code for cholmod_dense with holes not yet written" #~ msgid "don't know if a dense pattern matrix makes sense" #~ msgstr "don't know if a dense pattern matrix makes sense" #, fuzzy #~ msgid "object of invalid class to 'as_cholmod_factor()'" #~ msgstr "invalid class of object to as_cholmod_factor" #~ msgid "failure in as_cholmod_factor" #~ msgstr "failure in as_cholmod_factor" #~ msgid "CHOLMOD factorization was unsuccessful" #~ msgstr "CHOLMOD factorization was unsuccessful" #, c-format #~ msgid "f->xtype of %d not recognized" #~ msgstr "f->xtype of %d not recognized" #, c-format #~ msgid "chm_diagN2U(): nrow=%d, ncol=%d" #~ msgstr "chm_diagN2U(): nrow=%d, ncol=%d" #, c-format #~ msgid "chm_diagN2U(x, uploT = %d): uploT should be +- 1" #~ msgstr "chm_diagN2U(x, uploT = %d): uploT은 반드시 1 또는 -1이어야 합니다" #~ msgid "dgCMatrix_lusol requires a square, non-empty matrix" #~ msgstr "" #~ "dgCMatrix_lusol은 정방(square)이며 비어있지 않은(non-empty) 행렬을 필요로 " #~ "합니다." #~ msgid "Dimensions of system to be solved are inconsistent" #~ msgstr "Dimensions of system to be solved are inconsistent" #~ msgid "cs_lusol failed" #~ msgstr "cs_lusol 실패" #~ msgid "dgCMatrix_qrsol(., order) needs order in {0,..,3}" #~ msgstr "dgCMatrix_qrsol(., order) needs order in {0,..,3}" #, c-format #~ msgid "" #~ "dgCMatrix_qrsol(<%d x %d>-matrix) requires a 'tall' rectangular matrix" #~ msgstr "" #~ "dgCMatrix_qrsol(<%d x %d>-matrix)은 'tall' 사각행렬(rectangular matrix)이 " #~ "필요합니다." #~ msgid "cs_qrsol() failed inside dgCMatrix_qrsol()" #~ msgstr "dgCMatrix_qrsol()의 내에서 cs_qrsol()이 실패했습니다" #~ msgid "dgCMatrix_cholsol requires a 'short, wide' rectangular matrix" #~ msgstr "dgCMatrix_cholsol requires a 'short, wide' rectangular matrix" #~ msgid "cholmod_sdmult error (rhs)" #~ msgstr "cholmod_sdmult error (rhs)" #, c-format #~ msgid "cholmod_factorize failed: status %d, minor %d from ncol %d" #~ msgstr "cholmod_factorize 실패: 상태 %d, minor %d from ncol %d" #, c-format #~ msgid "cholmod_solve (CHOLMOD_A) failed: status %d, minor %d from ncol %d" #~ msgstr "cholmod_solve (CHOLMOD_A) 실패: 상태 %d, minor %d from ncol %d" #~ msgid "cholmod_sdmult error (resid)" #~ msgstr "cholmod_sdmult error (resid)" #~ msgid "SuiteSparseQR_C_QR returned an error code" #~ msgstr "에러코드가 SuiteSparseQR_C_QR로부터 반환되었습니다." #, fuzzy, c-format #~ msgid "LAPACK routine '%s': matrix is exactly singular, %s[i,i]=0, i=%d" #~ msgstr "Lapack 루틴 dgetrs: 시스템(system)이 정확하게 특이(singular)합니다." #, fuzzy, c-format #~ msgid "" #~ "LAPACK routine '%s': leading principal minor of order %d is not positive" #~ msgstr "the leading minor of order %d is not positive definite" #, fuzzy #~ msgid "missing 'Matrix' namespace; should never happen" #~ msgstr "" #~ "'Matrix' 네임스페이스(namespace)를 찾을 수 없습니다. 반드시 존재해야 합니" #~ "다 " #, fuzzy #~ msgid "'Matrix' namespace not determined correctly" #~ msgstr "올바르게 정의된 Matrix 네임스페이스(namespace)가 아닙니다" #~ msgid "Csparse_sort(x): x is not a valid (apart from sorting) CsparseMatrix" #~ msgstr "" #~ "Csparse_sort(x): x is not a valid (apart from sorting) CsparseMatrix" #~ msgid "csp_eye argument n must be positive" #~ msgstr "csp_eye의 인자 n은 반드시 양수이어야 합니다" #~ msgid "invalid class of 'x' in Matrix_as_cs(a, x)" #~ msgstr "Matrix_as_cs(a, x)에 입력된 'x'의 클래스가 올바르지 않습니다." #, c-format #~ msgid "invalid class of object to %s" #~ msgstr "invalid class of object to %s" #, c-format #~ msgid "cs matrix not compatible with class '%s'" #~ msgstr "cs matrix not compatible with class '%s'" #, c-format #~ msgid "Inappropriate class cl='%s' in Matrix_css_to_SEXP(S, cl, ..)" #~ msgstr "" #~ "Matrix_css_to_SEXP(S, cl, ..)에 입력된 cl='%s'은 올바른 클래스가 아닙니다." #, c-format #~ msgid "Inappropriate class cl='%s' in Matrix_csn_to_SEXP(S, cl, ..)" #~ msgstr "" #~ "Matrix_csn_to_SEXP(S, cl, ..)에 입력된 cl='%s'는 올바른 클래스가 아닙니다." #, c-format #~ msgid "Dimensions of x and y are not compatible for %s" #~ msgstr "x와 y의 차원정보가 %s와 일치하지 않습니다." #~ msgid "Argument y must be numeric, integer or logical" #~ msgstr "인자 y는 반드시 수치형, 정수형, 또는 논리형이어야 합니다." #~ msgid "Matrices are not conformable for multiplication" #~ msgstr "곱셈연산을 할 수 있는 행렬들이 아닙니다" #~ msgid "dtrMatrix must be square" #~ msgstr "dtrMatrix는 정방행렬이 아닙니다." #, c-format #~ msgid "Dimensions of a (%d,%d) and b (%d,%d) do not conform" #~ msgstr "a (%d,%d)와 b (%d,%d)의 크기가 서로 일치하지 않습니다." #~ msgid "right=TRUE is not yet implemented __ FIXME" #~ msgstr "right=TRUE의 경우는 아직 구현되지 않았습니다 __ FIXME" #, c-format #~ msgid "cholmod_change_factor failed with status %d" #~ msgstr "cholmod_change_factor가 실패했으며 상태 %d를 가집니다" #~ msgid "system argument is not valid" #~ msgstr "시스템 인자가 올바르지 않습니다" #, c-format #~ msgid "cholmod_updown() returned %d" #~ msgstr "%d가 cholmod_updown()로부터 반환되었습니다" #~ msgid "cholmod_drop() failed" #~ msgstr "cholmod_drop() failed" #, fuzzy #~ msgid "'off' does not have length 1" #~ msgstr "슬롯 '%s'의 길이는 반드시 1이어야 합니다." #, fuzzy #~ msgid "invalid 'code' to 'R_matrix_as_dense()'" #~ msgstr "dup_mMatrix_as_dgeMatrix에 올바르지 않은 클래스 '%s'입니다" #, fuzzy #~ msgid "invalid 'uplo' to 'R_matrix_as_dense()'" #~ msgstr "dup_mMatrix_as_dgeMatrix에 올바르지 않은 클래스 '%s'입니다" #, fuzzy #~ msgid "invalid 'diag' to 'R_matrix_as_dense()'" #~ msgstr "dup_mMatrix_as_dgeMatrix에 올바르지 않은 클래스 '%s'입니다" #, fuzzy #~ msgid "invalid argument 'system'" #~ msgstr "'%s' 인자는 유효하지 않습니다" #, fuzzy #~ msgid "dimensions of 'qr' and 'y' are inconsistent" #~ msgstr "Dimensions of system to be solved are inconsistent" #, fuzzy #~ msgid "invalid 'op'" #~ msgstr "'%s' 인자는 유효하지 않습니다" #, fuzzy #~ msgid "'names' must be TRUE or FALSE" #~ msgstr "'uplo'는 반드시 UPP 또는 LOW이어야 합니다." #~ msgid "Csparse_crossprod(): error return from cholmod_aat()" #~ msgstr "Csparse_crossprod(): cholmod_aat()로부터 에러가 반환되었습니다" #, fuzzy #~ msgid "invalid 'kind' to 'R_sparse_as_kind()'" #~ msgstr "Csparse_subassign()에서 사용되는 'x'의 클래스가 올바르지 않습니다." #~ msgid "slot p must have length = nrow(.) + 1" #~ msgstr "슬롯 p는 반드시 nrow(.) + 1의 길이(length)를 가져야 합니다." #~ msgid "last element of slot p must match length of slots j and x" #~ msgstr "슬롯 p의 마지막 요소는 반드시 슬롯 j 와 x의 길이와 일치해야 합니다." #~ msgid "all column indices must be between 0 and ncol-1" #~ msgstr "모든 열 인덱스는 반드시 0 부터 ncol-1 사이의 값이어야 합니다." #~ msgid "slot j is not *strictly* increasing inside a column" #~ msgstr "슬롯 j는 열(column)내에서 *단조*증가하지 않습니다" #~ msgid "not a 'n.CMatrix'" #~ msgstr "'n.CMatrix'이 아닙니다. " #, c-format #~ msgid "nz2Csparse(): invalid/non-implemented r_kind = %d" #~ msgstr "nz2Csparse(): 유효하지 않거나 구현되지 않은 r_kind = %d입니다" #~ msgid "Nonsymmetric matrix in Csparse_symmetric_to_general" #~ msgstr "Csparse_symmetric_to_general에 비대칭행렬이 사용되었습니다" #~ msgid "Csparse_general_to_symmetric(): matrix is not square!" #~ msgstr "Csparse_general_to_symmetric(): 정방행렬이 아닙니다!" #~ msgid "Index i must be NULL or integer" #~ msgstr "인덱스 i는 반드시 NULL 또는 정수(integer)이어야 합니다." #~ msgid "Index j must be NULL or integer" #~ msgstr "인덱스 j는 반드시 NULL 또는 정수(integer)이어야 합니다." #, c-format #~ msgid "negative vector lengths not allowed: np = %d, nnz = %d" #~ msgstr "벡터의 길이가 음수입니다: np = %d, nnz = %d" #~ msgid "exactly 1 of 'i', 'j' or 'p' must be NULL" #~ msgstr "'i', 'j', 또는 'p' 중의 하나만이 반드시 NULL 이어야 합니다." #, c-format #~ msgid "np = %d, must be zero when p is NULL" #~ msgstr "p가 NULL인 경우에는 반드시 np의 값은 0이어야 하는데 %d 입니다." #, c-format #~ msgid "p[0] = %d, should be zero" #~ msgstr "p[0]의 값은 0 이어야 하는데 %d 를 가집니다." #~ msgid "p must be non-decreasing" #~ msgstr "p는 반드시 감소하지 않아야(non-decreasing) 합니다." #, c-format #~ msgid "Inconsistent dimensions: np = 0 and nnz = %d" #~ msgstr "차원정보가 일치하지 않습니다: np = 0 그리고 nnz = %d" #, c-format #~ msgid "invalid column index at position %d" #~ msgstr "%d번째 위치에서 유효하지 않은 열인덱스가 있습니다" #, c-format #~ msgid "strlen of cls argument = %d, should be 8" #~ msgstr "cls의 strlen 인자의 길이는 8 이어야 하는데 %d 입니다." #, c-format #~ msgid "cls = \"%s\" does not end in \"CMatrix\"" #~ msgstr "cls = \"%s\" does not end in \"CMatrix\"" #, c-format #~ msgid "cls = \"%s\" must begin with 'd', 'l' or 'n'" #~ msgstr "cls = \"%s\"는 반드시 'd', 'l' 또는 'n'으로 시작해야 합니다." #~ msgid "Only 'g'eneral sparse matrix types allowed" #~ msgstr "Only 'g'eneral sparse matrix types allowed" #~ msgid "code not yet written for cls = \"lgCMatrix\"" #~ msgstr "아직은 cls = \"lgCMatrix\"을 위하여 작성된 코드가 아닙니다" #, fuzzy, c-format #~ msgid "%s must be (traditional R) matrix" #~ msgstr "A는 반드시 논리형 행렬(logical matrix)이어야 합니다." #, fuzzy, c-format #~ msgid "%s must be character string" #~ msgstr "'s1'과 's2'는 반드시 \"character\"형 벡터이어야 합니다." #, fuzzy, c-format #~ msgid "strlen of cls argument = %d, should be 9" #~ msgstr "cls의 strlen 인자의 길이는 8 이어야 하는데 %d 입니다." #, fuzzy, c-format #~ msgid "cls = \"%s\" must begin with 'd', 'l' or 'n' for now" #~ msgstr "cls = \"%s\"는 반드시 'd', 'l' 또는 'n'으로 시작해야 합니다." #, fuzzy, c-format #~ msgid "%s must be a logical or double vector" #~ msgstr "A는 반드시 논리형 행렬(logical matrix)이어야 합니다." #, c-format #~ msgid "argument type[1]='%s' must be one of 'M','1','O','I','F' or 'E'" #~ msgstr "" #~ "인자 type[1]='%s'은 반드시 'M','1','O','I','F' 또는 'E' 중 하나의 값을 가" #~ "져야 합니다." #, c-format #~ msgid "argument type[1]='%s' must be one of '1','O', or 'I'" #~ msgstr "" #~ "인자 type[1]='%s'은 반드시 '1', '0', 또는 'I' 중 하나의 값을 가져야 합니" #~ "다." #~ msgid "object must be a named, numeric vector" #~ msgstr "객체는 반드시 원소에 이름이 주어진 수치형 벡터이어야 합니다." #~ msgid "'factors' slot must be a named list" #~ msgstr "'factors' 슬롯은 반드시 이름이 주어진 리스트이어야 합니다" #~ msgid "Matrix object has no 'factors' slot" #~ msgstr "행렬의 객체가 'factors' 슬롯을 가지고 있지 않습니다" #~ msgid "'s1' and 's2' must be \"character\" vectors" #~ msgstr "'s1'과 's2'는 반드시 \"character\"형 벡터이어야 합니다." #~ msgid "length of x slot != prod(Dim)" #~ msgstr "x 슬롯의 길이가 prod(Dim)과 같지 않습니다." #~ msgid "Negative value in Dim" #~ msgid_plural "Negative values in Dim" #~ msgstr[0] "Dim 안에 음수가 있습니다." #, c-format #~ msgid "invalid class '%s' to dup_mMatrix_as_geMatrix" #~ msgstr "dup_mMatrix_as_geMatrix에 올바르지 않은 클래스 '%s'입니다" #, c-format #~ msgid "unexpected ctype = %d in dup_mMatrix_as_geMatrix" #~ msgstr "" #~ "dup_mMatrix_as_geMatrix에 사용할 수 없는 ctype = %d가 입력되었습니다." #~ msgid "lengths of slots i and j must match" #~ msgstr "슬롯 i의 길이와 슬롯 j의 길이는 반드시 일치해야 합니다." #~ msgid "slot Dim must have length 2" #~ msgstr "슬롯 Dim의 길이는 반드시 2이어야 합니다." #~ msgid "" #~ "all row indices (slot 'i') must be between 0 and nrow-1 in a TsparseMatrix" #~ msgstr "" #~ "TsparseMatrix에 사용되는 모든 행에 대한 인덱스 (슬롯 'i')는 반드시 0과 " #~ "nrow-1 사이에 존재하는 정수이어야 합니다." #~ msgid "" #~ "all column indices (slot 'j') must be between 0 and ncol-1 in a " #~ "TsparseMatrix" #~ msgstr "" #~ "TsparseMatrix에 사용되는 모든 열에 대한 인덱스 (슬롯 'j')는 반드시 0과 " #~ "ncol-1 사이에 존재하는 정수이어야 합니다." #~ msgid "Supernodal LDL' decomposition not available" #~ msgstr "Supernodal LDL' decomposition not available" #~ msgid "Supernodal/simplicial class inconsistent with type flags" #~ msgstr "Supernodal/simplicial class inconsistent with type flags" #~ msgid "Number of supernodes must be positive when is_super is TRUE" #~ msgstr "" #~ "is_super가 TRUE인 경우에 supernodes의 개수는 반드시 양수이어야 합니다." #~ msgid "Lengths of super and pi must be equal" #~ msgstr "super의 길이와 pi의 길이는 반드시 서로 같아야 합니다." #~ msgid "Lengths of super and px must be equal" #~ msgstr "super의 길이와 px의 길이는 반드시 서로 같아야 합니다." #, c-format #~ msgid "First call to Lapack routine dgels returned error code %d" #~ msgstr "" #~ "Lapack 루틴 dgels에 첫번째 호출로부터 다음과 같은 에러코드가 반환되었습니" #~ "다: %d" #, c-format #~ msgid "Second call to Lapack routine dgels returned error code %d" #~ msgstr "" #~ "Lapack 루틴 dgels에 두번째 호출로부터 다음과 같은 에러코드가 반환되었습니" #~ "다: %d" #, c-format #~ msgid "tol, given as %g, must be non-negative" #~ msgstr "tol의 값은 음이 아닌 수이어야 하는데 %g를 가지고 있습니다." #, c-format #~ msgid "Second call to dgeqrf returned error code %d" #~ msgstr "" #~ "dgeqrf에 두번째 호출로부터 다음과 같은 에러코드가 반환되었습니다: %d" #, c-format #~ msgid "Lower band %d > upper band %d" #~ msgstr "Lower band %d > upper band %d" #~ msgid "ddense_to_symmetric(): matrix is not square!" #~ msgstr "ddense_to_symmetric(): 정방행렬이 아닙니다!" #, c-format #~ msgid "matrix is not symmetric [%d,%d]" #~ msgstr "행렬이 대칭(symmetric)적이지 않습니다 [%d,%d]." #~ msgid "matrix is not square! (symmetric part)" #~ msgstr "정방행렬이 아닙니다! (symmetric part)" #~ msgid "matrix is not square! (skew-symmetric part)" #~ msgstr "정방행렬이 아닙니다! (skew-symmetric part)" #~ msgid "lengths of slots 'i' and 'x' must match" #~ msgstr "슬롯 'i'의 길이와 슬롯 'x'의 길이는 반드시 일치해야 합니다." #~ msgid "lengths of slots 'j' and 'x' must match" #~ msgstr "슬롯 'j'의 길이와 슬롯 'x'의 길이는 반드시 일치해야 합니다." #, c-format #~ msgid "invalid class(x) '%s' in compressed_to_TMatrix(x)" #~ msgstr "" #~ "compressed_to_TMatrix(x) 내에 유효하지 않은 class(x) '%s'가 존재합니다" #, c-format #~ msgid "invalid class(x) '%s' in R_to_CMatrix(x)" #~ msgstr "R_to_CMatrix(x) 내에 유효하지 않은 class(x) '%s'가 존재합니다." #~ msgid "A must have #{rows} >= #{columns}" #~ msgstr "A는 반드시 #{rows} >= #{columns}을 만족해야 합니다." #~ msgid "cs_sqr failed" #~ msgstr "cs_sqr 실패" #~ msgid "LU decomposition applies only to square matrices" #~ msgstr "LU 분해(decomposition)은 오로지 정방행렬에만 적용됩니다." #~ msgid "cs_lu(A) failed: near-singular A (or out of memory)" #~ msgstr "cs_lu(A) failed: near-singular A (or out of memory)" #~ msgid "dgCMatrix_matrix_solve(.., sparse=TRUE) not yet implemented" #~ msgstr "dgCMatrix_matrix_solve(.., sparse=TRUE)은 아직 구현되지 않았습니다" #~ msgid "lengths of slots i and x must match" #~ msgstr "슬롯 i의 길이와 슬롯 x의 길이는 서로 일치해야 합니다." #, c-format #~ msgid "Cannot coerce to too large *geMatrix with %.0f entries" #~ msgstr "Cannot coerce to too large *geMatrix with %.0f entries" #~ msgid "x slot must be numeric \"double\"" #~ msgstr "x 슬롯(slot)은 반드시 \"double\"형 숫자(numeric)이어야 합니다." #~ msgid "factors slot must be named list" #~ msgstr "factors slot must be named list" #~ msgid "rcond requires a square, non-empty matrix" #~ msgstr "rcond는 비어있지 않은 정방행렬이어야 합니다." #~ msgid "Cannot factor a matrix with zero extents" #~ msgstr "Cannot factor a matrix with zero extents" #~ msgid "Solve requires a square matrix" #~ msgstr "Solve를 이용하기 위해서는 정방행렬을 사용해야 합니다." #, c-format #~ msgid "error [%d] from Lapack 'dgecon()'" #~ msgstr "Lapack 'dgecon()'으로부터 에러 [%d]가 발생하였습니다." #, c-format #~ msgid "" #~ "Lapack dgecon(): system computationally singular, reciprocal condition " #~ "number = %g" #~ msgstr "" #~ "Lapack dgecon(): 시스템이 계산적으로 특이하며, 역상태수(reciprocal " #~ "condition number) %g를 가집니다" #~ msgid "Lapack routine dgetri: system is exactly singular" #~ msgstr "Lapack 루틴 dgetri: 시스템(system)이 정확하게 특이(singular)합니다." #~ msgid "dpoMatrix is not positive definite" #~ msgstr "dpoMatrix는 양정치(positive definite)가 아닙니다." #~ msgid "Cannot solve() for matrices with zero extents" #~ msgstr "크기가 0인 행렬에 solve()를 사용할 수 없습니다" #~ msgid "Argument b must be a numeric matrix" #~ msgstr "인자 b는 반드시 수치형 행렬(numeric matrix)이어야 합니다." #~ msgid "chm_factor_name(): did not get string of length 11" #~ msgstr "chm_factor_name(): 길이가 11인 문자열을 가지지 못했습니다" #~ msgid "" #~ "Cholesky factorization failed; unusually, please report to Matrix-authors" #~ msgstr "" #~ "콜레스키 분해에 실패했습니다. Matrix 패키지의 저자에게 보고해 주시길 부탁" #~ "드립니다 " #~ msgid "internal_chm_factor: Cholesky factorization failed" #~ msgstr "internal_chm_factor: 콜레스키 분해에 실패했습니다" #~ msgid "Non-symmetric matrix passed to dsCMatrix_to_dgTMatrix" #~ msgstr "dsCMatrix_to_dgTMatrix에 비대칭 행렬이 전달되었습니다" #~ msgid "Incorrect length of 'x' slot" #~ msgstr "'x' 슬롯의 길이가 올바르지 않습니다." #, c-format #~ msgid "Lapack routine dsytrf returned error code %d" #~ msgstr "Lapack 루틴 dsytrl로부터 다음의 에러코드가 반환되었습니다: %d" #, fuzzy #~ msgid "x must be a \"double\" (numeric) matrix" #~ msgstr "X는 반드시 실수(real)형 숫자를 가진 행렬이어야 합니다." #, fuzzy #~ msgid "matrix_trf(x, *): matrix is not square" #~ msgstr "ddense_to_symmetric(): 정방행렬이 아닙니다!" #~ msgid "cannot set diag() as long as 'diag = \"U\"'" #~ msgstr "'diag = \"U\"'이기 때문에 diag()를 정할 수 없습니다." #~ msgid "cannot add diag() as long as 'diag = \"U\"'" #~ msgstr "'diag = \"U\"'이기 때문에 diag()를 추가할 수 없습니다." #~ msgid "A must be a logical matrix" #~ msgstr "A는 반드시 논리형 행렬(logical matrix)이어야 합니다." #~ msgid "length(p) must match nrow(V)" #~ msgstr "length(p)는 반드시 nrow(V)와 일치해야 합니다." #~ msgid "length(beta) must match ncol(V)" #~ msgstr "length(beta)는 반드시 ncol(V)와 일치해야 합니다." #~ msgid "length(q) must be zero or ncol(R)" #~ msgstr "length(q)는 반드시 0 또는 ncol(R)이어야 합니다." #, c-format #~ msgid "sparseQR_Qmult(): nrow(y) = %d != %d = nrow(V)" #~ msgstr "sparseQR_Qmult(): nrow(y) = %d != %d = nrow(V)" #~ msgid "\"dtrMatrix\" objects in '%*%' must have matching (square) dimension" #~ msgstr "" #~ "\"dtrMatrix\" objects in '%*%' must have matching (square) dimension" #~ msgid "not a CsparseMatrix" #~ msgstr "CsparseMatrix가 아닙니다." Matrix/po/R-pl.po0000644000176200001440000022011414521047060013305 0ustar liggesusersmsgid "" msgstr "" "Project-Id-Version: Matrix 1.1-2-2\n" "Report-Msgid-Bugs-To: bugs.r-project.org\n" "POT-Creation-Date: 2023-11-02 21:33\n" "PO-Revision-Date: 2014-03-27 14:47+0100\n" "Last-Translator: Łukasz Daniel \n" "Language-Team: Łukasz Daniel \n" "Language: pl_PL\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2);\n" "X-Poedit-SourceCharset: iso-8859-1\n" "X-Generator: Poedit 1.5.4\n" # Matrix/R/Auxiliaries.R: 23 # stop(gettextf("invalid 'mod': %s", mod), domain = "R-Matrix") # Matrix/R/Auxiliaries.R: 26 # stop(gettextf("invalid 'mod': %s", mod), domain = "R-Matrix") #, fuzzy msgid "invalid mode \"%s\"" msgstr "niepoprawne 'mod': %s" msgid "" "%s(<%s>, <%s>) is not yet implemented; ask maintainer(\"%s\") to implement " "the missing method" msgstr "" # Matrix/R/sparseVector.R: 278 # stop(gettextf("Class %s is not yet implemented", dQuote(cNam)), domain = "R-Matrix") #, fuzzy msgid "complex %s not yet implemented" msgstr "Klasa %s nie jest jeszcze zaimplementowana" # Matrix/R/ngTMatrix.R: 24 # stop("cannot coerce 'NA's to \"nsparseMatrix\"") #, fuzzy msgid "cannot coerce matrix of type \"%s\" to %s" msgstr "nie można przekształcić wartości 'NA' na 'nsparseMatrix'" # Matrix/R/Auxiliaries.R: 641 # stop(gettextf("not yet implemented for class %s", dQuote(class.x)), domain = "R-Matrix") #, fuzzy msgid "non0.i() not yet implemented for class %s" msgstr "jeszcze niezaimplementowane dla klasy %s" msgid "%s=\"%s\" invalid for %s@uplo=\"%s\"" msgstr "" msgid "'%s' is not \"%1$s\", \"D%1$s\", or \"%1$s.\"" msgstr "" msgid "unexpected %s=\"%s\" in '%s' method" msgstr "" # Matrix/R/HBMM.R: 13 # stop("Not a valid format") msgid "Not a valid format" msgstr "Niepoprawny format" # Matrix/R/HBMM.R: 33 # stop("'file' must be a character string or connection") # Matrix/R/HBMM.R: 82 # stop("'file' must be a character string or connection") msgid "'file' must be a character string or connection" msgstr "'file' musi być łańcuchem tekstowym lub połączeniem" # Matrix/R/HBMM.R: 47 # stop(gettextf("Invalid storage type: %s", t1), domain = "R-Matrix") msgid "Invalid storage type: %s" msgstr "Niepoprawny typ przechowywania: %s" # Matrix/R/HBMM.R: 48 # stop("Only numeric sparse matrices allowed") msgid "Only numeric sparse matrices allowed" msgstr "Dozwolone są jedynie liczbowe rzadkie macierze" # Matrix/R/HBMM.R: 51 # stop(gettextf("Invalid storage format: %s", t2), domain = NA) msgid "Invalid storage format: %s" msgstr "Niepoprawny format przechowywania: %s" # Matrix/R/HBMM.R: 53 # stop(gettextf("Invalid assembled indicator: %s", t3), domain = "R-Matrix") msgid "Invalid assembled indicator: %s" msgstr "Niepoprawnie złożony wskaźnik: %s" # Matrix/R/HBMM.R: 91 # stop("file is not a MatrixMarket file") msgid "file is not a MatrixMarket file" msgstr "plik nie jest plikiem typu 'MatrixMarket'" # Matrix/R/HBMM.R: 93 # stop(gettextf("type '%s' not recognized", typ), domain = "R-Matrix") msgid "type '%s' not recognized" msgstr "typ '%s' nie został rozpoznany" # Matrix/R/HBMM.R: 95 # stop(gettextf("representation '%s' not recognized", repr), domain = "R-Matrix") msgid "representation '%s' not recognized" msgstr "reprezentacja '%s' nie została rozpoznana" # Matrix/R/HBMM.R: 98 # stop(gettextf("element type '%s' not recognized", elt), domain = "R-Matrix") msgid "element type '%s' not recognized" msgstr "element typu '%s' nie został rozpoznany" # Matrix/R/HBMM.R: 102 # stop(gettextf("symmetry form '%s' not recognized", sym), domain = "R-Matrix") msgid "symmetry form '%s' not recognized" msgstr "forma symetryczna '%s' nie została rozpoznana" msgid "readMM(): expected %d entries but found only %d" msgstr "" #, fuzzy msgid "readMM(): row indices 'i' are not in 1:nrow[=%d]" msgstr "readMM(): wartości wiersza 'i' nie są w przedziale 1:nr" # Matrix/R/HBMM.R: 110 # stop("readMM(): column values 'j' are not in 1:nc", call.=FALSE) #, fuzzy msgid "readMM(): column indices 'j' are not in 1:ncol[=%d]" msgstr "readMM(): wartości kolumny 'j' nie są w przedziale 1:nc" # Matrix/R/HBMM.R: 131 # stop("symmetry form 'skew-symmetric' not yet implemented for reading") # Matrix/R/HBMM.R: 158 # stop("symmetry form 'skew-symmetric' not yet implemented for reading") msgid "symmetry form 'skew-symmetric' not yet implemented for reading" msgstr "" "forma symetryczna 'skew-symmetric' nie jest jeszcze zaimplementowana na " "potrzeby odczytu" # Matrix/R/HBMM.R: 138 # stop("symmetry form 'hermitian' not yet implemented for reading") # Matrix/R/HBMM.R: 165 # stop("symmetry form 'hermitian' not yet implemented for reading") msgid "symmetry form 'hermitian' not yet implemented for reading" msgstr "" "forma symetryczna 'hermitian' nie jest jeszcze zaimplementowana na potrzeby " "odczytu" # Matrix/R/HBMM.R: 141 # stop(gettextf("symmetry form '%s' is not yet implemented", sym), domain = "R-Matrix") # Matrix/R/HBMM.R: 168 # stop(gettextf("symmetry form '%s' is not yet implemented", sym), domain = "R-Matrix") msgid "symmetry form '%s' is not yet implemented" msgstr "forma symetryczna '%s' nie jest jeszcze zaimplementowana" # Matrix/R/HBMM.R: 172 # stop("element type 'complex' not yet implemented") msgid "element type 'complex' not yet implemented" msgstr "typ elementu 'complex' nie jest jeszcze zaimplementowany" # Matrix/R/HBMM.R: 175 # stop(sprintf(gettext("'%s()' is not yet implemented for element type '%s'", domain = "R-Matrix"), "readMM", elt), domain = NA) msgid "'%s()' is not yet implemented for element type '%s'" msgstr "'%s()' nie jest jeszcze zaimplementowany dla typu '%s' elementu" # Matrix/R/HBMM.R: 178 # stop(sprintf(gettext("'%s()' is not yet implemented for representation '%s'", domain = "R-Matrix"), "readMM", repr), domain = NA) msgid "'%s()' is not yet implemented for representation '%s'" msgstr "'%s()' nie jest jeszcze zaimplementowane dla reprezentacji '%s'" msgid "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%3$s\", or \"%4$s\"" msgstr "" msgid "" "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%2$s2\", \"%2$s2.\", \"%3$s\", or " "\"%4$s\"" msgstr "" # Matrix/R/Ops.R: 1117 # warning("longer object length\n\tis not a multiple of shorter object length") # Matrix/R/Ops.R: 1512 # warning("longer object length\n\tis not a multiple of shorter object length") # Matrix/R/Ops.R: 1604 # warning("longer object length\n\tis not a multiple of shorter object length") # Matrix/R/Ops.R: 1630 # warning("longer object length\n\tis not a multiple of shorter object length") msgid "longer object length is not a multiple of shorter object length" msgstr "" "długość dłuższego obiektu nie jest wielokrotnością długości krótszego obiektu" # Matrix/R/sparseMatrix.R: 372 # stop(gettextf("invalid 'col.names' string: %s", cn), domain = "R-Matrix") #, fuzzy msgid "invalid class \"%s\" in '%s' method" msgstr "niepoprawny łańcuch 'col.names': %s" msgid "invalid type \"%s\" in '%s' method" msgstr "" # Matrix/R/Auxiliaries.R: 273 # stop(gettextf("non-conformable matrix dimensions in %s", deparse(sys.call(sys.parent()))), call. = FALSE, domain = "R-Matrix") msgid "non-conformable matrix dimensions in %s" msgstr "niezgodne wymiary macierzy w %s" # Matrix/R/Auxiliaries.R: 292 # warning(gettextf("dimnames [%d] mismatch in %s", j, deparse(sys.call(sys.parent()))), call. = FALSE, domain = "R-Matrix") msgid "dimnames [%d] mismatch in %s" msgstr "niezgodność nazw wymiarów [%d] w %s" # Matrix/R/Ops.R: 35 # warning("inefficient method used for \"- e1\"") msgid "inefficient method used for \"- e1\"" msgstr "nieefektywna metoda użyta dla '- e1'" # Matrix/R/Ops.R: 1595 # stop(sprintf( # "dim [product %d] do not match the length of object [%d]", # n1, n2)) # Matrix/R/Ops.R: 1621 # stop(sprintf( # "dim [product %d] do not match the length of object [%d]", # n2, n1)) msgid "dim [product %d] do not match the length of object [%d]" msgstr "wymiar [produkt %d] nie zgadza się z długością obiektu [%d]" # Matrix/R/Ops.R: 174 # stop("internal bug in \"Compare\" method (Cmp.Mat.atomic); please report") msgid "internal bug in \"Compare\" method (Cmp.Mat.atomic); please report" msgstr "" "błąd wewnętrzny w metodzie 'Compare' (Cmp.Mat.atomic); proszę zgłosić raport" # Matrix/R/Ops.R: 183 # stop("Cmp.Mat.atomic() should not be called for diagonalMatrix") msgid "Cmp.Mat.atomic() should not be called for diagonalMatrix" msgstr "'Cmp.Mat.atomic()' nie powinien być wywołany dla 'diagonalMatrix'" # Matrix/R/Ops.R: 422 # stop("Matrices must have same number of rows for arithmetic") msgid "Matrices must have same number of rows for arithmetic" msgstr "" "Macierze muszą mieć tę samą liczbę wierszy jeśli mają być przeprowadzane " "działania arytmetyczne" # Matrix/R/Ops.R: 438 # stop(gettextf("number of rows are not compatible for %s", .Generic), domain = "R-Matrix") msgid "number of rows are not compatible for %s" msgstr "liczba wierszy nie jest zgodna dla %s" # Matrix/R/Ops.R: 449 # stop ("length of 2nd arg does not match dimension of first") # Matrix/R/Ops.R: 503 # stop ("length of 2nd arg does not match dimension of first") msgid "length of 2nd arg does not match dimension of first" msgstr "długość drugiego argumentu nie zgadza się z wymiarem pierwszego" # Matrix/R/Ops.R: 461 # stop ("length of 1st arg does not match dimension of 2nd") # Matrix/R/Ops.R: 534 # stop ("length of 1st arg does not match dimension of 2nd") msgid "length of 1st arg does not match dimension of 2nd" msgstr "długość pierwszego argumentu nie zgadza się z wymiarem drugiego" # Matrix/R/Ops.R: 674 # stop("internal bug in \"Logic\" method (Logic.Mat.atomic); please report") msgid "internal bug in \"Logic\" method (Logic.Mat.atomic); please report" msgstr "" "błąd wewnętrzny w metodzie 'Logic' (.Logic.Mat.atomic); proszę zgłosić raport" # Matrix/R/Ops.R: 683 # stop("Logic.Mat.atomic() should not be called for diagonalMatrix") msgid "Logic.Mat.atomic() should not be called for diagonalMatrix" msgstr "'Logic.Mat.atomic()' nie powinien być wywołany dla 'diagonalMatrix'" # Matrix/R/Ops.R: 1115 # stop("vector too long in Matrix - vector operation") msgid "vector too long in Matrix - vector operation" msgstr "wektor jest zbyt długi w operacji macierz-wektor" # Matrix/R/Ops.R: 1117 # warning("longer object length\n\tis not a multiple of shorter object length") # Matrix/R/Ops.R: 1512 # warning("longer object length\n\tis not a multiple of shorter object length") # Matrix/R/Ops.R: 1604 # warning("longer object length\n\tis not a multiple of shorter object length") # Matrix/R/Ops.R: 1630 # warning("longer object length\n\tis not a multiple of shorter object length") msgid "" "longer object length\n" "\tis not a multiple of shorter object length" msgstr "" "długość dłuższego obiektu\n" "\tnie jest wielokrotnością długości krótszego obiektu" # Matrix/R/diagMatrix.R: 779 # stop(gettextf("intermediate 'r' is of type %s", typeof(r)), domain = "R-Matrix") msgid "intermediate 'r' is of type %s" msgstr "pośrednie 'r' jest typu %s" # Matrix/R/diagMatrix.R: 796 # stop("not yet implemented .. please report") msgid "not yet implemented .. please report" msgstr "jeszcze niezaimplementowane .. proszę zgłosić raport" # Matrix/R/abIndex.R: 13 # stop("'force' must be (coercable to) TRUE or FALSE") msgid "'force' must be (coercable to) TRUE or FALSE" msgstr "'force' musi być (przekształcalne do) TRUE lub FALSE" # Matrix/R/abIndex.R: 162 # stop("invalid (to - from)/by in 'seq(.)'") msgid "invalid (to - from)/by in seq(.)" msgstr "niepoprawne '(to - from)/by' w 'seq(.)'" # Matrix/R/abIndex.R: 165 # stop("wrong sign in 'by' argument") msgid "wrong sign in 'by' argument" msgstr "niepoprawny znak w argumencie 'by'" # Matrix/R/abIndex.R: 167 # stop("'by' argument is much too small") msgid "'by' argument is much too small" msgstr "argument 'by' jest znacznie za mały" # Matrix/R/abIndex.R: 177 # stop("length must be non-negative number") msgid "length must be non-negative number" msgstr "długość musi być nieujemną liczbą" # Matrix/R/abIndex.R: 198 # stop("too many arguments") msgid "too many arguments" msgstr "zbyt wiele argumentów" # Matrix/R/abIndex.R: 286 # warning("c(,..) of different kinds, coercing all to 'rleDiff'") msgid "c(,..) of different kinds, coercing all to 'rleDiff'" msgstr "" "'c(,..)' różnych rodzajów, przekształcanie wszystkich do 'rleDiff'" # Matrix/R/abIndex.R: 345 # stop("[i] is not yet implemented") msgid "[i] is not yet implemented" msgstr "'[i]' nie jest jeszcze zaimplementowane" # Matrix/R/abIndex.R: 423 # stop("all() is not yet implemented") msgid "all() is not yet implemented" msgstr "'all()' nie jest jeszcze zaimplementowane" # Matrix/R/abIndex.R: 429 # stop("sum() is not yet implemented") msgid "sum() is not yet implemented" msgstr "'sum()' nie jest jeszcze zaimplementowane" # Matrix/R/abIndex.R: 432 # stop("prod() is not yet implemented") msgid "prod() is not yet implemented" msgstr "'prod()' nie jest jeszcze zaimplementowane" # Matrix/R/abIndex.R: 460 # stop("not yet implemented") # Matrix/R/sparseMatrix.R: 676 # stop("not yet implemented") msgid "not yet implemented" msgstr "jeszcze niezaimplementowane" # Matrix/R/abIndex.R: 518 # warning("x / 0 for an x with sign-change\nno longer representable as 'rleDiff'") msgid "" "x / 0 for an x with sign-change\n" " no longer representable as 'rleDiff'" msgstr "" "x / 0 dla ' x' ze zmianą znaku nie jest dłużej reprezentowalne jako " "'rleDiff'" # Matrix/R/abIndex.R: 693 # stop(" --> is not yet implemented") msgid " --> is not yet implemented" msgstr " --> nie jest jeszcze zaimplementowane" # Matrix/R/abIndex.R: 698 # stop(" --> is not yet implemented") msgid " --> is not yet implemented" msgstr " --> nie jest jeszcze zaimplementowane" # Matrix/R/diagMatrix.R: 528 # stop("chol() is undefined for diagonal matrix with negative entries") #, fuzzy msgid "%1$s(%2$s) is undefined: '%2$s' is not positive semidefinite" msgstr "" "'chol()' jest nieokreślona dla macierzy diagonalnych z ujemnymi wpisami" # Matrix/R/diagMatrix.R: 358 # stop("matrix is not diagonal") #, fuzzy msgid "matrix is not square" msgstr "macierz nie jest diagonalna" msgid "" "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%3$s\", \"%3$s.\", \"%3$s1\", \"%3$s1." "\", or \"%4$s\"" msgstr "" # Matrix/R/sparseVector.R: 235 # stop("'x' must inherit from \"sparseVector\"") #, fuzzy msgid "'%s' does not inherit from virtual class %s" msgstr "argument 'x' musi być obiektem klasy \"sparseVector\"" msgid "D[i,i] is NA, i=%d" msgstr "" msgid "D[i,i] is negative, i=%d" msgstr "" msgid "'%1$s' is not formally symmetric; factorizing tcrossprod(%1$s)" msgstr "" # Matrix/R/ndenseMatrix.R: 77 # stop("not a symmetric matrix; consider forceSymmetric() or symmpart()") # Matrix/R/dgTMatrix.R: 37 # stop("not a symmetric matrix; consider forceSymmetric() or symmpart()") # Matrix/R/ldenseMatrix.R: 65 # stop("not a symmetric matrix; consider forceSymmetric() or symmpart()") # Matrix/R/Csparse.R: 76 # stop("not a symmetric matrix; consider forceSymmetric() or symmpart()") # Matrix/R/dsyMatrix.R: 8 # stop("not a symmetric matrix; consider forceSymmetric() or symmpart()") #, fuzzy msgid "matrix is not symmetric; consider forceSymmetric(.) or symmpart(.)" msgstr "" "to nie jest macierz symetryczna; rozważ 'forceSymmetric()' lub 'symmpart()'" # Matrix/R/dgTMatrix.R: 44 # stop("the matrix is not triangular") #, fuzzy msgid "matrix is not triangular; consider triu(.) or tril(.)" msgstr "macierz nie jest trójkątna" msgid "matrix is not diagonal; consider Diagonal(x=diag(.))" msgstr "" # Matrix/R/sparseMatrix.R: 731 # stop("invalid 'type'") #, fuzzy msgid "invalid type \"%s\" in '%s'" msgstr "niepoprawny 'type'" # Matrix/R/HBMM.R: 47 # stop(gettextf("Invalid storage type: %s", t1), domain = "R-Matrix") #, fuzzy msgid "invalid %s=\"%s\" to '%s'" msgstr "Niepoprawny typ przechowywania: %s" msgid "dimensions cannot exceed %s" msgstr "" # Matrix/R/sparseMatrix.R: 372 # stop(gettextf("invalid 'col.names' string: %s", cn), domain = "R-Matrix") #, fuzzy msgid "invalid class \"%s\" in '%s'" msgstr "niepoprawny łańcuch 'col.names': %s" msgid "%s length cannot exceed %s" msgstr "" # Matrix/R/condest.R: 74 # stop("'A' must be a square matrix") # Matrix/R/condest.R: 194 # stop("'A' must be a square matrix") msgid "'A' must be a square matrix" msgstr "'A' musi być macierzą kwadratową" # Matrix/R/condest.R: 186 # stop("must either specify 'A' or the functions 'A.x' and 'At.x'") msgid "must either specify 'A' or the functions 'A.x' and 'At.x'" msgstr "potrzeba określić 'A' lub funkcje 'A.x' oraz 'At.x'" # Matrix/R/condest.R: 188 # warning("when 'A' is specified, 'A.x' and 'At.x' are disregarded") msgid "when 'A' is specified, 'A.x' and 'At.x' are disregarded" msgstr "gdy 'A' jest określone, 'A.x' oraz 'At.x' są odrzucane" # Matrix/R/condest.R: 234 # warning(gettextf("not converged in %d iterations", iter.max), domain = "R-Matrix") msgid "not converged in %d iterations" msgstr "nie uzbieżnił się w %d iteracjach" # Matrix/R/condest.R: 249 # message("hit a cycle (1) -- stop iterations") msgid "hit a cycle (1) -- stop iterations" msgstr "natrafiona na cykl (1) -- zatrzymywanie iteracji" # Matrix/R/condest.R: 283 # message("hit a cycle (2) -- stop iterations") msgid "hit a cycle (2) -- stop iterations" msgstr "natrafiona na cykl (2) -- zatrzymywanie iteracji" # Matrix/R/condest.R: 300 # message("not enough new vecs -- stop iterations") msgid "not enough new vecs -- stop iterations" msgstr "zbyt mało nowych wektorów -- zatrzymywanie iteracji" # Matrix/R/Matrix.R: 206 # stop("invalid 'data'") msgid "invalid 'data'" msgstr "niepoprawne 'data'" # Matrix/R/Matrix.R: 224 # warning("'nrow', 'ncol', etc, are disregarded for matrix 'data'") #, fuzzy msgid "'nrow', 'ncol', 'byrow' disregarded for [mM]atrix 'data'" msgstr "'nrow', 'ncol', itd., są nieuwzględniane dla 'data' typu macierzowego" msgid "data is too long" msgstr "" # Matrix/R/sparseMatrix.R: 44 # stop("exactly one of 'i', 'j', or 'p' must be missing from call") #, fuzzy msgid "exactly one of 'i', 'j', and 'p' must be missing from call" msgstr "dokłanie jeden z 'i', 'j', lub 'p' musi być nieobecny w wywołaniu" msgid "" "use Diagonal() to construct diagonal (symmetric && triangular) sparse " "matrices" msgstr "" msgid "'giveCsparse' is deprecated; using 'repr' instead" msgstr "" msgid "'giveCsparse' is deprecated; setting repr=\"T\" for you" msgstr "" # Matrix/R/sparseMatrix.R: 48 # stop("'p' must be a non-decreasing vector (0, ...)") #, fuzzy msgid "'p' must be a nondecreasing vector c(0, ...)" msgstr "'p' musi być niemalejącym wektorem (0, ...)" msgid "dimensions cannot exceed 2^31-1" msgstr "" msgid "'i' and 'j' must not contain NA" msgstr "" msgid "'i' and 'j' must be" msgstr "" msgid "positive" msgstr "" msgid "non-negative" msgstr "" # Matrix/R/Matrix.R: 206 # stop("invalid 'data'") #, fuzzy msgid "invalid 'dims'" msgstr "niepoprawne 'data'" msgid "'dims' must contain all (i,j) pairs" msgstr "" # Matrix/R/sparseMatrix.R: 67 # stop("symmetric matrix must be square") msgid "symmetric matrix must be square" msgstr "macierz symetryczna musi być kwadratowa" # Matrix/R/sparseMatrix.R: 67 # stop("symmetric matrix must be square") #, fuzzy msgid "triangular matrix must be square" msgstr "macierz symetryczna musi być kwadratowa" msgid "p[length(p)]" msgstr "" msgid "length(i)" msgstr "" # Matrix/R/sparseMatrix.R: 79 # warning("length(i) is not a multiple of length(x)") #, fuzzy msgid "is not an integer multiple of length(x)" msgstr "'length(i)' nie jest wielokrotnością 'length(x)'" msgid "length(x) must not exceed" msgstr "" msgid "invalid 'repr'; must be \"C\", \"R\", or \"T\"" msgstr "" # Matrix/R/abIndex.R: 177 # stop("length must be non-negative number") #, fuzzy msgid "'n' must be a non-negative integer" msgstr "długość musi być nieujemną liczbą" msgid "'x' has unsupported class \"%s\"" msgstr "" msgid "'x' has unsupported type \"%s\"" msgstr "" msgid "attempt to recycle 'x' of length 0 to length 'n' (n > 0)" msgstr "" msgid "'shape' must be one of \"g\", \"t\", \"s\"" msgstr "" msgid "'kind' must be one of \"d\", \"l\", \"n\"" msgstr "" msgid "mismatch between typeof(x)=\"%s\" and kind=\"%s\"; using kind=\"%s\"" msgstr "" # Matrix/R/sparseVector.R: 237 # stop("'ncol' must be >= 0") #, fuzzy msgid "'cols' must be numeric" msgstr "'ncol' musi być >= 0" msgid "'cols' has elements not in seq(0, length.out = n)" msgstr "" msgid "'uplo' must be \"U\" or \"L\"" msgstr "" # Matrix/R/sparseVector.R: 237 # stop("'ncol' must be >= 0") #, fuzzy msgid "'lst' must be a list" msgstr "'ncol' musi być >= 0" msgid "'giveCsparse' has been deprecated; setting 'repr = \"T\"' for you" msgstr "" msgid "'giveCsparse' has been deprecated; will use 'repr' instead" msgstr "" # Matrix/R/bandSparse.R: 26 # stop(sprintf(ngettext(len.k, "'diagonals' matrix must have %d column (= length(k) )", "'diagonals' matrix must have %d columns (= length(k) )", domain = "R-Matrix"), len.k), domain = NA) msgid "'diagonals' matrix must have %d columns (= length(k) )" msgstr "macierz 'diagonals' musi mieć %d kolumnę (= length(k) )" # Matrix/R/bandSparse.R: 31 # stop(gettextf("'diagonals' must have the same length (%d) as 'k'", len.k), domain = "R-Matrix") msgid "'diagonals' must have the same length (%d) as 'k'" msgstr "'diagonals' musi mieć tę samą długość (%d) co 'k'" msgid "matrix can only be symmetric if square, but n != m" msgstr "" # Matrix/R/bandSparse.R: 36 # stop("for symmetric band matrix, only specify upper or lower triangle\n hence, all k must have the same sign") msgid "" "for symmetric band matrix, only specify upper or lower triangle\n" " hence, all k must have the same sign" msgstr "" "dla symetrycznej macierzy wstęgowej, określ jedynie górny oraz dolny " "trójkąt\n" "tak więc, wszystkie k muszą mieć ten sam znak" # Matrix/R/bandSparse.R: 64 # warning(gettextf("the %d-th (sub)-diagonal (k = %d) is too short; filling with NA's", s, kk), domain = "R-Matrix") msgid "the %d-th (sub)-diagonal (k = %d) is too short; filling with NA's" msgstr "" "(pod)-diagonala %d (k = %d) jest zbyt krótkal wypełnianie wartościami NA" msgid "invalid 'repr'; must be \"C\", \"T\", or \"R\"" msgstr "" # Matrix/R/sparseVector.R: 235 # stop("'x' must inherit from \"sparseVector\"") msgid "'x' must inherit from \"sparseVector\"" msgstr "argument 'x' musi być obiektem klasy \"sparseVector\"" # Matrix/R/sparseVector.R: 237 # stop("'ncol' must be >= 0") msgid "'ncol' must be >= 0" msgstr "'ncol' musi być >= 0" # Matrix/R/sparseVector.R: 239 # stop("'nrow' must be >= 0") msgid "'nrow' must be >= 0" msgstr "'nrow' musi być >= 0" # Matrix/R/sparseVector.R: 242 # stop("Must specify 'nrow' when 'symmetric' is true") msgid "Must specify 'nrow' when 'symmetric' is true" msgstr "'nrow' musi być określone, gdy 'symmetric' ma wartość TRUE" # Matrix/R/sparseVector.R: 244 # stop("'nrow' and 'ncol' must be the same when 'symmetric' is true") msgid "'nrow' and 'ncol' must be the same when 'symmetric' is true" msgstr "" "'nrow' oraz 'ncol' muszą mieć tę samą wartość gdy 'symmetric' ma wartość TRUE" # Matrix/R/sparseVector.R: 247 # stop("'x' must have length nrow^2 when 'symmetric' is true") msgid "'x' must have length nrow^2 when 'symmetric' is true" msgstr "'x' musi mieć długość równą 'nrow'^2 gdy 'symmetric' ma wartość TRUE" # Matrix/R/sparseVector.R: 255 # warning("'ncol' is not a factor of length(x)") msgid "'ncol' is not a factor of length(x)" msgstr "'ncol' nie jest czynnikiem długości 'length(x)'" # Matrix/R/sparseVector.R: 260 # warning("'nrow' is not a factor of length(x)") msgid "'nrow' is not a factor of length(x)" msgstr "'nrow' nie jest czynnikiem długości 'length(x)'" # Matrix/R/sparseVector.R: 278 # stop(gettextf("Class %s is not yet implemented", dQuote(cNam)), domain = "R-Matrix") msgid "Class %s is not yet implemented" msgstr "Klasa %s nie jest jeszcze zaimplementowana" # Matrix/R/abIndex.R: 177 # stop("length must be non-negative number") #, fuzzy msgid "'%s' and '%s' must be positive integers" msgstr "długość musi być nieujemną liczbą" # Matrix/R/symmetricMatrix.R: 114 # stop("'x' is not symmetric nor triangular") #, fuzzy msgid "matrix is not symmetric or triangular" msgstr "'x' nie jest macierzą symetryczną ani trójkątną" # Matrix/R/dgTMatrix.R: 44 # stop("the matrix is not triangular") #, fuzzy msgid "matrix is not symmetric" msgstr "macierz nie jest trójkątna" # Matrix/R/symmetricMatrix.R: 114 # stop("'x' is not symmetric nor triangular") #, fuzzy msgid "matrix is not triangular" msgstr "'x' nie jest macierzą symetryczną ani trójkątną" msgid "" "the default value of argument '%s' of method '%s(<%s>, <%s>)' may change " "from %s to %s as soon as the next release of Matrix; set '%s' when " "programming" msgstr "" msgid "determinant of non-square matrix is undefined" msgstr "" msgid "replacement diagonal has wrong length" msgstr "" msgid "replacement diagonal has incompatible type \"%s\"" msgstr "" msgid "assigned dimensions are not of type \"%s\" or \"%s\"" msgstr "" msgid "assigned dimensions do not have length %d" msgstr "" msgid "assigned dimensions are NA" msgstr "" msgid "assigned dimensions are negative" msgstr "" msgid "assigned dimensions exceed %s" msgstr "" # Matrix/R/Ops.R: 1595 # stop(sprintf( # "dim [product %d] do not match the length of object [%d]", # n1, n2)) # Matrix/R/Ops.R: 1621 # stop(sprintf( # "dim [product %d] do not match the length of object [%d]", # n2, n1)) #, fuzzy msgid "assigned dimensions [product %.0f] do not match object length [%.0f]" msgstr "wymiar [produkt %d] nie zgadza się z długością obiektu [%d]" msgid "'%s' has non-finite values" msgstr "" msgid "'%1$s' is not \"%2$s\", \"%3$s\", or \"%2$s.\"" msgstr "" # Matrix/R/sparseMatrix.R: 198 # stop("only square matrices can be used as incidence matrices for graphs") #, fuzzy msgid "only square matrices can be used as graph incidence matrices" msgstr "" "jedynie kwadratowe macierze mogą zostać użyte jako macierz incydencji dla " "grafów" # Matrix/R/dgTMatrix.R: 106 # stop("'lwd' must be NULL or non-negative numeric") msgid "'lwd' must be NULL or non-negative numeric" msgstr "'lwd' musi mieć wartość NULL lub być nieujemną liczbą" # Matrix/R/sparseVector.R: 278 # stop(gettextf("Class %s is not yet implemented", dQuote(cNam)), domain = "R-Matrix") #, fuzzy msgid "%s(<%s>) is not yet implemented" msgstr "Klasa %s nie jest jeszcze zaimplementowana" msgid "'%s' is not of type \"%s\" or \"%s\"" msgstr "" msgid "'%s' contains NA" msgstr "" msgid "'%s' has elements less than %d" msgstr "" # Matrix/R/abIndex.R: 177 # stop("length must be non-negative number") #, fuzzy msgid "'%s' is not a non-negative number" msgstr "długość musi być nieujemną liczbą" msgid "'%s' has elements exceeding '%s'" msgstr "" msgid "'%s' is not %d or %d" msgstr "" # Matrix/R/sparseVector.R: 255 # warning("'ncol' is not a factor of length(x)") #, fuzzy msgid "'%s' is not a permutation of seq_len(%s)" msgstr "'ncol' nie jest czynnikiem długości 'length(x)'" # Matrix/R/indMatrix.R: 71 # stop("must have exactly one non-zero entry per row") # Matrix/R/pMatrix.R: 33 # stop("must have exactly one non-zero entry per row") #, fuzzy msgid "matrix must have exactly one entry in each row or column" msgstr "potrzeba mieć dokładnie jeden niezerowy wpis na wiersz" # Matrix/R/dgTMatrix.R: 20 # stop("cannot coerce non-symmetric \"dgTMatrix\" to \"dsCMatrix\" class") #, fuzzy msgid "attempt to coerce non-square matrix to %s" msgstr "" "nie można przekształcić niesymetrycznej macierzy klasy \"dgTMatrix\" na " "klasę \"dsCMatrix\"" # Matrix/R/indMatrix.R: 71 # stop("must have exactly one non-zero entry per row") # Matrix/R/pMatrix.R: 33 # stop("must have exactly one non-zero entry per row") #, fuzzy msgid "matrix must have exactly one entry in each row and column" msgstr "potrzeba mieć dokładnie jeden niezerowy wpis na wiersz" # Matrix/R/sparseMatrix.R: 748 # warning("rcond(.) via sparse -> dense coercion") #, fuzzy msgid "'%s' via sparse -> dense coercion" msgstr "'rcond(.)' poprzez przekształcenie rzadkie -> gęste" # Matrix/R/denseMatrix.R: 101 # stop(gettextf("invalid nargs()= %d", na), domain = "R-Matrix") # Matrix/R/denseMatrix.R: 164 # stop(gettextf("invalid nargs()= %d", na), domain = "R-Matrix") #, fuzzy msgid "invalid %s=\"%s\"" msgstr "niepoprawne nargs()=%d" msgid "norm" msgstr "" # Matrix/R/indMatrix.R: 133 # stop("kronecker method must use default 'FUN'") # Matrix/R/kronecker.R: 33 # stop("kronecker method must use default 'FUN'") # Matrix/R/kronecker.R: 51 # stop("kronecker method must use default 'FUN'") #, fuzzy msgid "'%s' method must use default %s=\"%s\"" msgstr "metoda kroneckera musi użyć domyślnej 'FUN'" # Matrix/R/Ops.R: 438 # stop(gettextf("number of rows are not compatible for %s", .Generic), domain = "R-Matrix") #, fuzzy msgid "number of nonzero entries cannot exceed %s" msgstr "liczba wierszy nie jest zgodna dla %s" # Matrix/R/nearPD.R: 52 # stop("Matrix seems negative semi-definite") msgid "Matrix seems negative semi-definite" msgstr "Macierz wydaje się być ujemnie określona" # Matrix/R/nearPD.R: 79 # warning(gettextf("'nearPD()' did not converge in %d iterations", iter), domain = "R-Matrix") msgid "'nearPD()' did not converge in %d iterations" msgstr "funkcja 'nearPD()' nie uzbieżniła się w %d iteracjach" # Matrix/R/sparseMatrix.R: 759 # stop("'V' is not a *square* matrix") #, fuzzy msgid "'cl' is not a character string" msgstr "'V' nie jest macierzą *kwadratową*" msgid "" "not a positive definite matrix (and positive semidefiniteness is not checked)" msgstr "" # Matrix/R/sparseMatrix.R: 759 # stop("'V' is not a *square* matrix") #, fuzzy msgid "'%s' is not a square numeric matrix" msgstr "'V' nie jest macierzą *kwadratową*" # Matrix/R/Matrix.R: 94 # warning("diag(.) had 0 or NA entries; non-finite result is doubtful") # Matrix/R/sparseMatrix.R: 764 # warning("diag(.) had 0 or NA entries; non-finite result is doubtful") #, fuzzy msgid "" "diag(%s) has non-positive or non-finite entries; finite result is doubtful" msgstr "'diag(.)' posiadało wpisy 0 lub NA; nieskończony wynik jest wątpliwy" # Matrix/R/Auxiliaries.R: 273 # stop(gettextf("non-conformable matrix dimensions in %s", deparse(sys.call(sys.parent()))), call. = FALSE, domain = "R-Matrix") #, fuzzy msgid "non-conformable arguments" msgstr "niezgodne wymiary macierzy w %s" msgid "" "matrix is structurally rank deficient; using augmented matrix with " "additional %d row(s) of zeros" msgstr "" msgid "" "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%2$s2\", \"%2$s2.\", \"%3$s\", " "\"%3$s1\", \"%4$s\", or \"%4$s1\"" msgstr "" msgid "'%s' has the wrong length" msgstr "" # Matrix/R/sparseMatrix.R: 372 # stop(gettextf("invalid 'col.names' string: %s", cn), domain = "R-Matrix") #, fuzzy msgid "invalid '%s': not in %d:%d" msgstr "niepoprawny łańcuch 'col.names': %s" msgid "need greater '%s' as pivoting occurred" msgstr "" msgid "qr2rankMatrix(.): QR with only %d out of %d finite diag(R) entries" msgstr "" msgid "" "rankMatrix(, method = '%s') coerces to dense matrix.\n" " Probably should rather use method = 'qr' !?" msgstr "" "rankMatrix(, method = '%s') przekształca macierz do " "gęstej macierzy.\n" " Prawdopodobnie należy użyć 'method = \"qr\"' !?" # Matrix/R/rankMatrix.R: 73 # warning(gettextf("rankMatrix(x, method='qrLINPACK'): computing t(x) as nrow(x) < ncol(x)")) msgid "rankMatrix(x, method='qr'): computing t(x) as nrow(x) < ncol(x)" msgstr "rankMatrix(x, method='qr'): obliczanie t(x) jako nrow(x) < ncol(x)" # Matrix/R/Auxiliaries.R: 373 # message(sprintf(gettext(" [[ suppressing %d column names %s... ]]", domain = "R-Matrix"), nc, paste(sQuote(cn[1:3]), collapse = ", ")), domain = NA) #, fuzzy msgid "[[ suppressing %d column name%s %s ... ]]" msgstr "[[ zmniejszanie %d nazw kolumn %s ... ]]" # Matrix/R/sparseMatrix.R: 372 # stop(gettextf("invalid 'col.names' string: %s", cn), domain = "R-Matrix") msgid "invalid 'col.names' string: %s" msgstr "niepoprawny łańcuch 'col.names': %s" msgid "uniDiag=TRUE, but not all diagonal entries are 1" msgstr "" msgid "uniDiag=TRUE, not all entries in diagonal coded as 1" msgstr "" msgid "in show(); maybe adjust options(max.print=, width=)" msgstr "" # Matrix/R/Auxiliaries.R: 375 # message(sprintf(gettext(" [[ suppressing %d column names %s ]]", domain = "R-Matrix"), nc, paste(sQuote(cn[1:lc]), collapse = ", ")), domain = NA) #, fuzzy msgid "suppressing %d columns and %d rows" msgstr "[[ zmniejszanie %d nazw kolumn %s ]]" # Matrix/R/Auxiliaries.R: 375 # message(sprintf(gettext(" [[ suppressing %d column names %s ]]", domain = "R-Matrix"), nc, paste(sQuote(cn[1:lc]), collapse = ", ")), domain = NA) #, fuzzy msgid "suppressing %d rows" msgstr "[[ zmniejszanie %d nazw kolumn %s ]]" # Matrix/R/Auxiliaries.R: 375 # message(sprintf(gettext(" [[ suppressing %d column names %s ]]", domain = "R-Matrix"), nc, paste(sQuote(cn[1:lc]), collapse = ", ")), domain = NA) #, fuzzy msgid "suppressing %d columns" msgstr "[[ zmniejszanie %d nazw kolumn %s ]]" # Matrix/R/sparseMatrix.R: 599 # stop("logic programming error in printSpMatrix2(), please report") msgid "logic programming error in printSpMatrix2(), please report" msgstr "błąd logiczny programu w 'printSpMatrix2()', proszę zgłosić raport" # Matrix/R/Matrix.R: 91 # stop("'V' is not a square matrix") #, fuzzy msgid "'%s' is not square" msgstr "'V' nie jest macierzą kwadratową" msgid "dimensions of '%s' and '%s' are inconsistent" msgstr "" msgid "'%1$s' is computationally singular, rcond(%1$s)=%2$g" msgstr "" msgid "'%s' is computationally singular, min(d)/max(d)=%g, d=abs(diag(U))" msgstr "" msgid "matrix is exactly singular, D[i,i]=0, i=%d" msgstr "" msgid "matrix is exactly singular, J[,j]=0, j=%d" msgstr "" msgid "matrix exactly singular, J[i,]=0, i=%d" msgstr "" msgid "cannot coerce from %s to %s" msgstr "" # Matrix/R/spModels.R: 113 # stop("model frame and formula mismatch in model.matrix()") #, fuzzy msgid "model frame and formula mismatch in sparse.model.matrix()" msgstr "niezgodność ramki modelu oraz formuły w 'model.matrix()'" # Matrix/R/spModels.R: 137 # stop("invalid 'contrasts.arg' argument") #, fuzzy msgid "non-list contrasts argument ignored" msgstr "niepoprawny argument 'contrasts.arg'" # Matrix/R/spModels.R: 137 # stop("invalid 'contrasts.arg' argument") #, fuzzy msgid "'contrasts.arg' argument must be named" msgstr "niepoprawny argument 'contrasts.arg'" # Matrix/R/spModels.R: 140 # warning(gettextf("variable '%s' is absent, its contrast will be ignored", nn), domain = "R-Matrix") msgid "variable '%s' is absent, its contrast will be ignored" msgstr "zmienna '%s' jest nieobecna, jej kontrast zostanie zignorowany" msgid "a sparseMatrix should rarely be centered: will not be sparse anymore" msgstr "" # Matrix/R/bind2.R: 395 # stop(gettextf("Matrices must have same number of columns in %s", deparse(sys.call(sys.parent()))), call. = FALSE, domain = "R-Matrix") # Matrix/R/Auxiliaries.R: 314 # stop(gettextf("Matrices must have same number of columns in %s", deparse(sys.call(sys.parent()))), call. = FALSE, domain = "R-Matrix") #, fuzzy msgid "length of 'center' must equal the number of columns of 'x'" msgstr "Macierze muszą mieć tę samą liczbę kolumn w %s" # Matrix/R/bind2.R: 395 # stop(gettextf("Matrices must have same number of columns in %s", deparse(sys.call(sys.parent()))), call. = FALSE, domain = "R-Matrix") # Matrix/R/Auxiliaries.R: 314 # stop(gettextf("Matrices must have same number of columns in %s", deparse(sys.call(sys.parent()))), call. = FALSE, domain = "R-Matrix") #, fuzzy msgid "length of 'scale' must equal the number of columns of 'x'" msgstr "Macierze muszą mieć tę samą liczbę kolumn w %s" msgid "trimmed means are not defined for complex data" msgstr "" msgid "first element used of '%s' argument" msgstr "" # Matrix/R/Matrix.R: 206 # stop("invalid 'data'") #, fuzzy msgid "invalid '%s' argument" msgstr "niepoprawne 'data'" msgid "should never happen ..." msgstr "" msgid "'%s' is deprecated; using '%s' instead" msgstr "" msgid "'%s' is deprecated; setting %s=\"%s\"" msgstr "" # Matrix/R/Matrix.R: 694 # stop(".M.repl.i.2col(): 'i' has no integer column number;\n should never happen; please report") msgid "" ".M.repl.i.2col(): 'i' has no integer column number;\n" " should never happen; please report" msgstr "" ".M.repl.i.2col(): 'i' posiada niecałkowitą liczbę kolumn;\n" "to nie powinno się nigdy wydarzyć; proszę zgłosić raport" # Matrix/R/Matrix.R: 667 # stop("such indexing must be by logical or 2-column numeric matrix") # Matrix/R/Matrix.R: 696 # stop("such indexing must be by logical or 2-column numeric matrix") # Matrix/R/Tsparse.R: 638 # stop("such indexing must be by logical or 2-column numeric matrix") msgid "such indexing must be by logical or 2-column numeric matrix" msgstr "" "takie indeksowanie musi być wykonane poprzez macierz logiczną lub 2-" "kolumnową macierz liczbową" # Matrix/R/Matrix.R: 698 # message(".M.repl.i.2col(): drop 'matrix' case ...") msgid ".M.repl.i.2col(): drop 'matrix' case ..." msgstr ".M.repl.i.2col(): zrzuć przypadek 'matrix' ..." # Matrix/R/Matrix.R: 704 # stop("negative values are not allowed in a matrix subscript") # Matrix/R/Tsparse.R: 641 # stop("negative values are not allowed in a matrix subscript") msgid "negative values are not allowed in a matrix subscript" msgstr "ujemne wartości nie są dozwolone w indeksach macierzy" # Matrix/R/Matrix.R: 706 # stop("NAs are not allowed in subscripted assignments") # Matrix/R/Tsparse.R: 643 # stop("NAs are not allowed in subscripted assignments") msgid "NAs are not allowed in subscripted assignments" msgstr "wartości NA nie są dozwolone w indeksowanych przypisaniach" # Matrix/R/Matrix.R: 713 # warning("number of items to replace is not a multiple of replacement length") # Matrix/R/Csparse.R: 245 # stop("number of items to replace is not a multiple of replacement length") # Matrix/R/Tsparse.R: 366 # warning("number of items to replace is not a multiple of replacement length") # Matrix/R/Tsparse.R: 405 # stop("number of items to replace is not a multiple of replacement length") # Matrix/R/Tsparse.R: 657 # warning("number of items to replace is not a multiple of replacement length") # Matrix/R/sparseVector.R: 530 # stop("number of items to replace is not a multiple of replacement length") msgid "number of items to replace is not a multiple of replacement length" msgstr "" "liczba pozycji do zastąpienia nie jest wielokrotnością długości elementu " "zastępującego" # Matrix/R/Matrix.R: 719 # message("m[ ] <- v: inefficiently treating single elements") msgid "m[ ] <- v: inefficiently treating single elements" msgstr "m[ ] <- v: nieefektywne traktowanie pojedynczych elementów" # Matrix/R/Matrix.R: 725 # stop(gettextf("nargs() = %d. Extraneous illegal arguments inside '[ .. ]' ?", nA), domain = "R-Matrix") msgid "nargs() = %d. Extraneous illegal arguments inside '[ .. ]' ?" msgstr "nargs() = %d. Obce nielegalne argumenty wewnątrz '[ .. ]' ?" # Matrix/R/Matrix.R: 796 # stop(gettextf("RHS 'value' (class %s) matches 'ANY', but must match matrix class %s", class(value), class(x)), domain = "R-Matrix") msgid "RHS 'value' (class %s) matches 'ANY', but must match matrix class %s" msgstr "" "prawa strona 'value' (klasa %s) pasuje do 'ANY', a musi pasować do klasy " "macierzy '%s'" # Matrix/R/Matrix.R: 797 # stop("not-yet-implemented 'Matrix[<-' method") msgid "not-yet-implemented 'Matrix[<-' method" msgstr "jeszcze niezaimplementowana metoda 'Matrix[<-'" # Matrix/R/denseMatrix.R: 101 # stop(gettextf("invalid nargs()= %d", na), domain = "R-Matrix") # Matrix/R/denseMatrix.R: 164 # stop(gettextf("invalid nargs()= %d", na), domain = "R-Matrix") msgid "invalid nargs()= %d" msgstr "niepoprawne nargs()=%d" # Matrix/R/Csparse.R: 240 # stop("nothing to replace with") # Matrix/R/Tsparse.R: 400 # stop("nothing to replace with") # Matrix/R/Tsparse.R: 653 # stop("nothing to replace with") # Matrix/R/sparseVector.R: 525 # stop("nothing to replace with") msgid "nothing to replace with" msgstr "nic do zastąpienia" # Matrix/R/Csparse.R: 247 # stop("too many replacement values") # Matrix/R/Tsparse.R: 495 # stop("too many replacement values") # Matrix/R/sparseVector.R: 557 # stop("too many replacement values") msgid "too many replacement values" msgstr "zbyt dużo wartości zamieniających" # Matrix/R/Csparse.R: 284 # warning("i1[1] == 0 ==> C-level verbosity will not happen!") msgid "i1[1] == 0 ==> C-level verbosity will not happen!" msgstr "i1[1] == 0 ==> tryb 'verbose' poziomu C nie zostanie wykonany!" msgid "using\t \"old code\" part in Csparse subassignment" msgstr "używanie\t części 'old code' w przypisaniu w 'Csparse'" msgid "" "using\"old code\" part in Csparse subassignment\n" " >>> please report to Matrix-authors@r-project.org" msgstr "" "używanie części 'old code' w przypisaniu w 'Csparse'\n" ">>> proszę zgłosić raport na adres 'Matrix-authors@r-project.org'" # Matrix/R/Tsparse.R: 126 # stop("you cannot mix negative and positive indices") # Matrix/R/sparseVector.R: 395 # stop("you cannot mix negative and positive indices") # Matrix/R/sparseVector.R: 462 # stop("you cannot mix negative and positive indices") msgid "you cannot mix negative and positive indices" msgstr "nie można mieszać ujemnych oraz dodatnich indeksów" # Matrix/R/Tsparse.R: 130 # stop(gettextf("index larger than maximal %d", n), domain = "R-Matrix") msgid "index larger than maximal %d" msgstr "indeks dłuższy niż maksymalny możliwy %d" # Matrix/R/Tsparse.R: 123 # stop("'NA' indices are not (yet?) supported for sparse Matrices") msgid "'NA' indices are not (yet?) supported for sparse Matrices" msgstr "indeksy 'NA' nie są (jeszcze?) wspierane dla rzadkich macierzy" # Matrix/R/Tsparse.R: 138 # stop(gettextf("logical subscript too long (%d, should be %d)", length(i), n), domain = "R-Matrix") msgid "logical subscript too long (%d, should be %d)" msgstr "indeks logiczny jest zbyt długi (%d, powinien być %d)" # Matrix/R/Tsparse.R: 143 # stop("no 'dimnames[[.]]': cannot use character indexing") msgid "no 'dimnames[[.]]': cannot use character indexing" msgstr "brak 'dimnames[[.]]': nie można używać indeksowania tekstowego" # Matrix/R/Tsparse.R: 145 # stop("invalid character indexing") msgid "invalid character indexing" msgstr "niepoprawne tekstowe indeksowanie" # Matrix/R/Tsparse.R: 309 # stop("internal bug: missing 'i' in replTmat(): please report") msgid "internal bug: missing 'i' in replTmat(): please report" msgstr "błąd wewnętrzny: brakuje 'i' w 'replTmat()': proszę zgłosić raport" # Matrix/R/Tsparse.R: 311 # stop("[ ] indexing not allowed: forgot a \",\" ?") msgid "[ ] indexing not allowed: forgot a \",\" ?" msgstr "indeksowanie [ ] nie jest dozwolone: zapomniałeś ',' ?" # Matrix/R/Tsparse.R: 313 # stop("internal bug: matrix 'i' in replTmat(): please report") msgid "internal bug: matrix 'i' in replTmat(): please report" msgstr "wewnętrzny błąd: macierz 'i' w 'replTmat()': proszę zgłosić raport" # Matrix/R/Tsparse.R: 342 # warning(if(iNA) # gettextf("x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced NA |--> TRUE.", dQuote(clx)) # else # gettextf("x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced.", dQuote(clx)), domain = "R-Matrix") msgid "" "x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced; NA |--> TRUE." msgstr "" "x[.] <- wartość: 'x' to %s, wartość nie w zakresie {TRUE, FALSE} zostaje " "przekształcona; NA |--> TRUE." # Matrix/R/Tsparse.R: 342 # warning(if(iNA) # gettextf("x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced NA |--> TRUE.", dQuote(clx)) # else # gettextf("x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced.", dQuote(clx)), domain = "R-Matrix") msgid "x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced." msgstr "" "x[.] <- wartość: 'x' to %s, wartość nie w zakresie {TRUE, FALSE} zostaje " "przekształcona." # Matrix/R/Tsparse.R: 500 # warning(if(iNA) # gettextf("x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced NA |--> TRUE.", dQuote(clx)) # else # gettextf("x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced.", dQuote(clx)), domain = "R-Matrix") msgid "" "x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced NA |--> TRUE." msgstr "" "x[.,.] <- wartość: 'x' to %s, wartość nie w zakresie {TRUE, FALSE} zostaje " "przekształcona NA |--> TRUE." # Matrix/R/Tsparse.R: 500 # warning(if(iNA) # gettextf("x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced NA |--> TRUE.", dQuote(clx)) # else # gettextf("x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced.", dQuote(clx)), domain = "R-Matrix") msgid "x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced." msgstr "" "x[.,.] <- wartość: 'x' to %s, wartość nie w zakresie {TRUE, FALSE} zostaje " "przekształcona." # Matrix/R/Tsparse.R: 529 # message(gettextf("x[.,.] <- val : x being coerced from Tsparse* to CsparseMatrix"), domain = "R-Matrix") msgid "x[.,.] <- val : x being coerced from Tsparse* to CsparseMatrix" msgstr "" "x[.,.] <- wartość : 'x' zostaje przekształcone z 'Tsparse*' na " "'CsparseMatrix'" # Matrix/R/Matrix.R: 769 # stop(gettextf("nargs() = %d should never happen; please report.", nA), domain = "R-Matrix") # Matrix/R/Matrix.R: 781 # stop(gettextf("nargs() = %d should never happen; please report.", nA), domain = "R-Matrix") # Matrix/R/Tsparse.R: 624 # stop(gettextf("nargs() = %d should never happen; please report.", nA), domain = "R-Matrix") msgid "nargs() = %d should never happen; please report." msgstr "'nargs() = %d' nie powinno się wydarzyć; proszę zgłosić raport." # Matrix/R/Tsparse.R: 669 # stop(gettextf("row indices must be <= nrow(.) which is %d", nr), domain = "R-Matrix") msgid "row indices must be <= nrow(.) which is %d" msgstr "indeksy wiersza muszą być <= 'nrow(.)' który wynosi %d" # Matrix/R/Tsparse.R: 670 # stop(gettextf("column indices must be <= ncol(.) which is %d", nc), domain = "R-Matrix") msgid "column indices must be <= ncol(.) which is %d" msgstr "indeksy kolumn muszą być <= 'ncol(.)' który wynosi %d" # Matrix/R/diagMatrix.R: 418 # stop(gettextf("Internal bug: nargs()=%d; please report", na), domain = "R-Matrix") msgid "Internal bug: nargs()=%d; please report" msgstr "Błąd wewnętrzny: nargs()=%d; proszę zgłosić raport" # Matrix/R/sparseVector.R: 415 # stop("index must be numeric, logical or sparseVector for indexing sparseVectors") msgid "" "index must be numeric, logical or sparseVector for indexing sparseVectors" msgstr "" "indeks musi być typem liczbowym, logicznym lub obiektem klasy 'sparseVector' " "na potrzeby indeksowania obiektów klasy 'sparseVector'" # Matrix/R/Rsparse.R: 32 # stop(gettextf("invalid class: %s", dQuote(cl)), domain = "R-Matrix") # Matrix/R/Rsparse.R: 59 # stop(gettextf("invalid class: %s", dQuote(cl)), domain = "R-Matrix") #, fuzzy msgid "invalid subscript class \"%s\"" msgstr "niepoprawna klasa: %s" # Matrix/R/HBMM.R: 47 # stop(gettextf("Invalid storage type: %s", t1), domain = "R-Matrix") #, fuzzy msgid "invalid subscript type \"%s\"" msgstr "Niepoprawny typ przechowywania: %s" msgid "recycled %s would have maximal index exceeding %s" msgstr "" msgid "subscripts exceeding %s replaced with NA" msgstr "" msgid "subscript out of bounds" msgstr "" # Matrix/R/Tsparse.R: 138 # stop(gettextf("logical subscript too long (%d, should be %d)", length(i), n), domain = "R-Matrix") #, fuzzy msgid "logical subscript too long" msgstr "indeks logiczny jest zbyt długi (%d, powinien być %d)" # Matrix/R/diagMatrix.R: 744 # stop("incompatible matrix dimensions") #, fuzzy msgid "incorrect number of dimensions" msgstr "niezgodne wymiary macierzy" msgid "only zeros may be mixed with negative subscripts" msgstr "" msgid "'%s' has length 0 but '%s' does not" msgstr "" # Matrix/R/dgTMatrix.R: 20 # stop("cannot coerce non-symmetric \"dgTMatrix\" to \"dsCMatrix\" class") #, fuzzy msgid "attempt to coerce matrix with NA to %s" msgstr "" "nie można przekształcić niesymetrycznej macierzy klasy \"dgTMatrix\" na " "klasę \"dsCMatrix\"" # Matrix/R/Matrix.R: 206 # stop("invalid 'data'") #, fuzzy msgid "invalid 'Class2'" msgstr "niepoprawne 'data'" # Matrix/R/abIndex.R: 165 # stop("wrong sign in 'by' argument") #, fuzzy #~ msgid "invalid 'each' argument" #~ msgstr "niepoprawny znak w argumencie 'by'" # Matrix/R/Matrix.R: 206 # stop("invalid 'data'") #, fuzzy #~ msgid "invalid 'times' argument" #~ msgstr "niepoprawne 'data'" # Matrix/R/Auxiliaries.R: 65 # stop(gettextf("not-yet-implemented method for %s(<%s>).\n ->> Ask the package authors to implement the missing feature.", fun, cl), call. = FALSE, domain = "R-Matrix") #~ msgid "" #~ "not-yet-implemented method for %s(<%s>).\n" #~ " ->> Ask the package authors to implement the missing feature." #~ msgstr "" #~ "metoda jeszcze niezaimplementowana dla %s(<%s>).\n" #~ " ->> Poproś autorów pakietu o zaimplementowanie brakującej " #~ "funkcjonalności." # Matrix/R/Auxiliaries.R: 68 # stop(gettextf("not-yet-implemented method for %s(<%s>, <%s>).\n ->> Ask the package authors to implement the missing feature.", fun, cl1, cl2), call. = FALSE, domain = "R-Matrix") #~ msgid "" #~ "not-yet-implemented method for %s(<%s>, <%s>).\n" #~ " ->> Ask the package authors to implement the missing feature." #~ msgstr "" #~ "metoda jeszcze niezaimplementowana dla %s(<%s>, <%s>).\n" #~ " ->> Poproś autorów pakietu o zaimplementowanie brakującej " #~ "funkcjonalności." # Matrix/R/Auxiliaries.R: 906 # stop(gettextf("general Matrix class not yet implemented for %s", dQuote(class(x))), domain = "R-Matrix") #, fuzzy #~ msgid "complex \"diagonalMatrix\" not yet implemented" #~ msgstr "ogólna klasa 'Matrix' jeszcze nie jest zaimplementowana dla %s" # Matrix/R/Auxiliaries.R: 641 # stop(gettextf("not yet implemented for class %s", dQuote(class.x)), domain = "R-Matrix") #, fuzzy #~ msgid "not yet implemented for class \"%s\"" #~ msgstr "jeszcze niezaimplementowane dla klasy %s" # Matrix/R/sparseMatrix.R: 731 # stop("invalid 'type'") #, fuzzy #~ msgid "invalid 'uplo'" #~ msgstr "niepoprawny 'type'" # Matrix/R/Matrix.R: 400 # stop("'lag' and 'differences' must be integers >= 1") #~ msgid "'lag' and 'differences' must be integers >= 1" #~ msgstr "'lag' oraz 'differences' muszą być liczbami całkowitymi >= 1" # Matrix/R/Matrix.R: 459 # stop("programming error: min() should have dispatched w/ 1st arg much earlier") #~ msgid "" #~ "programming error: min() should have dispatched w/ 1st arg much earlier" #~ msgstr "" #~ "błąd programistyczny: 'min()' powinno zostać wysłane z pierwszym " #~ "argumentem znacznie wcześniej" #~ msgid "in Summary(, .): %s(<%s>, <%s>,...)" #~ msgstr "w funkcji 'Summary(, .): %s(<%s>, <%s>,...)'" #, fuzzy #~ msgid "in Summary(, .): %s(<%s>, <%s>)" #~ msgstr "w funkcji 'Summary(, .): %s(<%s>, <%s>,...)'" # Matrix/R/Ops.R: 438 # stop(gettextf("number of rows are not compatible for %s", .Generic), domain = "R-Matrix") #, fuzzy #~ msgid "number of rows of matrices must match" #~ msgstr "liczba wierszy nie jest zgodna dla %s" # Matrix/R/Ops.R: 438 # stop(gettextf("number of rows are not compatible for %s", .Generic), domain = "R-Matrix") #, fuzzy #~ msgid "number of columns of matrices must match" #~ msgstr "liczba wierszy nie jest zgodna dla %s" # Matrix/R/denseMatrix.R: 71 # stop("dim(.) value must be numeric of length 2") # Matrix/R/sparseVector.R: 317 # stop("dim(.) value must be numeric of length 2") # Matrix/R/sparseMatrix.R: 711 # stop("dim(.) value must be numeric of length 2") #, fuzzy #~ msgid "dimensions must be numeric of length 2" #~ msgstr "wartości 'dim(.)' muszą być liczbami o długości 2" # Matrix/R/condest.R: 74 # stop("'A' must be a square matrix") # Matrix/R/condest.R: 194 # stop("'A' must be a square matrix") #, fuzzy #~ msgid "'perm' must be numeric" #~ msgstr "'A' musi być macierzą kwadratową" # Matrix/R/sparseVector.R: 237 # stop("'ncol' must be >= 0") #, fuzzy #~ msgid "'margin' must be 1 or 2" #~ msgstr "'ncol' musi być >= 0" # Matrix/R/products.R: 186 # stop(gettextf("not-yet-implemented method for <%s> %%*%% <%s>", class(x), class(y)), domain = "R-Matrix") #~ msgid "not-yet-implemented method for <%s> %%*%% <%s>" #~ msgstr "jeszcze niezaimplementowana metoda dla <%s> %%*%% <%s>" # Matrix/R/diagMatrix.R: 225 # stop(gettextf("%s kind not yet implemented", sQuote(kind)), domain = "R-Matrix") #, fuzzy #~ msgid "'boolArith = %d' not yet implemented" #~ msgstr "rodzaj %s nie jest jeszcze zaimplementowany" # Matrix/R/sparseMatrix.R: 748 # warning("rcond(.) via sparse -> dense coercion") #, fuzzy #~ msgid "'rcond' via sparse -> dense coercion" #~ msgstr "'rcond(.)' poprzez przekształcenie rzadkie -> gęste" # Matrix/R/Matrix.R: 206 # stop("invalid 'data'") #, fuzzy #~ msgid "invalid 'norm'" #~ msgstr "niepoprawne 'data'" # Matrix/R/ngTMatrix.R: 24 # stop("cannot coerce 'NA's to \"nsparseMatrix\"") #, fuzzy #~ msgid "cannot coerce zsparseVector to dgCMatrix" #~ msgstr "nie można przekształcić wartości 'NA' na 'nsparseMatrix'" # Matrix/R/sparseVector.R: 53 # stop("cannot coerce 'NA's to \"nsparseVector\"") #, fuzzy #~ msgid "cannot coerce zsparseVector to dgeMatrix" #~ msgstr "" #~ "nie można przekształcić wartości NA na obiekt klasy \"nsparseVector\"" # Matrix/R/sparseVector.R: 740 # stop("'times >= 0' is required") #~ msgid "'times >= 0' is required" #~ msgstr "wymagane jest 'times >= 0'" # Matrix/R/Auxiliaries.R: 305 # stop(gettextf("Matrices must have same number of rows in %s", deparse(sys.call(sys.parent()))), call. = FALSE, domain = "R-Matrix") #~ msgid "Matrices must have same number of rows in %s" #~ msgstr "Macierze muszą mieć tę samą liczbę wierszy w %s" # Matrix/R/bind2.R: 395 # stop(gettextf("Matrices must have same number of columns in %s", deparse(sys.call(sys.parent()))), call. = FALSE, domain = "R-Matrix") # Matrix/R/Auxiliaries.R: 314 # stop(gettextf("Matrices must have same number of columns in %s", deparse(sys.call(sys.parent()))), call. = FALSE, domain = "R-Matrix") #~ msgid "Matrices must have same number of columns in %s" #~ msgstr "Macierze muszą mieć tę samą liczbę kolumn w %s" # Matrix/R/lMatrix.R: 8 # stop("\"lMatrix\" object with NAs cannot be coerced to \"nMatrix\"") #, fuzzy #~ msgid "only lists of length 2 can be coerced to indMatrix" #~ msgstr "" #~ "obiekt klasy \"lMatrix\" z wartościami NA nie może zostać przekształcony " #~ "na obiekt klasy \"nMatrix\"" # Matrix/R/sparseMatrix.R: 13 # stop("only 2-dimensional tables can be directly coerced to sparse matrices") #, fuzzy #~ msgid "only 2-dimensional tables can be coerced to sparseMatrix" #~ msgstr "" #~ "jedynie 2-wymiarowe tablice mogą zostać bezpośrednio przekształcone w " #~ "rzadkie macierze" # Matrix/R/symmetricMatrix.R: 114 # stop("'x' is not symmetric nor triangular") #, fuzzy #~ msgid "matrix is not symmetric or" #~ msgstr "'x' nie jest macierzą symetryczną ani trójkątną" # Matrix/R/ndenseMatrix.R: 86 # stop("not a triangular matrix") # Matrix/R/ldenseMatrix.R: 74 # stop("not a triangular matrix") # Matrix/R/Auxiliaries.R: 805 # stop("not a triangular matrix") # Matrix/R/Auxiliaries.R: 1035 # stop("not a triangular matrix") #, fuzzy #~ msgid "triangular" #~ msgstr "to nie jest macierz trójkątną" # Matrix/R/diagMatrix.R: 358 # stop("matrix is not diagonal") #, fuzzy #~ msgid "matrix is not" #~ msgstr "macierz nie jest diagonalna" # Matrix/R/Auxiliaries.R: 167 # stop("'x' is not positive definite -- chol() undefined.") # Matrix/R/dsparseMatrix.R: 18 # stop("'x' is not positive definite -- chol() undefined.") #~ msgid "'x' is not positive definite -- chol() undefined." #~ msgstr "'x' nie jest dodatnio określone -- nieokreślony 'chol()'." # Matrix/R/Auxiliaries.R: 248 # stop(gettextf("Matrices must have same dimensions in %s", deparse(sys.call(sys.parent()))), call. = FALSE, domain = "R-Matrix") #~ msgid "Matrices must have same dimensions in %s" #~ msgstr "Macierze muszą mieć te same wymiary w %s" # Matrix/R/Auxiliaries.R: 375 # message(sprintf(gettext(" [[ suppressing %d column names %s ]]", domain = "R-Matrix"), nc, paste(sQuote(cn[1:lc]), collapse = ", ")), domain = NA) #~ msgid "[[ suppressing %d column names %s ]]" #~ msgstr "[[ zmniejszanie %d nazw kolumn %s ]]" # Matrix/R/Auxiliaries.R: 521 # stop(gettext("'x' must be \"sparseMatrix\""), domain = "R-Matrix") #~ msgid "'x' must be \"sparseMatrix\"" #~ msgstr "'x' musi być obiektem klasy \"sparseMatrix\"" # Matrix/R/Auxiliaries.R: 821 # stop(gettextf("not yet implemented for matrix with typeof %s", typeof(x)), domain = "R-Matrix") # Matrix/R/Auxiliaries.R: 834 # stop(gettextf("not yet implemented for matrix with typeof %s", typeof(x)), domain = "R-Matrix") #~ msgid "not yet implemented for matrix with typeof %s" #~ msgstr "jeszcze niezaimplementowana dla macierzy z typem %s" # Matrix/R/Auxiliaries.R: 850 # stop(gettextf(" not yet implemented for %s", clx@className), domain = "R-Matrix") #~ msgid "not yet implemented for %s" #~ msgstr "jeszcze nie jest zaimplementowana dla %s" # Matrix/R/CHMfactor.R: 122 # message(sprintf(gettext("Quadratic matrix '%s' (=: A) is not formally symmetric. Will be treated as A A'", domain = "R-Matrix"), "parent"), domain = NA) #~ msgid "" #~ "Quadratic matrix '%s' (=: A) is not formally\n" #~ "\tsymmetric. Will be treated as\tA A'" #~ msgstr "" #~ "Macierz kwadratowa '%s' (=: A) nie jest formalnie symetryczna. Będzie " #~ "traktowana jako A A'" # Matrix/R/CHMfactor.R: 134 # stop("'update' must be logical or '+' or '-'; 'C' a matrix, and 'L' a \"CHMfactor\"") #~ msgid "" #~ "'update' must be logical or '+' or '-'; 'C' a matrix, and 'L' a " #~ "\"CHMfactor\"" #~ msgstr "" #~ "'update' musi być wartością logiczną lub '+' lub '-'; 'C' musi być " #~ "macierzą, oraz 'L' musi być obiektem klasy 'CHMfactor'" # Matrix/R/CHMfactor.R: 145 # stop("update must be TRUE/FALSE or '+' or '-'") #~ msgid "update must be TRUE/FALSE or '+' or '-'" #~ msgstr "'update' musi wynosić TRUE/FALSE lub '+' lub '-'" # Matrix/R/Csparse.R: 190 # stop("Matrix-internal error in [i,,d]; please report") #~ msgid "Matrix-internal error in [i,,d]; please report" #~ msgstr "" #~ "błąd wewnętrzny w pakiecie 'Matrix' w '[i,,d]'; proszę zgłosić " #~ "raport" # Matrix/R/Csparse.R: 498 # stop("Cholesky() -> *symbolic* factorization -- not yet implemented") #~ msgid "" #~ "Cholesky() -> *symbolic* factorization -- not yet implemented" #~ msgstr "" #~ "Cholesky() -> *symboliczna* faktoryzacja -- jeszcze " #~ "niezaimplementowana" # Matrix/R/Matrix.R: 71 # warning("trimmed mean of 'sparseVector' -- suboptimally using as.numeric(.)") #~ msgid "trimmed mean of 'sparseVector' -- suboptimally using as.numeric(.)" #~ msgstr "" #~ "przycięta średnia 'sparseVector' -- optymalnie używając 'as.numeric(.)'" # Matrix/R/Matrix.R: 144 # stop(gettextf("invalid dimnames given for %s object", dQuote(class(x))), domain = "R-Matrix") #~ msgid "invalid dimnames given for %s object" #~ msgstr "podano niepoprawne nazwy wymiarów dla obiektu %s" # Matrix/R/Matrix.R: 154 # message("dimnames(.) <- NULL: translated to \ndimnames(.) <- list(NULL,NULL) <==> unname(.)") #~ msgid "" #~ "dimnames(.) <- NULL: translated to \n" #~ "dimnames(.) <- list(NULL,NULL) <==> unname(.)" #~ msgstr "" #~ "dimnames(.) <- NULL: przetłumaczono na\n" #~ "dimnames(.) <- list(NULL,NULL) <==> unname(.)" # Matrix/R/Matrix.R: 186 # warning("'nrow', 'ncol', etc, are disregarded when 'data' is \"Matrix\" already") #~ msgid "" #~ "'nrow', 'ncol', etc, are disregarded when 'data' is \"Matrix\" already" #~ msgstr "" #~ "'nrow', 'ncol', itd., nie są uwzględniane gdy 'data' ma już typ 'Matrix'" # Matrix/R/Matrix.R: 251 # stop("complex matrices not yet implemented in Matrix package") #~ msgid "complex matrices not yet implemented in Matrix package" #~ msgstr "" #~ "macierze zespolone nie są jeszcze zaimplementowane w pakiecie 'Matrix'" # Matrix/R/Matrix.R: 311 # warning("using slow kronecker() method") # Matrix/R/Matrix.R: 318 # warning("using slow kronecker() method") #~ msgid "using slow kronecker() method" #~ msgstr "używanie powolnej metody 'kronecker()'" # Matrix/R/Matrix.R: 334 # stop(gettextf("Cholesky(A) called for 'A' of class \"%s\";\n\t it is currently defined for sparseMatrix only; consider using chol() instead", class(A)), call. = FALSE, domain = "R-Matrix") #~ msgid "" #~ "Cholesky(A) called for 'A' of class \"%s\";\n" #~ "\t it is currently defined for sparseMatrix only; consider using chol() " #~ "instead" #~ msgstr "" #~ "metoda 'Cholesky(A)' poprosiła o 'A' klasy '%s';\n" #~ "\t aktualnie jest ona zdefiniowana jedynie dla klasy 'sparseMatrix'; " #~ "rozważ w zamian użycie 'metodychol()'" # Matrix/R/Matrix.R: 563 # stop("invalid or not-yet-implemented 'Matrix' subsetting") #~ msgid "invalid or not-yet-implemented 'Matrix' subsetting" #~ msgstr "niepoprawne lub jeszcze niezaimplementowane podstawienie 'Matrix'" # Matrix/R/Matrix.R: 574 # message("[ ] : .M.sub.i.logical() maybe inefficient") #~ msgid "[ ] : .M.sub.i.logical() maybe inefficient" #~ msgstr "[ ] : '.M.sub.i.logical()' może być niewydajne" # Matrix/R/Matrix.R: 590 # stop(gettextf("nargs() = %d. Extraneous illegal arguments inside '[ .. ]' (i.logical)?", nA), domain = "R-Matrix") #~ msgid "" #~ "nargs() = %d. Extraneous illegal arguments inside '[ .. ]' (i.logical)?" #~ msgstr "" #~ "nargs() = %d. Obce nielegalne argumenty wewnątrz '[ .. ]' (i.logical)?" # Matrix/R/Matrix.R: 644 # message("m[ ]: inefficiently indexing single elements") #, fuzzy #~ msgid "" #~ "m[]: inefficiently indexing single elements - should not " #~ "happen, please report!" #~ msgstr "m[ ]: nieefektywne indeksowanie pojedynczych elementów" # Matrix/R/Matrix.R: 673 # stop(gettextf("nargs() = %d. Extraneous illegal arguments inside '[ .. ]' (i.2col)?", nA), domain = "R-Matrix") #~ msgid "" #~ "nargs() = %d. Extraneous illegal arguments inside '[ .. ]' (i.2col)?" #~ msgstr "" #~ "nargs() = %d. Obce nielegalne argumenty wewnątrz '[ .. ]' (i.2col)?" # Matrix/R/Matrix.R: 663 # stop(".M.sub.i.2col(): 'i' has no integer column number;\n should never happen; please report") #~ msgid "" #~ ".M.sub.i.2col(): 'i' has no integer column number;\n" #~ " should never happen; please report" #~ msgstr "" #~ ".M.sub.i.2col(): 'i' posiada niecałkowitą liczbę kolumn;\n" #~ "to nie powinno się nigdy wydarzyć; proszę zgłosić raport" # Matrix/R/Tsparse.R: 8 # stop("not-yet-implemented coercion to \"TsparseMatrix\"") #~ msgid "not-yet-implemented coercion to \"TsparseMatrix\"" #~ msgstr "jeszcze niezaimplementowane przekształcenie na 'TsparseMatrix'" # Matrix/R/Tsparse.R: 206 # stop("Matrix-internal error in [i,,d]; please report") #~ msgid "Matrix-internal error in [i,,d]; please report" #~ msgstr "" #~ "błąd wewnętrzny pakiecie 'Matrix' w '[i,,d]'; proszę zgłosić " #~ "raport" # Matrix/R/Tsparse.R: 256 # stop("FIXME: NOT YET FINISHED IMPLEMENTATION") #~ msgid "FIXME: NOT YET FINISHED IMPLEMENTATION" #~ msgstr "FIXME: JESZCZE NIEZAKOŃCZONA IMPLEMENTACJA" # Matrix/R/denseMatrix.R: 30 # stop("diagonalMatrix in .dense2C() -- should never happen, please report!") #~ msgid "diagonalMatrix in .dense2C() -- should never happen, please report!" #~ msgstr "" #~ "'diagonalMatrix' w '.dense2C()' -- nie powinno nigdy się wydarzyć, proszę " #~ "zgłosić raport!" # Matrix/R/denseMatrix.R: 36 # stop(gettextf("undefined method for class %s", dQuote(cl)), domain = "R-Matrix") #~ msgid "undefined method for class %s" #~ msgstr "niezdefiniowana metoda dla klasy %s" # Matrix/R/denseMatrix.R: 73 # stop("dimensions don't match the number of cells") # Matrix/R/sparseVector.R: 319 # stop("dimensions don't match the number of cells") # Matrix/R/sparseMatrix.R: 713 # stop("dimensions don't match the number of cells") #~ msgid "dimensions don't match the number of cells" #~ msgstr "wymiary nie zgadzają się z liczbą komórek" # Matrix/R/dgCMatrix.R: 94 # stop(gettextf("LU computationally singular: ratio of extreme entries in |diag(U)| = %9.4g", # rU[1] / rU[2]), # domain = "R-Matrix") #~ msgid "" #~ "LU computationally singular: ratio of extreme entries in |diag(U)| = %9.4g" #~ msgstr "" #~ "LU obliczeniowo osobliwa: stosunek ekstremalnych wpisów w |diag(U)| = " #~ "%9.4g" # Matrix/R/diagMatrix.R: 28 # stop("'x' has invalid data type") #~ msgid "'x' has invalid data type" #~ msgstr "'x' posiada niepoprawny typ danych" # Matrix/R/diagMatrix.R: 72 # stop("length(x) must be either 1 or #{cols}") #~ msgid "length(x) must be either 1 or #{cols}" #~ msgstr "'length(x)' musi wynosić 1 lub #{kolumn}" # Matrix/R/diagMatrix.R: 101 # stop("some arguments are not matrices") #~ msgid "some arguments are not matrices" #~ msgstr "niektóre argumenty nie są macierzami" # Matrix/R/diagMatrix.R: 225 # stop(gettextf("%s kind not yet implemented", sQuote(kind)), domain = "R-Matrix") #~ msgid "%s kind not yet implemented" #~ msgstr "rodzaj %s nie jest jeszcze zaimplementowany" # Matrix/R/diagMatrix.R: 337 # stop("non-square matrix") # Matrix/R/diagMatrix.R: 357 # stop("non-square matrix") #~ msgid "non-square matrix" #~ msgstr "niekwadratowa macierz" # Matrix/R/diagMatrix.R: 339 # stop("matrix with non-zero off-diagonals cannot be coerced to \"diagonalMatrix\"") #~ msgid "" #~ "matrix with non-zero off-diagonals cannot be coerced to \"diagonalMatrix\"" #~ msgstr "" #~ "macierz z niezerowaymi wartościami pozadiagonalnymi nie może zostać " #~ "przekształcona w na obiekt klasy \"diagonalMatrix\"" # Matrix/R/diagMatrix.R: 586 # stop("non-matching dimensions") # Matrix/R/diagMatrix.R: 599 # stop("non-matching dimensions") # Matrix/R/diagMatrix.R: 615 # stop("non-matching dimensions") # Matrix/R/diagMatrix.R: 627 # stop("non-matching dimensions") # Matrix/R/diagMatrix.R: 658 # stop("non-matching dimensions") # Matrix/R/diagMatrix.R: 676 # stop("non-matching dimensions") #~ msgid "non-matching dimensions" #~ msgstr "niezgodne wymiary" # Matrix/R/dppMatrix.R: 27 # stop("not a positive definite matrix") # Matrix/R/dsyMatrix.R: 94 # stop("not a positive definite matrix") #~ msgid "not a positive definite matrix" #~ msgstr "to nie jest dodatnio określona macierz" # Matrix/R/dsCMatrix.R: 5 # warning("as(.,\"dsCMatrix\") is deprecated (since 2008); do use as(., \"symmetricMatrix\")") #~ msgid "" #~ "as(.,\"dsCMatrix\") is deprecated (since 2008); do use as(., " #~ "\"symmetricMatrix\")" #~ msgstr "" #~ "'as(.,\"dsCMatrix\")' jest przestarzałe (0d 2008); używaj 'as(., " #~ "\"symmetricMatrix\")'" # Matrix/R/dtpMatrix.R: 14 # warning("inefficient coercion (lost triangularity); please report") #~ msgid "inefficient coercion (lost triangularity); please report" #~ msgstr "" #~ "nieefektywne przekształcenie (utracono trójkątność); proszę zgłosić raport" # Matrix/R/indMatrix.R: 13 # stop("coercion to \"indMatrix\" only works from integer numeric") #~ msgid "coercion to \"indMatrix\" only works from integer numeric" #~ msgstr "" #~ "przekształcenie na \"indMatrix\" działa jedynie dla liczb całkowitych" #~ msgid "" #~ "coercion from list(i1,...,ik, d) to \"indMatrix\" failed.\n" #~ " All entries must be integer valued and the number of columns, d, not " #~ "smaller\n" #~ " than the maximal index i*." #~ msgstr "" #~ "przekształcenie z 'list(i1,...,ik, d)' na obiekt klasy \"indMatrix\" nie " #~ "powiodło się.\n" #~ " Wszystkie wpisy muszą być wartościami całkowitymi a liczba kolumn d nie " #~ "może być mniejsza niż maksymalny indeks i*." # Matrix/R/indMatrix.R: 65 # stop("the number of non-zero entries differs from nrow(.)") # Matrix/R/pMatrix.R: 27 # stop("the number of non-zero entries differs from nrow(.)") #~ msgid "the number of non-zero entries differs from nrow(.)" #~ msgstr "liczba niezerowych wpisów różni się od 'nrow(.)'" # Matrix/R/indMatrix.R: 158 # stop('replacing "indMatrix" entries is not allowed, as rarely sensible') #~ msgid "replacing \"indMatrix\" entries is not allowed, as rarely sensible" #~ msgstr "" #~ "zastępowanie wpisów \"indMatrix\" jest niedozwolone, ponieważ jest to " #~ "rzadko sensowne" # Matrix/R/nsCMatrix.R: 58 # stop("function is temporarily disabled") #~ msgid "temporarily disabled" #~ msgstr "funkcja jest tymczasowo niedostępna" # Matrix/R/ngTMatrix.R: 24 # stop("cannot coerce 'NA's to \"nsparseMatrix\"") #, fuzzy #~ msgid "cannot coerce NA values to pattern \"ntCMatrix\"" #~ msgstr "nie można przekształcić wartości 'NA' na 'nsparseMatrix'" # Matrix/R/pMatrix.R: 17 # stop("coercion to \"pMatrix\" only works from integer numeric") #~ msgid "coercion to \"pMatrix\" only works from integer numeric" #~ msgstr "" #~ "przekształcenie na obiekt klasy \"pMatrix\" działa jedynie dla liczb " #~ "całkowitych" # Matrix/R/pMatrix.R: 25 # stop("not a square matrix") #~ msgid "not a square matrix" #~ msgstr "to nie jest macierz kwadratowa" # Matrix/R/sparseMatrix.R: 58 # stop("NA's in (i,j) are not allowed") #~ msgid "NA's in (i,j) are not allowed" #~ msgstr "wartości NA w (i,j) nie są dozwolone" # Matrix/R/sparseMatrix.R: 240 # stop("Matrix-internal error in [i,,d]; please report") #~ msgid "Matrix-internal error in [i,,d]; please report" #~ msgstr "" #~ "błąd wewnętrzny pakietu 'Matrix' w '[i,,d]'; proszę zgłosić " #~ "raport" # Matrix/R/sparseQR.R: 16 # warning("qr.R() may differ from qr.R() because of permutations. Possibly use our qrR() instead") #~ msgid "" #~ "qr.R() may differ from qr.R() because of permutations. " #~ "Possibly use our qrR() instead" #~ msgstr "" #~ "'qr.R()' może różnić się od 'qr.R()' z powodu permutacji. " #~ "Być może użyj metody qrR() w zamian" # Matrix/R/symmetricMatrix.R: 72 # stop(sprintf("(un)packing only applies to dense matrices, class(x)='%s'", # cx)) # Matrix/R/symmetricMatrix.R: 93 # stop(sprintf("(un)packing only applies to dense matrices, class(x)='%s'", # class(x))) #~ msgid "(un)packing only applies to dense matrices, class(x)='%s'" #~ msgstr "" #~ "(roz)pakowanie stosuje się jedynie do gęstych macierzy, class(x)='%s'" # Matrix/R/Auxiliaries.R: 167 # stop("'x' is not positive definite -- chol() undefined.") # Matrix/R/dsparseMatrix.R: 18 # stop("'x' is not positive definite -- chol() undefined.") #, fuzzy #~ msgid "'x' is not symmetric -- chol() undefined." #~ msgstr "'x' nie jest dodatnio określone -- nieokreślony 'chol()'." # Matrix/R/Auxiliaries.R: 1376 # warning(sprintf(gettext("arguments %s are disregarded in\n %s", domain = "R-Matrix"), # sub(")$", '', sub("^list\\(", '', deparse(list(...), control=c()))), # deparse(sys.call(-1), control=c())), call. = FALSE, domain = NA) #, fuzzy #~ msgid "" #~ "extra argument %s will be disregarded in\n" #~ " %s" #~ msgid_plural "" #~ "extra arguments %s will be disregarded in\n" #~ " %s" #~ msgstr[0] "" #~ "argumenty %s zostały odrzucone w\n" #~ " %s" #~ msgstr[1] "" #~ "argumenty %s zostały odrzucone w\n" #~ " %s" #~ msgstr[2] "" #~ "argumenty %s zostały odrzucone w\n" #~ " %s" # Matrix/R/Ops.R: 134 # stop(sprintf(gettext(" %s %s is undefined", domain = "R-Matrix"), .Generic, paste0(class(e2),"(0)")), domain = NA) # Matrix/R/Ops.R: 634 # stop(sprintf(gettext(" %s %s is undefined", domain = "R-Matrix"), .Generic, paste0(class(e2),"(0)")), domain = NA) # Matrix/R/Ops.R: 1126 # stop(sprintf(gettext(" %s %s is undefined", domain = "R-Matrix"), .Generic, paste0(class(e2),"(0)")), domain = NA) #~ msgid " %s %s is undefined" #~ msgstr " %s %s nie jest określone" # Matrix/R/Ops.R: 1165 # stop(sprintf(gettext("%s %s is undefined", domain = "R-Matrix"), paste0(class(e2),"(0)"), .Generic), domain = NA) #~ msgid "%s %s is undefined" #~ msgstr "%s %s nie jest określone" # Matrix/R/spModels.R: 125 # warning(gettextf("variable '%s' converted to a factor", i), domain = "R-Matrix") #~ msgid "variable '%s' converted to a factor" #~ msgstr "zmienna '%s' została zamieniona na czynnik" # Matrix/R/lMatrix.R: 8 # stop("\"lMatrix\" object with NAs cannot be coerced to \"nMatrix\"") #~ msgid "\"dMatrix\" object with NAs cannot be coerced to \"nMatrix\"" #~ msgstr "" #~ "obiekt klasy \"dMatrix\" z wartościami NA nie może zostać przekształcony " #~ "na obiekt klasy \"nMatrix\"" # Matrix/R/indMatrix.R: 63 # stop("not a skinny matrix") #~ msgid "not a skinny matrix" #~ msgstr "to nie jest chuda macierz" #~ msgid "longer object length" #~ msgstr "długość dłuższego obiektu" Matrix/po/R-de.po0000644000176200001440000012735714521047060013301 0ustar liggesusers# Translation of R-matrix to German # Copyright (C) 2001-2020 The R Foundation # This file is distributed under the same license as the matrix package. # Chris Leick , 2009. # Detlef Steuer , 2012-2020. msgid "" msgstr "" "Project-Id-Version: R 4.0.0 / matrix 1.3-0\n" "Report-Msgid-Bugs-To: bugs.r-project.org\n" "POT-Creation-Date: 2023-11-02 21:33\n" "PO-Revision-Date: 2020-04-01 16:01+0200\n" "Last-Translator: Detlef Steuer \n" "Language-Team: R-Core \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #, fuzzy msgid "invalid mode \"%s\"" msgstr "ungültiges 'mod': %s" msgid "" "%s(<%s>, <%s>) is not yet implemented; ask maintainer(\"%s\") to implement " "the missing method" msgstr "" #, fuzzy msgid "complex %s not yet implemented" msgstr "Klasse %s noch nicht implementiert" #, fuzzy msgid "cannot coerce matrix of type \"%s\" to %s" msgstr "'NA's können nicht in \"nsparseMatrix\" umgewandelt werden" #, fuzzy msgid "non0.i() not yet implemented for class %s" msgstr "noch nicht implementiert für Klasse %s" msgid "%s=\"%s\" invalid for %s@uplo=\"%s\"" msgstr "" msgid "'%s' is not \"%1$s\", \"D%1$s\", or \"%1$s.\"" msgstr "" msgid "unexpected %s=\"%s\" in '%s' method" msgstr "" msgid "Not a valid format" msgstr "Kein gültiges Format" msgid "'file' must be a character string or connection" msgstr "'file' muss eine Zeichenkette oder Verbindung sein" msgid "Invalid storage type: %s" msgstr "Ungültiger Speichertyp: %s" msgid "Only numeric sparse matrices allowed" msgstr "Nur dünn besetzte Matrizen erlaubt" msgid "Invalid storage format: %s" msgstr "Ungültiges Speicherformat: %s" msgid "Invalid assembled indicator: %s" msgstr "Ungültig zusammengesetzter Indikator: %s" msgid "file is not a MatrixMarket file" msgstr "Datei ist keine MatrixMarket-Datei" msgid "type '%s' not recognized" msgstr "Typ '%s' nicht erkannt" msgid "representation '%s' not recognized" msgstr "Repräsentation '%s' nicht erkannt" msgid "element type '%s' not recognized" msgstr "Elementtyp '%s' nicht erkannt" msgid "symmetry form '%s' not recognized" msgstr "Symmetrieform '%s' nicht erkannt" msgid "readMM(): expected %d entries but found only %d" msgstr "" #, fuzzy msgid "readMM(): row indices 'i' are not in 1:nrow[=%d]" msgstr "readMM(): Zeile\t Werte 'i' sind nicht in 1:nr" #, fuzzy msgid "readMM(): column indices 'j' are not in 1:ncol[=%d]" msgstr "readMM(): Spalte\t Werte 'j' sind nicht in 1:nc" msgid "symmetry form 'skew-symmetric' not yet implemented for reading" msgstr "Symmetrieform 'skew-symmetric' noch nicht zum Lesen implementiert" msgid "symmetry form 'hermitian' not yet implemented for reading" msgstr "Symmetrieform 'hermitian' noch nicht zum Lesen implementiert" msgid "symmetry form '%s' is not yet implemented" msgstr "Symmetrieform '%s' noch nicht implementiert" msgid "element type 'complex' not yet implemented" msgstr "Elementtyp 'complex' noch nicht implementiert" msgid "'%s()' is not yet implemented for element type '%s'" msgstr "'%s()' ist noch nicht für Elementtyp '%s' implementiert" msgid "'%s()' is not yet implemented for representation '%s'" msgstr "'%s()' ist noch nicht implementiert für Darstellung '%s'" msgid "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%3$s\", or \"%4$s\"" msgstr "" msgid "" "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%2$s2\", \"%2$s2.\", \"%3$s\", or " "\"%4$s\"" msgstr "" msgid "longer object length is not a multiple of shorter object length" msgstr "längere Objektlänge ist kein Vielfaches der kürzeren Objektlänge" #, fuzzy msgid "invalid class \"%s\" in '%s' method" msgstr "ungültige 'col.names'-Zeichenkette: %s" msgid "invalid type \"%s\" in '%s' method" msgstr "" msgid "non-conformable matrix dimensions in %s" msgstr "nicht konforme Matrixdimensionen in %s" msgid "dimnames [%d] mismatch in %s" msgstr "dimnames [%d] passen nicht in %s" msgid "inefficient method used for \"- e1\"" msgstr "ineffiziente Methode für '- e1' benutzt" msgid "dim [product %d] do not match the length of object [%d]" msgstr "dim [produkt %d] passt nicht zur Länge des Objekts [%d]" msgid "internal bug in \"Compare\" method (Cmp.Mat.atomic); please report" msgstr "" "interner Fehler in der \"Compare\"-Methode (Cmp.Mat.atomic). Bitte berichten" msgid "Cmp.Mat.atomic() should not be called for diagonalMatrix" msgstr "Cmp.Mat.atomic() sollte nicht für diagonalMatrix aufgerufen werden" msgid "Matrices must have same number of rows for arithmetic" msgstr "Matrizen müssen für Arithmetik die gleiche Anzahl Zeilen haben" msgid "number of rows are not compatible for %s" msgstr "Anzahl der Zeilen ist nicht kompatibel für %s" msgid "length of 2nd arg does not match dimension of first" msgstr "Länge des zweiten Arguments passt nicht zur Dimension des ersten" msgid "length of 1st arg does not match dimension of 2nd" msgstr "Länge des ersten arg passt nicht zur Dimension des zweiten" msgid "internal bug in \"Logic\" method (Logic.Mat.atomic); please report" msgstr "" "interner Fehler in der \"Logic\"-Methode (.Logic.Mat.atomic). Bitte berichten" msgid "Logic.Mat.atomic() should not be called for diagonalMatrix" msgstr "Logic.mat.atomic() sollte für diagonalMatrix nicht aufgerufen werden" msgid "vector too long in Matrix - vector operation" msgstr "Vektor zu lang in der Matrix - Vektor Operation" msgid "" "longer object length\n" "\tis not a multiple of shorter object length" msgstr "" "längere Objektlänge\n" "\tist kein Vielfaches der kürzeren Objektlänge" msgid "intermediate 'r' is of type %s" msgstr "Zwischenergebnis 'r' ist vom Typ %s" msgid "not yet implemented .. please report" msgstr "noch nicht implementiert ... bitte melden" msgid "'force' must be (coercable to) TRUE or FALSE" msgstr "'force' muss (umwandelbar nach) TRUE oder FALSE sein" msgid "invalid (to - from)/by in seq(.)" msgstr "unzulässiges (to - from)/by in seq(.)" msgid "wrong sign in 'by' argument" msgstr "falsches Vorzeichen im Argument 'by'" msgid "'by' argument is much too small" msgstr "Argument 'by' ist zu klein" msgid "length must be non-negative number" msgstr "Länge muss eine nicht negative Zahl sein" msgid "too many arguments" msgstr "zu viele Argumente" msgid "c(,..) of different kinds, coercing all to 'rleDiff'" msgstr "" "c(,..) von unterschiedlichen Arten, alle werden in 'rleDiff' " "umgewandelt" msgid "[i] is not yet implemented" msgstr "[i] ist noch nicht implementiert" msgid "all() is not yet implemented" msgstr "all() ist noch nicht implementiert" msgid "sum() is not yet implemented" msgstr "sum() ist noch nicht implementiert" msgid "prod() is not yet implemented" msgstr "prod() ist noch nicht implementiert" msgid "not yet implemented" msgstr "noch nicht implementiert" msgid "" "x / 0 for an x with sign-change\n" " no longer representable as 'rleDiff'" msgstr "" "x / 0 für einen x mit Vorzeichenwechsel\n" " nicht länger als 'rleDiff' darstellbar" msgid " --> is not yet implemented" msgstr " --> ist noch nicht implementiert" msgid " --> is not yet implemented" msgstr " --> ist noch nicht implementiert" #, fuzzy msgid "%1$s(%2$s) is undefined: '%2$s' is not positive semidefinite" msgstr "chol() ist undefiniert für diagonale Matrix mit negativen Einträgen" #, fuzzy msgid "matrix is not square" msgstr "Matrix ist nicht diagonal" msgid "" "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%3$s\", \"%3$s.\", \"%3$s1\", \"%3$s1." "\", or \"%4$s\"" msgstr "" #, fuzzy msgid "'%s' does not inherit from virtual class %s" msgstr "'x' muss von \"sparseVector\" geerbt sein" msgid "D[i,i] is NA, i=%d" msgstr "" msgid "D[i,i] is negative, i=%d" msgstr "" msgid "'%1$s' is not formally symmetric; factorizing tcrossprod(%1$s)" msgstr "" #, fuzzy msgid "matrix is not symmetric; consider forceSymmetric(.) or symmpart(.)" msgstr "" "keine symmetrische Matrix. Erwägen Sie forceSymmetric() oder symmpart()" #, fuzzy msgid "matrix is not triangular; consider triu(.) or tril(.)" msgstr "die Matrix ist nicht dreieckig" msgid "matrix is not diagonal; consider Diagonal(x=diag(.))" msgstr "" #, fuzzy msgid "invalid type \"%s\" in '%s'" msgstr "ungültiger 'type'" #, fuzzy msgid "invalid %s=\"%s\" to '%s'" msgstr "Ungültiger Speichertyp: %s" msgid "dimensions cannot exceed %s" msgstr "" #, fuzzy msgid "invalid class \"%s\" in '%s'" msgstr "ungültige 'col.names'-Zeichenkette: %s" msgid "%s length cannot exceed %s" msgstr "" msgid "'A' must be a square matrix" msgstr "'A' muss eine quadratische Matrix sein" msgid "must either specify 'A' or the functions 'A.x' and 'At.x'" msgstr "muss entweder 'A' angeben oder die Funktionen 'A.x' und 'At.x'" msgid "when 'A' is specified, 'A.x' and 'At.x' are disregarded" msgstr "wenn 'A' angegeben wurde, werden 'A.x' und 'At.x' nicht berücksichtigt" msgid "not converged in %d iterations" msgstr "nicht konvergiert in %d Iterationsschritten" msgid "hit a cycle (1) -- stop iterations" msgstr "auf einen Zyklus getroffen (1) – Iterationen stoppen" msgid "hit a cycle (2) -- stop iterations" msgstr "auf einen Zyklus getroffen (2) – Iterationen stoppen" msgid "not enough new vecs -- stop iterations" msgstr "nicht genügend neue Vektoren – Iterationen stoppen" msgid "invalid 'data'" msgstr "ungültiges 'data'" #, fuzzy msgid "'nrow', 'ncol', 'byrow' disregarded for [mM]atrix 'data'" msgstr "'nrow', 'ncol', etc werden nicht für Matrix 'data' berücksichtigt" msgid "data is too long" msgstr "" #, fuzzy msgid "exactly one of 'i', 'j', and 'p' must be missing from call" msgstr "exakt eins von 'i', 'j' oder 'p' muss im Aufruf fehlen" msgid "" "use Diagonal() to construct diagonal (symmetric && triangular) sparse " "matrices" msgstr "" msgid "'giveCsparse' is deprecated; using 'repr' instead" msgstr "" msgid "'giveCsparse' is deprecated; setting repr=\"T\" for you" msgstr "" #, fuzzy msgid "'p' must be a nondecreasing vector c(0, ...)" msgstr "'p' muss ein nicht abnehmender Vektor (0, ...) sein" msgid "dimensions cannot exceed 2^31-1" msgstr "" msgid "'i' and 'j' must not contain NA" msgstr "" msgid "'i' and 'j' must be" msgstr "" msgid "positive" msgstr "" msgid "non-negative" msgstr "" #, fuzzy msgid "invalid 'dims'" msgstr "ungültiges 'data'" msgid "'dims' must contain all (i,j) pairs" msgstr "" msgid "symmetric matrix must be square" msgstr "symmetrische Matrix muss quadratisch sein" msgid "triangular matrix must be square" msgstr "Dreiecksmatrix muss quadratisch sein" msgid "p[length(p)]" msgstr "" msgid "length(i)" msgstr "" #, fuzzy msgid "is not an integer multiple of length(x)" msgstr "length(i) ist kein Vielfaches von length(x)" msgid "length(x) must not exceed" msgstr "" msgid "invalid 'repr'; must be \"C\", \"R\", or \"T\"" msgstr "" #, fuzzy msgid "'n' must be a non-negative integer" msgstr "Länge muss eine nicht negative Zahl sein" msgid "'x' has unsupported class \"%s\"" msgstr "" msgid "'x' has unsupported type \"%s\"" msgstr "" msgid "attempt to recycle 'x' of length 0 to length 'n' (n > 0)" msgstr "" msgid "'shape' must be one of \"g\", \"t\", \"s\"" msgstr "" msgid "'kind' must be one of \"d\", \"l\", \"n\"" msgstr "" msgid "mismatch between typeof(x)=\"%s\" and kind=\"%s\"; using kind=\"%s\"" msgstr "" #, fuzzy msgid "'cols' must be numeric" msgstr "'ncol' muss >= 0 sein" msgid "'cols' has elements not in seq(0, length.out = n)" msgstr "" msgid "'uplo' must be \"U\" or \"L\"" msgstr "" #, fuzzy msgid "'lst' must be a list" msgstr "'ncol' muss >= 0 sein" msgid "'giveCsparse' has been deprecated; setting 'repr = \"T\"' for you" msgstr "" msgid "'giveCsparse' has been deprecated; will use 'repr' instead" msgstr "" msgid "'diagonals' matrix must have %d columns (= length(k) )" msgstr "'diagonals'-Matrix muss %d Spalten haben (= length(k) )" msgid "'diagonals' must have the same length (%d) as 'k'" msgstr "'diagonals' muss die gleiche Länge (%d) wie 'k' haben" msgid "matrix can only be symmetric if square, but n != m" msgstr "" "Matrix kann nur symmetrisch sein, wenn sie quadratisch ist, aber n != m" msgid "" "for symmetric band matrix, only specify upper or lower triangle\n" " hence, all k must have the same sign" msgstr "" "geben Sie für symmetrische Bandmatrizen nur oberes oder unteres Dreieck an.\n" " deshalb müssen alle k dasselbe Vorzeichen haben." msgid "the %d-th (sub)-diagonal (k = %d) is too short; filling with NA's" msgstr "" "die %d-te (Unter)-Diagonale (k = %d) ist zu kurz und wird mit NA aufgefüllt" msgid "invalid 'repr'; must be \"C\", \"T\", or \"R\"" msgstr "" msgid "'x' must inherit from \"sparseVector\"" msgstr "'x' muss von \"sparseVector\" geerbt sein" msgid "'ncol' must be >= 0" msgstr "'ncol' muss >= 0 sein" msgid "'nrow' must be >= 0" msgstr "'nrow' muss >= 0 sein" msgid "Must specify 'nrow' when 'symmetric' is true" msgstr "'nrow' muss angegeben werden, wenn 'symmetric' auf true gesetzt ist" msgid "'nrow' and 'ncol' must be the same when 'symmetric' is true" msgstr "" "'nrow' und 'ncol' müssen gleich sein, wenn 'symmetric' auf true gesetzt ist" msgid "'x' must have length nrow^2 when 'symmetric' is true" msgstr "'x' muss die Länge nrow^2, wenn 'symmetric' auf true gesetzt ist" msgid "'ncol' is not a factor of length(x)" msgstr "'ncol' ist kein Faktor von length(x)" msgid "'nrow' is not a factor of length(x)" msgstr "'nrow' ist kein Faktor von length(x)" msgid "Class %s is not yet implemented" msgstr "Klasse %s noch nicht implementiert" #, fuzzy msgid "'%s' and '%s' must be positive integers" msgstr "Länge muss eine nicht negative Zahl sein" #, fuzzy msgid "matrix is not symmetric or triangular" msgstr "'x' ist weder symmetrisch noch in Dreiecksform" #, fuzzy msgid "matrix is not symmetric" msgstr "die Matrix ist nicht dreieckig" #, fuzzy msgid "matrix is not triangular" msgstr "'x' ist weder symmetrisch noch in Dreiecksform" msgid "" "the default value of argument '%s' of method '%s(<%s>, <%s>)' may change " "from %s to %s as soon as the next release of Matrix; set '%s' when " "programming" msgstr "" msgid "determinant of non-square matrix is undefined" msgstr "" msgid "replacement diagonal has wrong length" msgstr "" msgid "replacement diagonal has incompatible type \"%s\"" msgstr "" msgid "assigned dimensions are not of type \"%s\" or \"%s\"" msgstr "" msgid "assigned dimensions do not have length %d" msgstr "" msgid "assigned dimensions are NA" msgstr "" msgid "assigned dimensions are negative" msgstr "" msgid "assigned dimensions exceed %s" msgstr "" #, fuzzy msgid "assigned dimensions [product %.0f] do not match object length [%.0f]" msgstr "dim [produkt %d] passt nicht zur Länge des Objekts [%d]" msgid "'%s' has non-finite values" msgstr "" msgid "'%1$s' is not \"%2$s\", \"%3$s\", or \"%2$s.\"" msgstr "" #, fuzzy msgid "only square matrices can be used as graph incidence matrices" msgstr "" "nur quadratische Matrizen können als Inzidenzmatrizen für Graphen benutzt " "werden" msgid "'lwd' must be NULL or non-negative numeric" msgstr "'lwd' muss NULL oder nicht negativ numerisch sein" #, fuzzy msgid "%s(<%s>) is not yet implemented" msgstr "Klasse %s noch nicht implementiert" msgid "'%s' is not of type \"%s\" or \"%s\"" msgstr "" msgid "'%s' contains NA" msgstr "" msgid "'%s' has elements less than %d" msgstr "" #, fuzzy msgid "'%s' is not a non-negative number" msgstr "Länge muss eine nicht negative Zahl sein" msgid "'%s' has elements exceeding '%s'" msgstr "" msgid "'%s' is not %d or %d" msgstr "" #, fuzzy msgid "'%s' is not a permutation of seq_len(%s)" msgstr "'ncol' ist kein Faktor von length(x)" #, fuzzy msgid "matrix must have exactly one entry in each row or column" msgstr "muss genau einen Nicht-Null-Eintrag pro Zeile haben" #, fuzzy msgid "attempt to coerce non-square matrix to %s" msgstr "" "nicht symmetrische \"dgTMatrix\" kann nicht in \"dsCMatrix\" Klasse " "umgewandelt werden" #, fuzzy msgid "matrix must have exactly one entry in each row and column" msgstr "muss genau einen Nicht-Null-Eintrag pro Zeile haben" #, fuzzy msgid "'%s' via sparse -> dense coercion" msgstr "rcond(.) über Umwandlung dünn besetzt -> dicht besetzt" #, fuzzy msgid "invalid %s=\"%s\"" msgstr "ungültige nargs()= %d" msgid "norm" msgstr "" #, fuzzy msgid "'%s' method must use default %s=\"%s\"" msgstr "kronecker-Methode muss Standard 'FUN' benutzen" #, fuzzy msgid "number of nonzero entries cannot exceed %s" msgstr "Anzahl der Zeilen ist nicht kompatibel für %s" msgid "Matrix seems negative semi-definite" msgstr "Matrix scheint negativ semidefinit zu sein" msgid "'nearPD()' did not converge in %d iterations" msgstr "nearPD() ist nicht in %d Iterationen konvergiert" #, fuzzy msgid "'cl' is not a character string" msgstr "'V' ist keine *quadratische* Matrix" msgid "" "not a positive definite matrix (and positive semidefiniteness is not checked)" msgstr "" #, fuzzy msgid "'%s' is not a square numeric matrix" msgstr "'V' ist keine *quadratische* Matrix" #, fuzzy msgid "" "diag(%s) has non-positive or non-finite entries; finite result is doubtful" msgstr "" "diag(.) hatte 0 oder NA Einträge. Nicht-endliches Ergebnis ist zweifelhaft" msgid "non-conformable arguments" msgstr "nicht passende Argumente" msgid "" "matrix is structurally rank deficient; using augmented matrix with " "additional %d row(s) of zeros" msgstr "" msgid "" "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%2$s2\", \"%2$s2.\", \"%3$s\", " "\"%3$s1\", \"%4$s\", or \"%4$s1\"" msgstr "" #, fuzzy msgid "'%s' has the wrong length" msgstr "RHS 'b' hat falsche Länge" #, fuzzy msgid "invalid '%s': not in %d:%d" msgstr "ungültige 'col.names'-Zeichenkette: %s" msgid "need greater '%s' as pivoting occurred" msgstr "" msgid "qr2rankMatrix(.): QR with only %d out of %d finite diag(R) entries" msgstr "" "qr2rankMatrix(.): QR Zerlegung mit nur %d von %d endlichen diag(R) Werten" msgid "" "rankMatrix(, method = '%s') coerces to dense matrix.\n" " Probably should rather use method = 'qr' !?" msgstr "" "rankMatrix(, method = '%s') wird in dicht\n" "besetzte Matrix umgewandelt. Evtl. eher method = 'qr' nutzen? " msgid "rankMatrix(x, method='qr'): computing t(x) as nrow(x) < ncol(x)" msgstr "rankMatrix(x, method='qr'): t(x) berechnet, da nrow(x) < ncol(x)" #, fuzzy msgid "[[ suppressing %d column name%s %s ... ]]" msgstr "[[ unterdrücke %d Spaltennamen %s ...]]" msgid "invalid 'col.names' string: %s" msgstr "ungültige 'col.names'-Zeichenkette: %s" msgid "uniDiag=TRUE, but not all diagonal entries are 1" msgstr "uniDiag=TRUE, aber nicht alle Diagonaleinträge sind 1" msgid "uniDiag=TRUE, not all entries in diagonal coded as 1" msgstr "uniDiag=TRUE, aber nicht alle Einträge der Diagonalen als 1 kodiert" #, fuzzy msgid "in show(); maybe adjust options(max.print=, width=)" msgstr "in show(); evtl. 'options(max.print= *, width= *)' anpassen" msgid "suppressing %d columns and %d rows" msgstr "%d Spalten und %d Zeilen werden unterdrückt" msgid "suppressing %d rows" msgstr "%d Zeilen werden unterdrückt" msgid "suppressing %d columns" msgstr "%d Spalten werden unterdrückt" msgid "logic programming error in printSpMatrix2(), please report" msgstr "logischer Programmierfehler in printSpMatrix2(), bitte berichten" #, fuzzy msgid "'%s' is not square" msgstr "'V' ist keine quadratische Matrix" msgid "dimensions of '%s' and '%s' are inconsistent" msgstr "" msgid "'%1$s' is computationally singular, rcond(%1$s)=%2$g" msgstr "" msgid "'%s' is computationally singular, min(d)/max(d)=%g, d=abs(diag(U))" msgstr "" msgid "matrix is exactly singular, D[i,i]=0, i=%d" msgstr "" msgid "matrix is exactly singular, J[,j]=0, j=%d" msgstr "" msgid "matrix exactly singular, J[i,]=0, i=%d" msgstr "" msgid "cannot coerce from %s to %s" msgstr "" #, fuzzy msgid "model frame and formula mismatch in sparse.model.matrix()" msgstr "Model-Frame und Formel passen nicht zusammen in model.matrix()" #, fuzzy msgid "non-list contrasts argument ignored" msgstr "unzulässiges 'contrasts.arg' Argument" #, fuzzy msgid "'contrasts.arg' argument must be named" msgstr "unzulässiges 'contrasts.arg' Argument" msgid "variable '%s' is absent, its contrast will be ignored" msgstr "Variable '%s' fehlt, ihr Kontrast wird irgnoriert" msgid "a sparseMatrix should rarely be centered: will not be sparse anymore" msgstr "" "eine schwach besetze Matrix sollte kaum je zentriert werden: sie ist dann " "nicht mehr schwach besetzt" msgid "length of 'center' must equal the number of columns of 'x'" msgstr "Länge von 'center' muss der Spaltenzahl von 'x' entsprechen" msgid "length of 'scale' must equal the number of columns of 'x'" msgstr "Länge von 'scale' muss der Spaltenzahl von 'x' entsprechen" msgid "trimmed means are not defined for complex data" msgstr "" msgid "first element used of '%s' argument" msgstr "" #, fuzzy msgid "invalid '%s' argument" msgstr "ungültiges 'data'" #, fuzzy msgid "should never happen ..." msgstr "Sollte niemals vorkommen. Bitte berichten." msgid "'%s' is deprecated; using '%s' instead" msgstr "" msgid "'%s' is deprecated; setting %s=\"%s\"" msgstr "" msgid "" ".M.repl.i.2col(): 'i' has no integer column number;\n" " should never happen; please report" msgstr "" ".M.repl.i.2col(): 'i' hat keine ganzzahlige Spaltennummer.\n" "Sollte nie passieren. Bitte melden." msgid "such indexing must be by logical or 2-column numeric matrix" msgstr "" "solche Indexierung muss von logischer oder 2-spaltig numerischer Matrix sein" msgid ".M.repl.i.2col(): drop 'matrix' case ..." msgstr ".M.repl.i.2col(): 'matrix'-Fall weglassen ..." msgid "negative values are not allowed in a matrix subscript" msgstr "negative Werte sind in einer Matrix-Subskript nicht erlaubt" msgid "NAs are not allowed in subscripted assignments" msgstr "NAs sind in indexierten Anweisungen nicht erlaubt" msgid "number of items to replace is not a multiple of replacement length" msgstr "" "Anzahl der zu ersetzenden Elemente ist kein Vielfaches der Austauschlänge" msgid "m[ ] <- v: inefficiently treating single elements" msgstr "m[ ] <- v: Einzelne Elemente ineffizient behandelt" msgid "nargs() = %d. Extraneous illegal arguments inside '[ .. ]' ?" msgstr "nargs() = %d. Irrelevante ungültige Argumente innerhalb '[ .. ]'?" msgid "RHS 'value' (class %s) matches 'ANY', but must match matrix class %s" msgstr "" "RHS 'value' (Klasse %s) passt zu 'ANY', muss aber zur Matrixklasse %s passen" msgid "not-yet-implemented 'Matrix[<-' method" msgstr "noch nicht implementierte 'Matrix[<-'-Methode" msgid "invalid nargs()= %d" msgstr "ungültige nargs()= %d" msgid "nothing to replace with" msgstr "nichts zu ersetzen mit" msgid "too many replacement values" msgstr "zu viele Austauschwerte" msgid "i1[1] == 0 ==> C-level verbosity will not happen!" msgstr "i1[1] == 0 ==> C-Ebene wird nicht detailliert sein!" msgid "using\t \"old code\" part in Csparse subassignment" msgstr "benutzt wird\t 'alter Kode'-Teil in Csparse-Unterzuweisung" msgid "" "using\"old code\" part in Csparse subassignment\n" " >>> please report to Matrix-authors@r-project.org" msgstr "" "benutzt wird 'alter Kode'-Teil in Csparse-Unterzuweisung\n" " >>> bitte an Matrix-authors@r-project.org berichten" msgid "you cannot mix negative and positive indices" msgstr "Sie können positive und negative Indizes nicht mischen" msgid "index larger than maximal %d" msgstr "Index größer als maximales %d" msgid "'NA' indices are not (yet?) supported for sparse Matrices" msgstr "" "'NA'-Indizes werden (noch?) nicht für dünn besetzte Matrizen unterstützt" msgid "logical subscript too long (%d, should be %d)" msgstr "logisches Subskript zu lang (%d, sollte %d sein)" msgid "no 'dimnames[[.]]': cannot use character indexing" msgstr "keine 'dimnames[[.]]': Zeichenindexierung kann nicht benutzt werden" msgid "invalid character indexing" msgstr "ungültige Zeichenindexierung" msgid "internal bug: missing 'i' in replTmat(): please report" msgstr "interner Fehler: Fehlendes 'i' in replTmat(): Bitte berichten" msgid "[ ] indexing not allowed: forgot a \",\" ?" msgstr "[ ] Indexierung nicht erlaubt: Ein ',' vergessen?" msgid "internal bug: matrix 'i' in replTmat(): please report" msgstr "interner Fehler: Matrix 'i' in replTmat(): Bitte berichten" msgid "" "x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced; NA |--> TRUE." msgstr "" "x[.] <- val: x ist %s, val nicht in {TRUE, FALSE}, wird umgewandelt;\n" "NA |--> TRUE." msgid "x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced." msgstr "x[.] <- val: x ist %s, val nicht in {TRUE, FALSE}, wird umgewandelt." msgid "" "x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced NA |--> TRUE." msgstr "" "x[.,.] <- val: x ist %s, val nicht in {TRUE, FALSE} wird umgewandelt NA |--> " "TRUE." msgid "x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced." msgstr "x[.,.] <- val: x ist %s, val nicht in {TRUE, FALSE} wird umgewandelt" msgid "x[.,.] <- val : x being coerced from Tsparse* to CsparseMatrix" msgstr "x[.,.] <- val : x wird von Tsparse* in CsparseMatrix umgewandelt" msgid "nargs() = %d should never happen; please report." msgstr "nargs() = %d sollte niemals vorkommen. Bitte berichten." msgid "row indices must be <= nrow(.) which is %d" msgstr "Zeilenindizes müssen <= nrow(.) sein, das ist %d" msgid "column indices must be <= ncol(.) which is %d" msgstr "Spaltenindizes müssen <= ncol(.) sein, das ist %d" msgid "Internal bug: nargs()=%d; please report" msgstr "Interner Fehler: nargs()=%d; bitte melden" msgid "" "index must be numeric, logical or sparseVector for indexing sparseVectors" msgstr "" "Index muss numerisch, logisch oder sparseVector sein, um sparseVector zu " "indizieren" #, fuzzy msgid "invalid subscript class \"%s\"" msgstr "ungültige Klasse: %s" #, fuzzy msgid "invalid subscript type \"%s\"" msgstr "Ungültiger Speichertyp: %s" msgid "recycled %s would have maximal index exceeding %s" msgstr "" msgid "subscripts exceeding %s replaced with NA" msgstr "" msgid "subscript out of bounds" msgstr "" #, fuzzy msgid "logical subscript too long" msgstr "logisches Subskript zu lang (%d, sollte %d sein)" #, fuzzy msgid "incorrect number of dimensions" msgstr "inkompatible Matrixdimensionen" msgid "only zeros may be mixed with negative subscripts" msgstr "" msgid "'%s' has length 0 but '%s' does not" msgstr "" #, fuzzy msgid "attempt to coerce matrix with NA to %s" msgstr "" "nicht symmetrische \"dgTMatrix\" kann nicht in \"dsCMatrix\" Klasse " "umgewandelt werden" #, fuzzy msgid "invalid 'Class2'" msgstr "ungültiges 'data'" #~ msgid "qr2rankMatrix(.): QR has negative diag(R) entries" #~ msgstr "qr2rankMatrix(.): QR enthält negative diag(R) Werte" #, fuzzy #~ msgid "invalid 'each' argument" #~ msgstr "falsches Vorzeichen im Argument 'by'" #, fuzzy #~ msgid "invalid 'times' argument" #~ msgstr "ungültiges 'data'" #~ msgid "" #~ "not-yet-implemented method for %s(<%s>).\n" #~ " ->> Ask the package authors to implement the missing feature." #~ msgstr "" #~ "noch nicht implementierte Methode für %s(<%s>).\n" #~ " ->> Bitten Sie die Autoren des Pakets, diese fehlende Funktion zu " #~ "implementieren." #~ msgid "" #~ "not-yet-implemented method for %s(<%s>, <%s>).\n" #~ " ->> Ask the package authors to implement the missing feature." #~ msgstr "" #~ "noch nicht implementierte Methode für %s(<%s>, <%s>).\n" #~ " ->> Bitten Sie die Autoren des Pakets, diese fehlende Funktion zu " #~ "implementieren." #, fuzzy #~ msgid "complex \"diagonalMatrix\" not yet implemented" #~ msgstr "allgemeine Matrixklasse noch nicht implementiert für %s" #, fuzzy #~ msgid "not yet implemented for class \"%s\"" #~ msgstr "noch nicht implementiert für Klasse %s" #, fuzzy #~ msgid "invalid 'uplo'" #~ msgstr "ungültiger 'type'" #~ msgid "'lag' and 'differences' must be integers >= 1" #~ msgstr "'lag' und 'differences' müssen ganze Zahlen >=1 sein" #~ msgid "" #~ "programming error: min() should have dispatched w/ 1st arg much earlier" #~ msgstr "" #~ "Programmierfehler: min() ohne erstes Argument hätte eher abgefangen sein " #~ "müssen" #~ msgid "in Summary(, .): %s(<%s>, <%s>,...)" #~ msgstr "in Summary(, .): %s(<%s>, <%s>, ...)" #~ msgid "in Summary(, .): %s(<%s>, <%s>)" #~ msgstr "in Summary(, .): %s(<%s>, <%s>)" #, fuzzy #~ msgid "number of rows of matrices must match" #~ msgstr "Anzahl der Zeilen ist nicht kompatibel für %s" #, fuzzy #~ msgid "number of columns of matrices must match" #~ msgstr "Anzahl der Zeilen ist nicht kompatibel für %s" #~ msgid "resulting x-slot has different type than x's or y's" #~ msgstr "resultierender x-slot hat einen anderen Typ als x oder y" #, fuzzy #~ msgid "dimensions must be numeric of length 2" #~ msgstr "dim(.)-Wert muss numerisch sein und die Länge 2 haben" #, fuzzy #~ msgid "'perm' must be numeric" #~ msgstr "'A' muss eine quadratische Matrix sein" #, fuzzy #~ msgid "'margin' must be 1 or 2" #~ msgstr "'ncol' muss >= 0 sein" #~ msgid "not-yet-implemented method for <%s> %%*%% <%s>" #~ msgstr "noch nicht implementierte Methode für <%s> %%*%% <%s>" #~ msgid "'boolArith = %d' not yet implemented" #~ msgstr "'boolArith = %d' noch nicht implementiert" #, fuzzy #~ msgid "'rcond' via sparse -> dense coercion" #~ msgstr "rcond(.) über Umwandlung dünn besetzt -> dicht besetzt" #, fuzzy #~ msgid "invalid 'norm'" #~ msgstr "ungültiges 'data'" #, fuzzy #~ msgid "cannot coerce zsparseVector to dgCMatrix" #~ msgstr "'NA's können nicht in \"ngCMatrix\" umgewandelt werden" #, fuzzy #~ msgid "cannot coerce zsparseVector to dgeMatrix" #~ msgstr "Kann NAs nicht in 'nsparseVector' umwandeln" #~ msgid "" #~ "number of non zeros is smaller than 'nnz' because of duplicated (i,j)s" #~ msgstr "" #~ "Anzahl von Nicht-Nullen ist kleiner als 'nnz' wegen doppelter (i,j)s" #~ msgid "'times >= 0' is required" #~ msgstr "'times >= 0' wird benötigt" #~ msgid "Matrices must have same number of rows in %s" #~ msgstr "Matrizen müssen die gleiche Anzahl Zeilen in %s haben" #~ msgid "Matrices must have same number of columns in %s" #~ msgstr "Matrizen müssen die gleiche Anzahl Spalten in %s haben" #, fuzzy #~ msgid "only lists of length 2 can be coerced to indMatrix" #~ msgstr "'lMatrix'-Objekt mit NAs kann nicht zu 'nMatrix' umgewandelt werden" #, fuzzy #~ msgid "only 2-dimensional tables can be coerced to sparseMatrix" #~ msgstr "" #~ "nur 2-dimensionale Tabellen könne direkt in eine dünn besetzte Matrix " #~ "umgewandelt werden" #, fuzzy #~ msgid "matrix is not symmetric or" #~ msgstr "'x' ist weder symmetrisch noch in Dreiecksform" #, fuzzy #~ msgid "triangular" #~ msgstr "keine Dreiecksmatrix" #, fuzzy #~ msgid "matrix is not" #~ msgstr "Matrix ist nicht diagonal" #~ msgid "'x' is not positive definite -- chol() undefined." #~ msgstr "'x' ist nicht positiv definit -- chol() undefiniert." #~ msgid "Matrices must have same dimensions in %s" #~ msgstr "Matrizen müssen in %s die gleichen Dimensionen haben" #~ msgid "names(dimnames()) must be NULL or of length two" #~ msgstr "names(dimnames()) muss entweder NULL oder von Länge 2 sein" #~ msgid "[[ suppressing %d column names %s ]]" #~ msgstr "[[ unterdrücke %d Spaltennamen %s ]]" #~ msgid "'x' must be \"sparseMatrix\"" #~ msgstr "'x' muss \"sparseMatrix\" sein" #~ msgid "not yet implemented for matrix with typeof %s" #~ msgstr "noch nicht implementiert für Matrix mit typeof %s" #~ msgid "not yet implemented for %s" #~ msgstr "noch nicht implementiert für %s" #~ msgid "" #~ "Quadratic matrix '%s' (=: A) is not formally\n" #~ "\tsymmetric. Will be treated as\tA A'" #~ msgstr "" #~ "Die quadratische Matrix '%s' (=: A) ist formal\n" #~ " nicht symmetrisch. Wird behandelt wie A A'" #~ msgid "" #~ "'update' must be logical or '+' or '-'; 'C' a matrix, and 'L' a " #~ "\"CHMfactor\"" #~ msgstr "" #~ "'update' muss entweder boolesch, '+' oder '-' sein; 'C' eine Matrix\n" #~ "und 'L' ein \"CHMfactor\"" #~ msgid "update must be TRUE/FALSE or '+' or '-'" #~ msgstr "update muss entweder TRUE/FALSE, '+' oder '-' sein" #~ msgid "Matrix-internal error in [i,,d]; please report" #~ msgstr "Matrixinterner Fehler in [i,,d]. Bitte berichten" #~ msgid "" #~ "Cholesky() -> *symbolic* factorization -- not yet implemented" #~ msgstr "" #~ "Cholesky() -> *symbolische* Faktorisierung – noch nicht " #~ "implementiert" #~ msgid "" #~ "as.matrix() is deprecated (to become a no-op in the future).\n" #~ "Use as(x, \"matrix\") or .asmatrix(x) instead." #~ msgstr "" #~ "as.matrix() is veraltet (und zukünftig no-op).\n" #~ "Bitte as(x, \"matrix\") oder .asmatrix() stattdessen nutzen." #~ msgid "" #~ "as.array() is deprecated. Use as(x, \"matrix\") or .asmatrix(x) " #~ "instead." #~ msgstr "" #~ "as.array() ist veraltet. Bitte stattdessen as(x, \"matrix\") " #~ "oder .asmatrix(x) nutzen" #~ msgid "trimmed mean of 'sparseVector' -- suboptimally using as.numeric(.)" #~ msgstr "" #~ "getrimmter Mittelwert von 'sparseVector' – suboptimalerweise wird as." #~ "numeric(.) benutzt" #~ msgid "invalid dimnames given for %s object" #~ msgstr "ungültige dimnames für %s Objekt gegeben" #~ msgid "" #~ "dimnames(.) <- NULL: translated to \n" #~ "dimnames(.) <- list(NULL,NULL) <==> unname(.)" #~ msgstr "" #~ "dimnames(.) <- NULL: übersetzt in\n" #~ "dimnames(.) <- list(NULL,NULL) <==> unname(.)" #~ msgid "" #~ "'nrow', 'ncol', etc, are disregarded when 'data' is \"Matrix\" already" #~ msgstr "" #~ "'nrow', 'ncol', etc. werden nicht berücksichtigt, wenn 'data' bereits " #~ "'Matrix' ist" #~ msgid "complex matrices not yet implemented in Matrix package" #~ msgstr "komplexe Matrizen noch nicht im Matrix-Paket implementiert" #~ msgid "using slow kronecker() method" #~ msgstr "langsame kronecker()-Methode wird benutzt" #~ msgid "" #~ "Cholesky(A) called for 'A' of class \"%s\";\n" #~ "\t it is currently defined for sparseMatrix only; consider using chol() " #~ "instead" #~ msgstr "" #~ "Cholesky(A) für 'A' der Klasse \"%s\" aufgerufen;\n" #~ "\t es ist derzeit nur für sparseMatrix definiert; erwägen Sie, chol() zu " #~ "benutzen " #~ msgid "invalid or not-yet-implemented 'Matrix' subsetting" #~ msgstr "ungültige oder noch nicht implementierte 'Matrix'-Untermenge" #~ msgid "[ ] : .M.sub.i.logical() maybe inefficient" #~ msgstr "[ ] : .M.sub.i.logical() könnte ineffizient sein" #~ msgid "" #~ "nargs() = %d. Extraneous illegal arguments inside '[ .. ]' (i.logical)?" #~ msgstr "" #~ "nargs() = %d. Irrelevante ungültige Argumente innerhalb '[ .. ]' (i." #~ "logical)?" #~ msgid "" #~ "m[]: inefficiently indexing single elements - should not " #~ "happen, please report!" #~ msgstr "" #~ "m[ ]: ineffiziente Indexierung einzelner Elemente - sollte " #~ "nicht passieren, bitte rückmelden!" #~ msgid "" #~ "nargs() = %d. Extraneous illegal arguments inside '[ .. ]' (i.2col)?" #~ msgstr "" #~ "nargs() = %d. Irrelevante ungültige Argumente innerhalb '[ .. ]' (i.2col)?" #~ msgid "" #~ ".M.sub.i.2col(): 'i' has no integer column number;\n" #~ " should never happen; please report" #~ msgstr "" #~ ".M.sub.i.2col(): 'i' hat keine ganzzahlige Spaltennummer.\n" #~ "Sollte nie passieren. Bitte melden!" #~ msgid "not-yet-implemented coercion to \"TsparseMatrix\"" #~ msgstr "noch nicht implementierte Typumwandlung zu 'TsparseMatrix'" #~ msgid "Matrix-internal error in [i,,d]; please report" #~ msgstr "Matrix-interner Fehler in [i,,d]; Bitte berichten" #~ msgid "FIXME: NOT YET FINISHED IMPLEMENTATION" #~ msgstr "ZU ERLEDIGEN: NOCH NICHT ABGESCHLOSSENE IMPLEMENTIERUNG" #~ msgid "diagonalMatrix in .dense2C() -- should never happen, please report!" #~ msgstr "" #~ "diagonalMatrix in .dense2C() -- sollte niemals vorkommen. Bitte berichten." #~ msgid "undefined method for class %s" #~ msgstr "undefinierte Methode für Klasse %s" #~ msgid "dimensions don't match the number of cells" #~ msgstr "Dimensionen passen nicht zur Anzahl der Zellen" #~ msgid "" #~ "LU computationally singular: ratio of extreme entries in |diag(U)| = %9.4g" #~ msgstr "" #~ "Die LU Zerlegung ist computational singulär; Quotient der extremen " #~ "Elemente von |diag(U)| = %9.4g" #~ msgid "RHS 'b' has wrong number of rows:" #~ msgstr "RHS 'b' hat falsche Zahl Zeilen:" #~ msgid "'x' has invalid data type" #~ msgstr "'x' hat ungültigen Datentyp" #~ msgid "length(x) must be either 1 or #{cols}" #~ msgstr "length(x) muss 1 oder #{cols} sein" #~ msgid "some arguments are not matrices" #~ msgstr "einige Argumente sind keine Matrizen" #~ msgid "%s kind not yet implemented" #~ msgstr "%s-Art noch nicht implementiert" #~ msgid "non-square matrix" #~ msgstr "nicht quadratische Matrix" #~ msgid "" #~ "matrix with non-zero off-diagonals cannot be coerced to \"diagonalMatrix\"" #~ msgstr "" #~ "Matrix mit Nichtdiagonalelementen ungleich Null kann nicht in " #~ "\"diagonalMatrix\" umgewandelt werden" #~ msgid "non-matching dimensions" #~ msgstr "nicht passende Dimensionen" #~ msgid "not a positive definite matrix" #~ msgstr "keine positiv definite Matrix" #~ msgid "" #~ "as(.,\"dsCMatrix\") is deprecated (since 2008); do use as(., " #~ "\"symmetricMatrix\")" #~ msgstr "" #~ "as(.,\"dsCMatrix\") ist veraltet (seit 2008). Benutzen Sie as(., " #~ "\"symmetricMatrix\")" #~ msgid "inefficient coercion (lost triangularity); please report" #~ msgstr "ineffiziente Umwandlung (Dreiecksgestalt verloren). Bitte berichten" #~ msgid "coercion to \"indMatrix\" only works from integer numeric" #~ msgstr "" #~ "Umwandlung zu \"indMatrix\" funktioniert nur von ganzzahligen numerischen " #~ "Werten" #~ msgid "" #~ "coercion from list(i1,...,ik, d) to \"indMatrix\" failed.\n" #~ " All entries must be integer valued and the number of columns, d, not " #~ "smaller\n" #~ " than the maximal index i*." #~ msgstr "" #~ "Umwandlung von list(i1,...,ik, d) zu \"indMatrix\" gescheitert.\n" #~ " Alle Elemente müssen ganzzahlig sein und die Anzahl Spalten, d, nicht " #~ "kleiner\n" #~ " als der maximale Index i*." #~ msgid "the number of non-zero entries differs from nrow(.)" #~ msgstr "die Anzahl der Nicht-Null-Einträge weicht von nrow(.) ab" #~ msgid "resulting matrix dimension would be too large" #~ msgstr "Dimenson der Ergebnismatrix wäre zu groß" #~ msgid "replacing \"indMatrix\" entries is not allowed, as rarely sensible" #~ msgstr "" #~ "Ersetzen von \"indMatrix\"-Einträgen ist nicht erlaubt, da selten sinnvoll" #~ msgid "temporarily disabled" #~ msgstr "zeitweise ausgeschaltet" #~ msgid "cannot coerce NA values to pattern \"ntCMatrix\"" #~ msgstr "'NA's können nicht in \"ntCMatrix\" umgewandelt werden" #~ msgid "coercion to \"pMatrix\" only works from integer numeric" #~ msgstr "" #~ "Umwandlung zu \"pMatrix\" funktioniert nur von ganzzahligen numerischen " #~ "Werten" #~ msgid "not a square matrix" #~ msgstr "keine quadratische Matrix" #~ msgid "NA's in (i,j) are not allowed" #~ msgstr "NAs sind in (i,j) nicht erlaubt" #~ msgid "" #~ "Both 'symmetric' and 'triangular', i.e. asking for diagonal matrix. Use " #~ "'Diagonal()' instead" #~ msgstr "" #~ "Sowohl 'symmetric' als auch 'triangular', also Diagonalgestalt. Nutze\n" #~ " stattdessen 'Diagonal()'" #~ msgid "triangular matrix must have all i >= j or i <= j" #~ msgstr "Deicksmatrix muss entweder alle i >= j oder i <= j haben" #~ msgid "Matrix-internal error in [i,,d]; please report" #~ msgstr "Matrix-interner Fehler in [i,,d]. Bitte berichten" #~ msgid "" #~ "qr.R() may differ from qr.R() because of permutations. " #~ "Possibly use our qrR() instead" #~ msgstr "" #~ "qr.R() könnte von qr.R() aufgrund von Permutationen " #~ "abweichen. Evtl. besser qrR() nutzen." #~ msgid "(un)packing only applies to dense matrices, class(x)='%s'" #~ msgstr "" #~ "(ent)packen ist nur für dicht besetzte Matrizen anwendbar, class(x)='%s'" #, fuzzy #~ msgid "'x' is not symmetric -- chol() undefined." #~ msgstr "'x' ist nicht positiv definit -- chol() undefiniert." #~ msgid "" #~ "extra argument %s will be disregarded in\n" #~ " %s" #~ msgid_plural "" #~ "extra arguments %s will be disregarded in\n" #~ " %s" #~ msgstr[0] "extra Argument %s wird nicht berücksichtigt in %s" #~ msgstr[1] "extra Argumente %s werden nicht berücksichtigt in %s" #~ msgid " %s %s is undefined" #~ msgstr " %s %s ist undefiniert" #~ msgid "%s %s is undefined" #~ msgstr "%s %s ist undefiniert" #~ msgid "variable '%s' converted to a factor" #~ msgstr "Variable '%s' konvertiert in einen Faktor" #~ msgid "\"dMatrix\" object with NAs cannot be coerced to \"nMatrix\"" #~ msgstr "" #~ "\"dMatrix\"-Objekt mit NAs kann nicht in \"nMatrix\" umgewandelt werden" #~ msgid "not a skinny matrix" #~ msgstr "keine lange (\"skinny\") Matrix" #~ msgid "longer object length" #~ msgstr "längere Objektlänge" #~ msgid "is not a multiple of shorter object length" #~ msgstr "ist kein Vielfaches der kürzeren Objektlänge" #~ msgid "duplicate ij-entries in 'Matrix[ ij ] <- value'; using last" #~ msgstr "" #~ "doppelte ij-Einträge in 'Matrix[ IJ ] <- value'. Letzter wird benutzt" #, fuzzy #~ msgid "method %s not applicable for qr() result class %s" #~ msgstr "Methode '%s' nicht nutzbar für das qr() Ergebniss der Klasse '%s'" #, fuzzy #~ msgid "too large index i > n = %d" #~ msgstr "zu großer Index i > n =" #~ msgid "," #~ msgstr "," #~ msgid "..." #~ msgstr "..." #~ msgid "arguments" #~ msgstr "Argumente" #~ msgid ")$" #~ msgstr ")$" #~ msgid "^list\\(" #~ msgstr "^list\\\\(" #~ msgid "dimnames(.) <- NULL: translated to" #~ msgstr "dimnames(.) <- NULL: übersetzt zu" #~ msgid ", ..." #~ msgstr ", ..." #~ msgid "" #~ msgstr "" #~ msgid "(0) is undefined" #~ msgstr "(0) ist undefiniert" #~ msgid "(0)" #~ msgstr "(0)" #~ msgid "no longer representable as 'rleDiff'" #~ msgstr "nicht länger als 'rleDiff' darstellbar" #~ msgid "hence, all k must have the same sign" #~ msgstr "daher müssen alle k das Zeichen haben" #~ msgid "too short; filling with NA's" #~ msgstr "zu kurz. Wird mit NAs gefüllt" #~ msgid "iterations" #~ msgstr "Iterationen" #~ msgid "'" #~ msgstr "'" #~ msgid "; please report" #~ msgstr ". Bitte berichten" #~ msgid "type '" #~ msgstr "Typ '" #~ msgid "representation '" #~ msgstr "Entsprechung '" #~ msgid "element type '" #~ msgstr "Elementtyp '" #~ msgid "symmetry form '" #~ msgstr "symmetrische Form '" #~ msgid "numeric()" #~ msgstr "numeric()" #~ msgid "must supply either 'formula' or 'data'" #~ msgstr "entweder 'formula' oder 'data' muss angegeben werden" #~ msgid "'formula' missing or incorrect" #~ msgstr "'formula' fehlt oder ist falsch" #~ msgid "interactions are not allowed" #~ msgstr "Wechselwirkungen sind nicht erlaubt" #~ msgid "xtabs(*, sparse=TRUE) applies only to two-way tables" #~ msgstr "xtabs(*, sparse=TRUE) liefert nur wechselseitige Tabellen" #~ msgid "cbind2() method for (%s,%s) not-yet defined" #~ msgstr "cbind2()-Methode für (%s,%s) noch nicht definiert" #~ msgid "not yet implemented for packed class" #~ msgstr "noch nicht für gepackte Klasse implementiert" #~ msgid "numeric(0)" #~ msgstr "numeric(0)" #~ msgid "'NA's coerced to 'FALSE' in coercion to logical sparse" #~ msgstr "'NA's zu 'FALSE' umwandeln in Umwandlung zu logisch dünne besetzt" #~ msgid "crossprod(x) calculated as x %*% x for sparse, symmetric x" #~ msgstr "" #~ "crossprod(x) berechnete als x %*% x für dünn besetztes,symmetrisches x" #~ msgid "tcrossprod(x) calculated as x %*% x for sparse, symmetric x" #~ msgstr "" #~ "tcrossprod(x) berechnete als x %*% x für dünn besetztes,symmetrisches x" #~ msgid "(j,p) --> RsparseMatrix : not yet implemented" #~ msgstr "(j,p) --> RsparseMatrix : Noch nicht implementiert" #~ msgid "unknown method" #~ msgstr "unbekannte Methode" #~ msgid "indexing out of range 0:" #~ msgstr "Indexierung außerhalb des Bereichs 0:" #~ msgid "nargs() =" #~ msgstr "nargs() =" #~ msgid "nrow * ncol < length(x)" #~ msgstr "'nrow' * ncol < length(x)" #~ msgid "nrow * ncol != length(x)" #~ msgstr "'nrow' * ncol != length(x)" Matrix/po/R-it.po0000644000176200001440000012224614521047060013315 0ustar liggesusers# R Italian translation # This file is distributed under the same license as the R package. # Copyright (C) The R Foundation. # Daniele Medri , 2005-2021. # msgid "" msgstr "" "Project-Id-Version: R-Matrix 1.3-3\n" "Report-Msgid-Bugs-To: bugs.r-project.org\n" "POT-Creation-Date: 2023-11-02 21:33\n" "PO-Revision-Date: 2021-04-14 12:18+0200\n" "Last-Translator: Daniele Medri \n" "Language-Team: Italian https://github.com/dmedri/R-italian-lang\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 2.2.1\n" #, fuzzy msgid "invalid mode \"%s\"" msgstr "'mod' non valido: %s" msgid "" "%s(<%s>, <%s>) is not yet implemented; ask maintainer(\"%s\") to implement " "the missing method" msgstr "" #, fuzzy msgid "complex %s not yet implemented" msgstr "La classe %s non è ancora implementata" #, fuzzy msgid "cannot coerce matrix of type \"%s\" to %s" msgstr "non è possibile la coercizione degli 'NA' in \"nsparseMatrix\"" #, fuzzy msgid "non0.i() not yet implemented for class %s" msgstr "non ancora implementato per la classe %s" msgid "%s=\"%s\" invalid for %s@uplo=\"%s\"" msgstr "" msgid "'%s' is not \"%1$s\", \"D%1$s\", or \"%1$s.\"" msgstr "" msgid "unexpected %s=\"%s\" in '%s' method" msgstr "" msgid "Not a valid format" msgstr "Non è un formato valido" msgid "'file' must be a character string or connection" msgstr "'file' dev'essere una stringa di caratteri o una connessione" msgid "Invalid storage type: %s" msgstr "Tipo di archiviazione non valido: %s" msgid "Only numeric sparse matrices allowed" msgstr "Sono ammesse solo matrici sparse numeriche" msgid "Invalid storage format: %s" msgstr "Formato di archiviazione non valido: %s" msgid "Invalid assembled indicator: %s" msgstr "Indicatore assemblato non valido:%s" msgid "file is not a MatrixMarket file" msgstr "il file non è un file MatrixMarket" msgid "type '%s' not recognized" msgstr "il tipo '%s' non è riconosciuto" msgid "representation '%s' not recognized" msgstr "rappresentazione '%s' non riconosciuta" msgid "element type '%s' not recognized" msgstr "tipo elemento '%s' non riconosciuto" msgid "symmetry form '%s' not recognized" msgstr "la forma di simmetria '%s' non è riconosciuta" msgid "readMM(): expected %d entries but found only %d" msgstr "" #, fuzzy msgid "readMM(): row indices 'i' are not in 1:nrow[=%d]" msgstr "readMM(): valori della\t riga 'i' non sono in 1:nr" #, fuzzy msgid "readMM(): column indices 'j' are not in 1:ncol[=%d]" msgstr "readMM(): i valori della colonna 'j' non sono in 1:nc" msgid "symmetry form 'skew-symmetric' not yet implemented for reading" msgstr "" "la forma di simmetria 'skew-symmetric' non è ancora implementata in lettura" msgid "symmetry form 'hermitian' not yet implemented for reading" msgstr "la forma di simmetria 'hermitian' non è ancora implementata in lettura" msgid "symmetry form '%s' is not yet implemented" msgstr "la forma di simmetria '%s' non è ancora implementata" msgid "element type 'complex' not yet implemented" msgstr "tipo di elemento 'complex' non ancora implementato" msgid "'%s()' is not yet implemented for element type '%s'" msgstr "'%s()' non è ancora implementato per il tipo elemento '%s'" msgid "'%s()' is not yet implemented for representation '%s'" msgstr "'%s()' non è ancora implementato per la rappresentazione '%s'" msgid "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%3$s\", or \"%4$s\"" msgstr "" msgid "" "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%2$s2\", \"%2$s2.\", \"%3$s\", or " "\"%4$s\"" msgstr "" msgid "longer object length is not a multiple of shorter object length" msgstr "" "la lunghezza più lunga dell'oggetto non è un multiplo della lunghezza più " "corta dell'oggetto" #, fuzzy msgid "invalid class \"%s\" in '%s' method" msgstr "stringa 'col.names' non valida: %s" msgid "invalid type \"%s\" in '%s' method" msgstr "" msgid "non-conformable matrix dimensions in %s" msgstr "dimensioni matrice non conformi in %s" msgid "dimnames [%d] mismatch in %s" msgstr "dimnames [%d] non corrisponde in %s" msgid "inefficient method used for \"- e1\"" msgstr "utilizzato metodo inefficiente per \"- e1\"" msgid "dim [product %d] do not match the length of object [%d]" msgstr "dim [product %d] non corrisponde con la lunghezza dell'oggetto [%d]" msgid "internal bug in \"Compare\" method (Cmp.Mat.atomic); please report" msgstr "" "bug interno nel metodo \"Compare\" (Cmp.Mat.atomic); per piacere, riportatelo" msgid "Cmp.Mat.atomic() should not be called for diagonalMatrix" msgstr "Cmp.Mat.atomic() non dovrebbe essere chiamata per diagonalMatrix" msgid "Matrices must have same number of rows for arithmetic" msgstr "Le matrici devono avere il medesimo numero di righe per l'aritmetica" msgid "number of rows are not compatible for %s" msgstr "il numero di righe non sono compatibili per %s" msgid "length of 2nd arg does not match dimension of first" msgstr "" "la lunghezza del secondo argomento non corrisponde con la dimensione del " "primo" msgid "length of 1st arg does not match dimension of 2nd" msgstr "" "la lunghezza del primo argomento non corrisponde con la dimensione della " "seconda" msgid "internal bug in \"Logic\" method (Logic.Mat.atomic); please report" msgstr "" "bug interno nel metodo \"Logic\" (Logic.Mat.atomic); per piacere, segnalatelo" msgid "Logic.Mat.atomic() should not be called for diagonalMatrix" msgstr "Logic.Mat.atomic() non dovrebbe essere chiamato per diagonalMatrix" msgid "vector too long in Matrix - vector operation" msgstr "vettore troppo lungo in Matrix - operazione vettoriale" msgid "" "longer object length\n" "\tis not a multiple of shorter object length" msgstr "" "la lunghezza dell'oggetto più lungo\n" "\tnon è un multiplo di lunghezza di quello più corto" msgid "intermediate 'r' is of type %s" msgstr "la 'r' intermedia è di tipo %s" msgid "not yet implemented .. please report" msgstr "non ancora implementato .. per piacere riportalo" msgid "'force' must be (coercable to) TRUE or FALSE" msgstr "'force' dev'essere (coercibile in) TRUE o FALSE" msgid "invalid (to - from)/by in seq(.)" msgstr "(to - from)/by in seq(.) non valido" msgid "wrong sign in 'by' argument" msgstr "segno errato nell'argomento 'by'" msgid "'by' argument is much too small" msgstr "l'argomento 'by' è troppo piccolo" msgid "length must be non-negative number" msgstr "la lunghezza dev'essere un numero non negativo" msgid "too many arguments" msgstr "troppi argomenti" msgid "c(,..) of different kinds, coercing all to 'rleDiff'" msgstr "c(,..) di diverso tipo, convertendo tutto a 'rleDiff'" msgid "[i] is not yet implemented" msgstr "[i] non è ancora implementato" msgid "all() is not yet implemented" msgstr "all() non è ancora implementato" msgid "sum() is not yet implemented" msgstr "sum() non è ancora implementato" msgid "prod() is not yet implemented" msgstr "prod() non è ancora implementato" msgid "not yet implemented" msgstr "non ancora implementato" msgid "" "x / 0 for an x with sign-change\n" " no longer representable as 'rleDiff'" msgstr "" "x / 0 per un x con cambio di segno\n" " non è più rappresentabile come 'rleDiff'" msgid " --> is not yet implemented" msgstr " --> non è ancora implementato" msgid " --> is not yet implemented" msgstr " --> non è ancora implementato" #, fuzzy msgid "%1$s(%2$s) is undefined: '%2$s' is not positive semidefinite" msgstr "chol() non è definito per una matrice diagonale con voci negative" #, fuzzy msgid "matrix is not square" msgstr "la matrice non è diagonale" msgid "" "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%3$s\", \"%3$s.\", \"%3$s1\", \"%3$s1." "\", or \"%4$s\"" msgstr "" #, fuzzy msgid "'%s' does not inherit from virtual class %s" msgstr "'x' deve ereditare da \"sparseVector\"" msgid "D[i,i] is NA, i=%d" msgstr "" msgid "D[i,i] is negative, i=%d" msgstr "" msgid "'%1$s' is not formally symmetric; factorizing tcrossprod(%1$s)" msgstr "" #, fuzzy msgid "matrix is not symmetric; consider forceSymmetric(.) or symmpart(.)" msgstr "" "non è una matrice simmetrica; si consideri forceSymmetric() o symmpart()" #, fuzzy msgid "matrix is not triangular; consider triu(.) or tril(.)" msgstr "la matrice non è triangolare" msgid "matrix is not diagonal; consider Diagonal(x=diag(.))" msgstr "" #, fuzzy msgid "invalid type \"%s\" in '%s'" msgstr "'type' non valido" #, fuzzy msgid "invalid %s=\"%s\" to '%s'" msgstr "Tipo di archiviazione non valido: %s" msgid "dimensions cannot exceed %s" msgstr "" #, fuzzy msgid "invalid class \"%s\" in '%s'" msgstr "stringa 'col.names' non valida: %s" msgid "%s length cannot exceed %s" msgstr "" msgid "'A' must be a square matrix" msgstr "'A' dev'essere una matrice quadrata" msgid "must either specify 'A' or the functions 'A.x' and 'At.x'" msgstr "si deve specificare 'A' o le funzioni 'A.x' e 'At.x'" msgid "when 'A' is specified, 'A.x' and 'At.x' are disregarded" msgstr "quando 'A' è specificato, 'A.x' e 'At.x' sono ignorati" msgid "not converged in %d iterations" msgstr "non convergente in %d iterazioni" msgid "hit a cycle (1) -- stop iterations" msgstr "fine ciclo (1) - interrompe le iterazioni" msgid "hit a cycle (2) -- stop iterations" msgstr "fine ciclo (2) - interrompe le iterazioni" msgid "not enough new vecs -- stop iterations" msgstr "non ci sono abbastanza nuovi vettori -- si interrompono le iterazioni" msgid "invalid 'data'" msgstr "'data' non valido" #, fuzzy msgid "'nrow', 'ncol', 'byrow' disregarded for [mM]atrix 'data'" msgstr "'nrow', 'ncol' e gli altri, sono ignorati dai dati della matrice" msgid "data is too long" msgstr "" #, fuzzy msgid "exactly one of 'i', 'j', and 'p' must be missing from call" msgstr "uno tra 'i', 'j' o 'p' non deve essere presente nella chiamata" msgid "" "use Diagonal() to construct diagonal (symmetric && triangular) sparse " "matrices" msgstr "" #, fuzzy msgid "'giveCsparse' is deprecated; using 'repr' instead" msgstr "'giveCsparse' è stato deprecato; si utilizzerà 'repr'" #, fuzzy msgid "'giveCsparse' is deprecated; setting repr=\"T\" for you" msgstr "'giveCsparse' è stato deprecato; viene impostato 'repr = \"T\"'" #, fuzzy msgid "'p' must be a nondecreasing vector c(0, ...)" msgstr "'p' dev'essere un vettore non decrescente (0, ...)" msgid "dimensions cannot exceed 2^31-1" msgstr "" msgid "'i' and 'j' must not contain NA" msgstr "" msgid "'i' and 'j' must be" msgstr "" msgid "positive" msgstr "" msgid "non-negative" msgstr "" #, fuzzy msgid "invalid 'dims'" msgstr "'data' non valido" msgid "'dims' must contain all (i,j) pairs" msgstr "" msgid "symmetric matrix must be square" msgstr "la matrice simmetrica dev'esser quadrata" msgid "triangular matrix must be square" msgstr "la matrice triangolare dev'esser quadrata" msgid "p[length(p)]" msgstr "" msgid "length(i)" msgstr "" #, fuzzy msgid "is not an integer multiple of length(x)" msgstr "length(i) non è un multiplo di length(x)" msgid "length(x) must not exceed" msgstr "" #, fuzzy msgid "invalid 'repr'; must be \"C\", \"R\", or \"T\"" msgstr "'repr' non valido; dev'essere \"C\", \"T\", o \"R\"" #, fuzzy msgid "'n' must be a non-negative integer" msgstr "la lunghezza dev'essere un numero non negativo" msgid "'x' has unsupported class \"%s\"" msgstr "" msgid "'x' has unsupported type \"%s\"" msgstr "" msgid "attempt to recycle 'x' of length 0 to length 'n' (n > 0)" msgstr "" msgid "'shape' must be one of \"g\", \"t\", \"s\"" msgstr "" #, fuzzy msgid "'kind' must be one of \"d\", \"l\", \"n\"" msgstr "'repr' non valido; dev'essere \"C\", \"T\", o \"R\"" msgid "mismatch between typeof(x)=\"%s\" and kind=\"%s\"; using kind=\"%s\"" msgstr "" #, fuzzy msgid "'cols' must be numeric" msgstr "'ncol' dev'essere >= 0" msgid "'cols' has elements not in seq(0, length.out = n)" msgstr "" #, fuzzy msgid "'uplo' must be \"U\" or \"L\"" msgstr "'repr' non valido; dev'essere \"C\", \"T\", o \"R\"" #, fuzzy msgid "'lst' must be a list" msgstr "'ncol' dev'essere >= 0" msgid "'giveCsparse' has been deprecated; setting 'repr = \"T\"' for you" msgstr "'giveCsparse' è stato deprecato; viene impostato 'repr = \"T\"'" msgid "'giveCsparse' has been deprecated; will use 'repr' instead" msgstr "'giveCsparse' è stato deprecato; si utilizzerà 'repr'" msgid "'diagonals' matrix must have %d columns (= length(k) )" msgstr "la matrice 'diagonals' deve avere %d colonne (= length(k) )" msgid "'diagonals' must have the same length (%d) as 'k'" msgstr "'diagonals' deve avere la medesima lunghezza (%d) di 'k'" msgid "matrix can only be symmetric if square, but n != m" msgstr "la matrice può essere unicamente simmetrica se quadrata, ma n != m" msgid "" "for symmetric band matrix, only specify upper or lower triangle\n" " hence, all k must have the same sign" msgstr "" "per la matrice di bande simmetriche, specificare solo il triangolo superiore " "o inferiore\n" " poi, tutti i k devono avere lo stesso segno" msgid "the %d-th (sub)-diagonal (k = %d) is too short; filling with NA's" msgstr "la %d' (sotto)-diagonale (k = %d) è troppo corta; si riempie con NA" msgid "invalid 'repr'; must be \"C\", \"T\", or \"R\"" msgstr "'repr' non valido; dev'essere \"C\", \"T\", o \"R\"" msgid "'x' must inherit from \"sparseVector\"" msgstr "'x' deve ereditare da \"sparseVector\"" msgid "'ncol' must be >= 0" msgstr "'ncol' dev'essere >= 0" msgid "'nrow' must be >= 0" msgstr "'nrow' dev'essere >= 0" msgid "Must specify 'nrow' when 'symmetric' is true" msgstr "Bisogna specificare 'nrow' quando 'symmetric' è true" msgid "'nrow' and 'ncol' must be the same when 'symmetric' is true" msgstr "'nrow' e 'ncol' dev'essere uguali quando 'symmetric' è true" msgid "'x' must have length nrow^2 when 'symmetric' is true" msgstr "'x' deve avere lunghezza nrow^2 quando 'symmetric' è true" msgid "'ncol' is not a factor of length(x)" msgstr "'ncol' non è un fattore di length(x)" msgid "'nrow' is not a factor of length(x)" msgstr "'nrow' non è un fattore di length(x)" msgid "Class %s is not yet implemented" msgstr "La classe %s non è ancora implementata" #, fuzzy msgid "'%s' and '%s' must be positive integers" msgstr "la lunghezza dev'essere un numero non negativo" #, fuzzy msgid "matrix is not symmetric or triangular" msgstr "'x' non è simmetrica ne triangolare" #, fuzzy msgid "matrix is not symmetric" msgstr "la matrice non è triangolare" #, fuzzy msgid "matrix is not triangular" msgstr "'x' non è simmetrica ne triangolare" msgid "" "the default value of argument '%s' of method '%s(<%s>, <%s>)' may change " "from %s to %s as soon as the next release of Matrix; set '%s' when " "programming" msgstr "" msgid "determinant of non-square matrix is undefined" msgstr "" msgid "replacement diagonal has wrong length" msgstr "" msgid "replacement diagonal has incompatible type \"%s\"" msgstr "" msgid "assigned dimensions are not of type \"%s\" or \"%s\"" msgstr "" msgid "assigned dimensions do not have length %d" msgstr "" msgid "assigned dimensions are NA" msgstr "" msgid "assigned dimensions are negative" msgstr "" msgid "assigned dimensions exceed %s" msgstr "" #, fuzzy msgid "assigned dimensions [product %.0f] do not match object length [%.0f]" msgstr "dim [product %d] non corrisponde con la lunghezza dell'oggetto [%d]" msgid "'%s' has non-finite values" msgstr "" msgid "'%1$s' is not \"%2$s\", \"%3$s\", or \"%2$s.\"" msgstr "" #, fuzzy msgid "only square matrices can be used as graph incidence matrices" msgstr "" "solo le matrici quadrate possono essere utilizzate come matrici di incidenza " "per i grafici" msgid "'lwd' must be NULL or non-negative numeric" msgstr "'lwd' dev'essere NULL o un numerico non negativo" #, fuzzy msgid "%s(<%s>) is not yet implemented" msgstr "La classe %s non è ancora implementata" msgid "'%s' is not of type \"%s\" or \"%s\"" msgstr "" msgid "'%s' contains NA" msgstr "" msgid "'%s' has elements less than %d" msgstr "" #, fuzzy msgid "'%s' is not a non-negative number" msgstr "la lunghezza dev'essere un numero non negativo" msgid "'%s' has elements exceeding '%s'" msgstr "" msgid "'%s' is not %d or %d" msgstr "" #, fuzzy msgid "'%s' is not a permutation of seq_len(%s)" msgstr "'ncol' non è un fattore di length(x)" #, fuzzy msgid "matrix must have exactly one entry in each row or column" msgstr "deve avere esattamente una voce non zero per riga" #, fuzzy msgid "attempt to coerce non-square matrix to %s" msgstr "" "non è possibile convertire la classe \"dgTMatrix\" non simmetrica nella " "classe \"dsCMatrix\"" #, fuzzy msgid "matrix must have exactly one entry in each row and column" msgstr "deve avere esattamente una voce non zero per riga" #, fuzzy msgid "'%s' via sparse -> dense coercion" msgstr "rcond (.) con coercizione sparsa -> densa" #, fuzzy msgid "invalid %s=\"%s\"" msgstr "nargs()= %d non valido" msgid "norm" msgstr "" #, fuzzy msgid "'%s' method must use default %s=\"%s\"" msgstr "il metodo di kronecker deve utilizzare in maniera predefinita 'FUN'" #, fuzzy msgid "number of nonzero entries cannot exceed %s" msgstr "il numero di righe non sono compatibili per %s" msgid "Matrix seems negative semi-definite" msgstr "Matrix sembra semi-definito negativo" msgid "'nearPD()' did not converge in %d iterations" msgstr "'nearPD()' non converge in %d iterazioni" #, fuzzy msgid "'cl' is not a character string" msgstr "'V' non è una matrice quadrata" msgid "" "not a positive definite matrix (and positive semidefiniteness is not checked)" msgstr "" #, fuzzy msgid "'%s' is not a square numeric matrix" msgstr "'V' non è una matrice quadrata" #, fuzzy msgid "" "diag(%s) has non-positive or non-finite entries; finite result is doubtful" msgstr "diag(.) ha 0 o voci NA; un risultato non-finito è incerto" msgid "non-conformable arguments" msgstr "gli argomenti non sono compatibili" msgid "" "matrix is structurally rank deficient; using augmented matrix with " "additional %d row(s) of zeros" msgstr "" msgid "" "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%2$s2\", \"%2$s2.\", \"%3$s\", " "\"%3$s1\", \"%4$s\", or \"%4$s1\"" msgstr "" #, fuzzy msgid "'%s' has the wrong length" msgstr "RHS 'b' ha una lunghezza errata" #, fuzzy msgid "invalid '%s': not in %d:%d" msgstr "stringa 'col.names' non valida: %s" msgid "need greater '%s' as pivoting occurred" msgstr "" msgid "qr2rankMatrix(.): QR with only %d out of %d finite diag(R) entries" msgstr "" "qr2rankMatrix(.): QR con solo %d elementi fuori dai %d finiti di diag(R)" msgid "" "rankMatrix(, method = '%s') coerces to dense matrix.\n" " Probably should rather use method = 'qr' !?" msgstr "" "rankMatrix(, method = '%s') convertito in matrice " "densa.\n" " Non si dovrebbe provare method = 'qr' !?" msgid "rankMatrix(x, method='qr'): computing t(x) as nrow(x) < ncol(x)" msgstr "rankMatrix(x, method='qr'): calcolando t(x) come nrow(x) < ncol(x)" #, fuzzy msgid "[[ suppressing %d column name%s %s ... ]]" msgstr "[[ suppressing %d column names %s ... ]]" msgid "invalid 'col.names' string: %s" msgstr "stringa 'col.names' non valida: %s" msgid "uniDiag=TRUE, but not all diagonal entries are 1" msgstr "uniDiag=TRUE, ma non tutte le voci diagonali sono 1" msgid "uniDiag=TRUE, not all entries in diagonal coded as 1" msgstr "uniDiag=TRUE, non tutte le voci in diagonale codificate come 1" #, fuzzy msgid "in show(); maybe adjust options(max.print=, width=)" msgstr "in show(); si dovrebbe aggiustare 'options(max.print= *, width = *)'" msgid "suppressing %d columns and %d rows" msgstr "soppresse %d colonne e %d righe" msgid "suppressing %d rows" msgstr "soppresse %d righe" msgid "suppressing %d columns" msgstr "soppresse %d colonne" msgid "logic programming error in printSpMatrix2(), please report" msgstr "" "errore di programmazione logica in printSpMatrix2(), per piacere, riportatelo" #, fuzzy msgid "'%s' is not square" msgstr "'V' non è una matrice quadrata" msgid "dimensions of '%s' and '%s' are inconsistent" msgstr "" msgid "'%1$s' is computationally singular, rcond(%1$s)=%2$g" msgstr "" msgid "'%s' is computationally singular, min(d)/max(d)=%g, d=abs(diag(U))" msgstr "" msgid "matrix is exactly singular, D[i,i]=0, i=%d" msgstr "" msgid "matrix is exactly singular, J[,j]=0, j=%d" msgstr "" msgid "matrix exactly singular, J[i,]=0, i=%d" msgstr "" msgid "cannot coerce from %s to %s" msgstr "" #, fuzzy msgid "model frame and formula mismatch in sparse.model.matrix()" msgstr "model frame e formula non corrispondono in model.matrix()" #, fuzzy msgid "non-list contrasts argument ignored" msgstr "argomento 'contrasts.arg' non valido" #, fuzzy msgid "'contrasts.arg' argument must be named" msgstr "argomento 'contrasts.arg' non valido" msgid "variable '%s' is absent, its contrast will be ignored" msgstr "variabile '%s' assente, i suoi contrasti saranno ignorati" msgid "a sparseMatrix should rarely be centered: will not be sparse anymore" msgstr "" "una sparseMatrix dovrebbe essere raramente centrata: non sarà più sparsa." msgid "length of 'center' must equal the number of columns of 'x'" msgstr "la lunghezza di 'center' deve eguagliare il numero di colonne di 'x'" msgid "length of 'scale' must equal the number of columns of 'x'" msgstr "la lunghezza di 'scale' deve eguagliare il numero di colonne di 'x'" msgid "trimmed means are not defined for complex data" msgstr "" msgid "first element used of '%s' argument" msgstr "" #, fuzzy msgid "invalid '%s' argument" msgstr "'data' non valido" msgid "should never happen ..." msgstr "" #, fuzzy msgid "'%s' is deprecated; using '%s' instead" msgstr "'giveCsparse' è stato deprecato; si utilizzerà 'repr'" #, fuzzy msgid "'%s' is deprecated; setting %s=\"%s\"" msgstr "'giveCsparse' è stato deprecato; viene impostato 'repr = \"T\"'" msgid "" ".M.repl.i.2col(): 'i' has no integer column number;\n" " should never happen; please report" msgstr "" ".M.repl.i.2col(): 'i' non ha un numero di colonna intero;\n" " non dovrebbe mai accadere; per piacere, segnalatelo" msgid "such indexing must be by logical or 2-column numeric matrix" msgstr "" "tale indicizzazione dev'essere per matrice logica o numerica a 2 colonne" msgid ".M.repl.i.2col(): drop 'matrix' case ..." msgstr ".M.repl.i.2col(): si elimina il caso 'matrix' ..." msgid "negative values are not allowed in a matrix subscript" msgstr "valori negativi non ammessi in subscript di matrice" msgid "NAs are not allowed in subscripted assignments" msgstr "NA non ammessi nelle assegnazioni subscript" msgid "number of items to replace is not a multiple of replacement length" msgstr "" "il numero di articoli da sostituire non è un multiplo della lunghezza di " "sostituzione" msgid "m[ ] <- v: inefficiently treating single elements" msgstr "m[ ] <- v: trattamento inefficiente dei singoli elementi" msgid "nargs() = %d. Extraneous illegal arguments inside '[ .. ]' ?" msgstr "nargs() = %d. Argomenti illegali estranei all'interno di '[ .. ]' ?" msgid "RHS 'value' (class %s) matches 'ANY', but must match matrix class %s" msgstr "" "RHS 'value' (classe %s) corrisponde a 'ANY', ma deve corrispondere ad una " "classe di matrice %s" msgid "not-yet-implemented 'Matrix[<-' method" msgstr "metodo 'Matrix[<-' non ancora implementato" msgid "invalid nargs()= %d" msgstr "nargs()= %d non valido" msgid "nothing to replace with" msgstr "niente da sostituire" msgid "too many replacement values" msgstr "troppi valori di sostituzione" msgid "i1[1] == 0 ==> C-level verbosity will not happen!" msgstr "i1[1] == 0 ==> la verbosità a livello C non accadrà!" msgid "using\t \"old code\" part in Csparse subassignment" msgstr "" "si utilizza\t una parte di \"vecchio codice\" nel sotto-assegnamento Csparse" msgid "" "using\"old code\" part in Csparse subassignment\n" " >>> please report to Matrix-authors@r-project.org" msgstr "" "si utilizza una parte di \"vecchio codice\" nel sotto-assegnamento Csparse\n" " >>> per piacere, riportatelo agli autori Matrix-authors@r-project.org" msgid "you cannot mix negative and positive indices" msgstr "non è possibile mischiare indici negativi e positivi" msgid "index larger than maximal %d" msgstr "indice più largo del massimo %d" msgid "'NA' indices are not (yet?) supported for sparse Matrices" msgstr "gli indici 'NA' non sono (ancora?) supportati per le matrici sparse" msgid "logical subscript too long (%d, should be %d)" msgstr "subscript logico troppo lungo (%d, dovrebbe essere %d)" msgid "no 'dimnames[[.]]': cannot use character indexing" msgstr "" "nessuna 'dimnames[[.]]': non è possibile utilizzare l'indicizzazione dei " "caratteri" msgid "invalid character indexing" msgstr "indicizzazione carattere non valida" msgid "internal bug: missing 'i' in replTmat(): please report" msgstr "bug interno: manca 'i' in replTmat(): per piacere, riportatelo" msgid "[ ] indexing not allowed: forgot a \",\" ?" msgstr "" "[ ] indicizzazione non ammessa: si è dimenticato un \",\" ?" msgid "internal bug: matrix 'i' in replTmat(): please report" msgstr "bug interno: matrix 'i' in replTmat(): per piacere, riportatelo" msgid "" "x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced; NA |--> TRUE." msgstr "" "x[.] <- val: x è %s, il valore esterno a {TRUE, FALSE} è convertito; NA |--> " "TRUE." msgid "x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced." msgstr "x[.] <- val: x è %s, il valore esterno a {TRUE, FALSE} è convertito." msgid "" "x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced NA |--> TRUE." msgstr "" "x[.,.] <- val: x è %s, il valore esterno a {TRUE, FALSE} è convertito; NA |--" "> TRUE." msgid "x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced." msgstr "x[.,.] <- val: x è %s, il valore esterno a {TRUE, FALSE} è convertito." msgid "x[.,.] <- val : x being coerced from Tsparse* to CsparseMatrix" msgstr "x[.,.] <- val : x è stato convertito da Tsparse* a CsparseMatrix" msgid "nargs() = %d should never happen; please report." msgstr "nargs() = %d non dovrebbe accadere; per piacere riportalo." msgid "row indices must be <= nrow(.) which is %d" msgstr "gli indici riga devono essere <= nrow(.) e sono %d" msgid "column indices must be <= ncol(.) which is %d" msgstr "gli indici di colonna devono essere <= ncol(.) e sono %d" msgid "Internal bug: nargs()=%d; please report" msgstr "Bug interno: nargs()=%d; per piacere riportalo" msgid "" "index must be numeric, logical or sparseVector for indexing sparseVectors" msgstr "" "l'indice dev'essere numerico, logico o sparseVector per l'indicizzazione di " "sparseVector" #, fuzzy msgid "invalid subscript class \"%s\"" msgstr "classe non valida: %s" #, fuzzy msgid "invalid subscript type \"%s\"" msgstr "Tipo di archiviazione non valido: %s" msgid "recycled %s would have maximal index exceeding %s" msgstr "" msgid "subscripts exceeding %s replaced with NA" msgstr "" msgid "subscript out of bounds" msgstr "" #, fuzzy msgid "logical subscript too long" msgstr "subscript logico troppo lungo (%d, dovrebbe essere %d)" #, fuzzy msgid "incorrect number of dimensions" msgstr "dimensioni matrice non compatibili" msgid "only zeros may be mixed with negative subscripts" msgstr "" msgid "'%s' has length 0 but '%s' does not" msgstr "" #, fuzzy msgid "attempt to coerce matrix with NA to %s" msgstr "" "non è possibile convertire la classe \"dgTMatrix\" non simmetrica nella " "classe \"dsCMatrix\"" #, fuzzy msgid "invalid 'Class2'" msgstr "'data' non valido" #~ msgid "qr2rankMatrix(.): QR has negative diag(R) entries" #~ msgstr "qr2rankMatrix(.): QR ha elementi diag(R) negativi" #, fuzzy #~ msgid "invalid 'each' argument" #~ msgstr "segno errato nell'argomento 'by'" #, fuzzy #~ msgid "invalid 'times' argument" #~ msgstr "'data' non valido" #~ msgid "" #~ "not-yet-implemented method for %s(<%s>).\n" #~ " ->> Ask the package authors to implement the missing feature." #~ msgstr "" #~ "metodo non ancora implementato per %s(<%s>).\n" #~ " - >> Chiedi agli autori del pacchetto di implementare la funzionalità " #~ "assente." #~ msgid "" #~ "not-yet-implemented method for %s(<%s>, <%s>).\n" #~ " ->> Ask the package authors to implement the missing feature." #~ msgstr "" #~ "metodo non ancora implementato per %s(<%s>, <%s>).\n" #~ " - >> Chiedi agli autori del pacchetto di implementare la funzionalità " #~ "assente." #, fuzzy #~ msgid "complex \"diagonalMatrix\" not yet implemented" #~ msgstr "classe generale Matrix non ancora implementata per %s" #, fuzzy #~ msgid "not yet implemented for class \"%s\"" #~ msgstr "non ancora implementato per la classe %s" #, fuzzy #~ msgid "invalid 'uplo'" #~ msgstr "'type' non valido" #~ msgid "'lag' and 'differences' must be integers >= 1" #~ msgstr "'lag' e 'differences' devono essere interi >= 1" #~ msgid "" #~ "programming error: min() should have dispatched w/ 1st arg much earlier" #~ msgstr "" #~ "errore di programmazione: min() dovrebbe aver fatto il dispatch con il " #~ "primo argomento molto prima" #~ msgid "in Summary(, .): %s(<%s>, <%s>,...)" #~ msgstr "in Summary(, .): %s(<%s>, <%s>,...)" #~ msgid "in Summary(, .): %s(<%s>, <%s>)" #~ msgstr "in Summary(, .): %s(<%s>, <%s>)" #, fuzzy #~ msgid "number of rows of matrices must match" #~ msgstr "il numero di righe non sono compatibili per %s" #, fuzzy #~ msgid "number of columns of matrices must match" #~ msgstr "il numero di righe non sono compatibili per %s" #~ msgid "resulting x-slot has different type than x's or y's" #~ msgstr "lo x-slot risultante ha un tipo diverso da quelli di x o y" #, fuzzy #~ msgid "dimensions must be numeric of length 2" #~ msgstr "il valore di dim(.) dev'essere numerico di lunghezza 2" #, fuzzy #~ msgid "'perm' must be numeric" #~ msgstr "'A' dev'essere una matrice quadrata" #, fuzzy #~ msgid "'margin' must be 1 or 2" #~ msgstr "'ncol' dev'essere >= 0" #~ msgid "not-yet-implemented method for <%s> %%*%% <%s>" #~ msgstr "metodo non ancora implementato per <%s> %%*%% <%s>" #~ msgid "'boolArith = %d' not yet implemented" #~ msgstr "'boolArith = %d' non ancora implementato" #, fuzzy #~ msgid "'rcond' via sparse -> dense coercion" #~ msgstr "rcond (.) con coercizione sparsa -> densa" #, fuzzy #~ msgid "invalid 'norm'" #~ msgstr "'data' non valido" #, fuzzy #~ msgid "cannot coerce zsparseVector to dgCMatrix" #~ msgstr "" #~ "non è possibile la coercizione dei valori 'NA' nel pattern \"ngCMatrix\"" #, fuzzy #~ msgid "cannot coerce zsparseVector to dgeMatrix" #~ msgstr "non è possibile la coercizione degli 'NA' in \"nsparseVector\"" #~ msgid "" #~ "number of non zeros is smaller than 'nnz' because of duplicated (i,j)s" #~ msgstr "" #~ "il numero di valori non-zero è inferiore a 'nnz' a causa di duplicati (i," #~ "j)s" #~ msgid "'times >= 0' is required" #~ msgstr "'times >= 0' è richiesto" #~ msgid "'giveCsparse' has been deprecated; setting 'repr = \"%s\"' for you" #~ msgstr "'giveCsparse' è stato deprecato; viene impostato 'repr = \"%s\"'" #~ msgid "Matrices must have same number of rows in %s" #~ msgstr "Le matrici devono avere il medesimo numero di righe in %s" #~ msgid "Matrices must have same number of columns in %s" #~ msgstr "Le matrici devono avere il medesimo numero di colonne in %s" #, fuzzy #~ msgid "only 2-dimensional tables can be coerced to sparseMatrix" #~ msgstr "" #~ "solo le tabelle bidimensionali possono essere convertite direttamente a " #~ "matrici sparse" #, fuzzy #~ msgid "matrix is not symmetric or" #~ msgstr "'x' non è simmetrica ne triangolare" #, fuzzy #~ msgid "triangular" #~ msgstr "non è una matrice triangolare" #, fuzzy #~ msgid "matrix is not" #~ msgstr "la matrice non è diagonale" #~ msgid "'x' is not positive definite -- chol() undefined." #~ msgstr "'x' non è definito positivo -- chol() non definito." #~ msgid "Matrices must have same dimensions in %s" #~ msgstr "Le matrici devono avere le medesime dimensioni in %s" #~ msgid "names(dimnames()) must be NULL or of length two" #~ msgstr "names(dimnames()) dev'essere NULL o lunga due" #~ msgid "[[ suppressing %d column names %s ]]" #~ msgstr "[[ soppressione di %d nomi colonna %s ]]" #~ msgid "'x' must be \"sparseMatrix\"" #~ msgstr "'x' dev'essere una \"sparseMatrix\"" #~ msgid "not yet implemented for matrix with typeof %s" #~ msgstr "non ancora implementato per matrici con typeof %s" #~ msgid "not yet implemented for %s" #~ msgstr "non ancora implementato per %s" #~ msgid "" #~ "Quadratic matrix '%s' (=: A) is not formally\n" #~ "\tsymmetric. Will be treated as\tA A'" #~ msgstr "" #~ "La matrice quadratica '%s' (=: A) non è formalmente\n" #~ "\tsimmetrica. Sarà trattata come\tA A'" #~ msgid "" #~ "'update' must be logical or '+' or '-'; 'C' a matrix, and 'L' a " #~ "\"CHMfactor\"" #~ msgstr "" #~ "'update' dev'essere logico o '+' o '-'; 'C' una matrice, e 'L' un " #~ "\"CHMfactor\"" #~ msgid "update must be TRUE/FALSE or '+' or '-'" #~ msgstr "l'aggiornamento dev'essere TRUE/FALSE o '+' o '-'" #~ msgid "Matrix-internal error in [i,,d]; please report" #~ msgstr "" #~ "Errore interno alla matrice in [i,,d]; per piacere riportalo" #~ msgid "" #~ "Cholesky() -> *symbolic* factorization -- not yet implemented" #~ msgstr "" #~ "Cholesky() -> *symbolic* factorization -- non ancora " #~ "implementato" #~ msgid "" #~ "as.matrix() is deprecated (to become a no-op in the future).\n" #~ "Use as(x, \"matrix\") or .asmatrix(x) instead." #~ msgstr "" #~ "as.matrix() è deprecato (per diventare una no-op in futuro).\n" #~ "Utilizza come alternativa as(x, \"matrix\") o .asmatrix(x)." #~ msgid "" #~ "as.array() is deprecated. Use as(x, \"matrix\") or .asmatrix(x) " #~ "instead." #~ msgstr "" #~ "as.array() è deprecato. Utilizza come alternativa as(x, " #~ "\"matrix\") o .asmatrix(x)." #~ msgid "trimmed mean of 'sparseVector' -- suboptimally using as.numeric(.)" #~ msgstr "" #~ "media tagliata di 'sparseVector' -- in modo non ottimale usando as." #~ "numeric (.)" #~ msgid "invalid dimnames given for %s object" #~ msgstr "i nomi di dimensioni non sono validi per l'oggetto %s" #~ msgid "" #~ "dimnames(.) <- NULL: translated to \n" #~ "dimnames(.) <- list(NULL,NULL) <==> unname(.)" #~ msgstr "" #~ "dimnames(.) <- NULL: tradotto in \n" #~ "dimnames(.) <- list(NULL,NULL) <==> unname(.)" #~ msgid "" #~ "'nrow', 'ncol', etc, are disregarded when 'data' is \"Matrix\" already" #~ msgstr "" #~ "'nrow', 'ncol' e gli altri, sono ignorati quando 'data' è già \"Matrix\"" #~ msgid "complex matrices not yet implemented in Matrix package" #~ msgstr "" #~ "le matrici complesse non sono ancora implementate nel pacchetto Matrix" #~ msgid "using slow kronecker() method" #~ msgstr "si utilizza il metodo kronecker() lento" #~ msgid "" #~ "Cholesky(A) called for 'A' of class \"%s\";\n" #~ "\t it is currently defined for sparseMatrix only; consider using chol() " #~ "instead" #~ msgstr "" #~ "Cholesky(A) ha chiamato 'A' della classe \"%s\";\n" #~ "\t è attualmente definito solo per sparseMatrix; si consideri l'utilizzo " #~ "di chol() come alternativa" #~ msgid "invalid or not-yet-implemented 'Matrix' subsetting" #~ msgstr "sotto-divisione 'Matrix' non valido o non ancora implementato" #~ msgid "[ ] : .M.sub.i.logical() maybe inefficient" #~ msgstr "" #~ "[ ] : .M.sub.i.logical() potrebbe essere inefficiente" #~ msgid "" #~ "nargs() = %d. Extraneous illegal arguments inside '[ .. ]' (i.logical)?" #~ msgstr "" #~ "nargs() = %d. Argomenti illegali estranei all'interno di '[ .. ]' (i." #~ "logical)?" #~ msgid "" #~ "m[]: inefficiently indexing single elements - should not " #~ "happen, please report!" #~ msgstr "" #~ "m[ ]: indicizzazione inefficiente dei singoli elementi - non " #~ "dovrebbe succedere, per piacere riportalo!" #~ msgid "" #~ "nargs() = %d. Extraneous illegal arguments inside '[ .. ]' (i.2col)?" #~ msgstr "" #~ "nargs() =%d. Argomenti illegali estranei all'interno di '[..]' (i.2col)?" #~ msgid "" #~ ".M.sub.i.2col(): 'i' has no integer column number;\n" #~ " should never happen; please report" #~ msgstr "" #~ ".M.sub.i.2col(): 'i' non ha un numero di colonna intero;\n" #~ " non dovrebbe mai accadere; per piacere, segnalatelo" #~ msgid "not-yet-implemented coercion to \"TsparseMatrix\"" #~ msgstr "coercizione in \"TsparseMatrix\" non ancora implementato" #~ msgid "Matrix-internal error in [i,,d]; please report" #~ msgstr "" #~ "Errore interno alla matrice in [i,,d]; per piacere riportalo" #~ msgid "FIXME: NOT YET FINISHED IMPLEMENTATION" #~ msgstr "FIXME: IMPLEMENTAZIONE NON ANCORA FINITA" #~ msgid "diagonalMatrix in .dense2C() -- should never happen, please report!" #~ msgstr "" #~ "diagonalMatrix in .dense2C() -- non dovrebbe mai accadere, per piacere, " #~ "riportatelo!" #~ msgid "undefined method for class %s" #~ msgstr "metodo per la classe %s non definito" #~ msgid "dimensions don't match the number of cells" #~ msgstr "le dimensioni non corrispondono con il numero di celle" #~ msgid "" #~ "LU computationally singular: ratio of extreme entries in |diag(U)| = %9.4g" #~ msgstr "" #~ "LU computazionalmente singolare: rapporto tra voci estreme in |diag(U)| " #~ "=%9.4g" #~ msgid "RHS 'b' has wrong number of rows:" #~ msgstr "RHS 'b' ha un numero errato di righe:" #~ msgid "'x' has invalid data type" #~ msgstr "'x' ha un tipo dato non valido" #~ msgid "length(x) must be either 1 or #{cols}" #~ msgstr "length(x) dev'essere 1 o #{cols}" #~ msgid "some arguments are not matrices" #~ msgstr "alcuni argomenti non sono matrici" #~ msgid "%s kind not yet implemented" #~ msgstr "%s kind non ancora implementato" #~ msgid "non-square matrix" #~ msgstr "matrice non quadrata" #~ msgid "" #~ "matrix with non-zero off-diagonals cannot be coerced to \"diagonalMatrix\"" #~ msgstr "" #~ "la matrice con diagonali diverse da zero non può essere convertita in " #~ "\"diagonalMatrix\"" #~ msgid "non-matching dimensions" #~ msgstr "dimensioni non corrispondenti" #~ msgid "not a positive definite matrix" #~ msgstr "non è una matrice definita positiva" #~ msgid "" #~ "as(.,\"dsCMatrix\") is deprecated (since 2008); do use as(., " #~ "\"symmetricMatrix\")" #~ msgstr "" #~ "as(.,\"dsCMatrix\") è deprecato (dal 2008); si utilizzi as(., " #~ "\"symmetricMatrix\")" #~ msgid "inefficient coercion (lost triangularity); please report" #~ msgstr "" #~ "coercizione inefficiente (triangolarità persa); per piacere, segnalatelo" #~ msgid "coercion to \"indMatrix\" only works from integer numeric" #~ msgstr "la coercizione in \"indMatrix\" funziona solo da interi numerici" #~ msgid "" #~ "coercion from list(i1,...,ik, d) to \"indMatrix\" failed.\n" #~ " All entries must be integer valued and the number of columns, d, not " #~ "smaller\n" #~ " than the maximal index i*." #~ msgstr "" #~ "coercizione dalla list(i1, ..., ik, d) a \"indMatrix\" non riuscita.\n" #~ " Tutte le voci devono essere valori interi e il numero di colonne, d, " #~ "non inferiore\n" #~ " all'indice massimo i*." #~ msgid "the number of non-zero entries differs from nrow(.)" #~ msgstr "il numero di voci diverse da zero differisce da nrow(.)" #~ msgid "resulting matrix dimension would be too large" #~ msgstr "la dimensione della matrice risultante sarà troppo grande" #~ msgid "replacing \"indMatrix\" entries is not allowed, as rarely sensible" #~ msgstr "" #~ "la sostituzione delle voci \"indMatrix\" non è ammessa, in quanto " #~ "raramente incisiva" #~ msgid "temporarily disabled" #~ msgstr "temporaneamente disabilitato" #~ msgid "cannot coerce NA values to pattern \"ntCMatrix\"" #~ msgstr "" #~ "non è possibile la coercizione dei valori 'NA' nel pattern \"ntCMatrix\"" #~ msgid "coercion to \"pMatrix\" only works from integer numeric" #~ msgstr "la coercizione in \"pMatrix\" funziona solo da interi numerici" #~ msgid "not a square matrix" #~ msgstr "non è una matrice quadrata" #~ msgid "NA's in (i,j) are not allowed" #~ msgstr "NA in (i,j) non sono ammessi" #~ msgid "" #~ "Both 'symmetric' and 'triangular', i.e. asking for diagonal matrix. Use " #~ "'Diagonal()' instead" #~ msgstr "" #~ "Sia 'symmetric' che 'triangular', es. chiedendo una matrice diagonale. " #~ "Si utilizzi 'Diagonal()' come alternativa" #~ msgid "triangular matrix must have all i >= j or i <= j" #~ msgstr "la matrice triangolare deve avere tutti i >= j o i <= j" #~ msgid "Matrix-internal error in [i,,d]; please report" #~ msgstr "" #~ "Errore interno alla matrice in [i,,d]; per piacere riportalo" #~ msgid "" #~ "qr.R() may differ from qr.R() because of permutations. " #~ "Possibly use our qrR() instead" #~ msgstr "" #~ "qr.R() potrebbe essere differente da qr.R() per le " #~ "permutazioni. Si utilizzi il nostro qrR() come alternativa" #~ msgid "(un)packing only applies to dense matrices, class(x)='%s'" #~ msgstr "il (un)packing si applica solo alle matrici dense, class(x)='%s'" #~ msgid "'x' is not symmetric -- chol() undefined." #~ msgstr "'x' non è simmetrico -- chol() non definito." #~ msgid "" #~ "extra argument %s will be disregarded in\n" #~ " %s" #~ msgid_plural "" #~ "extra arguments %s will be disregarded in\n" #~ " %s" #~ msgstr[0] "" #~ "l'argomento extra %s sarà ignorato in\n" #~ " %s" #~ msgstr[1] "" #~ "gli argomenti extra %s saranno ignorati in\n" #~ " %s" #~ msgid "%s %s is undefined" #~ msgstr "%s %s non è definita" #~ msgid " %s %s is undefined" #~ msgstr " %s %s non è definita" Matrix/po/R-fr.po0000644000176200001440000012565214521047060013314 0ustar liggesusersmsgid "" msgstr "" "Project-Id-Version: Matrix 1.1-1\n" "POT-Creation-Date: 2023-11-02 21:33\n" "PO-Revision-Date: 2021-02-11 11:04+0100\n" "Last-Translator: Philippe Grosjean \n" "Language-Team: none\n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 2.4.2\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #, fuzzy msgid "invalid mode \"%s\"" msgstr "'mod' incorrect : %s" msgid "" "%s(<%s>, <%s>) is not yet implemented; ask maintainer(\"%s\") to implement " "the missing method" msgstr "" #, fuzzy msgid "complex %s not yet implemented" msgstr "La classe %s n'est pas encore implémentée" #, fuzzy msgid "cannot coerce matrix of type \"%s\" to %s" msgstr "impossible de convertir automatiquement des 'NA's en \"nsparseMatrix\"" #, fuzzy msgid "non0.i() not yet implemented for class %s" msgstr "pas encore implémenté pour la classe %s" msgid "%s=\"%s\" invalid for %s@uplo=\"%s\"" msgstr "" msgid "'%s' is not \"%1$s\", \"D%1$s\", or \"%1$s.\"" msgstr "" msgid "unexpected %s=\"%s\" in '%s' method" msgstr "" msgid "Not a valid format" msgstr "Pas un format acceptable" msgid "'file' must be a character string or connection" msgstr "'file' doit être une chaîne de caractères ou une connexion" msgid "Invalid storage type: %s" msgstr "Type de stockage incorrect : %s" msgid "Only numeric sparse matrices allowed" msgstr "Seules les matrices éparses numériques sont autorisées" msgid "Invalid storage format: %s" msgstr "Format de stockage incorrect : %s" msgid "Invalid assembled indicator: %s" msgstr "Indicateur d'assemblage incorrect : %s" msgid "file is not a MatrixMarket file" msgstr "le fichier n'est pas un fichier MatrixMarket" msgid "type '%s' not recognized" msgstr "type '%s' non reconnu" msgid "representation '%s' not recognized" msgstr "représentation '%s' non reconnue" msgid "element type '%s' not recognized" msgstr "type d'élément '%s' non reconnu" msgid "symmetry form '%s' not recognized" msgstr "la symétrie n'est pas reconnue pour '%s'" msgid "readMM(): expected %d entries but found only %d" msgstr "" #, fuzzy msgid "readMM(): row indices 'i' are not in 1:nrow[=%d]" msgstr "readMM() : ligne\t valeurs 'i' ne sont pas comprises entre 1:nr" #, fuzzy msgid "readMM(): column indices 'j' are not in 1:ncol[=%d]" msgstr "readMM() : colonne valeurs 'j' ne sont pas comprises entre 1:nc" msgid "symmetry form 'skew-symmetric' not yet implemented for reading" msgstr "" "la forme de symétrie 'skew-symmetric' n'est pas encore implémentée pour la " "lecture" msgid "symmetry form 'hermitian' not yet implemented for reading" msgstr "" "la forme de symétrie 'hermitian' n'est pas encore implémentée pour la lecture" msgid "symmetry form '%s' is not yet implemented" msgstr "la forme de symétrie '%s' n'est pas encore implémentée" msgid "element type 'complex' not yet implemented" msgstr "le type d'élément 'complex' n'est pas encore implémenté" msgid "'%s()' is not yet implemented for element type '%s'" msgstr "'%s()' n'est pas encore implémenté pour le type d'élément '%s'" msgid "'%s()' is not yet implemented for representation '%s'" msgstr "'%s' n'est pas encore implémenté pour la représentation '%s'" msgid "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%3$s\", or \"%4$s\"" msgstr "" msgid "" "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%2$s2\", \"%2$s2.\", \"%3$s\", or " "\"%4$s\"" msgstr "" msgid "longer object length is not a multiple of shorter object length" msgstr "" "la longueur de l'objet le plus long n'est pas un multiple de la longueur de " "l'objet le plus court" #, fuzzy msgid "invalid class \"%s\" in '%s' method" msgstr "chaîne de caractères 'col.names' incorrecte : %s" msgid "invalid type \"%s\" in '%s' method" msgstr "" msgid "non-conformable matrix dimensions in %s" msgstr "matrices de dimensions incompatibles dans %s" msgid "dimnames [%d] mismatch in %s" msgstr "dimnames [%d] incohérentes dans %s" msgid "inefficient method used for \"- e1\"" msgstr "méthode inefficace utilisée pour \"- e1\"" msgid "dim [product %d] do not match the length of object [%d]" msgstr "dim [product %d] ne correspond pas à la longueur de l'objet [%d]" msgid "internal bug in \"Compare\" method (Cmp.Mat.atomic); please report" msgstr "" "bogue interne dans la méthode \"Compare\" (Cmp.Mat.atomic) ; veuillez " "reporter ceci" msgid "Cmp.Mat.atomic() should not be called for diagonalMatrix" msgstr "Cmp.Mat.atomic() ne devrait pas être appelé pour diagonalMatrix" msgid "Matrices must have same number of rows for arithmetic" msgstr "" "Les matrices doivent avoir le même nombre de lignes pour les opérations " "arithmétiques" msgid "number of rows are not compatible for %s" msgstr "nombre incompatible de lignes pour %s" msgid "length of 2nd arg does not match dimension of first" msgstr "la longueur du 2ème arg ne correspond pas à la dimension du premier" msgid "length of 1st arg does not match dimension of 2nd" msgstr "la longueur du 1er arg ne correspond pas à la dimension du second" msgid "internal bug in \"Logic\" method (Logic.Mat.atomic); please report" msgstr "" "bogue interne dans la méthode \"Logic\" (Logic.Mat.atomic) ; veuillez " "reporter ceci" msgid "Logic.Mat.atomic() should not be called for diagonalMatrix" msgstr "Logic.Mat.atomic() ne devrait pas être appelé pour diagonalMatrix" msgid "vector too long in Matrix - vector operation" msgstr "vecteur trop long dans une opération Matrix - vecteur" msgid "" "longer object length\n" "\tis not a multiple of shorter object length" msgstr "" "la longueur de l'objet le plus long\n" "\tn'est pas un multiple de la longueur de l'objet le plus court" msgid "intermediate 'r' is of type %s" msgstr "le 'r' intermédiaire est de type %s" msgid "not yet implemented .. please report" msgstr "pas encore implémenté .. veuillez reporter ceci" msgid "'force' must be (coercable to) TRUE or FALSE" msgstr "'force' doit être (convertible en) TRUE ou FALSE" msgid "invalid (to - from)/by in seq(.)" msgstr "(to - from)/by incorrect dans seq(.)" msgid "wrong sign in 'by' argument" msgstr "signe incorrect dans l'argument 'by'" msgid "'by' argument is much too small" msgstr "l'argument 'by' est beaucoup trop petit" msgid "length must be non-negative number" msgstr "la longueur doit être un nombre non négatif" msgid "too many arguments" msgstr "trop d'arguments" msgid "c(,..) of different kinds, coercing all to 'rleDiff'" msgstr "" "c(,..) de différentes sortes, convertis automatiquement en " "'rleDiff\"" msgid "[i] is not yet implemented" msgstr "[i] n'est pas encore implémenté" msgid "all() is not yet implemented" msgstr "all() n'est pas encore implémenté" msgid "sum() is not yet implemented" msgstr "sum() n'est pas encore implémenté" msgid "prod() is not yet implemented" msgstr "prod() n'est pas encore implémenté" msgid "not yet implemented" msgstr "pas encore implémenté" msgid "" "x / 0 for an x with sign-change\n" " no longer representable as 'rleDiff'" msgstr "" "x / 0 pour un x avec changement de signe\n" " il n'est plus représentable comme 'rleDiff'" msgid " --> is not yet implemented" msgstr " --> n'est pas encore implémenté" msgid " --> is not yet implemented" msgstr " --> n'est pas encore implémenté" #, fuzzy msgid "%1$s(%2$s) is undefined: '%2$s' is not positive semidefinite" msgstr "" "chol() est indéfini pour une matrice diagonale avec des entrées négatives" #, fuzzy msgid "matrix is not square" msgstr "la matrice n'est pas diagonale" msgid "" "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%3$s\", \"%3$s.\", \"%3$s1\", \"%3$s1." "\", or \"%4$s\"" msgstr "" #, fuzzy msgid "'%s' does not inherit from virtual class %s" msgstr "'x' doit hériter de \"sparseVector\"" msgid "D[i,i] is NA, i=%d" msgstr "" msgid "D[i,i] is negative, i=%d" msgstr "" msgid "'%1$s' is not formally symmetric; factorizing tcrossprod(%1$s)" msgstr "" #, fuzzy msgid "matrix is not symmetric; consider forceSymmetric(.) or symmpart(.)" msgstr "" "ce n'est pas une matrice symétrique ; considérez forceSymmetric() ou " "symmpart()" #, fuzzy msgid "matrix is not triangular; consider triu(.) or tril(.)" msgstr "la matrice n'est pas triangulaire" msgid "matrix is not diagonal; consider Diagonal(x=diag(.))" msgstr "" #, fuzzy msgid "invalid type \"%s\" in '%s'" msgstr "'type' invalide" #, fuzzy msgid "invalid %s=\"%s\" to '%s'" msgstr "Type de stockage incorrect : %s" msgid "dimensions cannot exceed %s" msgstr "" #, fuzzy msgid "invalid class \"%s\" in '%s'" msgstr "chaîne de caractères 'col.names' incorrecte : %s" msgid "%s length cannot exceed %s" msgstr "" msgid "'A' must be a square matrix" msgstr "'A' doit être une matrice carrée" msgid "must either specify 'A' or the functions 'A.x' and 'At.x'" msgstr "il faut spécifier 'A' ou les fonctions 'A.x' et 'At.x'" msgid "when 'A' is specified, 'A.x' and 'At.x' are disregarded" msgstr "lorsque 'A' est spécifié, 'A.x' et 'At.x' ne sont pas pris en compte" msgid "not converged in %d iterations" msgstr "pas de convergence en %d itérations" msgid "hit a cycle (1) -- stop iterations" msgstr "un cycle est atteint (1) -- arrêt des itérations" msgid "hit a cycle (2) -- stop iterations" msgstr "un cycle est atteint (2) -- arrêt des itérations" msgid "not enough new vecs -- stop iterations" msgstr "pas assez de nouveaux vecs -- arrêt des itérations" msgid "invalid 'data'" msgstr "'data' incorrect" #, fuzzy msgid "'nrow', 'ncol', 'byrow' disregarded for [mM]atrix 'data'" msgstr "'nrow', 'ncol', etc, ne sont pas utilisés pour la matrice 'data'" msgid "data is too long" msgstr "" #, fuzzy msgid "exactly one of 'i', 'j', and 'p' must be missing from call" msgstr "" "exactement une valeur parmi 'i', 'j' ou 'p' doit être manquante dans l'appel" msgid "" "use Diagonal() to construct diagonal (symmetric && triangular) sparse " "matrices" msgstr "" #, fuzzy msgid "'giveCsparse' is deprecated; using 'repr' instead" msgstr "‘giveCsparse’ est obsolète ; utilisation de 'repr' à la place" #, fuzzy msgid "'giveCsparse' is deprecated; setting repr=\"T\" for you" msgstr "'giveCsparse' est obsolète ; j’ai mis 'repr = \"T\"' pour vous" #, fuzzy msgid "'p' must be a nondecreasing vector c(0, ...)" msgstr "'p' doit être un vecteur non décroissant (0, ...)" msgid "dimensions cannot exceed 2^31-1" msgstr "" msgid "'i' and 'j' must not contain NA" msgstr "" msgid "'i' and 'j' must be" msgstr "" msgid "positive" msgstr "" msgid "non-negative" msgstr "" #, fuzzy msgid "invalid 'dims'" msgstr "'data' incorrect" msgid "'dims' must contain all (i,j) pairs" msgstr "" msgid "symmetric matrix must be square" msgstr "la matrice symétrique doit être carrée" msgid "triangular matrix must be square" msgstr "la matrice triangulaire doit être carrée" msgid "p[length(p)]" msgstr "" msgid "length(i)" msgstr "" #, fuzzy msgid "is not an integer multiple of length(x)" msgstr "length(i) n'est pas un multiple de length(x)" msgid "length(x) must not exceed" msgstr "" #, fuzzy msgid "invalid 'repr'; must be \"C\", \"R\", or \"T\"" msgstr "'repr' incorrect ; il doit être \"C\", \"T\", ou \"R\"" #, fuzzy msgid "'n' must be a non-negative integer" msgstr "la longueur doit être un nombre non négatif" msgid "'x' has unsupported class \"%s\"" msgstr "" msgid "'x' has unsupported type \"%s\"" msgstr "" msgid "attempt to recycle 'x' of length 0 to length 'n' (n > 0)" msgstr "" msgid "'shape' must be one of \"g\", \"t\", \"s\"" msgstr "" #, fuzzy msgid "'kind' must be one of \"d\", \"l\", \"n\"" msgstr "'repr' incorrect ; il doit être \"C\", \"T\", ou \"R\"" msgid "mismatch between typeof(x)=\"%s\" and kind=\"%s\"; using kind=\"%s\"" msgstr "" #, fuzzy msgid "'cols' must be numeric" msgstr "'ncol' doit être >= 0" msgid "'cols' has elements not in seq(0, length.out = n)" msgstr "" #, fuzzy msgid "'uplo' must be \"U\" or \"L\"" msgstr "'repr' incorrect ; il doit être \"C\", \"T\", ou \"R\"" #, fuzzy msgid "'lst' must be a list" msgstr "'ncol' doit être >= 0" msgid "'giveCsparse' has been deprecated; setting 'repr = \"T\"' for you" msgstr "'giveCsparse' est obsolète ; j’ai mis 'repr = \"T\"' pour vous" msgid "'giveCsparse' has been deprecated; will use 'repr' instead" msgstr "‘giveCsparse’ est obsolète ; utilisation de 'repr' à la place" msgid "'diagonals' matrix must have %d columns (= length(k) )" msgstr "une matrice 'diagonals' doit avoir %d colonnes (= length(k) )" msgid "'diagonals' must have the same length (%d) as 'k'" msgstr "'diagonals' doit avoir la même longueur (%d) que 'k'" msgid "matrix can only be symmetric if square, but n != m" msgstr "" "une matrice peut seulement être symétrique si elle est carrée, mais n != m" msgid "" "for symmetric band matrix, only specify upper or lower triangle\n" " hence, all k must have the same sign" msgstr "" "pour une matrice de bande symétrique, spécifiez seulement le triangle " "supérieur ou inférieur\n" " donc, tous les k doivent avoir le même signe" msgid "the %d-th (sub)-diagonal (k = %d) is too short; filling with NA's" msgstr "" "la %d-ième (sous)-diagonale (k = %d) est trop courte ; elle est repliée avec " "des NAs" msgid "invalid 'repr'; must be \"C\", \"T\", or \"R\"" msgstr "'repr' incorrect ; il doit être \"C\", \"T\", ou \"R\"" msgid "'x' must inherit from \"sparseVector\"" msgstr "'x' doit hériter de \"sparseVector\"" msgid "'ncol' must be >= 0" msgstr "'ncol' doit être >= 0" msgid "'nrow' must be >= 0" msgstr "'nrow' doit être >= 0" msgid "Must specify 'nrow' when 'symmetric' is true" msgstr "Il faut spécifier 'nrow' lorsque 'symmetric' est vrai" msgid "'nrow' and 'ncol' must be the same when 'symmetric' is true" msgstr "'now' et 'ncol' doivent être les mêmes lorsque 'symmetric' est vrai" msgid "'x' must have length nrow^2 when 'symmetric' is true" msgstr "'x' doit avoir une longueur nrow^2 lorsque 'symmetric' est vrai" msgid "'ncol' is not a factor of length(x)" msgstr "'ncol' n'est pas un factor de length(x)" msgid "'nrow' is not a factor of length(x)" msgstr "'nrow' n'est pas un factor de length(x)" msgid "Class %s is not yet implemented" msgstr "La classe %s n'est pas encore implémentée" #, fuzzy msgid "'%s' and '%s' must be positive integers" msgstr "la longueur doit être un nombre non négatif" #, fuzzy msgid "matrix is not symmetric or triangular" msgstr "'x' n'est ni symétrique ni triangulaire" #, fuzzy msgid "matrix is not symmetric" msgstr "la matrice n'est pas triangulaire" #, fuzzy msgid "matrix is not triangular" msgstr "'x' n'est ni symétrique ni triangulaire" msgid "" "the default value of argument '%s' of method '%s(<%s>, <%s>)' may change " "from %s to %s as soon as the next release of Matrix; set '%s' when " "programming" msgstr "" msgid "determinant of non-square matrix is undefined" msgstr "" msgid "replacement diagonal has wrong length" msgstr "" msgid "replacement diagonal has incompatible type \"%s\"" msgstr "" msgid "assigned dimensions are not of type \"%s\" or \"%s\"" msgstr "" msgid "assigned dimensions do not have length %d" msgstr "" msgid "assigned dimensions are NA" msgstr "" msgid "assigned dimensions are negative" msgstr "" msgid "assigned dimensions exceed %s" msgstr "" #, fuzzy msgid "assigned dimensions [product %.0f] do not match object length [%.0f]" msgstr "dim [product %d] ne correspond pas à la longueur de l'objet [%d]" msgid "'%s' has non-finite values" msgstr "" msgid "'%1$s' is not \"%2$s\", \"%3$s\", or \"%2$s.\"" msgstr "" #, fuzzy msgid "only square matrices can be used as graph incidence matrices" msgstr "" "seules des matrices carrées peuvent être utilisées comme matrices " "d'incidence pour les graphiques" msgid "'lwd' must be NULL or non-negative numeric" msgstr "'lwd' doit être un nombre non négatif ou NULL" #, fuzzy msgid "%s(<%s>) is not yet implemented" msgstr "La classe %s n'est pas encore implémentée" msgid "'%s' is not of type \"%s\" or \"%s\"" msgstr "" msgid "'%s' contains NA" msgstr "" msgid "'%s' has elements less than %d" msgstr "" #, fuzzy msgid "'%s' is not a non-negative number" msgstr "la longueur doit être un nombre non négatif" msgid "'%s' has elements exceeding '%s'" msgstr "" msgid "'%s' is not %d or %d" msgstr "" #, fuzzy msgid "'%s' is not a permutation of seq_len(%s)" msgstr "'ncol' n'est pas un factor de length(x)" #, fuzzy msgid "matrix must have exactly one entry in each row or column" msgstr "doit avoir exactement une entrée non zéro par ligne" #, fuzzy msgid "attempt to coerce non-square matrix to %s" msgstr "" "impossible de convertir automatiquement des \"dgMAtrix\" non symétriques en " "classe \"dsCMatrix\"" #, fuzzy msgid "matrix must have exactly one entry in each row and column" msgstr "doit avoir exactement une entrée non zéro par ligne" #, fuzzy msgid "'%s' via sparse -> dense coercion" msgstr "conversion automatique rcond(.) via sparse -> dense" #, fuzzy msgid "invalid %s=\"%s\"" msgstr "nargs()= %d incorrect" msgid "norm" msgstr "" #, fuzzy msgid "'%s' method must use default %s=\"%s\"" msgstr "méthode kronecker doit utiliser une 'FUN' par défaut" #, fuzzy msgid "number of nonzero entries cannot exceed %s" msgstr "nombre incompatible de lignes pour %s" msgid "Matrix seems negative semi-definite" msgstr "La matrice semble négative et semi-définie" msgid "'nearPD()' did not converge in %d iterations" msgstr "'nearPD()' n'a pas converti en %d itérations" #, fuzzy msgid "'cl' is not a character string" msgstr "'V' n'est pas une matrice *carrée*" msgid "" "not a positive definite matrix (and positive semidefiniteness is not checked)" msgstr "" #, fuzzy msgid "'%s' is not a square numeric matrix" msgstr "'V' n'est pas une matrice *carrée*" #, fuzzy msgid "" "diag(%s) has non-positive or non-finite entries; finite result is doubtful" msgstr "diag(.) avait 0 ou NA données ; un résultat non fini est douteux" msgid "non-conformable arguments" msgstr "matrices de dimensions incompatibles dans les arguments" msgid "" "matrix is structurally rank deficient; using augmented matrix with " "additional %d row(s) of zeros" msgstr "" msgid "" "'%1$s' is not \"%2$s1\", \"%2$s1.\", \"%2$s2\", \"%2$s2.\", \"%3$s\", " "\"%3$s1\", \"%4$s\", or \"%4$s1\"" msgstr "" #, fuzzy msgid "'%s' has the wrong length" msgstr "Le membre droit 'b' est de longueur incorrecte" #, fuzzy msgid "invalid '%s': not in %d:%d" msgstr "chaîne de caractères 'col.names' incorrecte : %s" msgid "need greater '%s' as pivoting occurred" msgstr "" msgid "qr2rankMatrix(.): QR with only %d out of %d finite diag(R) entries" msgstr "qr2rankMatrix(.): QR avec seulement %d de %d entrées finies de diag(R)" msgid "" "rankMatrix(, method = '%s') coerces to dense matrix.\n" " Probably should rather use method = 'qr' !?" msgstr "" "rankMatrix(, method = '%s') converti automatiquement en " "matrice dense.\n" " Il faudrait probablement plutôt utiliser une méthode = 'qr' ?" msgid "rankMatrix(x, method='qr'): computing t(x) as nrow(x) < ncol(x)" msgstr "rankMatrix(x, method='qr') : calcul de t(x) comme nrow(x) < ncol(x)" #, fuzzy msgid "[[ suppressing %d column name%s %s ... ]]" msgstr "[[ suppression de %d noms de colonnes %s … ]]" msgid "invalid 'col.names' string: %s" msgstr "chaîne de caractères 'col.names' incorrecte : %s" msgid "uniDiag=TRUE, but not all diagonal entries are 1" msgstr "uniDiag=TRUE, mais pas toutes les entrées diagonales sont à 1" msgid "uniDiag=TRUE, not all entries in diagonal coded as 1" msgstr "" "uniDiag=TRUE, toutes les entrées de la diagonale ne sont pas encodées à 1" #, fuzzy msgid "in show(); maybe adjust options(max.print=, width=)" msgstr "dans show() ; ajustez peut-être 'options(max.print= *, width = *)'" msgid "suppressing %d columns and %d rows" msgstr "suppression de %d colonnes et %d lignes" msgid "suppressing %d rows" msgstr "suppression de %d lignes" msgid "suppressing %d columns" msgstr "suppression de %d colonnes" msgid "logic programming error in printSpMatrix2(), please report" msgstr "" "erreur logique de programmation dans printSpMAtrix2(), veuillez reporter ceci" #, fuzzy msgid "'%s' is not square" msgstr "'V' n'est pas une matrice carrée" msgid "dimensions of '%s' and '%s' are inconsistent" msgstr "" msgid "'%1$s' is computationally singular, rcond(%1$s)=%2$g" msgstr "" msgid "'%s' is computationally singular, min(d)/max(d)=%g, d=abs(diag(U))" msgstr "" msgid "matrix is exactly singular, D[i,i]=0, i=%d" msgstr "" msgid "matrix is exactly singular, J[,j]=0, j=%d" msgstr "" msgid "matrix exactly singular, J[i,]=0, i=%d" msgstr "" msgid "cannot coerce from %s to %s" msgstr "" #, fuzzy msgid "model frame and formula mismatch in sparse.model.matrix()" msgstr "" "le cadre du modèle et la formule ne correspondent pas dans model.matrix()" #, fuzzy msgid "non-list contrasts argument ignored" msgstr "argument 'contrast.arg' incorrect" #, fuzzy msgid "'contrasts.arg' argument must be named" msgstr "argument 'contrast.arg' incorrect" msgid "variable '%s' is absent, its contrast will be ignored" msgstr "la variable '%s' est absente, ses contrastes seront ignorés" msgid "a sparseMatrix should rarely be centered: will not be sparse anymore" msgstr "" "une sparseMatrix doit rarement être centrée : elle ne sera plus éparse " "ensuite" msgid "length of 'center' must equal the number of columns of 'x'" msgstr "la longueur de 'center' doit être égale au nombre de colonnes de 'x'" msgid "length of 'scale' must equal the number of columns of 'x'" msgstr "la longueur de 'scale' doit être égale au nombre de colonnes de 'x'" msgid "trimmed means are not defined for complex data" msgstr "" msgid "first element used of '%s' argument" msgstr "" #, fuzzy msgid "invalid '%s' argument" msgstr "'data' incorrect" msgid "should never happen ..." msgstr "" #, fuzzy msgid "'%s' is deprecated; using '%s' instead" msgstr "‘giveCsparse’ est obsolète ; utilisation de 'repr' à la place" #, fuzzy msgid "'%s' is deprecated; setting %s=\"%s\"" msgstr "'giveCsparse' est obsolète ; j’ai mis 'repr = \"T\"' pour vous" msgid "" ".M.repl.i.2col(): 'i' has no integer column number;\n" " should never happen; please report" msgstr "" ".M.repl.i.2col() : 'i' n'a\tpas un nombre entier de colonnes ;\n" " ceci ne devrait pas se produite. Veuillez envoyer un rapport de bogue" msgid "such indexing must be by logical or 2-column numeric matrix" msgstr "" "un tel indiçage doit être réalisé avec un vecteur booléen ou une matrice " "numérique à deux colonnes" msgid ".M.repl.i.2col(): drop 'matrix' case ..." msgstr ".M.repl.i.2col() : cas 'matrix' non traité ..." msgid "negative values are not allowed in a matrix subscript" msgstr "" "les valeurs négatives ne sont pas permises dans les indices de matrices" msgid "NAs are not allowed in subscripted assignments" msgstr "Les NAs ne sont pas autorisés dans les assignations avec indices" msgid "number of items to replace is not a multiple of replacement length" msgstr "" "le nombre d'éléments à remplacer n'est pas un multiple de la longueur de " "remplacement" msgid "m[ ] <- v: inefficiently treating single elements" msgstr "m[ ] <- v : traitement inefficace d'éléments uniques" msgid "nargs() = %d. Extraneous illegal arguments inside '[ .. ]' ?" msgstr "nargs() = %d. Arguments supplémentaires dans '[ .. ]' illégaux ?" msgid "RHS 'value' (class %s) matches 'ANY', but must match matrix class %s" msgstr "" "La 'value' du membre gauche de l'équation (classe %s) correspond à 'ANY', " "mais doit correspondre à la classe de matrice %s" msgid "not-yet-implemented 'Matrix[<-' method" msgstr "méthode 'Matrix[<-' non encore implémentée" msgid "invalid nargs()= %d" msgstr "nargs()= %d incorrect" msgid "nothing to replace with" msgstr "rien à remplacer avec" msgid "too many replacement values" msgstr "trop de valeurs de remplacement" msgid "i1[1] == 0 ==> C-level verbosity will not happen!" msgstr "" "i1[1] == 0 ==> au niveau C, aucune information détaillée ne sera affichée !" msgid "using\t \"old code\" part in Csparse subassignment" msgstr "" "utilisation d'une partie\t d'\"ancien code\" dans une sous-assignation " "Csparse" msgid "" "using\"old code\" part in Csparse subassignment\n" " >>> please report to Matrix-authors@r-project.org" msgstr "" "utilisation d'une partie d'\"ancien code\" dans une sous-assignation " "Csparse\n" " >>> veuillez envoyer un rapport à Matrix-authors@r-project.org" msgid "you cannot mix negative and positive indices" msgstr "vous ne pouvez pas mélanger des indices négatifs et positifs" msgid "index larger than maximal %d" msgstr "indice plus grand que la valeur maximale %d" msgid "'NA' indices are not (yet?) supported for sparse Matrices" msgstr "" "les indices 'NA' ne sont pas (encore?) supportés pour les Matrices éparses" msgid "logical subscript too long (%d, should be %d)" msgstr "indice logique trop long (%d, devrait être %d)" msgid "no 'dimnames[[.]]': cannot use character indexing" msgstr "" "pas de 'dimnames[[.]]' : impossible d'utiliser un indiçage de chaîne de " "caractères" msgid "invalid character indexing" msgstr "indiçage de chaînes de caractères incorrect" msgid "internal bug: missing 'i' in replTmat(): please report" msgstr "bogue interne : 'i' manquant dans replTmat() : veuillez reporter ceci" msgid "[ ] indexing not allowed: forgot a \",\" ?" msgstr "" "indiçage [ ] non permis : n'avez-vous pas oublié une \",\" ?" msgid "internal bug: matrix 'i' in replTmat(): please report" msgstr "bogue interne : matrice 'i' dans replTmat() : veuillez reporter ceci" msgid "" "x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced; NA |--> TRUE." msgstr "" "x[.] <- val: x vaut %s, val qui ne sont pas dans {TRUE, FALSE} sont " "convertis ; NA |--> TRUE." msgid "x[.] <- val: x is %s, val not in {TRUE, FALSE} is coerced." msgstr "" "x[.] <- val: x vaut %s, val qui ne sont pas dans {TRUE, FALSE} sont " "convertis." msgid "" "x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced NA |--> TRUE." msgstr "" "x[.,.] <- val: x vaut %s, val qui ne sont pas dans {TRUE, FALSE} sont " "convertis NA |--> TRUE." msgid "x[.,.] <- val: x is %s, val not in {TRUE, FALSE} is coerced." msgstr "" "x[.,.] <- val: x vaut %s, val qui ne sont pas dans {TRUE, FALSE} sont " "convertis." msgid "x[.,.] <- val : x being coerced from Tsparse* to CsparseMatrix" msgstr "" "x[.,.] <- val: x est converti automatiquement de Tsparse* vers CsparseMatrix" msgid "nargs() = %d should never happen; please report." msgstr "nargs() = %d ne devrait jamais se produire ; veuillez reporter ceci." msgid "row indices must be <= nrow(.) which is %d" msgstr "les indices de lignes doivent être <= nrow(.) qui est %d" msgid "column indices must be <= ncol(.) which is %d" msgstr "les indices de colonnes doivent être <= ncol(.) qui est %d" msgid "Internal bug: nargs()=%d; please report" msgstr "Bogue interne : nargs()=%d ; veuillez reporter ceci" msgid "" "index must be numeric, logical or sparseVector for indexing sparseVectors" msgstr "" "les indices doivent être numériques, booléens ou sparseVector pour " "l'indiçage sparseVectors" #, fuzzy msgid "invalid subscript class \"%s\"" msgstr "classe incorrecte : %s" #, fuzzy msgid "invalid subscript type \"%s\"" msgstr "Type de stockage incorrect : %s" msgid "recycled %s would have maximal index exceeding %s" msgstr "" msgid "subscripts exceeding %s replaced with NA" msgstr "" msgid "subscript out of bounds" msgstr "" #, fuzzy msgid "logical subscript too long" msgstr "indice logique trop long (%d, devrait être %d)" #, fuzzy msgid "incorrect number of dimensions" msgstr "dimensions incompatibles des matrices" msgid "only zeros may be mixed with negative subscripts" msgstr "" msgid "'%s' has length 0 but '%s' does not" msgstr "" #, fuzzy msgid "attempt to coerce matrix with NA to %s" msgstr "" "impossible de convertir automatiquement des \"dgMAtrix\" non symétriques en " "classe \"dsCMatrix\"" #, fuzzy msgid "invalid 'Class2'" msgstr "'data' incorrect" #~ msgid "qr2rankMatrix(.): QR has negative diag(R) entries" #~ msgstr "qr2rankMatrix(.): QR a des entrées négatives dans diag(R)" #, fuzzy #~ msgid "invalid 'each' argument" #~ msgstr "signe incorrect dans l'argument 'by'" #, fuzzy #~ msgid "invalid 'times' argument" #~ msgstr "'data' incorrect" #~ msgid "" #~ "not-yet-implemented method for %s(<%s>).\n" #~ " ->> Ask the package authors to implement the missing feature." #~ msgstr "" #~ "méthode non encore implémentée pour %s(<%s>).\n" #~ " ->> Demandez aux auteurs du package d'implémenter cette fonction " #~ "manquante." #~ msgid "" #~ "not-yet-implemented method for %s(<%s>, <%s>).\n" #~ " ->> Ask the package authors to implement the missing feature." #~ msgstr "" #~ "méthode non encore implémentée pour %s(<%s>, <%s>).\n" #~ " ->> Demandez aux auteurs du package d'implémenter cette fonction " #~ "manquante." #, fuzzy #~ msgid "complex \"diagonalMatrix\" not yet implemented" #~ msgstr "classe Matrix générale pas encore implémentée pour %s" #, fuzzy #~ msgid "not yet implemented for class \"%s\"" #~ msgstr "pas encore implémenté pour la classe %s" #, fuzzy #~ msgid "invalid 'uplo'" #~ msgstr "'type' invalide" #~ msgid "'lag' and 'differences' must be integers >= 1" #~ msgstr "'lag' et 'differences' doivent être des entiers >= 1" #~ msgid "" #~ "programming error: min() should have dispatched w/ 1st arg much earlier" #~ msgstr "" #~ "erreur de programmation : min() aurait dû être dispatché avec le 1er arg " #~ "bien plus tôt" #~ msgid "in Summary(, .): %s(<%s>, <%s>,...)" #~ msgstr "dans Summary() : %s(<%s>, <%s>, …)" #~ msgid "in Summary(, .): %s(<%s>, <%s>)" #~ msgstr "dans Summary(, ) : %s(<%s>, <%s>)" #, fuzzy #~ msgid "number of rows of matrices must match" #~ msgstr "nombre incompatible de lignes pour %s" #, fuzzy #~ msgid "number of columns of matrices must match" #~ msgstr "nombre incompatible de lignes pour %s" #~ msgid "resulting x-slot has different type than x's or y's" #~ msgstr "le slot x résultant a un type différent que celui des x ou des y" #, fuzzy #~ msgid "dimensions must be numeric of length 2" #~ msgstr "la valeur de dim(.) doit être numérique de longueur 2" #, fuzzy #~ msgid "'perm' must be numeric" #~ msgstr "'A' doit être une matrice carrée" #, fuzzy #~ msgid "'margin' must be 1 or 2" #~ msgstr "'ncol' doit être >= 0" #~ msgid "not-yet-implemented method for <%s> %%*%% <%s>" #~ msgstr "méthode pas encore implémentée pour <%s> %%*%% <%s>" #~ msgid "'boolArith = %d' not yet implemented" #~ msgstr "'boolArith = %d' n'est pas encore implémenté" #, fuzzy #~ msgid "'rcond' via sparse -> dense coercion" #~ msgstr "conversion automatique rcond(.) via sparse -> dense" #, fuzzy #~ msgid "invalid 'norm'" #~ msgstr "'data' incorrect" #, fuzzy #~ msgid "cannot coerce zsparseVector to dgCMatrix" #~ msgstr "" #~ "impossible de convertir automatiquement des 'NA's en modèle \"ngCMatrix\"" #, fuzzy #~ msgid "cannot coerce zsparseVector to dgeMatrix" #~ msgstr "" #~ "impossible de convertir automatiquement les 'NA's en \"nsparseVector\"" #~ msgid "" #~ "number of non zeros is smaller than 'nnz' because of duplicated (i,j)s" #~ msgstr "" #~ "le nombre de valeurs non nulles est plus petit que 'nnz' à cause de (i,j) " #~ "dupliqués" #~ msgid "'times >= 0' is required" #~ msgstr "'times >= 0' est requis" #~ msgid "'giveCsparse' has been deprecated; setting 'repr = \"%s\"' for you" #~ msgstr "'giveCsparse' est obsolète ; j’ai mis 'repr = \"%s\"' pour vous" #~ msgid "Matrices must have same number of rows in %s" #~ msgstr "Les matrices doivent avoir le même nombre de lignes dans %s" #~ msgid "Matrices must have same number of columns in %s" #~ msgstr "Les matrices doivent avoir le même nombre de colonnes dans %s" #, fuzzy #~ msgid "only lists of length 2 can be coerced to indMatrix" #~ msgstr "" #~ "un objet \"Matrix\" avec NAs ne peut être converti automatiquement en " #~ "\"nMatrix\"" #, fuzzy #~ msgid "only 2-dimensional tables can be coerced to sparseMatrix" #~ msgstr "" #~ "seules des tables bidimensionnelles peuvent être automatiquement " #~ "converties en matrices éparses" #, fuzzy #~ msgid "matrix is not symmetric or" #~ msgstr "'x' n'est ni symétrique ni triangulaire" #, fuzzy #~ msgid "triangular" #~ msgstr "ce n'est pas une matrice triangulaire" #, fuzzy #~ msgid "matrix is not" #~ msgstr "la matrice n'est pas diagonale" #~ msgid "'x' is not positive definite -- chol() undefined." #~ msgstr "'x' n'est pas positif fini --chol() non défini." #~ msgid "Matrices must have same dimensions in %s" #~ msgstr "Les matrices doivent avoir les mêmes dimensions en %s" #~ msgid "names(dimnames()) must be NULL or of length two" #~ msgstr "names(dimnames()) doit être NULL ou de longueur deux" #~ msgid "[[ suppressing %d column names %s ]]" #~ msgstr "[[ suppression de %d noms de colonnes %s ]]" #~ msgid "'x' must be \"sparseMatrix\"" #~ msgstr "'x' doit être \"sparseMatrix\"" #~ msgid "not yet implemented for matrix with typeof %s" #~ msgstr "pas encore implémenté pour une matrice avec typeof %s" #~ msgid "not yet implemented for %s" #~ msgstr "pas encore implémenté pour %s" #~ msgid "" #~ "Quadratic matrix '%s' (=: A) is not formally\n" #~ "\tsymmetric. Will be treated as\tA A'" #~ msgstr "" #~ "La matrice quadratique '%s' (=: A) n'est pas formellement\n" #~ "\tsymétrique. Elle sera traitée comme \tA A'" #~ msgid "" #~ "'update' must be logical or '+' or '-'; 'C' a matrix, and 'L' a " #~ "\"CHMfactor\"" #~ msgstr "" #~ "'update' doit être une valeur booléenne ou '+' ou '-' ; 'C' doit être une " #~ "matrice, et 'L' un \"CHMfactor\"" #~ msgid "update must be TRUE/FALSE or '+' or '-'" #~ msgstr "update doit être TRUE/FALSE ou '+' ou '-'" #~ msgid "Matrix-internal error in [i,,d]; please report" #~ msgstr "" #~ "Erreur interne d'objet Matrix dans [i,,d] ; veuillez envoyer un " #~ "rapport" #~ msgid "" #~ "Cholesky() -> *symbolic* factorization -- not yet implemented" #~ msgstr "" #~ "Cholesky() -> factorisation *symbolique* -- pas encore " #~ "implémentée" #~ msgid "" #~ "as.matrix() is deprecated (to become a no-op in the future).\n" #~ "Use as(x, \"matrix\") or .asmatrix(x) instead." #~ msgstr "" #~ "as.matrix() est obsolète (va disparaître dans le futur).\n" #~ "Utilisez as(x, \"matrix\") ou .asmatrix(x) à la place." #~ msgid "" #~ "as.array() is deprecated. Use as(x, \"matrix\") or .asmatrix(x) " #~ "instead." #~ msgstr "" #~ "as.array() est obsolète. Utilisez as(x, \"matrix\") ou ." #~ "asmatrix(x) à la place." #~ msgid "trimmed mean of 'sparseVector' -- suboptimally using as.numeric(.)" #~ msgstr "" #~ "moyenne élaguée du 'sparseVector' -- utilisation suboptimale de as." #~ "numeric()" #~ msgid "invalid dimnames given for %s object" #~ msgstr "dimnames incorrects fournis pour l'objet %s" #~ msgid "" #~ "dimnames(.) <- NULL: translated to \n" #~ "dimnames(.) <- list(NULL,NULL) <==> unname(.)" #~ msgstr "" #~ "dimnames(.) <- NULL : traduit en \n" #~ "dimnames(.) <- list(NULL,NULL) <==> unname(.)" #~ msgid "" #~ "'nrow', 'ncol', etc, are disregarded when 'data' is \"Matrix\" already" #~ msgstr "" #~ "'nrow', 'ncol', etc, sont ignorés lorsque 'data' est déjà un objet " #~ "\"Matrix\"" #~ msgid "complex matrices not yet implemented in Matrix package" #~ msgstr "" #~ "les matrices complexes ne sont pas encore implémentées dans le package " #~ "Matrix" #~ msgid "using slow kronecker() method" #~ msgstr "utilisation de la méthode lente kronecker()" #~ msgid "" #~ "Cholesky(A) called for 'A' of class \"%s\";\n" #~ "\t it is currently defined for sparseMatrix only; consider using chol() " #~ "instead" #~ msgstr "" #~ "Cholesky(A) appelé pour 'A' de classe \"%s\" :\n" #~ "\t est actuellement défini pour sparseMatrix seulement ; considérez " #~ "utiliser chol() à la place" #~ msgid "invalid or not-yet-implemented 'Matrix' subsetting" #~ msgstr "" #~ "extraction d'un sous-ensemble de 'Matrix' incorrect ou pas encore " #~ "implémenté" #~ msgid "[ ] : .M.sub.i.logical() maybe inefficient" #~ msgstr "[ ] : .M.sub.i.logical() peut être inefficace" #~ msgid "" #~ "nargs() = %d. Extraneous illegal arguments inside '[ .. ]' (i.logical)?" #~ msgstr "" #~ "nargs() = %d. Arguments additionnels dans '[…]' inacceptables (i." #~ "logical) ?" #~ msgid "" #~ "m[]: inefficiently indexing single elements - should not " #~ "happen, please report!" #~ msgstr "" #~ "m[] : indice sur un seul élément inefficace - ne devrait pas " #~ "se produire, veuillez faire un rapport de ceci !" #~ msgid "" #~ "nargs() = %d. Extraneous illegal arguments inside '[ .. ]' (i.2col)?" #~ msgstr "" #~ "nargs() = %d. Arguments additionnels dans '[ .. ]' incorrects (i.2col) ?" #~ msgid "" #~ ".M.sub.i.2col(): 'i' has no integer column number;\n" #~ " should never happen; please report" #~ msgstr "" #~ ".M.sub.i.2col() : 'i' n'a pas un nombre entier de colonnes;\n" #~ " ceci ne devrait jamais se produire. Veuillez envoyer un rapport de bogue" #~ msgid "not-yet-implemented coercion to \"TsparseMatrix\"" #~ msgstr "conversion automatique en \"TsparseMatrix\" pas encore implémentée" #~ msgid "Matrix-internal error in [i,,d]; please report" #~ msgstr "" #~ "Erreur interne de matrice dans [i,,d] ; veuillez reporter ceci" #~ msgid "FIXME: NOT YET FINISHED IMPLEMENTATION" #~ msgstr "FIXME : IMPLEMENTATION PAS ENCORE TERMINEE" #~ msgid "diagonalMatrix in .dense2C() -- should never happen, please report!" #~ msgstr "" #~ "diagonalMatrix dans .dense2C() -- ne devrait jamais se produire, veuillez " #~ "reporter ceci !" #~ msgid "undefined method for class %s" #~ msgstr "méthode non définie pour la classe %s" #~ msgid "dimensions don't match the number of cells" #~ msgstr "les dimensions ne correspondent pas au nombre de cellules" #~ msgid "" #~ "LU computationally singular: ratio of extreme entries in |diag(U)| = %9.4g" #~ msgstr "" #~ "LU calculée singulière : rapport d'entrées extrêmes dans |diag(U)| = %9.4g" #~ msgid "RHS 'b' has wrong number of rows:" #~ msgstr "Le membre droit 'b' a un nombre de lignes incorrect :" #~ msgid "'x' has invalid data type" #~ msgstr "'x' a un type de données incorrect" #~ msgid "length(x) must be either 1 or #{cols}" #~ msgstr "length(x) doit être soit 1 ou #{cols}" #~ msgid "some arguments are not matrices" #~ msgstr "certains arguments ne sont pas des matrices" #~ msgid "%s kind not yet implemented" #~ msgstr "le type %s n'est pas encore implémenté" #~ msgid "non-square matrix" #~ msgstr "matrice non carrée" #~ msgid "" #~ "matrix with non-zero off-diagonals cannot be coerced to \"diagonalMatrix\"" #~ msgstr "" #~ "une matrice avec des cellules non nulles hors diagonale ne peut être " #~ "convertie automatiquement en \"diagonalMatrix\"" #~ msgid "non-matching dimensions" #~ msgstr "dimensions incohérentes" #~ msgid "not a positive definite matrix" #~ msgstr "matrice qui n'est pas un définie positive" #~ msgid "" #~ "as(.,\"dsCMatrix\") is deprecated (since 2008); do use as(., " #~ "\"symmetricMatrix\")" #~ msgstr "" #~ "as(.,\"dsCMatrix\") est obsolète (depuis 2008) ; utilisez plutôt as(., " #~ "\"symmetricMatrix\")" #~ msgid "inefficient coercion (lost triangularity); please report" #~ msgstr "" #~ "conversion automatique inefficace (triangularité perdue) ; veuillez " #~ "reporter ceci" #~ msgid "coercion to \"indMatrix\" only works from integer numeric" #~ msgstr "" #~ "la conversion automatique en \"indMatrix\" ne fonctionne que pour des " #~ "nombres entiers" #~ msgid "" #~ "coercion from list(i1,...,ik, d) to \"indMatrix\" failed.\n" #~ " All entries must be integer valued and the number of columns, d, not " #~ "smaller\n" #~ " than the maximal index i*." #~ msgstr "" #~ "la conversion automatique depuis list(i1,...,ik, d) en \"indMatrix\" a " #~ "échoué.\n" #~ " Toutes les entrées doivent être des valeurs entières et le nombre de " #~ "colonnes, d, ne peut être plus petit\n" #~ " que l'indice maximal i*." #~ msgid "the number of non-zero entries differs from nrow(.)" #~ msgstr "le nombre d'entrées non zéro diffère de nrow(.)" #~ msgid "resulting matrix dimension would be too large" #~ msgstr "la matrice résultante serait trop large" #~ msgid "replacing \"indMatrix\" entries is not allowed, as rarely sensible" #~ msgstr "" #~ "le replacement d'entrées \"indMatrix\" n'est pas autorisé, c'est rarement " #~ "judicieux" #~ msgid "temporarily disabled" #~ msgstr "temporairement désactivé" #~ msgid "cannot coerce NA values to pattern \"ntCMatrix\"" #~ msgstr "" #~ "impossible de convertir automatiquement des 'NA's en modèle \"ntCMatrix\"" #~ msgid "coercion to \"pMatrix\" only works from integer numeric" #~ msgstr "" #~ "conversion automatique en \"pMatrix\" ne fonctionne que pour des nombres " #~ "entiers" #~ msgid "not a square matrix" #~ msgstr "ce n'est pas une matrice carrée" #~ msgid "NA's in (i,j) are not allowed" #~ msgstr "NAs dans (i,j) ne sont pas permis" #~ msgid "" #~ "Both 'symmetric' and 'triangular', i.e. asking for diagonal matrix. Use " #~ "'Diagonal()' instead" #~ msgstr "" #~ "À la fois 'symmetric' et 'triangular', i.e. requête pour une matrice " #~ "diagonale. Utilisez 'Diagonal()' à la place" #~ msgid "triangular matrix must have all i >= j or i <= j" #~ msgstr "la matrice triangulaire doit avoir tous ses i >= j ou i <= j" #~ msgid "Matrix-internal error in [i,,d]; please report" #~ msgstr "" #~ "Erreur interne de matrice dans [i,,d] ; veuillez reporter ceci" #~ msgid "" #~ "qr.R() may differ from qr.R() because of permutations. " #~ "Possibly use our qrR() instead" #~ msgstr "" #~ "qr.R() peut être différent de qr.R() en raison des " #~ "permutations. Utilisez éventuellement notre qrR() à la place" #~ msgid "(un)packing only applies to dense matrices, class(x)='%s'" #~ msgstr "" #~ "la (dé)compaction ne s'applique qu'à des matrices denses, class(x)='%s'" #~ msgid "'x' is not symmetric -- chol() undefined." #~ msgstr "'x' n'est pas symétrique -- chol() non défini." #~ msgid "" #~ "extra argument %s will be disregarded in\n" #~ " %s" #~ msgid_plural "" #~ "extra arguments %s will be disregarded in\n" #~ " %s" #~ msgstr[0] "" #~ "l’argument supplémentaire %s n’est pas utilisé dans\n" #~ " %s" #~ msgstr[1] "" #~ "les arguments supplémentaires %s ne sont pas utilisés dans\n" #~ " %s" #~ msgid " %s %s is undefined" #~ msgstr " %s %s est indéfini" #~ msgid "%s %s is undefined" #~ msgstr "%s %s est indéfini" #~ msgid "variable '%s' converted to a factor" #~ msgstr "variable '%s' converti en facteur" #~ msgid "\"dMatrix\" object with NAs cannot be coerced to \"nMatrix\"" #~ msgstr "" #~ "un objet \"dMatrix\" avec NAs ne peut être converti automatiquement en " #~ "\"nMatrix\"" #~ msgid "not a skinny matrix" #~ msgstr "pas une matrice légère" #~ msgid "longer object length" #~ msgstr "la longueur de l'objet le plus long" #~ msgid "is not a multiple of shorter object length" #~ msgstr "n'est pas un multiple de l'objet le plus court" Matrix/po/de.po0000644000176200001440000015553314521047060013077 0ustar liggesusers# Translation of Matrix to German # Copyright (C) 2001-2021 The R Foundation # This file is distributed under the same license as the Matrix package. # Chris Leick , 2009-2011. # Detlef Steuer , 2012-2021. msgid "" msgstr "" "Project-Id-Version: R 4.0.4 / Matrix 1.3-3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-11-02 21:33-0400\n" "PO-Revision-Date: 2021-02-11 13:00+0100\n" "Last-Translator: Detlef Steuer \n" "Language-Team: R Core \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: Csparse.c:26 Csparse.c:318 chm_common.c:165 chm_common.c:291 #: chm_common.c:813 chm_common.c:816 chm_common.c:849 chm_common.c:867 #: dgCMatrix.c:18 dgCMatrix.c:43 dgCMatrix.c:70 dgCMatrix.c:84 dgCMatrix.c:89 #: dgCMatrix.c:94 #, fuzzy, c-format msgid "'%s' failed" msgstr "cs_qr fehlgeschlagen" #: Csparse.c:35 chm_common.c:54 #, fuzzy, c-format msgid "'%s' slot is not increasing within columns after sorting" msgstr "Slot j ist nicht zunehmend innerhalb einer Spalte" #: Csparse.c:77 coerce.c:220 coerce.c:240 coerce.c:250 coerce.c:905 #: coerce.c:911 coerce.c:1015 coerce.c:1501 coerce.c:1521 coerce.c:1531 #: coerce.c:2061 coerce.c:2256 coerce.c:2262 coerce.c:2268 coerce.c:2397 #: coerce.c:2404 coerce.c:2494 coerce.c:2629 coerce.c:2707 coerce.c:2729 #: coerce.c:4327 coerce.c:4396 dense.c:701 products.c:936 products.c:1288 #: solve.c:719 solve.c:968 solve.c:1100 sparse.c:1233 sparse.c:1625 #, fuzzy, c-format msgid "invalid '%s' to '%s'" msgstr "ungültiges '%s' Argument" #: Csparse.c:316 #, fuzzy, c-format msgid "failed to open file \"%s\" for writing" msgstr "Öffnen von Datei '%s' zum Schreiben fehlgeschlagen" #: attrib.c:229 #, fuzzy msgid "invalid factor name" msgstr "ungültiges '%s' Argument" #: attrib.c:233 #, c-format msgid "attempt to set factor on %s without '%s' slot" msgstr "" #: bind.c:46 bind.c:153 msgid "number of rows of matrices must match" msgstr "" #: bind.c:48 bind.c:155 msgid "number of columns of matrices must match" msgstr "" #: bind.c:51 bind.c:158 bind.c:182 bind.c:206 chm_common.c:474 chm_common.c:623 #: chm_common.c:717 cholmod-etc.c:183 cholmod-etc.c:282 cholmod-etc.c:325 #: coerce.c:215 coerce.c:235 coerce.c:260 coerce.c:268 coerce.c:276 #: coerce.c:341 coerce.c:1496 coerce.c:1516 coerce.c:1543 coerce.c:1551 #: coerce.c:1559 products.c:28 products.c:50 products.c:56 #, c-format msgid "dimensions cannot exceed %s" msgstr "" #: bind.c:210 msgid "number of rows of result is not a multiple of vector length" msgstr "" #: bind.c:212 msgid "number of columns of result is not a multiple of vector length" msgstr "" #: bind.c:626 bind.c:691 sparse.c:912 sparse.c:993 #, c-format msgid "%s cannot exceed %s" msgstr "" #: bind.c:756 bind.c:853 chm_common.c:720 cholmod-etc.c:328 coerce.c:29 #: coerce.c:518 coerce.c:811 coerce.c:945 coerce.c:2772 coerce.c:3041 #: coerce.c:3139 dense.c:924 products.c:151 products.c:212 products.c:291 #: products.c:379 products.c:456 products.c:550 products.c:865 subscript.c:1232 #: subscript.c:1417 utils-R.c:32 #, c-format msgid "attempt to allocate vector of length exceeding %s" msgstr "" #: bind.c:858 products.c:1354 msgid "should never happen ..." msgstr "" #: chm_common.c:11 chm_common.c:34 validity.c:38 validity.c:183 validity.c:262 #: validity.c:281 validity.c:290 validity.c:309 validity.c:335 validity.c:355 #: validity.c:405 validity.c:422 validity.c:456 validity.c:473 validity.c:507 #: validity.c:509 validity.c:959 validity.c:992 validity.c:1074 validity.c:1094 #: validity.c:1160 validity.c:1162 validity.c:1210 validity.c:1273 #: validity.c:1275 validity.c:1321 validity.c:1368 validity.c:1417 #: validity.c:1450 validity.c:1460 validity.c:1473 validity.c:1527 #: validity.c:1529 validity.c:1561 validity.c:1573 validity.c:1596 #: validity.c:1659 validity.c:1678 validity.c:1680 validity.c:1712 #: validity.c:1747 validity.c:1775 #, fuzzy, c-format msgid "'%s' slot is not of type \"%s\"" msgstr "Dim-Slot ist nicht ganzzahlig" #: chm_common.c:14 validity.c:357 validity.c:407 validity.c:458 validity.c:880 #: validity.c:891 validity.c:961 validity.c:994 validity.c:1096 validity.c:1164 #: validity.c:1212 validity.c:1277 validity.c:1323 validity.c:1462 #: validity.c:1479 validity.c:1531 validity.c:1533 validity.c:1563 #: validity.c:1575 validity.c:1598 validity.c:1714 validity.c:1751 #: validity.c:1779 validity.c:1829 #, fuzzy, c-format msgid "'%s' slot does not have length %s" msgstr "Dim-Slot muss die Länge 2 haben" #: chm_common.c:18 validity.c:410 validity.c:461 validity.c:1667 #: validity.c:1687 validity.c:1689 #, fuzzy, c-format msgid "first element of '%s' slot is not 0" msgstr "erstes Element von Slot p muss Null sein" #: chm_common.c:23 chm_common.c:46 validity.c:43 validity.c:361 validity.c:414 #: validity.c:432 validity.c:465 validity.c:483 validity.c:519 validity.c:521 #: validity.c:1041 validity.c:1053 validity.c:1100 validity.c:1173 #: validity.c:1185 validity.c:1286 validity.c:1298 validity.c:1327 #: validity.c:1378 validity.c:1427 validity.c:1466 validity.c:1486 #: validity.c:1567 validity.c:1583 validity.c:1608 validity.c:1672 #: validity.c:1692 validity.c:1694 validity.c:1721 #, c-format msgid "'%s' slot contains NA" msgstr "" #: chm_common.c:26 validity.c:416 validity.c:467 #, fuzzy, c-format msgid "'%s' slot is not nondecreasing" msgstr "Slot p darf nicht abnehmend sein" #: chm_common.c:29 validity.c:418 validity.c:469 #, c-format msgid "first differences of '%s' slot exceed %s" msgstr "" #: chm_common.c:37 validity.c:424 validity.c:475 #, fuzzy, c-format msgid "'%s' slot has length less than %s" msgstr "'Dim'-Slot hat eine Länge kleiner zwei" #: chm_common.c:49 validity.c:363 validity.c:434 validity.c:485 validity.c:523 #: validity.c:526 validity.c:1043 validity.c:1102 validity.c:1175 #: validity.c:1187 validity.c:1288 validity.c:1300 validity.c:1380 #: validity.c:1429 validity.c:1488 validity.c:1610 validity.c:1723 #, fuzzy, c-format msgid "'%s' slot has elements not in {%s}" msgstr "'Dim'-Slot hat eine Länge kleiner zwei" #: chm_common.c:467 chm_common.c:470 chm_common.c:472 chm_common.c:616 #: chm_common.c:619 chm_common.c:621 chm_common.c:711 chm_common.c:713 #: cholmod-etc.c:177 cholmod-etc.c:179 cholmod-etc.c:181 cholmod-etc.c:276 #: cholmod-etc.c:278 cholmod-etc.c:280 cholmod-etc.c:319 cholmod-etc.c:321 #: cs-etc.c:43 #, c-format msgid "wrong '%s'" msgstr "" #: chm_common.c:477 cholmod-etc.c:186 #, fuzzy, c-format msgid "'%s' would overflow type \"%s\"" msgstr "Dim-Slot ist nicht ganzzahlig" #: chm_common.c:481 cholmod-etc.c:190 #, c-format msgid "n+1 would overflow type \"%s\"" msgstr "" #: chm_common.c:486 cholmod-etc.c:195 #, fuzzy, c-format msgid "leading principal minor of order %d is not positive" msgstr "der führende Minor der Ordnung %d ist nicht positiv definit" #: chm_common.c:489 cholmod-etc.c:198 #, fuzzy, c-format msgid "leading principal minor of order %d is zero" msgstr "der führende Minor der Ordnung %d ist nicht positiv definit" #: chm_common.c:715 cholmod-etc.c:323 msgid "leading dimension not equal to number of rows" msgstr "" #: chm_common.c:778 #, c-format msgid "" "invalid simplicial Cholesky factorization: structural zero on main diagonal " "in column %d" msgstr "" #: chm_common.c:838 #, fuzzy, c-format msgid "CHOLMOD error '%s' at file '%s', line %d" msgstr "Cholmod-Fehler '%s' bei Datei %s, Zeile %d" #: chm_common.c:841 #, fuzzy, c-format msgid "CHOLMOD warning '%s' at file '%s', line %d" msgstr "Cholmod-Warnung '%s' bei Datei %s, Zeile %d" #: coerce.c:24 coerce.c:364 coerce.c:1050 #, fuzzy, c-format msgid "attempt to construct non-square %s" msgstr "Determinante benötigt eine quadratische Matrix" #: coerce.c:186 coerce.c:476 coerce.c:1467 coerce.c:1622 #, c-format msgid "second argument of '%s' does not specify a subclass of %s" msgstr "" #: coerce.c:194 coerce.c:200 coerce.c:484 coerce.c:490 coerce.c:925 #: coerce.c:1475 coerce.c:1481 coerce.c:1630 coerce.c:1636 coerce.c:2275 #: coerce.c:3344 coerce.c:3349 #, fuzzy, c-format msgid "'%s' must be \"%s\" or \"%s\"" msgstr "'%s' muss in '%s' sein" #: coerce.c:246 coerce.c:496 coerce.c:793 coerce.c:917 coerce.c:1527 #: coerce.c:1642 dense.c:322 dense.c:1107 dense.c:1683 dense.c:1688 #: dense.c:1934 dense.c:2129 sparse.c:783 sparse.c:2448 sparse.c:3140 #: sparse.c:3145 sparse.c:3150 sparse.c:3426 sparse.c:3663 #, fuzzy, c-format msgid "'%s' must be %s or %s" msgstr "'%s' muss in '%s' sein" #: coerce.c:266 coerce.c:274 coerce.c:285 coerce.c:1549 coerce.c:1557 #: coerce.c:1568 msgid "nonempty vector supplied for empty matrix" msgstr "" #: coerce.c:287 coerce.c:1570 #, c-format msgid "vector length (%lld) exceeds matrix length (%d * %d)" msgstr "" #: coerce.c:290 coerce.c:1573 #, c-format msgid "matrix length (%d * %d) is not a multiple of vector length (%lld)" msgstr "" #: coerce.c:521 #, c-format msgid "coercing n-by-n %s to %s is not supported for n*n exceeding %s" msgstr "" #: coerce.c:525 coerce.c:815 coerce.c:949 #, c-format msgid "sparse->dense coercion: allocating vector of size %0.1f GiB" msgstr "" #: coerce.c:1196 coerce.c:1941 coerce.c:2948 coerce.c:2954 #, c-format msgid "attempt to construct %s with more than %s nonzero entries" msgstr "" #: coerce.c:3246 #, fuzzy msgid "attempt to pack non-square matrix" msgstr "Determinante benötigt eine quadratische Matrix" #: coerce.c:3420 coerce.c:3590 #, c-format msgid "unable to aggregate %s with '%s' and '%s' slots of length exceeding %s" msgstr "" #: coerce.c:4211 #, fuzzy, c-format msgid "attempt to pack a %s" msgstr "Determinante benötigt eine quadratische Matrix" #: coerce.c:4330 dense.c:1237 sparse.c:2579 #, fuzzy, c-format msgid "'%s' must be %s or %s or %s" msgstr "'%s' muss in '%s' sein" #: dense.c:210 dense.c:215 sparse.c:590 sparse.c:595 #, fuzzy, c-format msgid "'%s' must be an integer from %s to %s" msgstr "'%s' muss in '%s' sein" #: dense.c:218 sparse.c:598 #, fuzzy, c-format msgid "'%s' must be less than or equal to '%s'" msgstr "'%s' muss in '%s' sein" #: dense.c:428 sparse.c:1069 #, fuzzy, c-format msgid "replacement diagonal has incompatible type \"%s\"" msgstr "Diagonale zur Ersetzung hat die falsche Länge" #: dense.c:437 sparse.c:1078 msgid "replacement diagonal has wrong length" msgstr "Diagonale zur Ersetzung hat die falsche Länge" #: dense.c:627 sparse.c:1274 #, fuzzy msgid "attempt to symmetrize a non-square matrix" msgstr "Determinante benötigt eine quadratische Matrix" #: dense.c:726 sparse.c:1652 msgid "attempt to get symmetric part of non-square matrix" msgstr "" #: dense.c:878 sparse.c:2082 msgid "attempt to get skew-symmetric part of non-square matrix" msgstr "" #: dense.c:1678 sparse.c:3135 #, fuzzy, c-format msgid "'%s' must be %d or %d" msgstr "'%s' muss in '%s' sein" #: dense.c:2161 #, c-format msgid "incorrect left cyclic shift, j (%d) < 0" msgstr "falsches zyklisches Linksverschieben, j (%d) < 0" #: dense.c:2164 #, c-format msgid "incorrect left cyclic shift, j (%d) >= k (%d)" msgstr "falsches zyklisches Linksverschieben, j (%d) >= k (%d)" #: dense.c:2167 #, c-format msgid "incorrect left cyclic shift, k (%d) > ldx (%d)" msgstr "falsches zyklisches Linksverschieben, k (%d) > ldx (%d)" #: dense.c:2220 #, fuzzy msgid "unknown error in getGivens" msgstr "Unbekannter Fehler in getGivens" #: dense.c:2229 dense.c:2243 dense.c:2273 msgid "X must be a numeric (double precision) matrix" msgstr "X muss eine numerische (doppelte Genauigkeit) Matrix sein" #: dense.c:2245 dense.c:2275 msgid "y must be a numeric (double precision) matrix" msgstr "y muss eine numerische (doppelte Genauigkeit) Matrix sein" #: dense.c:2249 dense.c:2279 #, c-format msgid "number of rows in y (%d) does not match number of rows in X (%d)" msgstr "" "Anzahl der Zeilen in y (%d) passt nicht zur Anzahl der Zeilen in X (%d)" # http://de.wikipedia.org/wiki/LAPACK #: dense.c:2265 #, fuzzy, c-format msgid "LAPACK dposv returned error code %d" msgstr "Lapack-Routine dposv gab Fehlerkode %d zurück" #: dense.c:2293 dense.c:2299 #, fuzzy, c-format msgid "LAPACK dgels returned error code %d" msgstr "Lapack-Routine %s gab einen Fehlerkode %d zurück" #: dense.c:2318 msgid "X must be a real (numeric) matrix" msgstr "X muss eine echte (numerische) Matrix sein" #: dense.c:2321 #, fuzzy, c-format msgid "tol, given as %g, must be >= 0" msgstr "tol, als %g gegeben, muss <= 1 sein" #: dense.c:2323 #, c-format msgid "tol, given as %g, must be <= 1" msgstr "tol, als %g gegeben, muss <= 1 sein" #: dense.c:2352 dense.c:2360 #, fuzzy, c-format msgid "LAPACK dgeqrf returned error code %d" msgstr "Erster Aufruf von dgeqrf gab Fehlerkode %d zurück" #: dense.c:2365 dense.c:2388 #, fuzzy, c-format msgid "LAPACK dtrcon returned error code %d" msgstr "Lapack-Routine dtrcon gab Fehlerkode %d zurück" #: determinant.c:33 #, fuzzy msgid "determinant of non-square matrix is undefined" msgstr "Determinante benötigt eine quadratische Matrix" #: determinant.c:276 #, fuzzy, c-format msgid "%s(<%s>) does not support structurally rank deficient case" msgstr "%s(): Fall mit strukturellem Rangdefizit: evtl FALSCHE Nullen" #: dgCMatrix.c:14 #, fuzzy, c-format msgid "'%s' is empty or not square" msgstr "Matrix ist nicht quadratisch" #: dgCMatrix.c:16 dgCMatrix.c:38 dgCMatrix.c:61 solve.c:43 solve.c:984 #, fuzzy, c-format msgid "dimensions of '%s' and '%s' are inconsistent" msgstr "Dimensionen des Systems sind inkonsistent" #: dgCMatrix.c:40 #, c-format msgid "%s(%s, %s) requires m-by-n '%s' with m >= n > 0" msgstr "" #: dgCMatrix.c:63 #, c-format msgid "%s(%s, %s) requires m-by-n '%s' with n >= m > 0" msgstr "" #: dgeMatrix.c:22 #, fuzzy, c-format msgid "dgeMatrix_svd(x,*): dim(x)[j] = %d is too large" msgstr "Matrix dimension %d x %d (= %g) ist zu groß" #: dgeMatrix.c:90 msgid "Matrix exponential requires square, non-null matrix" msgstr "Exponentielle Matrix benötigt eine quadratische Matrix ungleich Null" #: dgeMatrix.c:107 dgeMatrix.c:109 #, c-format msgid "dgeMatrix_exp: LAPACK routine dgebal returned %d" msgstr "dgeMatrix_exp: LAPACK-Routine dgebal gab %d zurück" #: dgeMatrix.c:147 #, c-format msgid "dgeMatrix_exp: dgetrf returned error code %d" msgstr "dgeMatrix_exp: dgetrf gab Fehlerkode %d zurück" #: dgeMatrix.c:149 #, c-format msgid "dgeMatrix_exp: dgetrs returned error code %d" msgstr "dgeMatrix_exp: dgetrs gab Fehlerkode %d zurück" #: dgeMatrix.c:224 msgid "dgeMatrix_Schur: argument x must be a non-null square matrix" msgstr "" "dgeMatrix_Schur: Argument x muss eine quadratische Matrix ungleich Null sein" #: dgeMatrix.c:237 msgid "dgeMatrix_Schur: first call to dgees failed" msgstr "dgeMatrix_Schur: Erster Aufruf von dgees fehlgeschlagen" #: dgeMatrix.c:246 #, c-format msgid "dgeMatrix_Schur: dgees returned code %d" msgstr "dgeMatrix_Schur: dgees gab Fehlerkode %d zurück" #: factorizations.c:355 sparse.c:196 #, fuzzy, c-format msgid "'%s' is not a number" msgstr "%s ist keine Liste" #: factorizations.c:376 #, c-format msgid "LU factorization of m-by-n %s requires m == n" msgstr "" #: factorizations.c:385 #, c-format msgid "LU factorization of %s failed: out of memory or near-singular" msgstr "" #: factorizations.c:462 #, c-format msgid "QR factorization of m-by-n %s requires m >= n" msgstr "" #: factorizations.c:471 #, c-format msgid "QR factorization of %s failed: out of memory" msgstr "" #: factorizations.c:571 factorizations.c:849 #, c-format msgid "'%s' is not a number or not finite" msgstr "" #: idz.c:467 idz.c:528 #, c-format msgid "incompatible '%s' and '%s' in '%s'" msgstr "" #: kappa.c:10 kappa.c:54 #, fuzzy, c-format msgid "argument '%s' is not of type \"%s\"" msgstr "Argument type[1]='%s' muss eine Zeichenkette aus einem Buchstaben sein" #: kappa.c:13 kappa.c:57 #, fuzzy, c-format msgid "argument '%s' has length %d" msgstr "'%s' muss die Zeichenkettenlänge 1 haben" #: kappa.c:17 kappa.c:61 #, fuzzy, c-format msgid "argument '%s' (\"%s\") does not have string length %d" msgstr "'%s' muss die Zeichenkettenlänge 1 haben" #: kappa.c:41 #, c-format msgid "" "argument '%s' (\"%s\") is not \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", or " "\"%s\"" msgstr "" #: kappa.c:75 #, fuzzy, c-format msgid "argument '%s' (\"%s\") is not \"%s\", \"%s\", or \"%s\"" msgstr "'%s' muss die Zeichenkettenlänge 1 haben" #: kappa.c:238 #, c-format msgid "%s(%s) is undefined: '%s' is not square" msgstr "" #: objects.c:23 #, c-format msgid "unexpected type \"%s\" in '%s'" msgstr "" #: objects.c:41 objects.c:58 #, c-format msgid "unexpected kind \"%c\" in '%s'" msgstr "" #: perm.c:26 perm.c:106 msgid "attempt to get sign of non-permutation" msgstr "" #: perm.c:51 perm.c:123 msgid "attempt to invert non-permutation" msgstr "" #: perm.c:66 #, fuzzy msgid "invalid transposition vector" msgstr "ungültiger Zeilenindex an Position %d" #: perm.c:79 perm.c:81 perm.c:96 perm.c:98 perm.c:113 perm.c:133 perm.c:145 #, fuzzy, c-format msgid "'%s' is not of type \"%s\"" msgstr "Dim-Slot ist nicht ganzzahlig" #: perm.c:83 perm.c:100 perm.c:147 #, fuzzy, c-format msgid "'%s' does not have length %d" msgstr "Slot '%s' muss die Länge 1 haben" #: perm.c:86 perm.c:103 #, c-format msgid "'%s' is NA" msgstr "" #: perm.c:115 perm.c:138 #, fuzzy, c-format msgid "'%s' or '%s' is not of type \"%s\"" msgstr "Dim-Slot ist nicht ganzzahlig" #: perm.c:117 perm.c:140 #, fuzzy, c-format msgid "'%s' or '%s' does not have length %d" msgstr "Slot '%s' muss die Länge 1 haben" #: perm.c:120 perm.c:143 #, c-format msgid "'%s' or '%s' is NA" msgstr "" #: perm.c:136 #, c-format msgid "'%s' has length exceeding %s" msgstr "" #: perm.c:150 #, c-format msgid "'%s' is NA or less than %s" msgstr "" #: products.c:107 products.c:210 products.c:289 products.c:377 products.c:454 #: products.c:548 products.c:809 products.c:859 msgid "non-conformable arguments" msgstr "" #: products.c:782 products.c:807 #, c-format msgid "'%s' does not support complex matrices" msgstr "" #: solve.c:38 #, fuzzy, c-format msgid "'%s' is not square" msgstr "Matrix ist nicht quadratisch" #: solve.c:497 #, c-format msgid "%s(<%s>, <%s>) failed: out of memory" msgstr "" #: solve.c:618 #, fuzzy, c-format msgid "attempt to construct %s with more than %s nonzero elements" msgstr "Determinante benötigt eine quadratische Matrix" #: sparseVector.c:90 #, c-format msgid "%s length cannot exceed %s" msgstr "" #: subscript.c:1542 subscript.c:1695 subscript.c:1938 subscript.c:2122 #, c-format msgid "%s too dense for %s; would have more than %s nonzero entries" msgstr "" #: subscript.c:2209 #, c-format msgid "NA subscripts in %s not supported for '%s' inheriting from %s" msgstr "" #: t_Csparse_subassign.c:142 msgid "invalid class of 'x' in Csparse_subassign()" msgstr "ungültige Klasse von 'x' in Csparse_subassign()" #: t_Csparse_subassign.c:144 msgid "invalid class of 'value' in Csparse_subassign()" msgstr "ungültige Klasse von 'value' in Csparse_subassign()" #: t_Csparse_subassign.c:187 #, c-format msgid "x[] <- val: val is coerced to logical for \"%s\" x" msgstr "x[] <- val: val in booleschen Wert umgewandelt für \"%s\" x" #: t_Csparse_subassign.c:192 #, c-format msgid "" "x[] <- val: val should be integer or logical, is coerced to integer, for " "\"%s\" x" msgstr "" "x[] <- val: val sollte ganzzahlig oder logisch sein, wird in ganze Zahl " "umgewandelt für \"%s\" x" #: t_Csparse_subassign.c:199 msgid "programming error in Csparse_subassign() should never happen" msgstr "Fehler in Csparse_subassign(); sollte niemals vorkommen" #: utils-R.c:30 utils-R.c:116 #, c-format msgid "indices would exceed %s" msgstr "" #: utils-R.c:235 utils-R.c:270 utils-R.c:281 utils-R.c:312 msgid "Argument must be numeric-like atomic vector" msgstr "Argument muss zahl-ähnlich atomar sein" #: utils-R.c:345 msgid "'data' must be of a vector type" msgstr "'data' muss ein Vektortyp sein" #: utils-R.c:352 #, c-format msgid "invalid '%s' argument" msgstr "ungültiges '%s' Argument" #: utils-R.c:359 utils-R.c:367 msgid "non-numeric matrix extent" msgstr "nicht-numerische Matrix-Ausdehnung" #: utils-R.c:362 msgid "invalid 'nrow' value (too large or NA)" msgstr "unzulässiger Wert für 'nrow' (zu groß oder NA)" #: utils-R.c:364 msgid "invalid 'nrow' value (< 0)" msgstr "unzulässiger Wert für 'nrow' (< 0)" #: utils-R.c:370 msgid "invalid 'ncol' value (too large or NA)" msgstr "unzulässiger Wert für 'ncol' (zu groß oder NA)" #: utils-R.c:372 msgid "invalid 'ncol' value (< 0)" msgstr "unzulässiger Wert für 'ncol' (< 0)" #: utils-R.c:390 #, c-format msgid "" "data length [%d] is not a sub-multiple or multiple of the number of rows [%d]" msgstr "" "Datenlänge [%d] ist kein Teilvielfaches oder Vielfaches der Zahl der Zeilen " "[%d]" #: utils-R.c:395 #, c-format msgid "" "data length [%d] is not a sub-multiple or multiple of the number of columns " "[%d]" msgstr "" "Datenlänge [%d] ist kein Teilvielfaches oder Vielfaches der Zahl der Spalten " "[%d]" #: utils-R.c:399 msgid "data length exceeds size of matrix" msgstr "Datenlänge überschreitet Größe der Matrix" #: utils-R.c:404 msgid "too many elements specified" msgstr "zu viele Elemente angegeben" #: utils-R.c:545 msgid "Argument ij must be 2-column integer matrix" msgstr "Argument ij muss eine zweispaltige ganzzahlige Matrix sein" #: utils-R.c:570 msgid "subscript 'i' out of bounds in M[ij]" msgstr "Subskript 'i' außerhalb des Bereichs in M[ij]" #: utils-R.c:572 msgid "subscript 'j' out of bounds in M[ij]" msgstr "Subskript 'j' außerhalb des Bereichs in M[ij]" #: utils-R.c:626 msgid "i and j must be integer vectors of the same length" msgstr "i und j müssen Ganzzahlvektoren mit der gleichen Länge sein" #: validity.c:40 validity.c:73 validity.c:264 validity.c:283 validity.c:292 #: validity.c:311 validity.c:337 validity.c:1010 validity.c:1452 #: validity.c:1476 #, fuzzy, c-format msgid "'%s' slot does not have length %d" msgstr "Dim-Slot muss die Länge 2 haben" #: validity.c:45 validity.c:965 validity.c:998 #, fuzzy, c-format msgid "'%s' slot has negative elements" msgstr "'Dim'-Slot hat eine Länge kleiner zwei" #: validity.c:71 validity.c:197 #, fuzzy, c-format msgid "'%s' slot is not a list" msgstr "Dim-Slot ist nicht ganzzahlig" #: validity.c:89 #, fuzzy, c-format msgid "%s[[%d]] is not NULL or a vector" msgstr "Dimnames[%d] ist kein Zeichenkettenvektor" #: validity.c:92 #, fuzzy, c-format msgid "length of %s[[%d]] (%lld) is not equal to %s[%d] (%d)" msgstr "length(Dimnames[%d]() unterscheidet sich von Dim[%d], was %d ist" #: validity.c:203 #, c-format msgid "'%s' slot has no '%s' attribute" msgstr "" #: validity.c:214 validity.c:277 validity.c:305 validity.c:376 validity.c:1115 #: validity.c:1446 validity.c:1807 #, c-format msgid "%s[1] != %s[2] (matrix is not square)" msgstr "" #: validity.c:239 validity.c:252 #, c-format msgid "%s[1] differs from %s[2]" msgstr "" #: validity.c:267 validity.c:286 validity.c:295 validity.c:314 #, fuzzy, c-format msgid "'%s' slot is not \"%s\" or \"%s\"" msgstr "x-Slot ist kein \\\"double\\\"" #: validity.c:320 validity.c:324 #, fuzzy, c-format msgid "'%s' slot is \"%s\" but '%s' slot does not have length %s" msgstr "Dim-Slot muss die Länge 2 haben" #: validity.c:340 #, fuzzy, c-format msgid "'%s' slot is not %d or %d" msgstr "x-Slot ist kein \\\"double\\\"" #: validity.c:346 validity.c:349 #, c-format msgid "%s-by-%s %s invalid for positive '%s' when %s=%d" msgstr "" #: validity.c:386 validity.c:1178 validity.c:1190 validity.c:1291 #: validity.c:1303 validity.c:1383 validity.c:1432 validity.c:1491 #, c-format msgid "'%s' slot contains duplicates" msgstr "" #: validity.c:437 validity.c:1613 #, fuzzy, c-format msgid "'%s' slot is not increasing within columns" msgstr "Slot j ist nicht zunehmend innerhalb einer Spalte" #: validity.c:488 #, fuzzy, c-format msgid "'%s' slot is not increasing within rows" msgstr "Slot j ist nicht zunehmend innerhalb einer Spalte" #: validity.c:512 validity.c:801 validity.c:827 validity.c:853 validity.c:1076 #: validity.c:1682 validity.c:1684 #, fuzzy, c-format msgid "'%s' and '%s' slots do not have equal length" msgstr "Dim-Slot muss die Länge 2 haben" #: validity.c:515 #, c-format msgid "'%s' slot has nonzero length but %s is 0" msgstr "" #: validity.c:555 validity.c:600 validity.c:646 validity.c:691 validity.c:735 #: validity.c:770 #, fuzzy, c-format msgid "%s=\"%s\" but there are entries below the diagonal" msgstr "" "uplo='U' darf keine dünn besetzten Einträge unterhalb der Diagonale haben" #: validity.c:565 validity.c:613 validity.c:656 validity.c:704 validity.c:740 #: validity.c:781 #, fuzzy, c-format msgid "%s=\"%s\" but there are entries above the diagonal" msgstr "" "uplo='L' darf keine dünn besetzten Einträge unterhalb der Diagonale haben" #: validity.c:603 validity.c:616 validity.c:694 validity.c:707 validity.c:773 #: validity.c:784 #, fuzzy, c-format msgid "%s=\"%s\" but there are entries on the diagonal" msgstr "" "uplo='U' darf keine dünn besetzten Einträge unterhalb der Diagonale haben" #: validity.c:911 validity.c:935 validity.c:939 msgid "matrix has negative diagonal elements" msgstr "" #: validity.c:955 validity.c:983 validity.c:987 msgid "matrix has nonunit diagonal elements" msgstr "" #: validity.c:1007 validity.c:1032 validity.c:1826 #, fuzzy, c-format msgid "'%s' slot is not of type \"%s\" or \"%s\"" msgstr "Dim-Slot ist nicht ganzzahlig" #: validity.c:1015 validity.c:1022 #, fuzzy, c-format msgid "'%s' slot is NA" msgstr "Dim-Slot ist nicht ganzzahlig" #: validity.c:1017 validity.c:1024 #, fuzzy, c-format msgid "'%s' slot is negative" msgstr "'Dim'-Slot hat eine Länge kleiner zwei" #: validity.c:1026 #, fuzzy, c-format msgid "'%s' slot exceeds %s" msgstr "'%s' muss in '%s' sein" #: validity.c:1036 #, fuzzy, c-format msgid "'%s' slot has length greater than '%s' slot" msgstr "'Dim'-Slot hat eine Länge kleiner zwei" #: validity.c:1046 validity.c:1674 validity.c:1696 validity.c:1698 #, fuzzy, c-format msgid "'%s' slot is not increasing" msgstr "Slot j ist nicht zunehmend innerhalb einer Spalte" #: validity.c:1056 #, fuzzy, c-format msgid "'%s' slot has elements not in {%s} after truncation towards zero" msgstr "'Dim'-Slot hat eine Länge kleiner zwei" #: validity.c:1059 #, fuzzy, c-format msgid "'%s' slot is not increasing after truncation towards zero" msgstr "Slot j ist nicht zunehmend innerhalb einer Spalte" #: validity.c:1125 validity.c:1152 validity.c:1814 validity.c:1821 #, fuzzy, c-format msgid "dimensions of '%s' slot are not identical to '%s'" msgstr "Dimensionen von x und y sind nicht kompatibel für %s" #: validity.c:1127 #, c-format msgid "'%s' slot is upper (not lower) triangular" msgstr "" #: validity.c:1140 #, c-format msgid "'%s' slot has nonunit diagonal elements" msgstr "" #: validity.c:1154 #, c-format msgid "'%s' slot is lower (not upper) triangular" msgstr "" #: validity.c:1166 validity.c:1279 validity.c:1370 validity.c:1419 #, fuzzy, c-format msgid "'%s' slot does not have length %s or length %s" msgstr "Dim-Slot muss die Länge 2 haben" #: validity.c:1206 msgid "matrix has more columns than rows" msgstr "" #: validity.c:1226 #, fuzzy, c-format msgid "'%s' slot has fewer than %s rows" msgstr "'Dim'-Slot hat eine Länge kleiner zwei" #: validity.c:1228 #, fuzzy, c-format msgid "'%s' slot has more than %s rows" msgstr "'Dim'-Slot hat eine Länge kleiner zwei" #: validity.c:1230 validity.c:1252 #, fuzzy, c-format msgid "'%s' slot does not have %s columns" msgstr "Dim-Slot muss die Länge 2 haben" #: validity.c:1237 #, fuzzy, c-format msgid "'%s' slot must be lower trapezoidal but has entries above the diagonal" msgstr "" "uplo='L' darf keine dünn besetzten Einträge unterhalb der Diagonale haben" #: validity.c:1250 #, fuzzy, c-format msgid "'%s' slot does not have %s row" msgstr "Dim-Slot muss die Länge 2 haben" #: validity.c:1259 #, fuzzy, c-format msgid "'%s' slot must be upper trapezoidal but has entries below the diagonal" msgstr "" "uplo='U' darf keine dünn besetzten Einträge unterhalb der Diagonale haben" #: validity.c:1263 #, c-format msgid "'%s' slot has negative diagonal elements" msgstr "" #: validity.c:1329 #, c-format msgid "'%s' slot has elements not in {%s}\\{%s}" msgstr "" #: validity.c:1338 #, c-format msgid "'%s' slot has unpaired negative elements" msgstr "" #: validity.c:1364 validity.c:1408 validity.c:1412 validity.c:1760 #: validity.c:1792 msgid "Cholesky factor has negative diagonal elements" msgstr "" #: validity.c:1455 #, fuzzy, c-format msgid "%s[%d] (%s) is not in %s" msgstr "%s ist keine Liste" #: validity.c:1468 validity.c:1569 #, fuzzy, c-format msgid "%s is not in {%s}" msgstr "%s ist keine Liste" #: validity.c:1505 #, c-format msgid "%s is not representable as \"%s\"" msgstr "" #: validity.c:1510 validity.c:1516 #, c-format msgid "%s[%d] (%s) is not %d or %d" msgstr "" #: validity.c:1513 validity.c:1629 validity.c:1632 validity.c:1635 #, c-format msgid "%s[%d] (%s) is not %d" msgstr "" #: validity.c:1538 #, c-format msgid "%s has elements not in {%s}" msgstr "" #: validity.c:1541 #, c-format msgid "%s has elements not in {%s}\\{%s}" msgstr "" #: validity.c:1544 #, c-format msgid "%s is %d but columns are not stored in increasing order" msgstr "" #: validity.c:1547 validity.c:1550 #, c-format msgid "traversal of '%s' slot does not complete in exactly %s steps" msgstr "" #: validity.c:1556 validity.c:1558 #, fuzzy, c-format msgid "%s is not %d" msgstr "%s ist keine Liste" #: validity.c:1579 #, c-format msgid "column '%s' is stored first but %s is not 0" msgstr "" #: validity.c:1585 #, fuzzy, c-format msgid "'%s' slot is not increasing when traversed in stored column order" msgstr "Slot j ist nicht zunehmend innerhalb einer Spalte" #: validity.c:1587 #, c-format msgid "'%s' slot allocates fewer than %s elements for column '%s'" msgstr "" #: validity.c:1590 #, c-format msgid "'%s' slot allocates more than %s elements for column '%s'" msgstr "" #: validity.c:1604 #, c-format msgid "first entry in column '%s' does not have row index '%s'" msgstr "" #: validity.c:1638 validity.c:1641 #, c-format msgid "%s[%d] (%s) is negative" msgstr "" #: validity.c:1644 #, c-format msgid "%s[%d] (%s) is not less than %s" msgstr "" #: validity.c:1662 #, fuzzy, c-format msgid "'%s' slot has length less than %d" msgstr "'Dim'-Slot hat eine Länge kleiner zwei" #: validity.c:1664 #, fuzzy, c-format msgid "'%s' slot has length greater than %s" msgstr "'Dim'-Slot hat eine Länge kleiner zwei" #: validity.c:1669 #, fuzzy, c-format msgid "last element of '%s' slot is not %s" msgstr "erstes Element von Slot p muss Null sein" #: validity.c:1702 #, c-format msgid "first differences of '%s' slot are less than those of '%s' slot" msgstr "" #: validity.c:1705 #, c-format msgid "supernode lengths exceed %s" msgstr "" #: validity.c:1707 #, c-format msgid "first differences of '%s' slot are not equal to supernode lengths" msgstr "" #: validity.c:1727 #, c-format msgid "" "'%s' slot is wrong within diagonal blocks (row and column indices do not " "coincide)" msgstr "" #: validity.c:1730 #, fuzzy, c-format msgid "'%s' slot is not increasing within supernodes" msgstr "Slot j ist nicht zunehmend innerhalb einer Spalte" #: validity.c:1845 #, fuzzy, c-format msgid "invalid class \"%s\" object: %s" msgstr "ungültige Klasse des Objektes zu %s" # http://www.matheboard.de/archive/160705/thread.html #, c-format #~ msgid "diagonal element %d of Cholesky factor is missing" #~ msgstr "Diagonalelement %d des Choleskyfaktors fehlt" #, c-format #~ msgid "cholmod_factorize_p failed: status %d, minor %d of ncol %d" #~ msgstr "cholmod_factorize_p fehlgeschlagen: Status %d, Minor %d von ncol %d" #~ msgid "cholmod_change_factor failed" #~ msgstr "cholmod_change_factor fehlgeschlagen" #~ msgid "cholmod_write_sparse returned error code" #~ msgstr "cholmod_write_sparse gab Fehlerkode zurück" #, c-format #~ msgid "%s = '%s' (back-permuted) is experimental" #~ msgstr "%s = '%s' (zurückgetauscht) ist experimentell" #~ msgid "diag_tC(): invalid 'resultKind'" #~ msgstr "diag_tC(): 'resultKind' ungültig" #, fuzzy #~ msgid "complex matrices are not yet supported" #~ msgstr "Kode für komplexe dünn besetzte Matrizen noch nicht geschrieben" #~ msgid "Argument rho must be an environment" #~ msgstr "Argument rho muss eine Umgebung sein" #~ msgid "invalid class of object to as_cholmod_sparse" #~ msgstr "ungültige Klasse des Objektes zu as_cholmod_sparse" #~ msgid "invalid object passed to as_cholmod_sparse" #~ msgstr "ungültiges Objekt an as_cholmod_sparse übergeben" #~ msgid "in_place cholmod_sort returned an error code" #~ msgstr "in_place cholmod_sort gab einen Fehlerkode zurück" #~ msgid "cholmod_sort returned an error code" #~ msgstr "cholmod_sort gab einen Fehlerkode zurück" #~ msgid "chm_sparse_to_SEXP(, *): invalid 'Rkind' (real kind code)" #~ msgstr "chm_sparse_to_SEXP(, *): ungültiges 'Rkind' (echter Artkode)" #~ msgid "unknown xtype in cholmod_sparse object" #~ msgstr "unbekannter xtype in Objekt cholmod_sparse" #~ msgid "complex sparse matrix code not yet written" #~ msgstr "Kode für komplexe dünn besetzte Matrizen noch nicht geschrieben" #~ msgid "Symmetric and triangular both set" #~ msgstr "Symmetrisch und dreieckig sind beide gesetzt" #~ msgid "invalid class of object to as_cholmod_triplet" #~ msgstr "ungültige Klasse des Objektes zu as_cholmod_triplet" #~ msgid "as_cholmod_triplet(): could not reallocate for internal diagU2N()" #~ msgstr "" #~ "as_cholmod_triplet(): konnte für internes diagU2N() nicht reallozieren" #~ msgid "unknown xtype in cholmod_triplet object" #~ msgstr "unbekannter xtype in Objekt cholmod_triplet" #~ msgid "invalid class of object to as_cholmod_dense" #~ msgstr "ungültige Klasse des Objektes zu as_cholmod_dense" #, c-format #~ msgid "" #~ "chm_transpose_dense(ans, x) not yet implemented for %s different from %s" #~ msgstr "" #~ "chm_transpose_dense(ans, x) noch nicht implementiert für %s verschieden " #~ "von %s" #, c-format #~ msgid "Unable to initialize cholmod: error code %d" #~ msgstr "cholmod kann nicht initialisiert werden: Fehlerkode %d" #~ msgid "unknown 'Rkind'" #~ msgstr "'Rkind' unbekannt" #~ msgid "unknown xtype" #~ msgstr "unbekannter xtype" #~ msgid "code for cholmod_dense with holes not yet written" #~ msgstr "Kode für cholmod_dense mit Löchern noch nicht geschrieben" #~ msgid "don't know if a dense pattern matrix makes sense" #~ msgstr "es ist nicht klar, ob eine dicht besetzte Mustermatrix sinnvoll ist" #, fuzzy #~ msgid "object of invalid class to 'as_cholmod_factor()'" #~ msgstr "ungültige Klasse des Objektes zu as_cholmod_factor" #~ msgid "failure in as_cholmod_factor" #~ msgstr "Misserfolg in as_cholmod_factor" #~ msgid "CHOLMOD factorization was unsuccessful" #~ msgstr "CHOLMOD-Faktorzerlegung war nicht erfolgreich" #, c-format #~ msgid "f->xtype of %d not recognized" #~ msgstr "f->xtype von %d nicht erkannt" #, c-format #~ msgid "chm_diagN2U(): nrow=%d, ncol=%d" #~ msgstr "chm_diagN2U(-matrix) requires a 'tall' rectangular matrix" #~ msgstr "" #~ "dgCMatrix_qrsol(<%d x %d>-Matrix) benötigt eine 'lange' rechteckige Matrix" #~ msgid "cs_qrsol() failed inside dgCMatrix_qrsol()" #~ msgstr "cs_qrsol() innerhalb dgCMatrix_qrsol() fehlgeschlagen" #~ msgid "dgCMatrix_cholsol requires a 'short, wide' rectangular matrix" #~ msgstr "dgCMatrix_cholsol benötigt eine kurze breite rechteckige Matrix" #~ msgid "cholmod_sdmult error (rhs)" #~ msgstr "cholmod_sdmult-Fehler (rhs)" #, c-format #~ msgid "cholmod_factorize failed: status %d, minor %d from ncol %d" #~ msgstr "cholmod_factorize fehlgeschlagen: Status %d, Minor %d von ncol %d" #, c-format #~ msgid "cholmod_solve (CHOLMOD_A) failed: status %d, minor %d from ncol %d" #~ msgstr "" #~ "cholmod_solve (CHOLMOD_A) fehlgeschlagen: Status %d, Minor %d von ncol %d" #~ msgid "cholmod_sdmult error (resid)" #~ msgstr "cholmod_sdmult-Fehler (resid)" #~ msgid "SuiteSparseQR_C_QR returned an error code" #~ msgstr "SuiteSparseQR_C_QR gab einen Fehlerkode zurück" #, fuzzy, c-format #~ msgid "LAPACK routine '%s': matrix is exactly singular, %s[i,i]=0, i=%d" #~ msgstr "Lapack-Routine dgetrs:: System ist exakt singulär" #, fuzzy, c-format #~ msgid "" #~ "LAPACK routine '%s': leading principal minor of order %d is not positive" #~ msgstr "der führende Minor der Ordnung %d ist nicht positiv definit" #, fuzzy #~ msgid "missing 'Matrix' namespace; should never happen" #~ msgstr "fehlender 'Matrix'-Namensraum: Sollte niemals vorkommen" #, fuzzy #~ msgid "'Matrix' namespace not determined correctly" #~ msgstr "Matrix-Namensraum nicht korrekt bestimmt" #~ msgid "Csparse_sort(x): x is not a valid (apart from sorting) CsparseMatrix" #~ msgstr "" #~ "Csparse_sort(x): x ist keine gültige (abgesehen vom Sortieren) " #~ "CsparseMatrix" #, c-format #~ msgid "Impossible Rk_x/Rk_y in Csparse_%s(), please report" #~ msgstr "Unmögliche Rk_x/Rk_y in Csparse_%s(). Bitte dem Entwickler melden!" #, c-format #~ msgid "chm_MOD_xtype() was not successful in Csparse_%s(), please report" #~ msgstr "" #~ "chm_MOD_xtype() nicht erfolgreich in Csparse_%s(). Bitte dem Entwickler " #~ "melden!" #, c-format #~ msgid "the number of columns differ in R_rbind2_vector: %d != %d" #~ msgstr "" #~ "die Anzahl der Spalten untescheidet sich in R_rbind2_vector: %d != %d" #~ msgid "csp_eye argument n must be positive" #~ msgstr "csp_eye-Argument n muss positiv sein" #~ msgid "invalid class of 'x' in Matrix_as_cs(a, x)" #~ msgstr "ungültige Klasse von 'x' in Matrix_as_cs(a, x)" #, c-format #~ msgid "invalid class of object to %s" #~ msgstr "ungültige Klasse des Objektes zu %s" #, c-format #~ msgid "cs matrix not compatible with class '%s'" #~ msgstr "cs-Matrix nicht kompatibel mit Klasse '%s'" #, c-format #~ msgid "Inappropriate class cl='%s' in Matrix_css_to_SEXP(S, cl, ..)" #~ msgstr "Unangemessene Klasse cl='%s' in Matrix_css_to_SEXP(S, cl, ..)" #, c-format #~ msgid "Inappropriate class cl='%s' in Matrix_csn_to_SEXP(S, cl, ..)" #~ msgstr "Unangemessene Klasse cl='%s' in Matrix_csn_to_SEXP(S, cl, ..)" #, c-format #~ msgid "Dimensions of x and y are not compatible for %s" #~ msgstr "Dimensionen von x und y sind nicht kompatibel für %s" #~ msgid "Argument y must be numeric, integer or logical" #~ msgstr "Argument y muss numerisch, ganzzahlig oder logisch sein" #~ msgid "Matrices are not conformable for multiplication" #~ msgstr "Matrizen sind nicht für Multiplikation konform" #, c-format #~ msgid "" #~ "dimension mismatch in matrix multiplication of \"dtrMatrix\": %d != %d" #~ msgstr "" #~ "Dimensionen passen nicht in Matrix multiplikation von \"dtrMatrix\": %d !" #~ "= %d" #~ msgid "dtrMatrix must be square" #~ msgstr "dtrMatrix muss quadratisch sein" #, c-format #~ msgid "Dimensions of a (%d,%d) and b (%d,%d) do not conform" #~ msgstr "Dimensionen von a (%d,%d) und b (%d,%d) sind nicht konform" #~ msgid "right=TRUE is not yet implemented __ FIXME" #~ msgstr "right=TRUE ist noch nicht implementiert __ FIXME" #, c-format #~ msgid "cholmod_change_factor failed with status %d" #~ msgstr "cholmod_change_factor mit Status %d fehlgeschlagen" #~ msgid "system argument is not valid" #~ msgstr "Systemargument ist nicht gültig" #, c-format #~ msgid "cholmod_updown() returned %d" #~ msgstr "cholmod_updown() gab Fehlerkode %d zurück" #~ msgid "cholmod_drop() failed" #~ msgstr "cholmod_drop() fehlgeschlagen" #, fuzzy #~ msgid "'off' does not have length 1" #~ msgstr "Slot '%s' muss die Länge 1 haben" #, fuzzy #~ msgid "invalid 'code' to 'R_matrix_as_dense()'" #~ msgstr "ungültige Klasse '%s' für dup_mMatrix_as_dgeMatrix" #, fuzzy #~ msgid "invalid 'uplo' to 'R_matrix_as_dense()'" #~ msgstr "ungültige Klasse '%s' für dup_mMatrix_as_dgeMatrix" #, fuzzy #~ msgid "invalid 'diag' to 'R_matrix_as_dense()'" #~ msgstr "ungültige Klasse '%s' für dup_mMatrix_as_dgeMatrix" #, fuzzy #~ msgid "invalid argument 'system'" #~ msgstr "ungültiges '%s' Argument" #, fuzzy #~ msgid "dimensions of 'qr' and 'y' are inconsistent" #~ msgstr "Dimensionen des Systems sind inkonsistent" #, fuzzy #~ msgid "invalid 'op'" #~ msgstr "ungültiges '%s' Argument" #, fuzzy #~ msgid "'names' must be TRUE or FALSE" #~ msgstr "'uplo' muss UPP oder LOW sein" #~ msgid "Csparse_crossprod(): error return from cholmod_aat()" #~ msgstr "Csparse_crossprod(): Fehler von cholmod_aat() zurückgegeben" #, fuzzy #~ msgid "invalid 'kind' to 'R_sparse_as_kind()'" #~ msgstr "ungültige Klasse von 'x' in Csparse_subassign()" #~ msgid "slot p must have length = nrow(.) + 1" #~ msgstr "Slot p muss Länge = nrow(.) + 1 haben" #~ msgid "last element of slot p must match length of slots j and x" #~ msgstr "" #~ "letztes Element von Slot p muss eine zu den Slots j und x passende Länge " #~ "haben" #~ msgid "all column indices must be between 0 and ncol-1" #~ msgstr "Alle Spaltenindizes müssen zwischen 0 und ncol-1 liegen" #~ msgid "slot j is not *strictly* increasing inside a column" #~ msgstr "Slot j ist nicht *strikt* zunehmend innerhalb einer Spalte" #~ msgid "Csparse_to_nz_pattern(x, tri = NA): 'tri' is taken as TRUE" #~ msgstr "Csparse_to_nz_pattern(x, tri = NA): 'tri' als TRUE angenommen" #~ msgid "not a 'n.CMatrix'" #~ msgstr "keine 'n.CMatrix'" #, c-format #~ msgid "nz2Csparse(): invalid/non-implemented r_kind = %d" #~ msgstr "nz2Csparse(): ungültiges/nicht implementiertes r_kind = %d" #~ msgid "Nonsymmetric matrix in Csparse_symmetric_to_general" #~ msgstr "Asymmetrische Matrix in Csparse_symmetric_to_general" #~ msgid "Csparse_general_to_symmetric(): matrix is not square!" #~ msgstr "Csparse_general_to_symmetric(): Matrix ist nicht quadratisch." #~ msgid "Index i must be NULL or integer" #~ msgstr "Index i muss NULL oder eine ganze Zahl sein" #~ msgid "Index j must be NULL or integer" #~ msgstr "Index j muss NULL oder eine ganze Zahl sein" #, c-format #~ msgid "negative vector lengths not allowed: np = %d, nnz = %d" #~ msgstr "negative Vektorlänge ist nicht erlaubt: np = %d, nnz = %d" #~ msgid "exactly 1 of 'i', 'j' or 'p' must be NULL" #~ msgstr "exakt 1 von 'i', 'j' oder 'p' muss NULL sein" #, c-format #~ msgid "np = %d, must be zero when p is NULL" #~ msgstr "np = %d, muss Null sein, wenn p NULL ist" #, c-format #~ msgid "p[0] = %d, should be zero" #~ msgstr "p[0] = %d, sollte Null sein" #~ msgid "p must be non-decreasing" #~ msgstr "p darf nicht abnehmend sein" #, c-format #~ msgid "Inconsistent dimensions: np = 0 and nnz = %d" #~ msgstr "Inkonsistente Dimensionen: np = 0 und nnz = %d" #, c-format #~ msgid "invalid column index at position %d" #~ msgstr "ungültiger Spaltenindex an Position %d" #, c-format #~ msgid "strlen of cls argument = %d, should be 8" #~ msgstr "strlen des cls-Arguments = %d, sollte 8 sein" #, c-format #~ msgid "cls = \"%s\" does not end in \"CMatrix\"" #~ msgstr "cls = '%s' endet nicht in 'CMatrix'" #, c-format #~ msgid "cls = \"%s\" must begin with 'd', 'l' or 'n'" #~ msgstr "cls = '%s' muss mit 'd', 'l' oder 'n' beginnen" #~ msgid "Only 'g'eneral sparse matrix types allowed" #~ msgstr "Nur 'g'enerelle dünn besetzte Matrixtypen erlaubt" #~ msgid "code not yet written for cls = \"lgCMatrix\"" #~ msgstr "Kode noch nicht für cls = 'lgCMatrix' geschrieben" #, c-format #~ msgid "%s must be (traditional R) matrix" #~ msgstr "%s muss eine traditionelle R Matrix sein" #, c-format #~ msgid "%s must be character string" #~ msgstr "%s muss eine Zeichenkette sein" #, c-format #~ msgid "nrow * ncol = %d * %d must equal length(x) = %ld" #~ msgstr "nrow * ncol = %d * %d muss gleich length(x) = %ld sein" #, c-format #~ msgid "strlen of cls argument = %d, should be 9" #~ msgstr "strlen des cls-Arguments = %d, sollte 9 sein" #, c-format #~ msgid "cls = \"%s\" must begin with 'd', 'l' or 'n' for now" #~ msgstr "cls = \"%s\" muss momentan mit 'd', 'l' oder 'n' beginnen" #, c-format #~ msgid "%s must be a logical or double vector" #~ msgstr "%s muss ein Boole'scher oder 'double' Vector sein" #, c-format #~ msgid "argument type[1]='%s' must be one of 'M','1','O','I','F' or 'E'" #~ msgstr "" #~ "Argument type[1]='%s' muss eins aus 'M', '1', 'O', 'I', 'F' oder 'E' sein" #, c-format #~ msgid "argument type[1]='%s' must be one of '1','O', or 'I'" #~ msgstr "Argument type[1]='%s' eins aus '1', 'O' oder 'I' sein" #~ msgid "object must be a named, numeric vector" #~ msgstr "Objekt muss ein benannter numerischer Vektor sein" #~ msgid "'factors' slot must be a named list" #~ msgstr "'factors'-Slot muss eine benannte Liste sein" #~ msgid "Matrix object has no 'factors' slot" #~ msgstr "Matrix Objekt hat keinen 'factors'-Slot" #~ msgid "'s1' and 's2' must be \"character\" vectors" #~ msgstr "'s1' und 's2' müssen 'character'-Vektoren sein" #~ msgid "length of x slot != prod(Dim)" #~ msgstr "Länge von x-Slot != prod(Dim)" #~ msgid "Negative value in Dim" #~ msgid_plural "Negative values in Dim" #~ msgstr[0] "Negativer Wert in Dim" #~ msgstr[1] "Negative Werte in Dim" #, c-format #~ msgid "%s is a list, but not of length 2" #~ msgstr "%s ist eine Liste, aber Länge ist nicht 2" #, c-format #~ msgid "invalid class '%s' to dup_mMatrix_as_geMatrix" #~ msgstr "ungültige Klasse '%s' für dup_mMatrix_as_geMatrix" #, c-format #~ msgid "unexpected ctype = %d in dup_mMatrix_as_geMatrix" #~ msgstr "unerwartetes ctype = %d in dup_mMatrix_as_geMatrix" #~ msgid "lengths of slots i and j must match" #~ msgstr "Längen der Slots i und j müssen passen" #~ msgid "slot Dim must have length 2" #~ msgstr "Slot Dim muss die Länge 2 haben" #~ msgid "" #~ "all row indices (slot 'i') must be between 0 and nrow-1 in a TsparseMatrix" #~ msgstr "" #~ "alle Zeilenindizes (slot 'i') müssen in TsparseMatrix zwischen 0 und " #~ "nrow-1 liegen" #~ msgid "" #~ "all column indices (slot 'j') must be between 0 and ncol-1 in a " #~ "TsparseMatrix" #~ msgstr "" #~ "Alle Spaltenindizes (slot 'j') müssen in TsparseMatrix zwischen 0 und " #~ "ncol-1 liegen" #~ msgid "Supernodal LDL' decomposition not available" #~ msgstr "Superknoten-LDL'-Zerlegung nicht verfügbar" #~ msgid "Supernodal/simplicial class inconsistent with type flags" #~ msgstr "Superknoten-/simpliziale Klasse inkonstent mit Typkennzeichen" #~ msgid "Number of supernodes must be positive when is_super is TRUE" #~ msgstr "Anzahl der Superknoten muss positiv sein, wenn is_super TRUE ist" #~ msgid "Lengths of super and pi must be equal" #~ msgstr "Längen von super und pi müssen gleich sein" #~ msgid "Lengths of super and px must be equal" #~ msgstr "Längen von super und px müssen gleich sein" #, c-format #~ msgid "First call to Lapack routine dgels returned error code %d" #~ msgstr "Erster Aufruf der Lapack-Routine dgels gab Fehlerkode %d zurück" #, c-format #~ msgid "Second call to Lapack routine dgels returned error code %d" #~ msgstr "Zweiter Aufruf der Lapack-Routine dgels gab Fehlerkode %d zurück" #, c-format #~ msgid "tol, given as %g, must be non-negative" #~ msgstr "tol, als %g gegeben, darf nicht negativ sein" #, c-format #~ msgid "Second call to dgeqrf returned error code %d" #~ msgstr "Zweiter Aufruf von dgeqrf gab Fehlerkode %d zurück" #, c-format #~ msgid "" #~ "dense_to_Csparse(): cholmod_l_dense_to_sparse failure status=%d" #~ msgstr "" #~ "dense_to_Csparse(): cholmod_l_dense_to_sparse Fehlerstatus=%d" #, c-format #~ msgid "" #~ "Matrix dimension %d x %d (= %g) too large [FIXME calling " #~ "cholmod_l_dense_to_sparse]" #~ msgstr "" #~ "Matrix dimension %d x %d (= %g) ist zu groß [FIXME mit " #~ "cholmod_l_dense_to_sparse]" #, c-format #~ msgid "Lower band %d > upper band %d" #~ msgstr "Unteres Band %d > oberes Band %d" #~ msgid "ddense_to_symmetric(): matrix is not square!" #~ msgstr "ddense_to_symmetric(): Matrix ist nicht quadratisch." #, c-format #~ msgid "matrix is not symmetric [%d,%d]" #~ msgstr "Matrix ist nicht symmetrisch [%d,%d]" #~ msgid "matrix is not square! (symmetric part)" #~ msgstr "Matrix ist nicht quadratisch. (symmetrischer Teil)" #~ msgid "matrix is not square! (skew-symmetric part)" #~ msgstr "Matrix ist nicht quadratisch. (schief-symmetrischer Teil)" #~ msgid "lengths of slots 'i' and 'x' must match" #~ msgstr "Längen der Slots 'i' und 'x' müssen übereinstimmen" #~ msgid "lengths of slots 'j' and 'x' must match" #~ msgstr "Längen der Slots 'j' und 'x' müssen übereinstimmen" #, c-format #~ msgid "invalid class(x) '%s' in compressed_to_TMatrix(x)" #~ msgstr "ungültige class(x) '%s' in compressed_to_TMatrix(x)" #, c-format #~ msgid "invalid class(x) '%s' in R_to_CMatrix(x)" #~ msgstr "ungültige class(x) '%s' in R_to_CMatrix(x)" #~ msgid "A must have #{rows} >= #{columns}" #~ msgstr "A muss #{rows} >= #{columns} haben" #~ msgid "cs_sqr failed" #~ msgstr "cs_sqr fehlgeschlagen" #~ msgid "dgcMatrix_QR(*, keep_dimnames = NA): NA taken as TRUE" #~ msgstr "dgcMatrix_QR(*, keep_dimnames = NA): NA taken as TRUE" #~ msgid "LU decomposition applies only to square matrices" #~ msgstr "LU-Zerlegung ist nur bei quadratischen Matrizen anwendbar" #~ msgid "cs_lu(A) failed: near-singular A (or out of memory)" #~ msgstr "" #~ "cs_lu(A) fehlgeschlagen: beinahe singuläres A (oder außerhalb des " #~ "Speichers)" #~ msgid "dgcMatrix_LU(*, keep_dimnames = NA): NA taken as TRUE" #~ msgstr "dgcMatrix_LU(*, keep_dimnames = NA): NA taken as TRUE" #~ msgid "dgCMatrix_matrix_solve(.., sparse=TRUE) not yet implemented" #~ msgstr "dgCMatrix_matrix_solve(.., sparse=TRUE) noch nicht implementiert" #~ msgid "lengths of slots i and x must match" #~ msgstr "Längen der Slots i und x müssen zusammen passen" #, c-format #~ msgid "too large matrix: %.0f" #~ msgstr "Matrix zu groß: %.0f" #, c-format #~ msgid "Cannot coerce to too large *geMatrix with %.0f entries" #~ msgstr "Kann nicht in eine große *geMatrix mit %.0f Einträgen umwandeln" #~ msgid "x slot must be numeric \"double\"" #~ msgstr "x-Slot muss ein numerischer 'double' Wert sein" #~ msgid "factors slot must be named list" #~ msgstr "Faktoren-Slot muss eine benannte Liste sein" #~ msgid "rcond requires a square, non-empty matrix" #~ msgstr "rcond benötigt eine quadratische, nicht leere Matrix" #~ msgid "diagonal to be added has wrong length" #~ msgstr "zu addierende Diagonale hat die falsche Länge" #~ msgid "Cannot factor a matrix with zero extents" #~ msgstr "Eine Matrix mit Umfang Null kann nicht berücksichtigt werden" #, c-format #~ msgid "Exact singularity detected during LU decomposition: %s, i=%d." #~ msgstr "Exakte Singularität während LU-Zerlegung entdeckt: %s, i=%d." #~ msgid "Solve requires a square matrix" #~ msgstr "Auflösen benötigt eine quadratische Matrix" #, c-format #~ msgid "error [%d] from Lapack 'dgecon()'" #~ msgstr "Fehler [%d] von Lapack-'dgecon()'" #, c-format #~ msgid "" #~ "Lapack dgecon(): system computationally singular, reciprocal condition " #~ "number = %g" #~ msgstr "" #~ "Lapack-dgecon(): System rechnerisch singulär, reziproke Konditionszahl = " #~ "%g" #~ msgid "Lapack routine dgetri: system is exactly singular" #~ msgstr "Lapack-Routine dgetri: System ist exakt singulär" #~ msgid "dpoMatrix is not positive definite" #~ msgstr "dpoMatrix ist nicht positiv definit" #~ msgid "Cannot solve() for matrices with zero extents" #~ msgstr "solve() für Matrizen mit Umfang Null nicht möglich" #~ msgid "Argument b must be a numeric matrix" #~ msgstr "Argument b muss eine numerische Matrix sein" #~ msgid "chm_factor_name(): did not get string of length 11" #~ msgstr "chm_factor_name(): habe keine Zeichenkette der Länge 11 bekommen" #~ msgid "" #~ "Cholesky factorization failed; unusually, please report to Matrix-authors" #~ msgstr "" #~ "Cholesky-Faktorisierung fehlgeschlagen; ungewöhnlich, bitte an Matrix-" #~ "authors melden!" #~ msgid "internal_chm_factor: Cholesky factorization failed" #~ msgstr "internal_chm_factor: Cholesky-Faktorisierung fehlgeschlagen" #~ msgid "Non-symmetric matrix passed to dsCMatrix_to_dgTMatrix" #~ msgstr "Nicht symmetrische Matrix an dsCMatrix_to_dgTMatrix übergeben" #~ msgid "Incorrect length of 'x' slot" #~ msgstr "Falsche Länge von 'x'-Slot" #, c-format #~ msgid "Lapack routine dsytrf returned error code %d" #~ msgstr "Lapack-Routine dsytrf gab Fehlerkode %d zurück" #~ msgid "x must be a \"double\" (numeric) matrix" #~ msgstr "X muss eine \"double\" (numerische) Matrix sein" #~ msgid "matrix_trf(x, *): matrix is not square" #~ msgstr "ddense_to_symmetric(): Matrix ist nicht quadratisch" #~ msgid "matrix_trf(*, uplo): uplo must be string" #~ msgstr "" #~ "matrix_trf(*, uplo): uplo muss ein String (character, length(.) == 1) " #~ "sein." #~ msgid "cannot set diag() as long as 'diag = \"U\"'" #~ msgstr "kann diag() nicht setzen solange 'diag = \"U\"'" #~ msgid "cannot add diag() as long as 'diag = \"U\"'" #~ msgstr "kann diag() nicht hinzufügen solange 'diag = \"U\"'" #~ msgid "x slot is not of correct length" #~ msgstr "x-Slot hat nicht die richtige Länge" #~ msgid "A must be a logical matrix" #~ msgstr "A muss eine logische Matrix sein" #~ msgid "length(p) must match nrow(V)" #~ msgstr "length(p) muss zu nrow(V) passen" #~ msgid "length(beta) must match ncol(V)" #~ msgstr "length(beta) muss zu ncol(V) passen" #~ msgid "length(q) must be zero or ncol(R)" #~ msgstr "length(q) muss null oder ncol(R) sein" #, c-format #~ msgid "sparseQR_Qmult(): nrow(y) = %d != %d = nrow(V)" #~ msgstr "sparseQR_Qmult(): nrow(y) = %d != %d = nrow(V)" #, fuzzy #~ msgid "\"dtrMatrix\" objects in '%*%' must have matching (square) dimension" #~ msgstr "" #~ "Dimensionen von \"dtrMatrix\" Objekten in '%*%' müssen passen und " #~ "quadratisch sein" #~ msgid "not a CsparseMatrix" #~ msgstr "keine CsparseMatrix" #~ msgid "slot p must have length = ncol(.) + 1" #~ msgstr "Slot p muss Länge = ncol(.) + 1 haben" #~ msgid "last element of slot p must match length of slots i and x" #~ msgstr "" #~ "letztes Element von Slot p muss eine zu den Slots i und x passende Länge " #~ "haben" #~ msgid "all row indices must be between 0 and nrow-1" #~ msgstr "alle Zeilenindizes müssen zwischen 0 und nrow-1 liegen" #~ msgid "" #~ "slot i is not *strictly* increasing inside a column (even after " #~ "cholmod_l_sort)" #~ msgstr "" #~ "Slot i ist nicht *strikt* zunehmend innerhalb einer Spalte (sogar nach " #~ "cholmod_l_sort)" #~ msgid "row indices are not sorted within columns" #~ msgstr "Zeilenindizes sind nicht innerhalb von Spalten sortiert" #~ msgid "slot i is not *strictly* increasing inside a column" #~ msgstr "Slot i ist nicht *strikt* zunehmend innerhalb einer Spalte" #~ msgid "could not find correct environment; please report!" #~ msgstr "korrekte Umgebung konnte nicht gefunden werden. Bitte berichten!" #~ msgid "previous CHOLMOD factorization was unsuccessful" #~ msgstr "frühere CHOLMOD Faktorisierung war nicht erfolgreich" #~ msgid "Negative value(s) in Dim" #~ msgstr "Negative(r) Wert(e) in Dim" #~ msgid "cs_qrsol failed" #~ msgstr "cs_qrsol fehlgeschlagen" #~ msgid "p[np] = %d != nnz = %d" #~ msgstr "p[np] = %d != nnz = %d" #~ msgid "ncol(V) != ncol(R)" #~ msgstr "ncol(V) != ncol(R)" Matrix/po/fr.po0000644000176200001440000015545014521047060013114 0ustar liggesusers# Translation of Matrix messages to French # Copyright (C) 2001 The R Foundation # This file is distributed under the same license as the Matrix package. # Philippe Grosjean, 2014- msgid "" msgstr "" "Project-Id-Version: Matrix 1.1-1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-11-02 21:33-0400\n" "PO-Revision-Date: 2021-04-12 18:57+0200\n" "Last-Translator: Philippe Grosjean \n" "Language-Team: none\n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "X-Generator: Poedit 2.4.2\n" #: Csparse.c:26 Csparse.c:318 chm_common.c:165 chm_common.c:291 #: chm_common.c:813 chm_common.c:816 chm_common.c:849 chm_common.c:867 #: dgCMatrix.c:18 dgCMatrix.c:43 dgCMatrix.c:70 dgCMatrix.c:84 dgCMatrix.c:89 #: dgCMatrix.c:94 #, fuzzy, c-format msgid "'%s' failed" msgstr "cs_qr a échoué" #: Csparse.c:35 chm_common.c:54 #, fuzzy, c-format msgid "'%s' slot is not increasing within columns after sorting" msgstr "le slot j ne contient pas de valeurs croissantes au sein d'une colonne" #: Csparse.c:77 coerce.c:220 coerce.c:240 coerce.c:250 coerce.c:905 #: coerce.c:911 coerce.c:1015 coerce.c:1501 coerce.c:1521 coerce.c:1531 #: coerce.c:2061 coerce.c:2256 coerce.c:2262 coerce.c:2268 coerce.c:2397 #: coerce.c:2404 coerce.c:2494 coerce.c:2629 coerce.c:2707 coerce.c:2729 #: coerce.c:4327 coerce.c:4396 dense.c:701 products.c:936 products.c:1288 #: solve.c:719 solve.c:968 solve.c:1100 sparse.c:1233 sparse.c:1625 #, fuzzy, c-format msgid "invalid '%s' to '%s'" msgstr "argument '%s' incorrect" #: Csparse.c:316 #, fuzzy, c-format msgid "failed to open file \"%s\" for writing" msgstr "erreur lors de l'ouverture en écriture du fichier \"%s\"" #: attrib.c:229 #, fuzzy msgid "invalid factor name" msgstr "argument '%s' incorrect" #: attrib.c:233 #, c-format msgid "attempt to set factor on %s without '%s' slot" msgstr "" #: bind.c:46 bind.c:153 msgid "number of rows of matrices must match" msgstr "" #: bind.c:48 bind.c:155 msgid "number of columns of matrices must match" msgstr "" #: bind.c:51 bind.c:158 bind.c:182 bind.c:206 chm_common.c:474 chm_common.c:623 #: chm_common.c:717 cholmod-etc.c:183 cholmod-etc.c:282 cholmod-etc.c:325 #: coerce.c:215 coerce.c:235 coerce.c:260 coerce.c:268 coerce.c:276 #: coerce.c:341 coerce.c:1496 coerce.c:1516 coerce.c:1543 coerce.c:1551 #: coerce.c:1559 products.c:28 products.c:50 products.c:56 #, c-format msgid "dimensions cannot exceed %s" msgstr "" #: bind.c:210 msgid "number of rows of result is not a multiple of vector length" msgstr "" #: bind.c:212 msgid "number of columns of result is not a multiple of vector length" msgstr "" #: bind.c:626 bind.c:691 sparse.c:912 sparse.c:993 #, c-format msgid "%s cannot exceed %s" msgstr "" #: bind.c:756 bind.c:853 chm_common.c:720 cholmod-etc.c:328 coerce.c:29 #: coerce.c:518 coerce.c:811 coerce.c:945 coerce.c:2772 coerce.c:3041 #: coerce.c:3139 dense.c:924 products.c:151 products.c:212 products.c:291 #: products.c:379 products.c:456 products.c:550 products.c:865 subscript.c:1232 #: subscript.c:1417 utils-R.c:32 #, c-format msgid "attempt to allocate vector of length exceeding %s" msgstr "" #: bind.c:858 products.c:1354 msgid "should never happen ..." msgstr "" #: chm_common.c:11 chm_common.c:34 validity.c:38 validity.c:183 validity.c:262 #: validity.c:281 validity.c:290 validity.c:309 validity.c:335 validity.c:355 #: validity.c:405 validity.c:422 validity.c:456 validity.c:473 validity.c:507 #: validity.c:509 validity.c:959 validity.c:992 validity.c:1074 validity.c:1094 #: validity.c:1160 validity.c:1162 validity.c:1210 validity.c:1273 #: validity.c:1275 validity.c:1321 validity.c:1368 validity.c:1417 #: validity.c:1450 validity.c:1460 validity.c:1473 validity.c:1527 #: validity.c:1529 validity.c:1561 validity.c:1573 validity.c:1596 #: validity.c:1659 validity.c:1678 validity.c:1680 validity.c:1712 #: validity.c:1747 validity.c:1775 #, fuzzy, c-format msgid "'%s' slot is not of type \"%s\"" msgstr "Le slot Dim n’est pas un entier" #: chm_common.c:14 validity.c:357 validity.c:407 validity.c:458 validity.c:880 #: validity.c:891 validity.c:961 validity.c:994 validity.c:1096 validity.c:1164 #: validity.c:1212 validity.c:1277 validity.c:1323 validity.c:1462 #: validity.c:1479 validity.c:1531 validity.c:1533 validity.c:1563 #: validity.c:1575 validity.c:1598 validity.c:1714 validity.c:1751 #: validity.c:1779 validity.c:1829 #, fuzzy, c-format msgid "'%s' slot does not have length %s" msgstr "Le slot Dim doit avoir une longueur de 2" #: chm_common.c:18 validity.c:410 validity.c:461 validity.c:1667 #: validity.c:1687 validity.c:1689 #, fuzzy, c-format msgid "first element of '%s' slot is not 0" msgstr "le premier élément du slot p doit être à zéro" #: chm_common.c:23 chm_common.c:46 validity.c:43 validity.c:361 validity.c:414 #: validity.c:432 validity.c:465 validity.c:483 validity.c:519 validity.c:521 #: validity.c:1041 validity.c:1053 validity.c:1100 validity.c:1173 #: validity.c:1185 validity.c:1286 validity.c:1298 validity.c:1327 #: validity.c:1378 validity.c:1427 validity.c:1466 validity.c:1486 #: validity.c:1567 validity.c:1583 validity.c:1608 validity.c:1672 #: validity.c:1692 validity.c:1694 validity.c:1721 #, c-format msgid "'%s' slot contains NA" msgstr "" #: chm_common.c:26 validity.c:416 validity.c:467 #, fuzzy, c-format msgid "'%s' slot is not nondecreasing" msgstr "le slot p ne peut contenir de valeurs décroissantes" #: chm_common.c:29 validity.c:418 validity.c:469 #, c-format msgid "first differences of '%s' slot exceed %s" msgstr "" #: chm_common.c:37 validity.c:424 validity.c:475 #, fuzzy, c-format msgid "'%s' slot has length less than %s" msgstr "le slot 'Dim' a une longueur inférieure à deux" #: chm_common.c:49 validity.c:363 validity.c:434 validity.c:485 validity.c:523 #: validity.c:526 validity.c:1043 validity.c:1102 validity.c:1175 #: validity.c:1187 validity.c:1288 validity.c:1300 validity.c:1380 #: validity.c:1429 validity.c:1488 validity.c:1610 validity.c:1723 #, fuzzy, c-format msgid "'%s' slot has elements not in {%s}" msgstr "le slot 'Dim' a une longueur inférieure à deux" #: chm_common.c:467 chm_common.c:470 chm_common.c:472 chm_common.c:616 #: chm_common.c:619 chm_common.c:621 chm_common.c:711 chm_common.c:713 #: cholmod-etc.c:177 cholmod-etc.c:179 cholmod-etc.c:181 cholmod-etc.c:276 #: cholmod-etc.c:278 cholmod-etc.c:280 cholmod-etc.c:319 cholmod-etc.c:321 #: cs-etc.c:43 #, c-format msgid "wrong '%s'" msgstr "" #: chm_common.c:477 cholmod-etc.c:186 #, fuzzy, c-format msgid "'%s' would overflow type \"%s\"" msgstr "Le slot Dim n’est pas un entier" #: chm_common.c:481 cholmod-etc.c:190 #, c-format msgid "n+1 would overflow type \"%s\"" msgstr "" #: chm_common.c:486 cholmod-etc.c:195 #, fuzzy, c-format msgid "leading principal minor of order %d is not positive" msgstr "le 'leading minor of order' %d n'est pas un entier fini" #: chm_common.c:489 cholmod-etc.c:198 #, fuzzy, c-format msgid "leading principal minor of order %d is zero" msgstr "le 'leading minor of order' %d n'est pas un entier fini" #: chm_common.c:715 cholmod-etc.c:323 msgid "leading dimension not equal to number of rows" msgstr "" #: chm_common.c:778 #, c-format msgid "" "invalid simplicial Cholesky factorization: structural zero on main diagonal " "in column %d" msgstr "" #: chm_common.c:838 #, fuzzy, c-format msgid "CHOLMOD error '%s' at file '%s', line %d" msgstr "Erreur Cholmod '%s' dans le fichier %s, ligne %d" #: chm_common.c:841 #, fuzzy, c-format msgid "CHOLMOD warning '%s' at file '%s', line %d" msgstr "Avertissement Cholmod '%s' dans le fichier %s, ligne %d" #: coerce.c:24 coerce.c:364 coerce.c:1050 #, fuzzy, c-format msgid "attempt to construct non-square %s" msgstr "Determinant nécessite une matrice carrée" #: coerce.c:186 coerce.c:476 coerce.c:1467 coerce.c:1622 #, c-format msgid "second argument of '%s' does not specify a subclass of %s" msgstr "" #: coerce.c:194 coerce.c:200 coerce.c:484 coerce.c:490 coerce.c:925 #: coerce.c:1475 coerce.c:1481 coerce.c:1630 coerce.c:1636 coerce.c:2275 #: coerce.c:3344 coerce.c:3349 #, fuzzy, c-format msgid "'%s' must be \"%s\" or \"%s\"" msgstr "'%s' doit être compris dans '%s'" #: coerce.c:246 coerce.c:496 coerce.c:793 coerce.c:917 coerce.c:1527 #: coerce.c:1642 dense.c:322 dense.c:1107 dense.c:1683 dense.c:1688 #: dense.c:1934 dense.c:2129 sparse.c:783 sparse.c:2448 sparse.c:3140 #: sparse.c:3145 sparse.c:3150 sparse.c:3426 sparse.c:3663 #, fuzzy, c-format msgid "'%s' must be %s or %s" msgstr "'%s' doit être compris dans '%s'" #: coerce.c:266 coerce.c:274 coerce.c:285 coerce.c:1549 coerce.c:1557 #: coerce.c:1568 msgid "nonempty vector supplied for empty matrix" msgstr "" #: coerce.c:287 coerce.c:1570 #, c-format msgid "vector length (%lld) exceeds matrix length (%d * %d)" msgstr "" #: coerce.c:290 coerce.c:1573 #, c-format msgid "matrix length (%d * %d) is not a multiple of vector length (%lld)" msgstr "" #: coerce.c:521 #, c-format msgid "coercing n-by-n %s to %s is not supported for n*n exceeding %s" msgstr "" #: coerce.c:525 coerce.c:815 coerce.c:949 #, c-format msgid "sparse->dense coercion: allocating vector of size %0.1f GiB" msgstr "" #: coerce.c:1196 coerce.c:1941 coerce.c:2948 coerce.c:2954 #, c-format msgid "attempt to construct %s with more than %s nonzero entries" msgstr "" #: coerce.c:3246 #, fuzzy msgid "attempt to pack non-square matrix" msgstr "Determinant nécessite une matrice carrée" #: coerce.c:3420 coerce.c:3590 #, c-format msgid "unable to aggregate %s with '%s' and '%s' slots of length exceeding %s" msgstr "" #: coerce.c:4211 #, fuzzy, c-format msgid "attempt to pack a %s" msgstr "Determinant nécessite une matrice carrée" #: coerce.c:4330 dense.c:1237 sparse.c:2579 #, fuzzy, c-format msgid "'%s' must be %s or %s or %s" msgstr "'%s' doit être compris dans '%s'" #: dense.c:210 dense.c:215 sparse.c:590 sparse.c:595 #, fuzzy, c-format msgid "'%s' must be an integer from %s to %s" msgstr "'%s' doit être compris dans '%s'" #: dense.c:218 sparse.c:598 #, fuzzy, c-format msgid "'%s' must be less than or equal to '%s'" msgstr "'%s' doit être compris dans '%s'" #: dense.c:428 sparse.c:1069 #, fuzzy, c-format msgid "replacement diagonal has incompatible type \"%s\"" msgstr "la diagonale de remplacement a une longueur incorrecte" #: dense.c:437 sparse.c:1078 msgid "replacement diagonal has wrong length" msgstr "la diagonale de remplacement a une longueur incorrecte" #: dense.c:627 sparse.c:1274 #, fuzzy msgid "attempt to symmetrize a non-square matrix" msgstr "Determinant nécessite une matrice carrée" #: dense.c:726 sparse.c:1652 msgid "attempt to get symmetric part of non-square matrix" msgstr "" #: dense.c:878 sparse.c:2082 msgid "attempt to get skew-symmetric part of non-square matrix" msgstr "" #: dense.c:1678 sparse.c:3135 #, fuzzy, c-format msgid "'%s' must be %d or %d" msgstr "'%s' doit être compris dans '%s'" #: dense.c:2161 #, c-format msgid "incorrect left cyclic shift, j (%d) < 0" msgstr "décalage cyclique à gauche incorrect, j (%d) < 0" #: dense.c:2164 #, c-format msgid "incorrect left cyclic shift, j (%d) >= k (%d)" msgstr "décalage cyclique à gauche incorrect, j (%d) >= k (%d)" #: dense.c:2167 #, c-format msgid "incorrect left cyclic shift, k (%d) > ldx (%d)" msgstr "décalage cyclique à gauche incorrect, k (%d) > ldx (%d)" #: dense.c:2220 #, fuzzy msgid "unknown error in getGivens" msgstr "Erreur inconnue dans getGivens" #: dense.c:2229 dense.c:2243 dense.c:2273 msgid "X must be a numeric (double precision) matrix" msgstr "X doit être une matrice numérique (double précision)" #: dense.c:2245 dense.c:2275 msgid "y must be a numeric (double precision) matrix" msgstr "y doit être une matrice numérique (double précision)" #: dense.c:2249 dense.c:2279 #, c-format msgid "number of rows in y (%d) does not match number of rows in X (%d)" msgstr "" "le nombre de lignes de y (%d) ne correspond pas au nombre de lignes de X (%d)" #: dense.c:2265 #, fuzzy, c-format msgid "LAPACK dposv returned error code %d" msgstr "La routine Lapack dposv a renvoyé le code d'erreur %d" #: dense.c:2293 dense.c:2299 #, fuzzy, c-format msgid "LAPACK dgels returned error code %d" msgstr "La routine Lapack %s a renvoyé le code d'erreur %d" #: dense.c:2318 msgid "X must be a real (numeric) matrix" msgstr "X doit être une matrice (numérique) de réels" #: dense.c:2321 #, fuzzy, c-format msgid "tol, given as %g, must be >= 0" msgstr "tol, donné comme %g, doit être <= 1" #: dense.c:2323 #, c-format msgid "tol, given as %g, must be <= 1" msgstr "tol, donné comme %g, doit être <= 1" #: dense.c:2352 dense.c:2360 #, fuzzy, c-format msgid "LAPACK dgeqrf returned error code %d" msgstr "Le premier appel à dgeqrf a renvoyé le code d'erreur %d" #: dense.c:2365 dense.c:2388 #, fuzzy, c-format msgid "LAPACK dtrcon returned error code %d" msgstr "La routine Lapack dtrcon a renvoyé le code d'erreur %d" #: determinant.c:33 #, fuzzy msgid "determinant of non-square matrix is undefined" msgstr "Determinant nécessite une matrice carrée" #: determinant.c:276 #, fuzzy, c-format msgid "%s(<%s>) does not support structurally rank deficient case" msgstr "" "%s() : cas structurellement déficient de rang : probablement des zéros " "ERRONES" #: dgCMatrix.c:14 #, fuzzy, c-format msgid "'%s' is empty or not square" msgstr "Matrix n'est pas carrée" #: dgCMatrix.c:16 dgCMatrix.c:38 dgCMatrix.c:61 solve.c:43 solve.c:984 #, fuzzy, c-format msgid "dimensions of '%s' and '%s' are inconsistent" msgstr "Les dimensions du système à résoudre sont incohérentes" #: dgCMatrix.c:40 #, c-format msgid "%s(%s, %s) requires m-by-n '%s' with m >= n > 0" msgstr "" #: dgCMatrix.c:63 #, c-format msgid "%s(%s, %s) requires m-by-n '%s' with n >= m > 0" msgstr "" #: dgeMatrix.c:22 #, fuzzy, c-format msgid "dgeMatrix_svd(x,*): dim(x)[j] = %d is too large" msgstr "La dimension de l’objet Matrix %d x %d (= %g) est trop large" #: dgeMatrix.c:90 msgid "Matrix exponential requires square, non-null matrix" msgstr "L'exponentiation de matrice nécessite une matrice carrée non nulle" #: dgeMatrix.c:107 dgeMatrix.c:109 #, c-format msgid "dgeMatrix_exp: LAPACK routine dgebal returned %d" msgstr "dgeMatrix_exp : la routine LAPACK dgebal a renvoyé %d" #: dgeMatrix.c:147 #, c-format msgid "dgeMatrix_exp: dgetrf returned error code %d" msgstr "dgeMatrix_exp : dgetrf a renvoyé le code d'erreur %d" #: dgeMatrix.c:149 #, c-format msgid "dgeMatrix_exp: dgetrs returned error code %d" msgstr "dgeMatrix_exp : dgetrs a renvoyé le code d'erreur %d" #: dgeMatrix.c:224 msgid "dgeMatrix_Schur: argument x must be a non-null square matrix" msgstr "dgeMatrix_Schur : l'argument x doit être une matrice carrée non nulle" #: dgeMatrix.c:237 msgid "dgeMatrix_Schur: first call to dgees failed" msgstr "dgeMatrix_Schur : le premier appel à dgees a échoué" #: dgeMatrix.c:246 #, c-format msgid "dgeMatrix_Schur: dgees returned code %d" msgstr "dgeMatrix_Schur : dgees a renvoyé le code d'erreur %d" #: factorizations.c:355 sparse.c:196 #, fuzzy, c-format msgid "'%s' is not a number" msgstr "%s n’est pas une liste" #: factorizations.c:376 #, c-format msgid "LU factorization of m-by-n %s requires m == n" msgstr "" #: factorizations.c:385 #, c-format msgid "LU factorization of %s failed: out of memory or near-singular" msgstr "" #: factorizations.c:462 #, c-format msgid "QR factorization of m-by-n %s requires m >= n" msgstr "" #: factorizations.c:471 #, c-format msgid "QR factorization of %s failed: out of memory" msgstr "" #: factorizations.c:571 factorizations.c:849 #, c-format msgid "'%s' is not a number or not finite" msgstr "" #: idz.c:467 idz.c:528 #, c-format msgid "incompatible '%s' and '%s' in '%s'" msgstr "" #: kappa.c:10 kappa.c:54 #, fuzzy, c-format msgid "argument '%s' is not of type \"%s\"" msgstr "" "l'argument type[1]='%s' doit être une chaîne de caractères à une seule lettre" #: kappa.c:13 kappa.c:57 #, fuzzy, c-format msgid "argument '%s' has length %d" msgstr "'%s' doit avoir une longueur de chaîne de caractères de 1" #: kappa.c:17 kappa.c:61 #, fuzzy, c-format msgid "argument '%s' (\"%s\") does not have string length %d" msgstr "'%s' doit avoir une longueur de chaîne de caractères de 1" #: kappa.c:41 #, c-format msgid "" "argument '%s' (\"%s\") is not \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", or " "\"%s\"" msgstr "" #: kappa.c:75 #, fuzzy, c-format msgid "argument '%s' (\"%s\") is not \"%s\", \"%s\", or \"%s\"" msgstr "'%s' doit avoir une longueur de chaîne de caractères de 1" #: kappa.c:238 #, c-format msgid "%s(%s) is undefined: '%s' is not square" msgstr "" #: objects.c:23 #, c-format msgid "unexpected type \"%s\" in '%s'" msgstr "" #: objects.c:41 objects.c:58 #, c-format msgid "unexpected kind \"%c\" in '%s'" msgstr "" #: perm.c:26 perm.c:106 msgid "attempt to get sign of non-permutation" msgstr "" #: perm.c:51 perm.c:123 msgid "attempt to invert non-permutation" msgstr "" #: perm.c:66 #, fuzzy msgid "invalid transposition vector" msgstr "indices de lignes erronés à la position %d" #: perm.c:79 perm.c:81 perm.c:96 perm.c:98 perm.c:113 perm.c:133 perm.c:145 #, fuzzy, c-format msgid "'%s' is not of type \"%s\"" msgstr "Le slot Dim n’est pas un entier" #: perm.c:83 perm.c:100 perm.c:147 #, fuzzy, c-format msgid "'%s' does not have length %d" msgstr "le slot '%s' doit avoir une longueur de 1" #: perm.c:86 perm.c:103 #, c-format msgid "'%s' is NA" msgstr "" #: perm.c:115 perm.c:138 #, fuzzy, c-format msgid "'%s' or '%s' is not of type \"%s\"" msgstr "Le slot Dim n’est pas un entier" #: perm.c:117 perm.c:140 #, fuzzy, c-format msgid "'%s' or '%s' does not have length %d" msgstr "le slot '%s' doit avoir une longueur de 1" #: perm.c:120 perm.c:143 #, c-format msgid "'%s' or '%s' is NA" msgstr "" #: perm.c:136 #, c-format msgid "'%s' has length exceeding %s" msgstr "" #: perm.c:150 #, c-format msgid "'%s' is NA or less than %s" msgstr "" #: products.c:107 products.c:210 products.c:289 products.c:377 products.c:454 #: products.c:548 products.c:809 products.c:859 msgid "non-conformable arguments" msgstr "" #: products.c:782 products.c:807 #, c-format msgid "'%s' does not support complex matrices" msgstr "" #: solve.c:38 #, fuzzy, c-format msgid "'%s' is not square" msgstr "Matrix n'est pas carrée" #: solve.c:497 #, c-format msgid "%s(<%s>, <%s>) failed: out of memory" msgstr "" #: solve.c:618 #, fuzzy, c-format msgid "attempt to construct %s with more than %s nonzero elements" msgstr "Determinant nécessite une matrice carrée" #: sparseVector.c:90 #, c-format msgid "%s length cannot exceed %s" msgstr "" #: subscript.c:1542 subscript.c:1695 subscript.c:1938 subscript.c:2122 #, c-format msgid "%s too dense for %s; would have more than %s nonzero entries" msgstr "" #: subscript.c:2209 #, c-format msgid "NA subscripts in %s not supported for '%s' inheriting from %s" msgstr "" #: t_Csparse_subassign.c:142 msgid "invalid class of 'x' in Csparse_subassign()" msgstr "classe de 'x' incorrecte dans Csparse_subassign()" #: t_Csparse_subassign.c:144 msgid "invalid class of 'value' in Csparse_subassign()" msgstr "classe de 'value' incorrecte dans Csparse_subassign()" #: t_Csparse_subassign.c:187 #, c-format msgid "x[] <- val: val is coerced to logical for \"%s\" x" msgstr "" "x[] <- val: val est converti automatiquement en valeurs logiques pour \"%s\" " "x" #: t_Csparse_subassign.c:192 #, c-format msgid "" "x[] <- val: val should be integer or logical, is coerced to integer, for " "\"%s\" x" msgstr "" "x[] <- val: val devrait être des entiers ou des valeurs booléennes, il est " "converti automatiquement en entiers pour \"%s\" x" #: t_Csparse_subassign.c:199 msgid "programming error in Csparse_subassign() should never happen" msgstr "" "erreur de programmation dans Csparse_subassign() qui ne devrait jamais se " "produire" #: utils-R.c:30 utils-R.c:116 #, c-format msgid "indices would exceed %s" msgstr "" #: utils-R.c:235 utils-R.c:270 utils-R.c:281 utils-R.c:312 msgid "Argument must be numeric-like atomic vector" msgstr "" "L'argument doit être un vecteur atomique de type numérique ou convertible en " "nombres" #: utils-R.c:345 msgid "'data' must be of a vector type" msgstr "'data' doit être de type vecteur" #: utils-R.c:352 #, c-format msgid "invalid '%s' argument" msgstr "argument '%s' incorrect" #: utils-R.c:359 utils-R.c:367 msgid "non-numeric matrix extent" msgstr "étendue de matrice non numérique" #: utils-R.c:362 msgid "invalid 'nrow' value (too large or NA)" msgstr "valeur 'nrow' incorrecte (trop large ou NA)" #: utils-R.c:364 msgid "invalid 'nrow' value (< 0)" msgstr "valeur 'nrow' incorrecte (< 0)" #: utils-R.c:370 msgid "invalid 'ncol' value (too large or NA)" msgstr "valeur 'ncol' incorrecte (trop large ou NA)" #: utils-R.c:372 msgid "invalid 'ncol' value (< 0)" msgstr "valeur 'ncol' incorrecte (< 0)" #: utils-R.c:390 #, c-format msgid "" "data length [%d] is not a sub-multiple or multiple of the number of rows [%d]" msgstr "" "la longueur des données [%d] n'est pas un sous-multiple ni un multiple du " "nombre de lignes [%d]" #: utils-R.c:395 #, c-format msgid "" "data length [%d] is not a sub-multiple or multiple of the number of columns " "[%d]" msgstr "" "la longueur des données [%d] n'est pas un sous-multiple ni un multiple du " "nombre de colonnes [%d]" #: utils-R.c:399 msgid "data length exceeds size of matrix" msgstr "la longueur des données excède la taille de la matrice" #: utils-R.c:404 msgid "too many elements specified" msgstr "trop d'éléments sont spécifiés" #: utils-R.c:545 msgid "Argument ij must be 2-column integer matrix" msgstr "L'argument ij doit être une matrice d'entiers à 2 colonnes" #: utils-R.c:570 msgid "subscript 'i' out of bounds in M[ij]" msgstr "indice 'i' hors plage dans M[ij]" #: utils-R.c:572 msgid "subscript 'j' out of bounds in M[ij]" msgstr "indice 'j' hors plage dans M[ij]" #: utils-R.c:626 msgid "i and j must be integer vectors of the same length" msgstr "i et j doivent être des vecteurs d'entiers de même longueur" #: validity.c:40 validity.c:73 validity.c:264 validity.c:283 validity.c:292 #: validity.c:311 validity.c:337 validity.c:1010 validity.c:1452 #: validity.c:1476 #, fuzzy, c-format msgid "'%s' slot does not have length %d" msgstr "Le slot Dim doit avoir une longueur de 2" #: validity.c:45 validity.c:965 validity.c:998 #, fuzzy, c-format msgid "'%s' slot has negative elements" msgstr "le slot 'Dim' a une longueur inférieure à deux" #: validity.c:71 validity.c:197 #, fuzzy, c-format msgid "'%s' slot is not a list" msgstr "Le slot Dim n’est pas un entier" #: validity.c:89 #, fuzzy, c-format msgid "%s[[%d]] is not NULL or a vector" msgstr "Dimnames[%d] n’est pas un vecteur de chaînes de caractères" #: validity.c:92 #, fuzzy, c-format msgid "length of %s[[%d]] (%lld) is not equal to %s[%d] (%d)" msgstr "length(Dimnames[%d]) diffère de Dim[%d] qui est %d" #: validity.c:203 #, c-format msgid "'%s' slot has no '%s' attribute" msgstr "" #: validity.c:214 validity.c:277 validity.c:305 validity.c:376 validity.c:1115 #: validity.c:1446 validity.c:1807 #, c-format msgid "%s[1] != %s[2] (matrix is not square)" msgstr "" #: validity.c:239 validity.c:252 #, c-format msgid "%s[1] differs from %s[2]" msgstr "" #: validity.c:267 validity.c:286 validity.c:295 validity.c:314 #, fuzzy, c-format msgid "'%s' slot is not \"%s\" or \"%s\"" msgstr "le slot x n’est pas un nombre \"double\"" #: validity.c:320 validity.c:324 #, fuzzy, c-format msgid "'%s' slot is \"%s\" but '%s' slot does not have length %s" msgstr "Le slot Dim doit avoir une longueur de 2" #: validity.c:340 #, fuzzy, c-format msgid "'%s' slot is not %d or %d" msgstr "le slot x n’est pas un nombre \"double\"" #: validity.c:346 validity.c:349 #, c-format msgid "%s-by-%s %s invalid for positive '%s' when %s=%d" msgstr "" #: validity.c:386 validity.c:1178 validity.c:1190 validity.c:1291 #: validity.c:1303 validity.c:1383 validity.c:1432 validity.c:1491 #, c-format msgid "'%s' slot contains duplicates" msgstr "" #: validity.c:437 validity.c:1613 #, fuzzy, c-format msgid "'%s' slot is not increasing within columns" msgstr "le slot j ne contient pas de valeurs croissantes au sein d'une colonne" #: validity.c:488 #, fuzzy, c-format msgid "'%s' slot is not increasing within rows" msgstr "le slot j ne contient pas de valeurs croissantes au sein d'une colonne" #: validity.c:512 validity.c:801 validity.c:827 validity.c:853 validity.c:1076 #: validity.c:1682 validity.c:1684 #, fuzzy, c-format msgid "'%s' and '%s' slots do not have equal length" msgstr "Le slot Dim doit avoir une longueur de 2" #: validity.c:515 #, c-format msgid "'%s' slot has nonzero length but %s is 0" msgstr "" #: validity.c:555 validity.c:600 validity.c:646 validity.c:691 validity.c:735 #: validity.c:770 #, fuzzy, c-format msgid "%s=\"%s\" but there are entries below the diagonal" msgstr "uplo='U' ne peut avoir des entrées éparses en dessous de la diagonale" #: validity.c:565 validity.c:613 validity.c:656 validity.c:704 validity.c:740 #: validity.c:781 #, fuzzy, c-format msgid "%s=\"%s\" but there are entries above the diagonal" msgstr "uplo='L' ne peut avoir des entrées éparses au dessus de la diagonale" #: validity.c:603 validity.c:616 validity.c:694 validity.c:707 validity.c:773 #: validity.c:784 #, fuzzy, c-format msgid "%s=\"%s\" but there are entries on the diagonal" msgstr "uplo='U' ne peut avoir des entrées éparses en dessous de la diagonale" #: validity.c:911 validity.c:935 validity.c:939 msgid "matrix has negative diagonal elements" msgstr "" #: validity.c:955 validity.c:983 validity.c:987 msgid "matrix has nonunit diagonal elements" msgstr "" #: validity.c:1007 validity.c:1032 validity.c:1826 #, fuzzy, c-format msgid "'%s' slot is not of type \"%s\" or \"%s\"" msgstr "Le slot Dim n’est pas un entier" #: validity.c:1015 validity.c:1022 #, fuzzy, c-format msgid "'%s' slot is NA" msgstr "Le slot Dim n’est pas un entier" #: validity.c:1017 validity.c:1024 #, fuzzy, c-format msgid "'%s' slot is negative" msgstr "le slot 'Dim' a une longueur inférieure à deux" #: validity.c:1026 #, fuzzy, c-format msgid "'%s' slot exceeds %s" msgstr "'%s' doit être compris dans '%s'" #: validity.c:1036 #, fuzzy, c-format msgid "'%s' slot has length greater than '%s' slot" msgstr "le slot 'Dim' a une longueur inférieure à deux" #: validity.c:1046 validity.c:1674 validity.c:1696 validity.c:1698 #, fuzzy, c-format msgid "'%s' slot is not increasing" msgstr "le slot j ne contient pas de valeurs croissantes au sein d'une colonne" #: validity.c:1056 #, fuzzy, c-format msgid "'%s' slot has elements not in {%s} after truncation towards zero" msgstr "le slot 'Dim' a une longueur inférieure à deux" #: validity.c:1059 #, fuzzy, c-format msgid "'%s' slot is not increasing after truncation towards zero" msgstr "le slot j ne contient pas de valeurs croissantes au sein d'une colonne" #: validity.c:1125 validity.c:1152 validity.c:1814 validity.c:1821 #, fuzzy, c-format msgid "dimensions of '%s' slot are not identical to '%s'" msgstr "Les dimensions de x et y ne sont pas compatibles pour %s" #: validity.c:1127 #, c-format msgid "'%s' slot is upper (not lower) triangular" msgstr "" #: validity.c:1140 #, c-format msgid "'%s' slot has nonunit diagonal elements" msgstr "" #: validity.c:1154 #, c-format msgid "'%s' slot is lower (not upper) triangular" msgstr "" #: validity.c:1166 validity.c:1279 validity.c:1370 validity.c:1419 #, fuzzy, c-format msgid "'%s' slot does not have length %s or length %s" msgstr "Le slot Dim doit avoir une longueur de 2" #: validity.c:1206 msgid "matrix has more columns than rows" msgstr "" #: validity.c:1226 #, fuzzy, c-format msgid "'%s' slot has fewer than %s rows" msgstr "le slot 'Dim' a une longueur inférieure à deux" #: validity.c:1228 #, fuzzy, c-format msgid "'%s' slot has more than %s rows" msgstr "le slot 'Dim' a une longueur inférieure à deux" #: validity.c:1230 validity.c:1252 #, fuzzy, c-format msgid "'%s' slot does not have %s columns" msgstr "Le slot Dim doit avoir une longueur de 2" #: validity.c:1237 #, fuzzy, c-format msgid "'%s' slot must be lower trapezoidal but has entries above the diagonal" msgstr "uplo='L' ne peut avoir des entrées éparses au dessus de la diagonale" #: validity.c:1250 #, fuzzy, c-format msgid "'%s' slot does not have %s row" msgstr "Le slot Dim doit avoir une longueur de 2" #: validity.c:1259 #, fuzzy, c-format msgid "'%s' slot must be upper trapezoidal but has entries below the diagonal" msgstr "uplo='U' ne peut avoir des entrées éparses en dessous de la diagonale" #: validity.c:1263 #, c-format msgid "'%s' slot has negative diagonal elements" msgstr "" #: validity.c:1329 #, c-format msgid "'%s' slot has elements not in {%s}\\{%s}" msgstr "" #: validity.c:1338 #, c-format msgid "'%s' slot has unpaired negative elements" msgstr "" #: validity.c:1364 validity.c:1408 validity.c:1412 validity.c:1760 #: validity.c:1792 msgid "Cholesky factor has negative diagonal elements" msgstr "" #: validity.c:1455 #, fuzzy, c-format msgid "%s[%d] (%s) is not in %s" msgstr "%s n’est pas une liste" #: validity.c:1468 validity.c:1569 #, fuzzy, c-format msgid "%s is not in {%s}" msgstr "%s n’est pas une liste" #: validity.c:1505 #, c-format msgid "%s is not representable as \"%s\"" msgstr "" #: validity.c:1510 validity.c:1516 #, c-format msgid "%s[%d] (%s) is not %d or %d" msgstr "" #: validity.c:1513 validity.c:1629 validity.c:1632 validity.c:1635 #, c-format msgid "%s[%d] (%s) is not %d" msgstr "" #: validity.c:1538 #, c-format msgid "%s has elements not in {%s}" msgstr "" #: validity.c:1541 #, c-format msgid "%s has elements not in {%s}\\{%s}" msgstr "" #: validity.c:1544 #, c-format msgid "%s is %d but columns are not stored in increasing order" msgstr "" #: validity.c:1547 validity.c:1550 #, c-format msgid "traversal of '%s' slot does not complete in exactly %s steps" msgstr "" #: validity.c:1556 validity.c:1558 #, fuzzy, c-format msgid "%s is not %d" msgstr "%s n’est pas une liste" #: validity.c:1579 #, c-format msgid "column '%s' is stored first but %s is not 0" msgstr "" #: validity.c:1585 #, fuzzy, c-format msgid "'%s' slot is not increasing when traversed in stored column order" msgstr "le slot j ne contient pas de valeurs croissantes au sein d'une colonne" #: validity.c:1587 #, c-format msgid "'%s' slot allocates fewer than %s elements for column '%s'" msgstr "" #: validity.c:1590 #, c-format msgid "'%s' slot allocates more than %s elements for column '%s'" msgstr "" #: validity.c:1604 #, c-format msgid "first entry in column '%s' does not have row index '%s'" msgstr "" #: validity.c:1638 validity.c:1641 #, c-format msgid "%s[%d] (%s) is negative" msgstr "" #: validity.c:1644 #, c-format msgid "%s[%d] (%s) is not less than %s" msgstr "" #: validity.c:1662 #, fuzzy, c-format msgid "'%s' slot has length less than %d" msgstr "le slot 'Dim' a une longueur inférieure à deux" #: validity.c:1664 #, fuzzy, c-format msgid "'%s' slot has length greater than %s" msgstr "le slot 'Dim' a une longueur inférieure à deux" #: validity.c:1669 #, fuzzy, c-format msgid "last element of '%s' slot is not %s" msgstr "le premier élément du slot p doit être à zéro" #: validity.c:1702 #, c-format msgid "first differences of '%s' slot are less than those of '%s' slot" msgstr "" #: validity.c:1705 #, c-format msgid "supernode lengths exceed %s" msgstr "" #: validity.c:1707 #, c-format msgid "first differences of '%s' slot are not equal to supernode lengths" msgstr "" #: validity.c:1727 #, c-format msgid "" "'%s' slot is wrong within diagonal blocks (row and column indices do not " "coincide)" msgstr "" #: validity.c:1730 #, fuzzy, c-format msgid "'%s' slot is not increasing within supernodes" msgstr "le slot j ne contient pas de valeurs croissantes au sein d'une colonne" #: validity.c:1845 #, fuzzy, c-format msgid "invalid class \"%s\" object: %s" msgstr "classe incorrecte d'objet à %s" #, c-format #~ msgid "diagonal element %d of Cholesky factor is missing" #~ msgstr "" #~ "l'élément de diagonale %d de la factorisation de Cholesky est manquant" #, c-format #~ msgid "cholmod_factorize_p failed: status %d, minor %d of ncol %d" #~ msgstr "cholmod_factorize_p a échoué : statut %d, mineur %d de ncol %d" #~ msgid "cholmod_change_factor failed" #~ msgstr "cholmod_change_factor a échoué" #~ msgid "cholmod_write_sparse returned error code" #~ msgstr "cholmod_write_sparse a renvoyé le code d'erreur" #, c-format #~ msgid "%s = '%s' (back-permuted) is experimental" #~ msgstr "%s = '%s' (back-permuted) est expérimental" #~ msgid "diag_tC(): invalid 'resultKind'" #~ msgstr "diag_tC() : 'resultKind' incorrect" #, fuzzy #~ msgid "complex matrices are not yet supported" #~ msgstr "le code n'est pas encore écrit pour les matrices éparses complexes" #~ msgid "Argument rho must be an environment" #~ msgstr "L'argument rho doit être un environnement" #~ msgid "invalid class of object to as_cholmod_sparse" #~ msgstr "classe d'objet incorrecte pour as_cholmod_sparse" #~ msgid "invalid object passed to as_cholmod_sparse" #~ msgstr "objet incorrect passé à as_cholmod_sparse" #~ msgid "in_place cholmod_sort returned an error code" #~ msgstr "in_place cholmod_sort a renvoyé un code d'erreur" #~ msgid "cholmod_sort returned an error code" #~ msgstr "cholmod_sort a renvoyé un code d'erreur" #~ msgid "chm_sparse_to_SEXP(, *): invalid 'Rkind' (real kind code)" #~ msgstr "chm_sparse_to_SEXP(, *) : 'Rkind' incorrect (real kind code)" #~ msgid "unknown xtype in cholmod_sparse object" #~ msgstr "xtype inconnu dans cholmod_sparse object" #~ msgid "complex sparse matrix code not yet written" #~ msgstr "le code n'est pas encore écrit pour les matrices éparses complexes" #~ msgid "Symmetric and triangular both set" #~ msgstr "Symmetric et triangular sont tous deux sélectionnés" #~ msgid "invalid class of object to as_cholmod_triplet" #~ msgstr "classe d'objet incorrecte pour as_cholmod_triplet" #~ msgid "as_cholmod_triplet(): could not reallocate for internal diagU2N()" #~ msgstr "" #~ "as_cholmod_triplet() : impossible de réallouer de la mémoire pour la " #~ "fonction interne diagU2N()" #~ msgid "unknown xtype in cholmod_triplet object" #~ msgstr "xtype inconnu dans l'objet cholmod_triplet" #~ msgid "invalid class of object to as_cholmod_dense" #~ msgstr "classe d'objet incorrecte pour as_cholmod_dense" #, c-format #~ msgid "" #~ "chm_transpose_dense(ans, x) not yet implemented for %s different from %s" #~ msgstr "" #~ "chm_transpose_dense(ans, x) pas encore implémenté pour %s différent de %s" #, c-format #~ msgid "Unable to initialize cholmod: error code %d" #~ msgstr "Impossible d'initialiser cholmod : code d'erreur %d" #~ msgid "unknown 'Rkind'" #~ msgstr "'Rkind' inconnu" #~ msgid "unknown xtype" #~ msgstr "xtype inconnu" #~ msgid "code for cholmod_dense with holes not yet written" #~ msgstr "" #~ "le code pour cholmod_dense en présence de trous n'est pas encore écrit" #~ msgid "don't know if a dense pattern matrix makes sense" #~ msgstr "je ne sais pas si une matrice pattern dense a un sens" #, fuzzy #~ msgid "object of invalid class to 'as_cholmod_factor()'" #~ msgstr "class d'objet incorrecte pour as_cholmod_factor" #~ msgid "failure in as_cholmod_factor" #~ msgstr "erreur dans as_cholmod_factor" #~ msgid "CHOLMOD factorization was unsuccessful" #~ msgstr "La factorisation CHOLMOD a échoué" #, c-format #~ msgid "f->xtype of %d not recognized" #~ msgstr "f->xtype de %d non reconnu" #, c-format #~ msgid "chm_diagN2U(): nrow=%d, ncol=%d" #~ msgstr "chm_diagN2U(): nrow=%d, ncol=%d" #, c-format #~ msgid "chm_diagN2U(x, uploT = %d): uploT should be +- 1" #~ msgstr "chm_diagN2U(x, uploT = %d): uploT doit être +- 1" #~ msgid "dgCMatrix_lusol requires a square, non-empty matrix" #~ msgstr "dgCMatrix_lusol nécessite une matrice carrée non vide" #~ msgid "Dimensions of system to be solved are inconsistent" #~ msgstr "Les dimensions du système à résoudre sont incohérentes" #~ msgid "cs_lusol failed" #~ msgstr "cs_lusol a échoué" #~ msgid "dgCMatrix_qrsol(., order) needs order in {0,..,3}" #~ msgstr "dgCMatrix_qrsol(., order) nécessite un ordre compris entre {0,..,3}" #, c-format #~ msgid "" #~ "dgCMatrix_qrsol(<%d x %d>-matrix) requires a 'tall' rectangular matrix" #~ msgstr "" #~ "dgCMatrix_qrsol(<%d x %d>-matrix) nécessite une matrice rectangulaire " #~ "haute ('tall')" #~ msgid "cs_qrsol() failed inside dgCMatrix_qrsol()" #~ msgstr "cs_qrsol() a échoué à l'intérieur de dgCMatrix_qrsol()" #~ msgid "dgCMatrix_cholsol requires a 'short, wide' rectangular matrix" #~ msgstr "dgCMatrix_cholsol nécessite une matrice rectangulaire en longueur" #~ msgid "cholmod_sdmult error (rhs)" #~ msgstr "erreur cholmod_sdmult (partie droite de l'équation)" #, c-format #~ msgid "cholmod_factorize failed: status %d, minor %d from ncol %d" #~ msgstr "cholmod_factorize a échoué : statut %d, mineur %d pour ncol %d" #, c-format #~ msgid "cholmod_solve (CHOLMOD_A) failed: status %d, minor %d from ncol %d" #~ msgstr "" #~ "cholmod_solve (CHOLMOD_A) a échoué : statut %d, mineur %d pour ncol %d" #~ msgid "cholmod_sdmult error (resid)" #~ msgstr "erreur cholmod_sdmult (resid)" #~ msgid "SuiteSparseQR_C_QR returned an error code" #~ msgstr "SuiteSparseQR_C_QR a renvoyé un code d'erreur" #, fuzzy, c-format #~ msgid "LAPACK routine '%s': matrix is exactly singular, %s[i,i]=0, i=%d" #~ msgstr "Routine Lapack dgetrs : le système est exactement singulier" #, fuzzy, c-format #~ msgid "" #~ "LAPACK routine '%s': leading principal minor of order %d is not positive" #~ msgstr "le 'leading minor of order' %d n'est pas un entier fini" #, fuzzy #~ msgid "missing 'Matrix' namespace; should never happen" #~ msgstr "" #~ "espace de noms 'Matrix' manquant : ceci ne devrait jamais se produire" #, fuzzy #~ msgid "'Matrix' namespace not determined correctly" #~ msgstr "L’espace de noms Matrix n'est pas correctement déterminé" #~ msgid "Csparse_sort(x): x is not a valid (apart from sorting) CsparseMatrix" #~ msgstr "" #~ "Csparse_sort(x) : x est une CsparseMatrix incorrecte (au delà d'un " #~ "problème de tri)" #, c-format #~ msgid "Impossible Rk_x/Rk_y in Csparse_%s(), please report" #~ msgstr "Rk_x/Rk_y impossible dans Csparse_%s(), veuillez reporter l’erreur" #, c-format #~ msgid "chm_MOD_xtype() was not successful in Csparse_%s(), please report" #~ msgstr "" #~ "chm_MOD_xtype() a échoué dans Csparse_%s(), veuillez reporter l’erreur" #, c-format #~ msgid "the number of columns differ in R_rbind2_vector: %d != %d" #~ msgstr "le nombre de colonnes diffère dans R_rbind2_vector: %d != %d" #~ msgid "csp_eye argument n must be positive" #~ msgstr "l'argument n de csp_eye doit être positif" #~ msgid "invalid class of 'x' in Matrix_as_cs(a, x)" #~ msgstr "classe incorrecte de 'x' dans Matrix_as_cs(a, x)" #, c-format #~ msgid "invalid class of object to %s" #~ msgstr "classe incorrecte d'objet à %s" #, c-format #~ msgid "cs matrix not compatible with class '%s'" #~ msgstr "matrice cs incompatible avec la classe '%s'" #, c-format #~ msgid "Inappropriate class cl='%s' in Matrix_css_to_SEXP(S, cl, ..)" #~ msgstr "Classe inappropriée cl='%s' dans Matrix_css_to_SEXP(S, cl, ..)" #, c-format #~ msgid "Inappropriate class cl='%s' in Matrix_csn_to_SEXP(S, cl, ..)" #~ msgstr "Classe inappropriée cl='%s' dans Matrix_csn_to_SEXP(S, cl, ..)" #, c-format #~ msgid "Dimensions of x and y are not compatible for %s" #~ msgstr "Les dimensions de x et y ne sont pas compatibles pour %s" #~ msgid "Argument y must be numeric, integer or logical" #~ msgstr "L'argument y doit être un nombre réel, un entier ou un booléen" #~ msgid "Matrices are not conformable for multiplication" #~ msgstr "Les matrices sont incohérentes pour la multiplication" #, c-format #~ msgid "" #~ "dimension mismatch in matrix multiplication of \"dtrMatrix\": %d != %d" #~ msgstr "" #~ "dimensions incompatibles pour la multiplication matricielle avec " #~ "\"dtrMatrix\" : %d != %d" #~ msgid "dtrMatrix must be square" #~ msgstr "dtrMatrix doit être carrée" #, c-format #~ msgid "Dimensions of a (%d,%d) and b (%d,%d) do not conform" #~ msgstr "Les dimensions de a (%d,%d) et b (%d,%d) ne sont pas conformes" #~ msgid "right=TRUE is not yet implemented __ FIXME" #~ msgstr "right=TRUE n'est pas encore implémenté __ FIXME" #, c-format #~ msgid "cholmod_change_factor failed with status %d" #~ msgstr "cholmod_change_factor a échoué avec le statut %d" #~ msgid "system argument is not valid" #~ msgstr "argument système incorrect" #, c-format #~ msgid "cholmod_updown() returned %d" #~ msgstr "cholmod_updown() a renvoyé %d" #~ msgid "cholmod_drop() failed" #~ msgstr "cholmod_drop() a échoué" #, fuzzy #~ msgid "'off' does not have length 1" #~ msgstr "le slot '%s' doit avoir une longueur de 1" #, fuzzy #~ msgid "invalid 'code' to 'R_matrix_as_dense()'" #~ msgstr "classe '%s' incorrecte pour dup_mMatrix_as_dgeMatrix" #, fuzzy #~ msgid "invalid 'uplo' to 'R_matrix_as_dense()'" #~ msgstr "classe '%s' incorrecte pour dup_mMatrix_as_dgeMatrix" #, fuzzy #~ msgid "invalid 'diag' to 'R_matrix_as_dense()'" #~ msgstr "classe '%s' incorrecte pour dup_mMatrix_as_dgeMatrix" #, fuzzy #~ msgid "invalid argument 'system'" #~ msgstr "argument '%s' incorrect" #, fuzzy #~ msgid "dimensions of 'qr' and 'y' are inconsistent" #~ msgstr "Les dimensions du système à résoudre sont incohérentes" #, fuzzy #~ msgid "invalid 'op'" #~ msgstr "argument '%s' incorrect" #, fuzzy #~ msgid "'names' must be TRUE or FALSE" #~ msgstr "'uplo' doit être UPP ou LOW" #~ msgid "Csparse_crossprod(): error return from cholmod_aat()" #~ msgstr "Csparse_crossprod() : erreur renvoyée par cholmod_aat()" #, fuzzy #~ msgid "invalid 'kind' to 'R_sparse_as_kind()'" #~ msgstr "classe de 'x' incorrecte dans Csparse_subassign()" #~ msgid "slot p must have length = nrow(.) + 1" #~ msgstr "le slot p doit avoir longueur = nrow(.) + 1" #~ msgid "last element of slot p must match length of slots j and x" #~ msgstr "" #~ "le dernier élément du slot p doit avoir la même longueur que les slots j " #~ "et x" #~ msgid "all column indices must be between 0 and ncol-1" #~ msgstr "tous les indices de colonnes doivent être compris entre 0 et ncol-1" #~ msgid "slot j is not *strictly* increasing inside a column" #~ msgstr "" #~ "le slot j ne contient pas de valeurs *strictement* croissantes au sein " #~ "d'une colonne" #~ msgid "Csparse_to_nz_pattern(x, tri = NA): 'tri' is taken as TRUE" #~ msgstr "" #~ "Csparse_to_nz_pattern(x, tri = NA): 'tri' est considéré comme étant TRUE" #~ msgid "not a 'n.CMatrix'" #~ msgstr "ceci n'est pas un 'n.CMatrix'" #, c-format #~ msgid "nz2Csparse(): invalid/non-implemented r_kind = %d" #~ msgstr "nz2Csparse() : r_kind = %d est incorrect/non implémenté" #~ msgid "Nonsymmetric matrix in Csparse_symmetric_to_general" #~ msgstr "Matrice non symétrique dans Csparse_symmetric_to_general" #~ msgid "Csparse_general_to_symmetric(): matrix is not square!" #~ msgstr "Csparse_general_to_symmetric() : la matrice n'est pas carrée !" #~ msgid "Index i must be NULL or integer" #~ msgstr "L’indice i doit être un entier ou NULL" #~ msgid "Index j must be NULL or integer" #~ msgstr "L’indice j doit être un entier ou NULL" #, c-format #~ msgid "negative vector lengths not allowed: np = %d, nnz = %d" #~ msgstr "" #~ "les longueurs négatives de vecteurs ne sont pas autorisées : np = %d, nnz " #~ "= %d" #~ msgid "exactly 1 of 'i', 'j' or 'p' must be NULL" #~ msgstr "un et un seul des arguments 'i', 'j' ou 'p' doit être NULL" #, c-format #~ msgid "np = %d, must be zero when p is NULL" #~ msgstr "np = %d, il doit être égal à zéro lorsque p est NULL" #, c-format #~ msgid "p[0] = %d, should be zero" #~ msgstr "p[0] = %d, il devrait être égal à zéro" #~ msgid "p must be non-decreasing" #~ msgstr "p ne peut pas être décroissant" #, c-format #~ msgid "Inconsistent dimensions: np = 0 and nnz = %d" #~ msgstr "Dimensions incohérentes : np = 0 et nnz = %d" #, c-format #~ msgid "invalid column index at position %d" #~ msgstr "indices de colonnes erronés à la position %d" #, c-format #~ msgid "strlen of cls argument = %d, should be 8" #~ msgstr "strlen de l'argument cls = %d, il devrait valoir 8" #, c-format #~ msgid "cls = \"%s\" does not end in \"CMatrix\"" #~ msgstr "cls = \"%s\" ne se finit pas dans \"CMatrix\"" #, c-format #~ msgid "cls = \"%s\" must begin with 'd', 'l' or 'n'" #~ msgstr "cls = \"%s\" doit commencer par 'd', 'l', ou 'n'" #~ msgid "Only 'g'eneral sparse matrix types allowed" #~ msgstr "Seuls des types de matrices éparses 'g'énéraux sont acceptés" #~ msgid "code not yet written for cls = \"lgCMatrix\"" #~ msgstr "le code pour cls = \"lgCMatrix\" n'est pas encore écrit" #, c-format #~ msgid "%s must be (traditional R) matrix" #~ msgstr "%s doit être une matrice (traditionelle de R)" #, c-format #~ msgid "%s must be character string" #~ msgstr "%s doit être une chaîne de caractères" #, c-format #~ msgid "nrow * ncol = %d * %d must equal length(x) = %ld" #~ msgstr "nrow * ncol = %d * %d doit être égal à length(x) = %ld" #, c-format #~ msgid "strlen of cls argument = %d, should be 9" #~ msgstr "strlen de l'argument cls = %d, il devrait valoir 9" #, c-format #~ msgid "cls = \"%s\" must begin with 'd', 'l' or 'n' for now" #~ msgstr "cls = \"%s\" doit commencer par 'd', 'l', ou 'n' pour l’instant" #, c-format #~ msgid "%s must be a logical or double vector" #~ msgstr "%s doit être un vecteur de booléens ou de doubles" #, c-format #~ msgid "argument type[1]='%s' must be one of 'M','1','O','I','F' or 'E'" #~ msgstr "l'argument type[1]='%s' doit être parmi 'M','1','O','I','F' ou 'E'" #, c-format #~ msgid "argument type[1]='%s' must be one of '1','O', or 'I'" #~ msgstr "l'argument type[1]='%s' doit être parmi '1','O' ou 'I'" #~ msgid "object must be a named, numeric vector" #~ msgstr "l'objet doit être un vecteur numérique nommé" #~ msgid "'factors' slot must be a named list" #~ msgstr "le slot 'factors' doit être une liste nommée" #~ msgid "Matrix object has no 'factors' slot" #~ msgstr "L’objet Matrix n’a pas de slot 'factors'" #~ msgid "'s1' and 's2' must be \"character\" vectors" #~ msgstr "'s1' et 's2' doivent être des vecteurs de type \"character\"" #~ msgid "length of x slot != prod(Dim)" #~ msgstr "la longueur du slot x != prod(Dim)" #~ msgid "Negative value in Dim" #~ msgid_plural "Negative values in Dim" #~ msgstr[0] "Valeur négative dans Dim" #~ msgstr[1] "Valeurs négatives dans Dim" #, c-format #~ msgid "%s is a list, but not of length 2" #~ msgstr "%s est une liste, mais pas de longueur 2" #, c-format #~ msgid "invalid class '%s' to dup_mMatrix_as_geMatrix" #~ msgstr "classe '%s' incorrecte pour dup_mMatrix_as_geMatrix" #, c-format #~ msgid "unexpected ctype = %d in dup_mMatrix_as_geMatrix" #~ msgstr "ctype = %d inattendu dans dup_mMatrix_as_geMatrix" #~ msgid "lengths of slots i and j must match" #~ msgstr "la longueur des slots i et j doit correspondre" #~ msgid "slot Dim must have length 2" #~ msgstr "le slot Dim doit avoir une longueur de 2" #~ msgid "" #~ "all row indices (slot 'i') must be between 0 and nrow-1 in a TsparseMatrix" #~ msgstr "" #~ "tous les indices de lignes (slot 'i') doivent être compris entre 0 et " #~ "nrow-1 dans une TsparseMatrix" #~ msgid "" #~ "all column indices (slot 'j') must be between 0 and ncol-1 in a " #~ "TsparseMatrix" #~ msgstr "" #~ "tous les indices de colonnes (slot 'j') doivent être compris entre 0 et " #~ "ncol-1 dans une TsparseMatrix" #~ msgid "Supernodal LDL' decomposition not available" #~ msgstr "La décomposition 'supernodal LDL' n'est pas disponible" #~ msgid "Supernodal/simplicial class inconsistent with type flags" #~ msgstr "Classe supernodal/simplicial incohérente avec les drapeaux de type" #~ msgid "Number of supernodes must be positive when is_super is TRUE" #~ msgstr "" #~ "Le nombre de supernoeuds doit être positif lorsque is_super vaut TRUE" #~ msgid "Lengths of super and pi must be equal" #~ msgstr "Les longueurs de super et pi doivent être égales" #~ msgid "Lengths of super and px must be equal" #~ msgstr "Les longueurs de super et px doivent être égales" #, c-format #~ msgid "First call to Lapack routine dgels returned error code %d" #~ msgstr "" #~ "Le premier appel à la routine Lapack dgels a renvoyé le code d'erreur %d" #, c-format #~ msgid "Second call to Lapack routine dgels returned error code %d" #~ msgstr "" #~ "Le second appel à la routine Lapack dgels a renvoyé le code d'erreur %d" #, c-format #~ msgid "tol, given as %g, must be non-negative" #~ msgstr "tol, donné comme %g, doit être non négatif" #, c-format #~ msgid "Second call to dgeqrf returned error code %d" #~ msgstr "Le second appel à dgeqrf a renvoyé le code d'erreur %d" #, c-format #~ msgid "" #~ "dense_to_Csparse(): cholmod_l_dense_to_sparse failure status=%d" #~ msgstr "" #~ "dense_to_Csparse(): cholmod_l_dense_to_sparse statut d’erreur=%d" #, c-format #~ msgid "" #~ "Matrix dimension %d x %d (= %g) too large [FIXME calling " #~ "cholmod_l_dense_to_sparse]" #~ msgstr "" #~ "Dimension de Matrix %d x %d (= %g) trop large [FIXME appeler " #~ "cholmod_l_dense_to_sparse]" #, c-format #~ msgid "Lower band %d > upper band %d" #~ msgstr "Bande basse %d > bande haute %d" #~ msgid "ddense_to_symmetric(): matrix is not square!" #~ msgstr "ddense_to_symmetric() : la matrice n'est pas carrée !" #, c-format #~ msgid "matrix is not symmetric [%d,%d]" #~ msgstr "la matrice n'est pas symétrique [%d,%d]" #~ msgid "matrix is not square! (symmetric part)" #~ msgstr "la matrice n'est pas carrée ! (partie symétrique)" #~ msgid "matrix is not square! (skew-symmetric part)" #~ msgstr "la matrice n'est pas carrée ! (partie 'skew-symetric')" #~ msgid "lengths of slots 'i' and 'x' must match" #~ msgstr "les longueurs des slots 'i' et 'x' doivent correspondre" #~ msgid "lengths of slots 'j' and 'x' must match" #~ msgstr "les longueurs des slots 'j' et 'x' doivent correspondre" #, c-format #~ msgid "invalid class(x) '%s' in compressed_to_TMatrix(x)" #~ msgstr "class(x) incorrecte '%s' dans compressed_to_TMatrix(x)" #, c-format #~ msgid "invalid class(x) '%s' in R_to_CMatrix(x)" #~ msgstr "class(x) incorrecte '%s' dans R_to_CMatrix(x)" #~ msgid "A must have #{rows} >= #{columns}" #~ msgstr "A doit avoir #{lignes} >= #{colonnes}" #~ msgid "cs_sqr failed" #~ msgstr "cs_sqr a échoué" #~ msgid "dgcMatrix_QR(*, keep_dimnames = NA): NA taken as TRUE" #~ msgstr "dgcMatrix_QR(*, keep_dimnames = NA): NA considéré comme TRUE" #~ msgid "LU decomposition applies only to square matrices" #~ msgstr "La décomposition LU n'est utilisable que pour des matrices carrées" #~ msgid "cs_lu(A) failed: near-singular A (or out of memory)" #~ msgstr "" #~ "cs_lu(A) a échoué : A pratiquement singulière (ou manque de mémoire)" #~ msgid "dgcMatrix_LU(*, keep_dimnames = NA): NA taken as TRUE" #~ msgstr "dgcMatrix_LU(*, keep_dimnames = NA): NA considéré comme TRUE" #~ msgid "dgCMatrix_matrix_solve(.., sparse=TRUE) not yet implemented" #~ msgstr "dgCMatrix_matrix_solve(.., sparse=TRUE) n'est pas encore implémenté" #~ msgid "lengths of slots i and x must match" #~ msgstr "les longueurs des slots i et x doivent correspondre" #, c-format #~ msgid "too large matrix: %.0f" #~ msgstr "matrice trop large : %.0f" #, c-format #~ msgid "Cannot coerce to too large *geMatrix with %.0f entries" #~ msgstr "" #~ "Impossible de convertir automatiquement vers une *geMatrix trop large " #~ "avec %.0f entrées" #~ msgid "x slot must be numeric \"double\"" #~ msgstr "le slot x doit être un nombre \"double\"" #~ msgid "factors slot must be named list" #~ msgstr "le slot factors doit être une liste nommée" #~ msgid "rcond requires a square, non-empty matrix" #~ msgstr "rcond nécessite une matrice carrée non vide" #~ msgid "diagonal to be added has wrong length" #~ msgstr "la diagonale à ajouter a une longueur incorrecte" #~ msgid "Cannot factor a matrix with zero extents" #~ msgstr "Impossible de factoriser une matrice de dimensions nulles" #, c-format #~ msgid "Exact singularity detected during LU decomposition: %s, i=%d." #~ msgstr "Singularité exacte détectée lors d'une décomposition LU : %s, i=%d." #~ msgid "Solve requires a square matrix" #~ msgstr "Solve nécessite une matrice carrée" #, c-format #~ msgid "error [%d] from Lapack 'dgecon()'" #~ msgstr "erreur [%d] depuis Lapack 'dgecon()'" #, c-format #~ msgid "" #~ "Lapack dgecon(): system computationally singular, reciprocal condition " #~ "number = %g" #~ msgstr "" #~ "Lapack dgecon() : système calculé singulier, nombre de condition " #~ "réciproque = %g" #~ msgid "Lapack routine dgetri: system is exactly singular" #~ msgstr "Routine Lapack dgetri : le système est exactement singulier" #~ msgid "dpoMatrix is not positive definite" #~ msgstr "dpoMatrix n'est pas un entier positif fini" #~ msgid "Cannot solve() for matrices with zero extents" #~ msgstr "" #~ "Impossible de résoudre avec solve() pour des matrices de dimensions nulles" #~ msgid "Argument b must be a numeric matrix" #~ msgstr "L'argument b doit être une matrice numérique" #~ msgid "chm_factor_name(): did not get string of length 11" #~ msgstr "" #~ "chm_factor_name() : une chaîne de caractères de longueur 11 n'est pas " #~ "obtenue" #~ msgid "" #~ "Cholesky factorization failed; unusually, please report to Matrix-authors" #~ msgstr "" #~ "La factorisation Cholesky a échoué ; inhabituel, veuillez reporter le " #~ "problème aux auteurs du package Matrix" #~ msgid "internal_chm_factor: Cholesky factorization failed" #~ msgstr "internal_chm_factor : la factorisation Cholesky a échoué" #~ msgid "Non-symmetric matrix passed to dsCMatrix_to_dgTMatrix" #~ msgstr "Matrice non symétrique passée à dsCMatrix_to_dgTMatrix" #~ msgid "Incorrect length of 'x' slot" #~ msgstr "Longueur incorrecte du slot 'x'" #, c-format #~ msgid "Lapack routine dsytrf returned error code %d" #~ msgstr "La routine Lapack dsytrf a renvoyé le code d'erreur %d" #~ msgid "x must be a \"double\" (numeric) matrix" #~ msgstr "x doit être une matrice (numérique) de réels (doubles)" #~ msgid "matrix_trf(x, *): matrix is not square" #~ msgstr "matrix_trf(x, *) : la matrice n'est pas carrée" #~ msgid "matrix_trf(*, uplo): uplo must be string" #~ msgstr "matrix_trf(*, uplo) : uplo doit être une chaîne de caractères" #~ msgid "cannot set diag() as long as 'diag = \"U\"'" #~ msgstr "impossible d'utiliser diag() puisque 'diag = \"U\"'" #~ msgid "cannot add diag() as long as 'diag = \"U\"'" #~ msgstr "impossible d'ajouter diag() puisque 'diag = \"U\"'" #~ msgid "x slot is not of correct length" #~ msgstr "le slot x est de longueur incorrecte" #~ msgid "A must be a logical matrix" #~ msgstr "A doit être une matrice de valeurs booléennes" #~ msgid "length(p) must match nrow(V)" #~ msgstr "length(p) doit correspondre à nrow(V)" #~ msgid "length(beta) must match ncol(V)" #~ msgstr "length(beta) doit correspondre à ncol(V)" #~ msgid "length(q) must be zero or ncol(R)" #~ msgstr "length(q) doit valoir zéro ou ncol(R)" #, c-format #~ msgid "sparseQR_Qmult(): nrow(y) = %d != %d = nrow(V)" #~ msgstr "sparseQR_Qmult(): nrow(y) = %d != %d = nrow(V)" #~ msgid "\"dtrMatrix\" objects in '%*%' must have matching (square) dimension" #~ msgstr "" #~ "les objets \"dtrMatrix\" dans '%%*%%' doivent avoir des dimensions " #~ "(carrées) cohérentes" #~ msgid "not a CsparseMatrix" #~ msgstr "ceci n'est pas un CsparseMatrix" Matrix/cleanup0000755000176200001440000000040214547724215013102 0ustar liggesusers#!/bin/sh ## INSTALL does not clean up after ./configure or in subdirectories of src/; ## we do not have a ./configure, hence we only need the following: sslib="SuiteSparse_config AMD COLAMD CHOLMOD" for d in ${sslib}; do (cd src/${d} && make clean) done

gf60ghÜ9f,~ʆ@s1aT sj 4W\vfLPkt(lc|ay΍0 š2ۮ4*EW̄Uz1%TJKD :PqRmؤB#4c[@ \ [b+a%ǮD(q%cxIaTqvՔ Wa qik\ӝ^z՟,d$xaCNT# D!_`wgӥs}?6ôJ!̽ |i!u݁km6u0l|8Yc7ݾMї1: on2].EÃbv9OM`mX''g7+wl Q\P+ o,[{A#7^~\6_Ϧofɼ)|Z,~8pODzTDz۲[cCP-&%[ю‘=2nŒ妔w! JEEEE pHQ1sM8 jMEW}jхkLoYa ]BVrLI\-gh~b9 XU:7[|]K%n3\ u# OY.L=.**7+cCkFGӓf|-C¹QXP8r9 Z >9L8BZOZOmmҶm i\D\&Қ5!k"g@b3j^,NQzԢ{to4̾*\訨r\20WBrU`VW`/4P+&[0fmS}h>/,9<=p)( !D S&fCkH=jOFjW7`֦d q٧G=Æ6TW8c 9V-57c/_29R@ln` %6ϰymd`ROhI34Kɪ(&ra _xkɲ [aY #2݂ⶭ&K7X0 06]׉5ٛk^7x endstream endobj 1035 0 obj << /Length 1674 /Filter /FlateDecode >> stream xڭXYoF~ׯ`Jكh$.R(}q(0TH*}g/+Qgwof_G׳ы b4fK`xagԛ-1o/nBGɢ8{|'+I67>"|I?e!Q 6)Ǟ=L9wK=lYuҶY-L:z]4nI\J@)(˽n:mKe =k+=%7b*OB/4׫!Vy~z]>aiXjV̏_*oSO+N'#WAFCIȦCtC ,l7t|kִ Y[\yeE]3߅оCݔDnJ2ߑP\2| ~Buk/FaFjRG!]$muR*'I֧_O`yҽw<87Ԝ pXLZߒ+bɃE}41ѳi2$~|eU[|˅ѵ+DRT n@Im|}i6SKJ +@J2q'yqTs*Y5BEzӸvIEGTCRGog#銬CE$K!( 诮CUr#?QGtBQ[_WiM IH9\U:7rj!Q:(w(P([>ЪԘ~M֤unJ8juY"67yptFOZzeRW L-ngjۃՅi l9N MKIV٠aa4 yP84#*:|KWM ޜ% A: Wj5 |qv+ ڽRCW<;}$Q wB3QmQWR}Jb`G<;WQiV9 ?"#`Gm䨉R֋R_`]n@E&Rv!Qad/ t?b!w(d kf+՛x77<,7FY0㺮VŕY=v$dOp+$0.dZY>Vs V<j@}Wυ5 R>#F )?^{2\c)@a-y˗uUYZ$MD:Yu5s.cPL['K3e "M-߁i =Mi0ܬj{q<^nDCNPlmۭ]@׫'x c mW0I XgNDΪVdl6WPyz?T$[[˦09%ddH]KwRƕrr $> stream xڭXs8_ 0v P 77~hs_c%Q?2C1J夽rs0^}v3X GoAB :p ZEVOߟPIRQO!!('Fz.q6m8_VeT,W*nf?w[Y`m^}"9 *!JFfPD:yqJ)tO(qi%ċ&زd^vD5,Pzp DJB"S)3]'xovTl EC827({Y.LT2^8~[b,B,X0S5'Up Ք^#g)Rcvu'l3š+jlQ"3u/Yw8f&#Fqqlܺaՙ^ACps`볬olˊ.cwUjzv+@Ŭ=)RX>[0R'C(L x I$ײ"h 4Ac&B-1N3ĭ(4mBL.xْ8U2Sߴ 8*v>9R G :}fQYG iXJrJW`PgU.]%ZSEe)bլjDeb.LtZh Jɴ+ɳOѝ׮H#t۴~Rj)Y&ߥm(d}n-,U~ ߘJn*cn]ezQH*_=")*3 Z)KTeg~ 6ej_e*3rba<38CU M3P68VVp(}nԶĹȆyr6irx^ endstream endobj 1072 0 obj << /Length 2410 /Filter /FlateDecode >> stream xڵY{oߟMp\DdР͡8m+\p E*|v~,_}730 ໳o/Ϟ2&HXb .C& "2-Ep .:w"5Z)dT@ǭYeO}7˽mvMg?+Ńv$,61t"$ID?%\2?Њ 1T3/u.}%E݂}zDPT \7-ZJ6:ϡgd,Ohh6ԱJx~L* e6|1yyUw25\Y>4)rߥ9=`p}zrLna6>X#o@wʈSY]z.B^4LlK!ϬДdBզ*t } O;i>ȑ+*ܓĄppEf Ɲzz'7C]4-a'Y3H /?4) *]P‹>{<L }qLD;sȈAwXVʚZ'NcSN0xD4㧎W+)]_ݛ܁ KI tWjn 4G' l5՚C)&{(눩A@9a1t{^|> stream xXMo#7 W^4ER,H[ ,`6؃7vv`;QIL !'|&]p1DrL=1HńbadB6Ď^*NJ5LiWi:LӨ% ?%S>L0MeS0dyspɘ߆̂VrP,l,7lQ8hĊ)!HH HŠm`\lP֓aQ7KHK)[B@%,M.e&PvԦ'ZOǶƉs[dN?aSXɈSP c,=%4 ؖmKw^ E$'C -EDj IGN(6 $iNP$1 ]R5p)fQძYT,CJ%QCsL>r h!EAb|&G? f!Un 6iL͢@*͢:% 3DH,,S4pIu,>$4 6(',CY4[΢@ eBfb156 ,ehԽqؓ>q/fUB`n>^xD;%_-ô _ϝ(xBiSQSVx糕;:rqnY6;Flʛ=ث!'_"AƠFc?Cd{_NWulenu=ŋ{ jiGt9Y\LkkN.ǯ_yHro\8R?xI\]u/g9<_SjRَӛ6ryԽ/&E>t?v?uc ,jRd=ɗ31^!ߝ>WkAGȩoKE0 D<5{ƹ jTVrvZ\~'q5^.w5xsrM(d#Ά@kuڗiLsNWr_\h\i6g_t0u?Ԧ= Bx%ѻ)<)1< Bn텼KΌHG;Ճ TIhb"ڑWD h9@֦EnEri>_K+{{$I[>(tMbB_}^gӋA֑*'ڋnqw}uޫ9|TljG@]M. zxA@j>so[ac޾U< x>!!58b $(9vXPD[ }1oiL O^LLVi }<_xr|YyWÍqCʚA}>hA{ůBi endstream endobj 1174 0 obj << /Length 2842 /Filter /FlateDecode >> stream x]s6ݿBNb |snUi)-'T.v>dr]Ln'dN^|IĢ̈́<Ȉ"d]\n6i9_i>](2*䄘VXs/SAkϞ?SbSMypQ}u˺jm]~%0B@&Ju6T<"v~OrPD#n5lFvW¡6i[_w-[jf+G4I^anE;ǀ1%H0Ը ,S<݁9%A" !_uuв78aYjz~&!O߹_.i7;E  \|._M3x{x?;=P{sJ[uƤ^d+WKCҝBE 9s/i eyi+蔂*Z׹4r?&g{'>MYA6_ssw| l~lz8?U|nktkӱfM6R10FJMw話idpoa9.]ޮgp@^WUqQguA5앏ߎ|׻=m2mڷ"{@xO҃aj(kws7W'P> 0,7'?  LɝL8䐣'?LTfNpp.Hc٫|H'! >Ƥs ӯΤ˶60@$\=2""xGg-Mi$Fd' Y@lғuF}N˕!!-:Y&g&ƒQ2F#gҦ5 DZ#$ @ GHC@vLpоl(i a }B$K艻l,AبX3X^vm6+:-Ja  4G-"x%*FՅP[Ѐ')<@Kq@>@xhtnA=LK>ŒO<@6;Ҟ3iȻuPxW<15G6Տl-i-n:(z^*Oou;$ligUŲ@ 4U0PCC?`_®m(Jr )zOAQ+ʦVS,֬ҰnIϨ8Yyۮ} *hK_JѥvSqŏl R-> qM=Ғx:7,Ap8ҡY)8gḠ4yc0ִ+Đ'+t]FK2nS@۳/pu\†H]mK^.\B0 {o~1gBS@~dn[T6`ErL5:t!=VUéϧHդE M)8]]#zEz%pPi2Pm2NuPd:E39.Vf $~WFs"*:RB]i^ bhd{Mr'+iwM~8Uv~}؀9 Vu2DɯG5f4}2ю}5| ~*'ڀk9_P/pcՑ2ff7]- :TH?y0P 0;^]2MA%& |$0\l26.~9_rb~/?6q2}^87$euBB"_CV֏;qA$rk'n[! ܱB<9b0#3`Zo J7uߐ Uaꯁzk'.ԅu2[`=j{}M/⨾P0!VޥY*MjҍoNe endstream endobj 1210 0 obj << /Length 2177 /Filter /FlateDecode >> stream xYYo~_!CK/dOۗ@)P@R3v}]͔D;AE,Y W7R. 2vA0F˅ Fw}}sxo%%c}XmW8׈i*;IdwN [ œ{7ҋ?SSƛMVcPb3,W(ɪtK)"C?4-iM=&p$Ѵ~\y!L!Io+#XXqiu+B%Y&(*1`Ua4S:&@[uO\u"&MkZ$86p!ATX} ~91`h?RV{N :~Dž>ΔKcc_ѣ}Q\a_Cfח& +kva%QӰz [' < YSebW2a:W-dJ.$K]{xeKXvrQ u1RlXb 6$'V"EAEJ\)HSz O!չ{,2S-vp+V4K ׭K<3k,ْ:VL@L(,5$FY!! 5oC] ~ROsmٵ Iu>IgBw<vӸ?qem+{#9wȨ kP2-ߙ8!kSgfT?n XN猆Z#[0|6qtx5)eRjxV\s:6井ZMnR2ڂ.kb=[+0bc UHIt4 ڡ"l%Є3-'U/e@M+z׀OiYSLqßє<Vl 4Vy+! FiU.%qֶFB8]j-ǎD#iIN>RFM.W+Ut Ƕ=Y> stream xYmo_!䰨|۵llӱx%9nq;|D:tE~HDQp83C~%;p{n}H۬Z~cͲ/;2{D#.cŻoЋ'^}V)>խ~?{ӰhEe]^WHKKBvo ǫP8PVᓯ`|Eks:Q&:\ E:(Q/?C)$zIM +ˣSP(ňPߙʅht^~ɖ]ݴ%7Oz> fN]ByKCTUW<3: wEumƀͫ2{SAЯd0uTwvdH#@LoQǻJ2f{Eq~տxS+^C ?x#'8q:$ Dߙw:sce[CБQCG 87[$PH0沆CCC<<2U:~.q8hנI1j~Rm8X/W_0yŔf мrHQ|n)77Ϲ \Cڷ 3o/BqiY'7յ[EPڜ5UֶGcw8VQ5mk^^ehmb?USB8JJkDV@ҔN7C<3Ĉ"MLR&k 0FQHf #=VTe ҷZH he1=O ǺJ ɹ#DOE(0{RKXd1Bc{B8,{-cܣ)'ӂ_ǀ!j|CߝIS{d[Y..InMi;kɈ'@B\NZm]ؖo iK+ Su>[7 h((9l'UYeOG<$0=$f+Vdɣ pp/BђK.@8tXjZ&:2?y<C<`ؕM5)+_<;"S*s9݅ϤR,+CX*qmu͌jΈ1'h8!{.wǮS @^^}T%KSu-;p '6e%SNf[є;u)U1g{i&NV1(> stream xYKs6Wh Jۃ걝&L&{IzHHbC Av}I%Ktowaw/H\6?4.z(G< rd@w;rAhֻ1ֲ\}_~H\ j "FZaF'c'i]~OkbcݭmP@K0\l9P8a?"B ?j˷YMe)< e/A^5Sa:iVhßP"{]iӠ6HM+.!NӚߍ59"3A!Fi ٷᗪ/,.C6h=@6 İM̴U d8 *4N)Ieki_g$ja=%լeeuH -_ts4̣#H`pK`C;a%ڐmE7 n(`vG#*W .a~s5 WϫK)"}qfMYƱ+h"K+RT[>W̵C4h6*Tڂy6*EC!FvsS+H4tXj H|c &jW#PTQ)`'pxFyQ*P0K%-!){ cB̷1;uI57"UUQJjS|M?$)eXQ,J?-vC`((5b&K t. g;K>z^V=Fˋ-~ڻALqM5ZVi33׉wfco9۽]Q v__E[޹#JQ'Mj@UOn!Q#wzUCn{\a^ޝ B endstream endobj 1167 0 obj << /Type /ObjStm /N 100 /First 968 /Length 1988 /Filter /FlateDecode >> stream xZ[o[7~c@DP(M +̄LXL*L?{P&NRU5 !c;vW] ]l"]H \D)2ΖJ1 `a^Aqŧ:ꝎD YDcd$@؈2G]cb"!)sDq:aLQ ` 1fDUVIIX%JX S,z2ɫ @I:R3` [LU(,2=Z&[y$κ JR`"I|x#! ȪPdjm$ ȩޏ{n`t?G_]\:GGGGG=r`5mٍsH=vdfwXl@|>+s|ldL@V_;A kD6S!-Nw1zx@dG[? ,Vӑ~ teLӽ[k|/bbfz} j)IEpԝNb<]ә:t2=ߙ3g4IifosyytPO4UsJaAE"xg&E-!MBa#{=xa/{]~qz>r x'DH,I!Ƌ~\=b)d5B h>l5[wbd4^լh֎/FM|ϫ QJ wTՏ.sH Ɏ2͑l0ܔuȍjݺ)n v~P+fM1-.Om je0X^DZɻ\+=ĵk\#@kFFFF "ae-%jDh7BᲒI.â(loϮ]23Ph0pCDy70p@8Gs;Ga18fF *S GPV{M.m3Ya, &Dwú<$,FPHF|AJN;KZ- *ڜkg" HGْ)Ȗh>_{XSwB k%"5|FNm?5e;(kyxpWూVȺ ١HH{` /3ʢMHڈE Z˵Koch3n{z|\%tOZ/ޮV/n>]]^~]?wŴ]-O:=j9M)h~Xc p 7X/.kbD`r~Vqw T!m![i\!B/Z /B<#}W΋HNOhG/G5V킃>lrP+3wirl0丕;&ČvFIm3~wfx5n7:(~WU^o6;o'>ՃZI >swpb%p.o r?'e_:T*ƾnpqkqkqkqkqkqk1DkLI!M4DH!M4DH[Y>;TP 2u΋j Y-l>[M!`ix'Cf.*j" U 7u{h1p.1`xC?X5'V CNVFvKqIBFWޅLd Pa endstream endobj 1290 0 obj << /Length 1575 /Filter /FlateDecode >> stream xڝWYs6~ׯ(Dޙ3-IfIPC{X"ev2KpLJuuތ~9NII9_9"'( }/O#1iu8cZKʈsЍ]gϦnHAޕzaӐ^~!G/rywJygM0^5/Jɷ{R~oǻr_oflCz,,_.p88&%̂5zk*d%ZorO*+ńI*7A n\2 J P+ko,jʪ`9_w<@#jPL,w $PكUY) 1maz#O6LpZ'nݒG_G*FxmiLXE1:Kx ?MkZ8 _m!N*̄q 6AQFҤ(ԣb2:68ulPd@sQZ%>NpMUgwPU?@A }J(pDEm[ `}(ҧIRTa SMؘ$NvxPa`Idkя0-4Р)D!GSa`&%,$ ۅ*hMڻR.xߦ+R4086LZL6\ >8UlY!\8q-.!YTpr| O-xoqβX+ȍxr[4Vd"Ylf&]KW,$P՚d':~G+ RPj[BjockbNpb.S)ݦq=]AR1Fq!Z ׭/,y2(^j?TPFӱXNp ES=%I zPŧ!iׅ;)C+f1ۉE!e !We^SeUwpZ,ln%N%wZr3au*SȹOg/X(mC$[4$A|P'S(f ŀv#PR(\껾WS7Nz[uTVj"O.t6P+1 /wcVqЂ]aJΕJԲRU\YRL OQ -%O?߿>??8 nY}*2Iy›a@>$;'QuBOI}4LuP=};3x[gFV#62kr> stream xYYoF~ Sٛd>H6n_Ė"UJ"`\n~MF NR$DX L'9<%tݚKnK*pk;]P3;BaRŃ]X-(y?~-/ )j؛UL(A+g,f,EDbN5Y+gP)q$ N- xi#$Xf\lAqPonۏSE xN5P~7?Z_tokcZ|ZډuZ?_)t[$ǽ*ۦ;T)ZPb!,Tҧf5f 4|Mkg}Z؅}6}P:IBvo|!b\P"h~-︽Z2#&LZ-Zbݾ*Q< z)K!18,FR&7%F?(lU]Fl7v0^b7[aKN/ EIoP'<Tzq`0u6sq)!HNbOWTkJ1gq`4܂w5nG钄cco*UuVu[:y:yg ^pHӭx)M 2 edPJzmP|Fv'K+qNzSVk6Gp0knN-H9("h?Ws߳O:ϔJt^GѤ;(d(iv'fFaCJ9. ѯsZmIARLy;Ԑb:'GOK:ThFK)m7ia5I4~ab)0;;Vn*d;.6 QM2'Z۱14Lc=gT8≜XĚķݣFEC2GnI1;1ju|qxp_PSJ/SnjݩM2?ԫ8+"9MUj ؕ\<ò(-e,򿵴j.@Lξ~W}mYllzx</kZj YtH4}OhLWE{,$Нw 8FT~Zv J+`4߫.ZmZcњǑ>;c5 lx_k X cʕccJe6`nbkYnL5t[-]o%ǷFC.=~;MJop.ҦrD>H79$;* &+NzܑvUy]V}+,ܦn^1UΕswԽ.k6->qG8:?M++X4z0|«gЏ1(?BRkMwoӺ͝ߦ*]gH^MH}&\4.ן<` "ATrԕM0Sl7vQv7ϓ< ޲` C]_Eѕ_u~mILYswr ^x7(@ROq۪LkDc{y~WCY9z,GlHl endstream endobj 1351 0 obj << /Length 2493 /Filter /FlateDecode >> stream xڽZ[s۸~lVZ.@f4q&ƻ/IfKK-EjI*$;tv" ;߹(tz}RG$QJDfZQ"]go~xw`tڪ^p:_iReD ۼ.9n7X+GknkO"k},UdtYLGV'*iXJJYm=~?%;g/95t .=1Oz4yVbޡ=vָfSq4omgm #M8$SK- u< AHnA9jvq &ǒ'>02x)lf$lռ.X%/7vlm jckV6t:X3Y%?-3E-b\v (q"d6Zd^\rX̘[F;^bRe䙄 =㰱^/Qxxz|:0 \\΃</BqZ4e 6 H |~m IZȃhAK߀%qRzVKwٚXC3 U*X,;<[#;2 ?GI,|h!!ߤMv{=Rݪ7"n)WI E]S,%%MUŮI7;SysuqPع+LnG6<>EMVۤ2WڭۺڧQی&gx9^۪q^`;x[hw؀,h,J ׅjQkGӾ\:gf= 8>3>&ң)&8OH~2/\g% pƆaнbIO? !u>aZ"^lB{F|"$Wobb2}0䪷N86!O_I=!RJAo*dQ"Pt?j!I?p8\`)T 1 QT_SԿH d"N&g@8ı'Eu "L3KVB){>?0't)5$6pD(6F! 6kQ? `}Na/9*.F nwqqLA -<6RUU}ٞڵk4 +括ܴwAD|dp([hc/F' 45mM~/mSU ślr:絥 h7'0~fD ab0Ɠ afo&4H_ZeZ<4~ -[쏎.}2G)yyzQW܃gbB endstream endobj 1274 0 obj << /Type /ObjStm /N 100 /First 982 /Length 2138 /Filter /FlateDecode >> stream xZ]o[}ׯCy9Wa,] v ׶J23jo"ږ sp8sy aM6R X g2@R"Q(A%""Hx A%Qm^6T5 Ttg1Bdp:xrxj 6VT R4;i/ S0ŒaS,pYjT@8@.0C`HqYcLId1R)N;mjbf  IL &PERdB]6ѭzwL` GE%61aZ" R&PTL! U"P}4ghe> XK` ;[`lc&2''97_fgyk~8o۫_S{v9\d\h~i_!L K k$.YuuO([Xb;:Iy5ZgjsLdd8>5ۏ\~Y-ՏOJI-rXBm`[:.VaXʱؠՍ)[Oz9W`) .VDv|&b|EB#`lvGoG#>یE'@&؋l~|h[bol'0_션S60lB j~LPT d324hU <N/֑`8I`$VZH`U`'77I? EI"9.#b[;IF]=0&PA: V{vxQ{>3?oH`o{2b29A =#S;LA-Vg+OgU)V\'Hys^? Pi>D%7y6ͻy~^nx7NWKcGŨ]+r<|=l[&!3, pN~%ƯUªEZ(ܽN@~%-"(Cygg#\5E=v hl͎n_ R}3/WլY馝̟͐9QPP +{YO&<#bMRl41iN%tI1eˌu=-z:%C %Jnpֻ[w:foC=n}0qyWye7Ec(5Aoڿ-| endstream endobj 1379 0 obj << /Length 2867 /Filter /FlateDecode >> stream xڽZKs8WHW"$v/vjf|RPr~vA4Dsҁx_z"Wxw?KyUdL^咤mgH4㰌?_ST۱I6ۦz m8҆f;~L^ɲ$۽$dsW jY&u;k*՛?4}z@wo>a4ciS~1Z8ODpPn2቎c5]kzácB]33,P KT -uO=T5MjKDXc-QC$FZș\0I# ܎$FMH `ZNEKjv lq_B !4+;H ;5Vu31na|k~*ʒ3$Q{`oWáh2D(LܫtM&T;#RՇR2e|P_&€Ǘ,3!zBƮD湼x}up3/sq^. 3/`MufMPLQ!{z?`8jvVnڹz ~4"2B^^+0)nW#<(5)/Eg+imIe|R*ۗ+uePN)DJ a*fŕ = .zjzJfF7a|tk) ]O%٠ǽar&GZѕ]^:ELGp5".QKA-q |݈>/u#+9.h> Kٙʝ=)oΡG76lX~79mPʁ)A5F*c\!,p>% ճznlvan ڹ@8U釅 _( |CJ&˧+ Y;`r"0^B3f+[bARVrvW9V 8B]ÚeY_)€b2i\&"C|3-^r64_5w^|"(氅"MQ7?lN]yDN kD%eZP XY#B}1[D : f{eБM>xK^ EXx2 5w]2G|q3l֫0OrGC-Cޟ19f &v}u=ڔeM`qe I ߙQmا^Bh'?=؁)Vts97(Ka7HRBLs)%I/$/l&I|mtتYIh%ki!T2Sm",͗+ȕsrr՟ 4 8Klp\\] _TtuA/ Ҙ !_7t2x9o~r#GBHIkA2 E>p;H )E@ҼlO}o6lKM|>[͇Z3%>vcEhqlm)3Q/ۜ-øjBbotjSH< gj0`sNiam/9еsgd||V'E3NNzqp6c%$30ntښ^g5n]g y -7pAOq dZa Ƙ^WڡjY7P7]We~"7)ǥ\4/["&ö)!nMΘ&.-( ~}v> stream xZݓ۶_q'^c!?:LS;NIN|}JyTH*_],H t9t o?js_}/7>}Hnx34ꦼ.zׯyEֻۧ\Ŝmx8~ͻIaXsCL,'& x:T7۪vVRJ/Pt}u1tt$$ AwC\H&k*2)59؈DfL֠=]W5F?E"q~j>">:)8J\lyA+:cY*QSP(%g:yyROO Bn C&`?V֌_#UzS;)/qkJOeu[K~oJף0dC)K 3`g;3C43G[m}Ќ _&/S۪[W q)pǨ ~Fϗnch` %@մ+ų`*cX7=%lҏe߃&[F tC]BR]]4赵q BIKk&Zڐ jХtD˥^$t f `U Bkҙٕ38,'(f?ɹ ^1-(1Gb*˓n?8hxaT߉7!-f PwPI6S7X%*]-g_qmqeBw|3ܯ iKͰ-)ym3iݝy>Mcb4=m)D)I޳Mk¼nB8[k΀ C6~k;MGT]k_-r5I[.6+Cz mj&_( ,R)리& ]{ D ETW^b cM5$ Kl_|a +IP2{ONyjJ_nh2f?Kl/n wjRGg!)-P*C?,Yš@G0~1r3TI7){N؉Wl>/69M |kh5HNECՔh^1g혒L,0h'm0[1¾>Tx'{-UugMIħH@NFQ7X곡Sq)LE94F*Sr. AfQqoẆFKS]lFXԱKf72Tm,t G+M̔=>/a ӊBmRsSb#'įשL8[ t+֧1i>Ὅ<ψI:Bg9*u| s qyQ C쒘`[ ;se^3zB5 .>PK_#g|y&1\MK` ?*G%,I!r&!GL#F#aD>0">F}z3C V|vp! +i,2ϻ"󣸚|"řz你lN~;p 8IE:9J,ڟSknl==2ә-Z9QLLԍ=%`A@)!RO9)=F_m Qi(V">SQd2WI0PK jsoM/.oB4(zN=Tq VjB2J1;_3R ͓yՋ(肑69҄HΦ )Q)SIVS$OY>S\zK`'䆷 |dgA,ah?υEZ&#f3i))ڦvI4(o1SN7Ms0~$ |FQF3O1';=a4Wz:Ya|NEf{ ,%I+h|r{*ht{ (L6ņzOOƥ MG]/ŧ&FrZcqGEܿt{𛈳PMkgOۣx>N:}w>|úkе=q ̴G.d*fyr_X@"Or9EqٻSC@ `IjގWU4h^_uO&C6x.fV,ee@3^U==Yl\f$z5l @R2^07] Í_<7QC+? endstream endobj 1426 0 obj << /Length 2030 /Filter /FlateDecode >> stream xڽXoBdkvWU#'3bkq%HwE%P33yPxW Ab@0F a,8f?ކ11(7/.ER *y6@0444-X%#oX $Bk p?OKTŶy?ÒEN%ցB%0R#mM"ʫTGeZh^Grz8O]Zi-7ľ7נ,F8hK^pQL)ܐ 5!SJ\ֿbL3C]&1CwSϳm"FUɮ)\4a֑1Oe2ySFc#`( 1cJOLRoԙpDٝ!ICg =_v̡_ܘZ&6?hy:ȵaby3ΖE Yk( _jM}}je^$w臐 (Ʈ.N)uU­K@\ֹ\]r],{^^舞C*ž  #C, 'r:Pɐ0t n|؋5$hH=c!5.XkQՅ ٣ t%Hy jn+ƖۅBQ#k4d>)F& ;sM>7xH!Bi>CnJq$ ,*SPdPC"8AZ QG)( 'F""a aoB6ޘ0IpA?Z gD`]+w<d~SNXM d~4aǬ54{8B>7ۚXTeJ 2KJALu{t~Q#UL&hF>_ _7xڧ<#l]Rfkc9ʍ<1}]Y*>wTHJua0aPOa +^ەx+^MзK~g +:'{+y-R jU\έ_?g"DfN\|gIcPMzWE[D,6{YR@LZSduiNj֝eNd M{ &xzRhb/ֶKz<B;,Cgjt9k٥n3X=N~BosnҸ/3MWČJqR2K; ScOGyyEROl> = KMaYd̎AqE)ħx?iM Ux MʪQ٧<{0MD>TIOg sUƮlJE1\"4~P|WE@;I}W7>}ҿKِJq,Z3IG+sm[vrm?>NI~C4Xּ\Z4e͜!kZ߉ , endstream endobj 1439 0 obj << /Length 1966 /Filter /FlateDecode >> stream xYIFWaԀUf$f|qIf HIP6Wɢ>,z[}6>WZ,JQ*vcD$ʣ6Ǣ?4yw^^1bd 51d[//LnhBHlc vlF)Nϟmx/mߴ/,:|dy,[?f}[~rqRAr\Z]s,6 ˲[vRҳ}aTyYUǢUs׆_l=*=6t}s*wukms]nJ}^;W;GJ+ި-fJ=>Zz=98z~vIM8 ?`U) V͏Vq|kj 9;IIjQYz鈗?XMם&_#7/p91S6..6ݲzs ) xlh{\#rA4MMz(Wѻ/_>uā08`.δeę) vus< =H8|/Y [rq&Z 331lAD'C-x BEnۖ:xFO{qn'Hg=.:SSڵPe[y sv,sRxfDt #F$4$%cv=I `pD\"T#-te_l>#D3- ^Hѡ0b{872ܱ49A 3:8{s\"D?D$-l`Gss("$Y@J\B^DCo^`%So,,K4_t3bRGC"c؀گ+fY[* ԧo6 ׬C,.~u%%cO]~$)J,"+2iTC.8`Ue8)Q, 7*7suF SM5ΦqK $|?|kc[T"$ TcU< Xt} /`$`>?;|@;=6P!hv07.yߔAd))c):K%†ߺl_ / U_ETmNB^_61qi n_A\w]im1#A6o!rVylz+0!K{O&БOn:W|5{_eX|S_.ڬfנ$fP3KSߞ}wzDH~a܏ydT™gVQv,{o{ s[4@N=5J^*<.{?"b60 6hg J3 b.hu44#ڪ1)HmwA0^§TMI xà+4n*|2{&jR_JKzSVn7jTs$1l.T+;U04H#gB.ѱIIڹȴeDheW),^JyA;}9TSkCm'"Z ]{3 endstream endobj 1473 0 obj << /Length 2949 /Filter /FlateDecode >> stream xڭZms۸_tT'Nn//׸I|t+-B/%IS|s"X,}va]g~~"&zq]0JzjJts?_r0R(/$xh\qN6I/YK b{3PK/5%E2oE[1$y-#Q$ls?_?/lLJ+Aipޖyb1'HTG 52`\2Yt0H`>+}, n+;E?o*kv{ l.T~'$ߜF*;03yʊCl|P *&AP{Syhk$7Y5wK2g+JהSCD~^?[ WnE֘ѤOw/@XTI1㠭M=e-vLsh]NƟ?}?%I8&ֵE]jkal8ۓ_rPLۡ" ʃE{L< # cjM]wQCovs""rpߒGߎkl>gRJ#Kvw۶4E5<+r~po/4zÄd lorC;c>4Kn $iL8Gu=dP踱A:mDr&邘"f,-! g H :ޚYb]vc^|wu2 s GyryI-ǐD),&"|.R(rĈKɼc|Ċhye,bا&igFhy2Q7uhҖgX$RNjِ(8&}z'EEO/l 9PGE#S{<舖*K38#??c |C蠯#4ؐϰ-gt1 Ӵn֟݉<Şh@BO"W^צJC"q< zH<•8 `٩܉5< r@6ØD|-Ig+Ȉ?q$-8#\,%Юb[]qL0u1DMަxG]$:g P=5͡v.Lg7nyrH6XX{_ڒC-bHFD<1T-dz( bRvϞTgG% 'bG<ǗOi,sIY;!/lyE6||6kǾV~@dL#pAՄ@`On\*4:;]z*־?sGW9R0T3.4hz7cG\#5XAER'clml4'}a;9K RsKƃ!8{ 7$&6n#4 іl.0"o+E_oVZEk: s2l-;H S¾x/ ,;],,vs]/ *fR԰,Rjfvc ?۸L]|,(" C` !8<1 5G᩟Ed@8l$y PuZf2j+0j@(&7VDx`ծ9(4_M.L\,~sLHˆofvE7cۭ=߭ke[T0dM;a$,4eڹ|_٫ 7X!Gshv4wssHeqd=d,t8yt,RCPHt4z-Nz *AAX.?("sJ2oo^^JCSc{ ޕ~I2F189;|{Vps z :[#5;ҤVP7S/qS1jFԕnF:}F}+M9[!@,4HCxsojzBxΨ ?=+.׾:hFb7<#jq_}BPX~+Zc4^u 5QKMSOsQ endstream endobj 1371 0 obj << /Type /ObjStm /N 100 /First 988 /Length 2580 /Filter /FlateDecode >> stream xZo_ 3~i$yP,|_PK%J"Kh`/W;;q8\3#z^714N6ϕ!RNS6<1`rQΔ2R>J!qd,F0y )^/Aglґ7̢.`8H] :[+]6\raⰦKS/^߀@|2S tb~܊D>J2We#ReSHoO0Y-odH #D{&7gJG&קN I&TL(ULt1{ {bttr}WY *hE,9 *gtK#Oę;ȓkʬGO J(@7"F0SI6`j&P̺}ua v^߀,s1feM~.?U *XE b\h}Y J *x9`.X±螸_Xq+]edE"" W0#ϕTfA{j^(yn`㬇 CVMav}yKC~>: W/509d+i_gliNOM .1`3F 7pP +W7p)p(1P(GPKT(`MT=[s ڊ vye_>3Y/凫 '',k2[.WH'ɢMPe2~ߛW*P |, ksyFs0A(yEx6*(f'݋7z췓~>u+7 RRllujlp u^`xvf-Fg~>s3|Sj!NP wVj1 Ba qnĹ5qjesiK\8ƹ4ÆHሬ&$DQ; B|>lU'dۇOF:! Yc`*y {V |1YY6ú0}hT^#6iRx䨰96iJl5{)RVX!&("6#Ad3A6l7fyT٬a!pk8('Kq!{ĖZd8 ՟% Oaw92+Y2(!VXكZZ(*P BV Wxλ@!&2@} K)@EGlk ʔRwXN-GX$ X|lXנԵLmFaQ셓=]Rmq~m pj6s2#g_E*@CHYۓI*Q̈́)gKbP6xmb=b u~DjZ%dsN(-L2/`ې=Zjޏ(`mc"s pK{l߫qlZkɪ޽ V&QɄ=+=hGa_,w-\ Km2 Pjy4b67ԥ_:G ("A2dp:LBV \{|zZgi׽gbZΧˋ7=_r~.m-hfCOUsbۃS;,HBm[%|;V^kJ/ZX2;c$pztbpIH!0R +X/G`[^:8qb.MPbr dutWG߱pzӀpս *29r6GmnCurQV^n&ݦpQ-Ļר*CSIw> stream xX[o0~@iP0VmӺ56fO]UpX%sӴ> $K/+R|اqoƗOgtN5plrjVEF?0a#`8f3َjs1j [഍MI h}|9F37`!mn[ʢxz!Me7우n6lDCH @~U:B=Wa:it8`,;O(R:=T M3ZB&1+52iD3g0/tT!40!LFz-е/0Kɬ-fݙ Q`A'ǔC9wEA-߅*ZE,ՏF&$p[RLxN-if23RL/POpJ} Zy7+`t(R۪1{*J/vWŖ2&aLIt=DT3ef$tN8UjN%^js`ZĠXACo[\봭~FRgymWHqx ~ji *xv鸶e;n1q0 8 ̒'cu\k)>,uʼn3 .-5y?)MRYK ҐWP$⮳d䄖*1K,ҎecW@Ӑ :9+UKUk0"v7f+HhU$Xmxh!$?nѫjJn 3oU lF~HP~i8yq[wW"گsV ڻX/'0Waܗ.9J떜-˭dJ:pYrBAb$'_ẻ*6\wf﬷>ʪ=: ;Ce\@}DG| u= 9C=ry6d%t? endstream endobj 1493 0 obj << /Length 1730 /Filter /FlateDecode >> stream xXYoF~ׯ Rٓu;H>đIhRBRVMrw9^~_87ƈ li48EcDb 8Jf~[4+wUܖZa'^.OjS|D`0ϦLy|sI-?O|$[ ڱzTu[:oDNFoB0E[1Eg:+۠մAk4j~ԏs39}9;Wo`fWY{|&C8¾za)A14"m@aeւ(\"o-.,;zm݀nRYޯj DaV-ҢIn;(XxnbN'%yO>yU*GWFL[?mxE,wnS ,?Vy (cl2+1@'P0؋]+WpL7;].] ӟ|64"{# WI8>+ѕ A!g{oGo:6TLƀɀ!p0,R1ТB8"-y 4EI*S˕2 X <葋q(D^Qp4oB3]eZϫldeam߰"8АW٘ nL偸#7 !|B$h7k,X}#~^JUʒbɓJOƦhY ~P V@tDQ+3u(!8\7Mjܘs8N\fC'Cjn8dqX@LP( clr$:iq D`"DL:ЙNvDr?^OBx  4Bbe,\k 22)>tx[VgCƈ)*<菦m [b.sʘ6+TRM=.l=ށiT6wxaiU 5|a}qԍڋ*Bzjq@`#!giN)WI*ԮSIG<&gQ#̂S %x2q2>`]5tCkL%bf+cS>U˗7Kw}ItyG' 8:ˣ+sbAe=%(o2%ؼ,J"]y)rKfHr9Pei!m3V@N12s tKIBgZ䭹Ik߁^2-T&r8$_EwZ29ݢ~?ԄD1ۛ7sLJ8 Exp:e}o@fWǓ]adf,7+H`*>[W\Ci /I*YHmjaȫ^zcޡB!Aw1Z?h pMhU͇DJq#]>Z0hS!c1Pd_8HFl1 ߟb4"Ȏk6E^"-LřܥvE/ ,!~r\XY̍2Fei.N]nbK}.m+IdPF% yp*ޫsNcNaqd}L2|6 V endstream endobj 1518 0 obj << /Length 2322 /Filter /FlateDecode >> stream xYY~_!8X@Jv$&lv'yY-q4D(&)LT$D c^uuWbpcɈF1-#auSUd?VD,_"mo~1'@VoR-ÖQ}gϚ%LmZX3[uQy'Ʉ՚ l&/oCwOYcd %Q 1#*D`&H#yF -ro$U|o Z0 'LX\B%2d HAEADO]@Ge^~d B`(!2A,% a[[F A2fW k0-mĶu\d ; wJp_շbpASM{ :'Q0 9L6-e{x|Kk|kC SK+pHR?fe|'gʭaE"D9%98&P-Ap(ǺS1k|L*nd]"%ch$ "b+%U}jyxmQ:;js!wzs)- )dY_KHc#W!CYx@0Z8m}j.۪ 8WFN=uIq -C'*|L+cA " ZB/.L$YsF r Jks5 QpUְjS o% 摣?"֒_۷uUf4?eu7nJKMk7=I;(rL +5omJ"O9&}6($v~,37V7T8JV Y-,'(Oי2l2@*wo|d^0H!-lw;#Wy֕Rg]H&M8 =&8.b/AqtXg:xq  *C87uW! ֋nvM""QTݛ0TB2$/WSE6LOXvKhlΦ"wz:NIG8~}U,aO ]2dBe$<L˗C1c@kybjX_HM5#S n PULb`.;=|~!q( ;Kȧa, =[)(Ϊ 5!sP]v4OY8Q2ؔkl\υ:YSԴpptrU/;$yxE yA#d@#IQ)x /JChi"BY2SykL!%;Sƀ(9I5nhI$x2n9,2K6קŰv'$% ABϩRxRYR!rp9;˭-@Y}KQTKu:SFGt S;+aפe[Wm"hGۮO,i[^!R#7K;:mUv>ϑ`&$O4wl7!NUke'Xc.p:;d;SS9rR{(8h0hqt ?f$"H}7Q&ϱu9lv]f}ao@D':f<7 th缔cQU' ʀV6 endstream endobj 1553 0 obj << /Length 2584 /Filter /FlateDecode >> stream xZ[o~?bq^nҼKJm)rRuwiRHc>3$%JZ휴EQPp曙oKO ӛ?޿zDs\0JziJ⻥7?.B1t1_l4ajZi7o_ QW+C76{'P&$l$-$I}F1$E3$%EEVlMfs.r>duOsw3T xQ{c05ާmܥ붬mVL$ѲLZqA,&kr_9F)0D,ML&kA+3ʶqoF0zs0F(M4[bAœyOX~OWl¾,P WgS{_=]<0@V(#FVD)'k5~S5ft kKrW[np}8-יk5GD_fynx4GHn7~D$DlA-,0h5(,6?D$?lWb"Yq' %u))Grbi 蝙HI~L$$Vp5o~ugL_ hꄤXKDs߱Og ֑21v M^lZ ]t0N;g:)D'Gl3^N*33$fkZԧ=S;]bT]c'VYo (u.5IHRUIDtVB' Lv|;tG eG :{|gPpGi|VUubv $=s⛋YIThջvף_ָ>^"e%7?3|뇀;y> N![=@c NnE(9+ RO_̳i/#\j/f50Qd5?+k҂0ezȒȒOO4*+!M#rAZ}@XqC~frCK&Ï`ƫ&-ŃqLaԖ"xۛ 湟=[_‹Dz1(BBWJ{(b'֥fr+Eɞ*fMݿXUM[Ϳ={b.~b7*^ngEh~3v{[զB(jȝ;W31%\jDC~n?-[ 0zT|4ªA FA@,WA,&:4τHsEZBD!kB@9?p"./R @x Sg[̈́ZyP`Q25{~K󭕃6Tg+\j?(~j匁qҧy9jcju:(\$-]ڒ%Aʃ,#e3Y*^@{*𨆲7&ZOO bڌS "JQi;KVkbM'R/c$Hb..]^0BCxv3Tmz I8W8wSzF'F'??40pG?YK}EDEThlj˨5)c:2_sΣfA7~ j&"vTwD Im+2檞[zB MQp Or]*PM-fIVI@wv4@;#y,e؄Y3Ў;nWG<\`t@Zǡ.bp0!5K ]  ű`*ɛUL x JIH=d/ƍ|;#k {twݰ(#K"LXWZ'aHnVm/\!v],OR0{8eFNkxcyصxUxKK_;;3JSS>·%Q=1 (u^s :`9̕MğF*M1Ea:vഴc=_X_M 5YAX8Tz+`.ɻKXYJΚsBu~ޮÎElc'w-}WJ[j6J`=@|6d1|ug] endstream endobj 1572 0 obj << /Length 1832 /Filter /FlateDecode >> stream xڝXYoF~iĴZv nܠɕE"oA+Ʈ۹h{ޛn.׶scQwnX=i&i$b1yy>rn|mY&ȞXqE'VY;;RGkG`ـL4,o\$ 8]JYR]sCr-O֙/'򩣅0~;AW,."L_`MZΘDl@{QӏAj@&MaYir ZܗQUFGɿWTl᭣ӣKchW \9y5A0|"&2ujW?Sӹvneѓф|ʿsC/?tEʪ/oE&æe+sD5FN-Pl!Jt<52&zB^-]:gl4lzF*^)2Lp*atOjKPoz Qwhm WJAŔQ?fj'iAq!fz9,h(IW#Bh^!m]'W;cG12n?^,X?6x`dmnzAlBVQ_> stream xYkMT*Vyhnޤi'0wŖ"V{3Cq(i`0l{Gŋ)#2{ƈq)`4[D&N?ō=I"V_S"&*m6n7D1\rQͨ2*$WKtuZ.3{^~k/E28e=?oQdhy;|z7'Zf^}S٤حˈ8zjEW')nPGl6A%:pK!0RIPSA$bFPtYOTɐg1T<HBXAB'봞Wٺ[~װ(/mg%qG%)OS'eDk.XFL``Ia U= (Hk'pO"F4V^=tD l9b%ם*MKcPօ]Nb;;FVP+e6_Zˤj[cHH ;oZm1o@3nʜDdDZJ1ĵSOFqЕץ{@TP&Y1<"b `I`E(,t};H*>=;u\ģɞ0/in,.)X;U}'S1jʤ~@#4(Vd & I >" O.=s(BQTUўx ġL{OSkPxOa? 9TgP?T>j4ÏG2ٜP'*q)R<;/ KE)~ԳqҨa2ұA;D j+~~LO{1=urTU!gtĢM5./Mj{J+v%&O̳l)00`;wz`"K¶;P~L: ΨP6%I+~4:6z1mtաN380^Q+3.4H4oGLWmmv_"ڻv`Le Bcݩ[|fz_`h1 yN{bߧ2?l;mJ5l!/ZW_Co/UJ,fEj xB_Bb:@*?i&$09FP,–NU̠n0JQGƦ ΰ@78#wqX;u7  M'fdyZ?`^Ha,V&+BZB/.uS=@F:qc&;=yzl~ B07IӤFa4OfN.-'|col)s,lyoVE}ijYB%kZ`6%_^A^<jOwbk4Ld46^'9R6+8m ?ܾ>#3P.;2!t, 644C^͑zd%E3dnc:zPp8<89D白Dzo;Jot)q=I}.E~E?[׽@;=jFb欣ݻ߾ڝf7 5b>丽 >ހ?r7c`O! 5Ym&ϙgc?//Ƹ/;=0~S̡aYڧWo B4RG(MT| 'a!5tb%꿿 endstream endobj 1481 0 obj << /Type /ObjStm /N 100 /First 977 /Length 2231 /Filter /FlateDecode >> stream xZMo[Wplx!gH>n 4@BĈ+HJ %#,ٖ,0#R$ 8 +âc0n@*A Kj )+Br\9i&TX7MU rXs60ԴXl0׶%Qg2V]\l)J`mUbMYGƺJVa\1`NHE6U%'s9I^H+٤$)P{ɾ~/;v-GR4YHg69%!QH瀃@-X8{ R4QHBѭ"=%W,ئ|pxxdNQtxc@`Պ냧OoWUmfvV`C6m lkGdaMw_nG0#&,ԻB\=ڨW~f_=η^X}֟-̉~tFӫ^ ގ7,`h@Y^Oġ [R fpqտjW]SV^35#_5#ce3W 7U=Lz zLD &/.o~6uKkzOl֠{9zڳj֗,gb='j@['|)2ْFLP wL-iz&TLrWnZ$PEl~}vb;mxi{I6y%~8T[>Z>6GL ZʯjBhBe &$s&PM瓿vQJڬ53땾 i1-:/k?t U4lEi m? -"VdPdSH\@P *:,/T(RW ~͆|%52+:_Sn*R+([j#HXG" OQ^ISwkcԽ9ѵyG\.NJ/s&UzȜ+ľ}o6h%HRrJ-Ɩ{c9c9!j#8|XȈAa|@Y~v`qOm|.cMDVY¬1~4+@ H;H~S7Aj6jCk53EoʆՆm^NYOݑT7Bܡdub&PqAؼD7"6ȋpwu/=֡@!}AEp=*-`M7ei+ڌ otv H.T߬en8| >]ďOpU*{iݥ)KYڀr meebce6%gTS=;Ւ{Wb1&go`:8} oƣn8/fgɚ}zq$(T10?Xa,T#; 6ygN+Or7B'g41K$RP?~ho>NY ?¼ BD/D.rbEhaq仒JOvwGYu&[H)/ }Ol . g_(FX d@7`-`3밫Ւczٓ_"IdV8.eg z; tMU͕mڂXn-oPCNsdʍkw#k,7k3GԎ+wu&1HDp^M3G7?Y endstream endobj 1612 0 obj << /Length 3801 /Filter /FlateDecode >> stream xڵr6_jc!v&L2[3I6$,sD6S_芵^ '[鶥@p\9"=Yjw/vz**xCW%X0S.55Aw5*7<5WyePy(RۼoeVb3t&% ;jnVBиނxF[h6G/7%r4Q^.Ggtu9カc8Ɂf"jDAjcdPW#)|0Kr0 {>I c_>p,6}eع%9|f6l1Fp`|,/n5nI{zJř# P܉;pL ≫[]VM}otՌ@ԿoJmWץf:cp;n`68Ya':"+:=,-~̭@h 04ŶxLvz WzLe_3Vbnchٜ gܨMsS&STNfsq9<+:w]fxW -\r{47Ҡ@1<1jtۗ|S턒\5¦ȫ۾laetr_@/:,DsC&'}lT7_7S9ddCyi}uLC9#QUC=W'X/`Ni ̖Nt(Y&c84yz0!4l||ӛ4ER׀{$Vp`L7W.q8 S7^mv0+#]ݛNjP%i&/(HWwƃcH5߂'w4 @\4 GLlsu0#v(SyyŦp(huv3AS;ĸ$e X[][b\_IyO>D0À;h[Ȯv2qMף, P7/}IEO12s̏N\v=(.Sv<("ˋ2y|8 GS~}\D%M!56ÃX H<ܳ2̂3w-%9[N bi J%hֶMЊY( '~x7%qhb,ֻ=ڀ?H1T!Ƥ׀rT8*e8woh 2L%/n:_ʼn0wJ^z24Uљ2e_d#xDO{vby;0&,2݄|# 1 2evd/m$aW.i;]5l=Ԝ)qS!ưkC)]ˉa>d[̼2IG^Hu]=YYʥ;?eװ5YENZAf z_Tl,1ӥLzHC|… v pms 2 Ob|Æ+H /϶T+\TOp]4_ʟI&!yzlg! ׽U=E5w/Ʉ=zxL'"mI%H_ v,@isdXO8lʂdT[#!EB˜S|L{qtN?3?`.Es[W-z=>/<",n d MSM+^Sp=KO x1\e=_fo& 搷=v%)%zb;o2>`bˋ_n}$lc+/loZD,L-[z#|z ,*^a[tEj= NcXHB!{*9_=$ @O:H+?15?X}-DQ>_b#BD$zn겜j4hTPWRbGKE ?ﮆ endstream endobj 1650 0 obj << /Length 2633 /Filter /FlateDecode >> stream xڭZs6t Advjhjn춳t4 Ylx߇L˒e2Aཇ߻c﯎8|sʭE0F1r"Ì߯._`$c.".:j&ODiN"&*9^[jSS)*9uf/gHH|Ęfq-2QU?_k;\x+JN8&zY1R@?eg7#6չbpY&}(#=-էֺF|/w'=!N=fhw` QggC?ҔTxWGIu`XȳbHG~VZh߳6bTKˣ ۈ!=t~vH- 'Pl=ZƂIKfx.AZ(tlu1)hɏﷹ.?u~׆G܇mC_ 75Y5"QqR!#3H\sp%D$H1 9xjV`g"uE)*T٣4"keaA1{.XFq?a]ne~ j]CUXm&C{qr`DZW"=1oV+{\$xeŒ_vA]Ɵ9(#Gsl+A*DK_w&ՌP Ʒ.^= x&2DQ#}1!0b8C,Ɋ $n[ϼ^{3…quˇ]-;E߽J<|:X{&Mpq:pmbw7U .'SCN2m, Զ1Ӧa+@x%s&#(zk` v/PT !W m=WMt摐bS|C4v %&U+`2@@N9P%TܵOf+d:7RPԞfw}gY~ R3 746cUr{XoR=0VaB,TmIdnuhM58\LL:x0O%5J3*` aqZ@2_wA9gLL4xR6rt[ŽjyEbhRg Hu: MQ3d7M`ӝ+_hVt'+s- .zBX* 9*MRF)} ~6? CNrb^}|lfQ>)fq4J((ҞFL#L3`T0y@].B.d|Mui7m ,G*?juvR]> stream xXo4޿"Ӊ5_y!X˩-Juk.%'v^N6-Z<<Z:b~tvQ+]kP\yd]Jc;AfbF mϗM)HuvAKZ6IAlcدX):?ը?S$wFN"eo\qL {HHwc̒[aٺ"%L Rc$O3>/ 6|V#z~Dp [ &&;D]*zlm:ڦa䫅Z~W%RA@EU|(:Rf+5 1z%:#A:CPg4J7qҫɭvsC%_"CV %&TjVFfx EW .<`hnt %v @*Isg}&""ɢd_#g`gD>ҏ>ҋ>xI#G~d~y$.XTh>$p͆ݑ/ R4gx?yI\ 0]}Z}$T AJ+GR oNѰ#lyrcOz 5OD]6; Ra4i&C9)BؐR(,/H3As,_k.OVNZ0ױ ăIƮhC9_oba'ƈG!߂:CFob๵I|`Y!ad&J7m:+[\Jzl%[IڊSII߾fU.ޅ"'5_@"K|Qz^Onn^Enxڑ> stream xX[o6~ϯTK͒5E%0xXy؃`DdIn>Rs&u0Ć^]h*>vC_Pض }6kO{b_/՗BjSK W{6WǑ/%;q|' 1M"b!$ R6eRʸH/d,oog}m4X]êcraBCʷ" "]șCΒ˝T*qQ;ܶf1y&ÍVPE ee0,c:mBPLYXYQ&h7c MgUW_ldh5ArO-3zSkB]ep._v" bm`p󼤟t볃> +pɈ>gbpgվtEXbji1֌$c>Pũw}9b;+]!ZEԪnࣉ=խ[%bS_ ^>UA8ʰ6f~EU{}?5*ǪYC&L&A(8ޭ7HMMfUNUmbQAO!C x[uA0lnQԉbxξ VoLu^pZ~'0 ~slc/>:.2(%3~8b0A_7ĹlM| Y[e7jg۳]hrwqеShB2Ni[^UC{pbk౮˨;U~o%+e"&pJ4[NCZpoix~,\-`64W5x7b2Ϯ}%ަ?TZ*Hdžv&tH6;{VM"* #JI c{ՙWc$B- 1u +~/^ZFˡӑU< 9icgֳFw$UcSm I&D2AG@SL"bJyq<Ou|G\W> {zD(c׳> yDR>lXU(cIʹMSWaj endstream endobj 1673 0 obj << /Length 1780 /Filter /FlateDecode >> stream xڝXmo6_+5+RAW Kiٗ4ȒCINa}7Y4H{(ۚYyd,pE>¶׷FCIj]$ -h5/r4rf3oumMN lÙX;r|n`H =,yŒ8n{6}ZyŰde߿y}00A5-/vɸ3wv4+jjN7+%AOI3T21HCiy|W= %BYK6 8}U&4tBrrquڟz'`xx,Q iF5ڐd[iG)Hto&(\|zs'F8OII@S:Ժ#cɣ&E!pug Z"vc`7wC =0k_.km؇C(=J}ڕjDf{Xjf6rvbF f&άt`:HUU7\2=ً<[#$YKD!Bj.oO*E\YJ>lӆlqJ;,b/=Eo!S%u_%;LmĬ8-˘Wz!ue1 Y I 7~nitQg ^HHlܤiʦrhXG=T~roڊ:nO P(BۤX,ksnk2}]@:msz;= *َGx'&ӡVuCm`RfXBz/SNPG徊e.oQ|o% Y,':]M1Ll_дN$UCm{!z o8^,shذiZ]vC$  E5-񘯵9KoNM;I_ ηJ2i;wB,^R^PO'ն/#d,7$DNZrr1v]יu9n;6u|xC 8pc.ЁBPbc *(=Xۊ|I< x m^|NI%7} Wqpt\v?5,܀uJ˄xsqC_2tIIU^|_PCFZ ko0Q  z(vȱ_C.p^{8Fsuz&,Zp梆:OUk5swjDF%/V-j/^lYzĘ9!f9rp.V_;v"Bɂ?h0R>zg^$!^ 6^>M *C9$%< Kԓp=1>‘_ ZPk^RaiR|%EpߚW݋U|0%%4Eu:2~bi/EΎ/W9PHn endstream endobj 1601 0 obj << /Type /ObjStm /N 100 /First 989 /Length 2404 /Filter /FlateDecode >> stream xZ]o}  ^;a-ɱER$ eVY%yG]p8s\UFkIENY4mvIVqdi89B93d^_:ME$\:g1*%XeB`֋hQM>Cey1yI{Qё]!_ҊQJy(D++GFE FK,O-$R`+))6(TEE!  -sYGp0 bHqXcԗWeXr/e.*+0'> :T^9Br*pAB(C [؏dƢ \ysF2܃b(تaHyI%#$+OJJXiEFdUCwqQ))3EJB+ `TXl3Z܃[qs8iFtBK1`jTtd^X2}488X?S"VQމlȵa"T_&惼 τTIb=z& 7ג&RA(kRqO5'hv\ίfǣhMG[{sޖי@SDƄޢۉ:>Vͥj:z7R͙zv2ig}m73hW_OAQ jU1fD|0cmgkLCg7M4jpVV9G+#HR\\ z'X(%sy2B6HU dU "xFP@A֪W^^BRXɨsCP۳sռ}mwԜbl* 3'tU˽7n}=J\oMlu8o Ǽ_B 5X׆P6Rm,pLqH&kL8\FT_Y~ ٠e q*AwC1Y ,-!MH>xm^<2SV]&1GB k0aX5&Aqz Jf4أKǁb fAע83Mhxa1- BsNg[4#Bs Ym=(`va>h'4v`mm8Uoa*#Юޗq;oJ皟#"~0dWrԾͿ+L͟y9횤R^$W[ӭۆ3ak&rWDw WUU]ꢪ.***dJ*dJ*>IeAmGD?B:BJ Rd8 L(PwoA-Ͷ|8n;{݃N@]ƌș*26>nDͶ<Ax#úPn,Ɖ<{eǷB7f40s!kAǽVU{~4j'Q7EoQ'فͺDqa5'EAsґ\6]~ӿ4Ͱ7h@h~55t6ׯ v%< "L@JYPG;B%Hӿ=Mbr$A.U:&vVbJO?_Ss6y4|=t{ó)R,9g$[C(ܒ >ϟC{]L2֕A1IQvAT$tQ|Y˾mN3 1`Q7NNP|9N9 8A+2k@v! [E!fPMFEmf~\XXn  ;. ?! Q ʱL>ou`65E[A&XCd-a5!zgag8b<-ƣC%^ވHrWL>A-K\-u!35lc%)qR]㑔w85v8 A"ؗ([ޒ |ع[;yZZk%lrٹOB8`Jw 2F>fɇa3Ls~Žu<@6ncʼV6ypV-\€@>CM%8_ݒY[Mv3͹h&G;~9C T l-}Bzx,9Fa?Z>,D Uv #}v8дԻ$KOͮh؝qH)ҤB$M_u2=7R|h#Ga3;q~2pOM7埽 쉵 endstream endobj 1701 0 obj << /Length 1901 /Filter /FlateDecode >> stream xYo6~_y/QRC`(ࡓ(y9pOܝM:[ IC5M.L3P3)(I K]T봲uyԁEu/A՚iTu&$ܔ-!a0n,*̓E^X%qX h Wim? Dz`~翥i/jɾhP#]Z'SPc?mX{F`R;wnQuP%Alaz..MbЩHgaRØzZ5LFo@m!xQ:[g- 4N ?Lb>zf(Fsq\I-NXw}zn<4ñ/zSߙ%v%|MQt%AjAWUO2 AChmbɁYiggH2Ll;(x~W?M. CfxB"46>;/>_8mL{[A/t [Ms}ek:;SGcʏ;L`!.K;P1d8;<&,uJ̺i}͓ݭ]BۏM1ʳ=(9˺hܔxO&Ay@Dʃ)O/ȩdOqyg|{d0X餭njGI k?Gt;PF_nHBI%']``ɀА?᣾!o%3l=+Uo+l1YSCw_]htgBµ:@?}o{as8;/bL^ endstream endobj 1745 0 obj << /Length 1409 /Filter /FlateDecode >> stream xX[oF~@هɞ ÀԭJMn_@0qh  %MT8Μu;+;~^ޟ QSY\9c<>FQgt\ϷY9ɒZ.ӯO}dj~*/oN, fqnT杽-l'0W0D,"Vs (_YnL EUIߴhXPC7ϵ}F"ZE=qSStX\IV$99&(܈H" ϕW湑E+W"+Q:>}RC:^* Su~NS|ugF^]$pUv(?Xuܣ,N1tĵ8~7BhE'#.)AF8}mlB)#\ Bet8B>; ·C0oq1*`x irLX"O&a]=pq3+k{f/@cueȜK/:jݥYWQe:eXJs:;PwЍ,9{dHtOO| Ac9׆j:ah$Jݘ6ZO Adi(lgN<nk;pȰG2\/Dمf3" s &™g/_ Nf0L)akg>`'nkL0aynqpbli!:I( иsm!`TYnhuFES0LUFw- C%&s5Z !nWsj5'=͉i5G`R^U9-HamRȻ^>ET4Ai-()ʀʢ(7f$\(P ͨzHi ȟ`y48$5LdZIO?$԰iΣL}IP)lQi2ePR%V@6؍i`M\/'MJǢSU`NY۞v3Y~ #j`˻$M(IP ^n4t0.cx{`X`#?R> stream xX[o6~ϯ0҇ـŐPTv˶dд@ecӶPYDIwx-ڲko{"%%}Px0O?^\Q:PFC:x ( %Q8x~xWwiYjerIU<2XfQMp1Ww1 4E Qzg hFAn>܎!N>10 eIbze>f4ژD7ZXQ⌶V}ex(c]7u#(M1qAcF5:w ^J0XKAL~$oQ}~?{;=۱oH]= L: )7|emwaAUR w Lиlr$P;-ΛY]-pؠVg}HBB! 1栅3D@9"Zl}Q /âZ\Jm5f&C^4*rRj~F$Sw6I:bs4 (NM ZB({`:ge8=u rya͹"m+ԹBժ(Pb[,>'|)P& %L@=lF$X, Q⛽]k 4븿';҅GrBpkJXMb8%tYPsOQp yA {uKSKTB ]k4Vbi4\&VyD3f(Nns@;p+K_Z=Mz!ϠM/m00lqr$Ђmci/'zJYIˮ@2Vʪ1-O*9?妐Ձ4ż QW(rruBhs=CއCu;}᪣;~iL#|on<f||cUBC-{5ZޒȾqgE+!?󣽥fx1A9 yP设[] L1QZ̛ӮGo>U)&DOúKؚ7 ̈́=6$g3㝛}'q 7v \@#['A_LA-ŵaub);kwwPoRz?iӂjU%eJ@ 7ͧZyk?NU3 z*+OQW}~JP_ v[zl8)=0f"M BZ͚jb:p5E*/Keh7˺_NIaݬ;Sυ]؍-1uO CirBWNz@m ~oFmԯ6Ɓtc_Nj)ȥFhZ/u)/ ;H^fNj; endstream endobj 1692 0 obj << /Type /ObjStm /N 100 /First 982 /Length 1604 /Filter /FlateDecode >> stream xYMoG W19tv>(N"ݢ*[kH2>RZJI$,s%ry8|pR H^-#%>@1Nzf]bOjL yDJB zQ $R0r PQQJ>ʆHD UC 1 ;$+p6)x${ aܬ a(xUH,XLR,2|$?X!B> |QI, |">7EsF,+H&/r)$ B*&U b?z`H;85/)6o?j"V\M/.=6$uv279Djvpl0=aS2rQUzGssj/Ls2z?77Q|׼@D|&B5ѬG.~Y y[L1TådbE. YBzs}y3't6e0`/SAw+TP#;;l Ս2*b۶8 k۰|EX((V: X YisTF=YTZ2NXT(-]$"Wݟ˹ԚÃuv7_ߓy?b|Nϛ URغ)jCI\S%iS8UC&T+:rVzh$`aw~k]dvEE?"B(b_M_?|+}E?4/#׎q)TNIhz3=qP Bs \ҎpA,{lW $/[% jtk =b ݺM5Be^Hdqz Ƥt=0ay#\lEelpDoNa{q|}}ODl@&חxx;-D_o+NlߥM cBq7A6Hk{k{ШZ—ohou4_,כE;R&tML隘51kbj h42ؒ\ChgN‹Kfu׭8YF֕q{b)J`?"s'`CIE:|7`I_#px|N($> stream xڥXs6~_^H H{w36\ArL⒴`M&A]}Kwa:^po(܋8F, vw#T=.\k{(&(aS=ekJr.8ԓA%o c]]JeeQK %,kUuQ?1qWo_a8\(ύ´om72JQ ?W5j*i?dN.7 CwyjŘUp#EzG<"~ӝzٴY2:(lhryB h#8KW&`n=`/n'u9zG8P΂vlbHy҉iVldd~PU^;햶ƞ2):LZέZ|%ǵ' T:JW3P'm^qMZ$FM:{]r~q,BSgh{G9d9{FC b@Xu}uw 5@οՐ}K:RTJYWS< Bymor&X]p=j.{!ٞ1?(C4y*E8`j 0-;PLkT,z`kh[i UP1@QUA(܉F̠ K9~J@r> stream xڥYmo6_a-N.bV|)npEŵ}fl~}g8ԛ-{@3g2l= g櫷Zhg3L*=3:d@o}֨9u̲,VnP&?<| g_Y(&u2[no~-`L%ʼnngsf~>zS_~N +3 @S.o#1q:=IPE@{eϻ~_i(SrC?S m'(֭xB uc/ p 9~gJ!Z$v3jǠ8Tfb FYX c'ҰUȓp" YKNvǏ}~ =EAC5۬OFhq#Z3ɄCTg9haOJm-ןg狏6/qNɊ~UCiUtl䔇(p\+&0Uo}UVjvu=.,.wlɁmH-m PEZ,`bVV @âP3IBIQ;1 *Ծn\DҚyKh4ɖ !` jXz sPNf8iM%wOKAbjCGyxJ-2&|镝ȾPa4V,rOMNy?RF+(!^YXߕJ}o,9MnS7X^z@et<6ijv۞dV ~/כXBwum,?U:_}!ӏO'|V .ݫVw\,R]%'KRBʐ"vSm?!CLI<$;C IѳSI u8oaዔNBquxo&hUSgӿKNׇ "90|B(AH$- i;~IdJ'Mn 6*#w zm;̾E`$}rtPy ,B'ҽa ]hmta]6w3e(s*UwXO]¥MDP5ڐp ') afʲ:)yOe %w5߼ž Aq 8`:cewX Ŵ {i Y7׶a5 qyN(ag{{;u,<,16ʃ^d4-ϳ.z+ 4@/Yk5CSߞa\![uscO2%`߿]K1/G9.BàjiC):DWNN4]^|`:?x˼JwsAeX'2ɎkhBcϕpԈ,Vq<>\&"/PN)ÁL ƁdCդG\s7g endstream endobj 1852 0 obj << /Length 1794 /Filter /FlateDecode >> stream xڭX[o6~ϯ0z!bD-!YEC[ Ztq%M򐒥07`/!ŐΕv';4' IBNWI$d|UM;8;: ýKI{rˁxtӽ3{"Gw[$13k1s<7&+xbh@"9 ;̴ʷEy̛6)h+˪.?T.c%3ǏUوo[Q, h$1a;|ⱎXy#qtZ,00؇~ ġ$A? ٛ‚?b9"Hw RZw,!g {Yx9g4ġ1Nt7. \(y݌S`   \ HL=]mYe#:7J!X 0Rv[F|L4"YYZ 6fJPm%n+.EmsĝnwSе: x_ka!BZًzI}qA؉DdvRu iV{6p=! {W$ϨSdq6W Mj )2o gP7l1^RSx X:,qBܰ3_-W8,5|uCJ[p`:J&ICt@uN{'4iH#:*U-Dt1!@.c/yu2mJex6pDjiH(84^(fl[>ig]$Gc ݘD}}I:Җd?P(K]q,6(t:J:[eA8? =Y ="~?sϔ>F3 yz=mOc&[S:`~fBl[;EP}G$ƃd "ԋAt!tMe!$w8d| Qȅ  ex%n4Ƭ.ss ' 1B-y˥^܀םnxz 8 d)7(#~Uj) ~ۦrs*{.~h|~ Ϋ][!|8?̀PW;-c:j@#Mٮ!R1v#/Vj]b9߶< ϯ5' 8U1xH^- "۰2u:tcAvBӛr͹73v6:a@z,?q/iPI_qUU-B7`Y]F5Űn(w׬} M}/pVTO}Mpka֨^[Y fk7B, dq<|M endstream endobj 1867 0 obj << /Length 1935 /Filter /FlateDecode >> stream xYo6~_!(5KR"%(Э](yK L[+Vf1k^uԻoEλNo:VgG1ҀZxLXEut+6b,1ߝhl D›&$9L$Ki/$ FA1~h.p|>YT(q|լzQ4զ=PuZi@gB7 KM[sgOS1C/f/ELdbuV]іljC9)Ic}v>wR Ǟc/Ǹ$DrX[4 K3&aj̋Oe_k|Zk UrKf^@]ܴxk"$۴FG@Lߗum۱13JyX7Yn8YZEQqT5(愲x81@8 ^G-xrP+'ҀRRy$/EMͲod` %.)N*%|Lus?YDLRe2"R4/ #x,q+kU_W8U\z1RkU]DGv>KEtdۗ (.M`f1 0Qyqe;$="0bS{nIy6 3H!sorz W qLs_"cdI&t,.8$fe0J@I0&薭#JH N!60س!p~OUY_Wߚ&YjRfK¾|uٗ&Ã>v͚a9yhb!A0syN"P^CfeV:8A:`Ĕ&Pb}d B0>agq{a>ń7ٜ( |*s^}BhFTch  &)fJl3ɣDSx۲Dʋ s/7;qp&R;r/ / M7A:9nN#kĄ -No4Ʀ]us %xy,5K 1ӀErwESyYw3좌9&EWMg`qUdF۹0<9ND,i",W@LN0y R.onq"I,F sپ\,alM벚@,ǀI'UyIxxTe14ޡvպVP[zV:x,nO+9$j.1ۃ,@U^ի .Bvp .Ax$4ݭ8|":Sǻyηz-w=<Òy0_|e$2 YD)՝pWH'?>Z/ڦ봥*QrwYN SO,l ׿qB+v0 5OjiB&R_! (VAHpN*5|O8ܺ5\˵:92]yYu)یfir_!:HŮ4lyMȴZL2W 4 g돭mLp]p"\ }@A$|!tyc!Y IV> stream xXKs6WhCM2mwҙ%Ɂa5EG}/)ēO~=Y')J% 1.'H0:'Z sh{Zt@9߬0'M w $h-ǝx[jE SoB\vY>b3h"2z2R"52axg6tpCq85uqx^40?Qv Rlg2]H/'v\y:+?eF'|~HKc4։Ђz3q[g˫8yqcrfX9lXCfud*7x*d7 bN5I.fA+lL n 2I^+]`EJ|)Xռox9uAo6)ci.{+>&_5h_M͜ [J;CtܸjgIC endstream endobj 1805 0 obj << /Type /ObjStm /N 100 /First 977 /Length 2146 /Filter /FlateDecode >> stream xZKoW14@X`mCI1,#ȮKCR| 4>$\3SU1肋`G!N"Q&5\BpI@FFȓXbq PڎVm*OE05,QJGq&(l 4:MFQشdkd5Jl&0m6" TXPM(1;m]S5LXS{'S!a \SNJ(x!Pm DHL>(enl#jYdlL% Yj442H{ b'|e &Z/\L]klB1I.<X%Q\-,PxļdY"_-b#26RPPM|ܜ(gP sPQ(Q#Af (l`9-+2gQcTr9ɀErnf)|k/!:Q<(=lN4ònx+ R͎k0_PXE>9==}&/M{|ddV>yױ=L^v{E|@Kɂj^jMOWK7y_\wN^w'=wLjS,W)cr?QE|Pz=%yRՃqwKˋϮ=a\t#Bӳ3{?/nd!4$aJy (pri;tbag>@{E}A@M^FqUamw2y bĘ9˛լ[oKJ{O,?Zʀ/}1]aɲ9[5ZuG'''''[fE-V`XG!>nV\%WsFHYp] QRt5_oF ʞM ,G[6g<6b+ҚF [M-3̗G23o(Hc ^݌B^T}2tpDX| o#*.W#/ȁ~F}OD~ۘz"h!#Q}29+NPzjrpz0jpHG$#1 ?W륹x- f O֢ ʟ&ݨd)NZ|R*3c$Cj6i .F \-fX- ƃ-9Fξg << w[Vȭp!*C>nø)> stream xڽXmo6_!(f1w:`Ka0RlmIr(z0h|x/f߯gH)$##ƥK:>,\f2 p9Q ΓQXD(01$XI+)n:.6yr_&K袶Z ;Sc -|D:ePnQ[)Z& λC *2/]XQT,̧xIⱌ ?HYoO)E@6A]8-#1Z=8F;];ѷu (]s~9um֦O:!64W ~ olQ66Poh&0ܑHT1C 0b=w߫{hR48]Sڇb%ELq-wCjS,85@tRvQ|d[g6fpc{ͱR(Eȶ)\1_۠tߑT S`H=6<ܔq~,5,ѐmySS Uu3س>kaLuR TN,)Wj'(Fnˤ\]꺼e KĀ;e~=h~w#Zd}\ u8v:psʟFѢmNEBM?1_Ԧ遣> -S7Uoz3}'PG aDG>CK09T4hh\UZGmM׋:{=\ջ0xЁ=97(ɬ>g;Bp|Lݴ=96`~1fޔ6 cXz}rtmSOaĪIy0Go_zٔhܛ&g$LcEs9MX}yz2~+ҡQsM<6Z9 #hXPudMx i~ag*=N2ެ:Waaڻy}>^nn}_K>i s8ָ8q`Вש{M Un¢7ȪN@ѣc+ׄ endstream endobj 2004 0 obj << /Length 2290 /Filter /FlateDecode >> stream xYێ} &/;I;5gl?p$JD"$5W FȾT:uEm@o~{&ABup DHD%xp~\ W?փN20i-#lrEoo$ bh% E,q#oOT5O KSy!aQoy5>u<zοKakİ nGOtۓaOQ3 @i:du$ *X~kx +#"GtHxJuPN}}`'ZiPv}Dzԛ$f#~ː+x^oZ_&/zfR8,,H+OEXbcI%)mmVd.6e->'!D5*bl!44##N`ȭYw/+X 9U66irbWyHeE{ne1oH^nz d22B0ml>5QQtmPٖYr'ALM & \oN heiBRg46dE(RUcc(ZfrodJb{ojJd:yKF=u25ꄰ!Pks,.sgY;fUz~)a!g`Y{lrkXrEMj Tߪ4 3a9&3wb!s֌Y To}%5ŀ.TYݹo_E1>fJq>??ii=jԂC) %My vveS{U 3$GԴ ,HTwVSN^gro95Ggƻ {Z30kיv4(PjivaΥ</@X/Kj WFvQ52 ʈ0ڙP#(F6CCORF&Ulhu.Cdf`)/zHWڪRj(DHK%tq+RNI]_MUVs_ŗ![Hپpdab7`|˄̓t?˪<6yyMz (Tz(IƑZfm[Vex(ۇщD}R RA-IA!c ENEoL#wOMVc.%累v_"nwcWy^hUU1s6!/*@ nb{[Dcg[`&OgNf]< H`{:a$>f^=v(,ÃDc9\1ݩյÄr"5>To.xrlz  }Y1LRCy>c--[l.PaBޫ O'VϣZ)LW]9qњ/BAhƋ6@Eǃm:s5U/q}\j*jM\m|[ͱ^a/hvק"F!UgPCV̈Fvw2%p8|1\yrN~{,v$ZѣgKUm}FRKNuɪS1愺]NeZ-mYٴ" AnQanw@ $&اw%2K\3AMP^r{OZcdI0$(ca1(hYK[ NυA $ БhkK(Ly0FT]=\Dz`3 3 je=#}A6{'OϸAE T?z$>8B^ #^ oOogQ>D"H]toy];I^2Zf /J(?"^=WD endstream endobj 1928 0 obj << /Type /ObjStm /N 100 /First 969 /Length 1620 /Filter /FlateDecode >> stream xYQo7 ~"(J@Pmm@ il %6Xbe˹KjļO'HBtQ R*ۯ:+Ʉ8c5,l`b)Di!'i`uRg.Wsp 60GWz G}lXJ]*>$P؇F)j9l_#;&#ڔ8iÉ 0kEWH jE,VLBbKV 8BH0I\ 5.5K'tSuQ1(e4 .С\4 tftڬRhIEfLfl:2fف|kA7EK)Y 0b-:$Z )ә25O:Z Z@G:JfNHQM(\tBHQDMNJaW пcc.ei Y,$9mjԿX p @JJpUv#FcwXЧnϿ炷. ^ӻѳgQbDzj[9'q۵TMȍO+6*6F=mtnčϺ[:CwhjraMi/E3wɋٽ;7NVo@IKxtNhA^b8id ~2a4~{=>ͯyF?aڃ6C6s%$P&M[7nv6soNדޟ^Md&c'/8W2vDG8]T/H!Vvxn$0/}RKZᡈ!gFda2;M'7;&*B"ltr$)}MVLx714a.}ܶQ6?|84չ+A \nWc)D˾HI|@lOX<|k"孾 bXru*ۏ,|ChmԾtNB5TsX)-:o& Zz@}@ш-'I*ۡ#Xi[tOD[Ͷhx]Qqay]V$OV[揭+9}ICH*Pa߾P :'PC}:'G uUCU+c΂鳔X+eCfw2\O׳Bio'Ҽ}Mo"CxTB Z~S.@6z2'@?W# eUJ[9 ?Xk Pi'K6p{.u%A@ՄL6{_Zu3oFNʒ#~-JɎrd VR\aXm|?i}ф.3X52(弁v=!P@E+ 7&ig>Sjѭ'ةn[Oy ^U1aYHAܖ  endstream endobj 2023 0 obj << /Length 1522 /Filter /FlateDecode >> stream xڭWY6~_!8H+6MRw&,u.ZZBdIѱiE[v6 Ù7 к짫م[|[Wk A׷Ub-m7__]nO#2 k:_L5?M)NBik@jSS]헀}~7|ڿB6l^\#Kj a_7.YhkJѸؖ';à;F ٯ S 6^TN"{cٷcٴBك DeE:2fOKb4#d:(AJ9=hgu)g @(U>˺$Sr1KQ뢒ʣrzp!qST2:&o ?g|s^*!K*<0x#-:y Dawޗ$O:L2aIS<#G]d{-#0 ,vvIB("o;A(^F 4d)R `E<¨/Y`zSuCsSPoTE U^T[>P:OMO{|8/=BQns:˟+!rD*YVEInHC9:t]mA\[8f\=,K놋n(F?3 T5E>X1c5,TħTthM;5r٬{!BG)T\*E^dfrC?C!]  s־󶅏+ZJw$8Eި+bCqIcEV(UbBm s4Ʈ(u^.,94&HکΣ%3?xWm"FqpA(8ԃ1p15A^x?ќaxCcf+{ҹR_.$}#X:.uĉP>R~:Ci\"TF&@H X,tc˚p 3K6Yؿg直,(=\bQ.Un4FѩezKZVVrzl(UAP& i'(t(K4/›|W ےFIDsZҪ%D-fY=0(i a0%;[[feǡ$%7BoݛE\JH3L;_¶8ۛ/MULݱ&nDW< <6n8UX9&GrAY>i!XYCKPd$*k%׷?J|vnXGЦu咮; QPV-퇹v=WЋ4( endstream endobj 2048 0 obj << /Length 1738 /Filter /FlateDecode >> stream xڵXKo6W>iӈKU IN/Nc+i㸿CkIa9a'_xq/F»ƈqEQb]kU6} ͓Y}xI8c{^_sB=2\A#aSn sy۽;FF",PLȁw&bI܋ZEv䫀?躧OPumr^bTU#b"BN"\0a3^&mU&V% Dqhp7-ۍ2z*t$sk C|?1S ZLrmkIfm"~U˶2vE@fw]iI\s0836I1 n_N7hwWEʢFZ25Q0ƊV),묥;Z鮮UwfVvSTIrN/']Ϗ3/m^5_Dnj)E哄AX'@"d F{La,KioT*oZ7Ӂb`(s/A=eRXLiP4MB9Hiah388+BZ94BX{Uy 𰰏n@s{ __RD؊ͦj$N=.Ŝٳs (=NxL/mIbPyF"%jXObD7u%ʤP͢@@f8Cfɧ{@ՏD ,t<Mutq_xWgfF D{_.ٛpsO9QQa#\łD1ruDšS(̦Zq`3&zR_T8C5J#t31w᪃F[-PPv1Cd"gG[$YDq#t1LPD233̛K̢~RlssRIPYNS˄5.m4@-iYUl|8Z;#r  :jAY0BAPEKDSRJ*Z2Ĉ!sJ^dg<x]$s4nGU:DNsPi.YkSm9g5dXkBjNga#LmjȐF ] kϴO>1*)2WՕYuRS:,6rcڎ6U݋bV+?J*i@'_W6ZA.P QerZ?QOL)kZǤs5p -.}#P jA1m(r?} I:QC)ȇ±CU1+.Hg`T's`'՝[vCfBGC}סcwRw0q2BT`U(7UfZ0+,Y) Lzٯ S'f:=tɐhe,eE'a 5frcK = ig}cN "[<fZ\|>s@,J XVQ0})~P՟1i}3Ïz@"`cx#"\p endstream endobj 2095 0 obj << /Length 1806 /Filter /FlateDecode >> stream xYIoFW:ɀ9KRg&Ek@#)l'oh9@€9o;;;oVܬ<'DG=f{ Fyͯ^|0q !`=&ɷQSnEu&n;ե4 \ge36}>{PqI(FVmE|>jxh#,¥oʭyvjMB.xmnZ3ڑY$M( J&3 2kSE+JgvE.c"0-dbQYY@4k2݌*+YZ紑yVe>>euʚ$PoL+|QU[؍4iN49Id4bƒFf[|*ypN6N+h.4ЫʺV|F"EүeM[  u-|\Ide`fZ"jT<k+lS&+ccv4-IJJ S?S›JzE=,;ǰS2 VeQ/Np'˅)X7?iTWb_K[zKZ+E0Оҫ$nV_VDtU)S߉I#,x {=4w8 #9׫?NKaA5%^bcgsEi%oAaz ԧ&PA2>7[Vx DZ2mQ|ut`q +[i;*:LOV̛%PGWrjNe|̑כȱIeՊ[PeDZը\ ꃁ?E!G(]te^iKK>h5Nj';@{2>?"T &xuǩd r,4-%8wTl`*BM }Uj0Q\k\fpҥJxD]~1}sA,[19}NFdsͲH1I hsjVRPG=գz*1TSNR}OO&(n=(R-]ĩ`rK_f @B*@̀!˾T'e"e=OGuv֓L;ñ#WC*xF"џˇrvbDN!c+n#Y#Be?(1'}UZ4{/?MW- endstream endobj 2015 0 obj << /Type /ObjStm /N 100 /First 980 /Length 2030 /Filter /FlateDecode >> stream xZo7~_Kg(](ȃcm#֐^o(V$r>5]pBqu5\LŒlA Y r,msp+1j!ۥ.F3N mU\di\N'doP5ոV[+l;13V LvRm2&0*p&v))ֶC]JlXpxⒶKz)XGǁ-bjHq'it!KŭX;&r18Δ9 B\v5:UZqblRjۑv T'D 5IitRۡ 2VvۂDiRCEebv](Wr6dT6d-4FSs۪&x S@&ƬNc09cmGجR3I2Wڅ`Y-E\n)(eֶ, לA YN M5 (ĦZ]l`$t/BP%p=L}6T\(BErہ̰[նls;w'Lp3_dJ͎foBM!s)]N9z)y^v&50[cםBʹmfi})W%db~@8a<1 >,k ,C58pݏߝUqMraA=p;oq~r}];w9!\ˊl6ЋU7X-!q%qQEw|;vOy^wNڮq@g>C9曣R4gv?\>t/zuOgۿ/7tݬ_Na^\^}&iM[k<1fs GKPfP9y'@THH,7arf%A d]En7of:,$ߵu}0 ' a[N!Sq mtlaP,N;FʴokX[a-O;fFw[QuIbig>3PE+I̐0%tij}W' HjUM3Oeo*z@6ލn쟢f=F= BԄ2Ia@#3 endstream endobj 2123 0 obj << /Length 1568 /Filter /FlateDecode >> stream xYY6~_! 1C}HӦh 쾥yP$-TKɻI~}NefoovVv{s*;`'_`unc>]N-4,ŗ 1Xa| sb\F 價f]ruuCYd ۵Z,)n.{5`K^ّB+?$mOFGbG[T]C5AQ%9.cRQ&OqJr^nB5odL3]ۨ*ϧ+!:x/y9Uk7"]t$ʒ>b5BvΘy}]q:1S ВQjA{ U:LGɌ/{5 EoS ڣEV^6 }DhLPM[P ITJ<(7z'#ϻ,+UTz'-bDaz4-(ABsi >.*?ZeZѺH'"'d`h}ґ¾ct?AҖqZy9e V}:,HJvFlRJAlig-EbJ jxsv;1dJeJ) }VJBIEt^wt[U[`Cv0y`#k<:{}BQ):aT)=p˹<+N Ma` K/BIlH"l:͜ }h3Ǵ/߁n`9(qTDv_Yl܈k%UR mx2K8RM Ze:ik mSua18Q |cTn/RM: i&jMQf I/T5ߦeqy;sf0X8}$1#de+}Zě1PNQ;F8o%yl\~+rW]Z>P!eW`'@ H硞99L{/ c"&pRG4 P thMV]m`~*NT^h5u"CͲH|ˈdMUdSז Ȱcζim&nRnh'ŝ}Rѥ֔&5iInڂk^e;'h^d[uQy\kat2R<Rj*6aS^E@i\e' w'7*5&XUFS*ګHt"vl75 <ֿ1D?Ǣ}#3 a`ĄDL>]wf5 V_UURsn6Q/cVCe RX_v;-} Aє endstream endobj 2143 0 obj << /Length 1934 /Filter /FlateDecode >> stream xYIoFW>I9l\ЦMAD44(R!)/}3oT&8"gy9\xD>͍C=p;əI+7o^`&}̜ty7U&y\zg3`.uY_]ߩ.ZpUWspփ#FF$͓6TܨԾ|jg]PL)B"ԀB=I2ݾCd.p5!>P`>#N"N<lw3G TCC¢X]1D _HˬhVU3Ј3q_UmnSU%5awEY,Rک6 xܪZ׸RHK%y )c{ԂfPL0Rgeq4SOGvam)1)r `8,Zh! vl}<_0~Z#H{S"_3R̤^9Ytݥ$"c:v}oxIPmB-_;zrT7Ίm/^HT8|:.W/1|s(T8g\pil&kg|zWBvq:}’Y͊63C 4L\}js< I;jXnYerL?(>g:A2Lu! &~ _7@,5d_ ]P*DIQ$='o{0Sw|1iϝ/F)SIK=DJ3Y J{ZC-PdU>W͸ě<Ax֖360KtTC9е}V:~9}M I!J(ËDWûKSV0*}Yٵ!|)"SZц)(o/踁4;aSBtiD43ۋ9n]u(OuOTqe͢)'T)Zo< 9 D4!Ht/~?ٜFb^ e,z食F=Xj@TӾ9=c57x>K)Y|b#8S~F^ ˡL"7 xY=RطR|w8,'z:GH! D*Av^|ZyǬC݂$K[Mdp+8r1/xy1cCBk "v;͸ۙsU.*x4 4fɥ 4p,X9.ƅC>c^=@]/K8- D :Q۶n^ۢc!tڷ2("cd}}dJ6]>Zx6-n_[p?¼Zkv>Cq#J0@Tq$0oeMOH위IFXᦷ̮0fq;kYlCH@bu,R<)> stream xڵXIsW܇z( &$IU'%v$BCPmw~<,$NMʀ@[o>qlrc?vr8P:Nj_p]pd|߉vB)5잲psnU+hKQ9Q3!`; Q;@}ejiӸ 2FGٝ63!aNQӴ\4ZtLS3f@vޕ ((SE،:P6*`,1G3k[ Ψڟ AHKB)O\o\Z*KG| u/rAy !K\۹VvEEm|=+74^[^cD4LO QA$H5ٸ%(-ۊ`PXBp܊}+%̺$^@d v>7ʤy½B26dDmGy(J;Ą^:hCpjRv f^P]6˾ɽ GLQz@s_=.k!~*=UNX{)R=g6ϗVrD4u}_QliHqMG1{ѳ8,yX@ȼ9I< 0w:?qץytH"ܴήk7 ;z7K+zdwcG樓rM&[p7ʬ:2̕ Yz'\ݐė1Zl_>}g(}#;v(V|-Gn#C%ˑ/59eS|9K Ϩf#iiV߼GVEf_PC;EKe}Ձcmm#ajԞ[h[;79LOJӽl*s9K\y-pdH? yC;lPWj0X_ >҂wT(+Zh#p"7ɗᑌ55o ij]Ct8مъz[]FȩOWǢ4؍wp9U{k0geS6pxhdhgD/`)h󜼄 Wk`ՑyHyWة:&}*Q9C gM ;Eµ >.~ ᑓb]YP.nnqPG4by< ,ſOB7EV/h͞kEھ;z{B 8Q1,/{yeR^0P%'q綜G 2fA+Uv;?Ҁ zl|^ Zy$DO8v^7֝}Brgg_;uM5IcC3TYs˜ GގP5\#W6A&A]MgpS_$ ᆵfQA endstream endobj 2196 0 obj << /Length 2526 /Filter /FlateDecode >> stream xZQ۶~ܓ4` A2?iCzN<$-E*$K;1Lc"@`ۅao^PjT _ `2TX,bu_}YG_HGL yg *ahŖ>ي?7A{_=_P&,/ 6(֏>~#uQ7^燷( ۹YsF%>hPE󩨼7M󐝴v}2oNA?~O=5wU8y9Բ圥QDB"X}V`EB :I(lPNmD$i+Q]ؗ`iS2JzÃ|eh WWYݏQ[f1xd/y$ $Β} jKx߈Ψ{6҉ږ eb~^%YpMJ8:& T޵3omYqF?{Ffay Q J;m{kŞvw1Jr]n~ڀ83< 2nh@s4  =vv.Z<=@ڃ74P /s2tk;W,Rm %ؽ/qƠm:+֔A*?Um ;3qJ)Ko3 My31qD:c}dOBrĠAp5?,Ym|P,J;.4H>?%{UO &;NAN a OURS4ƫrwS:۵N)J O<Āk`@zN鳜Ё)zo\eJBa"E>kb]?K<Z~wK# !Czk F}g烨bCVFKUoh%BlF[|,I,iq̨9ªoe׷0iG4@Wc:ρUىh-\Ei# Fq0*Q%RǛ9SL+9]~d5eqC+rNbhW7) fFBNw6 Gp̊@qYy8Y`:w)eJYDV;40w^5FxCQ]|dSD=TX49ih82&X[5{u:$ c׈N5j|l̍S)YfQzϢX=4%bh*}SYa@ Bo Y᜻ Wʺ%6gܒKLfp uaS|o}Si>Hɉ:jRΖwYb>JéαMǼTl{Z` *`r>dK/.|<9EDQ/+q5,O.2ޔ|f`5FG &+ԤK.a-Id4~ 'k7-ߚ7_ "-ZQW >b܄Nj~ۣ$/aQ_y_o_ۘ " ҠV2?0~=1J ]gVƗ 8W{G<,*etx9~3%'z7P쇸eZS1N]"x蔳$ 섏+6u҅M*L^x,H%8d\$nFhX > stream xڕXr6}WpJ xsL8yJ)MkT@](i&(dXF&@}% Nr[EƟlĜى0 K~!}AxkX@LQ İIY^fxSƈu# t]2'.GS"^ΐSSmZڟSN(ϞiAVsu;.ܯ*y12eaj mt Qt!#! [G@4h "P{+o1 Obf4F;g敒W{ d3S7N5 = (N= Xף]E3*+Dr랮etO[G*JQF\wyqdfǫH|Rv:(G1PU~[~&jU?wp Sg,rA4횊K&ž>(mh;irukZ!^h> g$1bA.cjIv~T 4FX|Da@PB),yf[d!mNtFISΝ(b08 'zuYjF /;D947#!|x"B{7-'{Pp/ZCvh} {EG5Ӄ.2vآ V}> stream xZn[}W}H I  A`xF4Ǩ,wwb^pװU[0Ժbj `h`Oqn|qwS0j8´bnsM j6gqzx U|”/曮0HK/%3N.p څ܅҅Rhf3DT^ 6B̭úz0,+qaLjƽrf1AَkMA}B>5kܓFB%?1W}\B ۲N 'P yu@'P Td%3<5sjL00_nF_WYڶ++/0opԚ~a3ONd_16;5,˶s|/',F[BĬ6 6,0/jLvpkc'öⴿ^#/] qJ̧!A,no^o)M%kyPԎk- ?ǶFE}=IkRDNȧiPy<t!FHiݵwNPEC+J~>2!'eH; jK˥8M,IUJS>ّP;',F}H1ʻr-w'9)d9@v8TWdct?Gv7"Pnl64o0``Dv8fG=)\: ט!h'D %e`~Cg9 ɪcPgaB Z.:|!/HS}CJ 0)6{:ƫ!R&eLkUNǵ)l`;IZG$yؼ#;4KP Y^qꊎI'"Ĺnd7w[:-NvK'it#>r4.Q S;AlI8[^]Ϧ#~f\@׃@f匿l313ls:Wc~LlwPS]VmzHVWLo1KDlTFRD@՘.nӓ~AzeRɾaW k_֟nn2,Ti;괤 Dl8E؜=' nZ O 'FIE:7 <| tx;(,  Uxk9Dd!Hd'( %Srz쾼$&رvJ vM[?Ut}vz {zVyCAvnŇY ij endstream endobj 2252 0 obj << /Length 2221 /Filter /FlateDecode >> stream xY[6~ϯN_b̐%Q-@@2ؗM4=VW\]2=.M)b!E;4]ݭy0\$yٮ* ) |Vp?_ɗ>HI'wUoΏH'v)X'h`y]&=j$ ySZox{Im;vMk^6U[Ӷ;uߕIUm&tg2R^<dGWתluxEP'G>ҀU brK78Y EZo/jLզVUecMvg9h<#Oo0/-IcAZ*Lz:$K`3e=Pu7˿6͕VxuZؿuxÊ? bȨGE &/fۯB,<ጥwT! kf,et + K%#Bg32z𕄴| ! 6j% sߗ!oU}~[2Iq`KIxָdM&brnV~@$gY<ڃS&>IG5 =p ]+]>,;jxkŀ: x[YιM5)lʴͫry`P3=1 Lev ecN| yb)?w3FT-ؽ`LJZ'fGcsSftl>(:lmyOapȢio\xM@ĠjSP^Ѡc lITs ;TgyeӡNw2@~|C.&)2'K(<;AyDž⯯2(&4A” yt)}jNN3BٌU`Ƽ1 _`hKШE$JnH ^.YpWf$1Va7Y*Ml퇦j16 2;Kwj5PVs_Z5]63$?A SӤ溿lH.;Kw;EQiWIKfp'u:̀p̒hM/4#aDE5|tBAD !á h\ۧL5ysyYKZӻߩrk<;9xTeլWQ FWuP/'cN|%O9AԽ5;ߛ[ɀ;P\b8 P)!Cƿ6TF=Ze['ACZ^ԍ}?:%T jN;]y?$I|c:_RzÜ`Xc 汻T=pt:<; a'åd(GoW, |#`N+^,܈=CboXD;th?!nL1pÀ|Nc{0bw~7E GH[vCY-fN%xLm:y>߰H`{0l/e;p]hA6` y@dd?,t7eܼS ;1ҴuCt2yf -| x,w{[tr* 8|58YG@+& 3V3#T'#~]R@OX6Bٟ enU)֤[΢.8&y3?U@PFZg9XoJnL?QUlwąIG34~앖uN7ߘQxMgpmךu~6/J՜Z֗Rk s`W?8!ԕʴI.s%M7SQoryh,Y҈̞:jOo9LĜ2Y 5]Jm?a|-\KY6?5#&llsf$Y>dkʮz'N;4(ֹbm^f\Ce= .E8e&bi䇛OmY< endstream endobj 2273 0 obj << /Length 1868 /Filter /FlateDecode >> stream xڽYKs6W>Q3AӃ餩^( 9Hjw DRCL緻0>>y{ CYBzQ'O0b pYz9zE cLO,MǸ"9_O9!0L ”W,acKYiM84`\W'󦿚 '%01EYpﶂh'3vFXrմٜf.zVkBHCjg1 Yi5ꃨ1f8۟0|,]^(iZOxR0ZM7#Y΅,rەM=^#!i0$UNn/MHX7۝F(!Yo{iOxX"0 PaeCQ✥r)' >OҮs?q˱0׊sj/D[U|ٜN{^D2sq9`aSPݎKD;mCEVW.=ܞ3VA:cT"2p߰禱-eLDKzF4Ǡ˦VۼG(8b#Wywe՜HPƌ)@]Դ%lj\ȥ[nE+BmSF'^P7]xA)ǜ^3#\*ȓ9P@/T)wQ>?Hҽew:(#Vz 0u3c()GK(P}1)p ^6] Y@,Eu ty)(8e˪GN7# g'NK9ux[Qt匲_E.ߊD KXm@nX9)|"}Up_q-laU;W|rO8E103LYufR[iB1 $8^,2Z,g@ngGS3ErR|BJ cl(hIbx݋Q5MA1$Q2KjBF#e}Nb(ݧ5+\70 `Բ\BfMl8' M"*).`~+Z3X C:KbFX<f|WB F j܌>{5ˡz٫_ *R\ҟ"wE<Hs`Bl;&ۚS=(*:F)ejI959XnM?Fe4|U^EHHmf#$f3N 3*{4kmis8 E1[򻮬JkL=$r%,'gqomE9}a g{^ꆨ ˯צX9l2 endstream endobj 2293 0 obj << /Length 1823 /Filter /FlateDecode >> stream xڵXmo6_e(`w5#R^X$CZg_~P%!"K^((Svat{s'qnWD(lnȣ.bq6i󫀎,"Og$3appF3kˇxϳxrb'}څ:k"9tvY.^ o"ŭay'Twp }kq@S: ڝyŝn%^cE,"l'!{r?Qbqu6Ac>}+-8%*uSMQ6e#_LE6$-H,A) i:<͊'r6#gDP㼶|jB^g#f ]7<i݋kٰYXg(Nj/:#19Aa T/f݅X`PQx &ɂ!%KzdXjb9Gt$xKʂSX~5]% ('7e%ܓu~Q|IPճ%]<5V iSWUVﳤ+–V-q%Q.r~2hH>+Lx#/2mSD)Qar]P+iD=ĒU2KzQ @xuA7I,@$q˚Qf 'C{B )wE.`ZXmvvZu>360l^Rw_&9͍j\ ˁ13j|ahڶB=af?fjȝ;uͿV[EԪɣojN$Z (t?XB i4̄m?Xj1F&Hɋ*׮TnJ G_ɭJUuzUŸ$P Q #0]z]}9Lnѣ)L.Z ,lڬ=0,g22ԛV鏇6`p) q`X|&%Oj i~QYC1c4$= m۲߼S8S6ޮ?\nxF endstream endobj 2319 0 obj << /Length 1700 /Filter /FlateDecode >> stream xX[o6~2%)궭] tŠȌU\I"ZRd#rt(R^txxv짋7!sb4p.1XFGnz4UvyR׋<C FQQ$a#hk]=}d¥>wz7?9\7#]-PiiyCӲ: n]@bauSn+Q4V\4Ysh+r&IL&Uk;i|IO4O|?(l#}#S'-fcg-ȹU)ΝX\;, =H0蝦(Hi_ͳ* #5=1Ojeͮ"I :EeS=ܷ|2im?x5! 󬛌FP/@؟gjdD/o^,-Ed{4Ic> _)͢VAݦJ4V^Btb$&I?$kG|YT":# r"c[[)kybg\el*0}`,<4)FzcM}D*Tk_le1]zCeqˊb4Z 7˱S ‘-QOk^"p5[ecE QZ։rnZjI!J Aq#W`TiַYs_<ywp.z!J Pd  Fn$tJGaHm(;z |2=+5퇅($5iYlJ>b0ksôcbzDCA@gI?̢a/;TD=; "BnT#WҪwxwǂ;d+-sHf#z.Hu{ۉ,*M:׮~XWvc(ayԜ75:VP%gm%۾R& VDhN2l-f[j_Qts0@;SFQ0FK}~Z^<[k41é:FQL)y`&l5A("ťh][SՏǣBqbjnkiCk{1?q׃oO0EvT 83pFٗ6d4L{-ET f)2#h9ڼHWr JrR] &Vjp#2w@_]M\/$Z]@RSg_Dܔ?+GJH)uǚZo >DL{LyݍhQ F; endstream endobj 2237 0 obj << /Type /ObjStm /N 100 /First 971 /Length 2095 /Filter /FlateDecode >> stream xZQo7~3C +A}P%Ζ InP8i:^}(`,q88\pő jx](UR_K%PbBu%'T m-i0JkaZZ+WrkFkIUjMЙ! !ONU "$ip{` 2E9گeEm inmc^Ma-ms`(h@Uӑ4B9ENHm.qe#G4{,x&{s(Wb1bX!m q!V̐*aZLm|%Y@6\fOj=*X/` &B{cT{B/yc )j* !%; y' s)YіVg gVnoa;V::n{6 44'V-;hC T5 33ő۪ PmBi@$Ƈ@iB] ####e"SE6;"ۭW NH v֒7E|P4[g͘lƨ.üv఻Ao)CX`|Z͒6Ju6S1, ~[f2I}H&! ]ҞDPOJ^5P$ä4P;1S$D֡@Ij9sxCPpT= J'vzb'NNQ *V> 38c$ߪ}j`~t[Py8`K½Hnq˿i. ر⠦/f}bqY`l|LKEBBfy;~uWǾ8^FN@ 616-n6U(4Ҿ: Ș7X&+߁wc^`xVf=ӫ?7D(y?]| endstream endobj 2388 0 obj << /Length 2300 /Filter /FlateDecode >> stream xڭYKo8W}Y|2ۇޙnw3blaJ$_U$%Q8E_ŪW_bqwR$ÂQJTXQ ߗ~ϱ FX 1Y7M㮨_h鵰kŚͻۙ՚GtPE1Ui]Gi֮(~DԇO+Ӯ791 d % ™$ sM8 |[ݡ"v[t1̩ڙ$QnVkrSCg:Д3C8S1iq.>nƧ}]̾Z-~ D/kn^$:Q{.e~z%Gɲqgٛp 3 W9&T^^3Dn^7Ӵv/Jy)wlh͗#K7]R !Eu( yv@"yݖӈz}^ζ?}+w_G\r*OF+!abڟ\<3kFOD^04#ٟ<& ;O [479c?gV G^H!'1|w퇓`#g1P"S1OOi/pӊaA%= ];>;¿`,mezd?ȶ(,ƀSGZ622VSM qh)t)?ޭ=U~HE+}؂SZtИ8d:TK<.}4\5l%8!2aMywȠvpvhJNv#Z S[3LyFHzMi}5|脉'e N"zR㉼a2x(E,ѹqx^ftk~ĔK,4|ŭjiY2t S\{JG! GG'K; ش{ @[1S2Avd^vfgILK;sƂ4*Vy1 V<8I7;Hx|-'`NJl-(P`AAU<RMd^'80iUlV bké~A; `-[^*VC6$h }nw6P2= GWdΫ ~A= cc8l՝{ }g9=xx#kG=fq6dSzer[#L1IZΰȓLwo(F~Z7@GXpym-c"+OktXRE"%tغ6ahk|9ݛM<SX ذIam;S$W iE\,p=9kE|` Ϸ Kk꼝x‰Rlh6; }d'=^3d/3+gGc,4Ra< _֎D2\DA9ִcMɈDBjWWEε ~o> stream xX[o6~ϯYYlи}Ii[$*Ԥ۟ߡHʒ"; \i<ɯ˓"8l燳((l]:U^-x* {}LPc!QGNssxN#I^𚥙 X^pizg&gTf8i/K9d[s !ѩH|+^DJP 2wc갬_B3Ͳ`9_zCY'[Kzl>OJOB{&w` ޚo\d5la%R@y@ނ~q+]˭<&XxA`iQsΖWgK KޙJmSZS $">EQY唇0!6zxw=D.,J((o[|c{Z9Q? •Ⱦ bxnq|CdJ%$4vcZ&V&ۙ!zKƮ.?]n av;,OCGb?B7E[;Nm1-b;`mB 9V?f`&/)6.ݱsHz'*@_[VkW tq]5?hJ> stream xڵX[ܶ~_!h^E*@;.PIZol?h%"i =6(sppכn^ AIL! #@ F<toI*$Xm]%ʴ͆ż~I`gΈQ0 "* 7u=YZ~vy2iofEm,F.ȌFH.@<ĸ_ʑ>Ǒ8FFr?͏w72a3h2n>|Ap2]D 몈rcZ|4Q#8Թ[<Q\WHү5L4hl \ ߏEgehTφMZ}C"Ig8B2M|>k25ʤ!W`2m'FDOn7O AX=\\"<'g#LtEVgK[c1̈|($-; IZoH,'[{' fe 1^gc7ߦ+;ef P~AXP1CCt&>ݎN9Kan)sYM3̭;ډNU;4Re歷̔=xhjV x} r@Y(Ќ GFCl9Ie]mlZGLJ۶,b89 qcJBa F$(lZD"tmgIZ~lυAQ;)VW&SuFIdLJH~if.FIG&q (ds<5 s`|[['͔Z"}F:i8&?+͚Q8$fB%Y X^/@@yp ϋ8U D -8G "vNJؼXWmRdMp. Wp q;cUG9kצpEŜ"9s KZ| dt[ԃo{ԗVN^T@rڍEvps)h &ҥleb\z3#Qm,c}Y˺  ~8ȤJWLa,Pmqz"/VBߕl}hq \6:ʢ,έZ`LI1r :w.$`Ͻֵ[˚=#wB 80U/B\B`Fc3=[S&!kS1C*8y N0+zap] +ICa1iڍN3E*x5~[AdȕUHȆwd(v㳎R uR\C}M.%Μ0\lT*Rr42Od hS dVFѢd~OI1`85L6wT%6$z))bm25vۢ v`Л'WUmys!By_ztĐb49.,ʂ`PI@V n|vv(VRmo?Y7 `b.Z-p 9|"e endstream endobj 2370 0 obj << /Type /ObjStm /N 100 /First 969 /Length 1510 /Filter /FlateDecode >> stream xYMo7W^rfHF|m(lhkʪ-Ԗ YF7v(2ڃIfWof9C#S ."9VGHQ*H! q3 uI8;&(I00\E I5pN"8˩JlJ15pqU: dh ,8?9pUY)rXy` mͣ8r#>rYGdި;}՞uo˓鲍0|S{I`:9 C#$p&Z6[A]h_1ӛˋ2[aAYTSb8YxH^hIF&gc4bO)G?=8o ގ|1g/h(|68]ӫ-20 PKs1Lǫ||ER8x;\r┽-RHCV7Oq8_&-(1q؈XEdAy힜N_B8*5%i%-[W6{OzIND[Ii8%6\\-s@Ez``OXrqfOw$_#?MjbeȃBU]YzH :?]mCUEh0EBzjDv%k;^KZLܵmŕl l_4>?4nϯ/QnZ! A |GKŚ,C!*f endstream endobj 2467 0 obj << /Length 2398 /Filter /FlateDecode >> stream xڵYmo~b+eDJKڴM $FZDw (Y^'8QԐyv+w7ݽcb"XmWu0p.[I䏛Hv߻}1eY>kNZin F8GK~Pݾɺsa %-Ju1;IB =WmبOt!]WW/ȅYo0v~T_ծ7'62ziQ }+xVÚKf2n.+Lpq ,DOp{i2:?T |1X17AϜ򴞧ʁcY{/թ̫ΙSLJw2 eΈk]73~L46点x2=s,D#TkW4Zw +0zad_WKa` Lu6Ɗ07|횻Nr,:RVR$c2Bpr{ob6)>Is>b8hQ}*KNkކ@gu)uPq8־a_{m]|F'a{ w?_^he\$?--uORDCDU[m`pmRTဍaM+ υ"n1G!hxQK=@ LC+0d Su aǦM 34fm 9.4J\ 3ɨt3x>D'^}t"f]G2c6LKL) U 1zlr*xP{23,Nc:,!!pn$gݩnJ`U41@%EVҟ|L3!ZК%sեc}EFL]Nuye3>3qd@ݱJOB(3Aݐűgh5m]*uJuŎIk8OB%Bp~?Gxg9l M%oٹpOՎ^a@~'  5y$t^ꚧI_0#KMS7yY>dfӉdWq`t22< e2p拡5*/tR}XP:tbI-ڞ4}YYv4ibM8 )oXO0 uE]xK mfcKFCa;vg%!`|M;Օ홪8m*kؽo/"q=x)JI4;_W Ƹ|` P a~ȼQc[|@lf;uipd W W*/-&w\… ~1!)|҄(L[ImM]'be D1):KϤ`G(5}Eo1H*L~_:"n_ّHN5w ٹa(\Gn~#^:%+G]T^uj&=0L4踾Wn_lv)|1gˌ[:i,uZo=E/D~vO˕O8Gr6Eb#S/`E[zpa& '+'ffFXkh.6fnK|*7KB{mf9(Է?}LN^toDIMG%IGiSk[Ip4U=s(a3>};̵u,}{r endstream endobj 2492 0 obj << /Length 2017 /Filter /FlateDecode >> stream xڥXKs6W UA es:VRZW5fsHh^Br,ٿ~hCҌ]*l@G\}}0Q!(%(D[g~(\HL(8&Xj.cv}!؞+DűI 6`Kޓ%-=D»׊.TtFI+ 5f 3"A_+!ZqIu]+&h$pg 7 |CNIVEۄJ8 α O./ CJ9tyu5"sފ$ k4/AFQV}m=QIs5Lt} ژ)4W}^!A˺ [cc3J7%FvMALIDsL]̚+c d{l m:ܦHϠ L]gn=țA[?EZÝխfW^ela8R#na萈4Wq4ЃR~Ӥzjۼϫ .!xOyl$-;]V&cm/,QGry!sN9 \!K0 6r* ':pa$a8Hkݦ6C>]FϛS 0SoQ/ze@dcņIkPρe&R$N@bd&.b(w ̩1:zW8aҺ J10"4-t.1SrfII ScM̫Iv鲪FL=$c%B \l3?]87$/Ҥ3AE ?tF"aBԴ֣@ϯ|G+RBxB_fTB$/99jLy7rlZ ƘCBns ݹQMA:¿0ezIS_"p{aPE(;]]zW@?c%Mm"0v.t@Yƚv#E1Ak"_p b(_mzl0 B p@#K!Ӵeī2QaQ\"^N%a8z;)ZA,|2RZ ۓ$6 6O(IN.SoLokMH_HS.KL0\Fe޻vեɨl0ƮNծ9@;#e=ҹd3ؘMuM.wM.wdFt;H|߉=L9W9-&^8Sg_ 8xpp(ݔ/'}6@l') ݗ^[{kE):wТN]~ХHpA;I6M`N&"!^,"$<|鳁i X௷c{4wdYdU#WD1b]3`CohxCj/O3=Y]Ӻl q'j9b ,B[O eMOz\8] 1n06-10eqckVꇏ:55Lɳ ]h9,3{o4@#Ϊ$WYksa.o;y#4"9-/Ŗ2Ndkg&vOgFzjX632VoT,67qY^vs83  EF[j9Q0$D*sݘ km|3OrnJ?c.{=qǚAy]S3˻Kzf"GE7j#ȿ]_}% endstream endobj 2515 0 obj << /Length 2182 /Filter /FlateDecode >> stream xYY~_U3 xهxצ_GF)R&F XoRSSg3>ŋq8KYhL,8JVه`Ӽgr]dMuoh- д#K.m(f B\TK~ڲZ-K^WYn_歾^jQQ f)8KuJ<ߝl 6҉7_S,?B%jgOyj|馤_K`|,٦~>+^s4rbٺ=ޏ[g%5 }UZf׹)nml܆B3Bc)>,>wZ$|yv]-w ql`śd3&1QŇ_l &Si2KP ſ~s NSyx^K&s׋U9Q,Iͬ['丯ů'zxBIJ&);UE6&-N6JsAqCܙq_,Jz yL0b]:ME@K,;X3_SǡZV^n :o)B fqH Jp_8+Cx_@(kaoChi<;H>a@Gv+tRJtUw$ TABs3̵N+)G0uvYzGzջˊ^P\'TV*+VjZaE5R-Ty``9Fl|aQH;qq 0"0(j[= bK×*1*QPaa°:dq -yAV>#zKkX::7 p 4*oK889a&ؐs %݀ҌDV=|w@R`1'ޘ6 Ӕ"B ݀q{vT k(9} 5(߳9]Tӗc޿Ott;8`PF"\poCbҡOnە@5 4e*LhFbhs6PL I'4Y# ǼțvBP3Xqޜ0#=U^g?hI'~US rW?*A޿<PgH f/萊myl\(Z,6>},JA>п( enuXa$ U1rwā8fJCoZSn>fe#|RQ΀TMB/7(bI_bm> stream xYoܸ_!=T X<) {@݃,ѻc+i'}/suMosp|秛os'F1'?9 r1J}rm JJ 9:jM֞I/^Z$m+7=+&=#DDwHiy}W,xŽ0m~܈_}'[0߽ӏM [=8aB"6KfP2ER} B Vhљ+ZS#7K?K&-R6P46+-'? T76" x"k" 80 t[a, Q4Ұz}=0$00#҂{pZm=vǺXE}/o?|MQ4). B ?t? X@"]*/vu#ZEL}B؁T] O2\;S]^W8A,X(6fAwpg0$:c#ƃzLM+ .ͥXML"݁ Ǿ[eWߧB%,蹹}L&&6lo17{O۳f]g.SdMWIխ +&|]m^.z&ňS<5Y[ܤ8't qwm-] C#UARz~)$jTa*Zi_deA1O}R`r$h:6`V%sΩ$zS5YêS}R0 R+anڤ9vkCx` d P0h Sԙ@~Veh:Ѳ.>uq.WYfKzňƇ 6cM"6+d 5X<":􇧦.m]D+2d@c}$&c^'r;ڕ$6ƎfRkꏵ<>ρ!a['C;W䥃h/L<Ġ VBQ2 ~5YWߘY+X?d1ĐEvcI3[%)OX(cD>.P0_ߞȧR"q*^cxNePw}w ]*ex~#9w5$0Y!^KN dvIs8HΆD;#eXMA>N⡟Q ( T  md*aRno?6m{r2kȤ"v24/[)9e|/fr%W\5>kwP .͊iV.+u4sWU]y_ESN:)M.j3O+ endstream endobj 2451 0 obj << /Type /ObjStm /N 100 /First 970 /Length 2164 /Filter /FlateDecode >> stream xZQo7~ׯ"ricjA'mHr7\Qϑ$+Şݝ%|Cbp?B?DhDPU7@d<'2!Ue1T9:N7:r$Ec0)JUfCUN&KUF*#ΔWm\zEV^%|c`{I = -Ye\z0C>j*aB :Z•4qJф*>1@R#{XK` [Z Nz?T_2KX ;}N=3bLHT:_unu3_LYaht {v|6Y7ra%FRR*ђr\Q^P˫t2B2( C P;rm9*g+HbRD3+3^0o7~3Y hLV\tjg>$j0?ϰE;Nx9bcQ6nIтcfL6:^OC"lAi(9ºN G{-@DC0~[ς\XMـ(;B6;1pE,PEp"0Jƪ%m,zvJR@Pŵu+7NEQlcCGjLBzAxoB iq_MHsQܨenRF-QKiRiFZ,mdi#K6BFA2=TD}7 cgS=0&wtbWZc#XyH-b$ x6 Q>)m i?rX@֣q8N2lJB?Ѯk|\sC5Z*ՓMHMM& J#c_*Kɗ~ mi-*@%e E;Ԅy[mY$V B9Իn5$xIП&[t{Ǖ|xD&"?77`MOZL\>?HNo7x 9X1ʤP=)3&pMwu2|GyW=J֧2iБ1E,rv3Tֳ]g߯Te+NS+9rNrC WdkjIOt¨ 8eh &ΏvnKw(SDIQǜßgMQ8*:;iAB"w(Jú8)vKu=?0A`Tڬ03r*l endstream endobj 2554 0 obj << /Length 1853 /Filter /FlateDecode >> stream xڵYݓ6_AgjE}J/L:޹Oi8`p. 04YHoQޡoŋ7s"uӼΒ |Mp?$I0%."#ٷ_>d8o/?359Y 2Mf,{xMd6nĩvԧ%enqs 6[;[{ۀvdi-vImb_r=4} k~2.L%}] K6/ nNK,  *Svd$.Md.Ea6ٷTI`K.ehȳ3I\G9a̖> KrjOXՑ[K"n#q=$v>t(dLZ#,>}V}xHMwn"STY 0QsYLZh\RIU5wnb>b$[! Pfc,NpԗO;4: ?]ݏ% ~8AOJmG= i+hE5_fJj1($/6 Рf@W2%do0ʍ)gTcEULMx$ G!ge7r:ֆ ;Ukt-7A9PxO]l- J{ 88^۩Zb.GB [AO txLTcG`kipl6o GT3TO {6Lc9HžЭ#[ĉzG_AhsE V5{me&IBu|& f*eSi/Ȍy2Ҋӵ6 |oXkOTAsƝ4ٸaN] @Ж<[ހҳ)y^x^+盾> stream xX[o6~ϯyY"%[u vKҧEJu$Iwx,ʲl/Cs;Waoaﷳ_Ϟ C/FqHCzQB/ 1Sߟ`e"89zMܿK:[,iԆ3lՀ>ع.hdRwxMaA̦՜rDKyu_)gd<Ǣ;uˤ3n/0KKsٹy敻Ț&+3M D(S|0>HV%yPhf״fVK8^P]_?RcRI \ʧoEJ"-%6$# fd)++0x 3V=2A`H(C͋Ya&/̰T9P5]91{\ l%9oR wiVlUV5U~+5MZ]fԍcgN`i~cj BS4d (<4e$$8b23v+^ EDN8!ۨeL1'ܗ`J!?Rʫy 'ADoN}h@>Kd-T`-Cg2S>th%Gw>xki'a.T8(!b'[Ѱ@0M-yxJUg5Xp;"`ŗ]~|Wh%N$4˪lڬݵ{c':a)M`3/ w؝辝vR$7]TKTS2cCޞAHY싙FBrLc&,dH Q4Vٖ[˪VQ*SJ3Su U6%W/.a6%_*@}yB uՇ;q?eE}A0I?VaUA4E> stream xXYoF~ 7{rꢉ(ݧ4*Iҿ,w"9fbIeQ/Zu9曝ڕ:xb]Fcן"48r |6e_ݰH ̟ MGcrl8Z&-K9zuGT[+=m)|w1d{9C5 ͹`ȋv6xȵM. С7edᯏb#]4ẶLm܊!x%Hhp ¨@Nyyrܧ#oG}qe:NwIPr!=*=ԣeڒ>ȃu)1P w0]G`xb̠dpo!qXa<XTQ|d8;B ^ Jo5.޲(ޛCbn8.xaHj4(WLۜ/XS 992!LBh2tD:e&NK@qm*t1Gnq9EZFK:4 "-8tsEA5 ԫ uVLJȳ J`LyFcKtoAEbcZNt~5a Iֻ/}k,^"_CϪ=uIX&Aj'wuy9xO'_Aɪ;2?UMNVj\ߦ46:dEG^X*R:d'/:\gHӸQ5^3+bA0/c9\:,MifxO[{/yf.(jkPp? %].;;ބm!yB5_Nͨ7`y{{!/ endstream endobj 2620 0 obj << /Length 2110 /Filter /FlateDecode >> stream xYK6ϯ`͉S"x C8v#8"Fb" Iٓ PFrٵA &w߮>Id OS(%B&J(VE[^N!e t̞{69Zw]zu! xDoРşXٺ$cDI]ݿz_#dS1% (.җY<50N­8lʼwy xxLiL<0p/jw}e{dd-I2Inя3^3I8aVtnCW֕QAA2•V[cH*{m[="L~E"" KOv! 2ea0hou(;kU 69HHǖͧ!4 DR]2a@#7jud|ȭ捶ںAܑGFmYm7\M4b2&$N f*O9`͝ +T=չN6P`5w26u('`</u>awdW'!J +;xn3P];Z_P%p8hxNNc9Q1I*LƾY^`0rTQNcg׍cP"NSA I4燓!T!BY1¸$|dB`83XL{QρrX Xp#P 5pd - K9 *t`cU&*7}ƺwvƤ5TQitR13Kq⾞_k >qJ<|\^eDQE §0`zrPGGEEH\] {5&5PB7P 'bXgk}P^#E @BcvӶtVɒTf>rgM5 }v}.E_ٺeT;N|+?ٍ'.< l;#X28<[jEn4ܮXߋbHȫZTI,u[ЛPW.3Ú MXqAF͛so< K>8r}51˔egfquގ19`ըՍ^l?Q ִ|ǗWg<ߚG/6Wׂ(pss `мѳwa:>͜v WdWoz}%l#iD/A Laؤu]JXJr(t^0B/~ɶ]6J)oou˯"9޽ǿKїCʻcx=<=} R x ҍm'*<W>8aLHn،[CK1>Hɛ£ǻ[]oѺ m̌#!U*?Uv9x>s 1P vf]WGt( !#/ ΅$WOč{c7)=Iz-.SCd /fUʫجr rsTe*YD@ endstream endobj 2544 0 obj << /Type /ObjStm /N 100 /First 972 /Length 1987 /Filter /FlateDecode >> stream xZQo7~݋V)R\C>Ĩkmvqlv4/;á(~4RP@l!΁jvC=v%pN)]BIrR_i4W",2~/+jv¡YW.tI0e $Z K `T͟pe /]H&bq# \ P tu]?a|Tj,u5wߘr[k5tWk )ʖߘ%M[= -JuTI\bH>uYWK%X1 Mb͑›ZRWܭhk!>ɭP &nJl; S oY3PYjb*!ay2I_5ZGȸ[1BRZOhh zdv"̾].W'w}dj}XLXN_Rq2;[\܆H`)%(pK6j}M~j=gșFL8Sԁ3uLmGeHހͫwEnFFDѷTƊj0IyuTDg6դIrdpіoHd/ůGG Y es-HK5>@ӟ?#?T>?-MFj{JhI@Œ'CG#3~\gx-k;ˆ.U֪CFAa6a,zTDJ|ѼViȦjS#HB w HV7GDA 52JҼ^ R2y&ŎSF^]mYAcmeMAhe?]ެ&ЕT-:"èn&@E+Iν?J} NS|ZO k S+9PÔ"3Ue[;XWp i7ZLȃ/1%x»)`kMq䜈aF}#'Ef]r/Amte*iX m|'%ؿXN`J`ƭ@ih AAcVY46KR?ُ*&Bo~1,BhR*|zv4鉟 .Gl]#Q~pH-XeYcc/~PZ8~c!0b#SMסJRC-HNDH}(}R̂R?CðΧ.u<5 a;X 5Je| P@j/O,66g*cI> stream xڝWYo6~_!t7]1$p@P; R=YKLuE/]+%M\sq7$-l[[zxV"ݝE0F[ukW?If˫S0AA6|@k/ K{@)7qV(΍z Ad`D(U?Og"?1}s_§ lF7dmSW?jHsjLIJ A>53L5yY%lHCLP͞(wUaEºslu6d+g+r1hU|-_ы cy[RFc{n:ٶr Q&pr)maaRMڐS-1]ɃTȠqy ]#'l ,؄FȒFΙ/h LˈyCcqrVGVռZu?~?Bȶ>/^P3? ӡmNLF3t&QAFp0<9\{`-;G<Gi L-*a;zD^k]=j/2.U~Xd(YW"Wc']A ܅<7٣ Oi[uBUף*ᴩ_lM9aeEs5E>Z(3ҵ:($:X(jM•x 9;:q׋VI Q`鉊ō[|~V@QVuMbn$$v7] Ѩ}(U8*~A`m;a`85]{h2p' endstream endobj 2643 0 obj << /Length 2112 /Filter /FlateDecode >> stream xڽYoF_ (@քsn ,:O}űĖ"7 =wqo~~7AQ`s{( 6a#N6 z}JbD5i[O:{iWa3h{g ::f(f_ 3]f}K3E7YIn^h`Ҟ$>ulG./RrY?{eCѦӷ~ #Ҟ¨kcx0 Q}zǃyND^; ȁOmRMv,*&%< ~[՗coI|±NvAꝻͪ<;$-?hF)X)ڶhC_$(jhM[ nqJ3^I/绬P+5!lNg i-т#@R<F3Qkn!✾yyLj:x ~M1 8\ " 45RZb^ 8}j ]ڙ3ƈ 2AQ`nc{'K^ĩ@;'^U$ CO&8tEUuJ^jt^Ud9FB7'σRdH4sad #nKQU%gIHb)H}tKgaKz#9*r}G/RNPk> stream xڵYIs6Wꅚ1,witqhHN}.HI@o;k;~_^ }'Fq@gy' 0:Go'u|] 03}$ .of!=6/_{yP'p`;7>jA0 `&!Ԣ;X)#\pVYRwyR-<ʱ{n-r,tE]T]z9j ( S̡xA Z7^UٶRWBDG"DF{!tpws-6Go&sR镦 #+ᦵ>0J"0{rAU&Fdwe!@K |IxCf (UEYx `&l7*brR麬rOSU%:+{UM*޸}Y ]m8)8WdT VnՃd" "5{n@\Q *<Fc/sγzz^ΊQ!E{XF(0(Ү3t_Ѐ"gbҢ^!,x}A|~K#4 p4ì{.XIg2f,D-B ŀ@ǒ tOKɑBENv_P'{ 0NL5|}c}Fo#Dlϋ=73wna'L4+yHu:ğP~?NG<^!;]/_YqV6p˜ׇD>岊'ի&hX1vs,m[!8y<8:B/K ~?+IF.U0 =p7gKjʿb8 hY\vZzbM=j f[#O<(̯ ^_'oJE endstream endobj 2678 0 obj << /Length 1878 /Filter /FlateDecode >> stream xڵXYs6~/Rk"8HvQIh RJR8xNDooO~^<{#DTˀ`X$)0Mq!ջgod[8F ǮyRMΒ2NWzu )HFH$XN>~^ ktD 1g?Zyњ#O$H ~ "ƸՒE&%8[F^;]kcg4 Pqp#@p>>B ;+]t_E>03x8I _i!1R5x}VL(#0?Q=FTNwpJ:`l$uY_%eu9y]"$ #NkQO?!ތ̣l7oX^(_\~%JFi' 6=Ϻ#MlOH 9 8OtSq+&tAc]u0DHEQ\8ч2٨)oTƷe9@hElUN[L2IYT& 9-gϱeN i:t' 7%^t\XSC%oȈafATmkmfM3e\=4SL5M *5"lҴ.BL"]g K?aL)T*&>QʀeڒgY!PC@\@liR 3e<]!msrrй eUnj o!83UZ@G]l}Oۦ^¢߽x'?8z漊9S<=F>ٶ,{7dG&K=M"ӆ xו>K-}uхfbhHBv: ڞ֣J3_PUR{RMܾKW"@[/Yœ;P,ᜪ!C#L7d83=jPb4;Zʀq?n,/|c=Cb*@S@2tr>TVpչ.,ۛNjJy#yn߸|:tr~dn8aʊN!Ǻ Sy:X endstream endobj 2690 0 obj << /Length 1646 /Filter /FlateDecode >> stream xڕXmoF _!d(`oU:I'iknkaX;u>uH6U/Ia}Ȓ-'Vg#yPu[˱~Z^< }+&1Zo,q3+d /\pʱP?+MxqdK]@߃un}X>So5hB6Ѧ$\]oʦiKZ2I_NTeHn`eP,b?*^6mDO"@?'9qg ;Ϥ2Sk `҈(SIS)k$zOq/7+Q m榩 dJy*6;QF6̥QgOVcA"@ynWc;/J`S k-WBSaGsd.Rс% _ u, %<ɔbiUjwJu[hb>Z}H ;<2-xQ5/g\T6t 5^-sk˛bHzM(]JciAci%vBd -^ٵD2%CK@jGq=Y=RMv DI~yҚ`2GP05tWco-oQ&dz(bƺdiamۤy~hP,en5 '+u@o, \4|Umq2]78,k~ͻD n{ o5QpD?e9H;fB%ַ9K.n`jw?$*vF){mgAٞ4qǀs/T!ds %^f,Z+,xNjVc[y}ga1$+ta|r':"=}!,@x~[kTrn*d;ab*Fۻ ʸ ) :jrC6A%9¡CU]rc8(& ϚGwJu#zm âsn^%HÌ7!aG9P0ӹ^r"Ͱ @]~rHF8]?ơ<܇ @ѪNr$e%W[~⋁Nd2Kɝ(Ӽb>K];W㾆3QI/IL; t/ϼ4ngp,0sTHpmў$c.P\°ߎ&sዑϽKtQZ+%caJM'3 1C}l՞;NؠcPBF|2g`0/14)> stream xYMo7W^᐀ P[ALJFM8ZC4o(mRv$(|04rp 鐂gB P¯Ϧ`|)&l# g1D^߰!<@HcA`IELNUYwe}ltYĊ-Vb> Ua) .:C::P%FĢ.JYQqT(*Ƣ"jRE ՋP'gb:)ZHL ^`8M)A*$:CDu9ֹ0[R}  !ԷQȐ u-4"{,ꬔZc8+915z;`!cpD3P{|Ⴀt&\|pFIBϐrcBz RZ4X;z1ձ1&AR5vu ֘`C1X3I?VPbLnu vsc[\Ì!i ױIC u Ih0ƐRX9@}&0.TYVh<3Hガ>6ͫ@95cG}[ёiƩzۍfbsXy/ە95͋gcӜV擩.ZiGSm童֊jsr1m_=ogg's0fH&osy {1SEwXT Vuw}ܻ 260 q(ndea+1"_Ǽow9m9-âkNRX6BhºȨyy>z67jtY8驯 }-6;-b=2ֺi~N:pܮg{<,dQt%Zۨdzw-DwHL<"%xiؾ=6kW|2_AYsF* l ]X=nϠaSоUKm@C>lu^nSVeq6 ]|6̺U%owYD+Y\ڃ6Wdk"zD[y"\+Iz!Zju${Jh/qt[vYvWc#bkAM;8wh,^6`k(z\Bj/$%[T 0HJ7:9.47)'@7-ʟw [\B;IPmjDWyzvL ~ijc H];=rfg7۩oFzk+DTs =EU4lګ3/&wl0׌N\x!{f)tfD7見nXtC<4 ĶHC(ӘԋNxG8[mȐ6nP]]E_ѤPvo٬/ۃ'0F4n8(Dh5?+N` MZ6,;6gmebv@ӛh6vcmF&۔*GjBaCE(_ -:-ݴ>y"6#p(zXp8Onqq:L\nRloekmVFs h2Xjpt3oom | endstream endobj 2751 0 obj << /Length 3586 /Filter /FlateDecode >> stream x\Ys~_'2'TMel.my٢meeQ!O~} iɔ>d8I&~͛~b"DLn&8IebqJ&7i*.~w? P`=$|[nW|T*7]Vog3>3?/$.7AR3z2bsxޚvW(N^q93f쵘9)Au7ŃtLޙ1/;`f|U[1C5y %O+[}>bTK6QI#lE OߩpW8E$nØy50]xNo9u?' )- a]KLcnzF,Ku+n _5-F(%0n+ =Yk{b9-8)ys~6df"#p]զzVa"tHfĉ ! D=?EihC-oECaC YmQVWedIF\*aTja EI}Sjxm8>Ũ) i(F$MHm|mIE:$vXqt(QN>ooN}{Ӵm}˻pUmbWY =oZ CÅݲ-N@ k,$>a{yC._*=v˅mu隷1\|qQTl/}ۧoT.Ҹ/GưAou{>j )d(%XnF?BA@٫'~G2e(b 0SXDN˭1\a.GK,$"i  7 yizw;xگS)RIA(' &$COLpElE*RnQ]Jc 'KbiMULeW:*zmun-hN&47TrЋ6{4R!襰KfU˷+ ~fƩ/H0ƍtSGcH76* ӯQT$ *`T ei9hRjwG%84"E?C$o3.¢fhc܆+^:(XF).zUeK'%cEjU|BQ g4Gy&R9?:Bo*߾Gn0ʜm6(0O\Rq6mOXN'u) ( qN>-K<8")'-O*qʂKj D7uWu0iZ܀Ge=}w:S.UB7sщZ]3Z%ui65[bt,7âQ> 69uPY͹{.VMIWS2:W122t3"2ɶ"L=݌ Ovv3 ;} H< _9΁K^S@1ȏPO|^W@ +U7 hqݏHj;=I@clE\k./fYPpOYD+mA~̕j;~l ut&Vа30@ nzL8řaDQ JҬ۞-2k<N8xX?P\:] > stream xڵY[6~_!j1CR(lf t'I34 P挅%G^tMy ~%~]|s⒳@ 8(dqc7n.$wV6r]/2G&'@T\mMw}q2LBuhIzfywivwy=iV~d.zV#bt}Wzko&Qˀ<| *ͧ޿]#`IQd[+F{y\S"b>f*d- kf#͢Nvնm&+ `6U7)w|H!z^-"RNE^bbvO8ڳ$zlmHQEfT}T)d(w1&Lj۴z Xb˦BJ/8W9 "O mT3k $>.:? O?PC} NCL0x]ˣ0mRR;"A$i6L)CJ\.=%y*q(ArH1JBr*Y)k6MoC3 ^z$4 JH2M_h8CjbAϬ ش&x$*ʄRA-< *K6Ot~phWO͍)ڟ6¬ebSMlBAWd6͕Ѽ)}!7p_DDN9"K*Y|Vd&ISr g&[rr澒@vF0B5NY-e{S*N0!U8\ƝEis\ʢbO :!A$X$ࠇaVJ#˼.'U7}`RA|̪(U-9$5(^yuߴq+W5L z\r #,0t4U 4Ė'Sݨ}IA @0@K`^/ڎŐ>\& jۣm'W0 )sY) |~>+ Ì3goӓrS]m 1Z6y{ ]By!LJ v_Vdce8ۦynb(QGa bwzڧ].kowKbB@!4My*y2*đ0f ۟W].K(9"(ү(TK[og t(2/ jʊ*jʊh&Bn@<^Dc;ebxB)#_· qQ@{=f.`L8}fZ\u.WYlw49'ս2u> stream xڥXے}WP*L\pUiy%.yq{wOHTLO> _|틯^"fq v!8g a.[w߯߄@Rz^ y8n}!`uea,wvRWx](LrAg Gutϝ2aEIQ<0ɻxԥk{cѢ%}Ÿk7U!SA/I2r-e\Y,cFwI^̿׻\ޣuȓ'Soi1yK"~Ϲtf%[j^o^$<uC-RtPh3S! uH3SHd) }BUY_Ο)G0joӺ儱&#֙.xLsbnڱTe>_x dC #wtz^$h'!# f޷IUXBނ4RL9B1o;k]SK~@nnvkAv%#B{z]0. Ye4z4[w&,\;CdɊ Zd߷Q3 g=.NEmΣN˞#WcPz,g޹nv3w-7i$?xSKg "RA -x!D'xYG,,,(w]`mJfB[W3MC8)׌Xl83iq21iPƇ(=fӔ(}!;?!$BN_b 7(cXByR6U4@몺rw^NK(ԟS-? ⍬ ֹbWI: hsQ>鮩S +.Q,T8}K? qJqm?6Wo!Y q<$.A4 m;_=JjyWb%W$PuA/{:_Г#z.?6y(A;`cRй_=K[4آWz`KGb ABG*ws؞ɾϼwKUjnG{j_^}N/GFgڎ&OݱHYܽC` endstream endobj 2813 0 obj << /Length 2023 /Filter /FlateDecode >> stream xڭX[o6~ ᐔDICL%- Z(eV=ncz<1Ez~zڼC/%=F) Bł(v}ՊE}JnJٵ߶7}RFdT/v۫]1RMTxYy7{^wg^@h>]gwk FƄ^h`d(!s&l磒՚Gԗ5ypV^8vs:B!I%0>!Bj&?vy]-^Đ%ޚ% _XZ{2'](&;((;U7ʫ[nbg\ʬ{Qi#zXL4e*$ 'BY[߬bo$"o0F2$l{Z;2Z;Cb&6N[yzeDW}^(e DUW:`|`' PF/UuRv z.C8%UYХk+maU@螥Q!ItXc !,!hZAu_RN>=c_.өnޮS [Lw))bx˥d@8Iӹ(Z԰JHВxh0ۃwl[NvRc"IdNc8^.V~`6\N '&M/]$FW LRS$#B&iukbBɣp?fY::1+'h*N` *KBA(o Sl._CWUDrl  J N))mxLײtg vcED(xD6rL_}j\٨!n=ґ_;;7Ce ~N]ܗEJ˴EzT1%|63Q26EW݊j|p_᬴ z, bpAu8o;)Q8F^;SEGY![&FrPMk V'VboUnP͜π ށe\7cUs6t#݁.h ׈Hەfk`+vZ1as%ڞPP܋^ڱ%|zl8PθCS˜0a2:i!D0!Pc}1su3I' o V2Tmoa3`Ӭ А iI/c2Ǩ=e:6*:=PUSn>Ȳ;KJ SOfv[ɀ53_4 k&Z[ AUw I2ҷ9Z`}w9$! &6 E35vPTG0moQ[?<8MWItiΎ "CwP|ky6/Ӿ'%u׶(C{d{-ˈ+KE9 #9}YA`';#/M#p&N}Oegr>99aIZwF|,"_/ur7I$PrXEyzA[9֦:$򐬆P]9 %"IMM[׏jq@cF$6jWH;o6PRmGn?6?n̹a RѣeOԮߜ5[t[{M` $1v@0}uXt>Ǖ^~|c㱽;웾4ğkڵƜPB3;U+T> (ŋ ߧOW/w7B% =!> stream xZ[o[~<$g]q"mjlɕMP#KvtC949pn:=TJK{񉲎sVJ:F`LY(Ⱥ +&VLecJXF¤7c/#C fþe1c0}9géΓ`O .\JV"F\P\@%11XHU Fr:F&.$DP)1U)9PUA *@FT2F)*XPkvIŕIUtהM,Uʺ.a䒮$t!+`0 T`c4xOLJ3ƊTdT0>(QtbrHa9JET/a.UAU*.T|aG*.8L᠘a%MIى)յ2p^=;G8xU ȞZYv5ugM_كS2+ ]ف \MbnNx>SG{p6 g cχGZTm.ok &8r0O§`hSoDh5!Xɍ(Kgjqƙgjqƙgjqƙgnqƙgny_SA^w|y}~6Oi{Aus27w%k#{L;0;6&/'{b;z;=:`6{dg'ptJ*6Dk1]M{ @  1p<>{`\Xr]@B%,_6Q?,Í ͨl=b0di-W㓳?^ =!zl% .lجa2Cd"8|8{KOpz& .Eif bxp(0GgbCՄG#q`wAf {>sg5 t~',=Y*Bn^A*`=qvaUZ92㵴Zdp'*rj`[mիS6X2{3~MˋC!R0U-U9n7G LFV SԣԣN=b0FUa^^B}r%,%PQ5/p){aX?תo M1яﻳrۮѥN:}6x9C9{#&đa/V? y"dT$RwE8DT$ @Pz.9=RP֗|uz71^ CR3%Z PBz(noٳL9 "ž:4#.tGp*J꧘0N@Iz$jR5eq"~ݦwߊΆu^Q? x;e`>λB|Al{dw 9O#Sn8? (>ƥ(5xz7b endstream endobj 2835 0 obj << /Length 1800 /Filter /FlateDecode >> stream xڵX[o6~0źˀdK6luSElw/8na !y|<5\/`zÈDж,a[s"ލBk|mzz, V:&(NʶY)9K4&3\ŜO9E|Y*Kj`W*ZFM(MjJ[51S4t}ۖH̓WMf!I)iд2i̒ՔcjzUS8i dt?4wFz#'_Zr?1H4nb{F:ML},rUM䰇f&,,ν"0H%wevʼn꽗hz6igLOɽyq@,ge4SuXHz!q@ Đ6]P#'s"Kp}OY c1Z`:z?]'NsӥIޖ%0Plbx8QW+ ɹzʕ]RmYqbd*x%BLBvFPSňAe_>H׃4x{7@M7^OHI\{S\Q'=]u)0sA4}8{`S@X;8Th^ZIwWqk^$Bh p̖mI4flʃ˧Y @|<g~icLmꂲJM<^ lX]8!Arpwo SÍ0-& ~ٕOQ Qć+8Sf`ԱC:o.O^;pz'7Q,axR$އXFs $KrHIBIe goM=fY3L8^u|*L4DFT#+/n9(h֘SX\.bT "yc{wbo67nDϓ5b,W2p?t9&AMH%51t>eq$C ҬF%A;5F. tHۃ3_ίX l9ԯ6yKOlv==~$Ͽ3 hlb6x$>SQ̤ !`ġJv,M|f)4㌮K>RyĽN*jE٭'!^5Jc%H&ـ /AH;VQt`.Aq 5c${7 Bi*8>L*^ɂI|"x9ZoSi/9<TT"*VX Gz[Ci*39, ZuHΨlL>ePU[6ks5(@"ji {#_5jGP1^8 Yg[=hu ;"f7`7q`H6@7?Ң1&z ߎ|29.]s'w(ӕ UJ^P &w endstream endobj 2843 0 obj << /Length 1471 /Filter /FlateDecode >> stream xWYoF~ׯ k˛EZ Mhre! ,=xL9CrogfZlYmjmY1'Vk`\/#uUf]9v˼M7?^  #$3ZD 'kWʓh #cD(҂%i-&Drq'Rm:'P&/)IVAmX/j*/)THj`U }Texn'e›aBd'F`E4p|0]tcN-=b<xPVkuawNH']U>Q?\ o=o3O0Fq#=R"5eYNlPpq/O:q݆6tх^p!"g%HǻPr Maq'w ǐAn/.g n!p購dII۩w-1 dC bS!=T9?%K=.$p҅B7 2OFH~LؾxHʺyq2OFx}(oXϞ>ۤ(jobL sb@!/ yS88W|U"D䞪qҋ[NOCشAe?Jzl2j $*ҽdnUM)1|,{d2݂> 5+Mڳ1ܖWufXO]dGC `T~!e/FDc췯WzW&nzlYU/K=wɵ?k}Mr/5iEQW\cxz}OX0!> stream xYK6WT{TE0 rjS3>x\( H23i<$IUj4_d7a8QpNƈ$ 1N/3A~]mF(##xTCZWخm@zzޜFFOmYI='Ŝ1nwwssoL{i:e(&NIYIy%gJz? IWO#'G龫OǬpg~\Z>O:Kl{;9ҾRr_o^eWwܨƙgX,.BVR]W>6W׹׹Rdg减/g<6բ/`r/E&1ڶB/MiRmv xLUc"sdOsMqZecf/ןG x[rdH6 . t$\MuQ*r]|Yʼq8e#7b!~!B0iMtaΟgYL "1¡5 #>\eC'F!EC;ji~x#A3!il#!D3jv쏢4Ie;gh4P$hhuܰ9cMjsTۀ82pfuq8fRɠ 1N`~!iw<@4lVǴ>S!X\:%FQ^fk_"`v KkCݮjGV2YuM_(j}"g#˅Q?PuVU rEɀE, jJ˷dGm6HH6pģ68/iR]G8 r9㭴Z"f2ƹz\{0z\c(s(6.e^8wBonb mLMX҄%6,Tc\< r̕]2 D.C Or{cLC!bkFQu_A9#-< 1Z&!Ko!UL@I4Օt˫@`: IӴП0L [d~AgXk/@%gϦ+'അ`]xcAICS-hMKnUA cNuQ:;YB#i7;`cCN6{ܧwʂڭ B'}G[ ׀Ͷ~؉~r&7YBg3E>iq!PH[20۸’nvVFlۜLݪCS~z1i;zYiT]^#;*i_'ތJ^l(Hc N$> stream xڽYm6_1O X-ۇ@ܵh _9@ckf|뗩%'E~Q/~]>E$S$EI9m?^ۿz>71)q]y>݄EG6tsu2l?y(&0ȇep!C4 )/t3 tE$ߟ|{<E$W2(+.(C^.x [C~O|f! hi8bx/K%2U&d[8_,4[e5{w_'e2-(NYrW` L~-SS .ƽeY-B?B1,{%P DU#2>htcM30 @||* .)(D& 幨L댕&gUq1 .9i|9Ha"5ѬhQ fhV0]KflFEVfYW r[:P 'xOI`s zt@&sdPsRJTGpo@4hڋ] ʹxh !όe88,cDVu3HbR ;-p}xlȻ:? K\.ysY5 Pk2!QvyS,xg K6c]mfhK5Zݕ{KVnz@c؍!jO=4cj67&xǒ$eH=amd?YM'p)țJ>kxq|iɁ~%g<㽾|ѓa*5 &\oVԢErI 0L,ձtA^p '`2!|NI'\VkGG. D(; +t\KZHejگEH&X^s>53xL>\gG=u&j2_u6nqsx6'Pd"˗w`k'Jc??%T$) T|^2NW<6c'6?yWm/ؔ6 4Èj2-i`TKk 4# 8JR/tO2l~t?rĥ}X!L D",^C Ƶ1:V5 "0ІY*&ο jܧ597EM4*^pYr19بQLrd4(6.#l;, ok[  `LM⶟Q nH۩B1jD!o$?qi}cΆ$6WŻxw;=|kիjz`FBCu:#n٪[JC@ԇW7dxm_^K\@DTS5,Iv>}vm"*+S}'(jڿQ : endstream endobj 2830 0 obj << /Type /ObjStm /N 100 /First 977 /Length 1816 /Filter /FlateDecode >> stream xZ[O[G~Wc޹MB"JTڢBvOxDvE>FG8pQDXYoaw跗nt\ghb)蠛Og'|b٫|bz=C>ޗ30')/ʪʪ0wF_O^Lgݬ G?~Sc2J0%4Fz*xϛ9?3Wtv|:r14=HkH-PuGUON"-z[$)gZ>vW @[[ Tʶؙ3Z|8q?$ם|iw:4O3M29"B3)t;T!-iKl0HL%OOOOOOO_W 0Z{zX}iҹՙ}kUټ|ISrHhH={@bbRaD<#Sel/̃0,)b΢I4T)|;Y*%No6(5͖~>/ɈaR4W֪vM{KB"Z YתڐiP_0:Mg;hVtPQL5vdƫ'Zdx%/IRhYj+rI;_3 fG+G3)Tء7UڦLk5;&Ε ݊xAMXqӎ@遺(@쁞3L=g9sϙ{s3=g9sYzj #zR.>Tmd˭ w:;t2֙l|<90EĊMOv[Ƞ]{3o?&=vԈ5J"/@#)/nz3=PR_vP(GOae UE uVn) zDg{ىBjW&.=Z3S n*l(j^\F:7^o{ZP'-oa-Ay$\B,¬< % +*blhņRQ4;})^=Kwe9[!!GmV&[oPcNJ+Rn5 MMLS/bjW2:M ]BkI+լcbjGTW endstream endobj 2944 0 obj << /Length 2300 /Filter /FlateDecode >> stream xڥY[s6~ϯиR &fgJێ=;cOifJS E*Šz_s?9̟?Wo.p$$lu7þh΢Gj=ꗳ(蝤QN^*\dgYPFx P^3`=d} Y90PG퉟k##Ei auG8c~u:b(RA(YUg$:-Ů\WN0AK-FY"/G|h$yHb̖1M滚 86yUM%&60%wWz m#$z\/ 45w(,V./o\%,T!2{mDž'CE %8/4E+v1kftN|* =j`U5Hʵ=ͦZ:T`rK^ݗY3(mD7P@Nt #D!HOyzbyX(Aض1u 0 :dsxRe+e^rf Y_-7.wBD0ݮZv#rS\|% k:cNm; `Cq ryNd] 27 |0]9ET.5׼ӦcپHnNN:AЛ"-Q!T4y&!Rs岩s.,$A>]H0 P= n<;F_r a߾}y=DZw߂NRx*q_21&4(J_HҐvI/S j'9Ԫ]r6J}ZnSCYi!= F$Bȡ-t@QDцLjC"BhQ0i( :*ٸ@ڷa^Ճʠ(Sˬ*f.CBv6 Mcd#>kLhzҮD cW)]"]WJG0j MPn8B IOnԹ9UQzBYZyeW]Imushl(n0p.y+ IJ<vvItm_ #SHیh0/A: z){/e ב^_J$y+[y^C+Ngdpɉ9BIis(htxeU~uix]ĵ[˩`![8PT/Q3b LF6] C דT`:Bh C pP\i^1\ɏvWh|(E[csw2:[$|z>Ջv$ffdf 2,஑02`~L}Ct<41n)Tw P畊Ct#:%Wi*\JR5`sOO!AKp]=΢@``TdFqW?ԗ2ZzH@W?'i*Yɴimpȇc6i2-Gd`$I }BN,Dc輋S ,&vZ/X,E'+1тj뷐rNlDGOӷ8L^ƿ|E;S-ʍ9f-U/*xwEJmO8H\"M򇟆axy8zB+vӓ.h쮟eb xi{$LP\@>~9Ul?w#D3UW)<$L\Z T;KS_G̓ 2jl.Ȧ_mj3Oò Ͼ@XWDBLv}SyԶz=՛ft endstream endobj 2956 0 obj << /Length 1734 /Filter /FlateDecode >> stream xڥX[o6~ϯӘ!)vX6-aKH%TQ^ oE%ˉ!pHrxw$vv>|yp|{NBNs9ssK2U,. QWY<&-9z=Li-`jy `-کj1(lLSVY>=2h^Q\GL0M"d6/Lwo) 8GH6)(dRW`ú ,H'@GӒ\*\V᪶(LUSrg/[EܨH*4ē+EL_meQߢ8-kS{svz~~PM <"lVZnYIi{BnIYk|b2$bV"W@%hVONӱ: ×] CoiO3}7!m EN8; L V/]8ϝ_Xou#,rXڈB>( -lB08)ex )_~c5ߛ?&3bUܽz hO(Qd B\(R2eE5RN T-H #5><K0DGwA7in vYa؄?8i}ز1Y={|;mB%n֪v[!mEFV>@]J&PV[0qy-t\HCR#MA!c MW?@9ih `'# YFs1h`18ȹTZ-r.O=vN+|E-dk;|lwQT(_m=DE@ZTҦK]I;#ɔF5a[- hכ--gYLW(V <C'+M}C#LlQƴj˥O=U5G.=Amw>\, [ʃL aetLYiho,NUv G<ք`A3k%.$ ױ75qLLD 6 nj̓0EVp1XK/S;r@&G!;"\!RaGEy%ްh. zoo-yiV!T8(WA0b0@,$̤k{[3PWyTqt|L6Ô=Q Y׌mnHj͵2(k|.}mǡ~jp1'!YdHm0Fx:^GR>E58wy5 `bo5 srGއZeT1QD6u1 rr+j,O endstream endobj 2992 0 obj << /Length 2301 /Filter /FlateDecode >> stream xڵYK8nrKƗMf .n;5*!klKyCy]HAhFrơI|U9p)#0kDS #F;U:mDcj^04SF"[1| #*UWJ.qffkl܎uf#岉>94]ƃ["ܬvbŖ۽]tp(1bы#&@BD:JS:icz"&|P̙ |K 0WV vlnܨE4* 3%' $3A\N #"9&ThN/8U}[0Ez 3ci62d1 [3WȀO1m/d i N ((͸+ZĹ+.]L,00"Oc>mV1eb <WT8!i qcnm hlo6DR]i/މ2xw]H е0>kHѺћl6ʟG)xQ OpٟYM93T`er-|m7F &Ɗ0xrߺ&Otӗ ute}ot?QJWIp!$f".wgr}wX.ܚHDH>*!{"Y *=]Z{rgĦx8Eφ uQ/#b !3 .rRQ%dK y2u]i^sgPr`g1&ffP!Fyub/yŦXB:6~͂Y ɛAC O%ǀ8DgOJaIe@ E| b28^J[';Vo qF)bhVu: ]~G;ʈx~+z/D"Xa,Uݶt;.K1#reHh8U3p*J:%:Cl>ػX>KoBәFIT82yK.*Xmgn9^8")a|]( zYKW+1QpK ;;_'QD8 oq_hyzA(^c`j LOsq\x!!ȈPNcۣ*r/'V17n2ּ0aXn5ڻ㵆j]ݡcUِ8C0va6 IS- r9[z TbICc;y{CLӺwXk;n,FjSʭv 8Bn#S<zX@UoQlw!86vu30]f=Hf9QQZd/niʔj[;t -pTNOާ}Ym%9)+ࣾ?E@{}.ρW/$+.u[bHe]5&h\{c3X*?!x[ٞM3d2#rgI41Ů5p/@862t'fȁ bpǪ :k֖eI: :["3YhV4'%3d1/0FYd›̉d՞ b@HG4m"wQa%~%U97o_*S;*`?0 HR,}-l!^)|Ș꫐}@C iBl6 CꅘL [kʍqZo{Et Su)㼫 AWaǗ dqrR,RcIY2-༿S endstream endobj 3013 0 obj << /Length 1529 /Filter /FlateDecode >> stream xڝXYs6~ׯ`iFBNθLNc7}HĆBRqw(Rd%aA,ߞX:+:'?_O ='&qa 0ws:g+YZ䗢$M3x m(#ar(T,jN^ǻ4Ko<3o`gOB4YLf1)%kQ5N <4gt&z¢g'_GSk9%|vD˺j\9/s⍔%R")vӍHS&J#6P@ȦvW1XQҍ}GؕqR03 rB[,9r: m }@icYHlA -y--UD-E#z"]*ⲶlDmEjl~0p  5",v+p[RmV"K!u;A% FKIj[g3ł)WL +r»[g$`f$:(_*BzxHH8cv(aC'Qpb8DpLA7\XAFI8x niR'EG]loF*6yd'*^hPDXͺ;wI|A b+t|Nc'O,A A'?_T6sLr ./#b)ın6l?E]fJUTQ du 7]o-[ {f[jf=Ȗ)b4{8qqhgY}VT<{uՅRgu{vtеJ9& i (ΓKqI)J!$qthd-k  JMϢ76_3hЩXhIgzz,šdpz_MSĿf,6ӬxYR1xߍ(=e7|0]X[wb#uRXC*ϝf-*P;W "(7p{}՞A'qU_J7 MuV[_m[EA|FebvT?0R6ImT=ٻyYT[Kc 0~5Ïx7 gHҸ[Av-Zt #6@ _<G-|*9gw%N7uF (ahej{ @bn Eڪ٣3Ѷ9i&VU)nnIk;s݃WŮ]ċ!x?q%V30.PA< n <ZiړʫX Ӫn<6=aix,ˬ8&<8M_e֌k1Ļ/7ly!%NncUĺ}UP ,tWSFST5,o _xh;#)?&a},(gYG<=ڏ\L<鰉T![~֩ endstream endobj 3032 0 obj << /Length 1357 /Filter /FlateDecode >> stream xڽXݓ6_KLP$!>]$dmܾ$yЁΦ]!!Gl_vn갷frz:ͭG0F!8ˆ?I֟6o_ل2@IiJlePnW&_a+$ɹ`8Xo\cl 0(Oh[9H?x>ikL%ɠ~VWwk/ǺO%$<# 4 U`+lDi6;gF.W\6m*sSdI:*|Hq)Bmh.o)AR ZTԓڬ^^(q )hxY {9|| :i@iorOg*9 ;QMQ既Mw}33QK^^ 0` I{e%KSh)'S=1GG\[:P>Og&ZNxԈɿIQH!YwM8^0pRN{dg1ʙ 98?!041( o͖0`-~VGt/^eiƑNwE l6+v%43fC<@$u1 \yZphbȇ B-`r?+m|wSWk&E%pP SÄ02MSlx˛%r6.Wˁ1RRn0cS 3qwܗ~ǢbGK+׋E]sՀaƏmʤ`>!tyyUS0odwhKXf'kЏf$@1'Fe.JIH}Sl6b0kCW^?ا._ ̘O(\wݾet endstream endobj 2941 0 obj << /Type /ObjStm /N 100 /First 984 /Length 2050 /Filter /FlateDecode >> stream xZ]o[G}ׯݗpHhxw,m}+K$o#]#sZR@ 83pFFqՑ q&d'M(.Q1Ml_19 Ŵ#'H'##l!}XrjeG RoS625S(TR5 hEť6bV64UIRH ߚ $VH136"c mB6j+&,F` -mHl#2HFdF6"cҬ @\R5*XЬ $ !*oYbׂ5Ңkl# F桢NlqH)jRvfU5%|$"47tRiB2VFKZjT,`Dc6a$TMbTe nMXTZbX2% 3a:ԜNr 6$(C2zl@\2Vpxl0 B.'%"C@Ρ-AWlQٕdoQ\قra %r# &-PU6u}7=B7$ymE@c=2>ZQ2Dt$9 ݢ[ǀFz[A1Ah./;:; ,P̩O|:(:>"͡bzg:J=w~1\ɭ"ފY tAkAdApN_?jB *bʴEJ-b@ja'(qZ,\WC7}Z`7}Mv6mӾ}&X[lpfzu֭}~X~rZElI@|P3Ls c%_1"[X 떅n>0Ql(w- ޱʣ,YsJwB zz!6"cîabKh 1W4q򍽆7ʻ(v2;NCfY|E6(Kb0Qkm$Pދ osas>S/ ۞@A'F@FiK^h/88햵Xmpc_:ekjx2+=*=* zVzV>9ٮhKzAJ- g @z/t[Vu[C՞F\ ؑh}CR#D Dq Gd ۫TnNS:o6gAY"['"kWƟwf>9sNڞ( }dgylfݞ>A;&9k\.>v`l/_a8?W/0ڂFk#M8mE0-6O4O;*x@\_Vv.d V eW8~LUnpA2{N ows}Z>E"`>f=s7 P,11oۭSXVa-/eoWZ!BԶ-i%Hm.g:62f#h3 `H_)Q/ _1r6T~wmxqxzm}*PwS/ʱWm"58*? LէTB+$%I҃tP|E).BApG}~ Lv~V #7 HX}pW^'=f!/Epv1f]\"e$e{w{v~ƆnlƼo7/,M(=I~yPwജ""5vna endstream endobj 3066 0 obj << /Length 2877 /Filter /FlateDecode >> stream xڵZm۸_8X3"E%wW Z۴(.*[W,$9k߯ ^zbp83fۙ7_^|Y@͌{e0 )_ollr2M&I0(!/<UK;x)B)j`0ߗo$ 7~Idjoʊu-Pi:I%q[2R8t{ZR4xa)]2ߋYTO=oqL,";&11OX]Ѯt:{|h_M=x&ZOFWo^ƿ^ W~v2/4x'3\^5L`ޢ&֜?H|UV,j:qCC0OZ}]-7j_v2rΑR(onδFo!ca+J'5V~Z `ajp^n58Rd!'h%mdkzam-<@[VvvARt4UfמLrn0VڋX7jV <6"(ϟmCooé@;}R9fՓ\ ٨MU&xP.\2'M.hy2 ,(%Cx"na"fa]AZhci8C Ҳ%4Q#̹A v|0b54}Y#W,ƷU^qp0V-c  b:A4h< AMq!j! T74r4tewsb)7IᠯsKۨFNc Zw[+CyrNɼIGo'x"~\UaWm,CȺzS™-NLwBngiF:N\g`=^V]&$w^=8\q&fmOL0ҕUM{nȼ('N"h0%l=p*{9 8!㡻vS 33]1P亮/8ז1-4YG.`H{ѷh[g$ 2x4Ss 8b]Vu9,OEoO ! d"HAz 2MgrtS誤'p ę5mD^zFF ^tY!eOTFfʧ|wMHE_3Hn0ksG@IxTH?Yv.ӆYgj'f$fA4w }Y2cPY^OQ^`XwN Nwϙ i\c/|‹`,aĚ=ʫX$ec/-30g5M?tOP-#ńp${ q?B$RB28%ػ7.Ė#('4Y`U̘rf~Qv4sC> stream xڵX[o6~ϯp>$[:oҤ˶E`$ZB(C-Ja+TEsh޻Qo#w[,{m## ={ůcJ9V$y([+ >lܱT/;64L,g|S[}h/A$N$T|ch,&ujiUФJJZ;5\gFK I#l Y.DA^|0pƆ"˳h8MC% lh2*25Wj(!-A$kBԆ9g斑 akƳ'BU1І44Sd(K DxJh\ܶLm; M'#, !.]d|4ASyvWkF# 0 `?WrlZ5}y.ss5$S#n)d'!Y҄f'⤡qu; Xd)L=W7g咘4#ac볺SG+ q9R u}u!e`Ya44VIQJ^QNT.e"kLx&E%9crHv`U^,I$L zǫF|q*c4KLțrj&NsߊY==WAfp:os86w;)/H딇uUβv"9BejŧmX3#dLzpfNl)ϱ ԰3}H*5N['vh6 3_r?skJV<%%H!^bðiane1 ]yIF?C%M.q窨=7t[3#Asz^o,py> stream xڵXKo6WɡP"EI)mHe$@i-V+m;ZI hჸp8Mm@g^x 'EpyDE JCZEIx.JٶO߿x#hI3iȈQwʋ7< 2ȮYƌ:N~wGMoa`#< %yFݐbt*jPj>⠬?Znp59T[ܺY]9qhuT tBJ_u}g^/uUx@^vle^_}>4gXP>|,8Z}#pg0.̿#B3%$M#Fl:1ɳUCt,W8wV>$ix 'C_ ˮѷ8~WmtGIz_D$ !djF:]W@NL%2bEy8 xDb: ,#s/[*';O'a߮PmE Cn5d4\6 V½ӀyCಆTk5A8!"XgUաckwձU r<s"JI;dVDmѝ4uQ-LiCRcALH'':ۭsdA YDWlhZ7Bp&߆3{|N|U^tKdl<_/I(TV\RfPxrg|,(HyVdS͒n'^,iD@DV C9 k2ek)+UthGt펒,q\.0֢Q2nƼ/Sl=íޫnWoLj:g,xڱkv E)6dm0XL+8i]VnΉ4 Qkha w &Av ql/`TqLgU~!!A <($]ǴI011TS$<⤭V.}gM8rNo4U)K Kö̩h a'5MA[ZKt \+7F2_@AH—Y[ lZXI]jqNRwu&'#Qvl68 վ 3w}9ݱORrߪՅNU^pV57Vi4t.{m40YuN4ia騍 D٫ݣ/;}(d%McUX,uSWw]#_HcCf3GsR&UڹީMqVK.:Բo˜QLcvέC) #&B/+ PݷHp&Kp?Ѩca8=\ow͔ğ.!f{stp*=P55»„Q>SjcM#xXÆCSor#=5P]Y*e~~*Px LpTReoJ]p{jC&I*Lc:ЫtHC{<>$CjN Lc2QBAvB^ڗ"5\(x}I_0M9 OJ:GcSGUhUy{߫S2v-ȇSY~޳|>i7Lu`hg0bs? 3 endstream endobj 3129 0 obj << /Length 2571 /Filter /FlateDecode >> stream xڽZ[oܸ~ϯ:n3\"Q"7٢}JTжZ44_ëD [ċs$E͟o)dNDYYRJ7 _n'&3)$sf}U ]*o N\OWNOr(:p@@dXaXB`̓XLCW4m3Ϣ1OQ^tdMϞX vZ6CUa 0Ֆ=[m̬$nITlhStU[[ƔWRC}YֻMsvz6/ߪM͕]_ M}dg(Th,W{lL釾)%дgaBG#</ss 9I몸o =Y#{@Je:+M1qHmnet\Pvþ_xȨ10$r<8LjaIϕ6E9E*}SŽ gMжYLIӶ?d_CT~=LN%q׻&}=ڔ2qWvp=6$86mm-f]mdWm[h 宍 r#AnBʣ$u|JD5 ~μ6;ͫ[{/pQr1vU+Jώt*G'zƑD@tFWrJe؞;  -g]ō'/8h*#IK{+hWE" | i)>\Y_v|IPO^/?Y|0j9W@L;ڊe@)U5T*gbM>CV;0OSܬ bPAٲm^+^z0Fut,;<yd{Vh|Xյy+ʲUs_?:96@Kc{%3tHtW EYֶa~oZ תxNTg3PC(Yɯ; Hῢ\?kM\=!U&(. ̄ȈB̨ziӳ cJU۱gMCQAGvTxSN d G6-#BmNsiH-A*SQBř I)MUf|׵voU7tiY|ѩyV50 1t\8T &=t,@ח?(nŦUZCU*]dW'xu[fr2^Q5:!0>J)JXIl`.J8J[c%Wg wf08 ^sKp`wּem-YWmrf 9\kG 1Ԭ;3;XbsUQ<,qNCV6;6s{[YVw&xAxkbxǏ9(yp Eb޼UB$;;D|ChY! ɑVJUu qf "AҀIv/R8!LG0xũc۶`U>pv6GC%2곑mV.c ~@>Um1ĴrIjzd:zeIJpm!PeP]K1h)iH3rVdMI(n% ~rwX"n~>qo YR-[oY:M0LQKܖ53SOWmHHٛ&TZNP[f>{t)W$?5y/ys3l)lfYWW^A7b])esN W Ř!dl2K1_yqףdނyTOc{ŋ ]?ƯOؘb5l뢜%(xF endstream endobj 3144 0 obj << /Length 2007 /Filter /FlateDecode >> stream xڭXo45>_@ /ZkiRdF'g$ =)V5&ܧI]> HqZ.~^s?hY- Zk$$F# IAyj:5vNtם(Y5>򖷛 4 (9 ^<-'$(w4[0St|BZ4- kWXyBu<H8@O2]L(H!;)>`B1rʦzBxFiiAK0P\"Jir5$hI!QZ?G In܂tmcq^[ʿ/*31^mpvs3`,!S$2p@Ka6PLɺPRՈ5:ff( wJy!-j_+|:YH(3{s 6$9k^+yH!n`珗bG8V~n(m,É.Q8ꋍ I@D0$#J2iqu:\|ՇU#o%^Ii7ro|cTBZrwטqE䟔FxJaD!k4(AUM"/m'qUЃr#(v+u m+5<-uP s2.*t=02^3[bue`"U"u!rDo)EP wu J2Cj@.ނ7$F1K*e d &DE]L4/HOػwM|i$w*FJu] k1'A4ap) }څ,L]hCα~m%Qy+ f3BOyV =uVxQ҆- X HUbQFT~`P <_qth i== bXI\h0 U|25mg.eqxOl5R/ei:c*|[ D:\"6y[q0{eLUY@-0#P[F,D˃\||;܅208Yr|iˀKLȔ:1:>MVjr9^o+|Do_,H^Gt[|,|霭-/`R2?UQ ˖Ǘk C̤Y7zއ=1[TV +W|ԵHkˌ-_~8RX쥏3닑u )cw|ORK5FIώx_7;D^V B IK-1<N0QT Mm}g<%5MM# 8x!i [Qh"y+y3Z"Ah鍗XsyqhD X/o~5zUN^K8if36! 5Isvs4;fvxE8ZHxߓ9gJ9y$t$2 A},@\naZr__=n5kn/SYY岛?.Yzleɛan7ccMb w&q/n&eٷS)jz??g He0p3QClLr:2ِ h{>8pԺy?]9 endstream endobj 3047 0 obj << /Type /ObjStm /N 100 /First 974 /Length 2078 /Filter /FlateDecode >> stream xZ]o[7} Eg]` i 쮑վu!)9Ԗ8)4WwH )IK!𻸘*bUI"'%1$_10WӨg u,p^UgƉ՜Μ]>qp9_k҇5%҂-bZ\,}-NbV n|ՉW3lZYZP8_GJf)L/o,ςIp].]5 RI#j,Я2ר\[h%[0BksƱСZoWu[jK,tU h b3钴o9/P?&`gxAqT`tAX̞d0I}-G`R,[#GD,[3׈XE>G@GD}j}x oR]0iV }t\$a qt(ɕn_,1Y̕6Q+JGp۲%EWrRRv ( _j,R'/-p(5Y%PW0XMk*].l53ZJiRϞ=;}SQ 鲉Vog_}07:r vz+Dn)!NN!>d>jqg@S<Mع=: >%RN@1.]jӶKZ}As3*J{{`qX&(WREu>ϩ#̄ t,VO%j<ތ༢ ?goM?!?d~z<d?jMOVܽY=Jzn@'Ǎر`çVg^(:33ooz- GBF"D(S{ŃRzc-vxJp̳,b+UYO0cjʶ\z*Pt\jq1_NH3HzrR`{rmU9ǡd]H$Vf|J47/COhAkiB%ȑ-!=ͬλaGG{@n֌ܩ{©$[{pd+Ïn QbG@ջ%PK`n(X5NZhnCN6a@Ƕ<{!fO Uo=\}/6z0-SժheV=*ʛz5\e䈮PdE 歖1B[,όcBw?RK2 endstream endobj 3154 0 obj << /Length 1835 /Filter /FlateDecode >> stream xX[o6~кY%C%CZw/Y0(%Wӭ~"% e'mŢIxw>?O~\L^^I($b2%F` nn yo'$9͞4q<}1MmRn;l5$es&pZQ|Có\`<%֌7MTf",~2 -KE^lw0M=`˜`kV#;}2"WV|U )l~5VڢLisI3d睈 z5H)@Yr0إ뼨;iee8kp"H!GJJ:]ƙ1c0IJ[y<7g& /q@J!6/[`Om A!g0΂ߺ >ڂ.aFDA:uௗ)KBH[l4KTg&x.J3x; 3BB VG= z(SR-twӁ #hX"F62q2{\y)EJ70ܦvF:sZobmB~#*:r]!Jv SkKsBLGEhNxՈs&24aSNZgWtm'Iˉ y@MR=0bg̺q_  Npg@<"<$DR.-X ŐnOĠ.U:o#YEWN]glV)Se5G/Tt/XPE4_]O9P]9AQu`[DM⅖/:vm, Er6%eƇwӇJLe9^y_.[Ъf>~BnfQM eTD{L^hUz&&U)kF'ԍlG?pm ]\CN:IӽǬD 0Xo|c6q󏅐^O!Zb溴: 纸9镇C">œBT9uAK!`q^8+TRxl߷,Y~Bn52e2UnpYl}"$Y!кҐA|UHKD *LO8H1uQohNю3gv/ʌzlNY]CGC` 34}R Cqxʟ8ؔI\ Fv&3Xx"EpB}8;c'f`ذ,B9l115dRS)[>VG\&vei[&Nxy9 ;DJ> 61\'V"17=,{xVTlՃ3pˏTEA„۽؍D݇K CA$:ԙP1Zzf8BNLұCӟxzzФc=Ԇ1+?%ijnjZoHڎ#@O9žDKa&h)9 \Ac{g/IwcEQ}zb@lvUQ(K9%(]64w}:,q8^6q"JD.|tI E) ^F<޳J+n'2_$~9m-e;+J2@rz;\4^&_'fwk/8斳B+";^őbPDa~ُj| / Rͣ-.._rqYE8m:;W$o9DwY}/$L6 W'wvN>/ڌ endstream endobj 3175 0 obj << /Length 1650 /Filter /FlateDecode >> stream xn6_!%)JCum7Tv8ؒ-iuË(ɦb0H~'V~};z EiLvQE! nl,+gӍE581LOF[p7ܝSՙy?I8[EK0IOɔFx lO730)k8/#N,_x0%B7? P8v`m .[{'l{oi~XgUe%AIG{j.ޯKX[7N h.*ܠn\l]+ @B6*HPYma~b>@X.YQc -@wVp B0k'O.!vD6x꼷 bлàV(0pZЫS|Ľ(|!TvqʯDue2!%$\:j-%^R:i[yVתg*xׯVũy._n}{vEP@>Jp1,Z >{Hh7eH7*O*ub0KjU3}lI'(khlLי~ʘk6oExE,IzD >&(}sud#3puҳK>_w]FŖQ̳}e EZpq n:%o髛ASʙލ~+[ZSC# GoiƄz3Sӄ)+4 }B,_-zSӡ=5_? I5a_^搁I Y~ռ[ŗtVt4}v3KhNә:-'Nl)CY_BdeTsv̠ .!Mkyآ::b"!e=aM S † |s> stream xX[o6~Ї9]~ 6  KxyPmQgK,ɿߑH]-9nHw.~4=3H*##ƥ$FQoc#Ong=W)(5@(~lлiw /& UK{& aaĉ^:܎0KvJvvF8vS4 2R--M 0N EO=GʈC&pD AFږX'Gc@_W4v45H)QT~-F:͠te栮DA59GAj6PE2D;7c[cӸ~UGYXVv%#Hpemg;w%͒$R;Z%H׉h1Hj^nH>|_T])f<`>yN?O[x1F# I|b8<niO&Ehi9d#3Aayr<6Aq! 3Jc!?iG;+p T%^} ռ(E\U؛8]z0bp|M-Xgkn`L WavvusGBz_thx,.8 8Cik2T4HPhFߕVX׽vRZ0]^{мsW\_4(Ǥd_46韊Lެ=2P*{l7az Q=K3Btr0;ڂ/Sڨx<v"ٴXaOhDu1Д7mlAMf9Me.S~h_fgW^l}f}7E") UiJ)Oi9=e4mʢcbY zH~A鐟K)r;j\rtةnq#uKƍƉ evPUq"!/Ağ@9?nEπ?+V>Xr=:>HH݌\tӋh~%,pPQXlz*yxף3YqS1t1zÛj%oT7?ƮP^&ʄ_;G6hZYթ\Tazsq1l~t<`6No/F endstream endobj 3254 0 obj << /Length 1436 /Filter /FlateDecode >> stream xڭWYoF~6{DZ.(l?8r_>ņ$cE{gR$EQÝog9/ ŇOPSy^sEc1l_Dyn|bQ\`{:{vJfTDd_%EG@(ZRzةv?.R7ʊK:VE8j@o,({/h|ƨsps3vrࢀ6`Gbك&G!Gz{x_2!m㐔5 R?1dWFZx~re g+gjv<ץ0,hyZu vZobDzn}}N]bͨ\_"3-WCѠ%fy5gwĸ*6|.5xIY)++ge RT{xw#Z,xV$0i~|S{nC0 #"32BQԏyDcgmhahWDKy%7/a$yaVpMӱE p{8e9-?\;^Eo-D[V7"3/InwK9"3r8 뇳uzp(CaDMM!˒^{RR:BP1ڔ0#Lht@.Rg"Y@Cvc'ښ`/MCXlψ9IޛOmw#˄exK(O(%(z0}xIb2rPsRCgtyyО3k!aχwE%3nvjp$riR ̇БӀ*Lwx1dk$jvMrh|C1+JaIHbI 淌=3VEDOBMaUϯ x&qSMnUI ɝB1 |Y"kx\A ̩Zˌ^b^wy(kTjTйjrR!O1uy16n\z\9(퐜ӓ{A`>F^xOEyz"ev5%LsOkft}U # u*:ߪn~4aLT|Efe>PML FMeӴ9zx%ͨqmvl[oz:pAw^}j0]Ѯu UX5,{yN?HJޓ-z7մ E-bTq|_Ru5v8hB_z3eUo{ilkٍz+r6!w:O([oH@}zt,]UYs3E/ "g!_utHhC8K]zs/;  endstream endobj 3149 0 obj << /Type /ObjStm /N 100 /First 975 /Length 1680 /Filter /FlateDecode >> stream xYKo7W^(r83$#@u )9 u@RJkqu>!Mj6*X8MITH0 k"fEj5&M66cf,b\*TKblTF <%ITUDu(sbtI`9@0I Șـ,Ihi4*& bbqbB?$Y X2 bxԂ&=( J0a>،qU, B"PB)Fdi< _ 9L8˲ ,m09SO 7!~GN7G|xs'w*`0.kwpƇϢI"g%mUKAn^hl+}㟗ӗӵ;q㟟]:n?c++M~4>զoϧgɣwA[K} {%?|ғM%4X9|Ǻ?-ge3^??>3ψ[Q\uMGY6/a6;z3M6J0Ҟ`˵?֟Bi#L-^rNQG|!<^w-}Y/gd?=V&[D^l Ŗ%NPQ"3^HC{QV~>:zBO5]Q/a0blf6ÁaA##PXE^pȀw _rX_`*b[=V&X,w!k5< ] IOnF@qU[rO^\݉]\ٖ}NcJ>þ-wIߖA:݉aMc!%e丰w.wK۹ۏJ{Dnnk#ubX*D6P/LߋabMjv{y@<D|-Gž̅n-:\n0TDb0X᳙݇:MWnȍ͡W`[j_ݜJُ;RO([o由gӊ?:`򁔯u=iGt}>H]L]L]1wD;)N!w r$]\!ݧfo瓷!R`o }8^zl@ ʾQgR^9zd𘎒/e/W? X)4#eZR#u7m]5E=v8>/~!1Pd/s%",ʊ]=z7%dKvuUo$S endstream endobj 3281 0 obj << /Length 1907 /Filter /FlateDecode >> stream xYmo6_!b37"ؚ[~JAh[-4wЎ BR$syg-=:=yD27[xcx#Qo{cNf=y)xg$QIAN5&).n7U| * =iRO^r0;z!b"UTΒMmTx?y:;zSnAs5S lDF؏fIB'ZH#hJXUw^FGi0 fty:aGлnpA aϮ@ۤv8N,٠UfEoM R:GuT 㰷Y  95 smSގm\+OKJu`YۍJR+V)E-:*cE8JHd=H_2`W2_Mr |շFe'0gx-#M bܨb d A9:'偽 ax8>9x:kf D@z=48h]^8}Xǘ*6m >}P'ٮ0=<*Yِ)]&|Np'-X8G "D"3eJ;ѰnkSɮT-Hϳ5FG!=8? Iм{1aF+r!)Jzȼ8.)emR$4*w Bv2l<޽cI9?$lJ$<GcjRgoL)fo߽+#s _b o OϞ')#%'Ip!=C1 -+^o=a3SXhtB^ahFkrO@ϋ2JŞd 3-WqrTь u4:E.‘8uHjaU> stream xڕYYs6~ׯ/T'BG%r>{w꺂p)8JI$DЈp6  CQ5>q%av_cyZEnՌ (eNYQT$ :|ZbM= mns },?. c!Ǐ{s/pQoMZjb 9%G 'Pb)  ON8xf: vakWH>R X'=(l,`[IJVcE(l(Xx}5^ImJ$-j#Y3fvc!T#^7+hU\k!J9:n?~z3 `$L1Gz$oݼ9U]"jͤ}M!>ˣIp}z5IgmF!/y5Y`6( .vj̻L0ݏH;z~$a0m=eHDž[}U񈄲6,PB:fW1gܞt@hZ0hW[T[-f]sAB͏NSS7'lj4#Zc넽d: Iє `%lmcFkHZ/i/xo )? !r@o"ko˫]dw\i W{24d4;wUj̋R6gOWϦS̑x"YZWnxW_*St3TH{/ߛy_ dK$kv굺~՛HL fXӭlWVT* % )H_!4(Pg(J+dS-1@9%mNzLt1>_,>gՇ3u)ݠnmjMx${; Rh Aʾ=SCiyh\C:iKh =$tf*47Ym`d=Z '}HLq;hB?N u m; uzj`PHgd9q0> stream xڝXY6~ׯP/KB0A3MZܢZ0d/8~B tkHU6ũp5(6DFG.k&R  ek1 b)j[6YdlEe# Ø2P6۪:l$#ԬӁP*eT ‚ |-um)!6ڸV\5cJ L~jv͇݇VR|>Ʌs2^t.<6cلMۨpf$OϗsB.tFw7'7Q i\;/2JW30!Ɛ eW@΃ʦ)V'O{]+a1nc9';hD1 壜@:Rѽ _6lieAeJN<{wgQޟglͰ+yڅAĎ]F Z9d>0y%ZT>Z>;r:p9 &$[Qnv&${u9ŎQg{cC-wdI5M&MJu^T['LR! >Oun^?\ Gy-uaP ΎGA(Y Gm!Խh Ov@ ~cEC AjԢㄑO8:N. >OGx endstream endobj 3266 0 obj << /Type /ObjStm /N 100 /First 986 /Length 1883 /Filter /FlateDecode >> stream xZ][}ׯcB!#wI`@[ZqٕI8>g(ݵz k\iH gI$$2J #,HRjP:-j4JBd0<[ 9 Z2 U$,H"&ܗ,dQR#fad_`kg(5b9aRb=5L)v|=7`N*>]ny89c+P)W[Cl>[_1C|(2v;kX,5LPMFU|Ծ5hPJp"c 0I֭҂dwv[ΖX' b\ -Jqɂf'g5"E]ԒK9(hJϒ50ۚ #hRj<ܛ S*}CЦ>Br@ܘJs@H5=HGh0r1 b,F-D| ,i^cj^C@^î@hiBM[vT8ς_ɓo?/jV?_7 ?3vf.abQ.X4i-&TS@^_ݬ7 -BbOd$ČH>d~ ?PKPN;: AAAf:)[6x}╡d'CR0YQ'5|m&,Yj{`UAQkI|O# $cG!Ym ӗ:܈Nϋ̈́|- ӆuZ I-qeOڣ^~!%ś8dmhpC~IP4,9D1y/"dxSA?cG&A9<\eBdKh&{jhF&^M<tOFM5Rۃj@564Уv `6!p{=2?}?g֟>T?g݇>jЏ ?OCCC4e?6;3ych:Nᘲ7](N(6R {"?mܷ>NŲ0=,q%w;(LNAbsk endstream endobj 3370 0 obj << /Length 1635 /Filter /FlateDecode >> stream xX[W8~W'Q%NN tt=a &S.~5dlcB`agFsIxp?ywك.uY;\f82Xf^>;t݆ 2%V+ka=#R:i`5o6B4$`D|Xtf2)4l<ضNiWETgG;AbyOVڷg#Csd(]O"'4c(\ #{ʳhbUςXȧuo=+HH6kY64p+Y'Ȧ5,=8iAd,ia9?SX+@F1 O8SvkP"^q"(i!1Gx!adm 8`fs.jssTΥfu{`x·?/zLdue0B+D_E|A ?MfHYςˁk0%+_Fo󜧥|Ւ K 2S kLprƵ*IX ^ȋޢ f=cSxyC ݭ{_)[ .4+]oLѰP/P!& ޫT]p(Tiz-_Q&q WN:,/T5v(Şj<`r<5Wixg2^&1;r~U@5E,v ̦,]؞@̧4Z3Iy [(oS`#ʺ\OGW{E g~P##lD\Dq mY$pd9~Kjyrf`|?crl)-bI> $:ȒպCM HS) {E賜G3[/-w\ZOSV֭uTYuϨňbE-һ?xis+/:κu6-rieJyr)ȶK`"Ouw9r01 Hx~'"a˥aW T6jVܶG8:FmGAI7%h+h> stream xX[sF~ׯJh˲ CZٙƎt<`2P޳";r;=[K [o?-'[>ͭŽE0F1bԶu;"X;9w+<;H2]\cFOssXpGL('PfMlWQj'f!d%¯(Jz:UOI}%x8!?[HGYT%iq9cm$}ߜ - UiTJׄ(bCO<˫Wx pIAeUljSf"lU"/ONb ҏ-? oP%`G(޳EC!-Dw2r0G0Y驣%v ־Աk̀qLfI3,)9u)c8 JBVɒjSM[fh)$ӍRnv)3-;n^Y\E1=sy}_,2A0tϜ9ej%"JIuۂRk>;U^]orY1=1WV:r)?Ҩ ۏۇ), m:n>G͎j7z|H‡_MJnݣ7e|%Vwg FaCq&\"P'}Io=8[ [ ̐Ǚ؊`BGɚZ!u(Wf> akG8P\cL݉5Ub##:v(OcGq1hrdtU^OQK=㈵cb<BFqX~ˑ瀥q3/r==02,u䙁#s r9Qo*nudoĄ4U,vk *ü($fQ-h0oBa74Z؅u}m63OM/w_bLY;SVsDHl A03-Dd?n-g_ÍC',I4Q_5IW3O:Vck2c[Q|IRQDIl*g/S41]ѡI\j0&T$Da;Q[|,E }A}%u\ǵ AMYbYҪ^esFGI" ;}ʰI]D:U-eN0BF دNTR"BuTI)oZU!Q"} uGqO:RW\l2Z@ěyd+Y^B>[2<9kx'}C \63Ĉm&]ro!.bIYqk HCEMm*(Zi/JC\#U-üğ endstream endobj 3395 0 obj << /Length 1479 /Filter /FlateDecode >> stream xڽXYo8~܇ 3JL BN-Z.B pϭ'ٿ,iR/FF,  5i0Dn1o.$|zy7Fd 0@*yef_PZȕkhZ$_`ϋI7R<_(--S>=Mj&AL2> N}&o͊ YkMDl6[45_Z|m5W&rLAh:mpH`{ьC;NKʿϑ7ktf,E.a^[qT#!5Kzs7$@R)@ou*qqo\-XA$ Lh# <".EQUZ kX jLcO6Bab7hgC`y)@^7Uںu@!=@"YCʀrm,\i3qjY?bz΅EmٺHc_2Y:Ӵ9GC>a*0 @(AJ?,8&`'ʒ5+w-5]|У"Þ' E遽gpFnC,8WI1|'%ϓUOi/+V'uw+:Ͷ]']NOGwuft7 [rݗs>tV&6FeMuֈ|;wϺviK>yFytS^پyɷk||z^#:j sӕ'yL~_h%vm|Y[kwnmNHݎr ֫N~cY t;c"r6%\A=hEw_,͗AMRsS 3u7"w) endstream endobj 3437 0 obj << /Length 1491 /Filter /FlateDecode >> stream xXێF}W ?w%R2ee36]sT4'E# mhNU?̾~'eT71.Hb$ n|wme NAN'_g?M=I׵?1oofg8 T Xf>` Hݺ 8!( yp=wxmdlH+eTL:=%!A(Ҋ8\F|U>Η!xq h乽W.*/6YD/$Uc$%R]R MZ'UCa@T!QȽ=6؆E"A.30EblSqLGb8=YD9bk ("tĿ{׹-CND,XwfH&pߟ5bƞ!c in&H a_Kdb3ҤR,aDeQR˦ Ba 3WWj[θ)+;)&Ί6aRZi?m(0EHW \qy"Y84Rr4 W& :)OFaY/v6C~}ʱ0sGOs<R!8:z޹W&H/v "9"C`rZO}i>}V2Ctv>"ޡ'QeKٖwqL`ip_Ju)f_x=Xӿ<:xv:w⛷uoXRT D|P(jehOwY=eðYcZ16\͇gHn)T!O?%s|{)H1e@("}dKAL {̟7[P:Ub}E"kac㭫a^wM] 6DP8Hz]&x%6NCH?uoyzoh8K{V.L;U E'Whoݧ<=A^B)%NV-[8LbĄlfxc6ŷ_봴遇A)Ht*—GB̦ǿ,np} @@oL$ΝOύ X0z`"ћHp&)DAo(n%QrwWOb("} ܔ$.bv74nuwco[ @ӻ @ ȋt+8ՒOYŖlgCqN;U=ޤ?90Гyycռ ^٫TtSѹRBcϕ& zXRœm\IVGL !VlKtpn2ϛDB?pQ}>DI'֗qMΝكz^7 GV/B7#EOf#9^2@`CBuwK endstream endobj 3365 0 obj << /Type /ObjStm /N 100 /First 978 /Length 1767 /Filter /FlateDecode >> stream xY[oSG~Gxٳ;*B DiJ%Tj&&q 6~3v !8ĆF"h\ٓW\J b#%qҟ$: EWbՕ\hRxA\]%Gך(13"(ȶ9RJdG.U=PT Vhv".`+2(JT8ڊH-?VJG+nHYw؂YsGW~ Q+c+8YE4 -6/5*0kkc&jjmx̲ 59$遂 *:XJ`6P8PYp<يJlEu@5P+2 0y 39 saeKQV@yG!2"9 AW % T2rN)!+2#g4x&Ɂʨ.S˚IS Fl2^*].cs)XC`s:j/k^z|Kf=GIf=Qa_جiz;;Ƴ^wt̞`* qS{NfJG0"r" vΎ\u{?ƣŋl2|OsrџN'Ozwbfh4OĂ |DհRd<L6 7:kZV^eRU`ނ6^4ђ=]v;K~44!J]^\/eaE,gҪ!{UQVmpɄ>*w hfGeT-[W :QP6(vY/u㺃}׽y?g;ͦڲ5 5`:oX&^ieTSfv_n`EEm;Л+ 5. 5ܻ$mP|WDTN9. dx4>'vw1*/4hF$a,ΎIv RuGݯlnCם~<9PΗ0ǟ˫uQ2o.骚 qekeF~u5c-coXʱD M6a+&1m4qyGjuDȾgIo_v7g kCEc(frL[~EmFr_g Zp ,[+*΂VN}(SpTn \Y](WD"(Cz]q%k3nj %8J\FÞF)z ,r4CHi^۽E4T7EQUBDsyĥ!Inh/-C 0(CF*;I @`Za#1-ʺ8jd AUį־`#36 #|fwgS?n5 IE9C?#"(}Z744 A_nhWn3ܨE>p F9 endstream endobj 3540 0 obj << /Length 1591 /Filter /FlateDecode >> stream xXK6W IQ"4ҼbYH@\Qnv;|Hi.Epfof_o8"4+`|z<(LO|-u/yHgAvFdUZ'XIzW,WF/TyY0JPDIU* |bVVY2dQ5VV΍v3xl.kYR 1Dr`0^|^BGfn=FLc"&FԼ>"0 Ȑ5,GHj)cdRaoe!9 f+Y(=޷Β村dt1ƯqqEI0(*>΂Tv_ŇM%W+ͩS˩Qx਼<--m)`eb4O˱GP B)ĶW7Ih1i9|s@l!ib6"GLf1 }D1kz<&=DQHuz?n:H0xa=HF̅'a6z$<.հ|7"rQaQ(NW`ӂ%=LazpsY.(bڬ?o @@iy됁f)Ĕs}u37Z ]̺tC#Q{z3[zJ:gIF7W@IAKIjS~ 3di;fMḠ81nGЎ#-,t_I㛭[q>O6*y]]HFfW%Wh񚫇 u'"ި S v^ԝ5nW'(`'FIP endstream endobj 3525 0 obj << /Type /ObjStm /N 100 /First 971 /Length 1249 /Filter /FlateDecode >> stream xYjc7}W}H# nBBK6mCMB}όs%-?#9H#K.) PjO)lF ,Q0@2Ʉ!noz(ɰB)[)#A{rAKA54vO MF C/)PJ+auA J f)>R@٣e#;4(I]!Fu 1h\FC:@]8a`rKB:z:z`xQ918,(>(}>PQbTr_0LG!h}Ѻ7}HT݇"QE>d]#m%Y -'L,ղfŒBZwr¢!f^(ܑbJjKc9߫Po=02XdJ(RM(v{"*䖆`]Ѫu͌aKp]mA0(jYpQ`\'(CbG᧟WzL͛]{[]#cKp*Rt;4&ִHH-єbښCs܃=xރ=xރXsۢGֶ%*9^ NJJw;PmoVӡ||r5ҦV70~0[0?:aB}8Ël2"l^mjY ~y93dvu;}x*DF)~x%Ay;/0:6Z^a%QGF4$8 JGcY6#!YMn-]X~6E3 Pi")Pb- [_anqXoNGb>;jw[[WZ@MRyNI%W$Vlz6cwaK-J^tIbniq+QK{ֿ`9*7Q-Λ=r{Y* di[! GS}q}{DH6ǽH,> stream xZKsܸWL˨ MUUz 4ԒJǧ q6ҁx6_0E/WZ/Rj"&c0:bJzi#}LQwS?O]gS;2ypy!/h ?{>h5OHb?hId,"朙XBX|8Q@:L naDGIO32K.X> 1 7YANOsiK[oTʄrfSwm^F<8h 3J%g3c")g} ԨФ[{J-s5~2ñꆾEet&MtD,sfoU|iiSPv8pÞs[Zل{ܫofBu^͐C[pݏX鞌SUD1c­}7C [AkXQTZ,AˑXn~inM'!d ^L7h)R-XwG6Č mǠcj$TG!,i4-Y  %ƈ;ẅ́OjO=OՉM-hþ\U`e J"T˗4J!z#8\tb4#J̋YJRE%gdx B4K[<9 g#$""CJ ~t \E@CL%qwB=&7 F# %> Gp3p.V]D_AfP(Ia0:*RRw@RSZ}spT1JNd@CaB]jp3BnENWpCG czG=6e>y%#+'.an]fE@wZ#5uM6f#PZ-uj-RDOj57 7ڹQ_ :M2Z^g%8=Tu\?$Xs7P ZdٹOcGD#"Ӄj*TU/VιMmHeKU4I.ؗwنc[&l!'$^ӰMvDv 78P 1_Zpi*F9t4 wotQL $rp$  dN(Y_7ԯnZ[Rs|s)t@]*w%t[SnEp~~Ȉ_i W+ZREKmoll-}b5v$ rf. ?4b:hfPx&#hʇ@0Q.` $x7/hv/:#@rugWOvw+Ai+;&tzOTg>]6$t? ~#6eq?J>zq/3yA? ^:f|L;Ͻ0Oy> stream xڵXk6_ḻ\ fEv&n-SrlXD<コ$1Ab*|v?7ϾY?{qw3s,8 }o~tz/Z~/*;6kY/~ZM4bqV1zƵ5&p{R+?NZ" w2`iW#Ou~i+CXbO0ύP.}#JaiKŭhϜWZuLqPC?jH2t6̋!&%4}jXZ_xM3m aP\uj FmMh"o?\3:6JXm0eC j>ti>_FK%NϠ/$Y:9 N q`ߕ:`'K!\8$mP<* 'p.uÙN2R^p['u>powM@e ﻬ  ?ӝ) ,J ,W:sm`͠uVzh0< s农y+/x|/]';kn"M}b}9`?#z>~: bR_{lPpL4%^7>SeOV "+ ԕPED\( l0_j(=D4ur*ǯ/h]uo͔1P_Oyf'&;K4TG|Vm>